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