Skip to content

Commit df094ad

Browse files
[FSSDK-11238] Test conversions notification_center and utils (#1020)
1 parent aaf83d7 commit df094ad

File tree

12 files changed

+1243
-9
lines changed

12 files changed

+1243
-9
lines changed

lib/core/bucketer/bucket_value_generator.spec.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@ describe('generateBucketValue', () => {
3636
it('should return an error if it cannot generate the hash value', () => {
3737
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3838
// @ts-ignore
39-
expect(() => generateBucketValue(null)).toThrowError(
40-
new OptimizelyError(INVALID_BUCKETING_ID)
41-
);
39+
expect(() => generateBucketValue(null)).toThrow(OptimizelyError);
40+
try {
41+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
42+
// @ts-ignore
43+
generateBucketValue(null);
44+
} catch (err) {
45+
expect(err).toBeInstanceOf(OptimizelyError);
46+
expect(err.baseMessage).toBe(INVALID_BUCKETING_ID);
47+
}
4248
});
4349
});

lib/core/bucketer/index.spec.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,14 @@ describe('including groups: random', () => {
198198
const bucketerParamsWithInvalidGroupId = cloneDeep(bucketerParams);
199199
bucketerParamsWithInvalidGroupId.experimentIdMap[configObj.experiments[4].id].groupId = '6969';
200200

201-
expect(() => bucketer.bucket(bucketerParamsWithInvalidGroupId)).toThrowError(
202-
new OptimizelyError(INVALID_GROUP_ID, '6969')
203-
);
201+
expect(()=> bucketer.bucket(bucketerParamsWithInvalidGroupId)).toThrow(OptimizelyError);
202+
203+
try {
204+
bucketer.bucket(bucketerParamsWithInvalidGroupId);
205+
} catch(err) {
206+
expect(err).toBeInstanceOf(OptimizelyError);
207+
expect(err.baseMessage).toBe(INVALID_GROUP_ID);
208+
}
204209
});
205210
});
206211

lib/notification_center/index.spec.ts

+606
Large diffs are not rendered by default.

lib/project_config/project_config.spec.ts

-3
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,6 @@ describe('getLayerId', () => {
322322
});
323323

324324
it('should throw error for invalid experiment key in getLayerId', function() {
325-
// expect(() => projectConfig.getLayerId(configObj, 'invalidExperimentKey')).toThrowError(
326-
// sprintf(INVALID_EXPERIMENT_ID, 'PROJECT_CONFIG', 'invalidExperimentKey')
327-
// );
328325
expect(() => projectConfig.getLayerId(configObj, 'invalidExperimentKey')).toThrowError(
329326
expect.objectContaining({
330327
baseMessage: INVALID_EXPERIMENT_ID,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { describe, it, expect } from 'vitest';
18+
import * as attributesValidator from './';
19+
import { INVALID_ATTRIBUTES, UNDEFINED_ATTRIBUTE } from 'error_message';
20+
import { OptimizelyError } from '../../error/optimizly_error';
21+
22+
describe('validate', () => {
23+
it('should validate the given attributes if attributes is an object', () => {
24+
expect(attributesValidator.validate({ testAttribute: 'testValue' })).toBe(true);
25+
});
26+
27+
it('should throw an error if attributes is an array', () => {
28+
const attributesArray = ['notGonnaWork'];
29+
30+
expect(() => attributesValidator.validate(attributesArray)).toThrow(OptimizelyError);
31+
32+
try {
33+
attributesValidator.validate(attributesArray);
34+
} catch (err) {
35+
expect(err).toBeInstanceOf(OptimizelyError);
36+
expect(err.baseMessage).toBe(INVALID_ATTRIBUTES);
37+
}
38+
});
39+
40+
it('should throw an error if attributes is null', () => {
41+
expect(() => attributesValidator.validate(null)).toThrowError(OptimizelyError);
42+
43+
try {
44+
attributesValidator.validate(null);
45+
} catch (err) {
46+
expect(err).toBeInstanceOf(OptimizelyError);
47+
expect(err.baseMessage).toBe(INVALID_ATTRIBUTES);
48+
}
49+
});
50+
51+
it('should throw an error if attributes is a function', () => {
52+
function invalidInput() {
53+
console.log('This is an invalid input!');
54+
}
55+
56+
expect(() => attributesValidator.validate(invalidInput)).toThrowError(OptimizelyError);
57+
58+
try {
59+
attributesValidator.validate(invalidInput);
60+
} catch(err) {
61+
expect(err).toBeInstanceOf(OptimizelyError);
62+
expect(err.baseMessage).toBe(INVALID_ATTRIBUTES);
63+
}
64+
});
65+
66+
it('should throw an error if attributes contains a key with an undefined value', () => {
67+
const attributeKey = 'testAttribute';
68+
const attributes: Record<string, unknown> = {};
69+
attributes[attributeKey] = undefined;
70+
71+
expect(() => attributesValidator.validate(attributes)).toThrowError(OptimizelyError);
72+
73+
try {
74+
attributesValidator.validate(attributes);
75+
} catch(err) {
76+
expect(err).toBeInstanceOf(OptimizelyError);
77+
expect(err.baseMessage).toBe(UNDEFINED_ATTRIBUTE);
78+
expect(err.params).toEqual([attributeKey]);
79+
}
80+
});
81+
});
82+
83+
describe('isAttributeValid', () => {
84+
it('isAttributeValid returns true for valid values', () => {
85+
const userAttributes: Record<string, unknown> = {
86+
browser_type: 'Chrome',
87+
is_firefox: false,
88+
num_users: 10,
89+
pi_value: 3.14,
90+
'': 'javascript',
91+
};
92+
93+
Object.keys(userAttributes).forEach(key => {
94+
const value = userAttributes[key];
95+
96+
expect(attributesValidator.isAttributeValid(key, value)).toBe(true);
97+
});
98+
});
99+
it('isAttributeValid returns false for invalid values', () => {
100+
const userAttributes: Record<string, unknown> = {
101+
null: null,
102+
objects: { a: 'b' },
103+
array: [1, 2, 3],
104+
infinity: Infinity,
105+
negativeInfinity: -Infinity,
106+
NaN: NaN,
107+
};
108+
109+
Object.keys(userAttributes).forEach(key => {
110+
const value = userAttributes[key];
111+
112+
expect(attributesValidator.isAttributeValid(key, value)).toBe(false);
113+
});
114+
});
115+
});
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { describe, it, expect } from 'vitest';
18+
import configValidator from './';
19+
import testData from '../../tests/test_data';
20+
import { INVALID_DATAFILE_MALFORMED, INVALID_DATAFILE_VERSION, NO_DATAFILE_SPECIFIED } from 'error_message';
21+
import { OptimizelyError } from '../../error/optimizly_error';
22+
23+
describe('validate', () => {
24+
it('should complain if datafile is not provided', () => {
25+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
26+
// @ts-ignore
27+
expect(() => configValidator.validateDatafile()).toThrow(OptimizelyError);
28+
29+
try {
30+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
31+
// @ts-ignore
32+
configValidator.validateDatafile();
33+
} catch (err) {
34+
expect(err).toBeInstanceOf(OptimizelyError);
35+
expect(err.baseMessage).toBe(NO_DATAFILE_SPECIFIED);
36+
}
37+
});
38+
39+
it('should complain if datafile is malformed', () => {
40+
expect(() => configValidator.validateDatafile('abc')).toThrow( OptimizelyError);
41+
42+
try {
43+
configValidator.validateDatafile('abc');
44+
} catch(err) {
45+
expect(err).toBeInstanceOf(OptimizelyError);
46+
expect(err.baseMessage).toBe(INVALID_DATAFILE_MALFORMED);
47+
}
48+
});
49+
50+
it('should complain if datafile version is not supported', () => {
51+
expect(() => configValidator.validateDatafile(JSON.stringify(testData.getUnsupportedVersionConfig())).toThrow(OptimizelyError));
52+
53+
try {
54+
configValidator.validateDatafile(JSON.stringify(testData.getUnsupportedVersionConfig()));
55+
} catch(err) {
56+
expect(err).toBeInstanceOf(OptimizelyError);
57+
expect(err.baseMessage).toBe(INVALID_DATAFILE_VERSION);
58+
expect(err.params).toEqual(['5']);
59+
}
60+
});
61+
62+
it('should not complain if datafile is valid', () => {
63+
expect(() => configValidator.validateDatafile(JSON.stringify(testData.getTestProjectConfig())).not.toThrowError());
64+
});
65+
});
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { describe, it, expect, beforeEach } from 'vitest';
17+
import * as eventTagUtils from './';
18+
import {
19+
FAILED_TO_PARSE_REVENUE,
20+
PARSED_REVENUE_VALUE,
21+
PARSED_NUMERIC_VALUE,
22+
FAILED_TO_PARSE_VALUE,
23+
} from 'log_message';
24+
import { getMockLogger } from '../../tests/mock/mock_logger';
25+
import { LoggerFacade } from '../../logging/logger';
26+
27+
describe('getRevenueValue', () => {
28+
let logger: LoggerFacade;
29+
30+
beforeEach(() => {
31+
logger = getMockLogger();
32+
});
33+
34+
it('should return the parseed integer for a valid revenue value', () => {
35+
let parsedRevenueValue = eventTagUtils.getRevenueValue({ revenue: '1337' }, logger);
36+
37+
expect(parsedRevenueValue).toBe(1337);
38+
expect(logger.info).toHaveBeenCalledWith(PARSED_REVENUE_VALUE, 1337);
39+
40+
parsedRevenueValue = eventTagUtils.getRevenueValue({ revenue: '13.37' }, logger);
41+
42+
expect(parsedRevenueValue).toBe(13);
43+
});
44+
45+
it('should return null and log a message for invalid value', () => {
46+
const parsedRevenueValue = eventTagUtils.getRevenueValue({ revenue: 'invalid' }, logger);
47+
48+
expect(parsedRevenueValue).toBe(null);
49+
expect(logger.info).toHaveBeenCalledWith(FAILED_TO_PARSE_REVENUE, 'invalid');
50+
});
51+
52+
it('should return null if the revenue value is not present in the event tags', () => {
53+
const parsedRevenueValue = eventTagUtils.getRevenueValue({ not_revenue: '1337' }, logger);
54+
55+
expect(parsedRevenueValue).toBe(null);
56+
});
57+
});
58+
59+
describe('getEventValue', () => {
60+
let logger: LoggerFacade;
61+
62+
beforeEach(() => {
63+
logger = getMockLogger();
64+
});
65+
66+
it('should return the parsed integer for a valid numeric value', () => {
67+
let parsedEventValue = eventTagUtils.getEventValue({ value: '1337' }, logger);
68+
69+
expect(parsedEventValue).toBe(1337);
70+
expect(logger.info).toHaveBeenCalledWith(PARSED_NUMERIC_VALUE, 1337);
71+
72+
parsedEventValue = eventTagUtils.getEventValue({ value: '13.37' }, logger);
73+
expect(parsedEventValue).toBe(13.37);
74+
});
75+
76+
it('should return null and log a message for invalid value', () => {
77+
const parsedNumericValue = eventTagUtils.getEventValue({ value: 'invalid' }, logger);
78+
79+
expect(parsedNumericValue).toBe(null);
80+
expect(logger.info).toHaveBeenCalledWith(FAILED_TO_PARSE_VALUE, 'invalid');
81+
});
82+
83+
it('should return null if the value is not present in the event tags', () => {
84+
const parsedNumericValue = eventTagUtils.getEventValue({ not_value: '13.37' }, logger);
85+
86+
expect(parsedNumericValue).toBe(null);
87+
});
88+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { describe, it, expect, beforeEach } from 'vitest';
17+
import { validate } from '.';
18+
import { OptimizelyError } from '../../error/optimizly_error';
19+
import { INVALID_EVENT_TAGS } from 'error_message';
20+
21+
describe('validate', () => {
22+
it('should validate the given event tags if event tag is an object', () => {
23+
expect(validate({ testAttribute: 'testValue' })).toBe(true);
24+
});
25+
26+
it('should throw an error if event tags is an array', () => {
27+
const eventTagsArray = ['notGonnaWork'];
28+
29+
expect(() => validate(eventTagsArray)).toThrow(OptimizelyError)
30+
31+
try {
32+
validate(eventTagsArray);
33+
} catch(err) {
34+
expect(err).toBeInstanceOf(OptimizelyError);
35+
expect(err.baseMessage).toBe(INVALID_EVENT_TAGS);
36+
}
37+
});
38+
39+
it('should throw an error if event tags is null', () => {
40+
expect(() => validate(null)).toThrow(OptimizelyError);
41+
42+
try {
43+
validate(null);
44+
} catch(err) {
45+
expect(err).toBeInstanceOf(OptimizelyError);
46+
expect(err.baseMessage).toBe(INVALID_EVENT_TAGS);
47+
}
48+
});
49+
50+
it('should throw an error if event tags is a function', () => {
51+
function invalidInput() {
52+
console.log('This is an invalid input!');
53+
}
54+
expect(() => validate(invalidInput)).toThrow(OptimizelyError);
55+
56+
try {
57+
validate(invalidInput);
58+
} catch(err) {
59+
expect(err).toBeInstanceOf(OptimizelyError);
60+
expect(err.baseMessage).toBe(INVALID_EVENT_TAGS);
61+
}
62+
});
63+
});

0 commit comments

Comments
 (0)