Skip to content

Commit 451255a

Browse files
Update JS-commons and add E2E tests for Semver matchers
1 parent 282b560 commit 451255a

File tree

7 files changed

+736
-8
lines changed

7 files changed

+736
-8
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"node": ">=6"
4141
},
4242
"dependencies": {
43-
"@splitsoftware/splitio-commons": "1.13.1",
43+
"@splitsoftware/splitio-commons": "1.13.2-rc.3",
4444
"@types/google.analytics": "0.0.40",
4545
"@types/ioredis": "^4.28.0",
4646
"bloom-filters": "^3.0.0",
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import sinon from 'sinon';
2+
import splitChangesMock1 from '../mocks/splitchanges.since.-1.semver.json';
3+
4+
import { SplitFactory } from '../../';
5+
6+
const listener = {
7+
logImpression: sinon.stub()
8+
};
9+
10+
const config = {
11+
core: {
12+
authorizationKey: '<fake-token>',
13+
key: 'emi@split.io'
14+
},
15+
urls: {
16+
sdk: 'https://sdk.evaluation-semver/api',
17+
events: 'https://events.evaluation-semver/api'
18+
},
19+
sync: {
20+
impressionsMode: 'DEBUG'
21+
},
22+
impressionListener: listener,
23+
streamingEnabled: false
24+
};
25+
26+
export default async function (fetchMock, assert) {
27+
28+
fetchMock.getOnce(config.urls.sdk + '/splitChanges?since=-1', { status: 200, body: splitChangesMock1 });
29+
fetchMock.getOnce(config.urls.sdk + '/splitChanges?since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } });
30+
fetchMock.getOnce(config.urls.sdk + '/mySegments/emi%40split.io', { status: 200, body: { mySegments: [] } });
31+
fetchMock.getOnce(config.urls.sdk + '/mySegments/2nd', { status: 200, body: { mySegments: [] } });
32+
33+
const splitio = SplitFactory(config);
34+
const client = splitio.client();
35+
36+
await client.ready();
37+
38+
// EQUAL_TO_SEMVER matcher
39+
assert.equal(client.getTreatment('semver_equalto', { 'version': '1.22.9' }), 'on', 'the rule will return `on` if attribute `version` is equal to `1.22.9`');
40+
assert.equal(client.getTreatment('semver_equalto', { 'version': '1.22.9+build' }), 'off', 'build metadata is not ignored');
41+
assert.equal(client.getTreatment('semver_equalto', { 'version': '1.22.9-rc.0' }), 'off', 'the rule will return `off` if attribute `version` is not equal to `1.22.9`');
42+
43+
// IN_LIST_SEMVER matcher
44+
assert.equal(client.getTreatment('semver_inlist', { 'version': '2.1.0' }), 'on', 'the rule will return `on` if attribute `version` is in list (`1.22.9`, `2.1.0`)');
45+
assert.equal(client.getTreatment('semver_inlist', { 'version': '1.22.9' }), 'on', 'the rule will return `on` if attribute `version` is in list (`1.22.9`, `2.1.0`)');
46+
assert.equal(client.getTreatment('semver_inlist', { 'version': '1.22.9+build' }), 'off', 'build metadata is not ignored');
47+
assert.equal(client.getTreatment('semver_inlist', { 'version': '1.22.9-rc.0' }), 'off', 'the rule will return `off` if attribute `version` is not in list (`1.22.9`, `2.1.0`)');
48+
49+
// GREATER_THAN_OR_EQUAL_TO_SEMVER matcher
50+
assert.equal(client.getTreatments(['semver_greater_or_equalto'], { 'version': '1.23.9' }).semver_greater_or_equalto, 'on', 'the rule will return `on` if attribute `version` is greater than or equal to `1.22.9`');
51+
assert.equal(client.getTreatments(['semver_greater_or_equalto'], { 'version': '1.22.9' }).semver_greater_or_equalto, 'on', 'the rule will return `on` if attribute `version` is greater than or equal to `1.22.9`');
52+
assert.equal(client.getTreatments(['semver_greater_or_equalto'], { 'version': '1.22.9+build' }).semver_greater_or_equalto, 'on', 'build metadata is ignored');
53+
assert.equal(client.getTreatments(['semver_greater_or_equalto'], { 'version': '1.22.9-rc.0' }).semver_greater_or_equalto, 'off', 'the rule will return `off` if attribute `version` is not greater than or equal to `1.22.9`');
54+
assert.equal(client.getTreatments(['semver_greater_or_equalto'], { 'version': '1.21.9' }).semver_greater_or_equalto, 'off', 'the rule will return `off` if attribute `version` is not greater than or equal to `1.22.9`');
55+
56+
// LESS_THAN_OR_EQUAL_TO_SEMVER matcher
57+
assert.deepEqual(client.getTreatmentWithConfig('semver_less_or_equalto', { 'version': '1.22.11' }), { treatment: 'off', config: null }, 'the rule will return `off` if attribute `version` is not less than or equal to `1.22.9`');
58+
assert.deepEqual(client.getTreatmentWithConfig('semver_less_or_equalto', { 'version': '1.22.9' }), { treatment: 'on', config: null }, 'the rule will return `on` if attribute `version` is less than or equal to `1.22.9`');
59+
assert.deepEqual(client.getTreatmentWithConfig('semver_less_or_equalto', { 'version': '1.22.9+build' }), { treatment: 'on', config: null }, 'build metadata is ignored');
60+
assert.deepEqual(client.getTreatmentWithConfig('semver_less_or_equalto', { 'version': '1.22.9-rc.0' }), { treatment: 'on', config: null }, 'the rule will return `on` if attribute `version` is less than or equal to `1.22.9`');
61+
assert.deepEqual(client.getTreatmentWithConfig('semver_less_or_equalto', { 'version': '1.21.9' }), { treatment: 'on', config: null }, 'the rule will return `on` if attribute `version` is less than or equal to `1.22.9`');
62+
63+
const client2 = splitio.client('2nd');
64+
await client2.ready();
65+
66+
// BETWEEN_SEMVER matcher
67+
assert.deepEqual(client2.getTreatmentsWithConfig(['semver_between'], { 'version': '2.1.1' }).semver_between, { treatment: 'off', config: null }, 'the rule will return `off` if attribute `version` is not between `1.22.9` and `2.1.0`');
68+
assert.deepEqual(client2.getTreatmentsWithConfig(['semver_between'], { 'version': '2.1.0+build' }).semver_between, { treatment: 'on', config: null }, 'build metadata is ignored');
69+
assert.deepEqual(client2.getTreatmentsWithConfig(['semver_between'], { 'version': '1.25.0' }).semver_between, { treatment: 'on', config: null }, 'the rule will return `on` if attribute `version` is between `1.22.9` and `2.1.0`');
70+
assert.deepEqual(client2.getTreatmentsWithConfig(['semver_between'], { 'version': '1.22.9' }).semver_between, { treatment: 'on', config: null }, 'the rule will return `on` if attribute `version` is between `1.22.9` and `2.1.0`');
71+
assert.deepEqual(client2.getTreatmentsWithConfig(['semver_between'], { 'version': '1.22.9-rc.0' }).semver_between, { treatment: 'off', config: null }, 'the rule will return `off` if attribute `version` is not between `1.22.9` and `2.1.0`');
72+
73+
// Evaluation of a flag with unsupported matcher
74+
assert.equal(client2.getTreatment('flag_with_unsupported_matcher'), 'control', 'evaluation of a flag with an unsupported matcher should return control');
75+
76+
let POSTED_IMPRESSIONS_COUNT;
77+
78+
fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', (_, opts) => {
79+
80+
const payload = JSON.parse(opts.body);
81+
82+
function validateImpressionData(featureFlagName, expectedImpressionCount, expectedOnCount, expectedLabel, expectedTreatment = 'on') {
83+
const impressions = payload.find(e => e.f === featureFlagName).i;
84+
85+
assert.equal(impressions.length, expectedImpressionCount, `We should have ${expectedImpressionCount} impressions for the feature flag ${featureFlagName}`);
86+
assert.equal(impressions.filter((imp) => imp.r === expectedLabel && imp.t === expectedTreatment).length, expectedOnCount, `${expectedOnCount} impression with 'on' treatment and label ${expectedLabel}`);
87+
}
88+
89+
validateImpressionData('semver_equalto', 3, 1, 'equal to semver');
90+
validateImpressionData('semver_inlist', 4, 2, 'in list semver');
91+
validateImpressionData('semver_greater_or_equalto', 5, 3, 'greater than or equal to semver');
92+
validateImpressionData('semver_less_or_equalto', 5, 4, 'less than or equal to semver');
93+
validateImpressionData('semver_between', 5, 3, 'between semver');
94+
validateImpressionData('flag_with_unsupported_matcher', 1, 1, 'unsupported matcher type', 'control');
95+
96+
POSTED_IMPRESSIONS_COUNT = payload.reduce((acc, curr) => acc + curr.i.length, 0);
97+
98+
return 200;
99+
});
100+
101+
await Promise.all([client.destroy(), client2.destroy()]);
102+
103+
setTimeout(() => {
104+
assert.equal(listener.logImpression.callCount, POSTED_IMPRESSIONS_COUNT, 'Impression listener should be called once per each impression generated.');
105+
106+
assert.end();
107+
}, 0);
108+
}

0 commit comments

Comments
 (0)