@@ -25,6 +25,13 @@ import { createProjectConfig } from '../project_config/project_config';
2525import { getMockLogger } from '../tests/mock/mock_logger' ;
2626import { createOdpManager } from '../odp/odp_manager_factory.node' ;
2727import { extractOdpManager } from '../odp/odp_manager_factory' ;
28+ import { Value } from '../utils/promise/operation_value' ;
29+ import { getDecisionTestDatafile } from '../tests/decision_test_datafile' ;
30+ import { DECISION_SOURCES } from '../utils/enums' ;
31+ import OptimizelyUserContext from '../optimizely_user_context' ;
32+ import { newErrorDecision } from '../optimizely_decision' ;
33+ import { EventDispatcher } from '../shared_types' ;
34+ import { ImpressionEvent } from '../event_processor/event_builder/user_event' ;
2835
2936describe ( 'Optimizely' , ( ) => {
3037 const eventDispatcher = {
@@ -59,4 +66,112 @@ describe('Optimizely', () => {
5966 expect ( eventProcessor . makeDisposable ) . toHaveBeenCalled ( ) ;
6067 expect ( odpManager . makeDisposable ) . toHaveBeenCalled ( ) ;
6168 } ) ;
69+
70+ describe ( 'decideAsync' , ( ) => {
71+ it ( 'should return an error decision with correct reasons if decisionService returns error' , async ( ) => {
72+ const projectConfig = createProjectConfig ( getDecisionTestDatafile ( ) ) ;
73+
74+ const projectConfigManager = getMockProjectConfigManager ( {
75+ initConfig : projectConfig ,
76+ } ) ;
77+
78+ const optimizely = new Optimizely ( {
79+ clientEngine : 'node-sdk' ,
80+ projectConfigManager,
81+ jsonSchemaValidator,
82+ logger,
83+ eventProcessor,
84+ odpManager,
85+ disposable : true ,
86+ cmabService : { } as any
87+ } ) ;
88+
89+ // @ts -ignore
90+ const decisionService = optimizely . decisionService ;
91+ vi . spyOn ( decisionService , 'resolveVariationsForFeatureList' ) . mockImplementation ( ( ) => {
92+ return Value . of ( 'async' , [ {
93+ error : true ,
94+ result : {
95+ variation : null ,
96+ experiment : projectConfig . experimentKeyMap [ 'exp_3' ] ,
97+ decisionSource : DECISION_SOURCES . FEATURE_TEST ,
98+ } ,
99+ reasons :[
100+ [ 'test reason %s' , '1' ] ,
101+ [ 'test reason %s' , '2' ] ,
102+ ]
103+ } ] ) ;
104+ } ) ;
105+
106+ const user = new OptimizelyUserContext ( {
107+ optimizely : { } as any ,
108+ userId : 'tester' ,
109+ attributes : {
110+ country : 'BD' ,
111+ age : 80 , // should satisfy audience condition for exp_3 which is cmab and not others
112+ } ,
113+ } ) ;
114+
115+ const decision = await optimizely . decideAsync ( user , 'flag_1' , [ ] ) ;
116+
117+ expect ( decision ) . toEqual ( newErrorDecision ( 'flag_1' , user , [ 'test reason 1' , 'test reason 2' ] ) ) ;
118+ } ) ;
119+
120+ it . only ( 'should include cmab uuid in dispatched event if decisionService returns a cmab uuid' , async ( ) => {
121+ const projectConfig = createProjectConfig ( getDecisionTestDatafile ( ) ) ;
122+
123+ const projectConfigManager = getMockProjectConfigManager ( {
124+ initConfig : projectConfig ,
125+ } ) ;
126+
127+ const eventProcessor = getForwardingEventProcessor ( eventDispatcher ) ;
128+ const processSpy = vi . spyOn ( eventProcessor , 'process' ) ;
129+
130+ const optimizely = new Optimizely ( {
131+ clientEngine : 'node-sdk' ,
132+ projectConfigManager,
133+ eventProcessor,
134+ jsonSchemaValidator,
135+ logger,
136+ odpManager,
137+ disposable : true ,
138+ cmabService : { } as any
139+ } ) ;
140+
141+ // @ts -ignore
142+ const decisionService = optimizely . decisionService ;
143+ vi . spyOn ( decisionService , 'resolveVariationsForFeatureList' ) . mockImplementation ( ( ) => {
144+ return Value . of ( 'async' , [ {
145+ error : false ,
146+ result : {
147+ cmabUuid : 'uuid-cmab' ,
148+ variation : projectConfig . variationIdMap [ '5003' ] ,
149+ experiment : projectConfig . experimentKeyMap [ 'exp_3' ] ,
150+ decisionSource : DECISION_SOURCES . FEATURE_TEST ,
151+ } ,
152+ reasons : [ ] ,
153+ } ] ) ;
154+ } ) ;
155+
156+ const user = new OptimizelyUserContext ( {
157+ optimizely : { } as any ,
158+ userId : 'tester' ,
159+ attributes : {
160+ country : 'BD' ,
161+ age : 80 , // should satisfy audience condition for exp_3 which is cmab and not others
162+ } ,
163+ } ) ;
164+
165+ const decision = await optimizely . decideAsync ( user , 'flag_1' , [ ] ) ;
166+
167+ expect ( decision . ruleKey ) . toBe ( 'exp_3' ) ;
168+ expect ( decision . flagKey ) . toBe ( 'flag_1' ) ;
169+ expect ( decision . variationKey ) . toBe ( 'variation_3' ) ;
170+ expect ( decision . enabled ) . toBe ( true ) ;
171+
172+ expect ( eventProcessor . process ) . toHaveBeenCalledOnce ( ) ;
173+ const event = processSpy . mock . calls [ 0 ] [ 0 ] as ImpressionEvent ;
174+ expect ( event . cmabUuid ) . toBe ( 'uuid-cmab' ) ;
175+ } ) ;
176+ } ) ;
62177} ) ;
0 commit comments