rollout 2.4.6 → 2.6.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +56 -32
- data/README.md +12 -1
- data/lib/rollout/feature.rb +20 -10
- data/lib/rollout/logging.rb +199 -0
- data/lib/rollout/version.rb +1 -1
- data/lib/rollout.rb +42 -11
- data/rollout.gemspec +2 -2
- data/spec/rollout/feature_spec.rb +54 -0
- data/spec/rollout/logging_spec.rb +143 -0
- data/spec/rollout_spec.rb +191 -240
- data/spec/spec_helper.rb +2 -2
- metadata +17 -10
data/spec/rollout_spec.rb
CHANGED
@@ -1,132 +1,130 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
RSpec.describe "Rollout" do
|
4
|
-
|
5
|
-
@rollout = Rollout.new(Redis.current)
|
6
|
-
end
|
4
|
+
let(:rollout) { Rollout.new($redis) }
|
7
5
|
|
8
6
|
describe "when a group is activated" do
|
9
7
|
before do
|
10
|
-
|
11
|
-
|
8
|
+
rollout.define_group(:fivesonly) { |user| user.id == 5 }
|
9
|
+
rollout.activate_group(:chat, :fivesonly)
|
12
10
|
end
|
13
11
|
|
14
12
|
it "the feature is active for users for which the block evaluates to true" do
|
15
|
-
expect(
|
13
|
+
expect(rollout).to be_active(:chat, double(id: 5))
|
16
14
|
end
|
17
15
|
|
18
16
|
it "is not active for users for which the block evaluates to false" do
|
19
|
-
expect(
|
17
|
+
expect(rollout).not_to be_active(:chat, double(id: 1))
|
20
18
|
end
|
21
19
|
|
22
20
|
it "is not active if a group is found in Redis but not defined in Rollout" do
|
23
|
-
|
24
|
-
expect(
|
21
|
+
rollout.activate_group(:chat, :fake)
|
22
|
+
expect(rollout).not_to be_active(:chat, double(id: 1))
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
28
26
|
describe "the default all group" do
|
29
27
|
before do
|
30
|
-
|
28
|
+
rollout.activate_group(:chat, :all)
|
31
29
|
end
|
32
30
|
|
33
31
|
it "evaluates to true no matter what" do
|
34
|
-
expect(
|
32
|
+
expect(rollout).to be_active(:chat, double(id: 0))
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
36
|
describe "deactivating a group" do
|
39
37
|
before do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
rollout.define_group(:fivesonly) { |user| user.id == 5 }
|
39
|
+
rollout.activate_group(:chat, :all)
|
40
|
+
rollout.activate_group(:chat, :some)
|
41
|
+
rollout.activate_group(:chat, :fivesonly)
|
42
|
+
rollout.deactivate_group(:chat, :all)
|
43
|
+
rollout.deactivate_group(:chat, "some")
|
46
44
|
end
|
47
45
|
|
48
46
|
it "deactivates the rules for that group" do
|
49
|
-
expect(
|
47
|
+
expect(rollout).not_to be_active(:chat, double(id: 10))
|
50
48
|
end
|
51
49
|
|
52
50
|
it "leaves the other groups active" do
|
53
|
-
expect(
|
51
|
+
expect(rollout.get(:chat).groups).to eq [:fivesonly]
|
54
52
|
end
|
55
53
|
|
56
54
|
it "leaves the other groups active using sets" do
|
57
|
-
@options =
|
55
|
+
@options = rollout.instance_variable_get("@options")
|
58
56
|
@options[:use_sets] = true
|
59
|
-
expect(
|
57
|
+
expect(rollout.get(:chat).groups).to eq [:fivesonly].to_set
|
60
58
|
end
|
61
59
|
end
|
62
60
|
|
63
61
|
describe "deactivating a feature completely" do
|
64
62
|
before do
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
rollout.define_group(:fivesonly) { |user| user.id == 5 }
|
64
|
+
rollout.activate_group(:chat, :all)
|
65
|
+
rollout.activate_group(:chat, :fivesonly)
|
66
|
+
rollout.activate_user(:chat, double(id: 51))
|
67
|
+
rollout.activate_percentage(:chat, 100)
|
68
|
+
rollout.activate(:chat)
|
69
|
+
rollout.deactivate(:chat)
|
72
70
|
end
|
73
71
|
|
74
72
|
it "removes all of the groups" do
|
75
|
-
expect(
|
73
|
+
expect(rollout).not_to be_active(:chat, double(id: 0))
|
76
74
|
end
|
77
75
|
|
78
76
|
it "removes all of the users" do
|
79
|
-
expect(
|
77
|
+
expect(rollout).not_to be_active(:chat, double(id: 51))
|
80
78
|
end
|
81
79
|
|
82
80
|
it "removes the percentage" do
|
83
|
-
expect(
|
81
|
+
expect(rollout).not_to be_active(:chat, double(id: 24))
|
84
82
|
end
|
85
83
|
|
86
84
|
it "removes globally" do
|
87
|
-
expect(
|
85
|
+
expect(rollout).not_to be_active(:chat)
|
88
86
|
end
|
89
87
|
end
|
90
88
|
|
91
89
|
describe "activating a specific user" do
|
92
90
|
before do
|
93
|
-
|
91
|
+
rollout.activate_user(:chat, double(id: 42))
|
94
92
|
end
|
95
93
|
|
96
94
|
it "is active for that user" do
|
97
|
-
expect(
|
95
|
+
expect(rollout).to be_active(:chat, double(id: 42))
|
98
96
|
end
|
99
97
|
|
100
98
|
it "remains inactive for other users" do
|
101
|
-
expect(
|
99
|
+
expect(rollout).not_to be_active(:chat, double(id: 24))
|
102
100
|
end
|
103
101
|
end
|
104
102
|
|
105
103
|
describe "activating a specific user by ID" do
|
106
104
|
before do
|
107
|
-
|
105
|
+
rollout.activate_user(:chat, 42)
|
108
106
|
end
|
109
107
|
|
110
108
|
it "is active for that user" do
|
111
|
-
expect(
|
109
|
+
expect(rollout).to be_active(:chat, double(id: 42))
|
112
110
|
end
|
113
111
|
|
114
112
|
it "remains inactive for other users" do
|
115
|
-
expect(
|
113
|
+
expect(rollout).not_to be_active(:chat, double(id: 24))
|
116
114
|
end
|
117
115
|
end
|
118
116
|
|
119
117
|
describe "activating a specific user with a string id" do
|
120
118
|
before do
|
121
|
-
|
119
|
+
rollout.activate_user(:chat, double(id: "user-72"))
|
122
120
|
end
|
123
121
|
|
124
122
|
it "is active for that user" do
|
125
|
-
expect(
|
123
|
+
expect(rollout).to be_active(:chat, double(id: "user-72"))
|
126
124
|
end
|
127
125
|
|
128
126
|
it "remains inactive for other users" do
|
129
|
-
expect(
|
127
|
+
expect(rollout).not_to be_active(:chat, double(id: "user-12"))
|
130
128
|
end
|
131
129
|
end
|
132
130
|
|
@@ -134,56 +132,56 @@ RSpec.describe "Rollout" do
|
|
134
132
|
context "specified by user objects" do
|
135
133
|
let(:users) { [double(id: 1), double(id: 2), double(id: 3)] }
|
136
134
|
|
137
|
-
before {
|
135
|
+
before { rollout.activate_users(:chat, users) }
|
138
136
|
|
139
137
|
it "is active for the given users" do
|
140
|
-
users.each { |user| expect(
|
138
|
+
users.each { |user| expect(rollout).to be_active(:chat, user) }
|
141
139
|
end
|
142
140
|
|
143
141
|
it "remains inactive for other users" do
|
144
|
-
expect(
|
142
|
+
expect(rollout).not_to be_active(:chat, double(id: 4))
|
145
143
|
end
|
146
144
|
end
|
147
145
|
|
148
146
|
context "specified by user ids" do
|
149
147
|
let(:users) { [1, 2, 3] }
|
150
148
|
|
151
|
-
before {
|
149
|
+
before { rollout.activate_users(:chat, users) }
|
152
150
|
|
153
151
|
it "is active for the given users" do
|
154
|
-
users.each { |user| expect(
|
152
|
+
users.each { |user| expect(rollout).to be_active(:chat, user) }
|
155
153
|
end
|
156
154
|
|
157
155
|
it "remains inactive for other users" do
|
158
|
-
expect(
|
156
|
+
expect(rollout).not_to be_active(:chat, 4)
|
159
157
|
end
|
160
158
|
end
|
161
159
|
end
|
162
160
|
|
163
161
|
describe "deactivating a specific user" do
|
164
162
|
before do
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
163
|
+
rollout.activate_user(:chat, double(id: 42))
|
164
|
+
rollout.activate_user(:chat, double(id: 4242))
|
165
|
+
rollout.activate_user(:chat, double(id: 24))
|
166
|
+
rollout.deactivate_user(:chat, double(id: 42))
|
167
|
+
rollout.deactivate_user(:chat, double(id: "4242"))
|
170
168
|
end
|
171
169
|
|
172
170
|
it "that user should no longer be active" do
|
173
|
-
expect(
|
171
|
+
expect(rollout).not_to be_active(:chat, double(id: 42))
|
174
172
|
end
|
175
173
|
|
176
174
|
it "remains active for other active users" do
|
177
|
-
@options =
|
175
|
+
@options = rollout.instance_variable_get("@options")
|
178
176
|
@options[:use_sets] = false
|
179
|
-
expect(
|
177
|
+
expect(rollout.get(:chat).users).to eq %w(24)
|
180
178
|
end
|
181
179
|
|
182
180
|
it "remains active for other active users using sets" do
|
183
|
-
@options =
|
181
|
+
@options = rollout.instance_variable_get("@options")
|
184
182
|
@options[:use_sets] = true
|
185
183
|
|
186
|
-
expect(
|
184
|
+
expect(rollout.get(:chat).users).to eq %w(24).to_set
|
187
185
|
end
|
188
186
|
end
|
189
187
|
|
@@ -193,16 +191,16 @@ RSpec.describe "Rollout" do
|
|
193
191
|
let(:inactive_users) { [double(id: 3), double(id: 4)] }
|
194
192
|
|
195
193
|
before do
|
196
|
-
|
197
|
-
|
194
|
+
rollout.activate_users(:chat, active_users + inactive_users)
|
195
|
+
rollout.deactivate_users(:chat, inactive_users)
|
198
196
|
end
|
199
197
|
|
200
198
|
it "is active for the active users" do
|
201
|
-
active_users.each { |user| expect(
|
199
|
+
active_users.each { |user| expect(rollout).to be_active(:chat, user) }
|
202
200
|
end
|
203
201
|
|
204
202
|
it "is not active for inactive users" do
|
205
|
-
inactive_users.each { |user| expect(
|
203
|
+
inactive_users.each { |user| expect(rollout).not_to be_active(:chat, user) }
|
206
204
|
end
|
207
205
|
end
|
208
206
|
|
@@ -211,16 +209,16 @@ RSpec.describe "Rollout" do
|
|
211
209
|
let(:inactive_users) { [3, 4] }
|
212
210
|
|
213
211
|
before do
|
214
|
-
|
215
|
-
|
212
|
+
rollout.activate_users(:chat, active_users + inactive_users)
|
213
|
+
rollout.deactivate_users(:chat, inactive_users)
|
216
214
|
end
|
217
215
|
|
218
216
|
it "is active for the active users" do
|
219
|
-
active_users.each { |user| expect(
|
217
|
+
active_users.each { |user| expect(rollout).to be_active(:chat, user) }
|
220
218
|
end
|
221
219
|
|
222
220
|
it "is not active for inactive users" do
|
223
|
-
inactive_users.each { |user| expect(
|
221
|
+
inactive_users.each { |user| expect(rollout).not_to be_active(:chat, user) }
|
224
222
|
end
|
225
223
|
end
|
226
224
|
end
|
@@ -229,230 +227,232 @@ RSpec.describe "Rollout" do
|
|
229
227
|
describe 'set a group of users' do
|
230
228
|
it 'should replace the users with the given array' do
|
231
229
|
users = %w(1 2 3 4)
|
232
|
-
|
233
|
-
|
234
|
-
expect(
|
230
|
+
rollout.activate_users(:chat, %w(10 20 30))
|
231
|
+
rollout.set_users(:chat, users)
|
232
|
+
expect(rollout.get(:chat).users).to eq(users)
|
235
233
|
end
|
236
234
|
end
|
237
235
|
|
238
236
|
describe "activating a feature globally" do
|
239
237
|
before do
|
240
|
-
|
238
|
+
rollout.activate(:chat)
|
241
239
|
end
|
242
240
|
|
243
241
|
it "activates the feature" do
|
244
|
-
expect(
|
242
|
+
expect(rollout).to be_active(:chat)
|
245
243
|
end
|
246
244
|
|
247
245
|
it "sets @data to empty hash" do
|
248
|
-
expect(
|
246
|
+
expect(rollout.get(:chat).data).to eq({})
|
249
247
|
end
|
250
248
|
end
|
251
249
|
|
252
250
|
describe "activating a feature for a percentage of users" do
|
253
251
|
before do
|
254
|
-
|
252
|
+
rollout.activate_percentage(:chat, 20)
|
255
253
|
end
|
256
254
|
|
257
255
|
it "activates the feature for that percentage of the users" do
|
258
|
-
expect((1..100).select { |id|
|
256
|
+
expect((1..100).select { |id| rollout.active?(:chat, double(id: id)) }.length).to be_within(2).of(20)
|
259
257
|
end
|
260
258
|
end
|
261
259
|
|
262
260
|
describe "activating a feature for a percentage of users" do
|
263
261
|
before do
|
264
|
-
|
262
|
+
rollout.activate_percentage(:chat, 20)
|
265
263
|
end
|
266
264
|
|
267
265
|
it "activates the feature for that percentage of the users" do
|
268
|
-
expect((1..200).select { |id|
|
266
|
+
expect((1..200).select { |id| rollout.active?(:chat, double(id: id)) }.length).to be_within(4).of(40)
|
269
267
|
end
|
270
268
|
end
|
271
269
|
|
272
270
|
describe "activating a feature for a percentage of users" do
|
273
271
|
before do
|
274
|
-
|
272
|
+
rollout.activate_percentage(:chat, 5)
|
275
273
|
end
|
276
274
|
|
277
275
|
it "activates the feature for that percentage of the users" do
|
278
|
-
expect((1..100).select { |id|
|
276
|
+
expect((1..100).select { |id| rollout.active?(:chat, double(id: id)) }.length).to be_within(2).of(5)
|
279
277
|
end
|
280
278
|
end
|
281
279
|
|
282
280
|
describe "activating a feature for a percentage of users" do
|
283
281
|
before do
|
284
|
-
|
282
|
+
rollout.activate_percentage(:chat, 0.1)
|
285
283
|
end
|
286
284
|
|
287
285
|
it "activates the feature for that percentage of the users" do
|
288
|
-
expect((1..10_000).to_set.select { |id|
|
286
|
+
expect((1..10_000).to_set.select { |id| rollout.active?(:chat, double(id: id)) }.length).to be_within(2).of(10)
|
289
287
|
end
|
290
288
|
end
|
291
289
|
|
292
290
|
describe "activating a feature for a percentage of users" do
|
293
291
|
before do
|
294
|
-
|
295
|
-
|
296
|
-
@options =
|
292
|
+
rollout.activate_percentage(:chat, 20)
|
293
|
+
rollout.activate_percentage(:beta, 20)
|
294
|
+
@options = rollout.instance_variable_get("@options")
|
297
295
|
end
|
298
296
|
|
299
297
|
it "activates the feature for a random set of users when opt is set" do
|
300
298
|
@options[:randomize_percentage] = true
|
301
|
-
chat_users = (1..100).select { |id|
|
302
|
-
beta_users = (1..100).select { |id|
|
299
|
+
chat_users = (1..100).select { |id| rollout.active?(:chat, double(id: id)) }
|
300
|
+
beta_users = (1..100).select { |id| rollout.active?(:beta, double(id: id)) }
|
303
301
|
expect(chat_users).not_to eq beta_users
|
304
302
|
end
|
305
303
|
it "activates the feature for the same set of users when opt is not set" do
|
306
304
|
@options[:randomize_percentage] = false
|
307
|
-
chat_users = (1..100).select { |id|
|
308
|
-
beta_users = (1..100).select { |id|
|
305
|
+
chat_users = (1..100).select { |id| rollout.active?(:chat, double(id: id)) }
|
306
|
+
beta_users = (1..100).select { |id| rollout.active?(:beta, double(id: id)) }
|
309
307
|
expect(chat_users).to eq beta_users
|
310
308
|
end
|
311
309
|
end
|
312
310
|
|
313
311
|
describe "activating a feature for a group as a string" do
|
314
312
|
before do
|
315
|
-
|
316
|
-
|
313
|
+
rollout.define_group(:admins) { |user| user.id == 5 }
|
314
|
+
rollout.activate_group(:chat, "admins")
|
317
315
|
end
|
318
316
|
|
319
317
|
it "the feature is active for users for which the block evaluates to true" do
|
320
|
-
expect(
|
318
|
+
expect(rollout).to be_active(:chat, double(id: 5))
|
321
319
|
end
|
322
320
|
|
323
321
|
it "is not active for users for which the block evaluates to false" do
|
324
|
-
expect(
|
322
|
+
expect(rollout).not_to be_active(:chat, double(id: 1))
|
325
323
|
end
|
326
324
|
end
|
327
325
|
|
328
326
|
describe "deactivating the percentage of users" do
|
329
327
|
before do
|
330
|
-
|
331
|
-
|
328
|
+
rollout.activate_percentage(:chat, 100)
|
329
|
+
rollout.deactivate_percentage(:chat)
|
332
330
|
end
|
333
331
|
|
334
332
|
it "becomes inactivate for all users" do
|
335
|
-
expect(
|
333
|
+
expect(rollout).not_to be_active(:chat, double(id: 24))
|
336
334
|
end
|
337
335
|
end
|
338
336
|
|
339
337
|
describe "deactivating the feature globally" do
|
340
338
|
before do
|
341
|
-
|
342
|
-
|
339
|
+
rollout.activate(:chat)
|
340
|
+
rollout.deactivate(:chat)
|
343
341
|
end
|
344
342
|
|
345
343
|
it "becomes inactivate" do
|
346
|
-
expect(
|
344
|
+
expect(rollout).not_to be_active(:chat)
|
347
345
|
end
|
348
346
|
end
|
349
347
|
|
350
348
|
describe "setting a feature on" do
|
351
349
|
before do
|
352
|
-
|
350
|
+
rollout.set(:chat, true)
|
353
351
|
end
|
354
352
|
|
355
353
|
it "becomes activated" do
|
356
|
-
expect(
|
354
|
+
expect(rollout).to be_active(:chat)
|
357
355
|
end
|
358
356
|
end
|
359
357
|
|
360
358
|
describe "setting a feature off" do
|
361
359
|
before do
|
362
|
-
|
360
|
+
rollout.set(:chat, false)
|
363
361
|
end
|
364
362
|
|
365
363
|
it "becomes inactivated" do
|
366
|
-
expect(
|
364
|
+
expect(rollout).not_to be_active(:chat)
|
367
365
|
end
|
368
366
|
end
|
369
367
|
|
370
368
|
describe "deleting a feature" do
|
371
369
|
before do
|
372
|
-
|
370
|
+
rollout.set(:chat, true)
|
373
371
|
end
|
374
372
|
|
375
373
|
context "when feature was passed as string" do
|
376
374
|
it "should be removed from features list" do
|
377
|
-
expect(
|
378
|
-
|
379
|
-
expect(
|
375
|
+
expect(rollout.features.size).to eq 1
|
376
|
+
rollout.delete('chat')
|
377
|
+
expect(rollout.features.size).to eq 0
|
380
378
|
end
|
381
379
|
end
|
382
380
|
|
383
381
|
it "should be removed from features list" do
|
384
|
-
expect(
|
385
|
-
|
386
|
-
expect(
|
382
|
+
expect(rollout.features.size).to eq 1
|
383
|
+
rollout.delete(:chat)
|
384
|
+
expect(rollout.features.size).to eq 0
|
387
385
|
end
|
388
386
|
|
389
387
|
it "should have metadata cleared" do
|
390
|
-
expect(
|
391
|
-
|
392
|
-
expect(
|
388
|
+
expect(rollout.get(:chat).percentage).to eq 100
|
389
|
+
rollout.delete(:chat)
|
390
|
+
expect(rollout.get(:chat).percentage).to eq 0
|
393
391
|
end
|
394
392
|
end
|
395
393
|
|
396
394
|
describe "keeps a list of features" do
|
397
395
|
it "saves the feature" do
|
398
|
-
|
399
|
-
expect(
|
396
|
+
rollout.activate(:chat)
|
397
|
+
expect(rollout.features).to be_include(:chat)
|
400
398
|
end
|
401
399
|
|
402
400
|
it "does not contain doubles" do
|
403
|
-
|
404
|
-
|
405
|
-
expect(
|
401
|
+
rollout.activate(:chat)
|
402
|
+
rollout.activate(:chat)
|
403
|
+
expect(rollout.features.size).to eq(1)
|
406
404
|
end
|
407
405
|
|
408
406
|
it "does not contain doubles when using string" do
|
409
|
-
|
410
|
-
|
411
|
-
expect(
|
407
|
+
rollout.activate(:chat)
|
408
|
+
rollout.activate("chat")
|
409
|
+
expect(rollout.features.size).to eq(1)
|
412
410
|
end
|
413
411
|
end
|
414
412
|
|
415
413
|
describe "#get" do
|
416
414
|
before do
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
415
|
+
rollout.activate_percentage(:chat, 10)
|
416
|
+
rollout.activate_group(:chat, :caretakers)
|
417
|
+
rollout.activate_group(:chat, :greeters)
|
418
|
+
rollout.activate(:signup)
|
419
|
+
rollout.activate_user(:chat, double(id: 42))
|
422
420
|
end
|
423
421
|
|
424
422
|
it "returns the feature object" do
|
425
|
-
feature =
|
423
|
+
feature = rollout.get(:chat)
|
426
424
|
expect(feature.groups).to eq [:caretakers, :greeters]
|
427
425
|
expect(feature.percentage).to eq 10
|
428
426
|
expect(feature.users).to eq %w(42)
|
429
427
|
expect(feature.to_hash).to eq(
|
430
428
|
groups: [:caretakers, :greeters],
|
431
429
|
percentage: 10,
|
432
|
-
users: %w(42)
|
430
|
+
users: %w(42),
|
431
|
+
data: {},
|
433
432
|
)
|
434
433
|
|
435
|
-
feature =
|
434
|
+
feature = rollout.get(:signup)
|
436
435
|
expect(feature.groups).to be_empty
|
437
436
|
expect(feature.users).to be_empty
|
438
437
|
expect(feature.percentage).to eq(100)
|
439
438
|
end
|
440
439
|
|
441
440
|
it "returns the feature objects using sets" do
|
442
|
-
@options =
|
441
|
+
@options = rollout.instance_variable_get("@options")
|
443
442
|
@options[:use_sets] = true
|
444
443
|
|
445
|
-
feature =
|
444
|
+
feature = rollout.get(:chat)
|
446
445
|
expect(feature.groups).to eq [:caretakers, :greeters].to_set
|
447
446
|
expect(feature.percentage).to eq 10
|
448
447
|
expect(feature.users).to eq %w(42).to_set
|
449
448
|
expect(feature.to_hash).to eq(
|
450
449
|
groups: [:caretakers, :greeters].to_set,
|
451
450
|
percentage: 10,
|
452
|
-
users: %w(42).to_set
|
451
|
+
users: %w(42).to_set,
|
452
|
+
data: {},
|
453
453
|
)
|
454
454
|
|
455
|
-
feature =
|
455
|
+
feature = rollout.get(:signup)
|
456
456
|
expect(feature.groups).to be_empty
|
457
457
|
expect(feature.users).to be_empty
|
458
458
|
expect(feature.percentage).to eq(100)
|
@@ -463,35 +463,37 @@ RSpec.describe "Rollout" do
|
|
463
463
|
let(:features) { %w(signup beta alpha gm) }
|
464
464
|
|
465
465
|
before do
|
466
|
-
features.each { |f|
|
466
|
+
features.each { |f| rollout.activate(f) }
|
467
467
|
|
468
|
-
|
468
|
+
rollout.clear!
|
469
469
|
end
|
470
470
|
|
471
471
|
it "each feature is cleared" do
|
472
472
|
features.each do |feature|
|
473
|
-
expect(
|
473
|
+
expect(rollout.get(feature).to_hash).to eq(
|
474
474
|
percentage: 0,
|
475
475
|
users: [],
|
476
|
-
groups: []
|
476
|
+
groups: [],
|
477
|
+
data: {},
|
477
478
|
)
|
478
479
|
end
|
479
480
|
end
|
480
481
|
|
481
482
|
it "each feature is cleared with sets" do
|
482
|
-
@options =
|
483
|
+
@options = rollout.instance_variable_get("@options")
|
483
484
|
@options[:use_sets] = true
|
484
485
|
features.each do |feature|
|
485
|
-
expect(
|
486
|
+
expect(rollout.get(feature).to_hash).to eq(
|
486
487
|
percentage: 0,
|
487
488
|
users: Set.new,
|
488
|
-
groups: Set.new
|
489
|
+
groups: Set.new,
|
490
|
+
data: {},
|
489
491
|
)
|
490
492
|
end
|
491
493
|
end
|
492
494
|
|
493
495
|
it "removes all features" do
|
494
|
-
expect(
|
496
|
+
expect(rollout.features).to be_empty
|
495
497
|
end
|
496
498
|
end
|
497
499
|
|
@@ -499,35 +501,35 @@ RSpec.describe "Rollout" do
|
|
499
501
|
let(:user_double) { double(id: 7) }
|
500
502
|
|
501
503
|
before do
|
502
|
-
|
503
|
-
|
504
|
-
|
504
|
+
rollout.activate(:chat)
|
505
|
+
rollout.activate_user(:video, user_double)
|
506
|
+
rollout.deactivate(:vr)
|
505
507
|
end
|
506
508
|
|
507
509
|
it "returns a hash" do
|
508
|
-
expect(
|
510
|
+
expect(rollout.feature_states).to be_a(Hash)
|
509
511
|
end
|
510
512
|
|
511
513
|
context "with user argument" do
|
512
514
|
it "maps active feature as true" do
|
513
|
-
state =
|
515
|
+
state = rollout.feature_states(user_double)[:video]
|
514
516
|
expect(state).to eq(true)
|
515
517
|
end
|
516
518
|
|
517
519
|
it "maps inactive feature as false" do
|
518
|
-
state =
|
520
|
+
state = rollout.feature_states[:vr]
|
519
521
|
expect(state).to eq(false)
|
520
522
|
end
|
521
523
|
end
|
522
524
|
|
523
525
|
context "with no argument" do
|
524
526
|
it "maps active feature as true" do
|
525
|
-
state =
|
527
|
+
state = rollout.feature_states[:chat]
|
526
528
|
expect(state).to eq(true)
|
527
529
|
end
|
528
530
|
|
529
531
|
it "maps inactive feature as false" do
|
530
|
-
state =
|
532
|
+
state = rollout.feature_states[:video]
|
531
533
|
expect(state).to eq(false)
|
532
534
|
end
|
533
535
|
end
|
@@ -537,36 +539,36 @@ RSpec.describe "Rollout" do
|
|
537
539
|
let(:user_double) { double(id: 19) }
|
538
540
|
|
539
541
|
before do
|
540
|
-
|
541
|
-
|
542
|
-
|
542
|
+
rollout.activate(:chat)
|
543
|
+
rollout.activate_user(:video, user_double)
|
544
|
+
rollout.deactivate(:vr)
|
543
545
|
end
|
544
546
|
|
545
547
|
it "returns an array" do
|
546
|
-
expect(
|
548
|
+
expect(rollout.active_features).to be_a(Array)
|
547
549
|
end
|
548
550
|
|
549
551
|
context "with user argument" do
|
550
552
|
it "includes active feature" do
|
551
|
-
features =
|
553
|
+
features = rollout.active_features(user_double)
|
552
554
|
expect(features).to include(:video)
|
553
555
|
expect(features).to include(:chat)
|
554
556
|
end
|
555
557
|
|
556
558
|
it "excludes inactive feature" do
|
557
|
-
features =
|
559
|
+
features = rollout.active_features(user_double)
|
558
560
|
expect(features).to_not include(:vr)
|
559
561
|
end
|
560
562
|
end
|
561
563
|
|
562
564
|
context "with no argument" do
|
563
565
|
it "includes active feature" do
|
564
|
-
features =
|
566
|
+
features = rollout.active_features
|
565
567
|
expect(features).to include(:chat)
|
566
568
|
end
|
567
569
|
|
568
570
|
it "excludes inactive feature" do
|
569
|
-
features =
|
571
|
+
features = rollout.active_features
|
570
572
|
expect(features).to_not include(:video)
|
571
573
|
end
|
572
574
|
end
|
@@ -574,27 +576,27 @@ RSpec.describe "Rollout" do
|
|
574
576
|
|
575
577
|
describe "#user_in_active_users?" do
|
576
578
|
it "returns true if activated for user" do
|
577
|
-
|
578
|
-
expect(
|
579
|
+
rollout.activate_user(:chat, double(id: 5))
|
580
|
+
expect(rollout.user_in_active_users?(:chat, "5")).to eq(true)
|
579
581
|
end
|
580
582
|
|
581
583
|
it "returns false if activated for group" do
|
582
|
-
|
583
|
-
expect(
|
584
|
+
rollout.activate_group(:chat, :all)
|
585
|
+
expect(rollout.user_in_active_users?(:chat, "5")).to eq(false)
|
584
586
|
end
|
585
587
|
end
|
586
588
|
|
587
589
|
describe "#multi_get" do
|
588
590
|
before do
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
591
|
+
rollout.activate_percentage(:chat, 10)
|
592
|
+
rollout.activate_group(:chat, :caretakers)
|
593
|
+
rollout.activate_group(:videos, :greeters)
|
594
|
+
rollout.activate(:signup)
|
595
|
+
rollout.activate_user(:photos, double(id: 42))
|
594
596
|
end
|
595
597
|
|
596
598
|
it "returns an array of features" do
|
597
|
-
features =
|
599
|
+
features = rollout.multi_get(:chat, :videos, :signup)
|
598
600
|
expect(features[0].name).to eq :chat
|
599
601
|
expect(features[0].groups).to eq [:caretakers]
|
600
602
|
expect(features[0].percentage).to eq 10
|
@@ -607,120 +609,69 @@ RSpec.describe "Rollout" do
|
|
607
609
|
|
608
610
|
describe 'when given feature keys is empty' do
|
609
611
|
it 'returns empty array' do
|
610
|
-
expect(
|
612
|
+
expect(rollout.multi_get(*[])).to match_array([])
|
611
613
|
end
|
612
614
|
end
|
613
615
|
end
|
614
616
|
|
615
617
|
describe "#set_feature_data" do
|
616
618
|
before do
|
617
|
-
|
619
|
+
rollout.set_feature_data(:chat, description: 'foo', release_date: 'bar')
|
618
620
|
end
|
619
621
|
|
620
622
|
it 'sets the data attribute on feature' do
|
621
|
-
expect(
|
623
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo', 'release_date' => 'bar')
|
622
624
|
end
|
623
625
|
|
624
626
|
it 'updates a data attribute' do
|
625
|
-
|
626
|
-
expect(
|
627
|
+
rollout.set_feature_data(:chat, description: 'baz')
|
628
|
+
expect(rollout.get(:chat).data).to include('description' => 'baz', 'release_date' => 'bar')
|
627
629
|
end
|
628
630
|
|
629
631
|
it 'only sets data on specified feature' do
|
630
|
-
|
631
|
-
expect(
|
632
|
-
expect(
|
632
|
+
rollout.set_feature_data(:talk, image_url: 'kittens.png')
|
633
|
+
expect(rollout.get(:chat).data).not_to include('image_url' => 'kittens.png')
|
634
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo', 'release_date' => 'bar')
|
633
635
|
end
|
634
636
|
|
635
637
|
it 'does not modify @data if param is nil' do
|
636
|
-
expect(
|
637
|
-
|
638
|
-
expect(
|
638
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo', 'release_date' => 'bar')
|
639
|
+
rollout.set_feature_data(:chat, nil)
|
640
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo', 'release_date' => 'bar')
|
639
641
|
end
|
640
642
|
|
641
643
|
it 'does not modify @data if param is empty string' do
|
642
|
-
expect(
|
643
|
-
|
644
|
-
expect(
|
644
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo', 'release_date' => 'bar')
|
645
|
+
rollout.set_feature_data(:chat, " ")
|
646
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo', 'release_date' => 'bar')
|
645
647
|
end
|
646
648
|
|
647
649
|
it 'properly parses data when it contains a |' do
|
648
650
|
user = double("User", id: 8)
|
649
|
-
|
650
|
-
|
651
|
-
expect(
|
652
|
-
expect(
|
651
|
+
rollout.activate_user(:chat, user)
|
652
|
+
rollout.set_feature_data(:chat, "|call||text|" => "a|bunch|of|stuff")
|
653
|
+
expect(rollout.get(:chat).data).to include("|call||text|" => "a|bunch|of|stuff")
|
654
|
+
expect(rollout.active?(:chat, user)).to be true
|
653
655
|
end
|
654
656
|
end
|
655
657
|
|
656
658
|
describe "#clear_feature_data" do
|
657
659
|
it 'resets data to empty string' do
|
658
|
-
|
659
|
-
expect(
|
660
|
-
|
661
|
-
expect(
|
660
|
+
rollout.set_feature_data(:chat, description: 'foo')
|
661
|
+
expect(rollout.get(:chat).data).to include('description' => 'foo')
|
662
|
+
rollout.clear_feature_data(:chat)
|
663
|
+
expect(rollout.get(:chat).data).to eq({})
|
662
664
|
end
|
663
665
|
end
|
664
666
|
|
665
667
|
describe 'Check if feature exists' do
|
666
668
|
it 'it should return true if the feature is exist' do
|
667
|
-
|
668
|
-
expect(
|
669
|
+
rollout.activate_percentage(:chat, 1)
|
670
|
+
expect(rollout.exists?(:chat)).to be true
|
669
671
|
end
|
670
672
|
|
671
673
|
it 'it should return false if the feature is not exist' do
|
672
|
-
expect(
|
673
|
-
end
|
674
|
-
end
|
675
|
-
end
|
676
|
-
|
677
|
-
describe "Rollout::Feature" do
|
678
|
-
describe "#add_user" do
|
679
|
-
it "ids a user using id_user_by" do
|
680
|
-
user = double("User", email: "test@test.com")
|
681
|
-
feature = Rollout::Feature.new(:chat, nil, id_user_by: :email)
|
682
|
-
feature.add_user(user)
|
683
|
-
expect(user).to have_received :email
|
684
|
-
end
|
685
|
-
end
|
686
|
-
|
687
|
-
describe "#initialize" do
|
688
|
-
describe "when string does not exist" do
|
689
|
-
it 'clears feature attributes when string is not given' do
|
690
|
-
feature = Rollout::Feature.new(:chat)
|
691
|
-
expect(feature.groups).to be_empty
|
692
|
-
expect(feature.users).to be_empty
|
693
|
-
expect(feature.percentage).to eq 0
|
694
|
-
expect(feature.data).to eq({})
|
695
|
-
end
|
696
|
-
|
697
|
-
it 'clears feature attributes when string is nil' do
|
698
|
-
feature = Rollout::Feature.new(:chat, nil)
|
699
|
-
expect(feature.groups).to be_empty
|
700
|
-
expect(feature.users).to be_empty
|
701
|
-
expect(feature.percentage).to eq 0
|
702
|
-
expect(feature.data).to eq({})
|
703
|
-
end
|
704
|
-
|
705
|
-
it 'clears feature attributes when string is empty string' do
|
706
|
-
feature = Rollout::Feature.new(:chat, "")
|
707
|
-
expect(feature.groups).to be_empty
|
708
|
-
expect(feature.users).to be_empty
|
709
|
-
expect(feature.percentage).to eq 0
|
710
|
-
expect(feature.data).to eq({})
|
711
|
-
end
|
712
|
-
|
713
|
-
describe "when there is no data" do
|
714
|
-
it 'sets @data to empty hash' do
|
715
|
-
feature = Rollout::Feature.new(:chat, "0||")
|
716
|
-
expect(feature.data).to eq({})
|
717
|
-
end
|
718
|
-
|
719
|
-
it 'sets @data to empty hash' do
|
720
|
-
feature = Rollout::Feature.new(:chat, "||| ")
|
721
|
-
expect(feature.data).to eq({})
|
722
|
-
end
|
723
|
-
end
|
674
|
+
expect(rollout.exists?(:chat)).to be false
|
724
675
|
end
|
725
676
|
end
|
726
677
|
end
|