Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ public <T> ProviderEvaluation<T> evaluate(
return error(defaultValue, ErrorCode.INVALID_CONTEXT);
}

if (context.getTargetingKey() == null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return error(defaultValue, ErrorCode.TARGETING_KEY_MISSING);
}

final Flag flag = config.flags.get(key);
if (flag == null) {
return error(defaultValue, ErrorCode.FLAG_NOT_FOUND);
Expand Down Expand Up @@ -127,6 +123,9 @@ public <T> ProviderEvaluation<T> evaluate(
return resolveVariant(
target, key, defaultValue, flag, split.variationKey, allocation, context);
} else {
if (targetingKey == null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return error(defaultValue, ErrorCode.TARGETING_KEY_MISSING);
}
// To match a split, subject must match ALL underlying shards
boolean allShardsMatch = true;
for (final Shard shard : split.shards) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,23 @@ public void testFlattening(

private static List<TestCase<?>> evaluateTestCases() {
return Arrays.asList(
// OF spec 3.1.1: targeting key is optional; static flags must evaluate successfully without
// it
new TestCase<>("default")
.flag("simple-string")
// no .targetingKey() -- null by default
.result(new Result<>("test-value").reason(TARGETING_MATCH.name()).variant("on")),
// Null targeting key on sharded flag must return TARGETING_KEY_MISSING
new TestCase<>("default")
.flag("shard-flag")
// no .targetingKey() -- null
.result(new Result<>("default").reason(ERROR.name()).errorCode(TARGETING_KEY_MISSING)),
// Null targeting key on rule-only flag (matching on non-id attribute) must succeed
new TestCase<>("default")
.flag("country-rule-flag")
// no .targetingKey() -- null
.context("country", "US")
.result(new Result<>("us-value").reason(TARGETING_MATCH.name()).variant("us")),
// OF.7: Empty string is a valid targeting key - evaluation should proceed as normal
new TestCase<>("default")
.flag("simple-string")
Expand Down Expand Up @@ -536,6 +550,7 @@ private ServerConfiguration createTestConfiguration() {
flags.put("not-matches-false-flag", createNotMatchesFalseFlag());
flags.put("not-one-of-false-flag", createNotOneOfFalseFlag());
flags.put("null-context-values-flag", createNullContextValuesFlag());
flags.put("country-rule-flag", createCountryRuleFlag());
return new ServerConfiguration(null, null, null, flags);
}

Expand Down Expand Up @@ -1194,6 +1209,33 @@ private Flag createNullContextValuesFlag() {
"null-context-values-flag", true, ValueType.STRING, variants, singletonList(allocation));
}

private Flag createCountryRuleFlag() {
final Map<String, Variant> variants = new HashMap<>();
variants.put("us", new Variant("us", "us-value"));
variants.put("global", new Variant("global", "global-value"));

// Rule: country ONE_OF ["US"] -> us (no shards, so null targeting key is fine)
final List<String> usCountries = singletonList("US");
final List<ConditionConfiguration> usConditions =
singletonList(new ConditionConfiguration(ConditionOperator.ONE_OF, "country", usCountries));
final List<Rule> usRules = singletonList(new Rule(usConditions));
final List<Split> usSplits = singletonList(new Split(emptyList(), "us", null));
final Allocation usAllocation =
new Allocation("us-alloc", usRules, null, null, usSplits, false);

// Fallback allocation (no rules, no shards)
final List<Split> globalSplits = singletonList(new Split(emptyList(), "global", null));
final Allocation globalAllocation =
new Allocation("global-alloc", null, null, null, globalSplits, false);

return new Flag(
"country-rule-flag",
true,
ValueType.STRING,
variants,
asList(usAllocation, globalAllocation));
}

private static Map<String, Object> mapOf(final Object... props) {
final Map<String, Object> result = new HashMap<>(props.length << 1);
int index = 0;
Expand Down
Loading