Skip to content

Commit 303a7ec

Browse files
E2E tests for standalone mode
1 parent 768a2ea commit 303a7ec

File tree

6 files changed

+76
-53
lines changed

6 files changed

+76
-53
lines changed

src/__tests__/browserSuites/impressions-listener.spec.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default function (assert) {
4646
const testAttrs = { is_test: true };
4747

4848
// Impression listener is shared across all client instances and does not get affected by configurations.
49-
client.getTreatment('hierarchical_splits_test');
49+
client.getTreatment('hierarchical_splits_test', undefined, { properties: { prop1: 'prop-value' } });
5050
client2.getTreatment('qc_team');
5151
client2.getTreatmentWithConfig('qc_team'); // Validate that the impression is the same.
5252
client3.getTreatment('qc_team', testAttrs);
@@ -58,7 +58,8 @@ export default function (assert) {
5858
treatment: 'no',
5959
bucketingKey: 'impr_bucketing_2',
6060
label: 'default rule',
61-
pt: undefined
61+
pt: undefined,
62+
properties: undefined
6263
};
6364

6465
assert.equal(listener.logImpression.callCount, 4, 'Impression listener logImpression method should be called after we call client.getTreatment, once per each impression generated.');
@@ -71,7 +72,7 @@ export default function (assert) {
7172
bucketingKey: undefined,
7273
label: 'expected label',
7374
changeNumber: 2828282828,
74-
pt: undefined
75+
properties: '{"prop1":"prop-value"}'
7576
},
7677
attributes: undefined,
7778
...metaData

src/__tests__/browserSuites/impressions.debug.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ export default function (fetchMock, assert) {
6363
k: 'facundo@split.io', t: 'o.n', m: data[0].i[1].m, c: 828282828282, r: 'another expected label', pt: data[0].i[0].m,
6464
}, {
6565
k: 'facundo@split.io', t: 'o.n', m: data[0].i[2].m, c: 828282828282, r: 'another expected label', pt: data[0].i[1].m
66+
}, {
67+
k: 'facundo@split.io', t: 'o.n', m: data[0].i[3].m, c: 828282828282, r: 'another expected label', pt: data[0].i[2].m, properties: '{"prop1":"value1"}'
68+
}, {
69+
k: 'facundo@split.io', t: 'o.n', m: data[0].i[4].m, c: 828282828282, r: 'another expected label', pt: data[0].i[3].m, properties: '{"prop1":"value2"}'
70+
}, {
71+
k: 'facundo@split.io', t: 'o.n', m: data[0].i[5].m, c: 828282828282, r: 'another expected label', pt: data[0].i[4].m, properties: '{"prop1":"value3"}'
72+
}, {
73+
k: 'facundo@split.io', t: 'o.n', m: data[0].i[6].m, c: 828282828282, r: 'another expected label', pt: data[0].i[5].m, properties: '{"prop1":"value4"}'
6674
}]
6775
}]);
6876

@@ -96,5 +104,11 @@ export default function (fetchMock, assert) {
96104
client.getTreatment('split_with_config');
97105
client.getTreatment('split_with_config');
98106
assert.equal(client.getTreatment('always_on_impressions_disabled_true'), 'on');
107+
108+
// with properties
109+
assert.equal(client.getTreatment('split_with_config', undefined, { properties: { prop1: 'value1' } }), 'o.n');
110+
assert.equal(client.getTreatments(['split_with_config'], undefined, { properties: { prop1: 'value2' } }).split_with_config, 'o.n');
111+
assert.equal(client.getTreatmentWithConfig('split_with_config', undefined, { properties: { prop1: 'value3' } }).treatment, 'o.n');
112+
assert.equal(client.getTreatmentsWithConfig(['split_with_config'], undefined, { properties: { prop1: 'value4' } }).split_with_config.treatment, 'o.n');
99113
});
100114
}

src/__tests__/browserSuites/impressions.spec.js

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -47,32 +47,21 @@ export default function (fetchMock, assert) {
4747

4848
const client = splitio.client();
4949
const assertPayload = req => {
50-
const resp = JSON.parse(req.body);
51-
52-
assert.equal(resp.length, 2, 'We performed evaluations for 3 features, but one with `impressionsDisabled` true, so we should have 2 items total');
53-
54-
const dependencyChildImpr = resp.filter(e => e.f === 'hierarchical_splits_test')[0];
55-
const splitWithConfigImpr = resp.filter(e => e.f === 'split_with_config')[0];
56-
const alwaysOnWithImpressionsDisabledTrue = resp.filter(e => e.f === 'always_on_impressions_disabled_true');
57-
58-
assert.true(dependencyChildImpr, 'Split we wanted to evaluate should be present on the impressions.');
59-
assert.false(resp.some(e => e.f === 'hierarchical_dep_always_on'), 'Parent split evaluations should not result in impressions.');
60-
assert.false(resp.some(e => e.f === 'hierarchical_dep_hierarchical'), 'No matter how deep is the chain.');
61-
assert.true(splitWithConfigImpr, 'Split evaluated with config should have generated an impression too.');
62-
assert.false(Object.prototype.hasOwnProperty.call(splitWithConfigImpr.i[0], 'configuration'), 'Impressions do not change with configuration evaluations.');
63-
assert.false(Object.prototype.hasOwnProperty.call(splitWithConfigImpr.i[0], 'config'), 'Impressions do not change with configuration evaluations.');
64-
assert.equal(alwaysOnWithImpressionsDisabledTrue.length, 0);
65-
66-
const {
67-
k,
68-
r,
69-
t
70-
} = dependencyChildImpr.i[0];
71-
72-
assert.equal(k, 'facundo@split.io', 'Present impression should have the correct key.');
73-
// The label present on the mock.
74-
assert.equal(r, 'expected label', 'Present impression should have the correct label.');
75-
assert.equal(t, 'on', 'Present impression should have the correct treatment.');
50+
const reqBody = JSON.parse(req.body);
51+
52+
assert.deepEqual(reqBody, [{
53+
f: 'hierarchical_splits_test',
54+
i: [{
55+
k: 'facundo@split.io', t: 'on', m: reqBody[0].i[0].m, c: 2828282828, r: 'expected label'
56+
}]
57+
}, {
58+
f: 'split_with_config',
59+
i: [{
60+
k: 'facundo@split.io', t: 'o.n', m: reqBody[1].i[0].m, c: 828282828282, r: 'another expected label'
61+
}, {
62+
k: 'facundo@split.io', t: 'o.n', m: reqBody[1].i[1].m, c: 828282828282, r: 'another expected label', properties: '{"some":"value2"}'
63+
}]
64+
}], 'We performed evaluations for 3 features, but one with `impressionsDisabled` true, so we should have 2 items total');
7665
};
7766

7867
fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, req) => {
@@ -93,28 +82,23 @@ export default function (fetchMock, assert) {
9382
return 200;
9483
});
9584

96-
fetchMock.postOnce(url(settings, '/testImpressions/count'), (url, opts) => {
97-
const data = JSON.parse(opts.body);
85+
fetchMock.postOnce(url(settings, '/testImpressions/count'), (url, req) => {
86+
const reqBody = JSON.parse(req.body);
9887

99-
assert.equal(data.pf.length, 2, 'We should generate impressions count for 2 features.');
100-
101-
// finding these validate the feature names collection too
102-
const splitWithConfigImpr = data.pf.filter(e => e.f === 'split_with_config')[0];
103-
const alwaysOnWithImpressionsDisabledTrue = data.pf.filter(e => e.f === 'always_on_impressions_disabled_true')[0];
104-
105-
assert.equal(splitWithConfigImpr.rc, 2);
106-
assert.equal(typeof splitWithConfigImpr.m, 'number');
107-
assert.equal(splitWithConfigImpr.m, truncatedTimeFrame);
108-
assert.equal(alwaysOnWithImpressionsDisabledTrue.rc, 1);
109-
assert.equal(typeof alwaysOnWithImpressionsDisabledTrue.m, 'number');
110-
assert.equal(alwaysOnWithImpressionsDisabledTrue.m, truncatedTimeFrame);
88+
assert.deepEqual(reqBody, {
89+
pf: [{
90+
f: 'split_with_config', m: truncatedTimeFrame, rc: 2
91+
}, {
92+
f: 'always_on_impressions_disabled_true', m: truncatedTimeFrame, rc: 1
93+
}]
94+
}, 'We should generate impressions count for 2 features.');
11195

11296
return 200;
11397
});
11498

11599
fetchMock.postOnce(url(settings, '/v1/keys/cs'), (url, opts) => {
116100
assert.deepEqual(JSON.parse(opts.body), {
117-
keys: [{ fs: [ 'always_on_impressions_disabled_true' ], k: 'facundo@split.io' }]
101+
keys: [{ fs: ['always_on_impressions_disabled_true'], k: 'facundo@split.io' }]
118102
}, 'We should only track unique keys for features flags with track impressions disabled.');
119103

120104
return 200;
@@ -129,9 +113,12 @@ export default function (fetchMock, assert) {
129113
config: '{"color":"brown","dimensions":{"height":12,"width":14},"text":{"inner":"click me"}}'
130114
}, 'We should get an evaluation as always.');
131115
client.getTreatmentWithConfig('split_with_config');
132-
client.getTreatmentWithConfig('split_with_config');
116+
client.getTreatmentWithConfig('split_with_config', undefined, { properties: { /* empty properties are ignored */ } });
117+
118+
// Impression should not be tracked (passed properties will not be submitted)
119+
assert.equal(client.getTreatment('always_on_impressions_disabled_true'), 'on', undefined, { properties: { some: 'value1' } });
133120

134-
// Impression should not be tracked
135-
assert.equal(client.getTreatment('always_on_impressions_disabled_true'), 'on');
121+
// Tracked impression with properties should be handled in DEBUG mode (doesn't increase `rc` count but adds an impression)
122+
assert.equal(client.getTreatment('split_with_config', undefined, { properties: { some: 'value2' } }), 'o.n');
136123
});
137124
}

src/__tests__/nodeSuites/impressions-listener.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ export default function (assert) {
3939
const testAttrs = { is_test: true };
4040

4141
// Generate one impression, depends on hierarchical_dep_hierarchical which depends on hierarchical_dep_always_on
42-
client.getTreatment('nicolas@split.io', 'hierarchical_splits_test');
42+
client.getTreatment('nicolas@split.io', 'hierarchical_splits_test', undefined, { properties: { prop1: 'prop-value' } });
4343
client.getTreatment({ matchingKey: 'marcio@split.io', bucketingKey: 'impr_bucketing_2' }, 'qc_team');
4444
client.getTreatment('facundo@split.io', 'qc_team', testAttrs);
4545
client.getTreatment('facundo@split.io', 'qc_team', testAttrs);
4646

4747
setTimeout(() => {
48-
assert.true(listener.logImpression.callCount, 4, 'Impression listener logImpression method should be called after we call client.getTreatment, once per each impression generated.');
48+
assert.equal(listener.logImpression.callCount, 4, 'Impression listener logImpression method should be called after we call client.getTreatment, once per each impression generated.');
4949
assert.true(listener.logImpression.getCall(0).calledWithExactly({
5050
impression: {
5151
feature: 'hierarchical_splits_test',
@@ -55,7 +55,7 @@ export default function (assert) {
5555
bucketingKey: undefined,
5656
label: 'expected label',
5757
changeNumber: 2828282828,
58-
pt: undefined
58+
properties: '{"prop1":"prop-value"}'
5959
},
6060
attributes: undefined,
6161
...metaData

src/__tests__/nodeSuites/impressions.debug.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ export default async function (key, fetchMock, assert) {
6363
k: 'facundo@split.io', t: 'o.n', m: data[0].i[1].m, c: 828282828282, r: 'another expected label', b: 'test_buck_key', pt: data[0].i[0].m
6464
}, {
6565
k: 'facundo@split.io', t: 'o.n', m: data[0].i[2].m, c: 828282828282, r: 'another expected label', b: 'test_buck_key', pt: data[0].i[1].m
66+
}, {
67+
k: 'emi@split.io', t: 'o.n', m: data[0].i[3].m, c: 828282828282, r: 'another expected label', properties: '{"prop1":"value1"}'
68+
}, {
69+
k: 'emi@split.io', t: 'o.n', m: data[0].i[4].m, c: 828282828282, r: 'another expected label', pt: data[0].i[3].m, properties: '{"prop1":"value2"}'
70+
}, {
71+
k: 'emi@split.io', t: 'o.n', m: data[0].i[5].m, c: 828282828282, r: 'another expected label', pt: data[0].i[4].m, properties: '{"prop1":"value3"}'
72+
}, {
73+
k: 'emi@split.io', t: 'o.n', m: data[0].i[6].m, c: 828282828282, r: 'another expected label', pt: data[0].i[5].m, properties: '{"prop1":"value4"}'
6674
}]
6775
}], 'We performed evaluations for one split, so we should have 1 item total.');
6876

@@ -98,4 +106,9 @@ export default async function (key, fetchMock, assert) {
98106
assert.equal(client.getTreatment({ matchingKey: key, bucketingKey: 'test_buck_key' }, 'split_with_config'), 'o.n');
99107
assert.equal(client.getTreatment({ matchingKey: key, bucketingKey: 'test_buck_key' }, 'split_with_config'), 'o.n');
100108
assert.equal(client.getTreatment({ matchingKey: 'other_key', bucketingKey: 'test_buck_key' }, 'always_on_impressions_disabled_true'), 'on');
109+
110+
assert.equal(client.getTreatment('emi@split.io', 'split_with_config', undefined, { properties: { prop1: 'value1' } }), 'o.n');
111+
assert.equal(client.getTreatments('emi@split.io', ['split_with_config'], undefined, { properties: { prop1: 'value2' } }).split_with_config, 'o.n');
112+
assert.equal(client.getTreatmentWithConfig('emi@split.io', 'split_with_config', undefined, { properties: { prop1: 'value3' } }).treatment, 'o.n');
113+
assert.equal(client.getTreatmentsWithConfig('emi@split.io', ['split_with_config'], undefined, { properties: { prop1: 'value4' } }).split_with_config.treatment, 'o.n');
101114
}

src/__tests__/nodeSuites/impressions.spec.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default async function (key, fetchMock, assert) {
5858
const alwaysOnWithImpressionsDisabledTrue = data.filter(e => e.f === 'always_on_impressions_disabled_true');
5959

6060
assert.equal(notExistentSplitImpr.i.length, 1); // Only one, the split not found is filtered by the non existent Split check.
61-
assert.equal(splitWithConfigImpr.i.length, 2);
61+
assert.equal(splitWithConfigImpr.i.length, 3);
6262
assert.equal(dependencyChildImpr.i.length, 1);
6363
assert.equal(alwaysOnWithImpressionsDisabledTrue.length, 0);
6464

@@ -75,6 +75,7 @@ export default async function (key, fetchMock, assert) {
7575
assert.equal(output.t, expected.treatment, 'Present impressions should have the correct treatment.');
7676
assert.equal(output.r, expected.label, 'Present impressions should have the correct label.');
7777
assert.equal(output.c, expected.changeNumber, 'Present impressions should have the correct changeNumber.');
78+
assert.equal(output.properties, expected.properties, 'Present impressions should have the correct properties.');
7879
assert.true(output.m >= (performedWhenReady ? readyEvaluationsStart : evaluationsStart) && output.m <= evaluationsEnd, 'Present impressions should have the correct timestamp (test with error margin).');
7980
}
8081

@@ -90,6 +91,10 @@ export default async function (key, fetchMock, assert) {
9091
keyName: 'facundo@split.io', label: 'another expected label', treatment: 'o.n',
9192
bucketingKey: 'test_buck_key', changeNumber: 828282828282
9293
});
94+
validateImpressionData(splitWithConfigImpr.i[2], {
95+
keyName: 'other_key', label: 'another expected label', treatment: 'o.n',
96+
changeNumber: 828282828282, properties: '{"some":"value2"}'
97+
});
9398

9499
// Not push impressions with a invalid key (aka matching key)
95100
assert.true(
@@ -153,8 +158,11 @@ export default async function (key, fetchMock, assert) {
153158
client.getTreatmentWithConfig({ matchingKey: key, bucketingKey: 'test_buck_key' }, 'split_with_config');
154159
client.getTreatmentWithConfig({ matchingKey: 'different', bucketingKey: 'test_buck_key' }, 'split_with_config');
155160

156-
// Impression should not be tracked
157-
assert.equal(client.getTreatment('other_key', 'always_on_impressions_disabled_true'), 'on');
161+
// Impression should not be tracked (passed properties will not be submitted)
162+
assert.equal(client.getTreatment('other_key', 'always_on_impressions_disabled_true'), 'on', undefined, { properties: { some: 'value1' } });
163+
164+
// Tracked impression with properties should be handled in DEBUG mode
165+
assert.equal(client.getTreatment('other_key', 'split_with_config', undefined, { properties: { some: 'value2' } }), 'o.n');
158166

159167
evaluationsEnd = Date.now();
160168
}

0 commit comments

Comments
 (0)