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