Skip to content

Commit 260d168

Browse files
committed
hooks are the highest precedence in context merging followed by invocation.
Fixes #43
1 parent 265ebd4 commit 260d168

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private <T> FlagEvaluationDetails<T> evaluateFlag(FlagValueType type, String key
6464
try {
6565
EvaluationContext ctxFromHook = hookSupport.beforeHooks(type, hookCtx, mergedHooks, hints);
6666

67-
EvaluationContext invocationCtx = EvaluationContext.merge(ctxFromHook, ctx);
67+
EvaluationContext invocationCtx = EvaluationContext.merge(ctx, ctxFromHook);
6868

6969
// merge of: API.context, client.context, invocation.context
7070
EvaluationContext mergedCtx = EvaluationContext.merge(

src/test/java/dev/openfeature/javasdk/HookSpecTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -455,14 +455,15 @@ public void finallyAfter(HookContext<Boolean> ctx, Map<String, Object> hints) {
455455

456456
}
457457

458-
@Specification(number="4.3.4", text="When before hooks have finished executing, any resulting evaluation context MUST be merged with the invocation evaluation context with the invocation evaluation context taking precedence in the case of any conflicts.")
458+
@Specification(number="4.3.4", text="When before hooks have finished executing, any resulting evaluation context MUST be merged with the existing evaluation context in the following order: before-hook (highest precedence), invocation, client, api (lowest precedence).")
459459
@Test void mergeHappensCorrectly() {
460460
EvaluationContext hookCtx = new EvaluationContext();
461-
hookCtx.addStringAttribute("test", "broken");
461+
hookCtx.addStringAttribute("test", "works");
462462
hookCtx.addStringAttribute("another", "exists");
463463

464464
EvaluationContext invocationCtx = new EvaluationContext();
465-
invocationCtx.addStringAttribute("test", "works");
465+
invocationCtx.addStringAttribute("something", "here");
466+
invocationCtx.addStringAttribute("test", "broken");
466467

467468
Hook<Boolean> hook = mockBooleanHook();
468469
when(hook.before(any(), any())).thenReturn(Optional.of(hookCtx));
@@ -485,6 +486,7 @@ public void finallyAfter(HookContext<Boolean> ctx, Map<String, Object> hints) {
485486
EvaluationContext ec = captor.getValue();
486487
assertEquals("works", ec.getStringAttribute("test"));
487488
assertEquals("exists", ec.getStringAttribute("another"));
489+
assertEquals("here", ec.getStringAttribute("something"));
488490
}
489491

490492
@Specification(number="4.4.3", text="If a finally hook abnormally terminates, evaluation MUST proceed, including the execution of any remaining finally hooks.")

0 commit comments

Comments
 (0)