prefab-cloud-ruby 0.13.1 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +39 -0
  3. data/.tool-versions +1 -0
  4. data/CODEOWNERS +1 -0
  5. data/Gemfile +11 -4
  6. data/Gemfile.lock +52 -32
  7. data/README.md +19 -1
  8. data/Rakefile +1 -0
  9. data/VERSION +1 -1
  10. data/compile_protos.sh +3 -0
  11. data/lib/prefab/auth_interceptor.rb +1 -0
  12. data/lib/prefab/cancellable_interceptor.rb +1 -0
  13. data/lib/prefab/client.rb +51 -38
  14. data/lib/prefab/config_client.rb +145 -73
  15. data/lib/prefab/config_helper.rb +29 -0
  16. data/lib/prefab/config_loader.rb +98 -13
  17. data/lib/prefab/config_resolver.rb +56 -49
  18. data/lib/prefab/error.rb +6 -0
  19. data/lib/prefab/errors/initialization_timeout_error.rb +13 -0
  20. data/lib/prefab/errors/invalid_api_key_error.rb +19 -0
  21. data/lib/prefab/errors/missing_default_error.rb +13 -0
  22. data/lib/prefab/feature_flag_client.rb +129 -11
  23. data/lib/prefab/internal_logger.rb +29 -0
  24. data/lib/prefab/logger_client.rb +10 -8
  25. data/lib/prefab/murmer3.rb +1 -0
  26. data/lib/prefab/noop_cache.rb +1 -0
  27. data/lib/prefab/noop_stats.rb +1 -0
  28. data/lib/prefab/options.rb +82 -0
  29. data/lib/prefab/ratelimit_client.rb +1 -0
  30. data/lib/prefab-cloud-ruby.rb +10 -0
  31. data/lib/prefab_pb.rb +214 -132
  32. data/lib/prefab_services_pb.rb +35 -6
  33. data/prefab-cloud-ruby.gemspec +29 -10
  34. data/run_test_harness_server.sh +8 -0
  35. data/test/.prefab.test.config.yaml +27 -1
  36. data/test/harness_server.rb +64 -0
  37. data/test/test_client.rb +98 -0
  38. data/test/test_config_client.rb +56 -0
  39. data/test/test_config_loader.rb +39 -25
  40. data/test/test_config_resolver.rb +134 -38
  41. data/test/test_feature_flag_client.rb +277 -35
  42. data/test/test_helper.rb +70 -4
  43. data/test/test_logger.rb +23 -29
  44. metadata +69 -14
  45. data/.ruby-version +0 -1
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+ require 'test_helper'
3
+
4
+ class TestClient < Minitest::Test
5
+ def setup
6
+ @client = new_client
7
+ end
8
+
9
+ def test_get
10
+ assert_equal "test sample value", @client.get("sample")
11
+ assert_equal 123, @client.get("sample_int")
12
+ end
13
+
14
+ def test_get_with_default
15
+ # A `false` value is not replaced with the default
16
+ assert_equal false, @client.get("false_value", "red")
17
+
18
+ # A falsy value is not replaced with the default
19
+ assert_equal 0, @client.get("zero_value", "red")
20
+
21
+ # A missing value returns the default
22
+ assert_equal "buckets", @client.get("missing_value", "buckets")
23
+ end
24
+
25
+ def test_get_with_missing_default
26
+ # it raises by default
27
+ err = assert_raises(Prefab::Errors::MissingDefaultError) do
28
+ assert_nil @client.get("missing_value")
29
+ end
30
+
31
+ assert_match(/No value found for key/, err.message)
32
+ assert_match(/on_no_default/, err.message)
33
+
34
+ # you can opt-in to return `nil` instead
35
+ client = new_client(on_no_default: Prefab::Options::ON_NO_DEFAULT::RETURN_NIL)
36
+ assert_nil client.get("missing_value")
37
+ end
38
+
39
+ def test_enabled
40
+ assert_equal false, @client.enabled?("does_not_exist")
41
+ assert_equal true, @client.enabled?("enabled_flag")
42
+ assert_equal false, @client.enabled?("disabled_flag")
43
+ assert_equal false, @client.enabled?("flag_with_a_value")
44
+ end
45
+
46
+ def test_ff_enabled_with_lookup_key
47
+ assert_equal false, @client.enabled?("in_lookup_key", "jimmy")
48
+ assert_equal true, @client.enabled?("in_lookup_key", "abc123")
49
+ assert_equal true, @client.enabled?("in_lookup_key", "xyz987")
50
+ end
51
+
52
+ def test_ff_get_with_lookup_key
53
+ assert_nil @client.get("in_lookup_key", "jimmy")
54
+ assert_equal "DEFAULT", @client.get("in_lookup_key", "jimmy", {}, "DEFAULT")
55
+
56
+ assert_equal true, @client.get("in_lookup_key", "abc123")
57
+ assert_equal true, @client.get("in_lookup_key", "xyz987")
58
+ end
59
+
60
+ def test_ff_enabled_with_attributes
61
+ assert_equal false, @client.enabled?("just_my_domain", "abc123", { domain: "gmail.com" })
62
+ assert_equal false, @client.enabled?("just_my_domain", "abc123", { domain: "prefab.cloud" })
63
+ assert_equal false, @client.enabled?("just_my_domain", "abc123", { domain: "example.com" })
64
+ end
65
+
66
+ def test_ff_get_with_attributes
67
+ assert_nil @client.get("just_my_domain", "abc123", { domain: "gmail.com" })
68
+ assert_equal "DEFAULT", @client.get("just_my_domain", "abc123", { domain: "gmail.com" }, "DEFAULT")
69
+
70
+ assert_equal "new-version", @client.get("just_my_domain", "abc123", { domain: "prefab.cloud" })
71
+ assert_equal "new-version", @client.get("just_my_domain", "abc123", { domain: "example.com" })
72
+ end
73
+
74
+ def test_getting_feature_flag_value
75
+ assert_equal false, @client.enabled?("flag_with_a_value")
76
+ assert_equal "all-features", @client.get("flag_with_a_value")
77
+ end
78
+
79
+ def test_ssl_certs
80
+ certs = @client.send(:ssl_certs).split("-----BEGIN CERTIFICATE-----")
81
+
82
+ # This is a smoke test to make sure multiple certs are loaded
83
+ assert certs.length > 1
84
+ end
85
+
86
+ private
87
+
88
+ def new_client(overrides = {})
89
+ options = Prefab::Options.new(**{
90
+ prefab_config_override_dir: "none",
91
+ prefab_config_classpath_dir: "test",
92
+ defaults_env: "unit_tests",
93
+ prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
94
+ }.merge(overrides))
95
+
96
+ Prefab::Client.new(options)
97
+ end
98
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ require 'test_helper'
3
+
4
+ class TestConfigClient < Minitest::Test
5
+ def setup
6
+ options = Prefab::Options.new(
7
+ prefab_config_override_dir: "none",
8
+ prefab_config_classpath_dir: "test",
9
+ defaults_env: "unit_tests",
10
+ prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
11
+ )
12
+
13
+ @config_client = Prefab::ConfigClient.new(MockBaseClient.new(options), 10)
14
+ end
15
+
16
+ def test_load
17
+ assert_equal "test sample value", @config_client.get("sample")
18
+ assert_equal 123, @config_client.get("sample_int")
19
+ end
20
+
21
+ def test_initialization_timeout_error
22
+ options = Prefab::Options.new(
23
+ api_key: "123-ENV-KEY-SDK",
24
+ initialization_timeout_sec: 0.01,
25
+ logdev: StringIO.new
26
+ )
27
+
28
+ err = assert_raises(Prefab::Errors::InitializationTimeoutError) do
29
+ Prefab::Client.new(options).config_client.get("anything")
30
+ end
31
+
32
+ assert_match(/couldn't initialize in 0.01 second timeout/, err.message)
33
+ end
34
+
35
+ def test_invalid_api_key_error
36
+ options = Prefab::Options.new(
37
+ api_key: "",
38
+ )
39
+
40
+ err = assert_raises(Prefab::Errors::InvalidApiKeyError) do
41
+ Prefab::Client.new(options).config_client.get("anything")
42
+ end
43
+
44
+ assert_match(/No API key/, err.message)
45
+
46
+ options = Prefab::Options.new(
47
+ api_key: "invalid",
48
+ )
49
+
50
+ err = assert_raises(Prefab::Errors::InvalidApiKeyError) do
51
+ Prefab::Client.new(options).config_client.get("anything")
52
+ end
53
+
54
+ assert_match(/format is invalid/, err.message)
55
+ end
56
+ end
@@ -1,41 +1,56 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class TestConfigLoader < Minitest::Test
4
5
  def setup
5
- ENV['PREFAB_CONFIG_OVERRIDE_DIR'] = "none"
6
- ENV['PREFAB_CONFIG_CLASSPATH_DIR'] = "test"
7
- @loader = Prefab::ConfigLoader.new(MockBaseClient.new)
6
+ options = Prefab::Options.new(
7
+ prefab_config_override_dir: "none",
8
+ prefab_config_classpath_dir: "test",
9
+ defaults_env: "unit_tests"
10
+ )
11
+ @loader = Prefab::ConfigLoader.new(MockBaseClient.new(options))
8
12
  end
9
13
 
10
14
  def test_load
11
15
  should_be :int, 123, "sample_int"
12
- should_be :string, "OneTwoThree", "sample"
16
+ should_be :string, "test sample value", "sample"
13
17
  should_be :bool, true, "sample_bool"
14
18
  should_be :double, 12.12, "sample_double"
15
19
  end
16
20
 
21
+ def test_load_in_no_default_env
22
+ options = Prefab::Options.new(
23
+ prefab_config_override_dir: "none",
24
+ prefab_config_classpath_dir: "test",
25
+ # no defaults_env
26
+ )
27
+ @loader = Prefab::ConfigLoader.new(MockBaseClient.new(options))
28
+ should_be :string, "default sample value", "sample"
29
+ should_be :bool, true, "sample_bool"
30
+ end
31
+
17
32
  def test_highwater
18
33
  assert_equal 0, @loader.highwater_mark
19
- @loader.set(Prefab::ConfigDelta.new(id: 1, key: "sample_int", value: Prefab::ConfigValue.new(int: 456)))
34
+ @loader.set(Prefab::Config.new(id: 1, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]),"test")
20
35
  assert_equal 1, @loader.highwater_mark
21
36
 
22
- @loader.set(Prefab::ConfigDelta.new(id: 5, key: "sample_int", value: Prefab::ConfigValue.new(int: 456)))
37
+ @loader.set(Prefab::Config.new(id: 5, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]),"test")
23
38
  assert_equal 5, @loader.highwater_mark
24
- @loader.set(Prefab::ConfigDelta.new(id: 2, key: "sample_int", value: Prefab::ConfigValue.new(int: 456)))
39
+ @loader.set(Prefab::Config.new(id: 2, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]),"test")
25
40
  assert_equal 5, @loader.highwater_mark
26
41
  end
27
42
 
28
43
  def test_keeps_most_recent
29
44
  assert_equal 0, @loader.highwater_mark
30
- @loader.set(Prefab::ConfigDelta.new(id: 1, key: "sample_int", value: Prefab::ConfigValue.new(int: 1)))
45
+ @loader.set(Prefab::Config.new(id: 1, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 1))]),"test")
31
46
  assert_equal 1, @loader.highwater_mark
32
47
  should_be :int, 1, "sample_int"
33
48
 
34
- @loader.set(Prefab::ConfigDelta.new(id: 4, key: "sample_int", value: Prefab::ConfigValue.new(int: 4)))
49
+ @loader.set(Prefab::Config.new(id: 4, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 4))]),"test")
35
50
  assert_equal 4, @loader.highwater_mark
36
51
  should_be :int, 4, "sample_int"
37
52
 
38
- @loader.set(Prefab::ConfigDelta.new(id: 2, key: "sample_int", value: Prefab::ConfigValue.new(int: 2)))
53
+ @loader.set(Prefab::Config.new(id: 2, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 2))]),"test")
39
54
  assert_equal 4, @loader.highwater_mark
40
55
  should_be :int, 4, "sample_int"
41
56
  end
@@ -43,37 +58,36 @@ class TestConfigLoader < Minitest::Test
43
58
  def test_api_precedence
44
59
  should_be :int, 123, "sample_int"
45
60
 
46
- @loader.set(Prefab::ConfigDelta.new(key: "sample_int", value: Prefab::ConfigValue.new(int: 456)))
61
+ @loader.set(Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]), "test")
47
62
  should_be :int, 456, "sample_int"
48
63
  end
49
64
 
50
65
  def test_api_deltas
51
66
  val = Prefab::ConfigValue.new(int: 456)
52
- delta = Prefab::ConfigDelta.new(key: "sample_int", value: val)
53
- @loader.set(delta)
67
+ config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)])
68
+ @loader.set(config, "test")
54
69
 
55
- deltas = Prefab::ConfigDeltas.new
56
- deltas.deltas << delta
57
- assert_equal deltas, @loader.get_api_deltas
70
+ configs = Prefab::Configs.new
71
+ configs.configs << config
72
+ assert_equal configs, @loader.get_api_deltas
58
73
  end
59
74
 
60
75
  def test_loading_tombstones_removes_entries
61
76
  val = Prefab::ConfigValue.new(int: 456)
62
- delta = Prefab::ConfigDelta.new(key: "sample_int", value: val)
63
- @loader.set(delta)
77
+ config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)], id: 2)
78
+ @loader.set(config, "test")
64
79
 
65
- delta = Prefab::ConfigDelta.new(key: "sample_int", value: nil)
66
- @loader.set(delta)
80
+ config = Prefab::Config.new(key: "sample_int", rows: [], id: 3)
81
+ @loader.set(config, "test")
67
82
 
68
- deltas = Prefab::ConfigDeltas.new
69
- assert_equal deltas, @loader.get_api_deltas
83
+ configs = Prefab::Configs.new
84
+ assert_equal configs, @loader.get_api_deltas
70
85
  end
71
86
 
72
87
  private
73
88
 
74
89
  def should_be(type, value, key)
75
- assert_equal type, @loader.calc_config[key].type
76
- assert_equal value, @loader.calc_config[key].send(type)
90
+ assert_equal type, @loader.calc_config[key][:config].rows[0].value.type
91
+ assert_equal value, @loader.calc_config[key][:config].rows[0].value.send(type)
77
92
  end
78
-
79
93
  end
@@ -1,22 +1,66 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class TestConfigResolver < Minitest::Test
4
5
 
6
+ STAGING_ENV_ID = 1
7
+ PRODUCTION_ENV_ID = 2
8
+ TEST_ENV_ID = 3
9
+
5
10
  def test_resolution
6
11
  @loader = MockConfigLoader.new
7
12
 
8
13
  loaded_values = {
9
- "projectA:key" => Prefab::ConfigValue.new(string: "valueA"),
10
- "key" => Prefab::ConfigValue.new(string: "value_none"),
11
- "projectB:key" => Prefab::ConfigValue.new(string: "valueB"),
12
- "projectB.subprojectX:key" => Prefab::ConfigValue.new(string: "projectB.subprojectX"),
13
- "projectB.subprojectY:key" => Prefab::ConfigValue.new(string: "projectB.subprojectY"),
14
- "projectB:key2" => Prefab::ConfigValue.new(string: "valueB2")
14
+ "key" => { config: Prefab::Config.new(
15
+ key: "key",
16
+ rows: [
17
+ Prefab::ConfigRow.new(
18
+ value: Prefab::ConfigValue.new(string: "value_no_env_default"),
19
+ ),
20
+ Prefab::ConfigRow.new(
21
+ project_env_id: TEST_ENV_ID,
22
+ value: Prefab::ConfigValue.new(string: "value_none"),
23
+ ),
24
+ Prefab::ConfigRow.new(
25
+ project_env_id: TEST_ENV_ID,
26
+ namespace: "projectA",
27
+ value: Prefab::ConfigValue.new(string: "valueA"),
28
+ ),
29
+ Prefab::ConfigRow.new(
30
+ project_env_id: TEST_ENV_ID,
31
+ namespace: "projectB",
32
+ value: Prefab::ConfigValue.new(string: "valueB"),
33
+ ),
34
+ Prefab::ConfigRow.new(
35
+ project_env_id: TEST_ENV_ID,
36
+ namespace: "projectB.subprojectX",
37
+ value: Prefab::ConfigValue.new(string: "projectB.subprojectX"),
38
+ ),
39
+ Prefab::ConfigRow.new(
40
+ project_env_id: TEST_ENV_ID,
41
+ namespace: "projectB.subprojectY",
42
+ value: Prefab::ConfigValue.new(string: "projectB.subprojectY"),
43
+ ),
44
+
45
+ ]
46
+ ) },
47
+ "key2" => { config: Prefab::Config.new(
48
+ key: "key2",
49
+ rows: [
50
+ value: Prefab::ConfigValue.new(string: "valueB2"),
51
+ ]
52
+ ) }
53
+
15
54
  }
16
55
 
17
56
  @loader.stub :calc_config, loaded_values do
18
- @resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
19
- assert_equal "value_none", @resolver.get("key")
57
+
58
+ @resolverA = resolver_for_namespace("", @loader, project_env_id: PRODUCTION_ENV_ID)
59
+ assert_equal "value_no_env_default", @resolverA.get("key")
60
+
61
+ ## below here in the test env
62
+ @resolverA = resolver_for_namespace("", @loader)
63
+ assert_equal "value_none", @resolverA.get("key")
20
64
 
21
65
  @resolverA = resolver_for_namespace("projectA", @loader)
22
66
  assert_equal "valueA", @resolverA.get("key")
@@ -27,7 +71,10 @@ class TestConfigResolver < Minitest::Test
27
71
  @resolverBX = resolver_for_namespace("projectB.subprojectX", @loader)
28
72
  assert_equal "projectB.subprojectX", @resolverBX.get("key")
29
73
 
30
- @resolverUndefinedSubProject = resolver_for_namespace("projectB.subprojectX:subsubQ", @loader)
74
+ @resolverBX = resolver_for_namespace("projectB.subprojectX", @loader)
75
+ assert_equal "valueB2", @resolverBX.get("key2")
76
+
77
+ @resolverUndefinedSubProject = resolver_for_namespace("projectB.subprojectX.subsubQ", @loader)
31
78
  assert_equal "projectB.subprojectX", @resolverBX.get("key")
32
79
 
33
80
  @resolverBX = resolver_for_namespace("projectC", @loader)
@@ -40,30 +87,75 @@ class TestConfigResolver < Minitest::Test
40
87
  @loader = MockConfigLoader.new
41
88
  @loader.stub :calc_config, {} do
42
89
  resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
43
- assert resolver.send(:starts_with_ns?, "", "a")
44
- assert resolver.send(:starts_with_ns?, "a", "a")
45
- assert resolver.send(:starts_with_ns?, "a", "a.b")
46
- assert !resolver.send(:starts_with_ns?, "a.b", "a")
47
-
48
- assert resolver.send(:starts_with_ns?, "corp", "corp.proj.proja")
49
- assert resolver.send(:starts_with_ns?, "corp.proj", "corp.proj.proja")
50
- assert resolver.send(:starts_with_ns?, "corp.proj.proja", "corp.proj.proja")
51
- assert !resolver.send(:starts_with_ns?, "corp.proj.projb", "corp.proj.proja")
52
-
53
- # corp:a:b is not a real delimited namespace
54
- assert !resolver.send(:starts_with_ns?, "corp", "corp:a:b")
55
- assert resolver.send(:starts_with_ns?, "foo", "foo.baz")
56
- assert resolver.send(:starts_with_ns?, "foo.baz", "foo.baz")
57
- assert !resolver.send(:starts_with_ns?, "foo.baz", "foo.bazz")
90
+ assert_equal [true, 0], resolver.send(:starts_with_ns?, "", "a")
91
+ assert_equal [true, 1], resolver.send(:starts_with_ns?, "a", "a")
92
+ assert_equal [true, 1], resolver.send(:starts_with_ns?, "a", "a.b")
93
+ assert_equal [false, 2], resolver.send(:starts_with_ns?, "a.b", "a")
94
+
95
+ assert_equal [true, 1], resolver.send(:starts_with_ns?, "corp", "corp.proj.proja")
96
+ assert_equal [true, 2], resolver.send(:starts_with_ns?, "corp.proj", "corp.proj.proja")
97
+ assert_equal [true, 3], resolver.send(:starts_with_ns?, "corp.proj.proja", "corp.proj.proja")
98
+ assert_equal [false, 3], resolver.send(:starts_with_ns?, "corp.proj.projb", "corp.proj.proja")
99
+
100
+ # corp_equal [true, 1:,a:b is not a real delimited namespace[0
101
+ assert_equal [false, 1], resolver.send(:starts_with_ns?, "corp", "corp:a:b")
102
+ assert_equal [true, 1], resolver.send(:starts_with_ns?, "foo", "foo.baz")
103
+ assert_equal [true, 2], resolver.send(:starts_with_ns?, "foo.baz", "foo.baz")
104
+ assert_equal [false, 2], resolver.send(:starts_with_ns?, "foo.baz", "foo.bazz")
105
+ end
106
+ end
107
+
108
+ def test_special_ff_variant_copying
109
+
110
+ @loader = MockConfigLoader.new
111
+ loaded_values = {
112
+ "ff" => { source: 'test',
113
+ config: Prefab::Config.new(
114
+ key: "ff",
115
+ variants: [
116
+ Prefab::FeatureFlagVariant.new(string: "inactive"),
117
+ Prefab::FeatureFlagVariant.new(string: "default"),
118
+ Prefab::FeatureFlagVariant.new(string: "env"),
119
+ ],
120
+ rows: [
121
+ { value: Prefab::ConfigValue.new(feature_flag: Prefab::FeatureFlag.new(
122
+ inactive_variant_idx: 0,
123
+ rules: default_ff_rule(1),
124
+ )) },
125
+ { project_env_id: TEST_ENV_ID,
126
+ value: Prefab::ConfigValue.new(feature_flag: Prefab::FeatureFlag.new(
127
+ inactive_variant_idx: 0,
128
+ rules: default_ff_rule(2),
129
+ )) }
130
+ ]
131
+ )
132
+ }
133
+ }
134
+ @loader.stub :calc_config, loaded_values do
135
+ resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
136
+ config = resolver.get_config("ff")
137
+ assert_equal 3, config.variants.size
138
+ assert_equal %w(inactive default env), config.variants.map(&:string)
58
139
  end
59
140
  end
60
141
 
61
142
  # colons are not allowed in keys, but verify behavior anyway
62
- def test_keys_with_colons
143
+ def test_key_and_namespaces_with_colons
63
144
  @loader = MockConfigLoader.new
145
+
64
146
  loaded_values = {
65
- "Key:With:Colons" => Prefab::ConfigValue.new(string: "value"),
66
- "proj:apikey" => Prefab::ConfigValue.new(string: "v2")
147
+ "Key:With:Colons" => { config: Prefab::Config.new(
148
+ key: "Key:With:Colons",
149
+ rows: [Prefab::ConfigRow.new(
150
+ value: Prefab::ConfigValue.new(string: "value")
151
+ )]
152
+ ) },
153
+ "proj:apikey" => { config: Prefab::Config.new(
154
+ key: "proj:apikey",
155
+ rows: [Prefab::ConfigRow.new(
156
+ value: Prefab::ConfigValue.new(string: "v2")
157
+ )]
158
+ ) }
67
159
  }
68
160
 
69
161
  @loader.stub :calc_config, loaded_values do
@@ -72,37 +164,41 @@ class TestConfigResolver < Minitest::Test
72
164
  assert_nil r.get("apikey")
73
165
 
74
166
  r = resolver_for_namespace("proj", @loader)
75
- assert_equal "v2", r.get("apikey")
167
+ assert_nil r.get("apikey")
76
168
 
77
169
  r = resolver_for_namespace("", @loader)
78
170
  assert_nil r.get("apikey")
79
171
 
80
-
81
172
  @resolverKeyWith = resolver_for_namespace("Ket:With", @loader)
82
173
  assert_nil @resolverKeyWith.get("Colons")
83
174
  assert_nil @resolverKeyWith.get("With:Colons")
84
- assert_nil @resolverKeyWith.get("Key:With:Colons")
175
+ assert_equal "value", @resolverKeyWith.get("Key:With:Colons")
85
176
 
86
177
  @resolverKeyWithExtra = resolver_for_namespace("Key:With:Extra", @loader)
87
- puts @resolverKeyWithExtra.to_s
88
178
  assert_nil @resolverKeyWithExtra.get("Colons")
89
179
  assert_nil @resolverKeyWithExtra.get("With:Colons")
90
- assert_nil @resolverKeyWithExtra.get("Key:With:Colons")
180
+ assert_equal "value", @resolverKeyWithExtra.get("Key:With:Colons")
91
181
 
92
182
  @resolverKey = resolver_for_namespace("Key", @loader)
93
- assert_equal "value", @resolverKey.get("With:Colons")
183
+ assert_nil @resolverKey.get("With:Colons")
94
184
  assert_nil @resolverKey.get("Colons")
95
- assert_nil @resolverKey.get("Key:With:Colons")
185
+ assert_equal "value", @resolverKey.get("Key:With:Colons")
96
186
 
97
187
  @resolverWithProperlySegmentedNamespace = resolver_for_namespace("Key.With.Extra", @loader)
98
188
  assert_nil @resolverWithProperlySegmentedNamespace.get("Colons")
99
- assert_equal "value", @resolverWithProperlySegmentedNamespace.get("With:Colons")
100
- assert_nil @resolverWithProperlySegmentedNamespace.get("Key:With:Colons")
189
+ assert_nil @resolverWithProperlySegmentedNamespace.get("With:Colons")
190
+ assert_equal "value", @resolverWithProperlySegmentedNamespace.get("Key:With:Colons")
101
191
  end
102
192
  end
103
193
 
104
- def resolver_for_namespace(namespace, loader)
105
- Prefab::ConfigResolver.new(MockBaseClient.new(namespace: namespace), loader)
194
+ def resolver_for_namespace(namespace, loader, project_env_id: TEST_ENV_ID)
195
+ options = Prefab::Options.new(
196
+ namespace: namespace
197
+ )
198
+ resolver = Prefab::ConfigResolver.new(MockBaseClient.new(options), loader)
199
+ resolver.project_env_id = project_env_id
200
+ resolver.update
201
+ resolver
106
202
  end
107
203
 
108
204
  end