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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +27 -0
  3. data/Gemfile +5 -3
  4. data/docs/images/flipper_cloud.png +0 -0
  5. data/examples/cloud/app.ru +12 -0
  6. data/examples/cloud/basic.rb +22 -0
  7. data/examples/cloud/cloud_setup.rb +4 -0
  8. data/examples/cloud/forked.rb +31 -0
  9. data/examples/cloud/import.rb +17 -0
  10. data/examples/cloud/threaded.rb +36 -0
  11. data/examples/dsl.rb +0 -14
  12. data/flipper-cloud.gemspec +19 -0
  13. data/flipper.gemspec +3 -2
  14. data/lib/flipper/cloud/configuration.rb +189 -0
  15. data/lib/flipper/cloud/dsl.rb +27 -0
  16. data/lib/flipper/cloud/instrumenter.rb +48 -0
  17. data/lib/flipper/cloud/message_verifier.rb +95 -0
  18. data/lib/flipper/cloud/middleware.rb +63 -0
  19. data/lib/flipper/cloud/routes.rb +14 -0
  20. data/lib/flipper/cloud.rb +53 -0
  21. data/lib/flipper/dsl.rb +0 -46
  22. data/lib/flipper/{railtie.rb → engine.rb} +19 -3
  23. data/lib/flipper/metadata.rb +5 -1
  24. data/lib/flipper/spec/shared_adapter_specs.rb +43 -43
  25. data/lib/flipper/test/shared_adapter_test.rb +43 -43
  26. data/lib/flipper/version.rb +1 -1
  27. data/lib/flipper.rb +3 -5
  28. data/spec/flipper/adapters/dual_write_spec.rb +2 -2
  29. data/spec/flipper/adapters/instrumented_spec.rb +1 -1
  30. data/spec/flipper/adapters/memoizable_spec.rb +6 -6
  31. data/spec/flipper/adapters/operation_logger_spec.rb +2 -2
  32. data/spec/flipper/adapters/read_only_spec.rb +6 -6
  33. data/spec/flipper/cloud/configuration_spec.rb +269 -0
  34. data/spec/flipper/cloud/dsl_spec.rb +82 -0
  35. data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
  36. data/spec/flipper/cloud/middleware_spec.rb +289 -0
  37. data/spec/flipper/cloud_spec.rb +180 -0
  38. data/spec/flipper/dsl_spec.rb +0 -75
  39. data/spec/flipper/engine_spec.rb +190 -0
  40. data/spec/flipper_integration_spec.rb +12 -12
  41. data/spec/flipper_spec.rb +0 -30
  42. data/spec/spec_helper.rb +0 -12
  43. data/spec/support/climate_control.rb +7 -0
  44. metadata +54 -10
  45. 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, @flipper.boolean)
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, @flipper.boolean(false))
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, @flipper.boolean)
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, @flipper.actor(actor22))
62
- assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
63
- assert_equal true, @adapter.enable(@feature, @time_gate, @flipper.time(45))
64
- assert_equal true, @adapter.disable(@feature, @boolean_gate, @flipper.boolean(false))
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, @flipper.actor(actor22))
89
- assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor_asdf))
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, @flipper.actor(actor22))
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, @flipper.actor(actor_asdf))
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, @flipper.actors(15))
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, @flipper.actors(0))
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, @flipper.actors(percentage))
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, @flipper.actors(percentage))
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, @flipper.time(10))
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, @flipper.time(0))
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, @flipper.time(percentage))
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, @flipper.time(percentage))
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, @flipper.boolean)
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, @flipper.actor(Flipper::Actor.new(22)))
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, @flipper.time(10))
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, @flipper.actors(10))
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, @flipper.boolean)
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, @flipper.actor(actor22))
207
- assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
208
- assert_equal true, @adapter.enable(@feature, @time_gate, @flipper.time(45))
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, @flipper.boolean)
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, @flipper.actor(actor22))
223
- assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
224
- assert_equal true, @adapter.enable(@feature, @time_gate, @flipper.time(45))
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, @flipper.boolean)
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, @flipper.boolean)
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, @flipper.actor(actor))
277
- assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor))
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, @flipper.actors(25))
289
- assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
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, @flipper.boolean)
294
- assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean)
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, @flipper.actors(25))
306
- assert_equal true, @adapter.enable(@feature, @time_gate, @flipper.time(25))
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, @flipper.actor(actor))
309
- assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean(true))
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
 
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.28.2'.freeze
2
+ VERSION = '1.0.0.pre'.freeze
3
3
  end
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, :bool, :boolean,
60
- :enable_actor, :disable_actor, :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/railtie" if defined?(Rails::Railtie)
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), local.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), local.boolean(false)
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) { flipper.actors(22) }
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, flipper.bool)
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, flipper.bool)
206
- adapter_result = adapter.enable(feature, gate, flipper.bool)
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, flipper.bool)
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, flipper.bool)
236
- adapter_result = adapter.disable(feature, gate, flipper.bool)
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 = flipper.bool
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 = flipper.bool
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, flipper.boolean)
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, flipper.actor(actor22))
48
- adapter.enable(feature, actors_gate, flipper.actors(25))
49
- adapter.enable(feature, time_gate, flipper.time(45))
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, flipper.boolean) }
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, flipper.boolean) }
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