prefab-cloud-ruby 0.24.5 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/VERSION +1 -1
- data/compile_protos.sh +7 -0
- data/lib/prefab/client.rb +20 -46
- data/lib/prefab/config_client.rb +9 -12
- data/lib/prefab/config_resolver.rb +2 -1
- data/lib/prefab/config_value_unwrapper.rb +20 -9
- data/lib/prefab/context.rb +43 -7
- data/lib/prefab/context_shape_aggregator.rb +1 -1
- data/lib/prefab/criteria_evaluator.rb +24 -16
- data/lib/prefab/evaluation.rb +48 -0
- data/lib/prefab/evaluation_summary_aggregator.rb +85 -0
- data/lib/prefab/example_contexts_aggregator.rb +76 -0
- data/lib/prefab/exponential_backoff.rb +5 -0
- data/lib/prefab/feature_flag_client.rb +0 -2
- data/lib/prefab/log_path_aggregator.rb +1 -1
- data/lib/prefab/logger_client.rb +12 -13
- data/lib/prefab/options.rb +52 -43
- data/lib/prefab/periodic_sync.rb +30 -13
- data/lib/prefab/rate_limit_cache.rb +41 -0
- data/lib/prefab/resolved_config_presenter.rb +2 -4
- data/lib/prefab/weighted_value_resolver.rb +1 -1
- data/lib/prefab-cloud-ruby.rb +5 -5
- data/lib/prefab_pb.rb +11 -1
- data/prefab-cloud-ruby.gemspec +14 -9
- data/test/integration_test.rb +1 -3
- data/test/integration_test_helpers.rb +0 -1
- data/test/support/common_helpers.rb +174 -0
- data/test/support/mock_base_client.rb +44 -0
- data/test/support/mock_config_client.rb +19 -0
- data/test/support/mock_config_loader.rb +1 -0
- data/test/test_client.rb +354 -40
- data/test/test_config_client.rb +1 -0
- data/test/test_config_loader.rb +1 -0
- data/test/test_config_resolver.rb +25 -24
- data/test/test_config_value_unwrapper.rb +22 -32
- data/test/test_context.rb +1 -0
- data/test/test_context_shape_aggregator.rb +11 -1
- data/test/test_criteria_evaluator.rb +180 -133
- data/test/test_evaluation_summary_aggregator.rb +162 -0
- data/test/test_example_contexts_aggregator.rb +238 -0
- data/test/test_helper.rb +5 -131
- data/test/test_integration.rb +6 -4
- data/test/test_local_config_parser.rb +2 -2
- data/test/test_log_path_aggregator.rb +9 -1
- data/test/test_logger.rb +6 -5
- data/test/test_options.rb +33 -2
- data/test/test_rate_limit_cache.rb +44 -0
- data/test/test_weighted_value_resolver.rb +13 -7
- metadata +13 -8
- data/lib/prefab/evaluated_configs_aggregator.rb +0 -60
- data/lib/prefab/evaluated_keys_aggregator.rb +0 -41
- data/lib/prefab/noop_cache.rb +0 -15
- data/lib/prefab/noop_stats.rb +0 -8
- data/test/test_evaluated_configs_aggregator.rb +0 -254
- data/test/test_evaluated_keys_aggregator.rb +0 -54
data/test/test_client.rb
CHANGED
@@ -3,34 +3,54 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class TestClient < Minitest::Test
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
LOCAL_ONLY = Prefab::Options::DATASOURCES::LOCAL_ONLY
|
7
|
+
|
8
|
+
PROJECT_ENV_ID = 1
|
9
|
+
KEY = 'the-key'
|
10
|
+
DEFAULT_VALUE = 'default_value'
|
11
|
+
DESIRED_VALUE = 'desired_value'
|
12
|
+
|
13
|
+
IRRELEVANT = 'this should never show up'
|
14
|
+
|
15
|
+
DEFAULT_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
|
16
|
+
DESIRED_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
|
17
|
+
|
18
|
+
TRUE_CONFIG = PrefabProto::ConfigValue.new(bool: true)
|
19
|
+
FALSE_CONFIG = PrefabProto::ConfigValue.new(bool: false)
|
20
|
+
|
21
|
+
DEFAULT_ROW = PrefabProto::ConfigRow.new(
|
22
|
+
values: [
|
23
|
+
PrefabProto::ConditionalValue.new(value: DEFAULT_VALUE_CONFIG)
|
24
|
+
]
|
25
|
+
)
|
9
26
|
|
10
27
|
def test_get
|
11
28
|
_, err = capture_io do
|
12
|
-
|
13
|
-
assert_equal '
|
14
|
-
assert_equal
|
29
|
+
client = new_client
|
30
|
+
assert_equal 'default', client.get('does.not.exist', 'default')
|
31
|
+
assert_equal 'test sample value', client.get('sample')
|
32
|
+
assert_equal 123, client.get('sample_int')
|
15
33
|
end
|
16
34
|
assert_equal '', err
|
17
35
|
end
|
18
36
|
|
19
37
|
def test_get_with_default
|
38
|
+
client = new_client
|
20
39
|
# A `false` value is not replaced with the default
|
21
|
-
assert_equal false,
|
40
|
+
assert_equal false, client.get('false_value', 'red')
|
22
41
|
|
23
42
|
# A falsy value is not replaced with the default
|
24
|
-
assert_equal 0,
|
43
|
+
assert_equal 0, client.get('zero_value', 'red')
|
25
44
|
|
26
45
|
# A missing value returns the default
|
27
|
-
assert_equal 'buckets',
|
46
|
+
assert_equal 'buckets', client.get('missing_value', 'buckets')
|
28
47
|
end
|
29
48
|
|
30
49
|
def test_get_with_missing_default
|
50
|
+
client = new_client
|
31
51
|
# it raises by default
|
32
52
|
err = assert_raises(Prefab::Errors::MissingDefaultError) do
|
33
|
-
assert_nil
|
53
|
+
assert_nil client.get('missing_value')
|
34
54
|
end
|
35
55
|
|
36
56
|
assert_match(/No value found for key/, err.message)
|
@@ -42,53 +62,87 @@ class TestClient < Minitest::Test
|
|
42
62
|
end
|
43
63
|
|
44
64
|
def test_enabled
|
45
|
-
|
46
|
-
assert_equal
|
47
|
-
assert_equal
|
48
|
-
assert_equal false,
|
65
|
+
client = new_client
|
66
|
+
assert_equal false, client.enabled?('does_not_exist')
|
67
|
+
assert_equal true, client.enabled?('enabled_flag')
|
68
|
+
assert_equal false, client.enabled?('disabled_flag')
|
69
|
+
assert_equal false, client.enabled?('flag_with_a_value')
|
49
70
|
end
|
50
71
|
|
51
72
|
def test_ff_enabled_with_user_key_match
|
52
|
-
|
53
|
-
|
54
|
-
|
73
|
+
client = new_client
|
74
|
+
|
75
|
+
ctx = { user: { key: 'jimmy' } }
|
76
|
+
assert_equal false, client.enabled?('user_key_match', ctx)
|
77
|
+
assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('user_key_match') }
|
78
|
+
|
79
|
+
ctx = { user: { key: 'abc123' } }
|
80
|
+
assert_equal true, client.enabled?('user_key_match', ctx)
|
81
|
+
assert_equal true, Prefab::Context.with_context(ctx) { client.enabled?('user_key_match') }
|
82
|
+
|
83
|
+
ctx = { user: { key: 'xyz987' } }
|
84
|
+
assert_equal true, client.enabled?('user_key_match', ctx)
|
85
|
+
assert_equal true, Prefab::Context.with_context(ctx) { client.enabled?('user_key_match') }
|
55
86
|
end
|
56
87
|
|
88
|
+
# NOTE: these are all `false` because we're doing a enabled? on a FF with string variants
|
89
|
+
# see test_ff_get_with_context for the raw value tests
|
57
90
|
def test_ff_enabled_with_context
|
58
|
-
|
59
|
-
|
60
|
-
|
91
|
+
client = new_client
|
92
|
+
|
93
|
+
ctx = { user: { domain: 'gmail.com' } }
|
94
|
+
assert_equal false, client.enabled?('just_my_domain', ctx)
|
95
|
+
assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('just_my_domain') }
|
96
|
+
|
97
|
+
ctx = { user: { domain: 'prefab.cloud' } }
|
98
|
+
assert_equal false, client.enabled?('just_my_domain', ctx)
|
99
|
+
assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('just_my_domain') }
|
100
|
+
|
101
|
+
ctx = { user: { domain: 'example.com' } }
|
102
|
+
assert_equal false, client.enabled?('just_my_domain', ctx)
|
103
|
+
assert_equal false, Prefab::Context.with_context(ctx) { client.enabled?('just_my_domain') }
|
61
104
|
end
|
62
105
|
|
63
106
|
def test_ff_get_with_context
|
64
|
-
|
65
|
-
assert_equal 'DEFAULT', @client.get('just_my_domain', 'abc123', { user: { domain: 'gmail.com' } }, 'DEFAULT')
|
107
|
+
client = new_client
|
66
108
|
|
67
|
-
|
68
|
-
|
109
|
+
ctx = { user: { domain: 'gmail.com' } }
|
110
|
+
assert_equal 'DEFAULT', client.get('just_my_domain', 'DEFAULT', ctx)
|
111
|
+
assert_equal 'DEFAULT', Prefab::Context.with_context(ctx) { client.get('just_my_domain', 'DEFAULT') }
|
112
|
+
|
113
|
+
ctx = { user: { domain: 'prefab.cloud' } }
|
114
|
+
assert_equal 'new-version', client.get('just_my_domain', 'DEFAULT', ctx)
|
115
|
+
assert_equal 'new-version', Prefab::Context.with_context(ctx) { client.get('just_my_domain', 'DEFAULT') }
|
116
|
+
|
117
|
+
ctx = { user: { domain: 'example.com' } }
|
118
|
+
assert_equal 'new-version', client.get('just_my_domain', 'DEFAULT', ctx)
|
119
|
+
assert_equal 'new-version', Prefab::Context.with_context(ctx) { client.get('just_my_domain', 'DEFAULT') }
|
69
120
|
end
|
70
121
|
|
71
122
|
def test_deprecated_no_dot_notation_ff_enabled_with_jit_context
|
123
|
+
client = new_client
|
72
124
|
# with no lookup key
|
73
|
-
assert_equal false,
|
74
|
-
assert_equal true,
|
75
|
-
assert_equal true,
|
125
|
+
assert_equal false, client.enabled?('deprecated_no_dot_notation', { domain: 'gmail.com' })
|
126
|
+
assert_equal true, client.enabled?('deprecated_no_dot_notation', { domain: 'prefab.cloud' })
|
127
|
+
assert_equal true, client.enabled?('deprecated_no_dot_notation', { domain: 'example.com' })
|
76
128
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
129
|
+
assert_stderr [
|
130
|
+
"[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash.",
|
131
|
+
"[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash.",
|
132
|
+
"[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash."
|
133
|
+
]
|
81
134
|
end
|
82
135
|
|
83
136
|
def test_getting_feature_flag_value
|
84
|
-
|
85
|
-
assert_equal
|
137
|
+
client = new_client
|
138
|
+
assert_equal false, client.enabled?('flag_with_a_value')
|
139
|
+
assert_equal 'all-features', client.get('flag_with_a_value')
|
86
140
|
end
|
87
141
|
|
88
142
|
def test_initialization_with_an_options_object
|
89
143
|
options_hash = {
|
90
144
|
namespace: 'test-namespace',
|
91
|
-
prefab_datasources:
|
145
|
+
prefab_datasources: LOCAL_ONLY
|
92
146
|
}
|
93
147
|
|
94
148
|
options = Prefab::Options.new(options_hash)
|
@@ -101,7 +155,7 @@ class TestClient < Minitest::Test
|
|
101
155
|
def test_initialization_with_a_hash
|
102
156
|
options_hash = {
|
103
157
|
namespace: 'test-namespace',
|
104
|
-
prefab_datasources:
|
158
|
+
prefab_datasources: LOCAL_ONLY
|
105
159
|
}
|
106
160
|
|
107
161
|
client = Prefab::Client.new(options_hash)
|
@@ -109,13 +163,273 @@ class TestClient < Minitest::Test
|
|
109
163
|
assert_equal client.namespace, 'test-namespace'
|
110
164
|
end
|
111
165
|
|
112
|
-
|
166
|
+
def test_evaluation_summary_aggregator
|
167
|
+
fake_api_key = '123-development-yourapikey-SDK'
|
168
|
+
|
169
|
+
# it is nil by default
|
170
|
+
assert_nil new_client(api_key: fake_api_key).evaluation_summary_aggregator
|
171
|
+
|
172
|
+
# it is nil when local_only even if collect_max_evaluation_summaries is true
|
173
|
+
assert_nil new_client(prefab_datasources: LOCAL_ONLY,
|
174
|
+
collect_evaluation_summaries: true, ).evaluation_summary_aggregator
|
175
|
+
|
176
|
+
# it is nil when collect_max_evaluation_summaries is false
|
177
|
+
assert_nil new_client(api_key: fake_api_key,
|
178
|
+
prefab_datasources: :all,
|
179
|
+
collect_evaluation_summaries: false).evaluation_summary_aggregator
|
180
|
+
|
181
|
+
# it is not nil when collect_max_evaluation_summaries is true and the datasource is not local_only
|
182
|
+
assert_equal Prefab::EvaluationSummaryAggregator,
|
183
|
+
new_client(api_key: fake_api_key,
|
184
|
+
prefab_datasources: :all,
|
185
|
+
collect_evaluation_summaries: true).evaluation_summary_aggregator.class
|
186
|
+
|
187
|
+
assert_logged [
|
188
|
+
"WARN 2023-08-09 15:18:12 -0400: cloud.prefab.client No success loading checkpoints"
|
189
|
+
]
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_get_with_basic_value
|
193
|
+
config = basic_value_config
|
194
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: true,
|
195
|
+
context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
|
196
|
+
|
197
|
+
assert_equal DESIRED_VALUE, client.get(config.key, IRRELEVANT, 'user' => { 'key' => 99 })
|
198
|
+
|
199
|
+
assert_summary client, {
|
200
|
+
[KEY, :CONFIG] => {
|
201
|
+
{
|
202
|
+
config_id: config.id,
|
203
|
+
config_row_index: 1,
|
204
|
+
selected_value: DESIRED_VALUE_CONFIG,
|
205
|
+
conditional_value_index: 0,
|
206
|
+
weighted_value_index: nil,
|
207
|
+
selected_index: nil
|
208
|
+
} => 1
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
assert_example_contexts client, [Prefab::Context.new({ user: { 'key' => 99 } })]
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_get_with_basic_value_with_context
|
216
|
+
config = basic_value_config
|
217
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: true,
|
218
|
+
context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
|
219
|
+
|
220
|
+
client.with_context('user' => { 'key' => 99 }) do
|
221
|
+
assert_equal DESIRED_VALUE, client.get(config.key)
|
222
|
+
end
|
223
|
+
|
224
|
+
assert_summary client, {
|
225
|
+
[KEY, :CONFIG] => {
|
226
|
+
{
|
227
|
+
config_id: config.id,
|
228
|
+
config_row_index: 1,
|
229
|
+
selected_value: DESIRED_VALUE_CONFIG,
|
230
|
+
conditional_value_index: 0,
|
231
|
+
weighted_value_index: nil,
|
232
|
+
selected_index: nil
|
233
|
+
} => 1
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
assert_example_contexts client, [Prefab::Context.new({ user: { 'key' => 99 } })]
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_get_with_weighted_values
|
241
|
+
config = PrefabProto::Config.new(
|
242
|
+
id: 123,
|
243
|
+
key: KEY,
|
244
|
+
config_type: PrefabProto::ConfigType::CONFIG,
|
245
|
+
rows: [
|
246
|
+
DEFAULT_ROW,
|
247
|
+
PrefabProto::ConfigRow.new(
|
248
|
+
project_env_id: PROJECT_ENV_ID,
|
249
|
+
values: [
|
250
|
+
PrefabProto::ConditionalValue.new(
|
251
|
+
criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
|
252
|
+
value: PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 98], ['def', 1],
|
253
|
+
['ghi', 1]]))
|
254
|
+
)
|
255
|
+
]
|
256
|
+
)
|
257
|
+
]
|
258
|
+
)
|
113
259
|
|
114
|
-
|
115
|
-
|
260
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID, collect_evaluation_summaries: true,
|
261
|
+
context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
|
116
262
|
|
117
|
-
|
118
|
-
assert_equal
|
263
|
+
2.times do
|
264
|
+
assert_equal 'abc', client.get(config.key, IRRELEVANT, 'user' => { 'key' => '1' })
|
119
265
|
end
|
266
|
+
|
267
|
+
3.times do
|
268
|
+
assert_equal 'def', client.get(config.key, IRRELEVANT, 'user' => { 'key' => '12' })
|
269
|
+
end
|
270
|
+
|
271
|
+
assert_equal 'ghi',
|
272
|
+
client.get(config.key, IRRELEVANT, 'user' => { 'key' => '4', admin: true })
|
273
|
+
|
274
|
+
assert_summary client, {
|
275
|
+
[KEY, :CONFIG] => {
|
276
|
+
{
|
277
|
+
config_id: config.id,
|
278
|
+
config_row_index: 1,
|
279
|
+
selected_value: PrefabProto::ConfigValue.new(string: 'abc'),
|
280
|
+
conditional_value_index: 0,
|
281
|
+
weighted_value_index: 0,
|
282
|
+
selected_index: nil
|
283
|
+
} => 2,
|
284
|
+
|
285
|
+
{
|
286
|
+
config_id: config.id,
|
287
|
+
config_row_index: 1,
|
288
|
+
selected_value: PrefabProto::ConfigValue.new(string: 'def'),
|
289
|
+
conditional_value_index: 0,
|
290
|
+
weighted_value_index: 1,
|
291
|
+
selected_index: nil
|
292
|
+
} => 3,
|
293
|
+
|
294
|
+
{
|
295
|
+
config_id: config.id,
|
296
|
+
config_row_index: 1,
|
297
|
+
selected_value: PrefabProto::ConfigValue.new(string: 'ghi'),
|
298
|
+
conditional_value_index: 0,
|
299
|
+
weighted_value_index: 2,
|
300
|
+
selected_index: nil
|
301
|
+
} => 1
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
assert_example_contexts client, [
|
306
|
+
Prefab::Context.new(user: { 'key' => '1' }),
|
307
|
+
Prefab::Context.new(user: { 'key' => '12' }),
|
308
|
+
Prefab::Context.new(user: { 'key' => '4', admin: true })
|
309
|
+
]
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_in_seg
|
313
|
+
segment_key = 'segment_key'
|
314
|
+
|
315
|
+
segment_config = PrefabProto::Config.new(
|
316
|
+
config_type: PrefabProto::ConfigType::SEGMENT,
|
317
|
+
key: segment_key,
|
318
|
+
rows: [
|
319
|
+
PrefabProto::ConfigRow.new(
|
320
|
+
values: [
|
321
|
+
PrefabProto::ConditionalValue.new(
|
322
|
+
value: TRUE_CONFIG,
|
323
|
+
criteria: [
|
324
|
+
PrefabProto::Criterion.new(
|
325
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
|
326
|
+
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
327
|
+
property_name: 'user.email'
|
328
|
+
)
|
329
|
+
]
|
330
|
+
),
|
331
|
+
PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
|
332
|
+
]
|
333
|
+
)
|
334
|
+
]
|
335
|
+
)
|
336
|
+
|
337
|
+
config = PrefabProto::Config.new(
|
338
|
+
key: KEY,
|
339
|
+
rows: [
|
340
|
+
DEFAULT_ROW,
|
341
|
+
|
342
|
+
PrefabProto::ConfigRow.new(
|
343
|
+
project_env_id: PROJECT_ENV_ID,
|
344
|
+
values: [
|
345
|
+
PrefabProto::ConditionalValue.new(
|
346
|
+
criteria: [
|
347
|
+
PrefabProto::Criterion.new(
|
348
|
+
operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
|
349
|
+
value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
|
350
|
+
)
|
351
|
+
],
|
352
|
+
value: DESIRED_VALUE_CONFIG
|
353
|
+
)
|
354
|
+
]
|
355
|
+
)
|
356
|
+
]
|
357
|
+
)
|
358
|
+
|
359
|
+
client = new_client(config: [config, segment_config], project_env_id: PROJECT_ENV_ID,
|
360
|
+
collect_evaluation_summaries: true, context_upload_mode: :periodic_example, allow_telemetry_in_local_mode: true)
|
361
|
+
|
362
|
+
assert_equal DEFAULT_VALUE, client.get(config.key)
|
363
|
+
assert_equal DEFAULT_VALUE,
|
364
|
+
client.get(config.key, IRRELEVANT, user: { key: 'abc', email: 'example@prefab.cloud' })
|
365
|
+
assert_equal DESIRED_VALUE, client.get(config.key, IRRELEVANT, user: { key: 'def', email: 'example@hotmail.com' })
|
366
|
+
|
367
|
+
assert_summary client, {
|
368
|
+
[segment_key, :SEGMENT] => {
|
369
|
+
{ config_id: 0, config_row_index: 0, conditional_value_index: 1, selected_value: FALSE_CONFIG,
|
370
|
+
weighted_value_index: nil, selected_index: nil } => 2,
|
371
|
+
{ config_id: 0, config_row_index: 0, conditional_value_index: 0, selected_value: TRUE_CONFIG,
|
372
|
+
weighted_value_index: nil, selected_index: nil } => 1
|
373
|
+
},
|
374
|
+
[KEY, :NOT_SET_CONFIG_TYPE] => {
|
375
|
+
{ config_id: 0, config_row_index: 0, conditional_value_index: 0, selected_value: DEFAULT_VALUE_CONFIG,
|
376
|
+
weighted_value_index: nil, selected_index: nil } => 2,
|
377
|
+
{ config_id: 0, config_row_index: 1, conditional_value_index: 0, selected_value: DESIRED_VALUE_CONFIG,
|
378
|
+
weighted_value_index: nil, selected_index: nil } => 1
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
382
|
+
assert_example_contexts client, [
|
383
|
+
Prefab::Context.new(user: { key: 'abc', email: 'example@prefab.cloud' }),
|
384
|
+
Prefab::Context.new(user: { key: 'def', email: 'example@hotmail.com' })
|
385
|
+
]
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_get_log_level
|
389
|
+
config = PrefabProto::Config.new(
|
390
|
+
id: 999,
|
391
|
+
key: 'log-level',
|
392
|
+
config_type: PrefabProto::ConfigType::LOG_LEVEL,
|
393
|
+
rows: [
|
394
|
+
PrefabProto::ConfigRow.new(
|
395
|
+
values: [
|
396
|
+
PrefabProto::ConditionalValue.new(
|
397
|
+
criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
|
398
|
+
value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::DEBUG)
|
399
|
+
)
|
400
|
+
]
|
401
|
+
)
|
402
|
+
]
|
403
|
+
)
|
404
|
+
|
405
|
+
client = new_client(config: config, project_env_id: PROJECT_ENV_ID,
|
406
|
+
collect_evaluation_summaries: true, allow_telemetry_in_local_mode: true)
|
407
|
+
|
408
|
+
assert_equal :DEBUG, client.get(config.key, IRRELEVANT)
|
409
|
+
|
410
|
+
# nothing is summarized for log levels
|
411
|
+
assert_summary client, {}
|
412
|
+
end
|
413
|
+
|
414
|
+
private
|
415
|
+
|
416
|
+
def basic_value_config
|
417
|
+
PrefabProto::Config.new(
|
418
|
+
id: 123,
|
419
|
+
key: KEY,
|
420
|
+
config_type: PrefabProto::ConfigType::CONFIG,
|
421
|
+
rows: [
|
422
|
+
DEFAULT_ROW,
|
423
|
+
PrefabProto::ConfigRow.new(
|
424
|
+
project_env_id: PROJECT_ENV_ID,
|
425
|
+
values: [
|
426
|
+
PrefabProto::ConditionalValue.new(
|
427
|
+
criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
|
428
|
+
value: DESIRED_VALUE_CONFIG
|
429
|
+
)
|
430
|
+
]
|
431
|
+
)
|
432
|
+
]
|
433
|
+
)
|
120
434
|
end
|
121
435
|
end
|
data/test/test_config_client.rb
CHANGED
data/test/test_config_loader.rb
CHANGED
@@ -22,6 +22,10 @@ class TestConfigResolver < Minitest::Test
|
|
22
22
|
]
|
23
23
|
)
|
24
24
|
|
25
|
+
class MockConfigLoader
|
26
|
+
def calc_config; end
|
27
|
+
end
|
28
|
+
|
25
29
|
def test_resolution
|
26
30
|
@loader = MockConfigLoader.new
|
27
31
|
|
@@ -117,31 +121,30 @@ class TestConfigResolver < Minitest::Test
|
|
117
121
|
|
118
122
|
@loader.stub :calc_config, loaded_values do
|
119
123
|
@resolverA = resolver_for_namespace('', @loader, project_env_id: PRODUCTION_ENV_ID)
|
120
|
-
assert_equal_context_and_jit DEFAULT_VALUE, @resolverA, 'key', {}
|
124
|
+
assert_equal_context_and_jit DEFAULT_VALUE, @resolverA, 'key', {}
|
121
125
|
|
122
126
|
## below here in the test env
|
123
127
|
@resolverA = resolver_for_namespace('', @loader)
|
124
|
-
assert_equal_context_and_jit 'value_none', @resolverA, 'key', {}
|
128
|
+
assert_equal_context_and_jit 'value_none', @resolverA, 'key', {}
|
125
129
|
|
126
130
|
@resolverA = resolver_for_namespace('projectA', @loader)
|
127
|
-
assert_equal_context_and_jit 'valueA', @resolverA, 'key', {}
|
131
|
+
assert_equal_context_and_jit 'valueA', @resolverA, 'key', {}
|
128
132
|
|
129
133
|
@resolverB = resolver_for_namespace('projectB', @loader)
|
130
|
-
assert_equal_context_and_jit 'valueB', @resolverB, 'key', {}
|
134
|
+
assert_equal_context_and_jit 'valueB', @resolverB, 'key', {}
|
131
135
|
|
132
136
|
@resolverBX = resolver_for_namespace('projectB.subprojectX', @loader)
|
133
|
-
assert_equal_context_and_jit 'projectB.subprojectX', @resolverBX, 'key', {}
|
137
|
+
assert_equal_context_and_jit 'projectB.subprojectX', @resolverBX, 'key', {}
|
134
138
|
|
135
139
|
@resolverBX = resolver_for_namespace('projectB.subprojectX', @loader)
|
136
|
-
assert_equal_context_and_jit 'valueB2', @resolverBX, 'key2', {}
|
140
|
+
assert_equal_context_and_jit 'valueB2', @resolverBX, 'key2', {}
|
137
141
|
|
138
142
|
@resolverUndefinedSubProject = resolver_for_namespace('projectB.subprojectX.subsubQ',
|
139
143
|
@loader)
|
140
|
-
assert_equal_context_and_jit 'projectB.subprojectX', @resolverUndefinedSubProject, 'key',
|
141
|
-
{}, :string
|
144
|
+
assert_equal_context_and_jit 'projectB.subprojectX', @resolverUndefinedSubProject, 'key', {}
|
142
145
|
|
143
146
|
@resolverBX = resolver_for_namespace('projectC', @loader)
|
144
|
-
assert_equal_context_and_jit 'value_none', @resolverBX, 'key', {}
|
147
|
+
assert_equal_context_and_jit 'value_none', @resolverBX, 'key', {}
|
145
148
|
|
146
149
|
assert_nil @resolverBX.get('key_that_doesnt_exist', nil)
|
147
150
|
|
@@ -244,9 +247,9 @@ class TestConfigResolver < Minitest::Test
|
|
244
247
|
resolver.project_env_id = PRODUCTION_ENV_ID
|
245
248
|
|
246
249
|
assert_equal_context_and_jit DEFAULT_VALUE, resolver, CONFIG_KEY,
|
247
|
-
{ user: { email: 'test@something-else.com' } }
|
250
|
+
{ user: { email: 'test@something-else.com' } }
|
248
251
|
assert_equal_context_and_jit IN_SEGMENT_VALUE, resolver, CONFIG_KEY,
|
249
|
-
{ user: { email: 'test@hotmail.com' } }
|
252
|
+
{ user: { email: 'test@hotmail.com' } }
|
250
253
|
end
|
251
254
|
end
|
252
255
|
|
@@ -312,10 +315,8 @@ class TestConfigResolver < Minitest::Test
|
|
312
315
|
options = Prefab::Options.new
|
313
316
|
resolver = Prefab::ConfigResolver.new(MockBaseClient.new(options), loader)
|
314
317
|
|
315
|
-
assert_equal_context_and_jit IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@hotmail.com' } }
|
316
|
-
|
317
|
-
assert_equal_context_and_jit NOT_IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@something-else.com' } },
|
318
|
-
:string
|
318
|
+
assert_equal_context_and_jit IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@hotmail.com' } }
|
319
|
+
assert_equal_context_and_jit NOT_IN_SEGMENT_VALUE, resolver, CONFIG_KEY, { user: { email: 'test@something-else.com' } }
|
319
320
|
end
|
320
321
|
end
|
321
322
|
|
@@ -356,9 +357,9 @@ class TestConfigResolver < Minitest::Test
|
|
356
357
|
resolver.project_env_id = TEST_ENV_ID
|
357
358
|
|
358
359
|
Prefab::Context.with_context({ user: { email: 'test@example.com' } }) do
|
359
|
-
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).
|
360
|
-
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).
|
361
|
-
assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'pro' } }).
|
360
|
+
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).unwrapped_value
|
361
|
+
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).unwrapped_value
|
362
|
+
assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'pro' } }).unwrapped_value
|
362
363
|
end
|
363
364
|
end
|
364
365
|
end
|
@@ -400,9 +401,9 @@ class TestConfigResolver < Minitest::Test
|
|
400
401
|
resolver.project_env_id = TEST_ENV_ID
|
401
402
|
|
402
403
|
Prefab::Context.with_context({ user: { email: 'test@hotmail.com' }, team: { plan: 'pro' } }) do
|
403
|
-
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).
|
404
|
-
assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { user: { email: 'test@example.com' } }).
|
405
|
-
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).
|
404
|
+
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY).unwrapped_value
|
405
|
+
assert_equal DESIRED_VALUE, resolver.get(CONFIG_KEY, { user: { email: 'test@example.com' } }).unwrapped_value
|
406
|
+
assert_equal DEFAULT_VALUE, resolver.get(CONFIG_KEY, { team: { plan: 'freebie' } }).unwrapped_value
|
406
407
|
end
|
407
408
|
end
|
408
409
|
end
|
@@ -419,11 +420,11 @@ class TestConfigResolver < Minitest::Test
|
|
419
420
|
resolver
|
420
421
|
end
|
421
422
|
|
422
|
-
def assert_equal_context_and_jit(expected_value, resolver, key, properties
|
423
|
-
assert_equal expected_value, resolver.get(key, properties).
|
423
|
+
def assert_equal_context_and_jit(expected_value, resolver, key, properties)
|
424
|
+
assert_equal expected_value, resolver.get(key, properties).unwrapped_value
|
424
425
|
|
425
426
|
Prefab::Context.with_context(properties) do
|
426
|
-
assert_equal expected_value, resolver.get(key).
|
427
|
+
assert_equal expected_value, resolver.get(key).unwrapped_value
|
427
428
|
end
|
428
429
|
end
|
429
430
|
end
|