|
| 1 | +# See https://github.com/gonzalo-bulnes/simple_token_authentication/issues/26 |
| 2 | +Feature: Password change provokes the authentication token reset |
| 3 | + As an user |
| 4 | + In order to ensure no-one can take advantage of my previous credentials |
| 5 | + I want my authentication token to become invalid when I change my password |
| 6 | + |
| 7 | + @rspec |
| 8 | + Scenario: After password change, the authentication token is renewed |
| 9 | + Given I have a dummy app with a Devise-enabled User |
| 10 | + And a scaffolded PrivatePost |
| 11 | + And I prepare the test database |
| 12 | + And the `authenticate_user!` and `sign_in` methods always raise an exception |
| 13 | + And User `acts_as_token_authenticatable` |
| 14 | + And PrivatePostsController `acts_as_token_authentication_handler_for` User |
| 15 | + And I write to "spec/factories/users.rb" with: |
| 16 | + """ |
| 17 | + FactoryGirl.define do |
| 18 | + sequence :email do |n| |
| 19 | + "user#{n}@factory.com" |
| 20 | + end |
| 21 | +
|
| 22 | + factory :user do |
| 23 | + email |
| 24 | + password "password" |
| 25 | + password_confirmation "password" |
| 26 | + end |
| 27 | + end |
| 28 | + """ |
| 29 | + And I write to "spec/requests/private_posts_controller_spec.rb" with: |
| 30 | + """ |
| 31 | + require 'spec_helper' |
| 32 | +
|
| 33 | + describe "PrivatePostsController" do |
| 34 | + describe "GET /private_posts" do |
| 35 | +
|
| 36 | + let!(:user) do |
| 37 | + FactoryGirl.create(:user \ |
| 38 | + ,email: 'alice@example.com' \ |
| 39 | + ,authentication_token: 'ExaMpLeTokEn' ) |
| 40 | + end |
| 41 | +
|
| 42 | + context "while password hasn't been renewed" do |
| 43 | + context "when the original authentication token is used" do |
| 44 | + it "performs token authentication" do |
| 45 | +
|
| 46 | + # `sign_in` is configured to raise an exception when called, |
| 47 | + # see spec/dummy/app/controllers/application_controller.rb |
| 48 | + lambda do |
| 49 | + # see https://github.com/rspec/rspec-rails/issues/65 |
| 50 | + # and http://guides.rubyonrails.org/testing.html#helpers-available-for-integration-tests |
| 51 | + request_via_redirect 'GET', private_posts_path, nil, { 'X-User-Email' => user.email, 'X-User-Token' => 'ExaMpLeTokEn' } |
| 52 | + end.should raise_exception(RuntimeError, "`sign_in` was called.") |
| 53 | + end |
| 54 | + end |
| 55 | + end |
| 56 | +
|
| 57 | + context "once the password has been changed" do |
| 58 | + context "when the original authentication token is used" do |
| 59 | + it "does not perform token authentication" do |
| 60 | +
|
| 61 | + # `sign_in` is configured to raise an exception when called, |
| 62 | + # see spec/dummy/app/controllers/application_controller.rb |
| 63 | + lambda do |
| 64 | + # see https://github.com/rspec/rspec-rails/issues/65 |
| 65 | + # and http://guides.rubyonrails.org/testing.html#helpers-available-for-integration-tests |
| 66 | + request_via_redirect 'GET', private_posts_path, nil, { 'X-User-Email' => user.email, 'X-User-Token' => 'ExaMpLeTokEn' } |
| 67 | + end.should raise_exception(RuntimeError, "`authenticate_user!` was called.") |
| 68 | + end |
| 69 | + end |
| 70 | + context "when the new authentication token is used" do |
| 71 | + it "performs token authentication" do |
| 72 | +
|
| 73 | + # `sign_in` is configured to raise an exception when called, |
| 74 | + # see spec/dummy/app/controllers/application_controller.rb |
| 75 | + lambda do |
| 76 | + # see https://github.com/rspec/rspec-rails/issues/65 |
| 77 | + # and http://guides.rubyonrails.org/testing.html#helpers-available-for-integration-tests |
| 78 | + request_via_redirect 'GET', private_posts_path, nil, { 'X-User-Email' => user.email, 'X-User-Token' => user.authentication_token } |
| 79 | + end.should raise_exception(RuntimeError, "`sign_in` was called.") |
| 80 | + end |
| 81 | + end |
| 82 | + end |
| 83 | + end |
| 84 | + end |
| 85 | + """ |
| 86 | + And I write to "spec/models/user_spec.rb" with: |
| 87 | + """ |
| 88 | + require 'spec_helper' |
| 89 | +
|
| 90 | + describe User do |
| 91 | +
|
| 92 | + # attributes |
| 93 | +
|
| 94 | + specify { expect(subject).to respond_to :authentication_token } |
| 95 | +
|
| 96 | + # validations |
| 97 | +
|
| 98 | + it 'has a valid factory' do |
| 99 | + expect(FactoryGirl.create(:user)).to be_valid |
| 100 | + end |
| 101 | +
|
| 102 | + # methods |
| 103 | +
|
| 104 | + describe '#renew_authentication_token!' do |
| 105 | +
|
| 106 | + let!(:user) { FactoryGirl.create(:user) } |
| 107 | +
|
| 108 | + it 'accepts no arguments' do |
| 109 | + expect{ user.renew_authentication_token!('oops') }.to raise_error |
| 110 | + end |
| 111 | +
|
| 112 | + it 'returns true' do |
| 113 | + expect(user.renew_authentication_token!).to eq true |
| 114 | + end |
| 115 | +
|
| 116 | + it "renews the user's authentication token" do |
| 117 | + original_authentication_token = user.authentication_token |
| 118 | +
|
| 119 | + expect(user.renew_authentication_token!).to change(user.authentication_token) |
| 120 | + end |
| 121 | + end |
| 122 | + end |
| 123 | + """ |
| 124 | + |
| 125 | + And I silence the PrivatePostsController spec errors |
| 126 | + |
| 127 | + When I run `rspec --format documentation` |
| 128 | + Then the exit status should be 0 |
| 129 | + And the output should match: |
| 130 | + """ |
| 131 | + User |
| 132 | + #renew_authentication_token |
| 133 | + """ |
| 134 | + And the output should match: |
| 135 | + """ |
| 136 | + accepts no arguments |
| 137 | + """ |
| 138 | + And the output should match: |
| 139 | + """ |
| 140 | + returns true |
| 141 | + """ |
| 142 | + And the output should match: |
| 143 | + """ |
| 144 | + renews the user's authentication token |
| 145 | + """ |
| 146 | + And the output should match: |
| 147 | + """ |
| 148 | + PrivatePostsController |
| 149 | + GET /private_posts |
| 150 | + """ |
| 151 | + And the output should match: |
| 152 | + """ |
| 153 | + while password hasn't been renewed |
| 154 | + when the original authentication token is used |
| 155 | + performs token authentication |
| 156 | + """ |
| 157 | + And the output should contain: |
| 158 | + """ |
| 159 | + once the password has been changed |
| 160 | + """ |
| 161 | + And the output should contain: |
| 162 | + """ |
| 163 | + when the original authentication token is used |
| 164 | + does not perform token authentication |
| 165 | + """ |
| 166 | + And the output should contain: |
| 167 | + """ |
| 168 | + when the new authentication token is used |
| 169 | + performs token authentication |
| 170 | + """ |
0 commit comments