From 4fbc7102fd26f8a253e2bd2649b3f0c220524144 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 10 Jan 2024 13:29:32 -0500 Subject: [PATCH] fix: wrong context passed to named provider Signed-off-by: Todd Baert --- .../client/src/client/open-feature-client.ts | 2 +- packages/client/src/open-feature.ts | 2 +- .../client/test/evaluation-context.spec.ts | 22 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/client/src/client/open-feature-client.ts b/packages/client/src/client/open-feature-client.ts index 84fdc79c7..dc86f0a50 100644 --- a/packages/client/src/client/open-feature-client.ts +++ b/packages/client/src/client/open-feature-client.ts @@ -179,7 +179,7 @@ export class OpenFeatureClient implements Client { const allHooksReversed = [...allHooks].reverse(); const context = { - ...OpenFeature.getContext(), + ...OpenFeature.getContext(this?.options?.name), }; // this reference cannot change during the course of evaluation diff --git a/packages/client/src/open-feature.ts b/packages/client/src/open-feature.ts index 1aa502439..d86c2cc0f 100644 --- a/packages/client/src/open-feature.ts +++ b/packages/client/src/open-feature.ts @@ -106,7 +106,7 @@ export class OpenFeatureAPI extends OpenFeatureCommonAPI impleme * @param {string} clientName The name to identify the client * @returns {EvaluationContext} Evaluation context */ - getContext(clientName: string): EvaluationContext; + getContext(clientName?: string): EvaluationContext; getContext(nameOrUndefined?: string): EvaluationContext { const clientName = stringOrUndefined(nameOrUndefined); if (clientName) { diff --git a/packages/client/test/evaluation-context.spec.ts b/packages/client/test/evaluation-context.spec.ts index 823bd123c..fa7b5cffb 100644 --- a/packages/client/test/evaluation-context.spec.ts +++ b/packages/client/test/evaluation-context.spec.ts @@ -76,6 +76,28 @@ describe('Evaluation Context', () => { expect(OpenFeature.getContext(clientName)).toEqual(globalContext); }); + it('should call onContextChange for appropriate provider with appropriate context', async () => { + const globalContext: EvaluationContext = { scope: 'global' }; + const testContext: EvaluationContext = { scope: 'test' }; + const clientName = 'test'; + const defaultProvider = new MockProvider(); + const provider1 = new MockProvider(); + + await OpenFeature.setProviderAndWait(defaultProvider); + await OpenFeature.setProviderAndWait(clientName, provider1); + + // Spy on context changed handlers of both providers + const defaultProviderSpy = jest.spyOn(defaultProvider, 'onContextChange'); + const provider1Spy = jest.spyOn(provider1, 'onContextChange'); + + await OpenFeature.setContext(globalContext); + await OpenFeature.setContext(clientName, testContext); + + // provider one should get global and specific context calls + expect(defaultProviderSpy).toHaveBeenCalledWith({}, globalContext); + expect(provider1Spy).toHaveBeenCalledWith(globalContext, testContext); + }); + it('should only call a providers onContextChange once when clearing context', async () => { const globalContext: EvaluationContext = { scope: 'global' }; const testContext: EvaluationContext = { scope: 'test' };