prefab-cloud-ruby 0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/Gemfile +9 -22
  4. data/Gemfile.lock +88 -160
  5. data/LICENSE.txt +1 -1
  6. data/Rakefile +14 -14
  7. data/VERSION +1 -1
  8. data/lib/prefab/auth_interceptor.rb +25 -0
  9. data/lib/prefab/client.rb +34 -139
  10. data/lib/prefab/config_client.rb +23 -275
  11. data/lib/prefab/config_loader.rb +27 -60
  12. data/lib/prefab/config_resolver.rb +40 -53
  13. data/lib/prefab/noop_cache.rb +13 -0
  14. data/lib/prefab/noop_stats.rb +8 -0
  15. data/lib/prefab/prefab_pb.rb +39 -0
  16. data/lib/prefab/prefab_services_pb.rb +37 -0
  17. data/lib/prefab/ratelimit_client.rb +58 -0
  18. data/lib/prefab/ratelimit_pb.rb +125 -0
  19. data/lib/prefab/store.rb +29 -0
  20. data/lib/prefab_client.rb +35 -0
  21. metadata +36 -198
  22. data/.envrc.sample +0 -3
  23. data/.github/workflows/ruby.yml +0 -46
  24. data/.gitmodules +0 -3
  25. data/.rubocop.yml +0 -13
  26. data/.tool-versions +0 -1
  27. data/CHANGELOG.md +0 -169
  28. data/CODEOWNERS +0 -1
  29. data/README.md +0 -94
  30. data/bin/console +0 -21
  31. data/compile_protos.sh +0 -18
  32. data/lib/prefab/config_client_presenter.rb +0 -18
  33. data/lib/prefab/config_value_unwrapper.rb +0 -115
  34. data/lib/prefab/config_value_wrapper.rb +0 -18
  35. data/lib/prefab/context.rb +0 -179
  36. data/lib/prefab/context_shape.rb +0 -20
  37. data/lib/prefab/context_shape_aggregator.rb +0 -65
  38. data/lib/prefab/criteria_evaluator.rb +0 -136
  39. data/lib/prefab/encryption.rb +0 -65
  40. data/lib/prefab/error.rb +0 -6
  41. data/lib/prefab/errors/env_var_parse_error.rb +0 -11
  42. data/lib/prefab/errors/initialization_timeout_error.rb +0 -13
  43. data/lib/prefab/errors/invalid_api_key_error.rb +0 -19
  44. data/lib/prefab/errors/missing_default_error.rb +0 -13
  45. data/lib/prefab/errors/missing_env_var_error.rb +0 -11
  46. data/lib/prefab/errors/uninitialized_error.rb +0 -13
  47. data/lib/prefab/evaluation.rb +0 -52
  48. data/lib/prefab/evaluation_summary_aggregator.rb +0 -87
  49. data/lib/prefab/example_contexts_aggregator.rb +0 -78
  50. data/lib/prefab/exponential_backoff.rb +0 -21
  51. data/lib/prefab/feature_flag_client.rb +0 -42
  52. data/lib/prefab/http_connection.rb +0 -41
  53. data/lib/prefab/internal_logger.rb +0 -16
  54. data/lib/prefab/local_config_parser.rb +0 -151
  55. data/lib/prefab/log_path_aggregator.rb +0 -69
  56. data/lib/prefab/logger_client.rb +0 -264
  57. data/lib/prefab/murmer3.rb +0 -50
  58. data/lib/prefab/options.rb +0 -208
  59. data/lib/prefab/periodic_sync.rb +0 -69
  60. data/lib/prefab/prefab.rb +0 -56
  61. data/lib/prefab/rate_limit_cache.rb +0 -41
  62. data/lib/prefab/resolved_config_presenter.rb +0 -86
  63. data/lib/prefab/time_helpers.rb +0 -7
  64. data/lib/prefab/weighted_value_resolver.rb +0 -42
  65. data/lib/prefab/yaml_config_parser.rb +0 -34
  66. data/lib/prefab-cloud-ruby.rb +0 -57
  67. data/lib/prefab_pb.rb +0 -93
  68. data/prefab-cloud-ruby.gemspec +0 -155
  69. data/test/.prefab.default.config.yaml +0 -2
  70. data/test/.prefab.unit_tests.config.yaml +0 -28
  71. data/test/integration_test.rb +0 -150
  72. data/test/integration_test_helpers.rb +0 -151
  73. data/test/support/common_helpers.rb +0 -180
  74. data/test/support/mock_base_client.rb +0 -42
  75. data/test/support/mock_config_client.rb +0 -19
  76. data/test/support/mock_config_loader.rb +0 -1
  77. data/test/test_client.rb +0 -444
  78. data/test/test_config_client.rb +0 -109
  79. data/test/test_config_loader.rb +0 -117
  80. data/test/test_config_resolver.rb +0 -430
  81. data/test/test_config_value_unwrapper.rb +0 -224
  82. data/test/test_config_value_wrapper.rb +0 -42
  83. data/test/test_context.rb +0 -203
  84. data/test/test_context_shape.rb +0 -50
  85. data/test/test_context_shape_aggregator.rb +0 -147
  86. data/test/test_criteria_evaluator.rb +0 -726
  87. data/test/test_encryption.rb +0 -16
  88. data/test/test_evaluation_summary_aggregator.rb +0 -162
  89. data/test/test_example_contexts_aggregator.rb +0 -238
  90. data/test/test_exponential_backoff.rb +0 -18
  91. data/test/test_feature_flag_client.rb +0 -48
  92. data/test/test_helper.rb +0 -17
  93. data/test/test_integration.rb +0 -58
  94. data/test/test_local_config_parser.rb +0 -147
  95. data/test/test_log_path_aggregator.rb +0 -62
  96. data/test/test_logger.rb +0 -621
  97. data/test/test_logger_initialization.rb +0 -12
  98. data/test/test_options.rb +0 -75
  99. data/test/test_prefab.rb +0 -12
  100. data/test/test_rate_limit_cache.rb +0 -44
  101. data/test/test_weighted_value_resolver.rb +0 -71
@@ -1,726 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
- require 'timecop'
5
-
6
- class TestCriteriaEvaluator < Minitest::Test
7
- PROJECT_ENV_ID = 1
8
- TEST_ENV_ID = 2
9
- KEY = 'the-key'
10
- DEFAULT_VALUE = 'default_value'
11
- DESIRED_VALUE = 'desired_value'
12
- WRONG_ENV_VALUE = 'wrong_env_value'
13
-
14
- DEFAULT_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
15
- DESIRED_VALUE_CONFIG = PrefabProto::ConfigValue.new(string: DESIRED_VALUE)
16
-
17
- TRUE_CONFIG = PrefabProto::ConfigValue.new(bool: true)
18
- FALSE_CONFIG = PrefabProto::ConfigValue.new(bool: false)
19
-
20
- DEFAULT_ROW = PrefabProto::ConfigRow.new(
21
- values: [
22
- PrefabProto::ConditionalValue.new(value: DEFAULT_VALUE_CONFIG)
23
- ]
24
- )
25
-
26
- def setup
27
- super
28
- @base_client = FakeBaseClient.new
29
- end
30
-
31
- def test_always_true
32
- config = PrefabProto::Config.new(
33
- id: 123,
34
- key: KEY,
35
- config_type: PrefabProto::ConfigType::CONFIG,
36
- rows: [
37
- DEFAULT_ROW,
38
- PrefabProto::ConfigRow.new(
39
- project_env_id: PROJECT_ENV_ID,
40
- values: [
41
- PrefabProto::ConditionalValue.new(
42
- criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
43
- value: DESIRED_VALUE_CONFIG
44
- )
45
- ]
46
- )
47
- ]
48
- )
49
-
50
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client, namespace: nil)
51
-
52
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
53
- end
54
-
55
- def test_nested_props_in
56
- config = PrefabProto::Config.new(
57
- key: KEY,
58
- rows: [
59
- DEFAULT_ROW,
60
- PrefabProto::ConfigRow.new(
61
- project_env_id: PROJECT_ENV_ID,
62
- values: [
63
- PrefabProto::ConditionalValue.new(
64
- criteria: [
65
- PrefabProto::Criterion.new(
66
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
67
- value_to_match: string_list(%w[ok fine]),
68
- property_name: 'user.key'
69
- )
70
- ],
71
- value: DESIRED_VALUE_CONFIG
72
- )
73
- ]
74
- )
75
- ]
76
- )
77
-
78
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
79
- namespace: nil)
80
-
81
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
82
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).unwrapped_value
83
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).unwrapped_value
84
- end
85
-
86
- def test_nested_props_not_in
87
- config = PrefabProto::Config.new(
88
- key: KEY,
89
- rows: [
90
- DEFAULT_ROW,
91
- PrefabProto::ConfigRow.new(
92
- project_env_id: PROJECT_ENV_ID,
93
- values: [
94
- PrefabProto::ConditionalValue.new(
95
- criteria: [
96
- PrefabProto::Criterion.new(
97
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
98
- value_to_match: string_list(%w[wrong bad]),
99
- property_name: 'user.key'
100
- )
101
- ],
102
- value: DESIRED_VALUE_CONFIG
103
- )
104
- ]
105
- )
106
- ]
107
- )
108
-
109
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
110
- namespace: nil)
111
-
112
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
113
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({ user: { key: 'ok' } })).unwrapped_value
114
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ user: { key: 'wrong' } })).unwrapped_value
115
- end
116
-
117
- def test_prop_is_one_of
118
- config = PrefabProto::Config.new(
119
- key: KEY,
120
- rows: [
121
- PrefabProto::ConfigRow.new(
122
- project_env_id: PROJECT_ENV_ID,
123
- values: [
124
- PrefabProto::ConditionalValue.new(
125
- criteria: [
126
- PrefabProto::Criterion.new(
127
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
128
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
129
- property_name: 'user.email_suffix'
130
- )
131
- ],
132
- value: DESIRED_VALUE_CONFIG
133
- )
134
- ]
135
- ),
136
- DEFAULT_ROW
137
- ]
138
- )
139
-
140
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
141
- namespace: nil)
142
-
143
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
144
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).unwrapped_value
145
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).unwrapped_value
146
- end
147
-
148
- def test_prop_is_not_one_of
149
- config = PrefabProto::Config.new(
150
- key: KEY,
151
- rows: [
152
- DEFAULT_ROW,
153
- PrefabProto::ConfigRow.new(
154
- project_env_id: PROJECT_ENV_ID,
155
- values: [
156
- PrefabProto::ConditionalValue.new(
157
- criteria: [
158
- PrefabProto::Criterion.new(
159
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
160
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
161
- property_name: 'user.email_suffix'
162
- )
163
- ],
164
- value: DESIRED_VALUE_CONFIG
165
- )
166
- ]
167
- )
168
- ]
169
- )
170
-
171
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
172
- namespace: nil)
173
-
174
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
175
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email_suffix: 'prefab.cloud' })).unwrapped_value
176
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email_suffix: 'hotmail.com' })).unwrapped_value
177
- end
178
-
179
- def test_prop_ends_with_one_of
180
- config = PrefabProto::Config.new(
181
- key: KEY,
182
- rows: [
183
- DEFAULT_ROW,
184
- PrefabProto::ConfigRow.new(
185
- project_env_id: PROJECT_ENV_ID,
186
- values: [
187
- PrefabProto::ConditionalValue.new(
188
- criteria: [
189
- PrefabProto::Criterion.new(
190
- operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
191
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
192
- property_name: 'user.email'
193
- )
194
- ],
195
- value: DESIRED_VALUE_CONFIG
196
- )
197
- ]
198
- )
199
- ]
200
- )
201
-
202
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
203
- namespace: nil)
204
-
205
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
206
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
207
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
208
- end
209
-
210
- def test_prop_does_not_end_with_one_of
211
- config = PrefabProto::Config.new(
212
- key: KEY,
213
- rows: [
214
- DEFAULT_ROW,
215
- PrefabProto::ConfigRow.new(
216
- project_env_id: PROJECT_ENV_ID,
217
- values: [
218
- PrefabProto::ConditionalValue.new(
219
- criteria: [
220
- PrefabProto::Criterion.new(
221
- operator: PrefabProto::Criterion::CriterionOperator::PROP_DOES_NOT_END_WITH_ONE_OF,
222
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
223
- property_name: 'user.email'
224
- )
225
- ],
226
- value: DESIRED_VALUE_CONFIG
227
- )
228
- ]
229
- )
230
- ]
231
- )
232
-
233
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client,
234
- namespace: nil)
235
-
236
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
237
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
238
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
239
- end
240
-
241
- def test_in_seg
242
- segment_key = 'segment_key'
243
-
244
- segment_config = PrefabProto::Config.new(
245
- config_type: PrefabProto::ConfigType::SEGMENT,
246
- key: segment_key,
247
- rows: [
248
- PrefabProto::ConfigRow.new(
249
- values: [
250
- PrefabProto::ConditionalValue.new(
251
- value: TRUE_CONFIG,
252
- criteria: [
253
- PrefabProto::Criterion.new(
254
- operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
255
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
256
- property_name: 'user.email'
257
- )
258
- ]
259
- ),
260
- PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
261
- ]
262
- )
263
- ]
264
- )
265
-
266
- config = PrefabProto::Config.new(
267
- key: KEY,
268
- rows: [
269
- DEFAULT_ROW,
270
-
271
- PrefabProto::ConfigRow.new(
272
- project_env_id: PROJECT_ENV_ID,
273
- values: [
274
- PrefabProto::ConditionalValue.new(
275
- criteria: [
276
- PrefabProto::Criterion.new(
277
- operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
278
- value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
279
- )
280
- ],
281
- value: DESIRED_VALUE_CONFIG
282
- )
283
- ]
284
- )
285
- ]
286
- )
287
-
288
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
289
- base_client: @base_client, namespace: nil,
290
- resolver: resolver_fake({ segment_key => segment_config }))
291
-
292
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
293
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
294
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
295
- end
296
-
297
- def test_not_in_seg
298
- segment_key = 'segment_key'
299
-
300
- segment_config = PrefabProto::Config.new(
301
- config_type: PrefabProto::ConfigType::SEGMENT,
302
- key: segment_key,
303
- rows: [
304
- PrefabProto::ConfigRow.new(
305
- values: [
306
- PrefabProto::ConditionalValue.new(
307
- value: TRUE_CONFIG,
308
- criteria: [
309
- PrefabProto::Criterion.new(
310
- operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
311
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
312
- property_name: 'user.email'
313
- )
314
- ]
315
- ),
316
- PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
317
- ]
318
- )
319
- ]
320
- )
321
-
322
- config = PrefabProto::Config.new(
323
- key: KEY,
324
- rows: [
325
- DEFAULT_ROW,
326
- PrefabProto::ConfigRow.new(
327
- project_env_id: PROJECT_ENV_ID,
328
- values: [
329
- PrefabProto::ConditionalValue.new(
330
- criteria: [
331
- PrefabProto::Criterion.new(
332
- operator: PrefabProto::Criterion::CriterionOperator::NOT_IN_SEG,
333
- value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
334
- )
335
- ],
336
- value: DESIRED_VALUE_CONFIG
337
- )
338
- ]
339
- )
340
- ]
341
- )
342
-
343
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
344
- base_client: @base_client, namespace: nil,
345
- resolver: resolver_fake({ segment_key => segment_config }))
346
-
347
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
348
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
349
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@hotmail.com' })).unwrapped_value
350
- end
351
-
352
- def test_multiple_conditions_in_one_value
353
- segment_key = 'segment_key'
354
-
355
- segment_config = PrefabProto::Config.new(
356
- config_type: PrefabProto::ConfigType::SEGMENT,
357
- key: segment_key,
358
- rows: [
359
- PrefabProto::ConfigRow.new(
360
- values: [
361
- PrefabProto::ConditionalValue.new(
362
- value: TRUE_CONFIG,
363
- criteria: [
364
- PrefabProto::Criterion.new(
365
- operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
366
- value_to_match: string_list(['prefab.cloud', 'gmail.com']),
367
- property_name: 'user.email'
368
- ),
369
-
370
- PrefabProto::Criterion.new(
371
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
372
- value_to_match: TRUE_CONFIG,
373
- property_name: 'user.admin'
374
- )
375
- ]
376
- ),
377
- PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
378
- ]
379
- )
380
- ]
381
- )
382
-
383
- config = PrefabProto::Config.new(
384
- key: KEY,
385
- rows: [
386
- DEFAULT_ROW,
387
- PrefabProto::ConfigRow.new(
388
- project_env_id: PROJECT_ENV_ID,
389
- values: [
390
- PrefabProto::ConditionalValue.new(
391
- criteria: [
392
- PrefabProto::Criterion.new(
393
- operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
394
- value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
395
- ),
396
-
397
- PrefabProto::Criterion.new(
398
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
399
- value_to_match: TRUE_CONFIG,
400
- property_name: 'user.deleted'
401
- )
402
- ],
403
- value: DESIRED_VALUE_CONFIG
404
- )
405
- ]
406
- )
407
- ]
408
- )
409
-
410
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
411
- base_client: @base_client, namespace: nil,
412
- resolver: resolver_fake({ segment_key => segment_config }))
413
-
414
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
415
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
416
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).unwrapped_value
417
- assert_equal DEFAULT_VALUE,
418
- evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).unwrapped_value
419
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).unwrapped_value
420
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).unwrapped_value
421
- assert_equal DEFAULT_VALUE,
422
- evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).unwrapped_value
423
- end
424
-
425
- def test_multiple_conditions_in_multiple_values
426
- segment_key = 'segment_key'
427
-
428
- segment_config = PrefabProto::Config.new(
429
- config_type: PrefabProto::ConfigType::SEGMENT,
430
- key: segment_key,
431
- rows: [
432
- PrefabProto::ConfigRow.new(
433
- values: [
434
- PrefabProto::ConditionalValue.new(
435
- value: TRUE_CONFIG,
436
- criteria: [
437
- PrefabProto::Criterion.new(
438
- operator: PrefabProto::Criterion::CriterionOperator::PROP_ENDS_WITH_ONE_OF,
439
- value_to_match: string_list(['prefab.cloud', 'gmail.com']),
440
- property_name: 'user.email'
441
- )
442
- ]
443
- ),
444
- PrefabProto::ConditionalValue.new(
445
- value: TRUE_CONFIG,
446
- criteria: [
447
- PrefabProto::Criterion.new(
448
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
449
- value_to_match: TRUE_CONFIG,
450
- property_name: 'user.admin'
451
- )
452
- ]
453
- ),
454
- PrefabProto::ConditionalValue.new(value: FALSE_CONFIG)
455
- ]
456
- )
457
- ]
458
- )
459
-
460
- config = PrefabProto::Config.new(
461
- key: KEY,
462
- rows: [
463
- DEFAULT_ROW,
464
- PrefabProto::ConfigRow.new(
465
- project_env_id: PROJECT_ENV_ID,
466
- values: [
467
- PrefabProto::ConditionalValue.new(
468
- criteria: [
469
- PrefabProto::Criterion.new(
470
- operator: PrefabProto::Criterion::CriterionOperator::IN_SEG,
471
- value_to_match: PrefabProto::ConfigValue.new(string: segment_key)
472
- ),
473
-
474
- PrefabProto::Criterion.new(
475
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_NOT_ONE_OF,
476
- value_to_match: TRUE_CONFIG,
477
- property_name: 'user.deleted'
478
- )
479
- ],
480
- value: DESIRED_VALUE_CONFIG
481
- )
482
- ]
483
- )
484
- ]
485
- )
486
-
487
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID,
488
- base_client: @base_client, namespace: nil,
489
- resolver: resolver_fake({ segment_key => segment_config }))
490
-
491
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
492
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud' })).unwrapped_value
493
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { admin: true })).unwrapped_value
494
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true })).unwrapped_value
495
- assert_equal DEFAULT_VALUE,
496
- evaluator.evaluate(context(user: { email: 'example@prefab.cloud', admin: true, deleted: true })).unwrapped_value
497
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com' })).unwrapped_value
498
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true })).unwrapped_value
499
- assert_equal DEFAULT_VALUE,
500
- evaluator.evaluate(context(user: { email: 'example@gmail.com', admin: true, deleted: true })).unwrapped_value
501
- end
502
-
503
- def test_stringifying_property_values_and_names
504
- config = PrefabProto::Config.new(
505
- key: KEY,
506
- rows: [
507
- DEFAULT_ROW,
508
- PrefabProto::ConfigRow.new(
509
- project_env_id: PROJECT_ENV_ID,
510
- values: [
511
- PrefabProto::ConditionalValue.new(
512
- criteria: [
513
- PrefabProto::Criterion.new(
514
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
515
- value_to_match: string_list(%w[1 true hello]),
516
- property_name: 'team.name'
517
- )
518
- ],
519
- value: DESIRED_VALUE_CONFIG
520
- )
521
- ]
522
- )
523
- ]
524
- )
525
-
526
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
527
- namespace: nil, base_client: @base_client)
528
-
529
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
530
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context(team: { name: 'prefab.cloud' })).unwrapped_value
531
-
532
- [1, true, :hello].each do |value|
533
- [:name, 'name'].each do |property_name|
534
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value })).unwrapped_value
535
- assert_equal DESIRED_VALUE, evaluator.evaluate(context(team: { property_name => value.to_s })).unwrapped_value
536
- end
537
- end
538
- end
539
-
540
- def test_in_int_range
541
- config = PrefabProto::Config.new(
542
- key: KEY,
543
- rows: [
544
- PrefabProto::ConfigRow.new(
545
- project_env_id: PROJECT_ENV_ID,
546
- values: [
547
- PrefabProto::ConditionalValue.new(
548
- criteria: [
549
- PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::IN_INT_RANGE,
550
- value_to_match: PrefabProto::ConfigValue.new(int_range: PrefabProto::IntRange.new(start: 30, end: 40)), property_name: 'user.age')
551
- ],
552
- value: DESIRED_VALUE_CONFIG
553
- ),
554
-
555
- PrefabProto::ConditionalValue.new(
556
- criteria: [
557
- PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)
558
- ],
559
- value: PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
560
- )
561
- ]
562
- )
563
- ]
564
- )
565
-
566
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
567
- namespace: nil, base_client: @base_client)
568
-
569
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
570
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 32 } })).unwrapped_value
571
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 29 } })).unwrapped_value
572
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({ 'user' => { 'age' => 41 } })).unwrapped_value
573
- end
574
-
575
- def test_in_int_range_for_time
576
- now = Time.now
577
-
578
- config = PrefabProto::Config.new(
579
- key: KEY,
580
- rows: [
581
- PrefabProto::ConfigRow.new(
582
- project_env_id: PROJECT_ENV_ID,
583
- values: [
584
- PrefabProto::ConditionalValue.new(
585
- criteria: [
586
- PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::IN_INT_RANGE,
587
- value_to_match: PrefabProto::ConfigValue.new(
588
- int_range: PrefabProto::IntRange.new(
589
- start: (now.to_i - 60) * 1000, end: (now.to_i + 60) * 1000
590
- )
591
- ), property_name: 'prefab.current-time')
592
- ],
593
- value: DESIRED_VALUE_CONFIG
594
- ),
595
-
596
- PrefabProto::ConditionalValue.new(
597
- criteria: [
598
- PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)
599
- ],
600
- value: PrefabProto::ConfigValue.new(string: DEFAULT_VALUE)
601
- )
602
- ]
603
- )
604
- ]
605
- )
606
-
607
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil,
608
- namespace: nil, base_client: @base_client)
609
-
610
- Timecop.freeze(now) do
611
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
612
- end
613
-
614
- Timecop.freeze(now - 60) do
615
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
616
- end
617
-
618
- Timecop.freeze(now - 61) do
619
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
620
- end
621
-
622
- Timecop.freeze(now + 59) do
623
- assert_equal DESIRED_VALUE, evaluator.evaluate(context({})).unwrapped_value
624
- end
625
-
626
- Timecop.freeze(now + 60) do
627
- assert_equal DEFAULT_VALUE, evaluator.evaluate(context({})).unwrapped_value
628
- end
629
- end
630
-
631
- def test_evaluating_a_log_level
632
- config = PrefabProto::Config.new(
633
- id: 999,
634
- key: 'log-level',
635
- config_type: PrefabProto::ConfigType::LOG_LEVEL,
636
- rows: [
637
- PrefabProto::ConfigRow.new(
638
- values: [
639
- PrefabProto::ConditionalValue.new(
640
- criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
641
- value: PrefabProto::ConfigValue.new(log_level: PrefabProto::LogLevel::DEBUG)
642
- )
643
- ]
644
- )
645
- ]
646
- )
647
-
648
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client, namespace: nil)
649
-
650
- assert_equal :DEBUG, evaluator.evaluate(context({})).unwrapped_value
651
- end
652
-
653
- def test_evaluating_a_weighted_value
654
- config = PrefabProto::Config.new(
655
- id: 123,
656
- key: KEY,
657
- config_type: PrefabProto::ConfigType::CONFIG,
658
- rows: [
659
- PrefabProto::ConfigRow.new(
660
- project_env_id: PROJECT_ENV_ID,
661
- values: [
662
- PrefabProto::ConditionalValue.new(
663
- criteria: [PrefabProto::Criterion.new(operator: PrefabProto::Criterion::CriterionOperator::ALWAYS_TRUE)],
664
- value: PrefabProto::ConfigValue.new(weighted_values: weighted_values([['abc', 98], ['def', 1], ['ghi', 1]]))
665
- )
666
- ]
667
- )
668
- ]
669
- )
670
-
671
- evaluator = Prefab::CriteriaEvaluator.new(config, project_env_id: PROJECT_ENV_ID, resolver: nil, base_client: @base_client, namespace: nil)
672
-
673
- 2.times do
674
- assert_equal 'abc', evaluator.evaluate(context('user' => { 'key' => '1' })).unwrapped_value
675
- end
676
-
677
- 3.times do
678
- context = context({ 'user' => { 'key' => '12' } })
679
- assert_equal 'def', evaluator.evaluate(context).unwrapped_value
680
- end
681
-
682
- context = context({ 'user' => { 'key' => '4' } })
683
- assert_equal 'ghi', evaluator.evaluate(context).unwrapped_value
684
- end
685
-
686
- private
687
-
688
- def string_list(values)
689
- PrefabProto::ConfigValue.new(string_list: PrefabProto::StringList.new(values: values))
690
- end
691
-
692
- class FakeResolver
693
- def initialize(config, base_client)
694
- @config = config
695
- @base_client = base_client
696
- end
697
-
698
- def raw(key)
699
- @config[key]
700
- end
701
-
702
- def get(key, properties = {})
703
- # This only gets called for segments, so we don't need to pass in a resolver
704
- Prefab::CriteriaEvaluator.new(@config[key], project_env_id: nil, resolver: nil,
705
- namespace: nil, base_client: @base_client).evaluate(properties)
706
- end
707
- end
708
-
709
- def resolver_fake(config)
710
- FakeResolver.new(config, @base_client)
711
- end
712
-
713
- class FakeBaseClient
714
- def initialize
715
- Prefab::LoggerClient.new($stdout)
716
- end
717
-
718
- def evaluation_summary_aggregator
719
- @evaluation_summary_aggregator ||= Prefab::EvaluationSummaryAggregator.new(client: self, max_keys: 9999, sync_interval: 9999)
720
- end
721
-
722
- def instance_hash
723
- 'fake-base-client-instance_hash'
724
- end
725
- end
726
- end