From 28f44b888e3f449385a77a5ea1df13a07fa9d737 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:31:36 -0700 Subject: [PATCH] fix: Prerequisites should not trigger hooks. --- .../__tests__/LDClientImpl.hooks.test.ts | 69 +++++++++++++++++++ .../shared/sdk-client/src/LDClientImpl.ts | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/packages/shared/sdk-client/__tests__/LDClientImpl.hooks.test.ts b/packages/shared/sdk-client/__tests__/LDClientImpl.hooks.test.ts index 9697d4179..9d9c6172f 100644 --- a/packages/shared/sdk-client/__tests__/LDClientImpl.hooks.test.ts +++ b/packages/shared/sdk-client/__tests__/LDClientImpl.hooks.test.ts @@ -3,6 +3,8 @@ import { AutoEnvAttributes } from '@launchdarkly/js-sdk-common'; import { Hook, HookMetadata } from '../src/api'; import LDClientImpl from '../src/LDClientImpl'; import { createBasicPlatform } from './createBasicPlatform'; +import * as mockResponseJson from './evaluation/mockResponse.json'; +import { MockEventSource } from './streaming/LDClientImpl.mocks'; import { makeTestDataManagerFactory } from './TestDataManager'; it('should use hooks registered during configuration', async () => { @@ -239,3 +241,70 @@ it('should execute both initial hooks and hooks added using addHook', async () = }, ); }); + +it('should not execute hooks for prerequisite evaluations', async () => { + const testHook: Hook = { + beforeEvaluation: jest.fn(), + afterEvaluation: jest.fn(), + beforeIdentify: jest.fn(), + afterIdentify: jest.fn(), + getMetadata(): HookMetadata { + return { + name: 'test hook', + }; + }, + }; + + const platform = createBasicPlatform(); + let mockEventSource: MockEventSource; + const simulatedEvents = [{ data: JSON.stringify(mockResponseJson) }]; + platform.requests.createEventSource.mockImplementation( + (streamUri: string = '', options: any = {}) => { + mockEventSource = new MockEventSource(streamUri, options); + mockEventSource.simulateEvents('put', simulatedEvents); + return mockEventSource; + }, + ); + + const factory = makeTestDataManagerFactory('sdk-key', platform); + const client = new LDClientImpl( + 'sdk-key', + AutoEnvAttributes.Disabled, + platform, + { + sendEvents: false, + hooks: [testHook], + logger: { + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }, + }, + factory, + ); + + await client.identify({ key: 'user-key' }); + await client.variation('has-prereq-depth-1', false); + + expect(testHook.beforeEvaluation).toHaveBeenCalledTimes(1); + + expect(testHook.beforeEvaluation).toHaveBeenCalledWith( + { context: { key: 'user-key' }, defaultValue: false, flagKey: 'has-prereq-depth-1' }, + {}, + ); + + expect(testHook.afterEvaluation).toHaveBeenCalledTimes(1); + + expect(testHook.afterEvaluation).toHaveBeenCalledWith( + { context: { key: 'user-key' }, defaultValue: false, flagKey: 'has-prereq-depth-1' }, + {}, + { + reason: { + kind: 'FALLTHROUGH', + }, + value: true, + variationIndex: 0, + }, + ); +}); diff --git a/packages/shared/sdk-client/src/LDClientImpl.ts b/packages/shared/sdk-client/src/LDClientImpl.ts index c29f5cf9e..a9abb0e49 100644 --- a/packages/shared/sdk-client/src/LDClientImpl.ts +++ b/packages/shared/sdk-client/src/LDClientImpl.ts @@ -357,7 +357,7 @@ export default class LDClientImpl implements LDClient { } prerequisites?.forEach((prereqKey) => { - this.variation(prereqKey, undefined); + this._variationInternal(prereqKey, undefined, this._eventFactoryDefault); }); this._eventProcessor?.sendEvent( eventFactory.evalEventClient(