From 8956ba2d1c7c261b49614194f75da6fef4d0bf5d Mon Sep 17 00:00:00 2001 From: Chandra shekar Varkala Date: Tue, 25 Jul 2023 02:48:28 -0500 Subject: [PATCH] chore: apicontract test --- test/__tests__/apicontract.test.1.ts | 204 ++++++++++++++++++ test/__tests__/data/generic_router_input.json | 92 ++++++++ 2 files changed, 296 insertions(+) create mode 100644 test/__tests__/apicontract.test.1.ts create mode 100644 test/__tests__/data/generic_router_input.json diff --git a/test/__tests__/apicontract.test.1.ts b/test/__tests__/apicontract.test.1.ts new file mode 100644 index 0000000000..2fadd9aa01 --- /dev/null +++ b/test/__tests__/apicontract.test.1.ts @@ -0,0 +1,204 @@ +import fs from 'fs'; +import path from 'path'; +import request from 'supertest'; +import { createHttpTerminator } from 'http-terminator'; +import Koa from 'koa'; +import bodyParser from 'koa-bodyparser'; +import { applicationRoutes } from '../../src/routes'; + +let server: any; +const OLD_ENV = process.env; + +beforeAll(async () => { + process.env = { ...OLD_ENV }; // Make a copy + const app = new Koa(); + app.use( + bodyParser({ + jsonLimit: '200mb', + }), + ); + applicationRoutes(app); + server = app.listen(9090); +}); + +afterAll(async () => { + process.env = OLD_ENV; // Restore old environment + const httpTerminator = createHttpTerminator({ + server, + }); + await httpTerminator.terminate(); +}); + +const getDataFromPath = (pathInput) => { + const testDataFile = fs.readFileSync(path.resolve(__dirname, pathInput)); + return JSON.parse(testDataFile.toString()); +}; + +const integrations = { + ACTIVE_CAMPAIGN: 'active_campaign', + ALGOLIA: 'algolia', + CANDU: 'candu', + DELIGHTED: 'delighted', + DRIP: 'drip', + FB_CUSTOM_AUDIENCE: 'fb_custom_audience', + GA: 'ga', + GAINSIGHT: 'gainsight', + GAINSIGHT_PX: 'gainsight_px', + GOOGLESHEETS: 'googlesheets', + GOOGLE_ADWORDS_ENHANCED_CONVERSIONS: 'google_adwords_enhanced_conversions', + GOOGLE_ADWORDS_REMARKETING_LISTS: 'google_adwords_remarketing_lists', + GOOGLE_ADWORDS_OFFLINE_CONVERSIONS: 'google_adwords_offline_conversions', + HS: 'hs', + ITERABLE: 'iterable', + KLAVIYO: 'klaviyo', + KUSTOMER: 'kustomer', + MAILCHIMP: 'mailchimp', + MAILMODO: 'mailmodo', + MARKETO: 'marketo', + OMETRIA: 'ometria', + PARDOT: 'pardot', + PINTEREST_TAG: 'pinterest_tag', + PROFITWELL: 'profitwell', + SALESFORCE: 'salesforce', + SFMC: 'sfmc', + SNAPCHAT_CONVERSION: 'snapchat_conversion', + TIKTOK_ADS: 'tiktok_ads', + TRENGO: 'trengo', + YAHOO_DSP: 'yahoo_dsp', + CANNY: 'canny', + LAMBDA: 'lambda', + WOOTRIC: 'wootric', + GOOGLE_CLOUD_FUNCTION: 'google_cloud_function', + BQSTREAM: 'bqstream', + CLICKUP: 'clickup', + FRESHMARKETER: 'freshmarketer', + FRESHSALES: 'freshsales', + MONDAY: 'monday', + CUSTIFY: 'custify', + USER: 'user', + REFINER: 'refiner', + FACEBOOK_OFFLINE_CONVERSIONS: 'facebook_offline_conversions', + MAILJET: 'mailjet', + SNAPCHAT_CUSTOM_AUDIENCE: 'snapchat_custom_audience', + MARKETO_STATIC_LIST: 'marketo_static_list', + CAMPAIGN_MANAGER: 'campaign_manager', + SENDGRID: 'sendgrid', + SENDINBLUE: 'sendinblue', + ZENDESK: 'zendesk', + MP: 'mp', + TIKTOK_ADS_OFFLINE_EVENTS: 'tiktok_ads_offline_events', + CRITEO_AUDIENCE: 'criteo_audience', + CUSTOMERIO: 'customerio', + BRAZE: 'braze', + OPTIMIZELY_FULLSTACK: 'optimizely_fullstack', + TWITTER_ADS: 'twitter_ads', +}; + +const features = getDataFromPath('../../src/features.json'); +const allIntegrations: string[] = []; +Object.keys(features.routerTransform).forEach((feature) => { + allIntegrations.push(integrations[feature]); +}); + +console.log(allIntegrations); + +//Only google sheets failing. Rest all passing. +describe('Router transform tests', () => { + allIntegrations.forEach((integration) => { + const data = getDataFromPath('./data/generic_router_input.json'); + data.input.forEach((inputData) => { + test(`${integration} router transform`, async () => { + inputData.destType = integration; + + const response = await request(server) + .post('/routerTransform') + .set('Accept', 'application/json') + .send(inputData); + expect(response.status).toEqual(200); + const routerOutput = JSON.parse(response.text).output; + + const returnedJobids = {}; + routerOutput.forEach((outEvent) => { + console.log(outEvent); + + //Assert that metadata is present and is an array + const metadata = outEvent.metadata; + expect(Array.isArray(metadata)).toEqual(true); + + //Assert that statusCode is present and is a number between 200 and 600 + const statusCode = outEvent.statusCode; + expect(statusCode).toBeDefined(); + expect(typeof statusCode === 'number').toEqual(true); + const validStatusCode = statusCode >= 200 && statusCode < 600; + expect(validStatusCode).toEqual(true); + + //Assert that every job_id in the input is present in the output one and only one time. + metadata.forEach((meta) => { + const jobId = meta.jobId; + console.log(jobId); + expect(returnedJobids[jobId]).toBeUndefined(); + returnedJobids[jobId] = true; + }); + }); + + const inputJobids = {}; + inputData.input.forEach((input) => { + const jobId = input.metadata.jobId; + inputJobids[jobId] = true; + }); + + expect(returnedJobids).toEqual(inputJobids); + }); + }); + }); +}); + +describe('Batch tests', () => { + allIntegrations.forEach((integration) => { + const data = getDataFromPath('./data/generic_router_input.json'); + data.input.forEach((inputData) => { + test(`${integration} batch`, async () => { + inputData.destType = integration; + + const response = await request(server) + .post('/batch') + .set('Accept', 'application/json') + .send(inputData); + expect(response.status).toEqual(200); + const routerOutput = JSON.parse(response.text).output; + + const returnedJobids = {}; + routerOutput.forEach((outEvent) => { + console.log(outEvent); + + //Assert that metadata is present and is an array + const metadata = outEvent.metadata; + expect(Array.isArray(metadata)).toEqual(true); + + //Assert that statusCode is present and is a number between 200 and 600 + const statusCode = outEvent.statusCode; + expect(statusCode).toBeDefined(); + expect(typeof statusCode === 'number').toEqual(true); + const validStatusCode = statusCode >= 200 && statusCode < 600; + expect(validStatusCode).toEqual(true); + + //Assert that every job_id in the input is present in the output one and only one time. + metadata.forEach((meta) => { + const jobId = meta.jobId; + console.log(jobId); + expect(returnedJobids[jobId]).toBeUndefined(); + returnedJobids[jobId] = true; + }); + }); + + const inputJobids = {}; + inputData.input.forEach((input) => { + const jobId = input.metadata.jobId; + inputJobids[jobId] = true; + }); + + expect(returnedJobids).toEqual(inputJobids); + }); + }); + }); +}); diff --git a/test/__tests__/data/generic_router_input.json b/test/__tests__/data/generic_router_input.json new file mode 100644 index 0000000000..12c2b15e04 --- /dev/null +++ b/test/__tests__/data/generic_router_input.json @@ -0,0 +1,92 @@ +{ + "input": [ + { + "input": [ + { + "message": { + "channel": "web", + "type": "identify", + "messageId": "84e26acc-56a5-4835-8233-591137fca468", + "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "originalTimestamp": "2019-10-14T09:03:17.562Z", + "anonymousId": "123456", + "userId": "123456", + "integrations": { + "All": true + }, + "sentAt": "2019-10-14T09:03:22.563Z" + }, + "metadata": { + "jobId": 1 + }, + "destination": { + "Config": { + "apiKey": "abcde", + "groupTypeTrait": "email", + "groupValueTrait": "age" + } + } + }, + { + "message": { + "channel": "web", + "request_ip": "1.1.1.1", + "type": "page", + "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", + "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "originalTimestamp": "2019-10-14T11:15:18.299Z", + "anonymousId": "00000000000000000000000000", + "userId": "12345", + "properties": { + "path": "/destinations/amplitude", + "referrer": "", + "search": "", + "title": "", + "url": "https://docs.rudderstack.com/destinations/amplitude", + "category": "destination", + "initial_referrer": "https://docs.rudderstack.com", + "initial_referring_domain": "docs.rudderstack.com" + }, + "integrations": { + "All": true + }, + "name": "ApplicationLoaded", + "sentAt": "2019-10-14T11:15:53.296Z" + }, + "metadata": { + "jobId": 2 + }, + "destination": { + "Config": { + "apiKey": "abcde" + } + } + } + ], + "destType": "xyz" + }, + { + "input": [ + { + "message": {}, + "metadata": { + "jobId": 1 + }, + "destination": { + "Config": {} + } + }, + { + "message": {}, + "metadata": { + "jobId": 2 + }, + "destination": { + "Config": {} + } + } + ], + "destType": "xyz" + } + ] +}