diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.ts similarity index 69% rename from packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js rename to packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.ts index 7ea2f8932b..34777b0951 100644 --- a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.ts @@ -1,34 +1,24 @@ -const { Curl } = require("../../curl") -const fs = require("fs") -const path = require("path") +import { Curl } from "../../curl" +import { readFileSync } from "fs" +import { join } from "path" -const getData = file => { - return fs.readFileSync(path.join(__dirname, `./data/${file}.txt`), "utf8") +const getData = (file: string) => { + return readFileSync(join(__dirname, `./data/${file}.txt`), "utf8") } describe("Curl Import", () => { - let curl + let curl: Curl beforeEach(() => { curl = new Curl() }) it("validates unsupported data", async () => { - let data - let supported - - // JSON - data = "{}" - supported = await curl.isSupported(data) - expect(supported).toBe(false) - - // Empty - data = "" - supported = await curl.isSupported(data) - expect(supported).toBe(false) + expect(await curl.isSupported("{}")).toBe(false) + expect(await curl.isSupported("")).toBe(false) }) - const init = async file => { + const init = async (file: string) => { await curl.isSupported(getData(file)) } @@ -39,14 +29,14 @@ describe("Curl Import", () => { }) describe("Returns queries", () => { - const getQueries = async file => { + const getQueries = async (file: string) => { await init(file) - const queries = await curl.getQueries() + const queries = await curl.getQueries("fake_datasource_id") expect(queries.length).toBe(1) return queries } - const testVerb = async (file, verb) => { + const testVerb = async (file: string, verb: string) => { const queries = await getQueries(file) expect(queries[0].queryVerb).toBe(verb) } @@ -59,7 +49,7 @@ describe("Curl Import", () => { await testVerb("patch", "patch") }) - const testPath = async (file, urlPath) => { + const testPath = async (file: string, urlPath: string) => { const queries = await getQueries(file) expect(queries[0].fields.path).toBe(urlPath) } @@ -69,7 +59,10 @@ describe("Curl Import", () => { await testPath("path", "http://example.com/paths/abc") }) - const testHeaders = async (file, headers) => { + const testHeaders = async ( + file: string, + headers: Record + ) => { const queries = await getQueries(file) expect(queries[0].fields.headers).toStrictEqual(headers) } @@ -82,7 +75,7 @@ describe("Curl Import", () => { }) }) - const testQuery = async (file, queryString) => { + const testQuery = async (file: string, queryString: string) => { const queries = await getQueries(file) expect(queries[0].fields.queryString).toBe(queryString) } @@ -91,7 +84,7 @@ describe("Curl Import", () => { await testQuery("query", "q1=v1&q1=v2") }) - const testBody = async (file, body) => { + const testBody = async (file: string, body?: Record) => { const queries = await getQueries(file) expect(queries[0].fields.requestBody).toStrictEqual( JSON.stringify(body, null, 2) diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js deleted file mode 100644 index b61991f7d6..0000000000 --- a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +++ /dev/null @@ -1,243 +0,0 @@ -const { OpenAPI2 } = require("../../openapi2") -const fs = require("fs") -const path = require("path") - -const getData = (file, extension) => { - return fs.readFileSync( - path.join(__dirname, `./data/${file}/${file}.${extension}`), - "utf8" - ) -} - -describe("OpenAPI2 Import", () => { - let openapi2 - - beforeEach(() => { - openapi2 = new OpenAPI2() - }) - - it("validates unsupported data", async () => { - let data - let supported - - // non json / yaml - data = "curl http://example.com" - supported = await openapi2.isSupported(data) - expect(supported).toBe(false) - - // Empty - data = "" - supported = await openapi2.isSupported(data) - expect(supported).toBe(false) - }) - - const init = async (file, extension) => { - await openapi2.isSupported(getData(file, extension)) - } - - const runTests = async (filename, test, assertions) => { - for (let extension of ["json", "yaml"]) { - await test(filename, extension, assertions) - } - } - - const testImportInfo = async (file, extension) => { - await init(file, extension) - const info = await openapi2.getInfo() - expect(info.name).toBe("Swagger Petstore") - } - - it("returns import info", async () => { - await runTests("petstore", testImportInfo) - }) - - describe("Returns queries", () => { - const indexQueries = queries => { - return queries.reduce((acc, query) => { - acc[query.name] = query - return acc - }, {}) - } - - const getQueries = async (file, extension) => { - await init(file, extension) - const queries = await openapi2.getQueries() - expect(queries.length).toBe(6) - return indexQueries(queries) - } - - const testVerb = async (file, extension, assertions) => { - const queries = await getQueries(file, extension) - for (let [operationId, method] of Object.entries(assertions)) { - expect(queries[operationId].queryVerb).toBe(method) - } - } - - it("populates verb", async () => { - const assertions = { - createEntity: "create", - getEntities: "read", - getEntity: "read", - updateEntity: "update", - patchEntity: "patch", - deleteEntity: "delete", - } - await runTests("crud", testVerb, assertions) - }) - - const testPath = async (file, extension, assertions) => { - const queries = await getQueries(file, extension) - for (let [operationId, urlPath] of Object.entries(assertions)) { - expect(queries[operationId].fields.path).toBe(urlPath) - } - } - - it("populates path", async () => { - const assertions = { - createEntity: "http://example.com/entities", - getEntities: "http://example.com/entities", - getEntity: "http://example.com/entities/{{entityId}}", - updateEntity: "http://example.com/entities/{{entityId}}", - patchEntity: "http://example.com/entities/{{entityId}}", - deleteEntity: "http://example.com/entities/{{entityId}}", - } - await runTests("crud", testPath, assertions) - }) - - const testHeaders = async (file, extension, assertions) => { - const queries = await getQueries(file, extension) - for (let [operationId, headers] of Object.entries(assertions)) { - expect(queries[operationId].fields.headers).toStrictEqual(headers) - } - } - - const contentTypeHeader = { - "Content-Type": "application/json", - } - - it("populates headers", async () => { - const assertions = { - createEntity: { - ...contentTypeHeader, - }, - getEntities: {}, - getEntity: {}, - updateEntity: { - ...contentTypeHeader, - }, - patchEntity: { - ...contentTypeHeader, - }, - deleteEntity: { - "x-api-key": "{{x-api-key}}", - }, - } - - await runTests("crud", testHeaders, assertions) - }) - - const testQuery = async (file, extension, assertions) => { - const queries = await getQueries(file, extension) - for (let [operationId, queryString] of Object.entries(assertions)) { - expect(queries[operationId].fields.queryString).toStrictEqual( - queryString - ) - } - } - - it("populates query", async () => { - const assertions = { - createEntity: "", - getEntities: "page={{page}}&size={{size}}", - getEntity: "", - updateEntity: "", - patchEntity: "", - deleteEntity: "", - } - await runTests("crud", testQuery, assertions) - }) - - const testParameters = async (file, extension, assertions) => { - const queries = await getQueries(file, extension) - for (let [operationId, parameters] of Object.entries(assertions)) { - expect(queries[operationId].parameters).toStrictEqual(parameters) - } - } - - it("populates parameters", async () => { - const assertions = { - createEntity: [], - getEntities: [ - { - name: "page", - default: "", - }, - { - name: "size", - default: "", - }, - ], - getEntity: [ - { - name: "entityId", - default: "", - }, - ], - updateEntity: [ - { - name: "entityId", - default: "", - }, - ], - patchEntity: [ - { - name: "entityId", - default: "", - }, - ], - deleteEntity: [ - { - name: "entityId", - default: "", - }, - { - name: "x-api-key", - default: "", - }, - ], - } - await runTests("crud", testParameters, assertions) - }) - - const testBody = async (file, extension, assertions) => { - const queries = await getQueries(file, extension) - for (let [operationId, body] of Object.entries(assertions)) { - expect(queries[operationId].fields.requestBody).toStrictEqual( - JSON.stringify(body, null, 2) - ) - } - } - it("populates body", async () => { - const assertions = { - createEntity: { - name: "name", - type: "type", - }, - getEntities: undefined, - getEntity: undefined, - updateEntity: { - id: 1, - name: "name", - type: "type", - }, - patchEntity: { - id: 1, - name: "name", - type: "type", - }, - deleteEntity: undefined, - } - await runTests("crud", testBody, assertions) - }) - }) -}) diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.ts b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.ts new file mode 100644 index 0000000000..c16b04beb7 --- /dev/null +++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.ts @@ -0,0 +1,135 @@ +import { OpenAPI2 } from "../../openapi2" +import { readFileSync } from "fs" +import { join } from "path" +import { groupBy, mapValues } from "lodash" +import { Query } from "@budibase/types" + +const getData = (file: string, extension: string) => { + return readFileSync( + join(__dirname, `./data/${file}/${file}.${extension}`), + "utf8" + ) +} + +describe("OpenAPI2 Import", () => { + let openapi2: OpenAPI2 + + beforeEach(() => { + openapi2 = new OpenAPI2() + }) + + it("validates unsupported data", async () => { + expect(await openapi2.isSupported("curl http://example.com")).toBe(false) + expect(await openapi2.isSupported("")).toBe(false) + }) + + describe.each(["json", "yaml"])("%s", extension => { + describe("petstore", () => { + beforeEach(async () => { + await openapi2.isSupported(getData("petstore", extension)) + }) + + it("returns import info", async () => { + const { name } = await openapi2.getInfo() + expect(name).toBe("Swagger Petstore") + }) + }) + + describe("crud", () => { + let queries: Record + beforeEach(async () => { + await openapi2.isSupported(getData("crud", extension)) + + const raw = await openapi2.getQueries("fake_datasource_id") + queries = mapValues(groupBy(raw, "name"), group => group[0]) + }) + + it("should have 6 queries", () => { + expect(Object.keys(queries).length).toBe(6) + }) + + it.each([ + ["createEntity", "create"], + ["getEntities", "read"], + ["getEntity", "read"], + ["updateEntity", "update"], + ["patchEntity", "patch"], + ["deleteEntity", "delete"], + ])("should have correct verb for %s", (operationId, method) => { + expect(queries[operationId].queryVerb).toBe(method) + }) + + it.each([ + ["createEntity", "http://example.com/entities"], + ["getEntities", "http://example.com/entities"], + ["getEntity", "http://example.com/entities/{{entityId}}"], + ["updateEntity", "http://example.com/entities/{{entityId}}"], + ["patchEntity", "http://example.com/entities/{{entityId}}"], + ["deleteEntity", "http://example.com/entities/{{entityId}}"], + ])("should have correct path for %s", (operationId, urlPath) => { + expect(queries[operationId].fields.path).toBe(urlPath) + }) + + it.each([ + ["createEntity", { "Content-Type": "application/json" }], + ["getEntities", {}], + ["getEntity", {}], + ["updateEntity", { "Content-Type": "application/json" }], + ["patchEntity", { "Content-Type": "application/json" }], + ["deleteEntity", { "x-api-key": "{{x-api-key}}" }], + ])(`should have correct headers for %s`, (operationId, headers) => { + expect(queries[operationId].fields.headers).toStrictEqual(headers) + }) + + it.each([ + ["createEntity", ""], + ["getEntities", "page={{page}}&size={{size}}"], + ["getEntity", ""], + ["updateEntity", ""], + ["patchEntity", ""], + ["deleteEntity", ""], + ])( + `should have correct query string for %s`, + (operationId, queryString) => { + expect(queries[operationId].fields.queryString).toBe(queryString) + } + ) + + it.each([ + ["createEntity", []], + [ + "getEntities", + [ + { name: "page", default: "" }, + { name: "size", default: "" }, + ], + ], + ["getEntity", [{ name: "entityId", default: "" }]], + ["updateEntity", [{ name: "entityId", default: "" }]], + ["patchEntity", [{ name: "entityId", default: "" }]], + [ + "deleteEntity", + [ + { name: "entityId", default: "" }, + { name: "x-api-key", default: "" }, + ], + ], + ])(`should have correct parameters for %s`, (operationId, parameters) => { + expect(queries[operationId].parameters).toStrictEqual(parameters) + }) + + it.each([ + ["createEntity", { name: "name", type: "type" }], + ["getEntities", undefined], + ["getEntity", undefined], + ["updateEntity", { id: 1, name: "name", type: "type" }], + ["patchEntity", { id: 1, name: "name", type: "type" }], + ["deleteEntity", undefined], + ])(`should have correct body for %s`, (operationId, body) => { + expect(queries[operationId].fields.requestBody).toBe( + JSON.stringify(body, null, 2) + ) + }) + }) + }) +})