rollout 2.1.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/spec/rollout_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require "spec_helper"
2
2
 
3
- describe "Rollout" do
3
+ RSpec.describe "Rollout" do
4
4
  before do
5
5
  @redis = Redis.new
6
6
  @rollout = Rollout.new(@redis)
@@ -13,16 +13,16 @@ describe "Rollout" do
13
13
  end
14
14
 
15
15
  it "the feature is active for users for which the block evaluates to true" do
16
- @rollout.should be_active(:chat, stub(:id => 5))
16
+ expect(@rollout).to be_active(:chat, double(id: 5))
17
17
  end
18
18
 
19
19
  it "is not active for users for which the block evaluates to false" do
20
- @rollout.should_not be_active(:chat, stub(:id => 1))
20
+ expect(@rollout).not_to be_active(:chat, double(id: 1))
21
21
  end
22
22
 
23
23
  it "is not active if a group is found in Redis but not defined in Rollout" do
24
24
  @rollout.activate_group(:chat, :fake)
25
- @rollout.should_not be_active(:chat, stub(:id => 1))
25
+ expect(@rollout).not_to be_active(:chat, double(id: 1))
26
26
  end
27
27
  end
28
28
 
@@ -32,7 +32,7 @@ describe "Rollout" do
32
32
  end
33
33
 
34
34
  it "evaluates to true no matter what" do
35
- @rollout.should be_active(:chat, stub(:id => 0))
35
+ expect(@rollout).to be_active(:chat, double(id: 0))
36
36
  end
37
37
  end
38
38
 
@@ -47,11 +47,11 @@ describe "Rollout" do
47
47
  end
48
48
 
49
49
  it "deactivates the rules for that group" do
50
- @rollout.should_not be_active(:chat, stub(:id => 10))
50
+ expect(@rollout).not_to be_active(:chat, double(id: 10))
51
51
  end
52
52
 
53
53
  it "leaves the other groups active" do
54
- @rollout.get(:chat).groups.should == [:fivesonly]
54
+ expect(@rollout.get(:chat).groups).to eq [:fivesonly].to_set
55
55
  end
56
56
  end
57
57
 
@@ -60,40 +60,40 @@ describe "Rollout" do
60
60
  @rollout.define_group(:fivesonly) { |user| user.id == 5 }
61
61
  @rollout.activate_group(:chat, :all)
62
62
  @rollout.activate_group(:chat, :fivesonly)
63
- @rollout.activate_user(:chat, stub(:id => 51))
63
+ @rollout.activate_user(:chat, double(id: 51))
64
64
  @rollout.activate_percentage(:chat, 100)
65
65
  @rollout.activate(:chat)
66
66
  @rollout.deactivate(:chat)
67
67
  end
68
68
 
69
69
  it "removes all of the groups" do
70
- @rollout.should_not be_active(:chat, stub(:id => 0))
70
+ expect(@rollout).not_to be_active(:chat, double(id: 0))
71
71
  end
72
72
 
73
73
  it "removes all of the users" do
74
- @rollout.should_not be_active(:chat, stub(:id => 51))
74
+ expect(@rollout).not_to be_active(:chat, double(id: 51))
75
75
  end
76
76
 
77
77
  it "removes the percentage" do
78
- @rollout.should_not be_active(:chat, stub(:id => 24))
78
+ expect(@rollout).not_to be_active(:chat, double(id: 24))
79
79
  end
80
80
 
81
81
  it "removes globally" do
82
- @rollout.should_not be_active(:chat)
82
+ expect(@rollout).not_to be_active(:chat)
83
83
  end
84
84
  end
85
85
 
86
86
  describe "activating a specific user" do
87
87
  before do
88
- @rollout.activate_user(:chat, stub(:id => 42))
88
+ @rollout.activate_user(:chat, double(id: 42))
89
89
  end
90
90
 
91
91
  it "is active for that user" do
92
- @rollout.should be_active(:chat, stub(:id => 42))
92
+ expect(@rollout).to be_active(:chat, double(id: 42))
93
93
  end
94
94
 
95
95
  it "remains inactive for other users" do
96
- @rollout.should_not be_active(:chat, stub(:id => 24))
96
+ expect(@rollout).not_to be_active(:chat, double(id: 24))
97
97
  end
98
98
  end
99
99
 
@@ -103,43 +103,111 @@ describe "Rollout" do
103
103
  end
104
104
 
105
105
  it "is active for that user" do
106
- @rollout.should be_active(:chat, stub(:id => 42))
106
+ expect(@rollout).to be_active(:chat, double(id: 42))
107
107
  end
108
108
 
109
109
  it "remains inactive for other users" do
110
- @rollout.should_not be_active(:chat, stub(:id => 24))
110
+ expect(@rollout).not_to be_active(:chat, double(id: 24))
111
111
  end
112
112
  end
113
113
 
114
114
  describe "activating a specific user with a string id" do
115
115
  before do
116
- @rollout.activate_user(:chat, stub(:id => 'user-72'))
116
+ @rollout.activate_user(:chat, double(id: "user-72"))
117
117
  end
118
118
 
119
119
  it "is active for that user" do
120
- @rollout.should be_active(:chat, stub(:id => 'user-72'))
120
+ expect(@rollout).to be_active(:chat, double(id: "user-72"))
121
121
  end
122
122
 
123
123
  it "remains inactive for other users" do
124
- @rollout.should_not be_active(:chat, stub(:id => 'user-12'))
124
+ expect(@rollout).not_to be_active(:chat, double(id: "user-12"))
125
+ end
126
+ end
127
+
128
+ describe "activating a group of users" do
129
+ context "specified by user objects" do
130
+ let(:users) { [double(id: 1), double(id: 2), double(id: 3)] }
131
+
132
+ before { @rollout.activate_users(:chat, users) }
133
+
134
+ it "is active for the given users" do
135
+ users.each { |user| expect(@rollout).to be_active(:chat, user) }
136
+ end
137
+
138
+ it "remains inactive for other users" do
139
+ expect(@rollout).not_to be_active(:chat, double(id: 4))
140
+ end
141
+ end
142
+
143
+ context "specified by user ids" do
144
+ let(:users) { [1, 2, 3] }
145
+
146
+ before { @rollout.activate_users(:chat, users) }
147
+
148
+ it "is active for the given users" do
149
+ users.each { |user| expect(@rollout).to be_active(:chat, user) }
150
+ end
151
+
152
+ it "remains inactive for other users" do
153
+ expect(@rollout).not_to be_active(:chat, 4)
154
+ end
125
155
  end
126
156
  end
127
157
 
128
158
  describe "deactivating a specific user" do
129
159
  before do
130
- @rollout.activate_user(:chat, stub(:id => 42))
131
- @rollout.activate_user(:chat, stub(:id => 4242))
132
- @rollout.activate_user(:chat, stub(:id => 24))
133
- @rollout.deactivate_user(:chat, stub(:id => 42))
134
- @rollout.deactivate_user(:chat, stub(:id => "4242"))
160
+ @rollout.activate_user(:chat, double(id: 42))
161
+ @rollout.activate_user(:chat, double(id: 4242))
162
+ @rollout.activate_user(:chat, double(id: 24))
163
+ @rollout.deactivate_user(:chat, double(id: 42))
164
+ @rollout.deactivate_user(:chat, double(id: "4242"))
135
165
  end
136
166
 
137
167
  it "that user should no longer be active" do
138
- @rollout.should_not be_active(:chat, stub(:id => 42))
168
+ expect(@rollout).not_to be_active(:chat, double(id: 42))
139
169
  end
140
170
 
141
171
  it "remains active for other active users" do
142
- @rollout.get(:chat).users.should == %w(24)
172
+ expect(@rollout.get(:chat).users).to eq %w(24).to_set
173
+ end
174
+ end
175
+
176
+ describe "deactivating a group of users" do
177
+ context "specified by user objects" do
178
+ let(:active_users) { [double(id: 1), double(id: 2)] }
179
+ let(:inactive_users) { [double(id: 3), double(id: 4)] }
180
+
181
+ before do
182
+ @rollout.activate_users(:chat, active_users + inactive_users)
183
+ @rollout.deactivate_users(:chat, inactive_users)
184
+ end
185
+
186
+ it "is active for the active users" do
187
+ active_users.each { |user| expect(@rollout).to be_active(:chat, user) }
188
+ end
189
+
190
+ it "is not active for inactive users" do
191
+ inactive_users.each { |user| expect(@rollout).not_to be_active(:chat, user) }
192
+ end
193
+ end
194
+
195
+ context "specified by user ids" do
196
+ let(:active_users) { [1, 2] }
197
+ let(:inactive_users) { [3, 4] }
198
+
199
+ before do
200
+ @rollout.activate_users(:chat, active_users + inactive_users)
201
+ @rollout.deactivate_users(:chat, inactive_users)
202
+ end
203
+
204
+ it "is active for the active users" do
205
+ active_users.each { |user| expect(@rollout).to be_active(:chat, user) }
206
+ end
207
+
208
+ it "is not active for inactive users" do
209
+ inactive_users.each { |user| expect(@rollout).not_to be_active(:chat, user) }
210
+ end
143
211
  end
144
212
  end
145
213
 
@@ -149,7 +217,7 @@ describe "Rollout" do
149
217
  end
150
218
 
151
219
  it "activates the feature" do
152
- @rollout.should be_active(:chat)
220
+ expect(@rollout).to be_active(:chat)
153
221
  end
154
222
  end
155
223
 
@@ -159,7 +227,7 @@ describe "Rollout" do
159
227
  end
160
228
 
161
229
  it "activates the feature for that percentage of the users" do
162
- (1..120).select { |id| @rollout.active?(:chat, stub(:id => id)) }.length.should be_within(1).of(20)
230
+ expect((1..120).select { |id| @rollout.active?(:chat, double(id: id)) }.length).to be_within(1).of(20)
163
231
  end
164
232
  end
165
233
 
@@ -169,7 +237,7 @@ describe "Rollout" do
169
237
  end
170
238
 
171
239
  it "activates the feature for that percentage of the users" do
172
- (1..200).select { |id| @rollout.active?(:chat, stub(:id => id)) }.length.should be_within(5).of(40)
240
+ expect((1..200).select { |id| @rollout.active?(:chat, double(id: id)) }.length).to be_within(5).of(40)
173
241
  end
174
242
  end
175
243
 
@@ -179,22 +247,43 @@ describe "Rollout" do
179
247
  end
180
248
 
181
249
  it "activates the feature for that percentage of the users" do
182
- (1..100).select { |id| @rollout.active?(:chat, stub(:id => id)) }.length.should be_within(2).of(5)
250
+ expect((1..100).select { |id| @rollout.active?(:chat, double(id: id)) }.length).to be_within(2).of(5)
251
+ end
252
+ end
253
+
254
+ describe "activating a feature for a percentage of users" do
255
+ before do
256
+ @rollout.activate_percentage(:chat, 20)
257
+ @rollout.activate_percentage(:beta, 20)
258
+ @options = @rollout.instance_variable_get("@options")
259
+ end
260
+
261
+ it "activates the feature for a random set of users when opt is set" do
262
+ @options[:randomize_percentage] = true
263
+ chat_users = (1..100).select { |id| @rollout.active?(:chat, double(id: id)) }
264
+ beta_users = (1..100).select { |id| @rollout.active?(:beta, double(id: id)) }
265
+ expect(chat_users).not_to eq beta_users
266
+ end
267
+ it "activates the feature for the same set of users when opt is not set" do
268
+ @options[:randomize_percentage] = false
269
+ chat_users = (1..100).select { |id| @rollout.active?(:chat, double(id: id)) }
270
+ beta_users = (1..100).select { |id| @rollout.active?(:beta, double(id: id)) }
271
+ expect(chat_users).to eq beta_users
183
272
  end
184
273
  end
185
274
 
186
275
  describe "activating a feature for a group as a string" do
187
276
  before do
188
277
  @rollout.define_group(:admins) { |user| user.id == 5 }
189
- @rollout.activate_group(:chat, 'admins')
278
+ @rollout.activate_group(:chat, "admins")
190
279
  end
191
280
 
192
281
  it "the feature is active for users for which the block evaluates to true" do
193
- @rollout.should be_active(:chat, stub(:id => 5))
282
+ expect(@rollout).to be_active(:chat, double(id: 5))
194
283
  end
195
284
 
196
285
  it "is not active for users for which the block evaluates to false" do
197
- @rollout.should_not be_active(:chat, stub(:id => 1))
286
+ expect(@rollout).not_to be_active(:chat, double(id: 1))
198
287
  end
199
288
  end
200
289
 
@@ -205,7 +294,7 @@ describe "Rollout" do
205
294
  end
206
295
 
207
296
  it "becomes inactivate for all users" do
208
- @rollout.should_not be_active(:chat, stub(:id => 24))
297
+ expect(@rollout).not_to be_active(:chat, double(id: 24))
209
298
  end
210
299
  end
211
300
 
@@ -216,7 +305,7 @@ describe "Rollout" do
216
305
  end
217
306
 
218
307
  it "becomes inactivate" do
219
- @rollout.should_not be_active(:chat)
308
+ expect(@rollout).not_to be_active(:chat)
220
309
  end
221
310
  end
222
311
 
@@ -226,7 +315,7 @@ describe "Rollout" do
226
315
  end
227
316
 
228
317
  it "becomes activated" do
229
- @rollout.should be_active(:chat)
318
+ expect(@rollout).to be_active(:chat)
230
319
  end
231
320
  end
232
321
 
@@ -235,27 +324,45 @@ describe "Rollout" do
235
324
  @rollout.set(:chat, false)
236
325
  end
237
326
 
238
- it "becomes activated" do
239
- @rollout.should_not be_active(:chat)
327
+ it "becomes inactivated" do
328
+ expect(@rollout).not_to be_active(:chat)
329
+ end
330
+ end
331
+
332
+ describe "deleting a feature" do
333
+ before do
334
+ @rollout.set(:chat, true)
335
+ end
336
+
337
+ it "should be removed from features list" do
338
+ expect(@rollout.features.size).to eq 1
339
+ @rollout.delete(:chat)
340
+ expect(@rollout.features.size).to eq 0
341
+ end
342
+
343
+ it "should have metadata cleared" do
344
+ expect(@rollout.get(:chat).percentage).to eq 100
345
+ @rollout.delete(:chat)
346
+ expect(@rollout.get(:chat).percentage).to eq 0
240
347
  end
241
348
  end
242
349
 
243
350
  describe "keeps a list of features" do
244
351
  it "saves the feature" do
245
352
  @rollout.activate(:chat)
246
- @rollout.features.should be_include(:chat)
353
+ expect(@rollout.features).to be_include(:chat)
247
354
  end
248
355
 
249
356
  it "does not contain doubles" do
250
357
  @rollout.activate(:chat)
251
358
  @rollout.activate(:chat)
252
- @rollout.features.size.should == 1
359
+ expect(@rollout.features.size).to eq(1)
253
360
  end
254
361
 
255
362
  it "does not contain doubles when using string" do
256
363
  @rollout.activate(:chat)
257
364
  @rollout.activate("chat")
258
- @rollout.features.size.should == 1
365
+ expect(@rollout.features.size).to eq(1)
259
366
  end
260
367
  end
261
368
 
@@ -265,24 +372,24 @@ describe "Rollout" do
265
372
  @rollout.activate_group(:chat, :caretakers)
266
373
  @rollout.activate_group(:chat, :greeters)
267
374
  @rollout.activate(:signup)
268
- @rollout.activate_user(:chat, stub(:id => 42))
375
+ @rollout.activate_user(:chat, double(id: 42))
269
376
  end
270
377
 
271
378
  it "returns the feature object" do
272
379
  feature = @rollout.get(:chat)
273
- feature.groups.should == [:caretakers, :greeters]
274
- feature.percentage.should == 10
275
- feature.users.should == %w(42)
276
- feature.to_hash.should == {
277
- :groups => [:caretakers, :greeters],
278
- :percentage => 10,
279
- :users => %w(42)
280
- }
380
+ expect(feature.groups).to eq [:caretakers, :greeters].to_set
381
+ expect(feature.percentage).to eq 10
382
+ expect(feature.users).to eq %w(42).to_set
383
+ expect(feature.to_hash).to eq(
384
+ groups: [:caretakers, :greeters].to_set,
385
+ percentage: 10,
386
+ users: %w(42).to_set
387
+ )
281
388
 
282
389
  feature = @rollout.get(:signup)
283
- feature.groups.should be_empty
284
- feature.users.should be_empty
285
- feature.percentage.should == 100
390
+ expect(feature.groups).to be_empty
391
+ expect(feature.users).to be_empty
392
+ expect(feature.percentage).to eq(100)
286
393
  end
287
394
  end
288
395
 
@@ -297,16 +404,16 @@ describe "Rollout" do
297
404
 
298
405
  it "each feature is cleared" do
299
406
  features.each do |feature|
300
- @rollout.get(feature).to_hash.should == {
301
- :percentage => 0,
302
- :users => [],
303
- :groups => []
304
- }
407
+ expect(@rollout.get(feature).to_hash).to eq(
408
+ percentage: 0,
409
+ users: Set.new,
410
+ groups: Set.new
411
+ )
305
412
  end
306
413
  end
307
414
 
308
415
  it "removes all features" do
309
- @rollout.features.should be_empty
416
+ expect(@rollout.features).to be_empty
310
417
  end
311
418
  end
312
419
 
@@ -314,44 +421,121 @@ describe "Rollout" do
314
421
  before do
315
422
  @legacy = Rollout::Legacy.new(@redis)
316
423
  @legacy.activate_percentage(:chat, 12)
317
- @legacy.activate_user(:chat, stub(:id => 42))
318
- @legacy.activate_user(:chat, stub(:id => 24))
424
+ @legacy.activate_user(:chat, double(id: 42))
425
+ @legacy.activate_user(:chat, double(id: 24))
319
426
  @legacy.activate_group(:chat, :dope_people)
320
- @rollout = Rollout.new(@redis, :migrate => true)
427
+ @rollout = Rollout.new(@redis, migrate: true)
321
428
  end
322
429
 
323
430
  it "imports the settings from the legacy rollout once" do
324
- @rollout.get(:chat).to_hash.should == {
325
- :percentage => 12,
326
- :users => %w(24 42),
327
- :groups => [:dope_people]
328
- }
431
+ expect(@rollout.get(:chat).to_hash).to eq({
432
+ percentage: 12,
433
+ users: %w(24 42),
434
+ groups: [:dope_people]
435
+ })
329
436
  @legacy.deactivate_all(:chat)
330
- @rollout.get(:chat).to_hash.should == {
331
- :percentage => 12,
332
- :users => %w(24 42),
333
- :groups => [:dope_people]
334
- }
335
- @redis.get("feature:chat").should_not be_nil
437
+ expect(@rollout.get(:chat).to_hash).to eq({
438
+ percentage: 12,
439
+ users: %w(24 42).to_set,
440
+ groups: [:dope_people].to_set
441
+ })
442
+ expect(@redis.get("feature:chat")).not_to be_nil
336
443
  end
337
444
 
338
445
  it "imports settings that were globally activated" do
339
446
  @legacy.activate_globally(:video_chat)
340
- @rollout.get(:video_chat).to_hash[:percentage].should == 100
447
+ expect(@rollout.get(:video_chat).to_hash[:percentage]).to eq(100)
448
+ end
449
+ end
450
+
451
+ describe "#feature_states" do
452
+ let(:user_double) { double(id: 7) }
453
+
454
+ before do
455
+ @rollout.activate(:chat)
456
+ @rollout.activate_user(:video, user_double)
457
+ @rollout.deactivate(:vr)
458
+ end
459
+
460
+ it "returns a hash" do
461
+ expect(@rollout.feature_states).to be_a(Hash)
462
+ end
463
+
464
+ context "with user argument" do
465
+ it "maps active feature as true" do
466
+ state = @rollout.feature_states(user_double)[:video]
467
+ expect(state).to eq(true)
468
+ end
469
+
470
+ it "maps inactive feature as false" do
471
+ state = @rollout.feature_states[:vr]
472
+ expect(state).to eq(false)
473
+ end
474
+ end
475
+
476
+ context "with no argument" do
477
+ it "maps active feature as true" do
478
+ state = @rollout.feature_states[:chat]
479
+ expect(state).to eq(true)
480
+ end
481
+
482
+ it "maps inactive feature as false" do
483
+ state = @rollout.feature_states[:video]
484
+ expect(state).to eq(false)
485
+ end
486
+ end
487
+ end
488
+
489
+ describe "#active_features" do
490
+ let(:user_double) { double(id: 19) }
491
+
492
+ before do
493
+ @rollout.activate(:chat)
494
+ @rollout.activate_user(:video, user_double)
495
+ @rollout.deactivate(:vr)
496
+ end
497
+
498
+ it "returns an array" do
499
+ expect(@rollout.active_features).to be_a(Array)
500
+ end
501
+
502
+ context "with user argument" do
503
+ it "includes active feature" do
504
+ features = @rollout.active_features(user_double)
505
+ expect(features).to include(:video)
506
+ expect(features).to include(:chat)
507
+ end
508
+
509
+ it "excludes inactive feature" do
510
+ features = @rollout.active_features(user_double)
511
+ expect(features).to_not include(:vr)
512
+ end
513
+ end
514
+
515
+ context "with no argument" do
516
+ it "includes active feature" do
517
+ features = @rollout.active_features
518
+ expect(features).to include(:chat)
519
+ end
520
+
521
+ it "excludes inactive feature" do
522
+ features = @rollout.active_features
523
+ expect(features).to_not include(:video)
524
+ end
341
525
  end
342
526
  end
343
527
  end
344
528
 
345
529
  describe "Rollout::Feature" do
346
530
  before do
347
- @user = stub("User", :email => "test@test.com")
348
- @feature = Rollout::Feature.new(:chat, nil, :id_user_by => :email)
531
+ @user = double("User", email: "test@test.com")
532
+ @feature = Rollout::Feature.new(:chat, nil, id_user_by: :email)
349
533
  end
350
534
 
351
535
  describe "#add_user" do
352
536
  it "ids a user using id_user_by" do
353
537
  @feature.add_user(@user)
354
- @user.should have_received :email
538
+ expect(@user).to have_received :email
355
539
  end
356
540
  end
357
541
  end
data/spec/spec_helper.rb CHANGED
@@ -1,11 +1,17 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
- require 'rollout'
4
- require 'rspec'
5
- require 'bourne'
6
- require 'redis'
3
+ require "rollout"
4
+ require "rspec"
5
+ require "redis"
6
+ require "codeclimate-test-reporter"
7
+
8
+ SimpleCov.start do
9
+ formatter SimpleCov::Formatter::MultiFormatter.new([
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ CodeClimate::TestReporter::Formatter,
12
+ ])
13
+ end
7
14
 
8
15
  RSpec.configure do |config|
9
- config.mock_with :mocha
10
16
  config.before { Redis.new.flushdb }
11
17
  end