From 90ca3dc8a827d5c715a046fe2076dc2efca7f473 Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Tue, 21 May 2024 20:42:03 +0200 Subject: [PATCH] fix: ditch supertest and expose http.Server instance --- package.json | 2 +- .../frontend-api.concurrency.e2e.test.ts | 32 ++++++----- src/test/e2e/helpers/test-helper.ts | 56 ++++++++++++++++++- yarn.lock | 40 +++---------- 4 files changed, 81 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 5283993cfcff..a82b4a6f2d73 100644 --- a/package.json +++ b/package.json @@ -206,7 +206,7 @@ "proxyquire": "2.1.3", "source-map-support": "0.5.21", "superagent": "9.0.2", - "supertest": "6.3.4", + "supertest": "7.0.0", "ts-node": "10.9.2", "tsc-watch": "6.2.0", "typescript": "5.4.2", diff --git a/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts b/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts index fd12f745dddb..820d691706c8 100644 --- a/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts +++ b/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts @@ -1,13 +1,13 @@ import { - type IUnleashTest, - setupAppWithAuth, + setupAppWithoutSupertest, + type IUnleashNoSupertest, } from '../../../test/e2e/helpers/test-helper'; import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; import getLogger from '../../../test/fixtures/no-logger'; import { randomId } from '../../util'; import { ApiTokenType } from '../../types/models/api-token'; -let app: IUnleashTest; +let app: IUnleashNoSupertest; let db: ITestDb; let appErrorLogs: string[] = []; @@ -21,7 +21,7 @@ beforeAll(async () => { baseLogger.error(msg, ...args); }, }; - app = await setupAppWithAuth(db.stores, { + app = await setupAppWithoutSupertest(db.stores, { frontendApiOrigins: ['https://example.com'], getLogger: () => appLogger, }); @@ -37,7 +37,7 @@ afterAll(async () => { await db.destroy(); }); -beforeEach(() => { +beforeEach(async () => { appErrorLogs = []; }); @@ -53,15 +53,19 @@ test('multiple parallel calls to api/frontend should not create multiple instanc environment: 'default', tokenName: `test-token-${randomId()}`, }); - - const promises = Array(10).fill( - app.request - .get('/api/frontend') - .set('Authorization', frontendTokenDefault.secret) - .expect('Content-Type', /json/) - .expect(200), + const address = app.server.address(); + expect(address).not.toBeNull(); + expect(address).toHaveProperty('port'); + const serverUrl = `http://localhost:${address.port}/api/frontend`; + await Promise.all( + Array.from(Array(10).keys()).map(() => + fetch(serverUrl, { + method: 'GET', + headers: { + Authorization: frontendTokenDefault.secret, + }, + }).then((res) => expect(res.status).toBe(200)), + ), ); - - await Promise.all(promises); expect(appErrorLogs).toHaveLength(0); }); diff --git a/src/test/e2e/helpers/test-helper.ts b/src/test/e2e/helpers/test-helper.ts index 638acbbd4ffa..a06f4a5b5c90 100644 --- a/src/test/e2e/helpers/test-helper.ts +++ b/src/test/e2e/helpers/test-helper.ts @@ -22,7 +22,7 @@ import type { import type { Knex } from 'knex'; import type TestAgent from 'supertest/lib/agent'; import type Test from 'supertest/lib/test'; - +import type { Server } from 'node:http'; process.env.NODE_ENV = 'test'; export interface IUnleashTest extends IUnleashHttpAPI { @@ -32,6 +32,13 @@ export interface IUnleashTest extends IUnleashHttpAPI { config: IUnleashConfig; } +export interface IUnleashNoSupertest { + server: Server; + services: IUnleashServices; + config: IUnleashConfig; + destroy: () => Promise; +} + /** * This is a collection of API helpers. The response code is optional, and should default to the success code for the request. * @@ -348,6 +355,53 @@ export async function setupApp(stores: IUnleashStores): Promise { return createApp(stores); } +export async function setupAppWithoutSupertest( + stores, + customOptions?: any, + db?: Db, +): Promise { + const config = createTestConfig({ + authentication: { + type: IAuthType.DEMO, + }, + server: { + unleashUrl: 'http://localhost:4242', + }, + disableScheduler: true, + ...{ + ...customOptions, + experimental: { + ...(customOptions?.experimental ?? {}), + flags: { + strictSchemaValidation: true, + ...(customOptions?.experimental?.flags ?? {}), + }, + }, + }, + }); + const services = createServices(stores, config, db); + const unleashSession = sessionDb(config, undefined); + const app = await getApp(config, stores, services, unleashSession, db); + const server = app.listen(0); + const destroy = async () => { + // iterate on the keys of services and if the services at that key has a function called destroy then call it + await Promise.all( + Object.keys(services).map(async (key) => { + if (services[key].destroy) { + await services[key].destroy(); + } + }), + ); + await server.close(); + }; + return { + server, + destroy, + services, + config, + }; +} + export async function setupAppWithCustomConfig( stores: IUnleashStores, // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types diff --git a/yarn.lock b/yarn.lock index fa85b8c89251..30a11eb1c016 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3461,16 +3461,6 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -formidable@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-2.1.2.tgz#fa973a2bec150e4ce7cac15589d7a25fc30ebd89" - integrity sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g== - dependencies: - dezalgo "^1.0.4" - hexoid "^1.0.0" - once "^1.4.0" - qs "^6.11.0" - formidable@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-3.5.1.tgz#9360a23a656f261207868b1484624c4c8d06ee1a" @@ -6399,7 +6389,7 @@ sanitize-filename@^1.6.3: dependencies: truncate-utf8-bytes "^1.0.0" -semver@^5.3.0, semver@^6.0.0, semver@^6.3.0, semver@^6.3.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@^5.3.0, semver@^6.0.0, semver@^6.3.0, semver@^6.3.1, semver@^7.3.4, semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -6911,7 +6901,7 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -superagent@9.0.2: +superagent@9.0.2, superagent@^9.0.1: version "9.0.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-9.0.2.tgz#a18799473fc57557289d6b63960610e358bdebc1" integrity sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w== @@ -6926,29 +6916,13 @@ superagent@9.0.2: mime "2.6.0" qs "^6.11.0" -superagent@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-8.1.2.tgz#03cb7da3ec8b32472c9d20f6c2a57c7f3765f30b" - integrity sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA== - dependencies: - component-emitter "^1.3.0" - cookiejar "^2.1.4" - debug "^4.3.4" - fast-safe-stringify "^2.1.1" - form-data "^4.0.0" - formidable "^2.1.2" - methods "^1.1.2" - mime "2.6.0" - qs "^6.11.0" - semver "^7.3.8" - -supertest@6.3.4: - version "6.3.4" - resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.3.4.tgz#2145c250570c2ea5d337db3552dbfb78a2286218" - integrity sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw== +supertest@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-7.0.0.tgz#cac53b3d6872a0b317980b2b0cfa820f09cd7634" + integrity sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA== dependencies: methods "^1.1.2" - superagent "^8.1.2" + superagent "^9.0.1" supports-color@^5.3.0: version "5.5.0"