mongoid_token_r 4.0.0

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.
@@ -0,0 +1,102 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
2
+
3
+ describe Mongoid::Token::Options do
4
+ before do
5
+ @options = Mongoid::Token::Options.new(
6
+ {
7
+ :length => 9999,
8
+ :retry_count => 8888,
9
+ :contains => :nonsense,
10
+ :field_name => :not_a_token
11
+ }
12
+ )
13
+ end
14
+
15
+ it "should have a length" do
16
+ @options.length.should == 9999
17
+ end
18
+
19
+ it "should default to a length of 4" do
20
+ Mongoid::Token::Options.new.length.should == 4
21
+ end
22
+
23
+ it "should have a retry count" do
24
+ @options.retry_count.should == 8888
25
+ end
26
+
27
+ it "should default to a retry count of 3" do
28
+ Mongoid::Token::Options.new.retry_count.should == 3
29
+ end
30
+
31
+ it "should have a list of characters to contain" do
32
+ @options.contains.should == :nonsense
33
+ end
34
+
35
+ it "should default to an alphanumeric set of characters to contain" do
36
+ Mongoid::Token::Options.new.contains.should == :alphanumeric
37
+ end
38
+
39
+ it "should have a field name" do
40
+ @options.field_name.should == :not_a_token
41
+ end
42
+
43
+ it "should default to a field name of 'token'" do
44
+ Mongoid::Token::Options.new.field_name.should == :token
45
+ end
46
+
47
+ it "should create a pattern" do
48
+ Mongoid::Token::Options.new.pattern.should == "%s4"
49
+ end
50
+
51
+ describe "override_to_param" do
52
+ it "should be an option" do
53
+ expect(Mongoid::Token::Options.new({:override_to_param => false}).override_to_param?).to eq false
54
+ end
55
+
56
+ it "should default to true" do
57
+ expect(Mongoid::Token::Options.new.override_to_param?).to eq true
58
+ end
59
+ end
60
+
61
+ describe "skip_finder" do
62
+ it "should be an option" do
63
+ expect(Mongoid::Token::Options.new({:skip_finders => true}).skip_finders?).to eq true
64
+ end
65
+
66
+ it "should default to false" do
67
+ expect(Mongoid::Token::Options.new.skip_finders?).to eq false
68
+ end
69
+ end
70
+
71
+ describe "id" do
72
+ context "when true" do
73
+ it "returns '_id' sa the field name" do
74
+ expect(Mongoid::Token::Options.new({id: true, field_name: :a_token}).field_name).to eq :_id
75
+ end
76
+ end
77
+
78
+ context "when false" do
79
+ it "returns the field_name option as the field name" do
80
+ expect(Mongoid::Token::Options.new({id: false, field_name: :a_token}).field_name).to eq :a_token
81
+ end
82
+ end
83
+ end
84
+
85
+ describe :generate_on_init do
86
+ it "defaults to false" do
87
+ expect(Mongoid::Token::Options.new({}).generate_on_init).to eq false
88
+ end
89
+
90
+ context "when id option set" do
91
+ it "is true" do
92
+ expect(Mongoid::Token::Options.new({id: true}).generate_on_init).to eq true
93
+ end
94
+ end
95
+
96
+ context "when id option is not set" do
97
+ it "is false" do
98
+ expect(Mongoid::Token::Options.new({id: false}).generate_on_init).to eq false
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,287 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. spec_helper])
2
+
3
+ describe Mongoid::Token do
4
+ after do
5
+ Object.send(:remove_const, :Document) if Object.constants.include?(:Document)
6
+ Object.send(:remove_const, :AnotherDocument) if Object.constants.include?(:AnotherDocument)
7
+ Object.send(:remove_const, :UntaintedDocument) if Object.constants.include?(:UntaintedDocument)
8
+ end
9
+
10
+ let(:document_class) do
11
+ class Document
12
+ include Mongoid::Document
13
+ include Mongoid::Token
14
+ end
15
+ Class.new(Document)
16
+ end
17
+
18
+ let(:document) do
19
+ document_class.create
20
+ end
21
+
22
+ describe "#token" do
23
+ describe "field" do
24
+ before(:each) { document_class.send(:token) }
25
+ it "should be created" do
26
+ expect(document).to have_field(:token)
27
+ end
28
+
29
+ it "should be indexed" do
30
+ index = document.index_specifications.first
31
+ expect(index.fields).to eq([:token])
32
+ expect(index.options).to have_key(:unique)
33
+ expect(index.options).to have_key(:sparse)
34
+ end
35
+ end
36
+
37
+ describe "options" do
38
+ it "should accept custom field names" do
39
+ document_class.send(:token, :field_name => :smells_as_sweet)
40
+ expect(document).to have_field(:smells_as_sweet)
41
+ end
42
+
43
+ it "should accept custom lengths" do
44
+ document_class.send(:token, :length => 13)
45
+ expect(document.token.length).to eq 13
46
+ end
47
+
48
+ it "should disable custom finders" do
49
+ class UntaintedDocument
50
+ include Mongoid::Document
51
+ include Mongoid::Token
52
+ end
53
+ dc = Class.new(UntaintedDocument)
54
+
55
+ dc.send(:token, :skip_finders => true)
56
+ expect(dc.public_methods).to_not include(:find_with_token)
57
+ end
58
+
59
+ it "should disable `to_param` overrides" do
60
+ document_class.send(:token, :override_to_param => false)
61
+ expect(document.to_param).to_not eq document.token
62
+ end
63
+
64
+ it "should return id when token does not exist when calling `to_param`" do
65
+ document_class.send(:token, :override_to_param => true)
66
+ document.unset :token
67
+ expect(document.to_param).to eq document.id.to_s
68
+ end
69
+
70
+ describe "contains" do
71
+ context "with :alphanumeric" do
72
+ it "should contain only letters and numbers" do
73
+ document_class.send(:token, :contains => :alphanumeric, :length => 64)
74
+ expect(document.token).to match(/[A-Za-z0-9]{64}/)
75
+ end
76
+ end
77
+ context "with :alpha" do
78
+ it "should contain only letters" do
79
+ document_class.send(:token, :contains => :alpha, :length => 64)
80
+ expect(document.token).to match(/[A-Za-z]{64}/)
81
+ end
82
+ end
83
+ context "with :alpha_upper" do
84
+ it "should contain only uppercase letters" do
85
+ document_class.send(:token, :contains => :alpha_upper, :length => 64)
86
+ expect(document.token).to match(/[A-Z]{64}/)
87
+ end
88
+ end
89
+ context "with :alpha_lower" do
90
+ it "should contain only lowercase letters" do
91
+ document_class.send(:token, :contains => :alpha_lower, :length => 64)
92
+ expect(document.token).to match(/[a-z]{64}/)
93
+ end
94
+ end
95
+ context "with :numeric" do
96
+ it "should only contain numbers" do
97
+ document_class.send(:token, :contains => :numeric, :length => 64)
98
+ expect(document.token).to match(/[0-9]{1,64}/)
99
+ end
100
+ end
101
+ context "with :fixed_numeric" do
102
+ it "should contain only numbers and be a fixed-length" do
103
+ document_class.send(:token, :contains => :fixed_numeric, :length => 64)
104
+ expect(document.token).to match(/[0-9]{64}/)
105
+ end
106
+ end
107
+ context "with :fixed_numeric_no_leading_zeros" do
108
+ it "should contain only numbers, be a fixed length, and have no leading zeros" do
109
+ document_class.send(:token, :contains => :fixed_numeric_no_leading_zeros, :length => 64)
110
+ expect(document.token).to match(/[1-9]{1}[0-9]{63}/)
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "pattern" do
116
+ it "should conform" do
117
+ document_class.send(:token, :pattern => "%d%d%d%d%C%C%C%C")
118
+ expect(document.token).to match(/[0-9]{4}[A-Z]{4}/)
119
+ end
120
+ context "when there's a static prefix" do
121
+ it "should start with the prefix" do
122
+ document_class.send(:token, :pattern => "PREFIX-%d%d%d%d")
123
+ expect(document.token).to match(/PREFIX\-[0-9]{4}/)
124
+ end
125
+ end
126
+ context "when there's an infix" do
127
+ it "should contain the infix" do
128
+ document_class.send(:token, :pattern => "%d%d%d%d-INFIX-%d%d%d%d")
129
+ expect(document.token).to match(/[0-9]{4}\-INFIX\-[0-9]{4}/)
130
+ end
131
+ end
132
+ context "when there's a suffix" do
133
+ it "should end with the suffix" do
134
+ document_class.send(:token, :pattern => "%d%d%d%d-SUFFIX")
135
+ expect(document.token).to match(/[0-9]{4}\-SUFFIX/)
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ it "should allow for multiple tokens of different names" do
142
+ document_class.send(:token, :contains => :alpha_upper)
143
+ document_class.send(:token, :field_name => :sharing_id, :contains => :alpha_lower)
144
+ expect(document.token).to match(/[A-Z]{4}/)
145
+ expect(document.sharing_id).to match(/[a-z]{4}/)
146
+ end
147
+ end
148
+
149
+ describe "callbacks" do
150
+ context "when the document is a new record" do
151
+ let(:document){ document_class.new }
152
+ it "should create the token after being saved" do
153
+ document_class.send(:token)
154
+ expect(document.token).to be_nil
155
+ document.save
156
+ expect(document.token).to_not be_nil
157
+ end
158
+ end
159
+ context "when the document is not a new record" do
160
+ it "should not change the token after being saved" do
161
+ document_class.send(:token)
162
+ token_before = document.token
163
+ document.save
164
+ expect(document.token).to eq token_before
165
+ end
166
+ context "and the token is nil" do
167
+ it "should create a new token after being saved" do
168
+ document_class.send(:token)
169
+ token_before = document.token
170
+ document.token = nil
171
+ document.save
172
+ expect(document.token).to_not be_nil
173
+ expect(document.token).to_not eq token_before
174
+ end
175
+ end
176
+ context "when the document is initialized with a token" do
177
+ it "should not change the token after being saved" do
178
+ document_class.send(:token)
179
+ token = 'test token'
180
+ expect(document_class.create!(token: token).token).to eq token
181
+ end
182
+ end
183
+ end
184
+ context "when the document is cloned" do
185
+ it "should set the token to nil" do
186
+ document.class.send(:token, :length => 64, :contains => :alpha_upper)
187
+ d2 = document.clone
188
+ expect(d2.token).to be_nil
189
+ end
190
+
191
+ it "should generate a new token with the same options as the source document" do
192
+ document.class.send(:token, :length => 64, :contains => :alpha_upper)
193
+ d2 = document.clone
194
+ d2.save
195
+ expect(d2.token).to_not eq document.token
196
+ expect(d2.token).to match(/[A-Z]{64}/)
197
+ end
198
+ end
199
+ end
200
+
201
+ describe "finders" do
202
+ it "should create a custom find method" do
203
+ document_class.send(:token, :field_name => :other_token)
204
+ expect(document.class.public_methods).to include(:find_by_other_token)
205
+ end
206
+ end
207
+
208
+ describe ".to_param" do
209
+ it "should return the token" do
210
+ document_class.send(:token)
211
+ expect(document.to_param).to eq document.token
212
+ end
213
+ end
214
+
215
+ describe "collision resolution" do
216
+ before(:each) do
217
+ document_class.send(:token)
218
+ document_class.create_indexes
219
+ end
220
+
221
+ context "when creating a new record" do
222
+ it "should raise an exception when collisions can't be resolved on save" do
223
+ document.token = "1234"
224
+ document.save
225
+ d2 = document.clone
226
+ d2.stub(:generate_token).and_return("1234")
227
+ expect{d2.save}.to raise_exception(Mongoid::Token::CollisionRetriesExceeded)
228
+ end
229
+
230
+ it "should raise an exception when collisions can't be resolved on create!" do
231
+ document.token = "1234"
232
+ document.save
233
+ document_class.any_instance.stub(:generate_token).and_return("1234")
234
+ expect{document_class.create!}.to raise_exception(Mongoid::Token::CollisionRetriesExceeded)
235
+ end
236
+ end
237
+
238
+ it "should not raise a custom error if another error is thrown during saving" do
239
+ I18n.enforce_available_locales = false # Supress warnings in this example
240
+ document_class.send(:field, :name)
241
+ document_class.send(:validates_presence_of, :name)
242
+ document_class.any_instance.stub(:generate_token).and_return("1234")
243
+ document_class.stub(:model_name).and_return(ActiveModel::Name.new(document_class, nil, "temp"))
244
+ expect{document_class.create!}.to raise_exception(Mongoid::Errors::Validations)
245
+ end
246
+
247
+ context "with other unique indexes present" do
248
+ before(:each) do
249
+ document_class.send(:field, :name)
250
+ document_class.send(:index, {:name => 1}, {:unique => true})
251
+ document_class.create_indexes
252
+ end
253
+
254
+ context "when violating the other index" do
255
+ it "should raise an operation failure" do
256
+ duplicate_name = "Got Duped."
257
+ document_class.create!(:name => duplicate_name)
258
+ expect{ document_class.create!(:name => duplicate_name) }.to raise_exception(Mongo::Error::OperationFailure)
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ describe "with overriden id" do
265
+ # Capture warnings about overriding _id, for cleaner test output
266
+ before do
267
+ @orig_stdout = $stdout
268
+ $stdout = StringIO.new
269
+ document_class.send(:token, id: true)
270
+ end
271
+
272
+ after do
273
+ $stdout = @orig_stdout
274
+ end
275
+
276
+ let(:document){ document_class.new }
277
+
278
+ it "should replace the _id field with a token" do
279
+ expect(document).to have_field(:_id)
280
+ expect(document).to_not have_field(:token)
281
+ end
282
+
283
+ it "should have a default token" do
284
+ expect(document.id).to_not be_blank
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,29 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
4
+ $: << File.expand_path("../../lib", __FILE__)
5
+
6
+ require 'database_cleaner'
7
+ require 'mongoid'
8
+ require 'mongoid-rspec'
9
+ require 'mongoid_token'
10
+
11
+ ENV['MONGOID_ENV'] = "test"
12
+
13
+ RSpec.configure do |config|
14
+ Mongo::Logger.logger.level = Logger::ERROR
15
+
16
+ config.include Mongoid::Matchers
17
+ config.before(:suite) do
18
+ DatabaseCleaner.strategy = :truncation
19
+ end
20
+
21
+ config.after(:each) do
22
+ DatabaseCleaner.clean
23
+ Mongoid.purge!
24
+ end
25
+ end
26
+
27
+ Mongoid.configure do |config|
28
+ config.connect_to("mongoid_token_test", {})
29
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_token_r
3
+ version: !ruby/object:Gem::Version
4
+ version: 4.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas Bruning
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mongoid
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ description: Mongoid token is a gem for creating random, unique tokens for mongoid
28
+ documents. Highly configurable and great for making URLs a little more compact.
29
+ email:
30
+ - nicholas@bruning.com.au
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".autotest"
36
+ - ".gitignore"
37
+ - ".rspec"
38
+ - ".travis.yml"
39
+ - Gemfile
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - benchmarks/benchmark.rb
44
+ - lib/mongoid/token.rb
45
+ - lib/mongoid/token/collision_resolver.rb
46
+ - lib/mongoid/token/collisions.rb
47
+ - lib/mongoid/token/exceptions.rb
48
+ - lib/mongoid/token/finders.rb
49
+ - lib/mongoid/token/generator.rb
50
+ - lib/mongoid/token/options.rb
51
+ - lib/mongoid_token.rb
52
+ - lib/version.rb
53
+ - mongoid_token.gemspec
54
+ - spec/mongoid/token/collisions_spec.rb
55
+ - spec/mongoid/token/exceptions_spec.rb
56
+ - spec/mongoid/token/finders_spec.rb
57
+ - spec/mongoid/token/generator_spec.rb
58
+ - spec/mongoid/token/options_spec.rb
59
+ - spec/mongoid/token_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: http://github.com/thetron/mongoid_token
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project: mongoid_token
81
+ rubygems_version: 2.4.8
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: A little random, unique token generator for Mongoid documents.
85
+ test_files:
86
+ - spec/mongoid/token/collisions_spec.rb
87
+ - spec/mongoid/token/exceptions_spec.rb
88
+ - spec/mongoid/token/finders_spec.rb
89
+ - spec/mongoid/token/generator_spec.rb
90
+ - spec/mongoid/token/options_spec.rb
91
+ - spec/mongoid/token_spec.rb
92
+ - spec/spec_helper.rb