Skip to content

Commit b593f5b

Browse files
authored
[FSSDK-12080] remove holdouts feature toggle (#1110)
1 parent 08928a5 commit b593f5b

File tree

8 files changed

+41
-97
lines changed

8 files changed

+41
-97
lines changed

lib/core/decision_service/index.spec.ts

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,30 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { describe, it, expect, vi, MockInstance, beforeEach, afterEach } from 'vitest';
16+
import { USER_PROFILE_LOOKUP_ERROR, USER_PROFILE_SAVE_ERROR } from 'error_message';
17+
import {
18+
SAVED_VARIATION_NOT_FOUND,
19+
USER_HAS_NO_FORCED_VARIATION
20+
} from 'log_message';
21+
import { beforeEach, describe, expect, it, MockInstance, vi } from 'vitest';
1722
import { CMAB_DUMMY_ENTITY_ID, CMAB_FETCH_FAILED, DecisionService } from '.';
18-
import { getMockLogger } from '../../tests/mock/mock_logger';
1923
import OptimizelyUserContext from '../../optimizely_user_context';
20-
import { bucket } from '../bucketer';
21-
import { getTestProjectConfig, getTestProjectConfigWithFeatures } from '../../tests/test_data';
2224
import { createProjectConfig, ProjectConfig } from '../../project_config/project_config';
2325
import { BucketerParams, Experiment, ExperimentBucketMap, Holdout, OptimizelyDecideOption, UserAttributes, UserProfile } from '../../shared_types';
24-
import { CONTROL_ATTRIBUTES, DECISION_SOURCES } from '../../utils/enums';
2526
import { getDecisionTestDatafile } from '../../tests/decision_test_datafile';
27+
import { getMockLogger } from '../../tests/mock/mock_logger';
28+
import { getTestProjectConfig, getTestProjectConfigWithFeatures } from '../../tests/test_data';
29+
import { CONTROL_ATTRIBUTES, DECISION_SOURCES } from '../../utils/enums';
2630
import { Value } from '../../utils/promise/operation_value';
27-
import {
28-
USER_HAS_NO_FORCED_VARIATION,
29-
VALID_BUCKETING_ID,
30-
SAVED_USER_VARIATION,
31-
SAVED_VARIATION_NOT_FOUND,
32-
} from 'log_message';
31+
import { bucket } from '../bucketer';
3332
import {
33+
AUDIENCE_EVALUATION_RESULT_COMBINED,
34+
EVALUATING_AUDIENCES_COMBINED,
3435
EXPERIMENT_NOT_RUNNING,
3536
RETURNING_STORED_VARIATION,
36-
USER_NOT_IN_EXPERIMENT,
3737
USER_FORCED_IN_VARIATION,
38-
EVALUATING_AUDIENCES_COMBINED,
39-
AUDIENCE_EVALUATION_RESULT_COMBINED,
40-
USER_IN_ROLLOUT,
41-
USER_NOT_IN_ROLLOUT,
42-
FEATURE_HAS_NO_EXPERIMENTS,
43-
USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE,
44-
USER_NOT_BUCKETED_INTO_TARGETING_RULE,
45-
USER_BUCKETED_INTO_TARGETING_RULE,
46-
NO_ROLLOUT_EXISTS,
47-
USER_MEETS_CONDITIONS_FOR_TARGETING_RULE,
38+
USER_NOT_IN_EXPERIMENT
4839
} from '../decision_service/index';
49-
import { BUCKETING_ID_NOT_STRING, USER_PROFILE_LOOKUP_ERROR, USER_PROFILE_SAVE_ERROR } from 'error_message';
5040

5141
type MockLogger = ReturnType<typeof getMockLogger>;
5242

@@ -114,14 +104,6 @@ vi.mock('../bucketer', () => ({
114104
bucket: mockBucket,
115105
}));
116106

117-
// Mock the feature toggle for holdout tests
118-
const mockHoldoutToggle = vi.hoisted(() => vi.fn());
119-
120-
vi.mock('../../feature_toggle', () => ({
121-
holdout: mockHoldoutToggle,
122-
}));
123-
124-
125107
const cloneDeep = (d: any) => JSON.parse(JSON.stringify(d));
126108

127109
const testData = getTestProjectConfig();
@@ -1956,7 +1938,6 @@ describe('DecisionService', () => {
19561938

19571939
describe('holdout', () => {
19581940
beforeEach(async() => {
1959-
mockHoldoutToggle.mockReturnValue(true);
19601941
const actualBucketModule = (await vi.importActual('../bucketer')) as { bucket: typeof bucket };
19611942
mockBucket.mockImplementation(actualBucketModule.bucket);
19621943
});

lib/core/decision_service/index.ts

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ import { OptimizelyError } from '../../error/optimizly_error';
7575
import { CmabService } from './cmab/cmab_service';
7676
import { Maybe, OpType, OpValue } from '../../utils/type';
7777
import { Value } from '../../utils/promise/operation_value';
78-
import * as featureToggle from '../../feature_toggle';
7978

8079
export const EXPERIMENT_NOT_RUNNING = 'Experiment %s is not running.';
8180
export const RETURNING_STORED_VARIATION =
@@ -940,19 +939,17 @@ export class DecisionService {
940939
reasons: decideReasons,
941940
});
942941
}
943-
if (featureToggle.holdout()) {
944-
const holdouts = getHoldoutsForFlag(configObj, feature.key);
945-
946-
for (const holdout of holdouts) {
947-
const holdoutDecision = this.getVariationForHoldout(configObj, holdout, user);
948-
decideReasons.push(...holdoutDecision.reasons);
949-
950-
if (holdoutDecision.result.variation) {
951-
return Value.of(op, {
952-
result: holdoutDecision.result,
953-
reasons: decideReasons,
954-
});
955-
}
942+
const holdouts = getHoldoutsForFlag(configObj, feature.key);
943+
944+
for (const holdout of holdouts) {
945+
const holdoutDecision = this.getVariationForHoldout(configObj, holdout, user);
946+
decideReasons.push(...holdoutDecision.reasons);
947+
948+
if (holdoutDecision.result.variation) {
949+
return Value.of(op, {
950+
result: holdoutDecision.result,
951+
reasons: decideReasons,
952+
});
956953
}
957954
}
958955

lib/feature_toggle.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* flag and all associated checks can be removed from the codebase.
3232
*/
3333

34-
export const holdout = () => false as const;
34+
// example feature flag definition
35+
// export const wipFeat = () => false as const;
3536

3637
export type IfActive<T extends () => boolean, Y, N = unknown> = ReturnType<T> extends true ? Y : N;

lib/notification_center/type.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
} from '../shared_types';
2727
import { DecisionSource } from '../utils/enums';
2828
import { Nullable } from '../utils/type';
29-
import { holdout, IfActive } from '../feature_toggle';
3029

3130
export type UserEventListenerPayload = {
3231
userId: string;
@@ -35,7 +34,7 @@ export type UserEventListenerPayload = {
3534

3635
export type ActivateListenerPayload = UserEventListenerPayload & {
3736
experiment: Experiment | null;
38-
holdout: IfActive<typeof holdout, Holdout | null>;
37+
holdout: Holdout | null;
3938
variation: Variation | null;
4039
logEvent: LogEvent;
4140
}

lib/optimizely/index.tests.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ import {
6767

6868
import { USER_BUCKETED_INTO_EXPERIMENT_IN_GROUP } from '../core/bucketer';
6969
import { resolvablePromise } from '../utils/promise/resolvablePromise';
70-
import { holdout } from '../feature_toggle';
7170

7271
var LOG_LEVEL = enums.LOG_LEVEL;
7372
var DECISION_SOURCES = enums.DECISION_SOURCES;

lib/project_config/project_config.spec.ts

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,28 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { describe, it, expect, beforeEach, afterEach, vi, assert, Mock, beforeAll, afterAll } from 'vitest';
17-
import { sprintf } from '../utils/fns';
18-
import { keyBy } from '../utils/fns';
19-
import projectConfig, { ProjectConfig, getHoldoutsForFlag } from './project_config';
20-
import { FEATURE_VARIABLE_TYPES, LOG_LEVEL } from '../utils/enums';
21-
import testDatafile from '../tests/test_data';
22-
import configValidator from '../utils/config_validator';
2316
import {
17+
FEATURE_NOT_IN_DATAFILE,
2418
INVALID_EXPERIMENT_ID,
2519
INVALID_EXPERIMENT_KEY,
20+
UNABLE_TO_CAST_VALUE,
2621
UNEXPECTED_RESERVED_ATTRIBUTE_PREFIX,
2722
UNRECOGNIZED_ATTRIBUTE,
2823
VARIABLE_KEY_NOT_IN_DATAFILE,
29-
FEATURE_NOT_IN_DATAFILE,
30-
UNABLE_TO_CAST_VALUE,
3124
} from 'error_message';
32-
import { getMockLogger } from '../tests/mock/mock_logger';
33-
import { VariableType } from '../shared_types';
25+
import { Mock, afterAll, afterEach, assert, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
3426
import { OptimizelyError } from '../error/optimizly_error';
35-
import { mock } from 'node:test';
27+
import { VariableType } from '../shared_types';
28+
import { getMockLogger } from '../tests/mock/mock_logger';
29+
import testDatafile from '../tests/test_data';
30+
import configValidator from '../utils/config_validator';
31+
import { FEATURE_VARIABLE_TYPES } from '../utils/enums';
32+
import { keyBy, sprintf } from '../utils/fns';
33+
import projectConfig, { ProjectConfig, getHoldoutsForFlag } from './project_config';
3634

37-
const buildLogMessageFromArgs = (args: any[]) => sprintf(args[1], ...args.splice(2));
3835
const cloneDeep = (obj: any) => JSON.parse(JSON.stringify(obj));
3936
const logger = getMockLogger();
4037

41-
const mockHoldoutToggle = vi.hoisted(() => vi.fn());
42-
43-
vi.mock('../feature_toggle', () => {
44-
return {
45-
holdout: mockHoldoutToggle,
46-
};
47-
});
4838

4939
describe('createProjectConfig', () => {
5040
let configObj: ProjectConfig;
@@ -383,20 +373,10 @@ const getHoldoutDatafile = () => {
383373
return datafile;
384374
}
385375

386-
describe('createProjectConfig - holdouts, feature toggle is on', () => {
387-
beforeAll(() => {
388-
mockHoldoutToggle.mockReturnValue(true);
389-
});
390-
391-
afterAll(() => {
392-
mockHoldoutToggle.mockReset();
393-
});
394-
376+
describe('createProjectConfig - holdouts', () => {
395377
it('should populate holdouts fields correctly', function() {
396378
const datafile = getHoldoutDatafile();
397379

398-
mockHoldoutToggle.mockReturnValue(true);
399-
400380
const configObj = projectConfig.createProjectConfig(JSON.parse(JSON.stringify(datafile)));
401381

402382
expect(configObj.holdouts).toHaveLength(3);
@@ -456,15 +436,7 @@ describe('createProjectConfig - holdouts, feature toggle is on', () => {
456436
});
457437
});
458438

459-
describe('getHoldoutsForFlag: feature toggle is on', () => {
460-
beforeAll(() => {
461-
mockHoldoutToggle.mockReturnValue(true);
462-
});
463-
464-
afterAll(() => {
465-
mockHoldoutToggle.mockReset();
466-
});
467-
439+
describe('getHoldoutsForFlag', () => {
468440
it('should return all applicable holdouts for a flag', () => {
469441
const datafile = getHoldoutDatafile();
470442
const configObj = projectConfig.createProjectConfig(JSON.parse(JSON.stringify(datafile)));

lib/project_config/project_config.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import {
5252
} from 'error_message';
5353
import { SKIPPING_JSON_VALIDATION, VALID_DATAFILE } from 'log_message';
5454
import { OptimizelyError } from '../error/optimizly_error';
55-
import * as featureToggle from '../feature_toggle';
5655

5756
interface TryCreatingProjectConfigConfig {
5857
// TODO[OASIS-6649]: Don't use object type
@@ -345,10 +344,6 @@ export const createProjectConfig = function(datafileObj?: JSON, datafileStr: str
345344
};
346345

347346
const parseHoldoutsConfig = (projectConfig: ProjectConfig): void => {
348-
if (!featureToggle.holdout()) {
349-
return;
350-
}
351-
352347
projectConfig.holdouts = projectConfig.holdouts || [];
353348
projectConfig.holdoutIdMap = keyBy(projectConfig.holdouts, 'id');
354349
projectConfig.globalHoldouts = [];

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@
6666
"test-umdbrowser": "npm run build-browser-umd && karma start karma.umd.conf.js --single-run",
6767
"test-karma-local": "karma start karma.local_chrome.bs.conf.js && npm run build-browser-umd && karma start karma.local_chrome.umd.conf.js",
6868
"prebuild": "npm run clean",
69-
"build": "npm run genmsg && rollup -c && cp dist/index.browser.d.ts dist/index.d.ts",
70-
"build:win": "npm run genmsg && rollup -c && type nul > dist/optimizely.lite.es.d.ts && type nul > dist/optimizely.lite.es.min.d.ts && type nul > dist/optimizely.lite.min.d.ts",
69+
"build": "tsc --noEmit && npm run genmsg && rollup -c && cp dist/index.browser.d.ts dist/index.d.ts",
70+
"build:win": "tsc --noEmit && npm run genmsg && rollup -c && type nul > dist/optimizely.lite.es.d.ts && type nul > dist/optimizely.lite.es.min.d.ts && type nul > dist/optimizely.lite.min.d.ts",
7171
"build-browser-umd": "rollup -c --config-umd",
7272
"coveralls": "nyc --reporter=lcov npm test",
7373
"prepare": "npm run build",

0 commit comments

Comments
 (0)