rollout 2.2.1 → 2.2.2
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/.travis.yml +4 -0
- data/Gemfile.lock +46 -6
- data/README.md +17 -12
- data/lib/rollout.rb +3 -4
- data/lib/rollout/version.rb +1 -1
- data/rollout.gemspec +3 -2
- data/spec/rollout_spec.rb +0 -31
- data/spec/spec_helper.rb +1 -1
- metadata +21 -10
- data/lib/rollout/legacy.rb +0 -134
- data/spec/legacy_spec.rb +0 -221
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ba2a7c48e65a966b1b16abcb9efa4469eaadf61
|
4
|
+
data.tar.gz: ac9a3df6b56547de407611ee9f6faecf5b60acca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04d929b8f4cd7879140135c48f41a68080be70a6e17f6030657b68acae16f78459adf99a08772e491f64decbfbbcfe717699c2bf27c9cafc95be7acfad6d14d3
|
7
|
+
data.tar.gz: 39a9083e5295d7797a6c4aac21a1736c6df7a121c047f106b160de9400d2272bbf205529cf7f7a479aa922d418d14f0fe362bba896d099f3aa8ad67f1003d6bf
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,23 +1,61 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rollout (2.2.
|
4
|
+
rollout (2.2.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
addressable (2.4.0)
|
10
|
+
builder (3.2.2)
|
9
11
|
codeclimate-test-reporter (0.4.8)
|
10
12
|
simplecov (>= 0.7.1, < 1.0.0)
|
13
|
+
descendants_tracker (0.0.4)
|
14
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
11
15
|
diff-lcs (1.2.5)
|
12
16
|
docile (1.1.5)
|
17
|
+
fakeredis (0.5.0)
|
18
|
+
redis (~> 3.0)
|
19
|
+
faraday (0.9.2)
|
20
|
+
multipart-post (>= 1.2, < 3)
|
13
21
|
git (1.2.9.1)
|
14
|
-
|
15
|
-
|
22
|
+
github_api (0.13.1)
|
23
|
+
addressable (~> 2.4.0)
|
24
|
+
descendants_tracker (~> 0.0.4)
|
25
|
+
faraday (~> 0.8, < 0.10)
|
26
|
+
hashie (>= 3.4)
|
27
|
+
multi_json (>= 1.7.5, < 2.0)
|
28
|
+
oauth2
|
29
|
+
hashie (3.4.3)
|
30
|
+
highline (1.7.8)
|
31
|
+
jeweler (2.0.1)
|
32
|
+
builder
|
33
|
+
bundler (>= 1.0)
|
16
34
|
git (>= 1.2.5)
|
35
|
+
github_api
|
36
|
+
highline (>= 1.6.15)
|
37
|
+
nokogiri (>= 1.5.10)
|
17
38
|
rake
|
39
|
+
rdoc
|
18
40
|
json (1.8.3)
|
19
|
-
|
20
|
-
|
41
|
+
jwt (1.5.1)
|
42
|
+
mini_portile2 (2.0.0)
|
43
|
+
multi_json (1.11.2)
|
44
|
+
multi_xml (0.5.5)
|
45
|
+
multipart-post (2.0.0)
|
46
|
+
nokogiri (1.6.7.2)
|
47
|
+
mini_portile2 (~> 2.0.0.rc2)
|
48
|
+
oauth2 (1.1.0)
|
49
|
+
faraday (>= 0.8, < 0.10)
|
50
|
+
jwt (~> 1.0, < 1.5.2)
|
51
|
+
multi_json (~> 1.3)
|
52
|
+
multi_xml (~> 0.5)
|
53
|
+
rack (>= 1.2, < 3)
|
54
|
+
rack (1.6.4)
|
55
|
+
rake (10.5.0)
|
56
|
+
rdoc (4.2.2)
|
57
|
+
json (~> 1.4)
|
58
|
+
redis (3.2.2)
|
21
59
|
rspec (3.4.0)
|
22
60
|
rspec-core (~> 3.4.0)
|
23
61
|
rspec-expectations (~> 3.4.0)
|
@@ -36,6 +74,7 @@ GEM
|
|
36
74
|
json (~> 1.8)
|
37
75
|
simplecov-html (~> 0.10.0)
|
38
76
|
simplecov-html (0.10.0)
|
77
|
+
thread_safe (0.3.5)
|
39
78
|
|
40
79
|
PLATFORMS
|
41
80
|
ruby
|
@@ -43,7 +82,8 @@ PLATFORMS
|
|
43
82
|
DEPENDENCIES
|
44
83
|
bundler (>= 1.0.0)
|
45
84
|
codeclimate-test-reporter
|
46
|
-
|
85
|
+
fakeredis
|
86
|
+
jeweler
|
47
87
|
redis
|
48
88
|
rollout!
|
49
89
|
rspec
|
data/README.md
CHANGED
@@ -4,6 +4,8 @@ Feature flippers.
|
|
4
4
|
|
5
5
|
[](https://travis-ci.org/FetLife/rollout)
|
6
6
|
[](https://codeclimate.com/github/FetLife/rollout)
|
7
|
+
[](https://gemnasium.com/FetLife/rollout)
|
7
9
|
[//]: # ([](https://codeclimate.com/github/FetLife/rollout/coverage))
|
8
10
|
|
9
11
|
## MAKE SURE TO READ THIS: 2.X Changes and Migration Path
|
@@ -17,17 +19,6 @@ This also has the effect of rollout no longer being dependent on redis. Just
|
|
17
19
|
give it something that responds to `set(key,value)`, `get(key)` and
|
18
20
|
`del(key)`.
|
19
21
|
|
20
|
-
If you have been using the 1.x format, you can initialize Rollout with
|
21
|
-
`migrate: true` and it'll do its best to automatically migrate your old
|
22
|
-
features to the new format. There will be some performance impact, but it
|
23
|
-
should be limited and short-lived since each feature only needs to get
|
24
|
-
migrated once.
|
25
|
-
|
26
|
-
## Rollout::Legacy
|
27
|
-
|
28
|
-
If you'd prefer to continue to use the old layout in redis, `Rollout::Legacy`
|
29
|
-
is a copy and paste of the old code :-).
|
30
|
-
|
31
22
|
## Install it
|
32
23
|
|
33
24
|
```bash
|
@@ -138,7 +129,21 @@ $rollout = Rollout.new($redis, randomize_percentage: true)
|
|
138
129
|
When on `randomize_percentage` will make sure that 50% of users for feature A
|
139
130
|
are selected independently from users for feature B.
|
140
131
|
|
141
|
-
##
|
132
|
+
## Global actions
|
133
|
+
|
134
|
+
While groups can come in handy, the actual global setter for a feature does not require a group to be passed.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
$rollout.activate(:chat)
|
138
|
+
```
|
139
|
+
|
140
|
+
In that case you can check the global availability of a feature using the following
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
$rollout.active?(:chat)
|
144
|
+
```
|
145
|
+
|
146
|
+
And if something is wrong you can set a feature off for everybody using
|
142
147
|
|
143
148
|
Deactivate everybody at once:
|
144
149
|
|
data/lib/rollout.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require "rollout/version"
|
2
|
-
require "rollout/legacy"
|
3
2
|
require "zlib"
|
4
3
|
require "set"
|
5
4
|
|
@@ -50,13 +49,13 @@ class Rollout
|
|
50
49
|
end
|
51
50
|
|
52
51
|
def active?(rollout, user)
|
53
|
-
if user
|
54
|
-
@percentage == 100
|
55
|
-
else
|
52
|
+
if user
|
56
53
|
id = user_id(user)
|
57
54
|
user_in_percentage?(id) ||
|
58
55
|
user_in_active_users?(id) ||
|
59
56
|
user_in_active_group?(user, rollout)
|
57
|
+
else
|
58
|
+
@percentage == 100
|
60
59
|
end
|
61
60
|
end
|
62
61
|
|
data/lib/rollout/version.rb
CHANGED
data/rollout.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["jamesgolick@gmail.com"]
|
10
10
|
s.description = "Feature flippers with redis."
|
11
11
|
s.summary = "Feature flippers with redis."
|
12
|
-
s.homepage = "https://github.com/
|
12
|
+
s.homepage = "https://github.com/FetLife/rollout"
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -18,7 +18,8 @@ Gem::Specification.new do |s|
|
|
18
18
|
|
19
19
|
s.add_development_dependency "rspec"
|
20
20
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
21
|
-
s.add_development_dependency "jeweler"
|
21
|
+
s.add_development_dependency "jeweler"
|
22
22
|
s.add_development_dependency "redis"
|
23
|
+
s.add_development_dependency "fakeredis"
|
23
24
|
s.add_development_dependency "codeclimate-test-reporter"
|
24
25
|
end
|
data/spec/rollout_spec.rb
CHANGED
@@ -417,37 +417,6 @@ RSpec.describe "Rollout" do
|
|
417
417
|
end
|
418
418
|
end
|
419
419
|
|
420
|
-
describe "migration mode" do
|
421
|
-
before do
|
422
|
-
@legacy = Rollout::Legacy.new(@redis)
|
423
|
-
@legacy.activate_percentage(:chat, 12)
|
424
|
-
@legacy.activate_user(:chat, double(id: 42))
|
425
|
-
@legacy.activate_user(:chat, double(id: 24))
|
426
|
-
@legacy.activate_group(:chat, :dope_people)
|
427
|
-
@rollout = Rollout.new(@redis, migrate: true)
|
428
|
-
end
|
429
|
-
|
430
|
-
it "imports the settings from the legacy rollout once" do
|
431
|
-
expect(@rollout.get(:chat).to_hash).to eq({
|
432
|
-
percentage: 12,
|
433
|
-
users: %w(24 42),
|
434
|
-
groups: [:dope_people]
|
435
|
-
})
|
436
|
-
@legacy.deactivate_all(:chat)
|
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
|
443
|
-
end
|
444
|
-
|
445
|
-
it "imports settings that were globally activated" do
|
446
|
-
@legacy.activate_globally(:video_chat)
|
447
|
-
expect(@rollout.get(:video_chat).to_hash[:percentage]).to eq(100)
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
420
|
describe "#feature_states" do
|
452
421
|
let(:user_double) { double(id: 7) }
|
453
422
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,7 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
require "rollout"
|
4
4
|
require "rspec"
|
5
|
-
require "redis"
|
5
|
+
require ENV["USE_REAL_REDIS"] == "true" ? "redis" : "fakeredis"
|
6
6
|
require "codeclimate-test-reporter"
|
7
7
|
|
8
8
|
SimpleCov.start do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rollout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Golick
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: jeweler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: redis
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fakeredis
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: codeclimate-test-reporter
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,13 +110,11 @@ files:
|
|
96
110
|
- LICENSE
|
97
111
|
- README.md
|
98
112
|
- lib/rollout.rb
|
99
|
-
- lib/rollout/legacy.rb
|
100
113
|
- lib/rollout/version.rb
|
101
114
|
- rollout.gemspec
|
102
|
-
- spec/legacy_spec.rb
|
103
115
|
- spec/rollout_spec.rb
|
104
116
|
- spec/spec_helper.rb
|
105
|
-
homepage: https://github.com/
|
117
|
+
homepage: https://github.com/FetLife/rollout
|
106
118
|
licenses: []
|
107
119
|
metadata: {}
|
108
120
|
post_install_message:
|
@@ -126,6 +138,5 @@ signing_key:
|
|
126
138
|
specification_version: 4
|
127
139
|
summary: Feature flippers with redis.
|
128
140
|
test_files:
|
129
|
-
- spec/legacy_spec.rb
|
130
141
|
- spec/rollout_spec.rb
|
131
142
|
- spec/spec_helper.rb
|
data/lib/rollout/legacy.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
class Rollout
|
2
|
-
class Legacy
|
3
|
-
def initialize(redis)
|
4
|
-
@redis = redis
|
5
|
-
@groups = {"all" => lambda { |user| true }}
|
6
|
-
end
|
7
|
-
|
8
|
-
def activate_globally(feature)
|
9
|
-
@redis.sadd(global_key, feature)
|
10
|
-
end
|
11
|
-
|
12
|
-
def deactivate_globally(feature)
|
13
|
-
@redis.srem(global_key, feature)
|
14
|
-
end
|
15
|
-
|
16
|
-
def activate_group(feature, group)
|
17
|
-
@redis.sadd(group_key(feature), group)
|
18
|
-
end
|
19
|
-
|
20
|
-
def deactivate_group(feature, group)
|
21
|
-
@redis.srem(group_key(feature), group)
|
22
|
-
end
|
23
|
-
|
24
|
-
def deactivate_all(feature)
|
25
|
-
@redis.del(group_key(feature))
|
26
|
-
@redis.del(user_key(feature))
|
27
|
-
@redis.del(percentage_key(feature))
|
28
|
-
deactivate_globally(feature)
|
29
|
-
end
|
30
|
-
|
31
|
-
def activate_user(feature, user)
|
32
|
-
@redis.sadd(user_key(feature), user.id)
|
33
|
-
end
|
34
|
-
|
35
|
-
def deactivate_user(feature, user)
|
36
|
-
@redis.srem(user_key(feature), user.id)
|
37
|
-
end
|
38
|
-
|
39
|
-
def define_group(group, &block)
|
40
|
-
@groups[group.to_s] = block
|
41
|
-
end
|
42
|
-
|
43
|
-
def active?(feature, user = nil)
|
44
|
-
if user
|
45
|
-
active_globally?(feature) ||
|
46
|
-
user_in_active_group?(feature, user) ||
|
47
|
-
user_active?(feature, user) ||
|
48
|
-
user_within_active_percentage?(feature, user)
|
49
|
-
else
|
50
|
-
active_globally?(feature)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def activate_percentage(feature, percentage)
|
55
|
-
@redis.set(percentage_key(feature), percentage)
|
56
|
-
end
|
57
|
-
|
58
|
-
def deactivate_percentage(feature)
|
59
|
-
@redis.del(percentage_key(feature))
|
60
|
-
end
|
61
|
-
|
62
|
-
def info(feature = nil)
|
63
|
-
if feature
|
64
|
-
{
|
65
|
-
:percentage => (active_percentage(feature) || 0).to_i,
|
66
|
-
:groups => active_groups(feature).map { |g| g.to_sym },
|
67
|
-
:users => active_user_ids(feature),
|
68
|
-
:global => active_global_features
|
69
|
-
}
|
70
|
-
else
|
71
|
-
{
|
72
|
-
:global => active_global_features
|
73
|
-
}
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
def key(name)
|
79
|
-
"feature:#{name}"
|
80
|
-
end
|
81
|
-
|
82
|
-
def group_key(name)
|
83
|
-
"#{key(name)}:groups"
|
84
|
-
end
|
85
|
-
|
86
|
-
def user_key(name)
|
87
|
-
"#{key(name)}:users"
|
88
|
-
end
|
89
|
-
|
90
|
-
def percentage_key(name)
|
91
|
-
"#{key(name)}:percentage"
|
92
|
-
end
|
93
|
-
|
94
|
-
def global_key
|
95
|
-
"feature:__global__"
|
96
|
-
end
|
97
|
-
|
98
|
-
def active_groups(feature)
|
99
|
-
@redis.smembers(group_key(feature)) || []
|
100
|
-
end
|
101
|
-
|
102
|
-
def active_user_ids(feature)
|
103
|
-
@redis.smembers(user_key(feature)).map { |id| id.to_i }
|
104
|
-
end
|
105
|
-
|
106
|
-
def active_global_features
|
107
|
-
(@redis.smembers(global_key) || []).map(&:to_sym)
|
108
|
-
end
|
109
|
-
|
110
|
-
def active_percentage(feature)
|
111
|
-
@redis.get(percentage_key(feature))
|
112
|
-
end
|
113
|
-
|
114
|
-
def active_globally?(feature)
|
115
|
-
@redis.sismember(global_key, feature)
|
116
|
-
end
|
117
|
-
|
118
|
-
def user_in_active_group?(feature, user)
|
119
|
-
active_groups(feature).any? do |group|
|
120
|
-
@groups.key?(group) && @groups[group].call(user)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def user_active?(feature, user)
|
125
|
-
@redis.sismember(user_key(feature), user.id)
|
126
|
-
end
|
127
|
-
|
128
|
-
def user_within_active_percentage?(feature, user)
|
129
|
-
percentage = active_percentage(feature)
|
130
|
-
return false if percentage.nil?
|
131
|
-
user.id % 100 < percentage.to_i
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
data/spec/legacy_spec.rb
DELETED
@@ -1,221 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
RSpec.describe "Rollout::Legacy" do
|
4
|
-
before do
|
5
|
-
@redis = Redis.new
|
6
|
-
@rollout = Rollout::Legacy.new(@redis)
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "when a group is activated" do
|
10
|
-
before do
|
11
|
-
@rollout.define_group(:fivesonly) { |user| user.id == 5 }
|
12
|
-
@rollout.activate_group(:chat, :fivesonly)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "the feature is active for users for which the block evaluates to true" do
|
16
|
-
expect(@rollout).to be_active(:chat, double(id: 5))
|
17
|
-
end
|
18
|
-
|
19
|
-
it "is not active for users for which the block evaluates to false" do
|
20
|
-
expect(@rollout).not_to be_active(:chat, double(id: 1))
|
21
|
-
end
|
22
|
-
|
23
|
-
it "is not active if a group is found in Redis but not defined in Rollout" do
|
24
|
-
@rollout.activate_group(:chat, :fake)
|
25
|
-
expect(@rollout).not_to be_active(:chat, double(id: 1))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "the default all group" do
|
30
|
-
before do
|
31
|
-
@rollout.activate_group(:chat, :all)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "evaluates to true no matter what" do
|
35
|
-
expect(@rollout).to be_active(:chat, double(id: 0))
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe "deactivating a group" do
|
40
|
-
before do
|
41
|
-
@rollout.define_group(:fivesonly) { |user| user.id == 5 }
|
42
|
-
@rollout.activate_group(:chat, :all)
|
43
|
-
@rollout.activate_group(:chat, :fivesonly)
|
44
|
-
@rollout.deactivate_group(:chat, :all)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "deactivates the rules for that group" do
|
48
|
-
expect(@rollout).not_to be_active(:chat, double(id: 10))
|
49
|
-
end
|
50
|
-
|
51
|
-
it "leaves the other groups active" do
|
52
|
-
expect(@rollout).to be_active(:chat, double(id: 5))
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "deactivating a feature completely" do
|
57
|
-
before do
|
58
|
-
@rollout.define_group(:fivesonly) { |user| user.id == 5 }
|
59
|
-
@rollout.activate_group(:chat, :all)
|
60
|
-
@rollout.activate_group(:chat, :fivesonly)
|
61
|
-
@rollout.activate_user(:chat, double(id: 51))
|
62
|
-
@rollout.activate_percentage(:chat, 100)
|
63
|
-
@rollout.activate_globally(:chat)
|
64
|
-
@rollout.deactivate_all(:chat)
|
65
|
-
end
|
66
|
-
|
67
|
-
it "removes all of the groups" do
|
68
|
-
expect(@rollout).not_to be_active(:chat, double(id: 0))
|
69
|
-
end
|
70
|
-
|
71
|
-
it "removes all of the users" do
|
72
|
-
expect(@rollout).not_to be_active(:chat, double(id: 51))
|
73
|
-
end
|
74
|
-
|
75
|
-
it "removes the percentage" do
|
76
|
-
expect(@rollout).not_to be_active(:chat, double(id: 24))
|
77
|
-
end
|
78
|
-
|
79
|
-
it "removes globally" do
|
80
|
-
expect(@rollout).not_to be_active(:chat)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe "activating a specific user" do
|
85
|
-
before do
|
86
|
-
@rollout.activate_user(:chat, double(id: 42))
|
87
|
-
end
|
88
|
-
|
89
|
-
it "is active for that user" do
|
90
|
-
expect(@rollout).to be_active(:chat, double(id: 42))
|
91
|
-
end
|
92
|
-
|
93
|
-
it "remains inactive for other users" do
|
94
|
-
expect(@rollout).not_to be_active(:chat, double(id: 24))
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe "deactivating a specific user" do
|
99
|
-
before do
|
100
|
-
@rollout.activate_user(:chat, double(id: 42))
|
101
|
-
@rollout.activate_user(:chat, double(id: 24))
|
102
|
-
@rollout.deactivate_user(:chat, double(id: 42))
|
103
|
-
end
|
104
|
-
|
105
|
-
it "that user should no longer be active" do
|
106
|
-
expect(@rollout).not_to be_active(:chat, double(id: 42))
|
107
|
-
end
|
108
|
-
|
109
|
-
it "remains active for other active users" do
|
110
|
-
expect(@rollout).to be_active(:chat, double(id: 24))
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe "activating a feature globally" do
|
115
|
-
before do
|
116
|
-
@rollout.activate_globally(:chat)
|
117
|
-
end
|
118
|
-
|
119
|
-
it "activates the feature" do
|
120
|
-
expect(@rollout).to be_active(:chat)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
describe "activating a feature for a percentage of users" do
|
125
|
-
before do
|
126
|
-
@rollout.activate_percentage(:chat, 20)
|
127
|
-
end
|
128
|
-
|
129
|
-
it "activates the feature for that percentage of the users" do
|
130
|
-
expect((1..120).select { |id| @rollout.active?(:chat, double(id: id)) }.length).to eq(39)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe "activating a feature for a percentage of users" do
|
135
|
-
before do
|
136
|
-
@rollout.activate_percentage(:chat, 20)
|
137
|
-
end
|
138
|
-
|
139
|
-
it "activates the feature for that percentage of the users" do
|
140
|
-
expect((1..200).select { |id| @rollout.active?(:chat, double(id: id)) }.length).to eq(40)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe "activating a feature for a percentage of users" do
|
145
|
-
before do
|
146
|
-
@rollout.activate_percentage(:chat, 5)
|
147
|
-
end
|
148
|
-
|
149
|
-
it "activates the feature for that percentage of the users" do
|
150
|
-
expect((1..100).select { |id| @rollout.active?(:chat, double(id: id)) }.length).to eq(5)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
|
155
|
-
describe "deactivating the percentage of users" do
|
156
|
-
before do
|
157
|
-
@rollout.activate_percentage(:chat, 100)
|
158
|
-
@rollout.deactivate_percentage(:chat)
|
159
|
-
end
|
160
|
-
|
161
|
-
it "becomes inactivate for all users" do
|
162
|
-
expect(@rollout).not_to be_active(:chat, double(id: 24))
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
describe "deactivating the feature globally" do
|
167
|
-
before do
|
168
|
-
@rollout.activate_globally(:chat)
|
169
|
-
@rollout.deactivate_globally(:chat)
|
170
|
-
end
|
171
|
-
|
172
|
-
it "becomes inactivate" do
|
173
|
-
expect(@rollout).not_to be_active(:chat)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "#info" do
|
178
|
-
context "global features" do
|
179
|
-
let(:features) { [:signup, :chat, :table] }
|
180
|
-
|
181
|
-
before do
|
182
|
-
features.each do |f|
|
183
|
-
@rollout.activate_globally(f)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
it "returns all global features" do
|
188
|
-
expect(@rollout.info[:global]).to include(*features)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe "with a percentage set" do
|
193
|
-
before do
|
194
|
-
@rollout.activate_percentage(:chat, 10)
|
195
|
-
@rollout.activate_group(:chat, :caretakers)
|
196
|
-
@rollout.activate_group(:chat, :greeters)
|
197
|
-
@rollout.activate_globally(:signup)
|
198
|
-
@rollout.activate_user(:chat, double(id: 42))
|
199
|
-
end
|
200
|
-
|
201
|
-
it "returns info about all the activations" do
|
202
|
-
info = @rollout.info(:chat)
|
203
|
-
expect(info[:percentage]).to eq(10)
|
204
|
-
expect(info[:groups]).to include(:caretakers, :greeters)
|
205
|
-
expect(info[:users]).to include(42)
|
206
|
-
expect(info[:global]).to include(:signup)
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
describe "without a percentage set" do
|
211
|
-
it "defaults to 0" do
|
212
|
-
expect(@rollout.info(:chat)).to eq(
|
213
|
-
percentage: 0,
|
214
|
-
groups: [],
|
215
|
-
users: [],
|
216
|
-
global: [],
|
217
|
-
)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|