omniauth-identity 3.0.6 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 469e5989686f13b8e924e7efc5cfbd2f205a13d45da6410f454f2d0b14e884ea
4
- data.tar.gz: 38424bbbc877d8d18aa4a35916697c59b31379809e05e5ff620de0089f53759c
3
+ metadata.gz: 89bd05bb3cf63c0a47e41c8f955f9b076d5c6b4ae0704eda10819f801eaa6059
4
+ data.tar.gz: a272f35f9bcc0de8937279904e2bde912865b50ac3a7752dada19f0ec7d6868c
5
5
  SHA512:
6
- metadata.gz: 1458cc73c99ca0bb267f9730d5e64daa8d6b7460720dd5790d443292cc8e938434190fcaf55195e5f039ffd50286018045ac2e0ed8c9a8e83eb5cae5878dcb62
7
- data.tar.gz: 439a1bd2702a7d5a729be16ad65fdd079a6a867f9ffa26c823b63d675dcaf2127311097b4f51a8c42425c33aba1d490dc46abf92d4bdab6c0185e191952d244c
6
+ metadata.gz: 26286ae10ba06b45b815bd21892ac27378eb338e446f0dcbe96037a8aa51d4097b55243ae12f5feef133577b1d793ce4732f636f930a6773c6b7e154e6256b4c
7
+ data.tar.gz: 11fc92beba0b8b849c1ce15784870bf4318aeaea14e5c7172f9c26b1891e357ba9603106765a5b2554c20d177a17c5e820bdb01733de169f3e67ec192f8d42e4
data/CHANGELOG.md CHANGED
@@ -8,6 +8,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [3.0.7] - 2021-03-23
12
+
13
+ ### Fixed
14
+
15
+ - \[ActiveRecord\] Fixed [#110](https://github.com/omniauth/omniauth-identity/issues/110) which prevented `OmniAuth::Identity::Models::ActiveRecord`-based records from saving.
16
+ - \[CouchPotato\] Fixed `OmniAuth::Identity::Models::CouchPotato`'s `#save`.
17
+ - \[Sequel\] Fixed `OmniAuth::Identity::Models::Sequel`'s `#save`.
18
+ - \[Model\] Only define `::create`, `#save`, and `#persisted?` when not already defined.
19
+ - \[Model\] Restore original `info` functionality which set `name` based on `first_name`, `last_name`, or `nickname`
20
+
21
+ ### Changed
22
+
23
+ - Upgraded to a newer `OmniAuth::Identity::SecurePassword` ripped from [Rails 6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activemodel/lib/active_model/secure_password.rb)
24
+ - Aeons ago the original was ripped from Rails 3.1, and frozen in time.
25
+ While writing specs, it was discovered to be incompatible with this gem's Sequel adapter.
26
+ - Specs validate that the new version does work.
27
+ In any case, the ripped version is only used when the `has_secure_password` macro is not yet defined in the class.
28
+
29
+ ### Added
30
+
31
+ - New specs to cover real use cases and implementations of each ORM model adapter that ships with the gem:
32
+ - ActiveRecord (Polyglot - Many Relational Databases)
33
+ - Sequel (Polyglot - Many Relational Databases)
34
+ - CouchPotato (CouchDB)
35
+ - Mongoid (MongoDB)
36
+ - NoBrainer (RethinkDB)
37
+
38
+ ## [3.0.6] - 2021-03-20
39
+
40
+ ### Fixed
41
+
42
+ - Fix breaking changes introduced by [#108](https://github.com/omniauth/omniauth-identity/pull/108) which prevented `:on_validation` from firing
43
+
44
+ ### Added
45
+
46
+ - New (or finally documented) options:
47
+ - `:create_identity_link_text` defaults to `'Create an Identity'`
48
+ - `:registration_failure_message` defaults to `'One or more fields were invalid'`
49
+ - `:validation_failure_message` defaults to `'Validation failed'`
50
+ - `:title` defaults to `'Identity Verification'`
51
+ - `:registration_form_title` defaults to `'Register Identity'`
52
+
11
53
  ## [3.0.5] - 2021-03-19
12
54
 
13
55
  ### Fixed
data/README.md CHANGED
@@ -93,8 +93,8 @@ Just include `OmniAuth::Identity::Models::Sequel` mixin, and specify
93
93
  whatever else you will need.
94
94
 
95
95
  ```ruby
96
- class SequelTestIdentity < Sequel::Model
97
- include OmniAuth::Identity::Models::Sequel
96
+ class SequelTestIdentity < Sequel::Model(:identities)
97
+ include ::OmniAuth::Identity::Models::Sequel
98
98
  auth_key :email
99
99
  # whatever else you want!
100
100
  end
@@ -108,8 +108,8 @@ fields that you will need.
108
108
 
109
109
  ```ruby
110
110
  class Identity
111
- include Mongoid::Document
112
- include OmniAuth::Identity::Models::Mongoid
111
+ include ::Mongoid::Document
112
+ include ::OmniAuth::Identity::Models::Mongoid
113
113
 
114
114
  field :email, type: String
115
115
  field :name, type: String
@@ -124,8 +124,9 @@ fields that you will need.
124
124
 
125
125
  ```ruby
126
126
  class Identity
127
- include CouchPotato::Persistence
128
- include OmniAuth::Identity::Models::CouchPotatoModule
127
+ # NOTE: CouchPotato::Persistence must be included before OmniAuth::Identity::Models::CouchPotatoModule
128
+ include ::CouchPotato::Persistence
129
+ include ::OmniAuth::Identity::Models::CouchPotatoModule
129
130
 
130
131
  property :email
131
132
  property :password_digest
@@ -147,8 +148,8 @@ fields that you will need.
147
148
 
148
149
  ```ruby
149
150
  class Identity
150
- include NoBrainer::Document
151
- include OmniAuth::Identity::Models::NoBrainer
151
+ include ::NoBrainer::Document
152
+ include ::OmniAuth::Identity::Models::NoBrainer
152
153
 
153
154
  auth_key :email
154
155
  end
@@ -265,6 +266,49 @@ option :locate_conditions, ->(req) { { model.auth_key => req['auth_key'] } }
265
266
 
266
267
  Please contribute some documentation if you have the gumption! The maintainer's time is limited, and sometimes the authors of PRs with new options don't update the _this_ readme. 😭
267
268
 
269
+ ## Contributing
270
+
271
+ 1. Fork it
272
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
273
+ 3. Commit your changes (`git commit -am ‘Added some feature’`)
274
+ 4. Push to the branch (`git push origin my-new-feature`)
275
+ 5. Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
276
+ - NOTE: In order to run *all* the tests you will need to have the following databases installed, configured, and running.
277
+ 1. [RethinkDB](https://rethinkdb.com), an open source, real-time, web database, [installed](https://rethinkdb.com/docs/install/) and [running](https://rethinkdb.com/docs/start-a-server/), e.g.
278
+ ```bash
279
+ brew install rethinkdb
280
+ rethinkdb
281
+ ```
282
+ 2. [MongoDB](https://docs.mongodb.com/manual/administration/install-community/)
283
+ ```bash
284
+ brew tap mongodb/brew
285
+ brew install mongodb-community@4.4
286
+ mongod --config /usr/local/etc/mongod.conf
287
+ ```
288
+ 3. [CouchDB](https://couchdb.apache.org) (download the .app)
289
+ To run all tests on all databases:
290
+ ```bash
291
+ bundle exec rake
292
+ ```
293
+ To run a specific DB:
294
+ ```bash
295
+ # CouchDB / CouchPotato
296
+ bundle exec rspec spec spec_orms --tag 'couchdb'
297
+
298
+ # ActiveRecord and Sequel, as they both use the in-memory SQLite driver.
299
+ bundle exec rspec spec spec_orms --tag 'sqlite3'
300
+
301
+ # NOTE - mongoid and nobrainer specs can't be isolated with "tag" because it still loads everything,
302
+ # and the two libraries are fundamentally incompatible.
303
+
304
+ # MongoDB / Mongoid
305
+ bundle exec rspec spec_orms/mongoid_spec.rb
306
+
307
+ # RethinkDB / NoBrainer
308
+ bundle exec rspec spec_orms/nobrainer_spec.rb
309
+ ```
310
+ 6. Create new Pull Request
311
+
268
312
  ## License
269
313
 
270
314
  MIT License. See LICENSE for details.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAuth
4
4
  module Identity
5
- VERSION = '3.0.6'
5
+ VERSION = '3.0.7'
6
6
  end
7
7
  end
@@ -14,7 +14,7 @@ module OmniAuth
14
14
  autoload :ActiveRecord, 'omniauth/identity/models/active_record'
15
15
  autoload :Mongoid, 'omniauth/identity/models/mongoid'
16
16
  autoload :CouchPotatoModule, 'omniauth/identity/models/couch_potato'
17
- autoload :NoBrainer, 'omniauth/identity/models/no_brainer'
17
+ autoload :NoBrainer, 'omniauth/identity/models/nobrainer'
18
18
  autoload :Sequel, 'omniauth/identity/models/sequel'
19
19
  end
20
20
  end
@@ -25,11 +25,13 @@ module OmniAuth
25
25
 
26
26
  def self.included(base)
27
27
  base.extend ClassMethods
28
+ base.extend ClassCreateApi unless base.respond_to?(:create)
29
+ im = base.instance_methods
30
+ base.include InstanceSaveApi unless im.include?(:save)
31
+ base.include InstancePersistedApi unless im.include?(:persisted?)
28
32
  end
29
33
 
30
34
  module ClassMethods
31
- extend Gem::Deprecate
32
-
33
35
  # Authenticate a user with the given key and password.
34
36
  #
35
37
  # @param [String] key The unique login key provided for a given identity.
@@ -52,52 +54,55 @@ module OmniAuth
52
54
  @auth_key || 'email'
53
55
  end
54
56
 
57
+ # Locate an identity given its unique login key.
58
+ #
59
+ # @abstract
60
+ # @param [String] key The unique login key.
61
+ # @return [Model] An instance of the identity model class.
62
+ def locate(_key)
63
+ raise NotImplementedError
64
+ end
65
+ end
66
+
67
+ module ClassCreateApi
55
68
  # Persists a new Identity object to the ORM.
56
- # Defaults to calling super. Override as needed per ORM.
69
+ # Only included if the class doesn't define create, as a reminder to define create.
70
+ # Override as needed per ORM.
57
71
  #
58
72
  # @deprecated v4.0 will begin using {#new} with {#save} instead.
59
73
  # @abstract
60
74
  # @param [Hash] args Attributes of the new instance.
61
75
  # @return [Model] An instance of the identity model class.
62
76
  # @since 3.0.5
63
- def create(*args)
64
- raise NotImplementedError unless defined?(super)
65
-
66
- super
77
+ def create(*_args)
78
+ raise NotImplementedError
67
79
  end
80
+ end
68
81
 
69
- # Locate an identity given its unique login key.
82
+ module InstanceSaveApi
83
+ # Persists a new Identity object to the ORM.
84
+ # Default raises an error. Override as needed per ORM.
85
+ # This base version's arguments are modeled after ActiveModel
86
+ # since it is a pattern many ORMs follow
70
87
  #
71
88
  # @abstract
72
- # @param [String] key The unique login key.
73
89
  # @return [Model] An instance of the identity model class.
74
- def locate(key)
90
+ # @since 3.0.5
91
+ def save(**_options, &_block)
75
92
  raise NotImplementedError
76
93
  end
77
94
  end
78
95
 
79
- # Persists a new Identity object to the ORM.
80
- # Default raises an error. Override as needed per ORM.
81
- #
82
- # @abstract
83
- # @return [Model] An instance of the identity model class.
84
- # @since 3.0.5
85
- def save
86
- raise NotImplementedError unless defined?(super)
87
-
88
- super
89
- end
90
-
91
- # Checks if the Identity object is persisted in the ORM.
92
- # Defaults to calling super. Override as needed per ORM.
93
- #
94
- # @abstract
95
- # @return [true or false] true if object exists, false if not.
96
- # @since 3.0.5
97
- def persisted?
98
- raise NotImplementedError unless defined?(super)
99
-
100
- super
96
+ module InstancePersistedApi
97
+ # Checks if the Identity object is persisted in the ORM.
98
+ # Default raises an error. Override as needed per ORM.
99
+ #
100
+ # @abstract
101
+ # @return [true or false] true if object exists, false if not.
102
+ # @since 3.0.5
103
+ def persisted?
104
+ raise NotImplementedError
105
+ end
101
106
  end
102
107
 
103
108
  # Returns self if the provided password is correct, false
@@ -106,7 +111,7 @@ module OmniAuth
106
111
  # @abstract
107
112
  # @param [String] password The password to check.
108
113
  # @return [self or false] Self if authenticated, false if not.
109
- def authenticate(password)
114
+ def authenticate(_password)
110
115
  raise NotImplementedError
111
116
  end
112
117
 
@@ -163,9 +168,13 @@ module OmniAuth
163
168
  #
164
169
  # @return [Hash] A string-keyed hash of user information.
165
170
  def info
166
- SCHEMA_ATTRIBUTES.each_with_object({}) do |attribute, hash|
171
+ info = {}
172
+ SCHEMA_ATTRIBUTES.each_with_object(info) do |attribute, hash|
167
173
  hash[attribute] = send(attribute) if respond_to?(attribute)
168
174
  end
175
+ info['name'] ||= [info['first_name'], info['last_name']].join(' ').strip if info['first_name'] || info['last_name']
176
+ info['name'] ||= info['nickname']
177
+ info
169
178
  end
170
179
  end
171
180
  end
@@ -6,8 +6,8 @@ module OmniAuth
6
6
  module Identity
7
7
  module Models
8
8
  class ActiveRecord < ::ActiveRecord::Base
9
- include OmniAuth::Identity::Model
10
- include OmniAuth::Identity::SecurePassword
9
+ include ::OmniAuth::Identity::Model
10
+ include ::OmniAuth::Identity::SecurePassword
11
11
 
12
12
  self.abstract_class = true
13
13
  has_secure_password
@@ -7,6 +7,7 @@ module OmniAuth
7
7
  module Models
8
8
  # can not be named CouchPotato since there is a class with that name
9
9
  # NOTE: CouchPotato is based on ActiveModel.
10
+ # NOTE: CouchPotato::Persistence must be included before OmniAuth::Identity::Models::CouchPotatoModule
10
11
  module CouchPotatoModule
11
12
  def self.included(base)
12
13
  base.class_eval do
@@ -23,6 +24,10 @@ module OmniAuth
23
24
  def self.locate(search_hash)
24
25
  where(search_hash).first
25
26
  end
27
+
28
+ def save
29
+ CouchPotato.database.save(self)
30
+ end
26
31
  end
27
32
  end
28
33
  end
@@ -6,9 +6,9 @@ module OmniAuth
6
6
  module Identity
7
7
  module Models
8
8
  # http://sequel.jeremyevans.net/ an SQL ORM
9
- # NOTE: Sequel is *not* based on ActiveModel, but supports the API we need, except for `persisted`:
9
+ # NOTE: Sequel is *not* based on ActiveModel, but supports the API we need, except for `persisted?`:
10
10
  # * create
11
- # * save, but save is deprecated in favor of `save_changes`
11
+ # * save
12
12
  module Sequel
13
13
  def self.included(base)
14
14
  base.class_eval do
@@ -17,7 +17,7 @@ module OmniAuth
17
17
  # plugin :validation_helpers
18
18
  plugin :validation_class_methods
19
19
 
20
- include OmniAuth::Identity::Model
20
+ include ::OmniAuth::Identity::Model
21
21
  include ::OmniAuth::Identity::SecurePassword
22
22
 
23
23
  has_secure_password
@@ -38,7 +38,7 @@ module OmniAuth
38
38
  end
39
39
 
40
40
  def save
41
- save_changes
41
+ super
42
42
  end
43
43
  end
44
44
  end
@@ -4,7 +4,7 @@ require 'bcrypt'
4
4
 
5
5
  module OmniAuth
6
6
  module Identity
7
- # This is taken directly from Rails 3.1 code and is used if
7
+ # This is lightly edited from Rails 6.1 code and is used if
8
8
  # the version of ActiveModel that's being used does not
9
9
  # include SecurePassword. The only difference is that instead of
10
10
  # using ActiveSupport::Concern, it checks to see if there is already
@@ -14,63 +14,124 @@ module OmniAuth
14
14
  base.extend ClassMethods unless base.respond_to?(:has_secure_password)
15
15
  end
16
16
 
17
+ # BCrypt hash function can handle maximum 72 bytes, and if we pass
18
+ # password of length more than 72 bytes it ignores extra characters.
19
+ # Hence need to put a restriction on password length.
20
+ MAX_PASSWORD_LENGTH_ALLOWED = 72
21
+
22
+ class << self
23
+ attr_accessor :min_cost # :nodoc:
24
+ end
25
+ self.min_cost = false
26
+
17
27
  module ClassMethods
18
28
  # Adds methods to set and authenticate against a BCrypt password.
19
- # This mechanism requires you to have a password_digest attribute.
29
+ # This mechanism requires you to have a +XXX_digest+ attribute.
30
+ # Where +XXX+ is the attribute name of your desired password.
31
+ #
32
+ # The following validations are added automatically:
33
+ # * Password must be present on creation
34
+ # * Password length should be less than or equal to 72 bytes
35
+ # * Confirmation of password (using a +XXX_confirmation+ attribute)
20
36
  #
21
- # Validations for presence of password, confirmation of password (using
22
- # a "password_confirmation" attribute) are automatically added.
23
- # You can add more validations by hand if need be.
37
+ # If confirmation validation is not needed, simply leave out the
38
+ # value for +XXX_confirmation+ (i.e. don't provide a form field for
39
+ # it). When this attribute has a +nil+ value, the validation will not be
40
+ # triggered.
41
+ #
42
+ # For further customizability, it is possible to suppress the default
43
+ # validations by passing <tt>validations: false</tt> as an argument.
44
+ #
45
+ # Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password:
46
+ #
47
+ # gem 'bcrypt', '~> 3.1.7'
24
48
  #
25
49
  # Example using Active Record (which automatically includes ActiveModel::SecurePassword):
26
50
  #
27
- # # Schema: User(name:string, password_digest:string)
51
+ # # Schema: User(name:string, password_digest:string, recovery_password_digest:string)
28
52
  # class User < ActiveRecord::Base
29
53
  # has_secure_password
54
+ # has_secure_password :recovery_password, validations: false
30
55
  # end
31
56
  #
32
- # user = User.new(:name => "david", :password => "", :password_confirmation => "nomatch")
33
- # user.save # => false, password required
34
- # user.password = "mUc3m00RsqyRe"
35
- # user.save # => false, confirmation doesn't match
36
- # user.password_confirmation = "mUc3m00RsqyRe"
37
- # user.save # => true
38
- # user.authenticate("notright") # => false
39
- # user.authenticate("mUc3m00RsqyRe") # => user
40
- # User.find_by_name("david").try(:authenticate, "notright") # => nil
41
- # User.find_by_name("david").try(:authenticate, "mUc3m00RsqyRe") # => user
42
- def has_secure_password
43
- attr_reader :password
57
+ # user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
58
+ # user.save # => false, password required
59
+ # user.password = 'mUc3m00RsqyRe'
60
+ # user.save # => false, confirmation doesn't match
61
+ # user.password_confirmation = 'mUc3m00RsqyRe'
62
+ # user.save # => true
63
+ # user.recovery_password = "42password"
64
+ # user.recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC"
65
+ # user.save # => true
66
+ # user.authenticate('notright') # => false
67
+ # user.authenticate('mUc3m00RsqyRe') # => user
68
+ # user.authenticate_recovery_password('42password') # => user
69
+ # User.find_by(name: 'david')&.authenticate('notright') # => false
70
+ # User.find_by(name: 'david')&.authenticate('mUc3m00RsqyRe') # => user
71
+ def has_secure_password(attribute = :password, validations: true)
72
+ # Load bcrypt gem only when has_secure_password is used.
73
+ # This is to avoid ActiveModel (and by extension the entire framework)
74
+ # being dependent on a binary library.
75
+ begin
76
+ require 'bcrypt'
77
+ rescue LoadError
78
+ warn "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install"
79
+ raise
80
+ end
44
81
 
45
- validates_confirmation_of :password
46
- validates_presence_of :password_digest
82
+ include InstanceMethodsOnActivation.new(attribute)
47
83
 
48
- include InstanceMethodsOnActivation
84
+ if validations
85
+ include ActiveModel::Validations
49
86
 
50
- if respond_to?(:attributes_protected_by_default)
51
- def self.attributes_protected_by_default
52
- super + ['password_digest']
87
+ # This ensures the model has a password by checking whether the password_digest
88
+ # is present, so that this works with both new and existing records. However,
89
+ # when there is an error, the message is added to the password attribute instead
90
+ # so that the error message will make sense to the end-user.
91
+ validate do |record|
92
+ record.errors.add(attribute, :blank) unless record.public_send("#{attribute}_digest").present?
53
93
  end
94
+
95
+ validates_length_of attribute, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
96
+ validates_confirmation_of attribute, allow_blank: true
54
97
  end
55
98
  end
56
99
  end
57
100
 
58
- module InstanceMethodsOnActivation
59
- # Returns self if the password is correct, otherwise false.
60
- def authenticate(unencrypted_password)
61
- if BCrypt::Password.new(password_digest) == unencrypted_password
62
- self
63
- else
64
- false
101
+ class InstanceMethodsOnActivation < Module
102
+ def initialize(attribute)
103
+ attr_reader attribute
104
+
105
+ define_method("#{attribute}=") do |unencrypted_password|
106
+ if unencrypted_password.nil?
107
+ public_send("#{attribute}_digest=", nil)
108
+ elsif !unencrypted_password.empty?
109
+ instance_variable_set("@#{attribute}", unencrypted_password)
110
+ cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
111
+ public_send("#{attribute}_digest=", BCrypt::Password.create(unencrypted_password, cost: cost))
112
+ end
65
113
  end
66
- end
67
114
 
68
- # Encrypts the password into the password_digest attribute.
69
- def password=(unencrypted_password)
70
- @password = unencrypted_password
71
- if unencrypted_password && !unencrypted_password.empty?
72
- self.password_digest = BCrypt::Password.create(unencrypted_password)
115
+ define_method("#{attribute}_confirmation=") do |unencrypted_password|
116
+ instance_variable_set("@#{attribute}_confirmation", unencrypted_password)
73
117
  end
118
+
119
+ # Returns +self+ if the password is correct, otherwise +false+.
120
+ #
121
+ # class User < ActiveRecord::Base
122
+ # has_secure_password validations: false
123
+ # end
124
+ #
125
+ # user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
126
+ # user.save
127
+ # user.authenticate_password('notright') # => false
128
+ # user.authenticate_password('mUc3m00RsqyRe') # => user
129
+ define_method("authenticate_#{attribute}") do |unencrypted_password|
130
+ attribute_digest = public_send("#{attribute}_digest")
131
+ BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
132
+ end
133
+
134
+ alias_method :authenticate, :authenticate_password if attribute == :password
74
135
  end
75
136
  end
76
137
  end
@@ -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,6 +1,12 @@
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(
@@ -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
@@ -1,23 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sqlite3'
3
4
  require 'sequel'
4
- # Connect to an in-memory sqlite3 database.
5
+
5
6
  DB = Sequel.sqlite
6
- DB.create_table :sequel_test_identities do
7
- primary_key :id
8
- String :ham_sandwich, null: false
9
- String :password_digest, null: false
10
- end
11
7
 
12
- class SequelTestIdentity < Sequel::Model
13
- include OmniAuth::Identity::Models::Sequel
14
- auth_key :ham_sandwich
15
- end
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'
16
29
 
17
- RSpec.describe(OmniAuth::Identity::Models::Sequel, db: true) do
18
- it 'delegates locate to the where query method' do
19
- allow(SequelTestIdentity).to receive(:where).with('ham_sandwich' => 'open faced',
20
- 'category' => 'sandwiches').and_return(['wakka'])
21
- expect(SequelTestIdentity.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
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
22
37
  end
23
38
  end
@@ -1,6 +1,10 @@
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
10
  let(:env_hash) { last_response.headers['env'] }
data/spec/spec_helper.rb CHANGED
@@ -1,21 +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 'sequel'
10
- require 'anonymous_active_record'
14
+ require 'rspec/block_is_expected'
11
15
  require 'byebug' if RUBY_ENGINE == 'ruby'
12
16
 
13
17
  # This gem
14
18
  require 'omniauth/identity'
15
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
+
16
26
  RSpec.configure do |config|
17
27
  config.include Rack::Test::Methods
18
- config.include Mongoid::Matchers, type: :model
28
+
29
+ # config.include ::Mongoid::Matchers, db: :mongodb
19
30
 
20
31
  # Enable flags like --only-failures and --next-failure
21
32
  config.example_status_persistence_file_path = '.rspec_status'
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'instance with instance methods' do
4
+ describe '#initialize' do
5
+ it 'does not raise an error' do
6
+ block_is_expected.not_to raise_error
7
+ end
8
+ end
9
+
10
+ describe '#uid' do
11
+ it 'defaults to #id' do
12
+ allow(instance).to receive(:respond_to?).with(:id).and_return(true)
13
+ allow(instance).to receive(:id).and_return 'wakka-do'
14
+ expect(instance.uid).to eq('wakka-do')
15
+ end
16
+
17
+ it 'stringifies it' do
18
+ allow(instance).to receive(:id).and_return 123
19
+ expect(instance.uid).to eq('123')
20
+ end
21
+
22
+ it 'raises NotImplementedError if #id is not defined' do
23
+ allow(instance).to receive(:respond_to?).with(:id).and_return(false)
24
+ expect { instance.uid }.to raise_error(NotImplementedError)
25
+ end
26
+ end
27
+
28
+ describe '#auth_key' do
29
+ it 'defaults to #email' do
30
+ allow(instance).to receive(:respond_to?).with(:email).and_return(true)
31
+ allow(instance).to receive(:email).and_return('bob@bob.com')
32
+ expect(instance.auth_key).to eq('bob@bob.com')
33
+ end
34
+
35
+ it 'uses the class .auth_key' do
36
+ instance.class.auth_key 'login'
37
+ allow(instance).to receive(:login).and_return 'bob'
38
+ expect(instance.auth_key).to eq('bob')
39
+ instance.class.auth_key nil
40
+ end
41
+ end
42
+
43
+ describe '#auth_key=' do
44
+ it 'defaults to setting email' do
45
+ allow(instance).to receive(:respond_to?).with(:email=).and_return(true)
46
+ expect(instance).to receive(:email=).with 'abc'
47
+
48
+ instance.auth_key = 'abc'
49
+ end
50
+
51
+ it 'uses a custom .auth_key if one is provided' do
52
+ instance.class.auth_key 'login'
53
+ allow(instance).to receive(:respond_to?).with(:login=).and_return(true)
54
+ expect(instance).to receive(:login=).with('abc')
55
+
56
+ instance.auth_key = 'abc'
57
+ end
58
+ end
59
+
60
+ describe '#info' do
61
+ it 'includes all attributes as they have been set' do
62
+ allow(instance).to receive(:name).and_return('Bob Bobson')
63
+ allow(instance).to receive(:nickname).and_return('bob')
64
+
65
+ expect(instance.info).to include({
66
+ 'name' => 'Bob Bobson',
67
+ 'nickname' => 'bob'
68
+ })
69
+ end
70
+
71
+ it 'uses firstname and lastname, over nickname, to set missing name' do
72
+ allow(instance).to receive(:first_name).and_return('shoeless')
73
+ allow(instance).to receive(:last_name).and_return('joe')
74
+ allow(instance).to receive(:nickname).and_return('george')
75
+ instance.info['name'] == 'shoeless joe'
76
+ end
77
+
78
+ it 'uses nickname to set missing name when first and last are not set' do
79
+ allow(instance).to receive(:nickname).and_return('bob')
80
+ instance.info['name'] == 'bob'
81
+ end
82
+
83
+ it 'does not overwrite a provided name' do
84
+ allow(instance).to receive(:name).and_return('Awesome Dude')
85
+ allow(instance).to receive(:first_name).and_return('Frank')
86
+ expect(instance.info['name']).to eq('Awesome Dude')
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'model with class methods' do
4
+ describe 'class definition' do
5
+ it 'does not raise an error' do
6
+ block_is_expected.not_to raise_error
7
+ end
8
+ end
9
+
10
+ describe '::authenticate' do
11
+ it 'calls locate and then authenticate' do
12
+ mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
13
+ allow(model_klass).to receive(:locate).with('email' => 'example').and_return(mocked_instance)
14
+ expect(model_klass.authenticate({ 'email' => 'example' }, 'pass')).to eq('abbadoo')
15
+ end
16
+
17
+ it 'calls locate with additional scopes when provided' do
18
+ mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
19
+ allow(model_klass).to receive(:locate).with('email' => 'example',
20
+ 'user_type' => 'admin').and_return(mocked_instance)
21
+ expect(model_klass.authenticate({ 'email' => 'example', 'user_type' => 'admin' }, 'pass')).to eq('abbadoo')
22
+ end
23
+
24
+ it 'recovers gracefully if locate is nil' do
25
+ allow(model_klass).to receive(:locate).and_return(nil)
26
+ expect(model_klass.authenticate('blah', 'foo')).to be false
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_context 'persistable model' do
4
+ include_context 'model with class methods'
5
+
6
+ describe 'instance methods' do
7
+ subject(:instance) { model_klass.new }
8
+
9
+ include_context 'instance with instance methods'
10
+
11
+ describe '#save' do
12
+ subject(:save) do
13
+ instance.email = DEFAULT_EMAIL
14
+ instance.password = DEFAULT_PASSWORD
15
+ instance.password_confirmation = DEFAULT_PASSWORD
16
+ instance.save
17
+ end
18
+
19
+ it 'does not raise an error' do
20
+ save
21
+ end
22
+ end
23
+ end
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-identity
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.6
4
+ version: 3.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-03-21 00:00:00.000000000 Z
13
+ date: 2021-03-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bcrypt
@@ -40,54 +40,6 @@ dependencies:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
- - !ruby/object:Gem::Dependency
44
- name: anonymous_active_record
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '1.0'
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: 1.0.8
53
- type: :development
54
- prerelease: false
55
- version_requirements: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: '1.0'
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 1.0.8
63
- - !ruby/object:Gem::Dependency
64
- name: mongoid
65
- requirement: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '7'
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - "~>"
75
- - !ruby/object:Gem::Version
76
- version: '7'
77
- - !ruby/object:Gem::Dependency
78
- name: nobrainer
79
- requirement: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - "~>"
82
- - !ruby/object:Gem::Version
83
- version: '0'
84
- type: :development
85
- prerelease: false
86
- version_requirements: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - "~>"
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
43
  - !ruby/object:Gem::Dependency
92
44
  name: rack-test
93
45
  requirement: !ruby/object:Gem::Requirement
@@ -131,19 +83,19 @@ dependencies:
131
83
  - !ruby/object:Gem::Version
132
84
  version: '3'
133
85
  - !ruby/object:Gem::Dependency
134
- name: sequel
86
+ name: rspec-block_is_expected
135
87
  requirement: !ruby/object:Gem::Requirement
136
88
  requirements:
137
89
  - - "~>"
138
90
  - !ruby/object:Gem::Version
139
- version: '5'
91
+ version: '1.0'
140
92
  type: :development
141
93
  prerelease: false
142
94
  version_requirements: !ruby/object:Gem::Requirement
143
95
  requirements:
144
96
  - - "~>"
145
97
  - !ruby/object:Gem::Version
146
- version: '5'
98
+ version: '1.0'
147
99
  - !ruby/object:Gem::Dependency
148
100
  name: sqlite3
149
101
  requirement: !ruby/object:Gem::Requirement
@@ -175,19 +127,19 @@ files:
175
127
  - lib/omniauth/identity/models/active_record.rb
176
128
  - lib/omniauth/identity/models/couch_potato.rb
177
129
  - lib/omniauth/identity/models/mongoid.rb
178
- - lib/omniauth/identity/models/no_brainer.rb
130
+ - lib/omniauth/identity/models/nobrainer.rb
179
131
  - lib/omniauth/identity/models/sequel.rb
180
132
  - lib/omniauth/identity/secure_password.rb
181
133
  - lib/omniauth/strategies/identity.rb
182
134
  - spec/omniauth/identity/model_spec.rb
183
135
  - spec/omniauth/identity/models/active_record_spec.rb
184
- - spec/omniauth/identity/models/couch_potato_spec.rb
185
- - spec/omniauth/identity/models/mongoid_spec.rb
186
- - spec/omniauth/identity/models/no_brainer_spec.rb
187
136
  - spec/omniauth/identity/models/sequel_spec.rb
188
137
  - spec/omniauth/identity/secure_password_spec.rb
189
138
  - spec/omniauth/strategies/identity_spec.rb
190
139
  - spec/spec_helper.rb
140
+ - spec/support/shared_contexts/instance_with_instance_methods.rb
141
+ - spec/support/shared_contexts/model_with_class_methods.rb
142
+ - spec/support/shared_contexts/persistable_model.rb
191
143
  homepage: http://github.com/omniauth/omniauth-identity
192
144
  licenses:
193
145
  - MIT
@@ -208,17 +160,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
160
  - !ruby/object:Gem::Version
209
161
  version: 1.3.6
210
162
  requirements: []
211
- rubygems_version: 3.2.3
163
+ rubygems_version: 3.2.9
212
164
  signing_key:
213
165
  specification_version: 4
214
166
  summary: Traditional username/password based authentication system for OmniAuth
215
167
  test_files:
216
- - spec/omniauth/identity/model_spec.rb
168
+ - spec/spec_helper.rb
169
+ - spec/support/shared_contexts/persistable_model.rb
170
+ - spec/support/shared_contexts/model_with_class_methods.rb
171
+ - spec/support/shared_contexts/instance_with_instance_methods.rb
217
172
  - spec/omniauth/identity/models/active_record_spec.rb
218
- - spec/omniauth/identity/models/couch_potato_spec.rb
219
- - spec/omniauth/identity/models/mongoid_spec.rb
220
- - spec/omniauth/identity/models/no_brainer_spec.rb
221
173
  - spec/omniauth/identity/models/sequel_spec.rb
222
174
  - spec/omniauth/identity/secure_password_spec.rb
175
+ - spec/omniauth/identity/model_spec.rb
223
176
  - spec/omniauth/strategies/identity_spec.rb
224
- - spec/spec_helper.rb
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'couch_potato'
4
-
5
- class CouchPotatoTestIdentity
6
- include CouchPotato::Persistence
7
- include OmniAuth::Identity::Models::CouchPotatoModule
8
- auth_key :ham_sandwich
9
- end
10
-
11
- RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, db: true) do
12
- describe 'model', type: :model do
13
- subject { CouchPotatoTestIdentity }
14
-
15
- it 'delegates locate to the where query method' do
16
- allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
17
- 'category' => 'sandwiches').and_return(['wakka'])
18
- expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
19
- end
20
- end
21
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'mongoid'
4
-
5
- class MongoidTestIdentity
6
- include Mongoid::Document
7
- include OmniAuth::Identity::Models::Mongoid
8
- auth_key :ham_sandwich
9
- store_in database: 'db1', collection: 'mongoid_test_identities', client: 'secondary'
10
- end
11
-
12
- RSpec.describe(OmniAuth::Identity::Models::Mongoid, db: true) do
13
- describe 'model', type: :model do
14
- subject { MongoidTestIdentity }
15
-
16
- it { is_expected.to be_mongoid_document }
17
-
18
- it 'does not munge collection name' do
19
- expect(subject).to be_stored_in(database: 'db1', collection: 'mongoid_test_identities', client: 'secondary')
20
- end
21
-
22
- it 'delegates locate to the where query method' do
23
- allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
24
- 'category' => 'sandwiches').and_return(['wakka'])
25
- expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
26
- end
27
- end
28
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'nobrainer'
4
-
5
- class NobrainerTestIdentity
6
- include NoBrainer::Document
7
- include OmniAuth::Identity::Models::NoBrainer
8
- auth_key :ham_sandwich
9
- end
10
-
11
- RSpec.describe(OmniAuth::Identity::Models::NoBrainer, db: true) do
12
- it 'delegates locate to the where query method' do
13
- allow(NobrainerTestIdentity).to receive(:where).with('ham_sandwich' => 'open faced',
14
- 'category' => 'sandwiches').and_return(['wakka'])
15
- expect(NobrainerTestIdentity.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
16
- end
17
- end