omniauth-identity 3.0.2 → 3.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,123 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ExampleModel
4
- include OmniAuth::Identity::Model
5
- end
6
-
7
3
  RSpec.describe OmniAuth::Identity::Model do
8
- context 'Class Methods' do
9
- subject { ExampleModel }
10
-
11
- describe '.locate' do
12
- it('is abstract') { expect { subject.locate('abc') }.to raise_error(NotImplementedError) }
4
+ before do
5
+ identity_test_klass = Class.new do
6
+ include OmniAuth::Identity::Model
13
7
  end
8
+ stub_const('IdentityTestClass', identity_test_klass)
9
+ end
14
10
 
15
- describe '.authenticate' do
16
- it 'calls locate and then authenticate' do
17
- mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
18
- allow(subject).to receive(:locate).with('email' => 'example').and_return(mocked_instance)
19
- expect(subject.authenticate({ 'email' => 'example' }, 'pass')).to eq('abbadoo')
20
- end
11
+ describe 'Class Methods' do
12
+ subject(:model_klass) { IdentityTestClass }
21
13
 
22
- it 'calls locate with additional scopes when provided' do
23
- mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
24
- allow(subject).to receive(:locate).with('email' => 'example',
25
- 'user_type' => 'admin').and_return(mocked_instance)
26
- expect(subject.authenticate({ 'email' => 'example', 'user_type' => 'admin' }, 'pass')).to eq('abbadoo')
27
- end
14
+ include_context 'model with class methods'
28
15
 
29
- it 'recovers gracefully if locate is nil' do
30
- allow(subject).to receive(:locate).and_return(nil)
31
- expect(subject.authenticate('blah', 'foo')).to be false
16
+ describe '::locate' do
17
+ it('is abstract') do
18
+ expect { model_klass.locate('email' => 'example') }.to raise_error(NotImplementedError)
32
19
  end
33
20
  end
34
21
  end
35
22
 
36
- context 'Instance Methods' do
37
- subject { ExampleModel.new }
23
+ describe 'Instance Methods' do
24
+ subject(:instance) { IdentityTestClass.new }
38
25
 
39
- describe '#authenticate' do
40
- it('is abstract') { expect { subject.authenticate('abc') }.to raise_error(NotImplementedError) }
41
- end
26
+ include_context 'instance with instance methods'
42
27
 
43
- describe '#uid' do
44
- it 'defaults to #id' do
45
- allow(subject).to receive(:respond_to?).with(:id).and_return(true)
46
- allow(subject).to receive(:id).and_return 'wakka-do'
47
- expect(subject.uid).to eq('wakka-do')
48
- end
49
-
50
- it 'stringifies it' do
51
- allow(subject).to receive(:id).and_return 123
52
- expect(subject.uid).to eq('123')
53
- end
54
-
55
- it 'raises NotImplementedError if #id is not defined' do
56
- allow(subject).to receive(:respond_to?).with(:id).and_return(false)
57
- expect { subject.uid }.to raise_error(NotImplementedError)
58
- end
28
+ describe '#authenticate' do
29
+ it('is abstract') { expect { instance.authenticate('my-password') }.to raise_error(NotImplementedError) }
59
30
  end
60
31
 
61
32
  describe '#auth_key' do
62
- it 'defaults to #email' do
63
- allow(subject).to receive(:respond_to?).with(:email).and_return(true)
64
- allow(subject).to receive(:email).and_return('bob@bob.com')
65
- expect(subject.auth_key).to eq('bob@bob.com')
66
- end
67
-
68
- it 'uses the class .auth_key' do
69
- subject.class.auth_key 'login'
70
- allow(subject).to receive(:login).and_return 'bob'
71
- expect(subject.auth_key).to eq('bob')
72
- subject.class.auth_key nil
73
- end
74
-
75
33
  it 'raises a NotImplementedError if the auth_key method is not defined' do
76
- expect { subject.auth_key }.to raise_error(NotImplementedError)
34
+ expect { instance.auth_key }.to raise_error(NotImplementedError)
77
35
  end
78
36
  end
79
37
 
80
38
  describe '#auth_key=' do
81
- it 'defaults to setting email' do
82
- allow(subject).to receive(:respond_to?).with(:email=).and_return(true)
83
- expect(subject).to receive(:email=).with 'abc'
84
-
85
- subject.auth_key = 'abc'
86
- end
87
-
88
- it 'uses a custom .auth_key if one is provided' do
89
- subject.class.auth_key 'login'
90
- allow(subject).to receive(:respond_to?).with(:login=).and_return(true)
91
- expect(subject).to receive(:login=).with('abc')
92
-
93
- subject.auth_key = 'abc'
94
- end
95
-
96
- it 'raises a NotImplementedError if the autH_key method is not defined' do
97
- expect { subject.auth_key = 'broken' }.to raise_error(NotImplementedError)
98
- end
99
- end
100
-
101
- describe '#info' do
102
- it 'includes attributes that are set' do
103
- allow(subject).to receive(:name).and_return('Bob Bobson')
104
- allow(subject).to receive(:nickname).and_return('bob')
105
-
106
- expect(subject.info).to eq({
107
- 'name' => 'Bob Bobson',
108
- 'nickname' => 'bob'
109
- })
110
- end
111
-
112
- it 'automaticallies set name off of nickname' do
113
- allow(subject).to receive(:nickname).and_return('bob')
114
- subject.info['name'] == 'bob'
115
- end
116
-
117
- it 'does not overwrite a provided name' do
118
- allow(subject).to receive(:name).and_return('Awesome Dude')
119
- allow(subject).to receive(:first_name).and_return('Frank')
120
- expect(subject.info['name']).to eq('Awesome Dude')
39
+ it 'raises a NotImplementedError if the auth_key method is not defined' do
40
+ expect { instance.auth_key = 'broken' }.to raise_error(NotImplementedError)
121
41
  end
122
42
  end
123
43
  end
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
3
+ require 'sqlite3'
4
+ require 'active_record'
5
+ require 'anonymous_active_record'
6
+
7
+ class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end
8
+
9
+ RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, sqlite3: true) do
4
10
  describe 'model', type: :model do
5
11
  subject(:model_klass) do
6
12
  AnonymousActiveRecord.generate(
7
13
  parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
8
- columns: %w[name provider],
14
+ columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
9
15
  connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
10
16
  ) do
11
17
  def flower
@@ -14,17 +20,20 @@ RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
14
20
  end
15
21
  end
16
22
 
17
- it 'delegates locate to the where query method' do
18
- allow(model_klass).to receive(:where).with('ham_sandwich' => 'open faced', 'category' => 'sandwiches',
19
- 'provider' => 'identity').and_return(['wakka'])
20
- expect(model_klass.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
23
+ include_context 'persistable model'
24
+
25
+ describe '::table_name' do
26
+ it 'does not use STI rules for its table name' do
27
+ expect(TestIdentity.table_name).to eq('test_identities')
28
+ end
21
29
  end
22
- end
23
30
 
24
- describe '#table_name' do
25
- class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end
26
- it 'does not use STI rules for its table name' do
27
- expect(TestIdentity.table_name).to eq('test_identities')
31
+ describe '::locate' do
32
+ it 'delegates locate to the where query method' do
33
+ allow(model_klass).to receive(:where).with('email' => 'open faced', 'category' => 'sandwiches',
34
+ 'provider' => 'identity').and_return(['wakka'])
35
+ expect(model_klass.locate('email' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
36
+ end
28
37
  end
29
38
  end
30
39
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sqlite3'
4
+ require 'sequel'
5
+
6
+ DB = Sequel.sqlite
7
+
8
+ RSpec.describe(OmniAuth::Identity::Models::Sequel, sqlite3: true) do
9
+ before(:all) do
10
+ # Connect to an in-memory sqlite3 database.
11
+ DB.create_table :sequel_test_identities do
12
+ primary_key :id
13
+ String :email, null: false
14
+ String :password_digest, null: false
15
+ end
16
+ end
17
+
18
+ before do
19
+ sequel_test_identity = Class.new(Sequel::Model(:sequel_test_identities)) do
20
+ include ::OmniAuth::Identity::Models::Sequel
21
+ end
22
+ stub_const('SequelTestIdentity', sequel_test_identity)
23
+ end
24
+
25
+ describe 'model', type: :model do
26
+ subject(:model_klass) { SequelTestIdentity }
27
+
28
+ include_context 'persistable model'
29
+
30
+ describe '::locate' do
31
+ it 'delegates to the where query method' do
32
+ allow(model_klass).to receive(:where).with('email' => 'open faced',
33
+ 'category' => 'sandwiches').and_return(['wakka'])
34
+ expect(model_klass.locate('email' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,14 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe OmniAuth::Strategies::Identity do
3
+ require 'sqlite3'
4
+ require 'active_record'
5
+ require 'anonymous_active_record'
6
+
7
+ RSpec.describe OmniAuth::Strategies::Identity, sqlite3: true do
4
8
  attr_accessor :app
5
9
 
6
- let(:auth_hash) { last_response.headers['env']['omniauth.auth'] }
7
- let(:identity_hash) { last_response.headers['env']['omniauth.identity'] }
10
+ let(:env_hash) { last_response.headers['env'] }
11
+ let(:auth_hash) { env_hash['omniauth.auth'] }
12
+ let(:identity_hash) { env_hash['omniauth.identity'] }
8
13
  let(:identity_options) { {} }
9
14
  let(:anon_ar) do
10
15
  AnonymousActiveRecord.generate(
11
- columns: %w[name provider],
16
+ parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
17
+ columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
12
18
  connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
13
19
  ) do
14
20
  def balloon
@@ -192,7 +198,7 @@ RSpec.describe OmniAuth::Strategies::Identity do
192
198
  end
193
199
  end
194
200
 
195
- context 'with successful creation' do
201
+ context 'with good identity' do
196
202
  let(:properties) do
197
203
  {
198
204
  name: 'Awesome Dude',
@@ -203,20 +209,71 @@ RSpec.describe OmniAuth::Strategies::Identity do
203
209
  }
204
210
  end
205
211
 
206
- before do
207
- allow(anon_ar).to receive('auth_key').and_return('email')
208
- m = double(uid: 'abc', name: 'Awesome Dude', email: 'awesome@example.com',
209
- info: { name: 'DUUUUDE!' }, persisted?: true)
210
- expect(anon_ar).to receive(:create).with(properties).and_return(m)
211
- end
212
-
213
212
  it 'sets the auth hash' do
214
213
  post '/auth/identity/register', properties
215
- expect(auth_hash['uid']).to eq('abc')
214
+ expect(auth_hash['uid']).to match(/\d+/)
215
+ expect(auth_hash['provider']).to eq('identity')
216
+ end
217
+
218
+ context 'with on_validation proc' do
219
+ let(:identity_options) do
220
+ { model: anon_ar, on_validation: on_validation_proc }
221
+ end
222
+ let(:on_validation_proc) do
223
+ lambda { |_env|
224
+ false
225
+ }
226
+ end
227
+
228
+ context 'when validation fails' do
229
+ it 'does not set the env hash' do
230
+ post '/auth/identity/register', properties
231
+ expect(env_hash).to eq(nil)
232
+ end
233
+
234
+ it 'renders registration form' do
235
+ post '/auth/identity/register', properties
236
+ expect(last_response.body).to be_include(described_class.default_options[:registration_form_title])
237
+ end
238
+
239
+ it 'displays validation failure message' do
240
+ post '/auth/identity/register', properties
241
+ expect(last_response.body).to be_include(described_class.default_options[:validation_failure_message])
242
+ end
243
+ end
244
+
245
+ context 'when validation succeeds' do
246
+ let(:on_validation_proc) do
247
+ lambda { |_env|
248
+ true
249
+ }
250
+ end
251
+
252
+ it 'sets the auth hash' do
253
+ post '/auth/identity/register', properties
254
+ expect(auth_hash['uid']).to match(/\d+/)
255
+ expect(auth_hash['provider']).to eq('identity')
256
+ end
257
+
258
+ it 'does not render registration form' do
259
+ post '/auth/identity/register', properties
260
+ expect(last_response.body).not_to be_include(described_class.default_options[:registration_form_title])
261
+ end
262
+
263
+ it 'does not display validation failure message' do
264
+ post '/auth/identity/register', properties
265
+ expect(last_response.body).not_to be_include(described_class.default_options[:validation_failure_message])
266
+ end
267
+
268
+ it 'does not display registration failure message' do
269
+ post '/auth/identity/register', properties
270
+ expect(last_response.body).not_to be_include(described_class.default_options[:registration_failure_message])
271
+ end
272
+ end
216
273
  end
217
274
  end
218
275
 
219
- context 'with invalid identity' do
276
+ context 'with bad identity' do
220
277
  let(:properties) do
221
278
  {
222
279
  name: 'Awesome Dude',
@@ -226,16 +283,17 @@ RSpec.describe OmniAuth::Strategies::Identity do
226
283
  provider: 'identity'
227
284
  }
228
285
  end
229
- let(:invalid_identity) { double(persisted?: false) }
286
+ let(:invalid_identity) { double(persisted?: false, save: false) }
230
287
 
231
288
  before do
232
- expect(anon_ar).to receive(:create).with(properties).and_return(invalid_identity)
289
+ expect(anon_ar).to receive(:new).with(properties).and_return(invalid_identity)
233
290
  end
234
291
 
235
292
  context 'default' do
236
293
  it 'shows registration form' do
237
294
  post '/auth/identity/register', properties
238
295
  expect(last_response.body).to be_include('Register Identity')
296
+ expect(last_response.body).to be_include('One or more fields were invalid')
239
297
  end
240
298
  end
241
299
 
@@ -250,6 +308,63 @@ RSpec.describe OmniAuth::Strategies::Identity do
250
308
  post '/auth/identity/register', properties
251
309
  expect(identity_hash).to eq(invalid_identity)
252
310
  expect(last_response.body).to be_include("FAIL'DOH!")
311
+ expect(last_response.body).not_to be_include('One or more fields were invalid')
312
+ end
313
+ end
314
+
315
+ context 'with on_validation proc' do
316
+ let(:identity_options) do
317
+ { model: anon_ar, on_validation: on_validation_proc }
318
+ end
319
+ let(:on_validation_proc) do
320
+ lambda { |_env|
321
+ false
322
+ }
323
+ end
324
+
325
+ context 'when validation fails' do
326
+ it 'does not set the env hash' do
327
+ post '/auth/identity/register', properties
328
+ expect(env_hash).to eq(nil)
329
+ end
330
+
331
+ it 'renders registration form' do
332
+ post '/auth/identity/register', properties
333
+ expect(last_response.body).to be_include(described_class.default_options[:registration_form_title])
334
+ end
335
+
336
+ it 'displays validation failure message' do
337
+ post '/auth/identity/register', properties
338
+ expect(last_response.body).to be_include(described_class.default_options[:validation_failure_message])
339
+ end
340
+ end
341
+
342
+ context 'when validation succeeds' do
343
+ let(:on_validation_proc) do
344
+ lambda { |_env|
345
+ true
346
+ }
347
+ end
348
+
349
+ it 'does not set the env hash' do
350
+ post '/auth/identity/register', properties
351
+ expect(env_hash).to eq(nil)
352
+ end
353
+
354
+ it 'renders registration form' do
355
+ post '/auth/identity/register', properties
356
+ expect(last_response.body).to be_include(described_class.default_options[:registration_form_title])
357
+ end
358
+
359
+ it 'does not display validation failure message' do
360
+ post '/auth/identity/register', properties
361
+ expect(last_response.body).not_to be_include(described_class.default_options[:validation_failure_message])
362
+ end
363
+
364
+ it 'display registration failure message' do
365
+ post '/auth/identity/register', properties
366
+ expect(last_response.body).to be_include(described_class.default_options[:registration_failure_message])
367
+ end
253
368
  end
254
369
  end
255
370
  end
data/spec/spec_helper.rb CHANGED
@@ -1,20 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # NOTE: mongoid and no_brainer can't be loaded at the same time.
4
+ # If you try it, one or both of them will not work.
5
+ # This is why the ORM specs are split into a separate directory and run in separate threads.
6
+
7
+ ENV['RUBY_ENV'] = 'test' # Used by NoBrainer
8
+ ENV['MONGOID_ENV'] = 'test' # Used by Mongoid
9
+
3
10
  ruby_version = Gem::Version.new(RUBY_VERSION)
4
11
  require 'simplecov' if ruby_version >= Gem::Version.new('2.7') && RUBY_ENGINE == 'ruby'
5
12
 
6
13
  require 'rack/test'
7
- require 'mongoid-rspec'
8
- require 'sqlite3'
9
- require 'anonymous_active_record'
14
+ require 'rspec/block_is_expected'
10
15
  require 'byebug' if RUBY_ENGINE == 'ruby'
11
16
 
12
17
  # This gem
13
18
  require 'omniauth/identity'
14
19
 
20
+ spec_root_matcher = %r{#{__dir__}/(.+)\.rb\Z}
21
+ Dir.glob(Pathname.new(__dir__).join('support/**/', '*.rb')).each { |f| require f.match(spec_root_matcher)[1] }
22
+
23
+ DEFAULT_PASSWORD = 'hang-a-left-at-the-diner'
24
+ DEFAULT_EMAIL = 'mojo@example.com'
25
+
15
26
  RSpec.configure do |config|
16
27
  config.include Rack::Test::Methods
17
- config.include Mongoid::Matchers, type: :model
28
+
29
+ # config.include ::Mongoid::Matchers, db: :mongodb
18
30
 
19
31
  # Enable flags like --only-failures and --next-failure
20
32
  config.example_status_persistence_file_path = '.rspec_status'