De-mock the environment variable tests.

This commit is contained in:
Sam Rose 2025-03-03 09:55:34 +00:00
parent b4ad744261
commit e2e1e9d7d2
No known key found for this signature in database
4 changed files with 155 additions and 142 deletions

View File

@ -1,153 +1,108 @@
const pg = require("pg") const pg = require("pg")
jest.mock("pg", () => { import { structures } from "./utilities"
return {
Client: jest.fn().mockImplementation(() => ({
connect: jest.fn(),
query: jest.fn().mockImplementation(() => ({ rows: [] })),
end: jest.fn().mockImplementation((fn: any) => fn()),
})),
queryMock: jest.fn().mockImplementation(() => {}),
on: jest.fn(),
}
})
import * as setup from "./utilities"
import { mocks } from "@budibase/backend-core/tests" import { mocks } from "@budibase/backend-core/tests"
import { env, events } from "@budibase/backend-core" import { setEnv } from "@budibase/backend-core"
import { QueryPreview } from "@budibase/types" import { Datasource } from "@budibase/types"
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
import {
DatabaseName,
datasourceDescribe,
} from "../../../integrations/tests/utils"
const structures = setup.structures const describes = datasourceDescribe({ only: [DatabaseName.POSTGRES] })
env._set("ENCRYPTION_KEY", "budibase") if (describes.length > 0) {
mocks.licenses.useEnvironmentVariables() describe.each(describes)("/api/env/variables", ({ dsProvider }) => {
const config = new TestConfiguration()
describe("/api/env/variables", () => { let rawDatasource: Datasource
let request = setup.getRequest() let restoreEnv: () => void
let config = setup.getConfig()
afterAll(setup.afterAll) beforeAll(async () => {
await config.init()
restoreEnv = setEnv({ ENCRYPTION_KEY: "budibase" })
mocks.licenses.useEnvironmentVariables()
beforeAll(async () => { const ds = await dsProvider()
await config.init() rawDatasource = ds.rawDatasource!
}) })
it("should be able check the status of env var API", async () => { afterAll(() => {
const res = await request restoreEnv()
.get(`/api/env/variables/status`) })
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.encryptionKeyAvailable).toEqual(true) beforeEach(async () => {
}) const { variables } = await config.api.environment.fetch()
for (const variable of variables) {
it("should be able to create an environment variable", async () => { await config.api.environment.destroy(variable)
await request
.post(`/api/env/variables`)
.send(structures.basicEnvironmentVariable("test", "test"))
.set(config.defaultHeaders())
.expect(200)
})
it("should be able to fetch the 'test' variable name", async () => {
const res = await request
.get(`/api/env/variables`)
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.variables.length).toEqual(1)
expect(res.body.variables[0]).toEqual("test")
})
it("should be able to update the environment variable 'test'", async () => {
const varName = "test"
await request
.patch(`/api/env/variables/${varName}`)
.send(structures.basicEnvironmentVariable("test", "test1"))
.set(config.defaultHeaders())
.expect(200)
})
it("should be able to delete the environment variable 'test'", async () => {
const varName = "test"
await request
.delete(`/api/env/variables/${varName}`)
.set(config.defaultHeaders())
.expect(200)
})
it("should create a datasource (using the environment variable) and query", async () => {
const datasourceBase = structures.basicDatasource()
await request
.post(`/api/env/variables`)
.send(structures.basicEnvironmentVariable("test", "test"))
.set(config.defaultHeaders())
datasourceBase.datasource.config = {
password: "{{ env.test }}",
}
const response = await request
.post(`/api/datasources`)
.send(datasourceBase)
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(response.body.datasource._id).toBeDefined()
const response2 = await request
.post(`/api/queries`)
.send(structures.basicQuery(response.body.datasource._id))
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(response2.body._id).toBeDefined()
})
it("should run a query preview and check the mocked results", async () => {
const datasourceBase = structures.basicDatasource()
await request
.post(`/api/env/variables`)
.send(structures.basicEnvironmentVariable("test", "test"))
.set(config.defaultHeaders())
datasourceBase.datasource.config = {
password: "{{ env.test }}",
}
const response = await request
.post(`/api/datasources`)
.send(datasourceBase)
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(response.body.datasource._id).toBeDefined()
const queryPreview: QueryPreview = {
datasourceId: response.body.datasource._id,
parameters: [],
fields: {},
queryVerb: "read",
name: response.body.datasource.name,
transformer: null,
schema: {},
readable: true,
}
const res = await request
.post(`/api/queries/preview`)
.send(queryPreview)
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.rows.length).toEqual(0)
expect(events.query.previewed).toHaveBeenCalledTimes(1)
// API doesn't include config in response
delete response.body.datasource.config
expect(events.query.previewed).toHaveBeenCalledWith(
response.body.datasource,
{
...queryPreview,
nullDefaultSupport: true,
} }
)
expect(pg.Client).toHaveBeenCalledWith({ password: "test", ssl: undefined }) await config.api.environment.create({
name: "test",
production: rawDatasource.config!.password,
development: rawDatasource.config!.password,
})
})
it("should be able check the status of env var API", async () => {
const { encryptionKeyAvailable } = await config.api.environment.status()
expect(encryptionKeyAvailable).toEqual(true)
})
it("should be able to fetch the 'test' variable name", async () => {
const { variables } = await config.api.environment.fetch()
expect(variables.length).toEqual(1)
expect(variables[0]).toEqual("test")
})
it("should be able to update the environment variable 'test'", async () => {
await config.api.environment.update("test", {
production: "test1",
development: "test1",
})
})
it("should be able to delete the environment variable 'test'", async () => {
await config.api.environment.destroy("test")
})
it("should create a datasource (using the environment variable) and query", async () => {
const datasource = await config.api.datasource.create({
...structures.basicDatasource().datasource,
config: {
...rawDatasource.config,
password: "{{ env.test }}",
},
})
const query = await config.api.query.save({
...structures.basicQuery(datasource._id!),
fields: { sql: "SELECT 1" },
})
expect(query._id).toBeDefined()
})
it("should run a query preview and check the mocked results", async () => {
const datasource = await config.api.datasource.create({
...structures.basicDatasource().datasource,
config: {
...rawDatasource.config,
password: "{{ env.test }}",
},
})
const query = await config.api.query.save({
...structures.basicQuery(datasource._id!),
fields: { sql: "SELECT 1 as id" },
})
const { rows } = await config.api.query.preview({
...query,
queryId: query._id!,
})
expect(rows).toEqual([{ id: 1 }])
})
}) })
}) }

View File

@ -0,0 +1,52 @@
import { Expectations, TestAPI } from "./base"
import {
CreateEnvironmentVariableRequest,
CreateEnvironmentVariableResponse,
GetEnvironmentVariablesResponse,
Row,
StatusEnvironmentVariableResponse,
UpdateEnvironmentVariableRequest,
} from "@budibase/types"
export class EnvironmentAPI extends TestAPI {
create = async (
body: CreateEnvironmentVariableRequest,
expectations?: Expectations
) => {
return await this._post<CreateEnvironmentVariableResponse>(
`/api/env/variables`,
{ body, expectations }
)
}
status = async (expectations?: Expectations) => {
return await this._get<StatusEnvironmentVariableResponse>(
`/api/env/variables/status`,
{ expectations }
)
}
fetch = async (expectations?: Expectations) => {
return await this._get<GetEnvironmentVariablesResponse>(
`/api/env/variables`,
{ expectations }
)
}
update = async (
varName: string,
body: UpdateEnvironmentVariableRequest,
expectations?: Expectations
) => {
return await this._patch<void>(`/api/env/variables/${varName}`, {
body,
expectations,
})
}
destroy = async (varName: string, expectations?: Expectations) => {
return await this._delete<void>(`/api/env/variables/${varName}`, {
expectations,
})
}
}

View File

@ -17,6 +17,7 @@ import { RowActionAPI } from "./rowAction"
import { AutomationAPI } from "./automation" import { AutomationAPI } from "./automation"
import { PluginAPI } from "./plugin" import { PluginAPI } from "./plugin"
import { WebhookAPI } from "./webhook" import { WebhookAPI } from "./webhook"
import { EnvironmentAPI } from "./environment"
export default class API { export default class API {
application: ApplicationAPI application: ApplicationAPI
@ -24,6 +25,7 @@ export default class API {
automation: AutomationAPI automation: AutomationAPI
backup: BackupAPI backup: BackupAPI
datasource: DatasourceAPI datasource: DatasourceAPI
environment: EnvironmentAPI
legacyView: LegacyViewAPI legacyView: LegacyViewAPI
permission: PermissionAPI permission: PermissionAPI
plugin: PluginAPI plugin: PluginAPI
@ -44,6 +46,7 @@ export default class API {
this.automation = new AutomationAPI(config) this.automation = new AutomationAPI(config)
this.backup = new BackupAPI(config) this.backup = new BackupAPI(config)
this.datasource = new DatasourceAPI(config) this.datasource = new DatasourceAPI(config)
this.environment = new EnvironmentAPI(config)
this.legacyView = new LegacyViewAPI(config) this.legacyView = new LegacyViewAPI(config)
this.permission = new PermissionAPI(config) this.permission = new PermissionAPI(config)
this.plugin = new PluginAPI(config) this.plugin = new PluginAPI(config)

View File

@ -37,6 +37,9 @@ import {
DeepPartial, DeepPartial,
FilterCondition, FilterCondition,
AutomationTriggerResult, AutomationTriggerResult,
EnvironmentVariablesDoc,
EnvironmentVariableValue,
CreateEnvironmentVariableRequest,
} from "@budibase/types" } from "@budibase/types"
import { LoopInput } from "../../definitions/automations" import { LoopInput } from "../../definitions/automations"
import { merge } from "lodash" import { merge } from "lodash"
@ -574,7 +577,7 @@ export function basicEnvironmentVariable(
name: string, name: string,
prod: string, prod: string,
dev?: string dev?: string
) { ): CreateEnvironmentVariableRequest {
return { return {
name, name,
production: prod, production: prod,