UNPKG

@budibase/server

Version:
214 lines (179 loc) • 6.87 kB
import nock from "nock" import TestConfiguration from "../../../../src/tests/utilities/TestConfiguration" import { createAutomationBuilder } from "../utilities/AutomationTestBuilder" import * as setup from "../utilities" import { AutomationActionStepId, AutomationStepOutputs, BodyType, PaginationConfig, RestQueryFields, } from "@budibase/types" import { encodeJSBinding } from "@budibase/string-templates" import { environmentVariables } from "@budibase/pro" import { mocks } from "@budibase/backend-core/tests" import { setEnv } from "@budibase/backend-core" describe("API REST request", () => { const config = new TestConfiguration() let envCleanup: () => void beforeAll(async () => { envCleanup = setEnv({ ENCRYPTION_KEY: "some-key", }) await config.init() // No snippet/js support in queries. Snippet support in auto config.app = await config.api.application.update(config.getAppId(), { snippets: [ { name: "tester", code: `return function (test) { return "snippet_" + (test || "no_value") } `, }, ], }) // Init env vars await config.doInTenant(async () => { mocks.licenses.useEnvironmentVariables() // Set some base variables await environmentVariables.update("env-1", { production: "a", development: "b", }) await environmentVariables.update("env-2", { production: "c", development: "d", }) const envKeys = await environmentVariables.fetch() expect(envKeys).toStrictEqual(["env-1", "env-2"]) }) }) afterAll(async () => { envCleanup() config.end() }) beforeEach(() => { nock.cleanAll() }) it("should be able to execute a query and relay the results", async () => { nock("http://myapi.com/api").get("/count").reply(200, { count: 1234 }) const queryFields: RestQueryFields = { disabledHeaders: {}, headers: {}, bodyType: BodyType.NONE, pagination: {} as PaginationConfig, path: "http://myapi.com/api/count", queryString: "", } const restSource = await config.restDatasource() const restQuery = await setup.saveRESTQuery(config, restSource, queryFields) const { steps } = await createAutomationBuilder(config) .onAppAction() .apiRequest({ query: { queryId: restQuery._id! } }) .test({ fields: {} }) const requestStep = steps.find( s => s.stepId === AutomationActionStepId.API_REQUEST ) expect(requestStep).not.toBeUndefined() const requestOutputs: AutomationStepOutputs<AutomationActionStepId.API_REQUEST> = requestStep?.outputs! const response = requestOutputs?.response?.[0] expect(requestOutputs.success).toBe(true) expect(requestOutputs.info.code).toBe(200) expect(response.count).toBe(1234) }) it("should be able to execute an API request with bindings/snippets/env in the query or automation step", async () => { nock("http://myapi.com/api") .get("/count") .query(true) .reply(200, (uri, _body) => { // Intercept the request and query the values as they are used. const url = new URL(`http://myapi.com${uri}`) const qBinding = url.searchParams.get("qBinding") const envQBinding = url.searchParams.get("envQBinding") const autoSnip = url.searchParams.get("autoSnip") const autoEnv = url.searchParams.get("autoEnv") return { qBinding, envQBinding, autoSnip, autoEnv } }) // Snippet values - should be processed in the automation const encodedSnippet = encodeJSBinding("return snippets.tester('running')") // 'Bindings' in the automation UI const parameters = [ { name: "someBinding", default: "hello", }, { name: "envBinding", // The development val of env-2 is used in the test default: "{{ env.env-2 }}", }, ] const queryFields: RestQueryFields = { path: "http://myapi.com/api/count", queryString: `qBinding={{ someBinding }}&envQBinding={{ envBinding }}&autoSnip={{ snip }}&autoEnv={{ autoEnv }}`, } // Build the rest source and query. const restSource = await config.restDatasource() const someQuery = await setup.saveRESTQuery( config, restSource, queryFields, parameters ) // Execute the auto const { steps } = await createAutomationBuilder(config) .onAppAction() .apiRequest({ query: { queryId: someQuery._id!, snip: encodedSnippet, someBinding: "replaced", autoEnv: "{{ env.env-1 }}", }, }) .test({ fields: {} }) // Confirm snippets are running. const [queryStep] = steps expect(queryStep?.inputs?.query?.snip).toBe("snippet_running") const requestStep = steps.find( s => s.stepId === AutomationActionStepId.API_REQUEST ) const requestOutputs: AutomationStepOutputs<AutomationActionStepId.API_REQUEST> = requestStep?.outputs! const response = requestOutputs?.response?.[0] // The value set in the automation should should be passed to the query. expect(response.qBinding).toBe("replaced") // The env variable configured in the query should be processed expect(response.envQBinding).toBe("d") // The snippet should have been processed in the automation and the result relayed. expect(response.autoSnip).toBe("snippet_running") // Env vars should have resolved in the auto and been relayed expect(response.autoEnv).toBe("b") }) // Legacy - the old Execute query step doesn't have any tests for the REST datasource type // This ensures that old steps configured in this way still run without issue. it("should be able to execute a query and relay the results - for the old execute query steps", async () => { nock("http://myapi.com/api").get("/count").reply(200, { count: 1234 }) const queryFields: RestQueryFields = { path: "http://myapi.com/api/count", } const restSource = await config.restDatasource() const restQuery = await setup.saveRESTQuery(config, restSource, queryFields) const { steps } = await createAutomationBuilder(config) .onAppAction() .executeQuery({ query: { queryId: restQuery._id! } }) // Main difference .test({ fields: {} }) const requestStep = steps.find( s => s.stepId === AutomationActionStepId.EXECUTE_QUERY ) expect(requestStep).not.toBeUndefined() const requestOutputs: AutomationStepOutputs<AutomationActionStepId.EXECUTE_QUERY> = requestStep?.outputs! const response = requestOutputs?.response?.[0] expect(requestOutputs.success).toBe(true) expect(requestOutputs.info.code).toBe(200) expect(response.count).toBe(1234) }) })