Skip to content

Commit

Permalink
feat: add support to add all kinds of mocks at test-case level
Browse files Browse the repository at this point in the history
Signed-off-by: Sai Sankeerth <[email protected]>
  • Loading branch information
Sai Sankeerth committed Sep 27, 2023
1 parent cb2205e commit 66b99dc
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 58 deletions.
59 changes: 7 additions & 52 deletions test/integrations/component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
getTestData,
getMockHttpCallsData,
getAllTestMockDataFilePaths,
addMock,
} from './testUtils';
import tags, { FEATURES } from '../../src/v0/util/tags';
import { Server } from 'http';
Expand Down Expand Up @@ -76,46 +77,13 @@ if (!opts.generate || opts.generate === 'false') {
// unmock already existing axios-mocking
mock = new MockAxiosAdapter(axios, { onNoMatch: 'passthrough' });
const registerAxiosMocks = (axiosMocks: MockHttpCallsData[]) => {
axiosMocks.forEach((axiosMock) => {
const { url, method, data: reqData, ...opts } = axiosMock.httpReq;
const { data, headers, status } = axiosMock.httpRes;

const headersAsymMatch = {
asymmetricMatch: function (actual) {
return isMatch(actual, opts.headers);
},
};

switch (method.toLowerCase()) {
case 'get':
// @ts-ignore
mock.onGet(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'delete':
// @ts-ignore
mock.onDelete(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'post':
// @ts-ignore
mock.onPost(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'patch':
// @ts-ignore
mock.onPatch(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'put':
// @ts-ignore
mock.onPut(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
default:
break;
}
});
axiosMocks.forEach((axiosMock) => addMock(mock, axiosMock));
};

// // all the axios requests will be stored in this map
const allTestMockDataFilePaths = getAllTestMockDataFilePaths(__dirname, opts.destination);
const allAxiosRequests = allTestMockDataFilePaths
.filter((d) => !d.includes('/af/'))
.map((currPath) => {
const mockNetworkCallsData: MockHttpCallsData[] = getMockHttpCallsData(currPath);
return mockNetworkCallsData;
Expand Down Expand Up @@ -205,26 +173,13 @@ const sourceTestHandler = async (tcData) => {

// Trigger the test suites
describe.each(allTestDataFilePaths)('%s Tests', (testDataPath) => {
beforeEach(() => {
jest.clearAllMocks();
});
// add special mocks for specific destinations
const testData: TestCaseData[] = getTestData(testDataPath);
test.each(testData)('$name - $module - $feature -> $description', async (tcData) => {
if (testDataPath.includes('yahoo_dsp')) {
// 21 September 2023 19:39:50 GMT+05:30
Date.now = jest.fn(() => 1695305390000);
}
if (tcData.feature === FEATURES.USER_DELETION && tcData.name === 'af') {
jest.spyOn(Date.prototype, 'toISOString').mockReturnValue('2023-09-24T11:22:24.018Z');
}

jest.mock('../../src/v0/util/index', () => {
const originalModule = jest.requireActual('../../src/v0/util/index');
return {
...originalModule,
generateUUID: jest.fn().mockImplementation(() => {
return 'generated_uuid';
}),
};
});
tcData?.mockFns?.(mock);

switch (tcData.module) {
case tags.MODULES.DESTINATION:
Expand Down
20 changes: 20 additions & 0 deletions test/integrations/destinations/af/deleteUsers/data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { cloneDeep } from 'lodash';
import { FEATURES } from '../../../../../src/v0/util/tags';
import { networkCallsData } from '../network';
import { addMock } from '../../../testUtils';
import MockAdapter from 'axios-mock-adapter';
import utils from '../../../../../src/v0/util';

const defaultMockFns = () => {
jest.spyOn(Date.prototype, 'toISOString').mockReturnValue('2023-09-24T11:22:24.018Z');
jest.spyOn(utils, 'generateUUID').mockReturnValue('97fcd7b2-cc24-47d7-b776-057b7b199513');
};

const requests = [
{
request: {
Expand Down Expand Up @@ -237,6 +247,11 @@ export const data = [
],
},
},
mockFns: (mockAdapter: MockAdapter) => {
const nwData = networkCallsData[0];
addMock(mockAdapter, nwData);
defaultMockFns();
},
},
{
name: 'af',
Expand Down Expand Up @@ -277,6 +292,11 @@ export const data = [
],
},
},
mockFns: (mockAdapter: MockAdapter) => {
const nwData = networkCallsData[1];
addMock(mockAdapter, nwData);
defaultMockFns();
},
},
...nonNetworkCases,
];
4 changes: 2 additions & 2 deletions test/integrations/destinations/af/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const networkCallsData = [
},
],
property_id: 'AnAID',
subject_request_id: 'generated_uuid',
subject_request_id: '97fcd7b2-cc24-47d7-b776-057b7b199513',
submitted_time: '2023-09-24T11:22:24.018Z',
},
},
Expand Down Expand Up @@ -50,7 +50,7 @@ export const networkCallsData = [
],
status_callback_urls: ['https://examplecontroller.com/opengdpr_callbacks'],
property_id: '123456789',
subject_request_id: 'generated_uuid',
subject_request_id: '97fcd7b2-cc24-47d7-b776-057b7b199513',
submitted_time: '2023-09-24T11:22:24.018Z',
},
headers: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import utils from '../../../../../src/v0/util';
export const mockFns = (_) => {
// @ts-ignore
jest.spyOn(utils, 'generateUUID').mockImplementation(() => 'generated_uuid');
};
export const data = [
{
name: 'optimizely_fullstack',
Expand Down Expand Up @@ -2162,4 +2167,4 @@ export const data = [
},
},
},
];
].map((d) => ({ ...d, mockFns }));
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FEATURES } from '../../../../../src/v0/util/tags';
import { mockFns } from '../processor/data';

export const data = [
{
Expand Down Expand Up @@ -557,5 +558,6 @@ export const data = [
},
},
},
mockFns,
},
];
12 changes: 11 additions & 1 deletion test/integrations/destinations/yahoo_dsp/processor/data.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { addMock } from '../../../testUtils';
import { networkCallsData } from '../network';

export const mockFns = (mockAdapter) => {
addMock(mockAdapter, networkCallsData[0]);
// 21 September 2023 19:39:50 GMT+05:30
Date.now = jest.fn(() => 1695305390000);
};
export const data = [
{
name: 'yahoo_dsp',
Expand Down Expand Up @@ -1107,4 +1115,6 @@ export const data = [
},
},
},
];
].map((d) => {
return { ...d, mockFns };
});
3 changes: 3 additions & 0 deletions test/integrations/destinations/yahoo_dsp/router/data.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { mockFns } from '../processor/data';

export const data = [
{
name: 'yahoo_dsp',
Expand Down Expand Up @@ -144,5 +146,6 @@ export const data = [
},
},
},
mockFns,
},
];
6 changes: 4 additions & 2 deletions test/integrations/testTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AxiosResponse } from "axios";
import { AxiosResponse } from 'axios';
import MockAdapter from 'axios-mock-adapter';

export interface requestType {
method: string;
Expand Down Expand Up @@ -36,9 +37,10 @@ export interface TestCaseData {
input: inputType;
output: outputType;
mock?: mockType[];
mockFns?: (mockAdapter: MockAdapter) => {};
}

export type MockHttpCallsData = {
httpReq: Record<string, any>;
httpRes: Partial<AxiosResponse>;
}
};
38 changes: 38 additions & 0 deletions test/integrations/testUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { globSync } from 'glob';
import { join } from 'path';
import { MockHttpCallsData, TestCaseData } from './testTypes';
import MockAdapter from 'axios-mock-adapter';
import isMatch from 'lodash/isMatch';

export const getTestDataFilePaths = (dirPath: string, destination: string = ''): string[] => {
const globPattern = join(dirPath, '**', 'data.ts');
Expand All @@ -27,3 +29,39 @@ export const getAllTestMockDataFilePaths = (dirPath: string, destination: string
}
return testFilePaths;
};

export const addMock = (mock: MockAdapter, axiosMock: MockHttpCallsData) => {
const { url, method, data: reqData, ...opts } = axiosMock.httpReq;
const { data, headers, status } = axiosMock.httpRes;

const headersAsymMatch = {
asymmetricMatch: function (actual) {
return isMatch(actual, opts.headers);
},
};

switch (method.toLowerCase()) {
case 'get':
// @ts-ignore
mock.onGet(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'delete':
// @ts-ignore
mock.onDelete(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'post':
// @ts-ignore
mock.onPost(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'patch':
// @ts-ignore
mock.onPatch(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
case 'put':
// @ts-ignore
mock.onPut(url, reqData, headersAsymMatch).reply(status, data, headers);
break;
default:
break;
}
};

0 comments on commit 66b99dc

Please sign in to comment.