@@ -25,6 +25,13 @@ import { createProjectConfig } from '../project_config/project_config';
25
25
import { getMockLogger } from '../tests/mock/mock_logger' ;
26
26
import { createOdpManager } from '../odp/odp_manager_factory.node' ;
27
27
import { 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' ;
28
35
29
36
describe ( 'Optimizely' , ( ) => {
30
37
const eventDispatcher = {
@@ -59,4 +66,112 @@ describe('Optimizely', () => {
59
66
expect ( eventProcessor . makeDisposable ) . toHaveBeenCalled ( ) ;
60
67
expect ( odpManager . makeDisposable ) . toHaveBeenCalled ( ) ;
61
68
} ) ;
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
+ } ) ;
62
177
} ) ;
0 commit comments