stn-simple_token_authentication 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +270 -0
  4. data/Rakefile +61 -0
  5. data/doc/README.md +18 -0
  6. data/lib/simple_token_authentication.rb +58 -0
  7. data/lib/simple_token_authentication/acts_as_token_authenticatable.rb +49 -0
  8. data/lib/simple_token_authentication/acts_as_token_authentication_handler.rb +22 -0
  9. data/lib/simple_token_authentication/adapter.rb +7 -0
  10. data/lib/simple_token_authentication/adapters/active_record_adapter.rb +14 -0
  11. data/lib/simple_token_authentication/adapters/mongoid_adapter.rb +14 -0
  12. data/lib/simple_token_authentication/adapters/rails_adapter.rb +14 -0
  13. data/lib/simple_token_authentication/adapters/rails_api_adapter.rb +18 -0
  14. data/lib/simple_token_authentication/configuration.rb +45 -0
  15. data/lib/simple_token_authentication/entities_manager.rb +10 -0
  16. data/lib/simple_token_authentication/entity.rb +64 -0
  17. data/lib/simple_token_authentication/fallback_authentication_handler.rb +11 -0
  18. data/lib/simple_token_authentication/sign_in_handler.rb +19 -0
  19. data/lib/simple_token_authentication/token_authentication_handler.rb +149 -0
  20. data/lib/simple_token_authentication/token_comparator.rb +20 -0
  21. data/lib/simple_token_authentication/token_generator.rb +9 -0
  22. data/lib/simple_token_authentication/version.rb +3 -0
  23. data/lib/tasks/simple_token_authentication_tasks.rake +4 -0
  24. data/spec/configuration/action_controller_callbacks_options_spec.rb +53 -0
  25. data/spec/configuration/fallback_to_devise_option_spec.rb +128 -0
  26. data/spec/configuration/header_names_option_spec.rb +463 -0
  27. data/spec/configuration/sign_in_token_option_spec.rb +92 -0
  28. data/spec/lib/simple_token_authentication/acts_as_token_authenticatable_spec.rb +108 -0
  29. data/spec/lib/simple_token_authentication/acts_as_token_authentication_handler_spec.rb +127 -0
  30. data/spec/lib/simple_token_authentication/adapter_spec.rb +19 -0
  31. data/spec/lib/simple_token_authentication/adapters/active_record_adapter_spec.rb +21 -0
  32. data/spec/lib/simple_token_authentication/adapters/mongoid_adapter_spec.rb +21 -0
  33. data/spec/lib/simple_token_authentication/adapters/rails_adapter_spec.rb +21 -0
  34. data/spec/lib/simple_token_authentication/adapters/rails_api_adapter_spec.rb +43 -0
  35. data/spec/lib/simple_token_authentication/configuration_spec.rb +133 -0
  36. data/spec/lib/simple_token_authentication/entities_manager_spec.rb +67 -0
  37. data/spec/lib/simple_token_authentication/entity_spec.rb +190 -0
  38. data/spec/lib/simple_token_authentication/errors_spec.rb +8 -0
  39. data/spec/lib/simple_token_authentication/fallback_authentication_handler_spec.rb +24 -0
  40. data/spec/lib/simple_token_authentication/sign_in_handler_spec.rb +43 -0
  41. data/spec/lib/simple_token_authentication/token_authentication_handler_spec.rb +351 -0
  42. data/spec/lib/simple_token_authentication/token_comparator_spec.rb +19 -0
  43. data/spec/lib/simple_token_authentication/token_generator_spec.rb +19 -0
  44. data/spec/lib/simple_token_authentication_spec.rb +181 -0
  45. data/spec/spec_helper.rb +15 -0
  46. data/spec/support/dummy_classes_helper.rb +80 -0
  47. data/spec/support/spec_for_adapter.rb +10 -0
  48. data/spec/support/spec_for_authentication_handler_interface.rb +8 -0
  49. data/spec/support/spec_for_configuration_option_interface.rb +28 -0
  50. data/spec/support/spec_for_entities_manager_interface.rb +8 -0
  51. data/spec/support/spec_for_sign_in_handler_interface.rb +8 -0
  52. data/spec/support/spec_for_token_comparator_interface.rb +8 -0
  53. data/spec/support/spec_for_token_generator_interface.rb +8 -0
  54. data/spec/support/specs_for_token_authentication_handler_interface.rb +8 -0
  55. metadata +250 -0
@@ -0,0 +1,351 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Any class which includes SimpleTokenAuthentication::TokenAuthenticationHandler' do
4
+
5
+ let(:described_class) do
6
+ define_dummy_class_which_includes SimpleTokenAuthentication::TokenAuthenticationHandler
7
+ end
8
+
9
+ after(:each) do
10
+ # ensure_examples_independence
11
+ SimpleTokenAuthentication.send(:remove_const, :SomeClass)
12
+ end
13
+
14
+ it_behaves_like 'a token authentication handler'
15
+
16
+ let(:subject) { described_class }
17
+
18
+ describe '.handle_token_authentication_for' do
19
+
20
+ before(:each) do
21
+ double_user_model
22
+ end
23
+
24
+ it 'ensures token authentication is handled for a given (token authenticatable) model', public: true do
25
+ entities_manager = double()
26
+ allow(entities_manager).to receive(:find_or_create_entity).and_return('entity')
27
+
28
+ # skip steps which are not relevant in this example
29
+ allow(SimpleTokenAuthentication).to receive(:fallback).and_return('default')
30
+ allow(subject).to receive(:entities_manager).and_return(entities_manager)
31
+ allow(subject).to receive(:set_token_authentication_hooks)
32
+ allow(subject).to receive(:define_token_authentication_helpers_for)
33
+
34
+ expect(subject).to receive(:set_token_authentication_hooks).with('entity', {option: 'value', fallback: 'default'})
35
+ subject.handle_token_authentication_for(User, {option: 'value'})
36
+ end
37
+
38
+ context 'when called multiple times' do
39
+
40
+ it 'ensures token authentication is handled for the given (token authenticatable) models', public: true do
41
+ double_super_admin_model
42
+ entities_manager = double()
43
+ allow(entities_manager).to receive(:find_or_create_entity).with(User).and_return('User entity')
44
+ allow(entities_manager).to receive(:find_or_create_entity).with(SuperAdmin).and_return('SuperAdmin entity')
45
+
46
+ # skip steps which are not relevant in this example
47
+ allow(SimpleTokenAuthentication).to receive(:fallback).and_return('default')
48
+ allow(subject).to receive(:entities_manager).and_return(entities_manager)
49
+ allow(subject).to receive(:set_token_authentication_hooks)
50
+ allow(subject).to receive(:define_token_authentication_helpers_for)
51
+
52
+ expect(subject).to receive(:set_token_authentication_hooks).with('User entity', {option: 'value', fallback: 'default'})
53
+ expect(subject).to receive(:set_token_authentication_hooks).with('SuperAdmin entity', {option: 'some specific value', fallback: 'default'})
54
+ subject.handle_token_authentication_for(User, {option: 'value'})
55
+ subject.handle_token_authentication_for(SuperAdmin, {option: 'some specific value'})
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '.entities_manager' do
61
+
62
+ before(:each) do
63
+ # The private tag is here to keep the following examples out of
64
+ # the public documentation.
65
+ subject.send :public_class_method, :entities_manager
66
+
67
+ allow(SimpleTokenAuthentication::EntitiesManager).to receive(:new)
68
+ .and_return('a EntitiesManager instance')
69
+ end
70
+
71
+ context 'when called for the first time' do
72
+
73
+ it 'creates a new EntitiesManager instance', private: true do
74
+ expect(SimpleTokenAuthentication::EntitiesManager).to receive(:new)
75
+ expect(subject.entities_manager).to eq 'a EntitiesManager instance'
76
+ end
77
+ end
78
+
79
+ context 'when a EntitiesManager instance was already created' do
80
+
81
+ before(:each) do
82
+ subject.entities_manager
83
+ # let's make any new EntitiesManager distinct from the first
84
+ allow(SimpleTokenAuthentication::EntitiesManager).to receive(:new)
85
+ .and_return('another EntitiesManager instance')
86
+ end
87
+
88
+ it 'returns that instance', private: true do
89
+ expect(subject.entities_manager).to eq 'a EntitiesManager instance'
90
+ end
91
+
92
+ it 'does not create a new EntitiesManager instance', private: true do
93
+ expect(SimpleTokenAuthentication::EntitiesManager).not_to receive(:new)
94
+ expect(subject.entities_manager).not_to eq 'another EntitiesManager instance'
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '.fallback_authentication_handler' do
100
+
101
+ before(:each) do
102
+ # The private tag is here to keep the following examples out of
103
+ # the public documentation.
104
+ subject.send :public_class_method, :fallback_authentication_handler
105
+
106
+ allow(SimpleTokenAuthentication::FallbackAuthenticationHandler).to receive(:new)
107
+ .and_return('a FallbackAuthenticationHandler instance')
108
+ end
109
+
110
+ context 'when called for the first time' do
111
+
112
+ it 'creates a new FallbackAuthenticationHandler instance', private: true do
113
+ expect(SimpleTokenAuthentication::FallbackAuthenticationHandler).to receive(:new)
114
+ expect(subject.fallback_authentication_handler).to eq 'a FallbackAuthenticationHandler instance'
115
+ end
116
+ end
117
+
118
+ context 'when a FallbackAuthenticationHandler instance was already created' do
119
+
120
+ before(:each) do
121
+ subject.fallback_authentication_handler
122
+ # let's make any new FallbackAuthenticationHandler distinct from the first
123
+ allow(SimpleTokenAuthentication::FallbackAuthenticationHandler).to receive(:new)
124
+ .and_return('another FallbackAuthenticationHandler instance')
125
+ end
126
+
127
+ it 'returns that instance', private: true do
128
+ expect(subject.fallback_authentication_handler).to eq 'a FallbackAuthenticationHandler instance'
129
+ end
130
+
131
+ it 'does not create a new FallbackAuthenticationHandler instance', private: true do
132
+ expect(SimpleTokenAuthentication::FallbackAuthenticationHandler).not_to receive(:new)
133
+ expect(subject.fallback_authentication_handler).not_to eq 'another FallbackAuthenticationHandler instance'
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '#find_record_from_identifier', private: true do
139
+
140
+ before(:each) do
141
+ @entity = double()
142
+ end
143
+
144
+ context 'when the Devise config. does not defines the identifier as a case-insentitive key' do
145
+
146
+ before(:each) do
147
+ allow(Devise).to receive_message_chain(:case_insensitive_keys, :include?)
148
+ .with(:email).and_return(false)
149
+ end
150
+
151
+ context 'when a downcased identifier was provided' do
152
+
153
+ before(:each) do
154
+ allow(@entity).to receive(:get_identifier_from_params_or_headers)
155
+ .and_return('alice@example.com')
156
+ end
157
+
158
+ it 'returns the proper record if any' do
159
+ # let's say there is a record
160
+ record = double()
161
+ allow(@entity).to receive_message_chain(:model, :where).with(email: 'alice@example.com')
162
+ .and_return([record])
163
+
164
+ expect(subject.new.send(:find_record_from_identifier, @entity)).to eq record
165
+ end
166
+ end
167
+
168
+ context 'when a upcased identifier was provided' do
169
+
170
+ before(:each) do
171
+ allow(@entity).to receive(:get_identifier_from_params_or_headers)
172
+ .and_return('AliCe@ExampLe.Com')
173
+ end
174
+
175
+ it 'does not return any record' do
176
+ # let's say there is a record...
177
+ record = double()
178
+ # ...whose identifier is downcased...
179
+ allow(@entity).to receive_message_chain(:model, :where).with(email: 'alice@example.com')
180
+ .and_return([record])
181
+ # ...not upcased
182
+ allow(@entity).to receive_message_chain(:model, :where).with(email: 'AliCe@ExampLe.Com')
183
+ .and_return([])
184
+
185
+ expect(subject.new.send(:find_record_from_identifier, @entity)).to be_nil
186
+ end
187
+ end
188
+ end
189
+
190
+
191
+ context 'when the Devise config. defines the identifier as a case-insentitive key' do
192
+
193
+ before(:each) do
194
+ allow(Devise).to receive_message_chain(:case_insensitive_keys, :include?)
195
+ .with(:email).and_return(true)
196
+ end
197
+
198
+ context 'and a downcased identifier was provided' do
199
+
200
+ before(:each) do
201
+ allow(@entity).to receive(:get_identifier_from_params_or_headers)
202
+ .and_return('alice@example.com')
203
+ end
204
+
205
+ it 'returns the proper record if any' do
206
+ # let's say there is a record
207
+ record = double()
208
+ allow(@entity).to receive_message_chain(:model, :where).with(email: 'alice@example.com')
209
+ .and_return([record])
210
+
211
+ expect(subject.new.send(:find_record_from_identifier, @entity)).to eq record
212
+ end
213
+ end
214
+
215
+ context 'and a upcased identifier was provided' do
216
+
217
+ before(:each) do
218
+ allow(@entity).to receive(:get_identifier_from_params_or_headers)
219
+ .and_return('AliCe@ExampLe.Com')
220
+ end
221
+
222
+ it 'returns the proper record if any' do
223
+ # let's say there is a record...
224
+ record = double()
225
+ # ...whose identifier is downcased...
226
+ allow(@entity).to receive_message_chain(:model, :where)
227
+ allow(@entity).to receive_message_chain(:model, :where).with(email: 'alice@example.com')
228
+ .and_return([record])
229
+ # ...not upcased
230
+ allow(@entity).to receive_message_chain(:model, :where).with(email: 'AliCe@ExampLe.Com')
231
+ .and_return([])
232
+
233
+ expect(subject.new.send(:find_record_from_identifier, @entity)).to eq record
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ describe 'and which supports the :before_filter hook' do
240
+
241
+ before(:each) do
242
+ allow(subject).to receive(:before_filter)
243
+ end
244
+
245
+ # User
246
+
247
+ context 'and which handles token authentication for User' do
248
+
249
+ before(:each) do
250
+ double_user_model
251
+ end
252
+
253
+ it 'ensures its instances require user to authenticate from token or any Devise strategy before any action', public: true do
254
+ expect(subject).to receive(:before_filter).with(:authenticate_user_from_token!, {})
255
+ subject.handle_token_authentication_for User
256
+ end
257
+
258
+ context 'and disables the fallback to Devise authentication' do
259
+
260
+ let(:options) do
261
+ { fallback_to_devise: false }
262
+ end
263
+
264
+ it 'ensures its instances require user to authenticate from token before any action', public: true do
265
+ expect(subject).to receive(:before_filter).with(:authenticate_user_from_token, {})
266
+ subject.handle_token_authentication_for User, options
267
+ end
268
+ end
269
+
270
+ describe 'instance' do
271
+
272
+ before(:each) do
273
+ double_user_model
274
+
275
+ subject.class_eval do
276
+ handle_token_authentication_for User
277
+ end
278
+ end
279
+
280
+ it 'responds to :authenticate_user_from_token', protected: true do
281
+ expect(subject.new).to respond_to :authenticate_user_from_token
282
+ end
283
+
284
+ it 'responds to :authenticate_user_from_token!', protected: true do
285
+ expect(subject.new).to respond_to :authenticate_user_from_token!
286
+ end
287
+
288
+ it 'does not respond to :authenticate_super_admin_from_token', protected: true do
289
+ expect(subject.new).not_to respond_to :authenticate_super_admin_from_token
290
+ end
291
+
292
+ it 'does not respond to :authenticate_super_admin_from_token!', protected: true do
293
+ expect(subject.new).not_to respond_to :authenticate_super_admin_from_token!
294
+ end
295
+ end
296
+ end
297
+
298
+ # SuperAdmin
299
+
300
+ context 'and which handles token authentication for SuperAdmin' do
301
+
302
+ before(:each) do
303
+ double_super_admin_model
304
+ end
305
+
306
+ it 'ensures its instances require super_admin to authenticate from token or any Devise strategy before any action', public: true do
307
+ expect(subject).to receive(:before_filter).with(:authenticate_super_admin_from_token!, {})
308
+ subject.handle_token_authentication_for SuperAdmin
309
+ end
310
+
311
+ context 'and disables the fallback to Devise authentication' do
312
+
313
+ let(:options) do
314
+ { fallback_to_devise: false }
315
+ end
316
+
317
+ it 'ensures its instances require super_admin to authenticate from token before any action', public: true do
318
+ expect(subject).to receive(:before_filter).with(:authenticate_super_admin_from_token, {})
319
+ subject.handle_token_authentication_for SuperAdmin, options
320
+ end
321
+ end
322
+
323
+ describe 'instance' do
324
+
325
+ before(:each) do
326
+ double_super_admin_model
327
+
328
+ subject.class_eval do
329
+ handle_token_authentication_for SuperAdmin
330
+ end
331
+ end
332
+
333
+ it 'responds to :authenticate_super_admin_from_token', protected: true do
334
+ expect(subject.new).to respond_to :authenticate_super_admin_from_token
335
+ end
336
+
337
+ it 'responds to :authenticate_super_admin_from_token!', protected: true do
338
+ expect(subject.new).to respond_to :authenticate_super_admin_from_token!
339
+ end
340
+
341
+ it 'does not respond to :authenticate_user_from_token', protected: true do
342
+ expect(subject.new).not_to respond_to :authenticate_user_from_token
343
+ end
344
+
345
+ it 'does not respond to :authenticate_user_from_token!', protected: true do
346
+ expect(subject.new).not_to respond_to :authenticate_user_from_token!
347
+ end
348
+ end
349
+ end
350
+ end
351
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleTokenAuthentication::TokenComparator do
4
+
5
+ it_behaves_like 'a token comparator'
6
+
7
+ it 'delegates token comparison to Devise.secure_compare', private: true do
8
+ devise = double()
9
+ allow(devise).to receive(:secure_compare).and_return('Devise.secure_compare response.')
10
+ stub_const('Devise', devise)
11
+
12
+ # delegating consists in sending the message
13
+ expect(Devise).to receive(:secure_compare)
14
+ response = subject.compare('A_raNd0MtoKeN', 'ano4heR-Tok3n')
15
+
16
+ # and returning the response
17
+ expect(response).to eq 'Devise.secure_compare response.'
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleTokenAuthentication::TokenGenerator do
4
+
5
+ it_behaves_like 'a token generator'
6
+
7
+ it 'delegates token generation to Devise.friendly_token', private: true do
8
+ devise = double()
9
+ allow(devise).to receive(:friendly_token).and_return('FRi3ndlY_TokeN')
10
+ stub_const('Devise', devise)
11
+
12
+ # delegating consists in sending the message
13
+ expect(Devise).to receive(:friendly_token)
14
+ response = subject.generate_token
15
+
16
+ # and returning the response
17
+ expect(response).to eq 'FRi3ndlY_TokeN'
18
+ end
19
+ end
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleTokenAuthentication do
4
+
5
+ it 'responds to :ensure_models_can_act_as_token_authenticatables', private: true do
6
+ expect(subject).to respond_to :ensure_models_can_act_as_token_authenticatables
7
+ end
8
+
9
+ it 'responds to :ensure_controllers_can_act_as_token_authentication_handlers', private: true do
10
+ expect(subject).to respond_to :ensure_controllers_can_act_as_token_authentication_handlers
11
+ end
12
+
13
+ context 'when ActiveRecord is available' do
14
+
15
+ before(:each) do
16
+ stub_const('ActiveRecord', Module.new)
17
+ stub_const('ActiveRecord::Base', Class.new)
18
+
19
+ # define a dummy ActiveRecord adapter
20
+ dummy_active_record_adapter = double()
21
+ allow(dummy_active_record_adapter).to receive(:base_class).and_return(ActiveRecord::Base)
22
+ stub_const('SimpleTokenAuthentication::Adapters::DummyActiveRecordAdapter',
23
+ dummy_active_record_adapter)
24
+ end
25
+
26
+ describe '#ensure_models_can_act_as_token_authenticatables' do
27
+
28
+ before(:each) do
29
+ class SimpleTokenAuthentication::DummyModel < ActiveRecord::Base; end
30
+ @dummy_model = SimpleTokenAuthentication::DummyModel
31
+
32
+ expect(@dummy_model.new).to be_instance_of SimpleTokenAuthentication::DummyModel
33
+ expect(@dummy_model.new).to be_kind_of ActiveRecord::Base
34
+ end
35
+
36
+ after(:each) do
37
+ SimpleTokenAuthentication.send(:remove_const, :DummyModel)
38
+ end
39
+
40
+ it 'allows any kind of ActiveRecord::Base to act as token authenticatable', private: true do
41
+ expect(@dummy_model).not_to respond_to :acts_as_token_authenticatable
42
+
43
+ subject.ensure_models_can_act_as_token_authenticatables [
44
+ SimpleTokenAuthentication::Adapters::DummyActiveRecordAdapter]
45
+
46
+ expect(@dummy_model).to respond_to :acts_as_token_authenticatable
47
+ end
48
+ end
49
+ end
50
+
51
+ context 'when Mongoid is available' do
52
+
53
+ before(:each) do
54
+ stub_const('Mongoid', Module.new)
55
+ stub_const('Mongoid::Document', Class.new)
56
+
57
+ # define a dummy Mongoid adapter
58
+ dummy_mongoid_adapter = double()
59
+ allow(dummy_mongoid_adapter).to receive(:base_class).and_return(Mongoid::Document)
60
+ stub_const('SimpleTokenAuthentication::Adapters::DummyMongoidAdapter',
61
+ dummy_mongoid_adapter)
62
+ end
63
+
64
+ describe '#ensure_models_can_act_as_token_authenticatables' do
65
+
66
+ before(:each) do
67
+ class SimpleTokenAuthentication::DummyModel < Mongoid::Document; end
68
+ @dummy_model = SimpleTokenAuthentication::DummyModel
69
+
70
+ expect(@dummy_model.new).to be_instance_of SimpleTokenAuthentication::DummyModel
71
+ expect(@dummy_model.new).to be_kind_of Mongoid::Document
72
+ end
73
+
74
+ after(:each) do
75
+ SimpleTokenAuthentication.send(:remove_const, :DummyModel)
76
+ end
77
+
78
+ it 'allows any kind of Mongoid::Document to act as token authenticatable', private: true do
79
+ expect(@dummy_model).not_to respond_to :acts_as_token_authenticatable
80
+
81
+ subject.ensure_models_can_act_as_token_authenticatables [
82
+ SimpleTokenAuthentication::Adapters::DummyMongoidAdapter]
83
+
84
+ expect(@dummy_model).to respond_to :acts_as_token_authenticatable
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'when no ORM, ODM or OxM is available' do
90
+
91
+ before(:each) do
92
+ stub_const('ActiveRecord', Module.new)
93
+ stub_const('Mongoid', Module.new)
94
+ end
95
+
96
+ describe '#load_available_adapters' do
97
+
98
+ it 'raises NoAdapterAvailableError', private: true do
99
+ allow(subject).to receive(:require).and_return(true)
100
+ hide_const('ActiveRecord')
101
+ hide_const('Mongoid')
102
+
103
+ expect do
104
+ subject.load_available_adapters SimpleTokenAuthentication.model_adapters
105
+ end.to raise_error SimpleTokenAuthentication::NoAdapterAvailableError
106
+ end
107
+ end
108
+ end
109
+
110
+ context 'when ActionController::Base is available' do
111
+
112
+ before(:each) do
113
+ stub_const('ActionController::Base', Class.new)
114
+
115
+ # define a dummy ActionController::Base (a.k.a 'Rails') adapter
116
+ dummy_rails_adapter = double()
117
+ allow(dummy_rails_adapter).to receive(:base_class).and_return(ActionController::Base)
118
+ stub_const('SimpleTokenAuthentication::Adapters::DummyRailsAdapter', dummy_rails_adapter)
119
+ end
120
+
121
+ describe '#ensure_controllers_can_act_as_token_authentication_handlers' do
122
+
123
+ before(:each) do
124
+ class SimpleTokenAuthentication::DummyController < ActionController::Base; end
125
+ @dummy_controller = SimpleTokenAuthentication::DummyController
126
+
127
+ expect(@dummy_controller.new).to be_instance_of SimpleTokenAuthentication::DummyController
128
+ expect(@dummy_controller.new).to be_kind_of ActionController::Base
129
+ end
130
+
131
+ after(:each) do
132
+ SimpleTokenAuthentication.send(:remove_const, :DummyController)
133
+ end
134
+
135
+ it 'allows any kind of ActionController::Base to acts as token authentication handler', private: true do
136
+ expect(@dummy_controller).not_to respond_to :acts_as_token_authentication_handler_for
137
+
138
+ subject.ensure_controllers_can_act_as_token_authentication_handlers [
139
+ SimpleTokenAuthentication::Adapters::DummyRailsAdapter]
140
+
141
+ expect(@dummy_controller).to respond_to :acts_as_token_authentication_handler_for
142
+ end
143
+ end
144
+ end
145
+
146
+ context 'when ActionController::API is available' do
147
+
148
+ before(:each) do
149
+ stub_const('ActionController::API', Class.new)
150
+
151
+ # define a dummy ActionController::API (a.k.a 'Rails API') adapter
152
+ dummy_rails_adapter = double()
153
+ allow(dummy_rails_adapter).to receive(:base_class).and_return(ActionController::API)
154
+ stub_const('SimpleTokenAuthentication::Adapters::DummyRailsAPIAdapter', dummy_rails_adapter)
155
+ end
156
+
157
+ describe '#ensure_controllers_can_act_as_token_authentication_handlers' do
158
+
159
+ before(:each) do
160
+ class SimpleTokenAuthentication::DummyController < ActionController::API; end
161
+ @dummy_controller = SimpleTokenAuthentication::DummyController
162
+
163
+ expect(@dummy_controller.new).to be_instance_of SimpleTokenAuthentication::DummyController
164
+ expect(@dummy_controller.new).to be_kind_of ActionController::API
165
+ end
166
+
167
+ after(:each) do
168
+ SimpleTokenAuthentication.send(:remove_const, :DummyController)
169
+ end
170
+
171
+ it 'allows any kind of ActionController::API to acts as token authentication handler', private: true do
172
+ expect(@dummy_controller).not_to respond_to :acts_as_token_authentication_handler_for
173
+
174
+ subject.ensure_controllers_can_act_as_token_authentication_handlers [
175
+ SimpleTokenAuthentication::Adapters::DummyRailsAPIAdapter]
176
+
177
+ expect(@dummy_controller).to respond_to :acts_as_token_authentication_handler_for
178
+ end
179
+ end
180
+ end
181
+ end