Skip to content

Commit a638aae

Browse files
authored
refac: findValidatedForcedDecision method moved to decision service (#730)
## Summary - Moves findValidatedForcedDecision method to decision service as validatedForcedDecision ## Test plan All unit test and FSC tests should pass.
1 parent 7d058bf commit a638aae

File tree

5 files changed

+109
-113
lines changed

5 files changed

+109
-113
lines changed

packages/optimizely-sdk/lib/core/decision_service/index.ts

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2017-2021 Optimizely, Inc. and contributors *
2+
* Copyright 2017-2022 Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -776,6 +776,98 @@ export class DecisionService {
776776
return bucketingId;
777777
}
778778

779+
/**
780+
* Finds a validated forced decision for specific flagKey and optional ruleKey.
781+
* @param {ProjectConfig} config A projectConfig.
782+
* @param {OptimizelyUserContext} user A Optimizely User Context.
783+
* @param {string} flagKey A flagKey.
784+
* @param {ruleKey} ruleKey A ruleKey (optional).
785+
* @return {DecisionResponse<Variation|null>} DecisionResponse object containing valid variation object and decide reasons.
786+
*/
787+
findValidatedForcedDecision(
788+
config: ProjectConfig,
789+
user: OptimizelyUserContext,
790+
flagKey: string,
791+
ruleKey?: string
792+
): DecisionResponse<Variation | null> {
793+
794+
const decideReasons: (string | number)[][] = [];
795+
const forcedDecision = user.getForcedDecision({ flagKey, ruleKey });
796+
let variation = null;
797+
let variationKey;
798+
const userId = user.getUserId()
799+
if (config && forcedDecision) {
800+
variationKey = forcedDecision.variationKey;
801+
variation = getFlagVariationByKey(config, flagKey, variationKey);
802+
if (variation) {
803+
if (ruleKey) {
804+
this.logger.log(
805+
LOG_LEVEL.INFO,
806+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,
807+
variationKey,
808+
flagKey,
809+
ruleKey,
810+
userId
811+
);
812+
decideReasons.push([
813+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,
814+
variationKey,
815+
flagKey,
816+
ruleKey,
817+
userId
818+
]);
819+
} else {
820+
this.logger.log(
821+
LOG_LEVEL.INFO,
822+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED,
823+
variationKey,
824+
flagKey,
825+
userId
826+
);
827+
decideReasons.push([
828+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED,
829+
variationKey,
830+
flagKey,
831+
userId
832+
])
833+
}
834+
} else {
835+
if (ruleKey) {
836+
this.logger.log(
837+
LOG_LEVEL.INFO,
838+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,
839+
flagKey,
840+
ruleKey,
841+
userId
842+
);
843+
decideReasons.push([
844+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,
845+
flagKey,
846+
ruleKey,
847+
userId
848+
]);
849+
} else {
850+
this.logger.log(
851+
LOG_LEVEL.INFO,
852+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID,
853+
flagKey,
854+
userId
855+
);
856+
decideReasons.push([
857+
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID,
858+
flagKey,
859+
userId
860+
])
861+
}
862+
}
863+
}
864+
865+
return {
866+
result: variation,
867+
reasons: decideReasons,
868+
}
869+
}
870+
779871
/**
780872
* Removes forced variation for given userId and experimentKey
781873
* @param {string} userId String representing the user id
@@ -1021,7 +1113,7 @@ export class DecisionService {
10211113
const decideReasons: (string | number)[][] = [];
10221114

10231115
// check forced decision first
1024-
const forcedDecisionResponse = user.findValidatedForcedDecision(configObj, flagKey, rule.key);
1116+
const forcedDecisionResponse = this.findValidatedForcedDecision(configObj, user, flagKey, rule.key);
10251117
decideReasons.push(...forcedDecisionResponse.reasons);
10261118

10271119
const forcedVariaton = forcedDecisionResponse.result;
@@ -1053,7 +1145,7 @@ export class DecisionService {
10531145

10541146
// check forced decision first
10551147
const rule = rules[ruleIndex];
1056-
const forcedDecisionResponse = user.findValidatedForcedDecision(configObj, flagKey, rule.key);
1148+
const forcedDecisionResponse = this.findValidatedForcedDecision(configObj, user, flagKey, rule.key);
10571149
decideReasons.push(...forcedDecisionResponse.reasons);
10581150

10591151
const forcedVariaton = forcedDecisionResponse.result;

packages/optimizely-sdk/lib/optimizely/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2020-2021, Optimizely, Inc. and contributors *
2+
* Copyright 2020-2022, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -1481,7 +1481,7 @@ export default class Optimizely {
14811481

14821482
const allDecideOptions = this.getAllDecideOptions(options);
14831483

1484-
const forcedDecisionResponse = user.findValidatedForcedDecision(configObj, key);
1484+
const forcedDecisionResponse = this.decisionService.findValidatedForcedDecision(configObj, user, key);
14851485
reasons.push(...forcedDecisionResponse.reasons);
14861486
const variation = forcedDecisionResponse.result;
14871487
if (variation) {

packages/optimizely-sdk/lib/optimizely_user_context/index.tests.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2020-2021, Optimizely, Inc. and contributors *
2+
* Copyright 2020-2022, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -372,11 +372,13 @@ describe('lib/optimizely_user_context', function() {
372372
notificationCenter,
373373
});
374374

375+
sinon.stub(optlyInstance.decisionService.logger, 'log')
375376
sinon.stub(eventDispatcher, 'dispatchEvent');
376377
sinon.stub(optlyInstance.notificationCenter, 'sendNotifications');
377378
});
378379

379380
afterEach(function() {
381+
optlyInstance.decisionService.logger.log.restore();
380382
eventDispatcher.dispatchEvent.restore();
381383
optlyInstance.notificationCenter.sendNotifications.restore();
382384
});
@@ -610,17 +612,13 @@ describe('lib/optimizely_user_context', function() {
610612
assert.deepEqual(decision.userContext.forcedDecisionsMap[featureKey][ruleKey], { variationKey });
611613

612614
sinon.assert.called(stubLogHandler.log);
613-
var logMessage = stubLogHandler.log.args[4][1];
614-
assert.strictEqual(
615-
logMessage,
616-
sprintf(
617-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,
618-
variationKey,
619-
featureKey,
620-
ruleKey,
621-
userId,
622-
)
623-
);
615+
var logMessage = optlyInstance.decisionService.logger.log.args[4];
616+
assert.strictEqual(logMessage[0], 2);
617+
assert.strictEqual(logMessage[1], 'Variation (%s) is mapped to flag (%s), rule (%s) and user (%s) in the forced decision map.');
618+
assert.strictEqual(logMessage[2], variationKey);
619+
assert.strictEqual(logMessage[3], featureKey);
620+
assert.strictEqual(logMessage[4], ruleKey);
621+
assert.strictEqual(logMessage[5], userId);
624622

625623
sinon.assert.calledOnce(eventDispatcher.dispatchEvent);
626624
var callArgs = eventDispatcher.dispatchEvent.getCalls()[0].args;

packages/optimizely-sdk/lib/optimizely_user_context/index.ts

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2020-2021, Optimizely, Inc. and contributors *
2+
* Copyright 2020-2022, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -13,8 +13,6 @@
1313
* See the License for the specific language governing permissions and *
1414
* limitations under the License. *
1515
***************************************************************************/
16-
import { getLogger } from '@optimizely/js-sdk-logging';
17-
1816
import Optimizely from '../../lib/optimizely';
1917
import {
2018
DecisionResponse,
@@ -32,8 +30,6 @@ import {
3230
} from '../core/project_config';
3331
import { LOG_MESSAGES, CONTROL_ATTRIBUTES } from '../utils/enums';
3432

35-
const logger = getLogger();
36-
3733
export default class OptimizelyUserContext {
3834
private optimizely: Optimizely;
3935
private userId: string;
@@ -213,91 +209,6 @@ export default class OptimizelyUserContext {
213209
return null;
214210
}
215211

216-
/**
217-
* Finds a validated forced decision for specific flagKey and optional ruleKey.
218-
* @param {ProjectConfig}config A projectConfig.
219-
* @param {string} flagKey A flagKey.
220-
* @param {ruleKey} ruleKey A ruleKey (optional).
221-
* @return {DecisionResponse<Variation|null>} DecisionResponse object containing valid variation object and decide reasons.
222-
*/
223-
findValidatedForcedDecision(
224-
config: ProjectConfig,
225-
flagKey: string,
226-
ruleKey?: string,
227-
): DecisionResponse<Variation | null> {
228-
229-
const decideReasons: (string | number)[][] = [];
230-
const forcedDecision = this.findForcedDecision({ flagKey, ruleKey });
231-
let variation = null;
232-
let variationKey;
233-
if (config && forcedDecision) {
234-
variationKey = forcedDecision.variationKey;
235-
variation = getFlagVariationByKey(config, flagKey, variationKey);
236-
if (variation) {
237-
if (ruleKey) {
238-
logger.info(
239-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,
240-
variationKey,
241-
flagKey,
242-
ruleKey,
243-
this.userId
244-
);
245-
decideReasons.push([
246-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,
247-
variationKey,
248-
flagKey,
249-
ruleKey,
250-
this.userId
251-
]);
252-
} else {
253-
logger.info(
254-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED,
255-
variationKey,
256-
flagKey,
257-
this.userId
258-
);
259-
decideReasons.push([
260-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED,
261-
variationKey,
262-
flagKey,
263-
this.userId
264-
])
265-
}
266-
} else {
267-
if (ruleKey) {
268-
logger.info(
269-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,
270-
flagKey,
271-
ruleKey,
272-
this.userId
273-
);
274-
decideReasons.push([
275-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,
276-
flagKey,
277-
ruleKey,
278-
this.userId
279-
]);
280-
} else {
281-
logger.info(
282-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID,
283-
flagKey,
284-
this.userId
285-
);
286-
decideReasons.push([
287-
LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID,
288-
flagKey,
289-
this.userId
290-
])
291-
}
292-
}
293-
}
294-
295-
return {
296-
result: variation,
297-
reasons: decideReasons,
298-
}
299-
}
300-
301212
private cloneUserContext(): OptimizelyUserContext {
302213
const userContext = new OptimizelyUserContext({
303214
optimizely: this.getOptimizely(),

packages/optimizely-sdk/lib/shared_types.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2020-2021, Optimizely
2+
* Copyright 2020-2022, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -382,11 +382,6 @@ export interface OptimizelyUserContext {
382382
options: OptimizelyDecideOption[],
383383
): { [key: string]: OptimizelyDecision };
384384
trackEvent(eventName: string, eventTags?: EventTags): void;
385-
findValidatedForcedDecision(
386-
config: ProjectConfig,
387-
flagKey: string,
388-
ruleKey?: string
389-
): DecisionResponse<Variation | null>;
390385
setForcedDecision(context: OptimizelyDecisionContext, decision: OptimizelyForcedDecision): boolean;
391386
getForcedDecision(context: OptimizelyDecisionContext): OptimizelyForcedDecision | null;
392387
removeForcedDecision(context: OptimizelyDecisionContext): boolean;

0 commit comments

Comments
 (0)