From 3d590e879e7abcc8c6eaf72ad044db00260ffe8b Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 9 Aug 2024 10:30:27 +0100 Subject: [PATCH] Rely on withEnv and setEnv functions in respective environment.ts files. --- packages/backend-core/src/index.ts | 2 +- .../{apikeys.spec.js => apikeys.spec.ts} | 15 ++--- .../src/api/routes/tests/application.spec.ts | 9 ++- .../src/api/routes/tests/attachment.spec.ts | 5 +- .../server/src/api/routes/tests/row.spec.ts | 7 ++- .../src/api/routes/tests/search.spec.ts | 8 ++- .../tests/{static.spec.js => static.spec.ts} | 25 ++++---- .../src/api/routes/tests/templates.spec.ts | 3 +- .../src/api/routes/tests/viewV2.spec.ts | 14 +++-- .../src/api/routes/tests/webhook.spec.ts | 3 +- .../tests/20240604153647_initial_sqs.spec.ts | 10 +++- .../src/automations/tests/openai.spec.ts | 5 +- packages/server/src/environment.ts | 27 +++++++++ .../integrations/tests/googlesheets.spec.ts | 3 +- .../sdk/app/rows/search/tests/search.spec.ts | 11 ++-- .../server/src/startup/tests/startup.spec.ts | 12 +++- .../src/tests/utilities/TestConfiguration.ts | 59 ------------------- 17 files changed, 109 insertions(+), 109 deletions(-) rename packages/server/src/api/routes/tests/{apikeys.spec.js => apikeys.spec.ts} (75%) rename packages/server/src/api/routes/tests/{static.spec.js => static.spec.ts} (88%) diff --git a/packages/backend-core/src/index.ts b/packages/backend-core/src/index.ts index a14a344655a..dbdce51c50b 100644 --- a/packages/backend-core/src/index.ts +++ b/packages/backend-core/src/index.ts @@ -27,7 +27,7 @@ export * as locks from "./redis/redlockImpl" export * as utils from "./utils" export * as errors from "./errors" export * as timers from "./timers" -export { default as env } from "./environment" +export { default as env, withEnv, setEnv } from "./environment" export * as blacklist from "./blacklist" export * as docUpdates from "./docUpdates" export * from "./utils/Duration" diff --git a/packages/server/src/api/routes/tests/apikeys.spec.js b/packages/server/src/api/routes/tests/apikeys.spec.ts similarity index 75% rename from packages/server/src/api/routes/tests/apikeys.spec.js rename to packages/server/src/api/routes/tests/apikeys.spec.ts index 678da38f28e..30f87fcfec6 100644 --- a/packages/server/src/api/routes/tests/apikeys.spec.js +++ b/packages/server/src/api/routes/tests/apikeys.spec.ts @@ -1,11 +1,12 @@ -const setup = require("./utilities") -const { checkBuilderEndpoint } = require("./utilities/TestFunctions") +import { withEnv } from "../../../environment" +import { getRequest, getConfig, afterAll as _afterAll } from "./utilities" +import { checkBuilderEndpoint } from "./utilities/TestFunctions" describe("/api/keys", () => { - let request = setup.getRequest() - let config = setup.getConfig() + let request = getRequest() + let config = getConfig() - afterAll(setup.afterAll) + afterAll(_afterAll) beforeAll(async () => { await config.init() @@ -13,7 +14,7 @@ describe("/api/keys", () => { describe("fetch", () => { it("should allow fetching", async () => { - await config.withEnv({ SELF_HOSTED: "true" }, async () => { + await withEnv({ SELF_HOSTED: "true" }, async () => { const res = await request .get(`/api/keys`) .set(config.defaultHeaders()) @@ -34,7 +35,7 @@ describe("/api/keys", () => { describe("update", () => { it("should allow updating a value", async () => { - await config.withEnv({ SELF_HOSTED: "true" }, async () => { + await withEnv({ SELF_HOSTED: "true" }, async () => { const res = await request .put(`/api/keys/TEST`) .send({ diff --git a/packages/server/src/api/routes/tests/application.spec.ts b/packages/server/src/api/routes/tests/application.spec.ts index 6ae598ee84b..a8e060a2b5c 100644 --- a/packages/server/src/api/routes/tests/application.spec.ts +++ b/packages/server/src/api/routes/tests/application.spec.ts @@ -14,7 +14,12 @@ jest.mock("../../../utilities/redis", () => ({ import { checkBuilderEndpoint } from "./utilities/TestFunctions" import * as setup from "./utilities" import { AppStatus } from "../../../db/utils" -import { events, utils, context } from "@budibase/backend-core" +import { + events, + utils, + context, + withEnv as withCoreEnv, +} from "@budibase/backend-core" import env from "../../../environment" import { type App } from "@budibase/types" import tk from "timekeeper" @@ -353,7 +358,7 @@ describe("/applications", () => { .delete(`/api/global/roles/${prodAppId}`) .reply(200, {}) - await config.withCoreEnv({ SQS_SEARCH_ENABLE: "true" }, async () => { + await withCoreEnv({ SQS_SEARCH_ENABLE: "true" }, async () => { await config.api.application.delete(app.appId) }) }) diff --git a/packages/server/src/api/routes/tests/attachment.spec.ts b/packages/server/src/api/routes/tests/attachment.spec.ts index 7ff4e67bcc8..53e0a1b15d5 100644 --- a/packages/server/src/api/routes/tests/attachment.spec.ts +++ b/packages/server/src/api/routes/tests/attachment.spec.ts @@ -1,3 +1,4 @@ +import { withEnv } from "../../../environment" import * as setup from "./utilities" import { APIError } from "@budibase/types" @@ -28,7 +29,7 @@ describe("/api/applications/:appId/sync", () => { }) it("should reject an upload with a malicious file extension", async () => { - await config.withEnv({ SELF_HOSTED: undefined }, async () => { + await withEnv({ SELF_HOSTED: undefined }, async () => { let resp = (await config.api.attachment.process( "ohno.exe", Buffer.from([0]), @@ -39,7 +40,7 @@ describe("/api/applications/:appId/sync", () => { }) it("should reject an upload with a malicious uppercase file extension", async () => { - await config.withEnv({ SELF_HOSTED: undefined }, async () => { + await withEnv({ SELF_HOSTED: undefined }, async () => { let resp = (await config.api.attachment.process( "OHNO.EXE", Buffer.from([0]), diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index cf94eb9f13d..9351976d668 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -40,6 +40,7 @@ import _, { merge } from "lodash" import * as uuid from "uuid" import { Knex } from "knex" import { InternalTables } from "../../../db/utils" +import { withEnv } from "../../../environment" const timestamp = new Date("2023-01-26T11:48:57.597Z").toISOString() tk.freeze(timestamp) @@ -1688,7 +1689,7 @@ describe.each([ } const row = await config.api.row.save(testTable._id!, draftRow) - await config.withEnv({ SELF_HOSTED: "true" }, async () => { + await withEnv({ SELF_HOSTED: "true" }, async () => { return context.doInAppContext(config.getAppId(), async () => { const enriched: Row[] = await outputProcessing(table, [row]) const [targetRow] = enriched @@ -2456,7 +2457,7 @@ describe.each([ describe("Formula JS protection", () => { it("should time out JS execution if a single cell takes too long", async () => { - await config.withEnv({ JS_PER_INVOCATION_TIMEOUT_MS: 40 }, async () => { + await withEnv({ JS_PER_INVOCATION_TIMEOUT_MS: 40 }, async () => { const js = Buffer.from( ` let i = 0; @@ -2494,7 +2495,7 @@ describe.each([ }) it("should time out JS execution if a multiple cells take too long", async () => { - await config.withEnv( + await withEnv( { JS_PER_INVOCATION_TIMEOUT_MS: 40, JS_PER_REQUEST_TIMEOUT_MS: 80, diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index d8c2a4a257a..5c0a04d64f3 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -11,6 +11,8 @@ import { MIN_VALID_DATE, SQLITE_DESIGN_DOC_ID, utils, + withEnv as withCoreEnv, + setEnv as setCoreEnv, } from "@budibase/backend-core" import * as setup from "./utilities" @@ -64,9 +66,9 @@ describe.each([ let rows: Row[] beforeAll(async () => { - await config.withCoreEnv({ SQS_SEARCH_ENABLE: "true" }, () => config.init()) + await withCoreEnv({ SQS_SEARCH_ENABLE: "true" }, () => config.init()) if (isSqs) { - envCleanup = config.setCoreEnv({ + envCleanup = setCoreEnv({ SQS_SEARCH_ENABLE: "true", SQS_SEARCH_ENABLE_TENANTS: [config.getTenantId()], }) @@ -2668,7 +2670,7 @@ describe.each([ }) it("can still page when the hard limit is hit", async () => { - await config.withCoreEnv( + await withCoreEnv( { SQL_MAX_ROWS: "6", }, diff --git a/packages/server/src/api/routes/tests/static.spec.js b/packages/server/src/api/routes/tests/static.spec.ts similarity index 88% rename from packages/server/src/api/routes/tests/static.spec.js rename to packages/server/src/api/routes/tests/static.spec.ts index 1358b5418af..62b72b2b8fc 100644 --- a/packages/server/src/api/routes/tests/static.spec.js +++ b/packages/server/src/api/routes/tests/static.spec.ts @@ -8,23 +8,24 @@ jest.mock("aws-sdk", () => ({ })), })) -const setup = require("./utilities") -const { constants } = require("@budibase/backend-core") +import { Datasource, SourceName } from "@budibase/types" +import { setEnv } from "../../../environment" +import { getRequest, getConfig, afterAll as _afterAll } from "./utilities" +import { constants } from "@budibase/backend-core" describe("/static", () => { - let request = setup.getRequest() - let config = setup.getConfig() - let app - let cleanupEnv + let request = getRequest() + let config = getConfig() + let cleanupEnv: () => void afterAll(() => { - setup.afterAll() + _afterAll() cleanupEnv() }) beforeAll(async () => { - cleanupEnv = config.setEnv({ SELF_HOSTED: "true" }) - app = await config.init() + cleanupEnv = setEnv({ SELF_HOSTED: "true" }) + await config.init() }) describe("/app", () => { @@ -49,7 +50,7 @@ describe("/static", () => { delete headers[constants.Header.APP_ID] const res = await request - .get(`/app${config.prodApp.url}`) + .get(`/app${config.getProdApp().url}`) .set(headers) .expect(200) @@ -68,14 +69,14 @@ describe("/static", () => { describe("/attachments", () => { describe("generateSignedUrls", () => { - let datasource + let datasource: Datasource beforeEach(async () => { datasource = await config.createDatasource({ datasource: { type: "datasource", name: "Test", - source: "S3", + source: SourceName.S3, config: {}, }, }) diff --git a/packages/server/src/api/routes/tests/templates.spec.ts b/packages/server/src/api/routes/tests/templates.spec.ts index 81c615487d2..98d375dec67 100644 --- a/packages/server/src/api/routes/tests/templates.spec.ts +++ b/packages/server/src/api/routes/tests/templates.spec.ts @@ -2,6 +2,7 @@ import * as setup from "./utilities" import path from "path" import nock from "nock" import { generator } from "@budibase/backend-core/tests" +import { withEnv as withCoreEnv } from "@budibase/backend-core" interface App { background: string @@ -89,7 +90,7 @@ describe("/templates", () => { SQS_SEARCH_ENABLE_TENANTS: [config.getTenantId()], } - await config.withCoreEnv(env, async () => { + await withCoreEnv(env, async () => { const name = generator.guid().replaceAll("-", "") const url = `/${name}` diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index ea6aedbe3cf..e18cffeaa80 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -24,7 +24,12 @@ import { generator, mocks } from "@budibase/backend-core/tests" import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" import merge from "lodash/merge" import { quotas } from "@budibase/pro" -import { db, roles } from "@budibase/backend-core" +import { + db, + roles, + withEnv as withCoreEnv, + setEnv as setCoreEnv, +} from "@budibase/backend-core" describe.each([ ["lucene", undefined], @@ -89,12 +94,11 @@ describe.each([ } beforeAll(async () => { - await config.withCoreEnv( - { SQS_SEARCH_ENABLE: isSqs ? "true" : "false" }, - () => config.init() + await withCoreEnv({ SQS_SEARCH_ENABLE: isSqs ? "true" : "false" }, () => + config.init() ) if (isSqs) { - envCleanup = config.setCoreEnv({ + envCleanup = setCoreEnv({ SQS_SEARCH_ENABLE: "true", SQS_SEARCH_ENABLE_TENANTS: [config.getTenantId()], }) diff --git a/packages/server/src/api/routes/tests/webhook.spec.ts b/packages/server/src/api/routes/tests/webhook.spec.ts index b741ce0820d..9c40a14f986 100644 --- a/packages/server/src/api/routes/tests/webhook.spec.ts +++ b/packages/server/src/api/routes/tests/webhook.spec.ts @@ -2,6 +2,7 @@ import { Webhook } from "@budibase/types" import * as setup from "./utilities" import { checkBuilderEndpoint } from "./utilities/TestFunctions" import { mocks } from "@budibase/backend-core/tests" +import { setEnv } from "../../../environment" const { basicWebhook, basicAutomation, collectAutomation } = setup.structures @@ -17,7 +18,7 @@ describe("/webhooks", () => { }) const setupTest = async () => { - cleanupEnv = config.setEnv({ SELF_HOSTED: "true" }) + cleanupEnv = setEnv({ SELF_HOSTED: "true" }) await config.init() const autoConfig = basicAutomation() autoConfig.definition.trigger.schema = { diff --git a/packages/server/src/appMigrations/migrations/tests/20240604153647_initial_sqs.spec.ts b/packages/server/src/appMigrations/migrations/tests/20240604153647_initial_sqs.spec.ts index f337958a5be..5f036bb87d0 100644 --- a/packages/server/src/appMigrations/migrations/tests/20240604153647_initial_sqs.spec.ts +++ b/packages/server/src/appMigrations/migrations/tests/20240604153647_initial_sqs.spec.ts @@ -1,6 +1,10 @@ import * as setup from "../../../api/routes/tests/utilities" import { basicTable } from "../../../tests/utilities/structures" -import { db as dbCore, SQLITE_DESIGN_DOC_ID } from "@budibase/backend-core" +import { + db as dbCore, + SQLITE_DESIGN_DOC_ID, + withEnv as withCoreEnv, +} from "@budibase/backend-core" import { LinkDocument, DocumentType, @@ -69,11 +73,11 @@ function oldLinkDocument(): Omit { type SQSEnvVar = "SQS_MIGRATION_ENABLE" | "SQS_SEARCH_ENABLE" async function sqsDisabled(envVar: SQSEnvVar, cb: () => Promise) { - await config.withCoreEnv({ [envVar]: "", SQS_SEARCH_ENABLE_TENANTS: [] }, cb) + await withCoreEnv({ [envVar]: "", SQS_SEARCH_ENABLE_TENANTS: [] }, cb) } async function sqsEnabled(envVar: SQSEnvVar, cb: () => Promise) { - await config.withCoreEnv( + await withCoreEnv( { [envVar]: "1", SQS_SEARCH_ENABLE_TENANTS: [config.getTenantId()] }, cb ) diff --git a/packages/server/src/automations/tests/openai.spec.ts b/packages/server/src/automations/tests/openai.spec.ts index 6bebe16a49c..41456f116d6 100644 --- a/packages/server/src/automations/tests/openai.spec.ts +++ b/packages/server/src/automations/tests/openai.spec.ts @@ -1,5 +1,6 @@ import { getConfig, runStep, afterAll as _afterAll } from "./utilities" import { OpenAI } from "openai" +import { withEnv as withCoreEnv, setEnv as setCoreEnv } from "@budibase/backend-core" jest.mock("openai", () => ({ OpenAI: jest.fn().mockImplementation(() => ({ @@ -32,7 +33,7 @@ describe("test the openai action", () => { }) beforeEach(() => { - resetEnv = config.setCoreEnv({ OPENAI_API_KEY: "abc123" }) + resetEnv = setCoreEnv({ OPENAI_API_KEY: "abc123" }) }) afterEach(() => { @@ -42,7 +43,7 @@ describe("test the openai action", () => { afterAll(_afterAll) it("should present the correct error message when the OPENAI_API_KEY variable isn't set", async () => { - await config.withCoreEnv({ OPENAI_API_KEY: "" }, async () => { + await withCoreEnv({ OPENAI_API_KEY: "" }, async () => { let res = await runStep("OPENAI", { prompt: OPENAI_PROMPT }) expect(res.response).toEqual( "OpenAI API Key not configured - please add the OPENAI_API_KEY environment variable." diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index e1525ebd1b4..05ebbe31511 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -1,5 +1,6 @@ import { env as coreEnv } from "@budibase/backend-core" import { ServiceType } from "@budibase/types" +import cloneDeep from "lodash/cloneDeep" coreEnv._set("SERVICE_TYPE", ServiceType.APPS) import { join } from "path" @@ -133,6 +134,32 @@ const environment = { }, } +export function setEnv(newEnvVars: Partial): () => void { + const oldEnv = cloneDeep(environment) + + let key: keyof typeof newEnvVars + for (key in newEnvVars) { + environment._set(key, newEnvVars[key]) + } + + return () => { + for (const [key, value] of Object.entries(oldEnv)) { + environment._set(key, value) + } + } +} + +export function withEnv(envVars: Partial, f: () => T) { + const cleanup = setEnv(envVars) + const result = f() + if (result instanceof Promise) { + return result.finally(cleanup) + } else { + cleanup() + return result + } +} + function cleanVariables() { // clean up any environment variable edge cases for (let [key, value] of Object.entries(environment)) { diff --git a/packages/server/src/integrations/tests/googlesheets.spec.ts b/packages/server/src/integrations/tests/googlesheets.spec.ts index 9b1ea815f55..e9d5290b2c9 100644 --- a/packages/server/src/integrations/tests/googlesheets.spec.ts +++ b/packages/server/src/integrations/tests/googlesheets.spec.ts @@ -1,3 +1,4 @@ +import { setEnv as setCoreEnv } from "@budibase/backend-core" import type { GoogleSpreadsheetWorksheet } from "google-spreadsheet" import nock from "nock" @@ -40,7 +41,7 @@ describe("Google Sheets Integration", () => { let cleanupEnv: () => void beforeAll(() => { - cleanupEnv = config.setCoreEnv({ + cleanupEnv = setCoreEnv({ GOOGLE_CLIENT_ID: "test", GOOGLE_CLIENT_SECRET: "test", }) diff --git a/packages/server/src/sdk/app/rows/search/tests/search.spec.ts b/packages/server/src/sdk/app/rows/search/tests/search.spec.ts index 47124d6667f..252b9a65565 100644 --- a/packages/server/src/sdk/app/rows/search/tests/search.spec.ts +++ b/packages/server/src/sdk/app/rows/search/tests/search.spec.ts @@ -3,6 +3,10 @@ import { Datasource, FieldType, Row, Table } from "@budibase/types" import TestConfiguration from "../../../../../tests/utilities/TestConfiguration" import { search } from "../../../../../sdk/app/rows/search" import { generator } from "@budibase/backend-core/tests" +import { + withEnv as withCoreEnv, + setEnv as setCoreEnv, +} from "@budibase/backend-core" import { DatabaseName, getDatasource, @@ -31,13 +35,12 @@ describe.each([ let rows: Row[] beforeAll(async () => { - await config.withCoreEnv( - { SQS_SEARCH_ENABLE: isSqs ? "true" : "false" }, - () => config.init() + await withCoreEnv({ SQS_SEARCH_ENABLE: isSqs ? "true" : "false" }, () => + config.init() ) if (isSqs) { - envCleanup = config.setCoreEnv({ + envCleanup = setCoreEnv({ SQS_SEARCH_ENABLE: "true", SQS_SEARCH_ENABLE_TENANTS: [config.getTenantId()], }) diff --git a/packages/server/src/startup/tests/startup.spec.ts b/packages/server/src/startup/tests/startup.spec.ts index fd2e0df61a3..7209033db89 100644 --- a/packages/server/src/startup/tests/startup.spec.ts +++ b/packages/server/src/startup/tests/startup.spec.ts @@ -1,6 +1,12 @@ +import { withEnv } from "../../environment" import TestConfiguration from "../../tests/utilities/TestConfiguration" import { startup } from "../index" -import { users, utils, tenancy } from "@budibase/backend-core" +import { + users, + utils, + tenancy, + withEnv as withCoreEnv, +} from "@budibase/backend-core" import nock from "nock" describe("check BB_ADMIN environment variables", () => { @@ -23,13 +29,13 @@ describe("check BB_ADMIN environment variables", () => { const EMAIL = "budibase@budibase.com", PASSWORD = "budibase" await tenancy.doInTenant(tenancy.DEFAULT_TENANT_ID, async () => { - await config.withEnv( + await withEnv( { MULTI_TENANCY: "0", SELF_HOSTED: "1", }, () => - config.withCoreEnv( + withCoreEnv( { BB_ADMIN_USER_EMAIL: EMAIL, BB_ADMIN_USER_PASSWORD: PASSWORD, diff --git a/packages/server/src/tests/utilities/TestConfiguration.ts b/packages/server/src/tests/utilities/TestConfiguration.ts index 3d53149385d..443d3c6bd9c 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.ts +++ b/packages/server/src/tests/utilities/TestConfiguration.ts @@ -247,65 +247,6 @@ export default class TestConfiguration { } } - async withEnv(newEnvVars: Partial, f: () => Promise) { - let cleanup = this.setEnv(newEnvVars) - try { - return await f() - } finally { - cleanup() - } - } - - /* - * Sets the environment variables to the given values and returns a function - * that can be called to reset the environment variables to their original values. - */ - setEnv(newEnvVars: Partial): () => void { - const oldEnv = cloneDeep(env) - - let key: keyof typeof newEnvVars - for (key in newEnvVars) { - env._set(key, newEnvVars[key]) - } - - return () => { - for (const [key, value] of Object.entries(oldEnv)) { - env._set(key, value) - } - } - } - - async withCoreEnv( - newEnvVars: Partial, - f: () => Promise - ) { - let cleanup = this.setCoreEnv(newEnvVars) - try { - return await f() - } finally { - cleanup() - } - } - - /* - * Sets the environment variables to the given values and returns a function - * that can be called to reset the environment variables to their original values. - */ - setCoreEnv(newEnvVars: Partial): () => void { - const oldEnv = cloneDeep(coreEnv) - - let key: keyof typeof newEnvVars - for (key in newEnvVars) { - coreEnv._set(key, newEnvVars[key]) - } - - return () => { - for (const [key, value] of Object.entries(oldEnv)) { - coreEnv._set(key, value) - } - } - } - async withUser(user: User, f: () => Promise) { const oldUser = this.user this.user = user