Skip to content

Commit b6f928f

Browse files
Merge pull request #88 from splitio/refactor_e2e_tests
Refactor E2E tests to use fetch-mock for flexibility
2 parents 99b4a2e + bfd8f85 commit b6f928f

22 files changed

+1574
-4880
lines changed

.eslintrc

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"plugins": [
77
"@typescript-eslint",
88
"import",
9-
"eslint-plugin-jsdoc"
9+
"eslint-plugin-tsdoc"
1010
],
1111
"env": {
1212
"browser": false,
@@ -35,6 +35,13 @@
3535
"no-use-before-define": "off",
3636
"no-undef": "off" // turned off to avoid issue with triple-slash path directive
3737
}
38+
},
39+
{
40+
// Enable TSDoc rules for TypeScript files, allowing the use of JSDoc in JS files.
41+
"files": ["**/*.ts"],
42+
"rules": {
43+
"tsdoc/syntax": "warn"
44+
}
3845
}
3946
],
4047
"rules": {
@@ -75,49 +82,6 @@
7582
"quote-props": ["error", "as-needed"],
7683
"comma-spacing": ["error", { "before": false, "after": true }],
7784
"object-curly-spacing": ["error", "always"],
78-
"no-trailing-spaces": "error",
79-
// jsdoc
80-
"jsdoc/check-access": "error",
81-
"jsdoc/check-alignment": "error",
82-
"jsdoc/check-param-names": ["error", {
83-
"allowExtraTrailingParamDocs": true
84-
}],
85-
"jsdoc/check-syntax": "error",
86-
"jsdoc/check-tag-names": ["error", {
87-
"definedTags": [
88-
"parent",
89-
"body",
90-
"endpoint",
91-
"ngdoc",
92-
"restrict"
93-
]
94-
}],
95-
"jsdoc/check-types": "error",
96-
"jsdoc/implements-on-classes": "error",
97-
"jsdoc/match-description": "error",
98-
"jsdoc/newline-after-description": "error",
99-
"jsdoc/require-description": ["error", {
100-
"checkConstructors": false,
101-
"descriptionStyle": "any"
102-
}],
103-
"jsdoc/require-description-complete-sentence": "error",
104-
"jsdoc/require-hyphen-before-param-description": ["error", "never"],
105-
"jsdoc/require-param": "error",
106-
"jsdoc/require-param-description": "error",
107-
"jsdoc/require-param-name": "error",
108-
"jsdoc/require-param-type": "error",
109-
"jsdoc/require-property": "error",
110-
"jsdoc/require-property-description": "error",
111-
"jsdoc/require-property-name": "error",
112-
"jsdoc/require-property-type": "error",
113-
"jsdoc/require-returns": "error",
114-
"jsdoc/require-returns-check": "error",
115-
"jsdoc/require-returns-type": "error",
116-
"jsdoc/valid-types": "error"
117-
},
118-
"settings": {
119-
"jsdoc": {
120-
"mode": "typescript"
121-
}
85+
"no-trailing-spaces": "error"
12286
}
12387
}

e2e/server/server.js

Lines changed: 0 additions & 39 deletions
This file was deleted.

e2e/synchronizer.test.ts

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1+
import responseMocks from './utils/responseMocks.json';
2+
import fetchMock from './utils/nodeFetchMock';
13
import { Synchronizer } from '../src/index';
24
import { PREFIX, REDIS_PREFIX, REDIS_URL, SERVER_MOCK_URL } from './utils/constants';
35
import runSDKConsumer from './utils/SDKConsumerMode';
46
import redisAdapterWrapper from './utils/redisAdapterWrapper';
57
import { ISynchronizerSettings } from '../types';
68

9+
fetchMock.get(SERVER_MOCK_URL + '/version', 200);
10+
fetchMock.post({ url: SERVER_MOCK_URL + '/v1/metrics/config', repeat: 3 }, 200);
11+
fetchMock.post({ url: SERVER_MOCK_URL + '/v1/metrics/usage', repeat: 3 }, 200);
12+
fetchMock.post({ url: SERVER_MOCK_URL + '/events/bulk', repeat: 3 }, 200);
13+
fetchMock.post({ url: SERVER_MOCK_URL + '/testImpressions/bulk', repeat: 2 }, 200);
14+
fetchMock.post({ url: SERVER_MOCK_URL + '/testImpressions/count', repeat: 2 }, 200);
15+
fetchMock.post({ url: SERVER_MOCK_URL + '/v1/keys/ss', repeat: 1 }, 200);
16+
717
let _redisWrapper = redisAdapterWrapper({ url: REDIS_URL });
818

9-
// @TODO validate HTTP requests
1019
const createSynchronizer = (synchronizerMode?: string) => {
1120
/**
1221
* Settings creation.
@@ -57,6 +66,15 @@ describe('Synchronizer e2e tests', () => {
5766

5867
describe('Runs Synchronizer for the [FIRST] time, and', () => {
5968
beforeAll(async () => {
69+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=-1', { status: 200, body: responseMocks.splitChanges[0] });
70+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=-1', { status: 200, body: responseMocks.segmentChanges[0] });
71+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/ENDIOS_PEREZ?since=-1', { status: 200, body: responseMocks.segmentChanges[1] });
72+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=-1', { status: 200, body: responseMocks.segmentChanges[2] });
73+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
74+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/ENDIOS_PEREZ?since=1606940431526', { status: 200, body: responseMocks.segmentChanges[4] });
75+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1609943267407', { status: 200, body: responseMocks.segmentChanges[5] });
76+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1617053238061', { status: 200, body: responseMocks.segmentChanges[6] });
77+
6078
const _synchronizer = createSynchronizer();
6179
await _synchronizer.execute();
6280
});
@@ -126,6 +144,10 @@ describe('Synchronizer e2e tests', () => {
126144

127145
describe('Runs Synchronizer a [SECOND] time and', () => {
128146
beforeAll(async () => {
147+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=1619720346271', { status: 200, body: responseMocks.splitChanges[2] });
148+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
149+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1617053238061', { status: 200, body: responseMocks.segmentChanges[6] });
150+
129151
const _synchronizer = createSynchronizer();
130152

131153
const hasExecute = await _synchronizer.execute();
@@ -202,6 +224,10 @@ describe('Synchronizer e2e tests', () => {
202224
});
203225

204226
test('Run Synchronizer and check that data was popped from Redis and sent to Split BE', async () => {
227+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=1619720346272', { status: 200, body: responseMocks.splitChanges[3] });
228+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
229+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1617053238061', { status: 200, body: responseMocks.segmentChanges[6] });
230+
205231
const _synchronizer = createSynchronizer();
206232

207233
const hasExecute = await _synchronizer.execute();
@@ -246,6 +272,10 @@ describe('Synchronizer e2e tests', () => {
246272
});
247273

248274
test('Run Synchronizer and check that data was popped from Redis and sent to Split BE', async () => {
275+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=1619720346272', { status: 200, body: responseMocks.splitChanges[3] });
276+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
277+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1617053238061', { status: 200, body: responseMocks.segmentChanges[6] });
278+
249279
const _synchronizer = createSynchronizer();
250280

251281
const hasExecute = await _synchronizer.execute();
@@ -317,6 +347,10 @@ describe('Synchronizer e2e tests - OPTIMIZED impressions mode & Flag Sets filter
317347

318348
describe('Synchronizer runs the first time', () => {
319349
beforeAll(async () => {
350+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=-1&sets=set_b', { status: 200, body: responseMocks.splitChanges[0] });
351+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=-1', { status: 200, body: responseMocks.segmentChanges[0] });
352+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
353+
320354
await _synchronizer.execute();
321355
});
322356

@@ -368,6 +402,9 @@ describe('Synchronizer e2e tests - OPTIMIZED impressions mode & Flag Sets filter
368402

369403
describe('Synchronizer runs a second time, and', () => {
370404
beforeAll(async () => {
405+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=1619720346271&sets=set_b', { status: 200, body: responseMocks.splitChanges[2] });
406+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
407+
371408
await _synchronizer.execute();
372409
});
373410

@@ -408,45 +445,40 @@ describe('Synchronizer e2e tests - OPTIMIZED impressions mode & Flag Sets filter
408445
});
409446
});
410447

411-
test('Synchronizer runs a 3rd time with same SDK key and filter criteria, but wrong URLs. Execution should fail and storage should not be updated', async () => {
448+
test('Synchronizer runs a 3rd time with same SDK key and filter criteria, but HTTP requests fail. Execution should fail and storage should not be updated', async () => {
412449
const keys = await _redisWrapper.getKeysByPrefix(`${REDIS_PREFIX}.`);
413450

414451
const synchronizer = new Synchronizer({
415452
...settings,
416453
sync: {
417-
// To final filter query after validation is `&sets=set_b`
454+
// Final filter query after validation is `&sets=set_b`
418455
splitFilters: [{
419456
type: 'bySet', values: ['set_b', ' '],
420457
}, {
421458
type: 'byName', values: ['set_b'],
422459
}],
423460
},
424-
urls: {
425-
sdk: SERVER_MOCK_URL + '/invalidpath',
426-
events: SERVER_MOCK_URL + '/invalidpath',
427-
telemetry: SERVER_MOCK_URL + '/invalidpath',
428-
},
429461
});
430462

463+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=1619720346272&sets=set_b', { status: 500 });
464+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
465+
431466
expect(await synchronizer.execute()).toBe(false);
432467
expect(await _redisWrapper.getKeysByPrefix(`${REDIS_PREFIX}.`)).toEqual(keys);
433468
});
434469

435-
test('Synchronizer runs a 4th time with a different SDK key and wrong URLs. Execution should fail and storage should be empty, except for storage hash', async () => {
470+
test('Synchronizer runs a 4th time with a different SDK key and HTTP requests fail. Execution should fail and storage should be empty, except for storage hash', async () => {
436471
const keys = await _redisWrapper.getKeysByPrefix(`${REDIS_PREFIX}.`);
437472

438473
const synchronizer = new Synchronizer({
439474
...settings,
440475
core: {
441476
authorizationKey: 'fakeSdkKeyForTesting-2',
442477
},
443-
urls: {
444-
sdk: SERVER_MOCK_URL + '/invalidpath',
445-
events: SERVER_MOCK_URL + '/invalidpath',
446-
telemetry: SERVER_MOCK_URL + '/invalidpath',
447-
},
448478
});
449479

480+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=-1&sets=set_b', { status: 500 });
481+
450482
expect(await synchronizer.execute()).toBe(false);
451483
expect(keys.length).toBeGreaterThan(0);
452484
expect(await _redisWrapper.getKeysByPrefix(`${REDIS_PREFIX}.`)).toEqual([`${REDIS_PREFIX}.hash`]);
@@ -459,6 +491,13 @@ describe('Synchronizer - only Splits & Segments mode', () => {
459491
let executeImpressionsAndEventsCallSpy: jest.SpyInstance;
460492

461493
beforeAll(async () => {
494+
fetchMock.getOnce(SERVER_MOCK_URL + '/splitChanges?s=1.1&since=-1', { status: 200, body: responseMocks.splitChanges[0] });
495+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=-1', { status: 200, body: responseMocks.segmentChanges[0] });
496+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=-1', { status: 200, body: responseMocks.segmentChanges[2] });
497+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/test_maldo?since=1589906133231', { status: 200, body: responseMocks.segmentChanges[3] });
498+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1609943267407', { status: 200, body: responseMocks.segmentChanges[5] });
499+
fetchMock.getOnce(SERVER_MOCK_URL + '/segmentChanges/Lucas_Segments_Tests?since=1617053238061', { status: 200, body: responseMocks.segmentChanges[6] });
500+
462501
_synchronizer = createSynchronizer('MODE_RUN_FEATURE_FLAGS_AND_SEGMENTS'); // @ts-ignore
463502
executeSplitsAndSegmentsCallSpy = jest.spyOn(_synchronizer, 'executeSplitsAndSegments'); // @ts-ignore
464503
executeImpressionsAndEventsCallSpy = jest.spyOn(_synchronizer, 'executeImpressionsAndEvents');

e2e/utils/nodeFetchMock.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import fetchMock from 'fetch-mock';
2+
import { __setFetch } from '../../src/synchronizers/getFetch';
3+
4+
const sandboxFetchMock = fetchMock.sandbox();
5+
6+
// config the fetch mock to chain routes (appends the new route to the list of routes)
7+
sandboxFetchMock.config.overwriteRoutes = false;
8+
9+
__setFetch(sandboxFetchMock);
10+
11+
export default sandboxFetchMock;
File renamed without changes.

0 commit comments

Comments
 (0)