Skip to content

Commit 00f930a

Browse files
committed
save
1 parent 9157744 commit 00f930a

File tree

2 files changed

+84
-141
lines changed

2 files changed

+84
-141
lines changed

lib/optimizely_user_context/index.spec.ts

Lines changed: 83 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { NOTIFICATION_TYPES } from '../notification_center/type';
2020
import OptimizelyUserContext from './';
2121
import Optimizely from '../optimizely';
2222
import testData from '../tests/test_data';
23-
import { EventDispatcher, OptimizelyDecideOption } from '../shared_types';
23+
import { EventDispatcher, NotificationCenter, OptimizelyDecideOption } from '../shared_types';
2424
import { getMockProjectConfigManager } from '../tests/mock/mock_project_config_manager';
2525
import { createProjectConfig } from '../project_config/project_config';
2626
import { getForwardingEventProcessor } from '../event_processor/event_processor_factory';
@@ -33,12 +33,13 @@ import {
3333
USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,
3434
USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,
3535
} from '../core/decision_service';
36-
import { R } from 'vitest/dist/chunks/environment.LoooBwUu.js';
3736
import { resolvablePromise } from '../utils/promise/resolvablePromise';
37+
import { LogEvent } from '../event_processor/event_dispatcher/event_dispatcher';
38+
import { DefaultNotificationCenter } from '../notification_center';
3839

3940
const getMockEventDispatcher = () => {
4041
const dispatcher = {
41-
dispatchEvent: vi.fn(() => Promise.resolve({ statusCode: 200 })),
42+
dispatchEvent: vi.fn((event: LogEvent) => Promise.resolve({ statusCode: 200 })),
4243
};
4344
return dispatcher;
4445
};
@@ -372,37 +373,26 @@ describe('OptimizelyUserContext', () => {
372373
});
373374

374375
describe('when valid forced decision is set', () => {
375-
// let optlyInstance: Optimizely;
376-
// let eventDispatcher: ReturnType<typeof getMockEventDispatcher>;
377-
// beforeEach(() => {
378-
379-
// (optlyInstance, eventDispatcher) = getOptlyInstancenew Optimizely({
380-
// clientEngine: 'node-sdk',
381-
// projectConfigManager: getMockProjectConfigManager({
382-
// initConfig: createProjectConfig(testData.getTestDecideProjectConfig()),
383-
// }),
384-
// cmabService: {} as any,
385-
// });
386-
387-
388-
// vi.spyOn(optlyInstance.notificationCenter, 'sendNotifications');
389-
// });
376+
let optlyInstance: Optimizely;
377+
let eventDispatcher: ReturnType<typeof getMockEventDispatcher>;
378+
beforeEach(() => {
379+
({ optlyInstance, eventDispatcher } = getOptlyInstance({
380+
datafileObj: testData.getTestDecideProjectConfig(),
381+
}));
390382

391-
// afterEach(() => {
392-
// eventDispatcher.dispatchEvent.mockClear();
393-
// vi.restoreAllMocks();
394-
// });
383+
vi.spyOn(optlyInstance.notificationCenter, 'sendNotifications');
384+
});
395385

396386
it('should return an expected decision object when forced decision is called and variation of different experiment but same flag key', () => {
397387
const flagKey = 'feature_1';
398388
const ruleKey = 'exp_with_audience';
399389
const variationKey = '3324490633';
400390

401-
getOptlyInstance({
402-
datafileObj: testData.getTestDecideProjectConfig(),
391+
const user = new OptimizelyUserContext({
392+
optimizely: optlyInstance,
393+
userId,
403394
});
404395

405-
const user = optlyInstance.createUserContext(userId);
406396
user.setForcedDecision({ flagKey: flagKey, ruleKey }, { variationKey });
407397
const decision = user.decide(flagKey, options as any);
408398

@@ -415,7 +405,11 @@ describe('OptimizelyUserContext', () => {
415405
});
416406

417407
it('should return forced decision object when forced decision is set for a flag and do NOT dispatch an event with DISABLE_DECISION_EVENT passed in decide options', () => {
418-
const user = optlyInstance.createUserContext(userId);
408+
const user = new OptimizelyUserContext({
409+
optimizely: optlyInstance,
410+
userId,
411+
});
412+
419413
const featureKey = 'feature_1';
420414
const variationKey = '3324490562';
421415
user.setForcedDecision({ flagKey: featureKey }, { variationKey });
@@ -428,10 +422,7 @@ describe('OptimizelyUserContext', () => {
428422
expect(decision.enabled).toEqual(true);
429423
expect(decision.userContext.getUserId()).toEqual(userId);
430424
expect(decision.userContext.getAttributes()).toEqual({});
431-
expect(Object.keys(decision.userContext.forcedDecisionsMap).length).toEqual(1);
432-
expect(decision.userContext.forcedDecisionsMap[featureKey][FORCED_DECISION_NULL_RULE_KEY]).toEqual({
433-
variationKey,
434-
});
425+
435426
expect(
436427
decision.reasons.includes(
437428
sprintf(USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED, variationKey, featureKey, userId)
@@ -441,8 +432,12 @@ describe('OptimizelyUserContext', () => {
441432
expect(eventDispatcher.dispatchEvent).not.toHaveBeenCalled();
442433
});
443434

444-
it('should return forced decision object when forced decision is set for a flag and do NOT dispatch an event with DISABLE_DECISION_EVENT string passed in decide options', () => {
445-
const user = optlyInstance.createUserContext(userId);
435+
it.only('should return forced decision object when forced decision is set for a flag and do NOT dispatch an event with DISABLE_DECISION_EVENT string passed in decide options', () => {
436+
const user = new OptimizelyUserContext({
437+
optimizely: optlyInstance,
438+
userId,
439+
});
440+
446441
const featureKey = 'feature_1';
447442
const variationKey = '3324490562';
448443
user.setForcedDecision({ flagKey: featureKey }, { variationKey });
@@ -452,10 +447,6 @@ describe('OptimizelyUserContext', () => {
452447
expect(decision.enabled).toEqual(true);
453448
expect(decision.userContext.getUserId()).toEqual(userId);
454449
expect(decision.userContext.getAttributes()).toEqual({});
455-
expect(Object.keys(decision.userContext.forcedDecisionsMap).length).toEqual(1);
456-
expect(decision.userContext.forcedDecisionsMap[featureKey][FORCED_DECISION_NULL_RULE_KEY]).toEqual({
457-
variationKey,
458-
});
459450
expect(
460451
decision.reasons.includes(
461452
sprintf(USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED, variationKey, featureKey, userId)
@@ -466,13 +457,6 @@ describe('OptimizelyUserContext', () => {
466457
});
467458

468459
it('should return forced decision object when forced decision is set for a flag and dispatch an event', () => {
469-
const { optlyInstance, eventDispatcher } = getOptlyInstance({
470-
datafileObj: testData.getTestDecideProjectConfig(),
471-
});
472-
473-
const notificationCenter = optlyInstance.notificationCenter;
474-
vi.spyOn(notificationCenter, 'sendNotifications');
475-
476460
const user = optlyInstance.createUserContext(userId);
477461
const featureKey = 'feature_1';
478462
const variationKey = '3324490562';
@@ -495,20 +479,21 @@ describe('OptimizelyUserContext', () => {
495479
).toEqual(true);
496480

497481
expect(eventDispatcher.dispatchEvent).toHaveBeenCalledTimes(1);
498-
const callArgs: any = eventDispatcher.dispatchEvent.mock.calls[0];
499-
const impressionEvent: any = callArgs[0];
500-
const eventDecision: any = impressionEvent.params.visitors[0].snapshots[0].decisions[0];
501-
const metadata = eventDecision.metadata;
482+
const callArgs = eventDispatcher.dispatchEvent.mock.calls[0];
483+
const impressionEvent = callArgs[0];
484+
const eventDecision = impressionEvent.params.visitors?.[0].snapshots?.[0].decisions?.[0];
485+
const metadata = eventDecision?.metadata;
502486

503-
expect(eventDecision.experiment_id).toEqual('');
504-
expect(eventDecision.variation_id).toEqual('3324490562');
487+
expect(eventDecision?.experiment_id).toEqual('');
488+
expect(eventDecision?.variation_id).toEqual('3324490562');
505489

506-
expect(metadata.flag_key).toEqual(featureKey);
507-
expect(metadata.rule_key).toEqual('');
508-
expect(metadata.rule_type).toEqual('feature-test');
509-
expect(metadata.variation_key).toEqual(variationKey);
510-
expect(metadata.enabled).toEqual(true);
490+
expect(metadata?.flag_key).toEqual(featureKey);
491+
expect(metadata?.rule_key).toEqual('');
492+
expect(metadata?.rule_type).toEqual('feature-test');
493+
expect(metadata?.variation_key).toEqual(variationKey);
494+
expect(metadata?.enabled).toEqual(true);
511495

496+
const notificationCenter = optlyInstance.notificationCenter as Mocked<DefaultNotificationCenter>;
512497
expect(notificationCenter.sendNotifications).toHaveBeenCalledTimes(3);
513498
const notificationCallArgs: any = (notificationCenter.sendNotifications as any).mock.calls[2];
514499
const expectedNotificationCallArgs = [
@@ -543,13 +528,6 @@ describe('OptimizelyUserContext', () => {
543528
});
544529

545530
it('should return forced decision object when forced decision is set for an experiment rule and dispatch an event', () => {
546-
const { optlyInstance, eventDispatcher } = getOptlyInstance({
547-
datafileObj: testData.getTestDecideProjectConfig(),
548-
});
549-
550-
const notificationCenter = optlyInstance.notificationCenter;
551-
vi.spyOn(notificationCenter, 'sendNotifications');
552-
553531
const attributes = { country: 'US' };
554532
const user = optlyInstance.createUserContext(userId, attributes);
555533
const featureKey = 'feature_1';
@@ -587,6 +565,8 @@ describe('OptimizelyUserContext', () => {
587565
expect(metadata.variation_key).toEqual('b');
588566
expect(metadata.enabled).toEqual(false);
589567

568+
const notificationCenter = optlyInstance.notificationCenter as Mocked<DefaultNotificationCenter>;
569+
590570
expect(notificationCenter.sendNotifications).toHaveBeenCalledTimes(3);
591571
const notificationCallArgs = (notificationCenter.sendNotifications as any).mock.calls[2];
592572
const expectedNotificationCallArgs = [
@@ -621,13 +601,6 @@ describe('OptimizelyUserContext', () => {
621601
});
622602

623603
it('should return forced decision object when forced decision is set for a delivery rule and dispatch an event', () => {
624-
const { optlyInstance, eventDispatcher } = getOptlyInstance({
625-
datafileObj: testData.getTestDecideProjectConfig(),
626-
});
627-
628-
const notificationCenter = optlyInstance.notificationCenter;
629-
vi.spyOn(notificationCenter, 'sendNotifications');
630-
631604
const user = optlyInstance.createUserContext(userId);
632605
const featureKey = 'feature_1';
633606
const variationKey = '3324490633';
@@ -658,7 +631,8 @@ describe('OptimizelyUserContext', () => {
658631
expect(metadata.rule_type).toEqual('rollout');
659632
expect(metadata.variation_key).toEqual('3324490633');
660633
expect(metadata.enabled).toEqual(true);
661-
634+
635+
const notificationCenter = optlyInstance.notificationCenter as Mocked<DefaultNotificationCenter>;
662636
expect(notificationCenter.sendNotifications).toHaveBeenCalledTimes(3);
663637
const notificationCallArgs = (notificationCenter.sendNotifications as any).mock.calls[2];
664638
const expectedNotificationCallArgs = [
@@ -692,29 +666,14 @@ describe('OptimizelyUserContext', () => {
692666
});
693667

694668
describe('when invalid forced decision is set', () => {
695-
let optlyInstance: any;
696-
let eventDispatcher: any;
697-
let eventProcessor: any;
698-
let createdLogger: any;
699-
669+
let optlyInstance: Optimizely;
670+
let eventDispatcher: ReturnType<typeof getMockEventDispatcher>;
700671
beforeEach(() => {
701-
createdLogger = getMockLogger();
702-
eventDispatcher = getMockEventDispatcher();
703-
eventProcessor = getForwardingEventProcessor(eventDispatcher);
704-
705-
optlyInstance = new Optimizely({
706-
clientEngine: 'node-sdk',
707-
projectConfigManager: getMockProjectConfigManager({
708-
initConfig: createProjectConfig(testData.getTestDecideProjectConfig()),
709-
}),
710-
eventProcessor,
711-
cmabService: {} as any,
712-
logger: createdLogger as any,
713-
});
714-
});
672+
({ optlyInstance, eventDispatcher } = getOptlyInstance({
673+
datafileObj: testData.getTestDecideProjectConfig(),
674+
}));
715675

716-
afterEach(() => {
717-
eventDispatcher.dispatchEvent.mockClear();
676+
vi.spyOn(optlyInstance.notificationCenter, 'sendNotifications');
718677
});
719678

720679
it('should NOT return forced decision object when forced decision is set for a flag', () => {
@@ -727,18 +686,15 @@ describe('OptimizelyUserContext', () => {
727686
// invalid forced decision will be ignored and regular decision will return
728687
expect(decision.variationKey).toEqual('18257766532');
729688
expect(decision.ruleKey).toEqual('18322080788');
730-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap).length).toEqual(1);
731-
expect((decision.userContext as any).forcedDecisionsMap[featureKey][FORCED_DECISION_NULL_RULE_KEY]).toEqual({
732-
variationKey,
733-
});
689+
734690
expect(
735691
decision.reasons.includes(
736692
sprintf(USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID, featureKey, userId)
737693
)
738694
).toEqual(true);
739695
});
740696

741-
it('should NOT return forced decision object when forced decision is set for an experiment rule', () => {
697+
it.only('should NOT return forced decision object when forced decision is set for an experiment rule', () => {
742698
const user = optlyInstance.createUserContext(userId);
743699
const featureKey = 'feature_1';
744700
const ruleKey = 'exp_with_audience';
@@ -749,17 +705,15 @@ describe('OptimizelyUserContext', () => {
749705
// invalid forced-decision will be ignored and regular decision will return
750706
expect(decision.variationKey).toEqual('18257766532');
751707
expect(decision.ruleKey).toEqual('18322080788');
752-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap).length).toEqual(1);
753-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap[featureKey]).length).toEqual(1);
754-
expect((decision.userContext as any).forcedDecisionsMap[featureKey][ruleKey]).toEqual({ variationKey });
708+
755709
expect(
756710
decision.reasons.includes(
757711
sprintf(USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID, featureKey, ruleKey, userId)
758712
)
759713
).toEqual(true);
760714
});
761715

762-
it('should NOT return forced decision object when forced decision is set for a delivery rule', () => {
716+
it.only('should NOT return forced decision object when forced decision is set for a delivery rule', () => {
763717
const user = optlyInstance.createUserContext(userId);
764718
const featureKey = 'feature_1';
765719
const variationKey = 'invalid';
@@ -770,9 +724,7 @@ describe('OptimizelyUserContext', () => {
770724
// invalid forced decision will be ignored and regular decision will return
771725
expect(decision.variationKey).toEqual('18257766532');
772726
expect(decision.ruleKey).toEqual('18322080788');
773-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap).length).toEqual(1);
774-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap[featureKey]).length).toEqual(1);
775-
expect((decision.userContext as any).forcedDecisionsMap[featureKey][ruleKey]).toEqual({ variationKey });
727+
776728
expect(
777729
decision.reasons.includes(
778730
sprintf(USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID, featureKey, ruleKey, userId)
@@ -782,32 +734,17 @@ describe('OptimizelyUserContext', () => {
782734
});
783735

784736
describe('when forced decision is set for a flag and an experiment rule', () => {
785-
let optlyInstance: any;
786-
let eventDispatcher: any;
787-
let eventProcessor: any;
788-
let createdLogger: any;
737+
let optlyInstance: Optimizely;
789738

790739
beforeEach(() => {
791-
createdLogger = getMockLogger();
792-
eventDispatcher = getMockEventDispatcher();
793-
eventProcessor = getForwardingEventProcessor(eventDispatcher);
794-
795-
optlyInstance = new Optimizely({
796-
clientEngine: 'node-sdk',
797-
projectConfigManager: getMockProjectConfigManager({
798-
initConfig: createProjectConfig(testData.getTestDecideProjectConfig()),
799-
}),
800-
eventProcessor,
801-
cmabService: {} as any,
802-
logger: createdLogger as any,
803-
});
804-
});
740+
({ optlyInstance } = getOptlyInstance({
741+
datafileObj: testData.getTestDecideProjectConfig(),
742+
}));
805743

806-
afterEach(() => {
807-
eventDispatcher.dispatchEvent.mockClear();
744+
vi.spyOn(optlyInstance.notificationCenter, 'sendNotifications');
808745
});
809746

810-
it('should prioritize flag forced decision over experiment rule', () => {
747+
it.only('should prioritize flag forced decision over experiment rule', () => {
811748
const user = optlyInstance.createUserContext(userId);
812749
const featureKey = 'feature_1';
813750
const flagVariationKey = '3324490562';
@@ -820,27 +757,33 @@ describe('OptimizelyUserContext', () => {
820757
// flag-to-decision is the 1st priority
821758
expect(decision.variationKey).toEqual(flagVariationKey);
822759
expect(decision.ruleKey).toEqual(null);
823-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap).length).toEqual(1);
824-
expect(Object.keys((decision.userContext as any).forcedDecisionsMap[featureKey]).length).toEqual(2);
825760
});
826761
});
827762
});
828763

829-
describe('#getForcedDecision', () => {
830-
it('should return correct forced variation', () => {
831-
const createdLogger = getMockLogger();
832-
const eventDispatcher = getMockEventDispatcher();
833-
const eventProcessor = getForwardingEventProcessor(eventDispatcher);
834-
const optlyInstance = new Optimizely({
835-
clientEngine: 'node-sdk',
836-
projectConfigManager: getMockProjectConfigManager({
837-
initConfig: createProjectConfig(testData.getTestDecideProjectConfig()),
838-
}),
839-
eventProcessor,
840-
cmabService: {} as any,
841-
logger: createdLogger as any,
842-
});
843-
const user = optlyInstance.createUserContext(userId);
764+
describe('getForcedDecision', () => {
765+
it.only('should return correct forced variation', () => {
766+
const { optlyInstance, createdLogger, eventDispatcher } = getOptlyInstance({
767+
datafileObj: testData.getTestDecideProjectConfig(),
768+
});
769+
770+
// const createdLogger = getMockLogger();
771+
// const eventDispatcher = getMockEventDispatcher();
772+
// const eventProcessor = getForwardingEventProcessor(eventDispatcher);
773+
// const optlyInstance = new Optimizely({
774+
// clientEngine: 'node-sdk',
775+
// projectConfigManager: getMockProjectConfigManager({
776+
// initConfig: createProjectConfig(testData.getTestDecideProjectConfig()),
777+
// }),
778+
// eventProcessor,
779+
// cmabService: {} as any,
780+
// logger: createdLogger,
781+
// });
782+
const user = new OptimizelyUserContext({
783+
optimizely: optlyInstance,
784+
userId,
785+
});
786+
844787
const featureKey = 'feature_1';
845788
const ruleKey = 'r';
846789
user.setForcedDecision({ flagKey: featureKey }, { variationKey: 'fv1' });

0 commit comments

Comments
 (0)