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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +39 -0
- data/.tool-versions +1 -0
- data/CODEOWNERS +1 -0
- data/Gemfile +11 -4
- data/Gemfile.lock +52 -32
- data/README.md +19 -1
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/compile_protos.sh +3 -0
- data/lib/prefab/auth_interceptor.rb +1 -0
- data/lib/prefab/cancellable_interceptor.rb +1 -0
- data/lib/prefab/client.rb +51 -38
- data/lib/prefab/config_client.rb +145 -73
- data/lib/prefab/config_helper.rb +29 -0
- data/lib/prefab/config_loader.rb +98 -13
- data/lib/prefab/config_resolver.rb +56 -49
- data/lib/prefab/error.rb +6 -0
- data/lib/prefab/errors/initialization_timeout_error.rb +13 -0
- data/lib/prefab/errors/invalid_api_key_error.rb +19 -0
- data/lib/prefab/errors/missing_default_error.rb +13 -0
- data/lib/prefab/feature_flag_client.rb +129 -11
- data/lib/prefab/internal_logger.rb +29 -0
- data/lib/prefab/logger_client.rb +10 -8
- data/lib/prefab/murmer3.rb +1 -0
- data/lib/prefab/noop_cache.rb +1 -0
- data/lib/prefab/noop_stats.rb +1 -0
- data/lib/prefab/options.rb +82 -0
- data/lib/prefab/ratelimit_client.rb +1 -0
- data/lib/prefab-cloud-ruby.rb +10 -0
- data/lib/prefab_pb.rb +214 -132
- data/lib/prefab_services_pb.rb +35 -6
- data/prefab-cloud-ruby.gemspec +29 -10
- data/run_test_harness_server.sh +8 -0
- data/test/.prefab.test.config.yaml +27 -1
- data/test/harness_server.rb +64 -0
- data/test/test_client.rb +98 -0
- data/test/test_config_client.rb +56 -0
- data/test/test_config_loader.rb +39 -25
- data/test/test_config_resolver.rb +134 -38
- data/test/test_feature_flag_client.rb +277 -35
- data/test/test_helper.rb +70 -4
- data/test/test_logger.rb +23 -29
- metadata +69 -14
- data/.ruby-version +0 -1
data/test/test_client.rb
ADDED
@@ -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
|
data/test/test_config_loader.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
7
|
-
|
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, "
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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
|
-
|
53
|
-
@loader.set(
|
67
|
+
config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)])
|
68
|
+
@loader.set(config, "test")
|
54
69
|
|
55
|
-
|
56
|
-
|
57
|
-
assert_equal
|
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
|
-
|
63
|
-
@loader.set(
|
77
|
+
config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)], id: 2)
|
78
|
+
@loader.set(config, "test")
|
64
79
|
|
65
|
-
|
66
|
-
@loader.set(
|
80
|
+
config = Prefab::Config.new(key: "sample_int", rows: [], id: 3)
|
81
|
+
@loader.set(config, "test")
|
67
82
|
|
68
|
-
|
69
|
-
assert_equal
|
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
|
-
"
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
19
|
-
|
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
|
-
@
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
143
|
+
def test_key_and_namespaces_with_colons
|
63
144
|
@loader = MockConfigLoader.new
|
145
|
+
|
64
146
|
loaded_values = {
|
65
|
-
"Key:With:Colons" => Prefab::
|
66
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
180
|
+
assert_equal "value", @resolverKeyWithExtra.get("Key:With:Colons")
|
91
181
|
|
92
182
|
@resolverKey = resolver_for_namespace("Key", @loader)
|
93
|
-
|
183
|
+
assert_nil @resolverKey.get("With:Colons")
|
94
184
|
assert_nil @resolverKey.get("Colons")
|
95
|
-
|
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
|
-
|
100
|
-
|
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::
|
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
|