flipper 0.28.2 → 1.0.0.pre
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/Changelog.md +27 -0
- data/Gemfile +5 -3
- data/docs/images/flipper_cloud.png +0 -0
- data/examples/cloud/app.ru +12 -0
- data/examples/cloud/basic.rb +22 -0
- data/examples/cloud/cloud_setup.rb +4 -0
- data/examples/cloud/forked.rb +31 -0
- data/examples/cloud/import.rb +17 -0
- data/examples/cloud/threaded.rb +36 -0
- data/examples/dsl.rb +0 -14
- data/flipper-cloud.gemspec +19 -0
- data/flipper.gemspec +3 -2
- data/lib/flipper/cloud/configuration.rb +189 -0
- data/lib/flipper/cloud/dsl.rb +27 -0
- data/lib/flipper/cloud/instrumenter.rb +48 -0
- data/lib/flipper/cloud/message_verifier.rb +95 -0
- data/lib/flipper/cloud/middleware.rb +63 -0
- data/lib/flipper/cloud/routes.rb +14 -0
- data/lib/flipper/cloud.rb +53 -0
- data/lib/flipper/dsl.rb +0 -46
- data/lib/flipper/{railtie.rb → engine.rb} +19 -3
- data/lib/flipper/metadata.rb +5 -1
- data/lib/flipper/spec/shared_adapter_specs.rb +43 -43
- data/lib/flipper/test/shared_adapter_test.rb +43 -43
- data/lib/flipper/version.rb +1 -1
- data/lib/flipper.rb +3 -5
- data/spec/flipper/adapters/dual_write_spec.rb +2 -2
- data/spec/flipper/adapters/instrumented_spec.rb +1 -1
- data/spec/flipper/adapters/memoizable_spec.rb +6 -6
- data/spec/flipper/adapters/operation_logger_spec.rb +2 -2
- data/spec/flipper/adapters/read_only_spec.rb +6 -6
- data/spec/flipper/cloud/configuration_spec.rb +269 -0
- data/spec/flipper/cloud/dsl_spec.rb +82 -0
- data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
- data/spec/flipper/cloud/middleware_spec.rb +289 -0
- data/spec/flipper/cloud_spec.rb +180 -0
- data/spec/flipper/dsl_spec.rb +0 -75
- data/spec/flipper/engine_spec.rb +190 -0
- data/spec/flipper_integration_spec.rb +12 -12
- data/spec/flipper_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -12
- data/spec/support/climate_control.rb +7 -0
- metadata +54 -10
- data/spec/flipper/railtie_spec.rb +0 -109
@@ -48,20 +48,20 @@ module Flipper
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_can_enable_disable_and_get_value_for_boolean_gate
|
51
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
51
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
52
52
|
assert_equal 'true', @adapter.get(@feature)[:boolean]
|
53
|
-
assert_equal true, @adapter.disable(@feature, @boolean_gate,
|
53
|
+
assert_equal true, @adapter.disable(@feature, @boolean_gate, Flipper::Types::Boolean.new(false))
|
54
54
|
assert_nil @adapter.get(@feature)[:boolean]
|
55
55
|
end
|
56
56
|
|
57
57
|
def test_fully_disables_all_enabled_things_when_boolean_gate_disabled
|
58
58
|
actor22 = Flipper::Actor.new('22')
|
59
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
59
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
60
60
|
assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
|
61
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
62
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
63
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
64
|
-
assert_equal true, @adapter.disable(@feature, @boolean_gate,
|
61
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor22))
|
62
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
63
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(45))
|
64
|
+
assert_equal true, @adapter.disable(@feature, @boolean_gate, Flipper::Types::Boolean.new(false))
|
65
65
|
assert_equal @adapter.default_config, @adapter.get(@feature)
|
66
66
|
end
|
67
67
|
|
@@ -85,34 +85,34 @@ module Flipper
|
|
85
85
|
actor22 = Flipper::Actor.new('22')
|
86
86
|
actor_asdf = Flipper::Actor.new('asdf')
|
87
87
|
|
88
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
89
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
88
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor22))
|
89
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor_asdf))
|
90
90
|
|
91
91
|
result = @adapter.get(@feature)
|
92
92
|
assert_equal Set['22', 'asdf'], result[:actors]
|
93
93
|
|
94
|
-
assert true, @adapter.disable(@feature, @actor_gate,
|
94
|
+
assert true, @adapter.disable(@feature, @actor_gate, Flipper::Types::Actor.new(actor22))
|
95
95
|
result = @adapter.get(@feature)
|
96
96
|
assert_equal Set['asdf'], result[:actors]
|
97
97
|
|
98
|
-
assert_equal true, @adapter.disable(@feature, @actor_gate,
|
98
|
+
assert_equal true, @adapter.disable(@feature, @actor_gate, Flipper::Types::Actor.new(actor_asdf))
|
99
99
|
result = @adapter.get(@feature)
|
100
100
|
assert_equal Set.new, result[:actors]
|
101
101
|
end
|
102
102
|
|
103
103
|
def test_can_enable_disable_get_value_for_percentage_of_actors_gate
|
104
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
104
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(15))
|
105
105
|
result = @adapter.get(@feature)
|
106
106
|
assert_equal '15', result[:percentage_of_actors]
|
107
107
|
|
108
|
-
assert_equal true, @adapter.disable(@feature, @actors_gate,
|
108
|
+
assert_equal true, @adapter.disable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(0))
|
109
109
|
result = @adapter.get(@feature)
|
110
110
|
assert_equal '0', result[:percentage_of_actors]
|
111
111
|
end
|
112
112
|
|
113
113
|
def test_can_enable_percentage_of_actors_gate_many_times_and_consistently_return_values
|
114
114
|
(1..100).each do |percentage|
|
115
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
115
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(percentage))
|
116
116
|
result = @adapter.get(@feature)
|
117
117
|
assert_equal percentage.to_s, result[:percentage_of_actors]
|
118
118
|
end
|
@@ -120,25 +120,25 @@ module Flipper
|
|
120
120
|
|
121
121
|
def test_can_disable_percentage_of_actors_gate_many_times_and_consistently_return_values
|
122
122
|
(1..100).each do |percentage|
|
123
|
-
assert_equal true, @adapter.disable(@feature, @actors_gate,
|
123
|
+
assert_equal true, @adapter.disable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(percentage))
|
124
124
|
result = @adapter.get(@feature)
|
125
125
|
assert_equal percentage.to_s, result[:percentage_of_actors]
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
129
|
def test_can_enable_disable_and_get_value_for_percentage_of_time_gate
|
130
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
130
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(10))
|
131
131
|
result = @adapter.get(@feature)
|
132
132
|
assert_equal '10', result[:percentage_of_time]
|
133
133
|
|
134
|
-
assert_equal true, @adapter.disable(@feature, @time_gate,
|
134
|
+
assert_equal true, @adapter.disable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(0))
|
135
135
|
result = @adapter.get(@feature)
|
136
136
|
assert_equal '0', result[:percentage_of_time]
|
137
137
|
end
|
138
138
|
|
139
139
|
def test_can_enable_percentage_of_time_gate_many_times_and_consistently_return_values
|
140
140
|
(1..100).each do |percentage|
|
141
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
141
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(percentage))
|
142
142
|
result = @adapter.get(@feature)
|
143
143
|
assert_equal percentage.to_s, result[:percentage_of_time]
|
144
144
|
end
|
@@ -146,21 +146,21 @@ module Flipper
|
|
146
146
|
|
147
147
|
def test_can_disable_percentage_of_time_gate_many_times_and_consistently_return_values
|
148
148
|
(1..100).each do |percentage|
|
149
|
-
assert_equal true, @adapter.disable(@feature, @time_gate,
|
149
|
+
assert_equal true, @adapter.disable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(percentage))
|
150
150
|
result = @adapter.get(@feature)
|
151
151
|
assert_equal percentage.to_s, result[:percentage_of_time]
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
155
|
def test_converts_boolean_value_to_a_string
|
156
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
156
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
157
157
|
result = @adapter.get(@feature)
|
158
158
|
assert_equal 'true', result[:boolean]
|
159
159
|
end
|
160
160
|
|
161
161
|
def test_converts_the_actor_value_to_a_string
|
162
162
|
assert_equal true,
|
163
|
-
@adapter.enable(@feature, @actor_gate,
|
163
|
+
@adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(Flipper::Actor.new(22)))
|
164
164
|
result = @adapter.get(@feature)
|
165
165
|
assert_equal Set['22'], result[:actors]
|
166
166
|
end
|
@@ -172,13 +172,13 @@ module Flipper
|
|
172
172
|
end
|
173
173
|
|
174
174
|
def test_converts_percentage_of_time_integer_value_to_a_string
|
175
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
175
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(10))
|
176
176
|
result = @adapter.get(@feature)
|
177
177
|
assert_equal '10', result[:percentage_of_time]
|
178
178
|
end
|
179
179
|
|
180
180
|
def test_converts_percentage_of_actors_integer_value_to_a_string
|
181
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
181
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(10))
|
182
182
|
result = @adapter.get(@feature)
|
183
183
|
assert_equal '10', result[:percentage_of_actors]
|
184
184
|
end
|
@@ -201,11 +201,11 @@ module Flipper
|
|
201
201
|
|
202
202
|
def test_clears_all_the_gate_values_for_the_feature_on_remove
|
203
203
|
actor22 = Flipper::Actor.new('22')
|
204
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
204
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
205
205
|
assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
|
206
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
207
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
208
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
206
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor22))
|
207
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
208
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(45))
|
209
209
|
|
210
210
|
assert_equal true, @adapter.remove(@feature)
|
211
211
|
|
@@ -217,11 +217,11 @@ module Flipper
|
|
217
217
|
@adapter.add(@feature)
|
218
218
|
assert_includes @adapter.features, @feature.key
|
219
219
|
|
220
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
220
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
221
221
|
assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
|
222
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
223
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
224
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
222
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor22))
|
223
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
224
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(45))
|
225
225
|
|
226
226
|
assert_equal true, @adapter.clear(@feature)
|
227
227
|
assert_includes @adapter.features, @feature.key
|
@@ -234,7 +234,7 @@ module Flipper
|
|
234
234
|
|
235
235
|
def test_can_get_multiple_features
|
236
236
|
assert @adapter.add(@flipper[:stats])
|
237
|
-
assert @adapter.enable(@flipper[:stats], @boolean_gate,
|
237
|
+
assert @adapter.enable(@flipper[:stats], @boolean_gate, Flipper::Types::Boolean.new)
|
238
238
|
assert @adapter.add(@flipper[:search])
|
239
239
|
|
240
240
|
result = @adapter.get_multi([@flipper[:stats], @flipper[:search], @flipper[:other]])
|
@@ -250,7 +250,7 @@ module Flipper
|
|
250
250
|
|
251
251
|
def test_can_get_all_features
|
252
252
|
assert @adapter.add(@flipper[:stats])
|
253
|
-
assert @adapter.enable(@flipper[:stats], @boolean_gate,
|
253
|
+
assert @adapter.enable(@flipper[:stats], @boolean_gate, Flipper::Types::Boolean.new)
|
254
254
|
assert @adapter.add(@flipper[:search])
|
255
255
|
|
256
256
|
result = @adapter.get_all
|
@@ -273,8 +273,8 @@ module Flipper
|
|
273
273
|
|
274
274
|
def test_can_double_enable_an_actor_without_error
|
275
275
|
actor = Flipper::Actor.new('Flipper::Actor;22')
|
276
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
277
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
276
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor))
|
277
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor))
|
278
278
|
assert_equal Set['Flipper::Actor;22'], @adapter.get(@feature).fetch(:actors)
|
279
279
|
end
|
280
280
|
|
@@ -285,13 +285,13 @@ module Flipper
|
|
285
285
|
end
|
286
286
|
|
287
287
|
def test_can_double_enable_percentage_without_error
|
288
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
289
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
288
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
289
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
290
290
|
end
|
291
291
|
|
292
292
|
def test_can_double_enable_without_error
|
293
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
294
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
293
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
294
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new)
|
295
295
|
end
|
296
296
|
|
297
297
|
def test_can_get_all_features_when_there_are_none
|
@@ -302,11 +302,11 @@ module Flipper
|
|
302
302
|
|
303
303
|
def test_clears_other_gate_values_on_enable
|
304
304
|
actor = Flipper::Actor.new('Flipper::Actor;22')
|
305
|
-
assert_equal true, @adapter.enable(@feature, @actors_gate,
|
306
|
-
assert_equal true, @adapter.enable(@feature, @time_gate,
|
305
|
+
assert_equal true, @adapter.enable(@feature, @actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
306
|
+
assert_equal true, @adapter.enable(@feature, @time_gate, Flipper::Types::PercentageOfTime.new(25))
|
307
307
|
assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
|
308
|
-
assert_equal true, @adapter.enable(@feature, @actor_gate,
|
309
|
-
assert_equal true, @adapter.enable(@feature, @boolean_gate,
|
308
|
+
assert_equal true, @adapter.enable(@feature, @actor_gate, Flipper::Types::Actor.new(actor))
|
309
|
+
assert_equal true, @adapter.enable(@feature, @boolean_gate, Flipper::Types::Boolean.new(true))
|
310
310
|
assert_equal @adapter.default_config.merge(boolean: "true"), @adapter.get(@feature)
|
311
311
|
end
|
312
312
|
|
data/lib/flipper/version.rb
CHANGED
data/lib/flipper.rb
CHANGED
@@ -56,13 +56,11 @@ module Flipper
|
|
56
56
|
# Public: All the methods delegated to instance. These should match the
|
57
57
|
# interface of Flipper::DSL.
|
58
58
|
def_delegators :instance,
|
59
|
-
:enabled?, :enable, :disable,
|
60
|
-
:enable_actor, :disable_actor,
|
59
|
+
:enabled?, :enable, :disable,
|
60
|
+
:enable_actor, :disable_actor,
|
61
61
|
:enable_group, :disable_group,
|
62
62
|
:enable_percentage_of_actors, :disable_percentage_of_actors,
|
63
|
-
:actors, :percentage_of_actors,
|
64
63
|
:enable_percentage_of_time, :disable_percentage_of_time,
|
65
|
-
:time, :percentage_of_time,
|
66
64
|
:features, :feature, :[], :preload, :preload_all,
|
67
65
|
:adapter, :add, :exist?, :remove, :import, :export,
|
68
66
|
:memoize=, :memoizing?,
|
@@ -167,4 +165,4 @@ require 'flipper/types/percentage_of_time'
|
|
167
165
|
require 'flipper/typecast'
|
168
166
|
require 'flipper/version'
|
169
167
|
|
170
|
-
require "flipper/
|
168
|
+
require "flipper/engine" if defined?(Rails)
|
@@ -55,14 +55,14 @@ RSpec.describe Flipper::Adapters::DualWrite do
|
|
55
55
|
|
56
56
|
it 'updates remote and local for #enable' do
|
57
57
|
feature = sync[:search]
|
58
|
-
subject.enable feature, feature.gate(:boolean),
|
58
|
+
subject.enable feature, feature.gate(:boolean), Flipper::Types::Boolean.new(true)
|
59
59
|
expect(remote_adapter.count(:enable)).to be(1)
|
60
60
|
expect(local_adapter.count(:enable)).to be(1)
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'updates remote and local for #disable' do
|
64
64
|
feature = sync[:search]
|
65
|
-
subject.disable feature, feature.gate(:boolean),
|
65
|
+
subject.disable feature, feature.gate(:boolean), Flipper::Types::Boolean.new(false)
|
66
66
|
expect(remote_adapter.count(:disable)).to be(1)
|
67
67
|
expect(local_adapter.count(:disable)).to be(1)
|
68
68
|
end
|
@@ -8,7 +8,7 @@ RSpec.describe Flipper::Adapters::Instrumented do
|
|
8
8
|
|
9
9
|
let(:feature) { flipper[:stats] }
|
10
10
|
let(:gate) { feature.gate(:percentage_of_actors) }
|
11
|
-
let(:thing) {
|
11
|
+
let(:thing) { Flipper::Types::PercentageOfActors.new(22) }
|
12
12
|
|
13
13
|
subject do
|
14
14
|
described_class.new(adapter, instrumenter: instrumenter)
|
@@ -189,7 +189,7 @@ RSpec.describe Flipper::Adapters::Memoizable do
|
|
189
189
|
feature = flipper[:stats]
|
190
190
|
gate = feature.gate(:boolean)
|
191
191
|
cache[described_class.key_for(feature.key)] = { some: 'thing' }
|
192
|
-
subject.enable(feature, gate,
|
192
|
+
subject.enable(feature, gate, Flipper::Types::Boolean.new)
|
193
193
|
expect(cache[described_class.key_for(feature.key)]).to be_nil
|
194
194
|
end
|
195
195
|
end
|
@@ -202,8 +202,8 @@ RSpec.describe Flipper::Adapters::Memoizable do
|
|
202
202
|
it 'returns result' do
|
203
203
|
feature = flipper[:stats]
|
204
204
|
gate = feature.gate(:boolean)
|
205
|
-
result = subject.enable(feature, gate,
|
206
|
-
adapter_result = adapter.enable(feature, gate,
|
205
|
+
result = subject.enable(feature, gate, Flipper::Types::Boolean.new)
|
206
|
+
adapter_result = adapter.enable(feature, gate, Flipper::Types::Boolean.new)
|
207
207
|
expect(result).to eq(adapter_result)
|
208
208
|
end
|
209
209
|
end
|
@@ -219,7 +219,7 @@ RSpec.describe Flipper::Adapters::Memoizable do
|
|
219
219
|
feature = flipper[:stats]
|
220
220
|
gate = feature.gate(:boolean)
|
221
221
|
cache[described_class.key_for(feature.key)] = { some: 'thing' }
|
222
|
-
subject.disable(feature, gate,
|
222
|
+
subject.disable(feature, gate, Flipper::Types::Boolean.new)
|
223
223
|
expect(cache[described_class.key_for(feature.key)]).to be_nil
|
224
224
|
end
|
225
225
|
end
|
@@ -232,8 +232,8 @@ RSpec.describe Flipper::Adapters::Memoizable do
|
|
232
232
|
it 'returns result' do
|
233
233
|
feature = flipper[:stats]
|
234
234
|
gate = feature.gate(:boolean)
|
235
|
-
result = subject.disable(feature, gate,
|
236
|
-
adapter_result = adapter.disable(feature, gate,
|
235
|
+
result = subject.disable(feature, gate, Flipper::Types::Boolean.new)
|
236
|
+
adapter_result = adapter.disable(feature, gate, Flipper::Types::Boolean.new)
|
237
237
|
expect(result).to eq(adapter_result)
|
238
238
|
end
|
239
239
|
end
|
@@ -37,7 +37,7 @@ RSpec.describe Flipper::Adapters::OperationLogger do
|
|
37
37
|
before do
|
38
38
|
@feature = flipper[:stats]
|
39
39
|
@gate = @feature.gate(:boolean)
|
40
|
-
@thing =
|
40
|
+
@thing = Flipper::Types::Boolean.new
|
41
41
|
@result = subject.enable(@feature, @gate, @thing)
|
42
42
|
end
|
43
43
|
|
@@ -54,7 +54,7 @@ RSpec.describe Flipper::Adapters::OperationLogger do
|
|
54
54
|
before do
|
55
55
|
@feature = flipper[:stats]
|
56
56
|
@gate = @feature.gate(:boolean)
|
57
|
-
@thing =
|
57
|
+
@thing = Flipper::Types::Boolean.new
|
58
58
|
@result = subject.disable(@feature, @gate, @thing)
|
59
59
|
end
|
60
60
|
|
@@ -42,11 +42,11 @@ RSpec.describe Flipper::Adapters::ReadOnly do
|
|
42
42
|
|
43
43
|
it 'can get feature' do
|
44
44
|
actor22 = Flipper::Actor.new('22')
|
45
|
-
adapter.enable(feature, boolean_gate,
|
45
|
+
adapter.enable(feature, boolean_gate, Flipper::Types::Boolean.new)
|
46
46
|
adapter.enable(feature, group_gate, flipper.group(:admins))
|
47
|
-
adapter.enable(feature, actor_gate,
|
48
|
-
adapter.enable(feature, actors_gate,
|
49
|
-
adapter.enable(feature, time_gate,
|
47
|
+
adapter.enable(feature, actor_gate, Flipper::Types::Actor.new(actor22))
|
48
|
+
adapter.enable(feature, actors_gate, Flipper::Types::PercentageOfActors.new(25))
|
49
|
+
adapter.enable(feature, time_gate, Flipper::Types::PercentageOfTime.new(45))
|
50
50
|
|
51
51
|
expect(subject.get(feature)).to eq(boolean: 'true',
|
52
52
|
groups: Set['admins'],
|
@@ -74,12 +74,12 @@ RSpec.describe Flipper::Adapters::ReadOnly do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it 'raises error on enable' do
|
77
|
-
expect { subject.enable(feature, boolean_gate,
|
77
|
+
expect { subject.enable(feature, boolean_gate, Flipper::Types::Boolean.new) }
|
78
78
|
.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'raises error on disable' do
|
82
|
-
expect { subject.disable(feature, boolean_gate,
|
82
|
+
expect { subject.disable(feature, boolean_gate, Flipper::Types::Boolean.new) }
|
83
83
|
.to raise_error(Flipper::Adapters::ReadOnly::WriteAttempted)
|
84
84
|
end
|
85
85
|
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require 'flipper/cloud/configuration'
|
2
|
+
require 'flipper/adapters/instrumented'
|
3
|
+
|
4
|
+
RSpec.describe Flipper::Cloud::Configuration do
|
5
|
+
let(:required_options) do
|
6
|
+
{ token: "asdf" }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "can set token" do
|
10
|
+
instance = described_class.new(required_options)
|
11
|
+
expect(instance.token).to eq(required_options[:token])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can set token from ENV var" do
|
15
|
+
with_env "FLIPPER_CLOUD_TOKEN" => "from_env" do
|
16
|
+
instance = described_class.new(required_options.reject { |k, v| k == :token })
|
17
|
+
expect(instance.token).to eq("from_env")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can set instrumenter" do
|
22
|
+
instrumenter = Object.new
|
23
|
+
instance = described_class.new(required_options.merge(instrumenter: instrumenter))
|
24
|
+
expect(instance.instrumenter).to be(instrumenter)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can set read_timeout" do
|
28
|
+
instance = described_class.new(required_options.merge(read_timeout: 5))
|
29
|
+
expect(instance.read_timeout).to eq(5)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can set read_timeout from ENV var" do
|
33
|
+
with_env "FLIPPER_CLOUD_READ_TIMEOUT" => "9" do
|
34
|
+
instance = described_class.new(required_options.reject { |k, v| k == :read_timeout })
|
35
|
+
expect(instance.read_timeout).to eq(9)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can set open_timeout" do
|
40
|
+
instance = described_class.new(required_options.merge(open_timeout: 5))
|
41
|
+
expect(instance.open_timeout).to eq(5)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can set open_timeout from ENV var" do
|
45
|
+
with_env "FLIPPER_CLOUD_OPEN_TIMEOUT" => "9" do
|
46
|
+
instance = described_class.new(required_options.reject { |k, v| k == :open_timeout })
|
47
|
+
expect(instance.open_timeout).to eq(9)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can set write_timeout" do
|
52
|
+
instance = described_class.new(required_options.merge(write_timeout: 5))
|
53
|
+
expect(instance.write_timeout).to eq(5)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "can set write_timeout from ENV var" do
|
57
|
+
with_env "FLIPPER_CLOUD_WRITE_TIMEOUT" => "9" do
|
58
|
+
instance = described_class.new(required_options.reject { |k, v| k == :write_timeout })
|
59
|
+
expect(instance.write_timeout).to eq(9)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can set sync_interval" do
|
64
|
+
instance = described_class.new(required_options.merge(sync_interval: 1))
|
65
|
+
expect(instance.sync_interval).to eq(1)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "can set sync_interval from ENV var" do
|
69
|
+
with_env "FLIPPER_CLOUD_SYNC_INTERVAL" => "5" do
|
70
|
+
instance = described_class.new(required_options.reject { |k, v| k == :sync_interval })
|
71
|
+
expect(instance.sync_interval).to eq(5)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "passes sync_interval into sync adapter" do
|
76
|
+
# The initial sync of http to local invokes this web request.
|
77
|
+
stub_request(:get, /flippercloud\.io/).to_return(status: 200, body: "{}")
|
78
|
+
|
79
|
+
instance = described_class.new(required_options.merge(sync_interval: 1))
|
80
|
+
poller = instance.send(:poller)
|
81
|
+
expect(poller.interval).to eq(1)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "can set debug_output" do
|
85
|
+
instance = described_class.new(required_options.merge(debug_output: STDOUT))
|
86
|
+
expect(instance.debug_output).to eq(STDOUT)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "defaults adapter block" do
|
90
|
+
# The initial sync of http to local invokes this web request.
|
91
|
+
stub_request(:get, /flippercloud\.io/).to_return(status: 200, body: "{}")
|
92
|
+
|
93
|
+
instance = described_class.new(required_options)
|
94
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::DualWrite)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "can override adapter block" do
|
98
|
+
# The initial sync of http to local invokes this web request.
|
99
|
+
stub_request(:get, /flippercloud\.io/).to_return(status: 200, body: "{}")
|
100
|
+
|
101
|
+
instance = described_class.new(required_options)
|
102
|
+
instance.adapter do |adapter|
|
103
|
+
Flipper::Adapters::Instrumented.new(adapter)
|
104
|
+
end
|
105
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::Instrumented)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "defaults url" do
|
109
|
+
instance = described_class.new(required_options.reject { |k, v| k == :url })
|
110
|
+
expect(instance.url).to eq("https://www.flippercloud.io/adapter")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "can override url using options" do
|
114
|
+
options = required_options.merge(url: "http://localhost:5000/adapter")
|
115
|
+
instance = described_class.new(options)
|
116
|
+
expect(instance.url).to eq("http://localhost:5000/adapter")
|
117
|
+
|
118
|
+
instance = described_class.new(required_options)
|
119
|
+
instance.url = "http://localhost:5000/adapter"
|
120
|
+
expect(instance.url).to eq("http://localhost:5000/adapter")
|
121
|
+
end
|
122
|
+
|
123
|
+
it "can override URL using ENV var" do
|
124
|
+
with_env "FLIPPER_CLOUD_URL" => "https://example.com" do
|
125
|
+
instance = described_class.new(required_options.reject { |k, v| k == :url })
|
126
|
+
expect(instance.url).to eq("https://example.com")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it "defaults sync_method to :poll" do
|
131
|
+
instance = described_class.new(required_options)
|
132
|
+
|
133
|
+
expect(instance.sync_method).to eq(:poll)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "sets sync_method to :webhook if sync_secret provided" do
|
137
|
+
instance = described_class.new(required_options.merge({
|
138
|
+
sync_secret: "secret",
|
139
|
+
}))
|
140
|
+
|
141
|
+
expect(instance.sync_method).to eq(:webhook)
|
142
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::DualWrite)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "sets sync_method to :webhook if FLIPPER_CLOUD_SYNC_SECRET set" do
|
146
|
+
with_env "FLIPPER_CLOUD_SYNC_SECRET" => "abc" do
|
147
|
+
instance = described_class.new(required_options)
|
148
|
+
|
149
|
+
expect(instance.sync_method).to eq(:webhook)
|
150
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::DualWrite)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it "can set sync_secret" do
|
155
|
+
instance = described_class.new(required_options.merge(sync_secret: "from_config"))
|
156
|
+
expect(instance.sync_secret).to eq("from_config")
|
157
|
+
end
|
158
|
+
|
159
|
+
it "can override sync_secret using ENV var" do
|
160
|
+
with_env "FLIPPER_CLOUD_SYNC_SECRET" => "from_env" do
|
161
|
+
instance = described_class.new(required_options.reject { |k, v| k == :sync_secret })
|
162
|
+
expect(instance.sync_secret).to eq("from_env")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it "can sync with cloud" do
|
167
|
+
body = JSON.generate({
|
168
|
+
"features": [
|
169
|
+
{
|
170
|
+
"key": "search",
|
171
|
+
"state": "on",
|
172
|
+
"gates": [
|
173
|
+
{
|
174
|
+
"key": "boolean",
|
175
|
+
"name": "boolean",
|
176
|
+
"value": true
|
177
|
+
},
|
178
|
+
{
|
179
|
+
"key": "groups",
|
180
|
+
"name": "group",
|
181
|
+
"value": []
|
182
|
+
},
|
183
|
+
{
|
184
|
+
"key": "actors",
|
185
|
+
"name": "actor",
|
186
|
+
"value": []
|
187
|
+
},
|
188
|
+
{
|
189
|
+
"key": "percentage_of_actors",
|
190
|
+
"name": "percentage_of_actors",
|
191
|
+
"value": 0
|
192
|
+
},
|
193
|
+
{
|
194
|
+
"key": "percentage_of_time",
|
195
|
+
"name": "percentage_of_time",
|
196
|
+
"value": 0
|
197
|
+
}
|
198
|
+
]
|
199
|
+
},
|
200
|
+
{
|
201
|
+
"key": "history",
|
202
|
+
"state": "off",
|
203
|
+
"gates": [
|
204
|
+
{
|
205
|
+
"key": "boolean",
|
206
|
+
"name": "boolean",
|
207
|
+
"value": false
|
208
|
+
},
|
209
|
+
{
|
210
|
+
"key": "groups",
|
211
|
+
"name": "group",
|
212
|
+
"value": []
|
213
|
+
},
|
214
|
+
{
|
215
|
+
"key": "actors",
|
216
|
+
"name": "actor",
|
217
|
+
"value": []
|
218
|
+
},
|
219
|
+
{
|
220
|
+
"key": "percentage_of_actors",
|
221
|
+
"name": "percentage_of_actors",
|
222
|
+
"value": 0
|
223
|
+
},
|
224
|
+
{
|
225
|
+
"key": "percentage_of_time",
|
226
|
+
"name": "percentage_of_time",
|
227
|
+
"value": 0
|
228
|
+
}
|
229
|
+
]
|
230
|
+
}
|
231
|
+
]
|
232
|
+
})
|
233
|
+
stub = stub_request(:get, "https://www.flippercloud.io/adapter/features?exclude_gate_names=true").
|
234
|
+
with({
|
235
|
+
headers: {
|
236
|
+
'Flipper-Cloud-Token'=>'asdf',
|
237
|
+
},
|
238
|
+
}).to_return(status: 200, body: body, headers: {})
|
239
|
+
instance = described_class.new(required_options)
|
240
|
+
instance.sync
|
241
|
+
|
242
|
+
# Check that remote was fetched.
|
243
|
+
expect(stub).to have_been_requested
|
244
|
+
|
245
|
+
# Check that local adapter really did sync.
|
246
|
+
local_adapter = instance.local_adapter
|
247
|
+
all = local_adapter.get_all
|
248
|
+
expect(all.keys).to eq(["search", "history"])
|
249
|
+
expect(all["search"][:boolean]).to eq("true")
|
250
|
+
expect(all["history"][:boolean]).to eq(nil)
|
251
|
+
end
|
252
|
+
|
253
|
+
it "can setup brow to report events to cloud" do
|
254
|
+
# skip logging brow
|
255
|
+
Brow.logger = Logger.new(File::NULL)
|
256
|
+
brow = described_class.new(required_options).brow
|
257
|
+
|
258
|
+
stub = stub_request(:post, "https://www.flippercloud.io/adapter/events")
|
259
|
+
.with { |request|
|
260
|
+
data = JSON.parse(request.body)
|
261
|
+
data.keys == ["uuid", "messages"] && data["messages"] == [{"n" => 1}]
|
262
|
+
}
|
263
|
+
.to_return(status: 201, body: "{}", headers: {})
|
264
|
+
|
265
|
+
brow.push({"n" => 1})
|
266
|
+
brow.worker.stop
|
267
|
+
expect(stub).to have_been_requested.times(1)
|
268
|
+
end
|
269
|
+
end
|