prefab-cloud-ruby 0.13.1 → 0.13.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|