From fe17abd7be9321e3d1ab05c865d816f0bde22bcf Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Thu, 6 Apr 2023 14:22:21 +0100 Subject: [PATCH 1/8] Add postgresSQL tests --- .../internal-api/api/BudibaseInternalAPI.ts | 3 + qa-core/src/internal-api/api/apis/AppAPI.ts | 1 + .../internal-api/api/apis/DatasourcesAPI.ts | 87 +++++++++++++++++++ .../src/internal-api/fixtures/datasources.ts | 37 ++++++++ qa-core/src/internal-api/fixtures/index.ts | 1 + .../tests/dataSources/postgresSQL.spec.ts | 60 +++++++++++++ qa-core/src/types/addedDatasource.ts | 5 ++ qa-core/src/types/index.ts | 1 + 8 files changed, 195 insertions(+) create mode 100644 qa-core/src/internal-api/api/apis/DatasourcesAPI.ts create mode 100644 qa-core/src/internal-api/fixtures/datasources.ts create mode 100644 qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts create mode 100644 qa-core/src/types/addedDatasource.ts diff --git a/qa-core/src/internal-api/api/BudibaseInternalAPI.ts b/qa-core/src/internal-api/api/BudibaseInternalAPI.ts index 5bb6b72ef0..4796799396 100644 --- a/qa-core/src/internal-api/api/BudibaseInternalAPI.ts +++ b/qa-core/src/internal-api/api/BudibaseInternalAPI.ts @@ -7,6 +7,7 @@ import ScreenAPI from "./apis/ScreenAPI" import SelfAPI from "./apis/SelfAPI" import TableAPI from "./apis/TableAPI" import UserAPI from "./apis/UserAPI" +import DatasourcesAPI from "./apis/DatasourcesAPI" import BudibaseInternalAPIClient from "./BudibaseInternalAPIClient" import { State } from "../../types" @@ -22,6 +23,7 @@ export default class BudibaseInternalAPI { self: SelfAPI tables: TableAPI users: UserAPI + datasources: DatasourcesAPI constructor(state: State) { this.client = new BudibaseInternalAPIClient(state) @@ -35,5 +37,6 @@ export default class BudibaseInternalAPI { this.self = new SelfAPI(this.client) this.tables = new TableAPI(this.client) this.users = new UserAPI(this.client) + this.datasources = new DatasourcesAPI(this.client) } } diff --git a/qa-core/src/internal-api/api/apis/AppAPI.ts b/qa-core/src/internal-api/api/apis/AppAPI.ts index 992728899e..bdbf5ba85d 100644 --- a/qa-core/src/internal-api/api/apis/AppAPI.ts +++ b/qa-core/src/internal-api/api/apis/AppAPI.ts @@ -60,6 +60,7 @@ export default class AppAPI { const [response, json] = await this.client.post(`/applications`, { body }) expect(response).toHaveStatusCode(200) expect(json._id).toBeDefined() + this.client.state.appId = json._id return json } diff --git a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts new file mode 100644 index 0000000000..15215b7ba4 --- /dev/null +++ b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts @@ -0,0 +1,87 @@ +import { Response } from "node-fetch" +import { Datasource } from "@budibase/types" +import { AddedDatasource } from "../../../types" +import BudibaseInternalAPIClient from "../BudibaseInternalAPIClient" + +export default class DatasourcesAPI { + client: BudibaseInternalAPIClient + + constructor(client: BudibaseInternalAPIClient) { + this.client = client + } + + async getIntegrations(): Promise<[Response, any]> { + const [response, json] = await this.client.get(`/integrations`) + expect(response).toHaveStatusCode(200) + const integrationsCount = Object.keys(json).length + expect(integrationsCount).toBe(16) + return [response, json] + } + + async getAll(): Promise<[Response, Datasource[]]> { + const [response, json] = await this.client.get(`/datasources`) + expect(response).toHaveStatusCode(200) + expect(json.length).toBeGreaterThan(0) + return [response, json] + } + + async getTable(dataSourceId: string): Promise<[Response, Datasource]> { + const [response, json] = await this.client.get( + `/datasources/${dataSourceId}` + ) + expect(response).toHaveStatusCode(200) + expect(json._id).toEqual(dataSourceId) + return [response, json] + } + + async add(body: any): Promise<[Response, AddedDatasource]> { + //temporarily using a hard coded datasource to test 500 error + const [response, json] = await this.client.post(`/datasources`, { body }) + expect(response).toHaveStatusCode(200) + expect(json.datasource._id).toBeDefined() + expect(json.datasource._rev).toBeDefined() + + return [response, json] + } + + async update(body: any): Promise<[Response, AddedDatasource]> { + const [response, json] = await this.client.put(`/datasources/${body._id}`, { + body, + }) + expect(response).toHaveStatusCode(200) + expect(json.datasource._id).toBeDefined() + expect(json.datasource._rev).toBeDefined() + + return [response, json] + } + + async previewQuery(body: any): Promise<[Response, any]> { + const [response, json] = await this.client.post(`/queries/preview`, { + body, + }) + expect(response).toHaveStatusCode(200) + return [response, json] + } + + async saveQuery(body: any): Promise<[Response, any]> { + const [response, json] = await this.client.post(`/queries`, { + body, + }) + expect(response).toHaveStatusCode(200) + return [response, json] + } + + async getQuery(queryId: string): Promise<[Response, any]> { + const [response, json] = await this.client.get(`/queries/${queryId}`) + expect(response).toHaveStatusCode(200) + return [response, json] + } + + async delete(dataSourceId: string, revId: string): Promise { + const [response, json] = await this.client.del( + `/datasources/${dataSourceId}/${revId}` + ) + expect(response).toHaveStatusCode(200) + return response + } +} diff --git a/qa-core/src/internal-api/fixtures/datasources.ts b/qa-core/src/internal-api/fixtures/datasources.ts new file mode 100644 index 0000000000..feb51add32 --- /dev/null +++ b/qa-core/src/internal-api/fixtures/datasources.ts @@ -0,0 +1,37 @@ +// Add information about the data source to the fixtures file from 1password + +export const mongoDB = () => { + return { + datasource: { + name: "MongoDB", + source: "MONGODB", + type: "datasource", + config: { + connectionString: "", + db: "", + }, + }, + + fetchSchema: false, + } +} + +export const postgresSQL = () => { + return { + datasource: { + name: "PostgresSQL", + plus: true, + source: "POSTGRES", + type: "datasource", + config: { + database: "", + host: "", + password: "", + port: 1111, + schema: "public", + user: "", + }, + }, + fetchSchema: true, + } +} diff --git a/qa-core/src/internal-api/fixtures/index.ts b/qa-core/src/internal-api/fixtures/index.ts index d97c5f76b7..880ff8d3d9 100644 --- a/qa-core/src/internal-api/fixtures/index.ts +++ b/qa-core/src/internal-api/fixtures/index.ts @@ -4,3 +4,4 @@ export * as rows from "./rows" export * as screens from "./screens" export * as tables from "./tables" export * as users from "./users" +export * as datasources from "./datasources" diff --git a/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts b/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts new file mode 100644 index 0000000000..b244cbde4b --- /dev/null +++ b/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts @@ -0,0 +1,60 @@ +import TestConfiguration from "../../config/TestConfiguration" +import * as fixtures from "../../fixtures" + +describe("Internal API - Data Sources: PostgresSQL", () => { + const config = new TestConfiguration() + + beforeAll(async () => { + await config.beforeAll() + }) + + afterAll(async () => { + await config.afterAll() + }) + + it("Create an app with a data source - PostgresSQL", async () => { + // Create app + const app = await config.api.apps.create({ + ...fixtures.apps.generateApp(), + useTemplate: "false", + }) + + // Add data source + const [dataSourceResponse, dataSourceJson] = + await config.api.datasources.add(fixtures.datasources.postgresSQL()) + const newDataSourceInfo = { + ...dataSourceJson.datasource, + name: "PostgresSQL2", + } + const [updatedDataSourceResponse, updatedDataSourceJson] = + await config.api.datasources.update(newDataSourceInfo) + + const dataSourceQuery = { + datasourceId: updatedDataSourceJson.datasource._id, + fields: { + sql: "SELECT * FROM categories;", + }, + name: "Query 1", + parameters: {}, + queryVerb: "read", + schema: {}, + transformer: "return data", + } + // Query data source + + const [queryResponse, queryJson] = + await config.api.datasources.previewQuery(dataSourceQuery) + + // Save query + const [saveQueryResponse, saveQueryJson] = + await config.api.datasources.saveQuery(dataSourceQuery) + // Get Query + const [getQueryResponse, getQueryJson] = + await config.api.datasources.getQuery(saveQueryJson._id) + // Delete data source + const deleteResponse = await config.api.datasources.delete( + updatedDataSourceJson.datasource._id, + updatedDataSourceJson.datasource._rev + ) + }) +}) diff --git a/qa-core/src/types/addedDatasource.ts b/qa-core/src/types/addedDatasource.ts new file mode 100644 index 0000000000..65f51fd1bd --- /dev/null +++ b/qa-core/src/types/addedDatasource.ts @@ -0,0 +1,5 @@ +import { Datasource } from "@budibase/types" + +export interface AddedDatasource { + datasource: Datasource +} diff --git a/qa-core/src/types/index.ts b/qa-core/src/types/index.ts index bc75da46f8..6c3740200c 100644 --- a/qa-core/src/types/index.ts +++ b/qa-core/src/types/index.ts @@ -8,6 +8,7 @@ export * from "./responseMessage" export * from "./routing" export * from "./state" export * from "./unpublishAppResponse" +export * from "./addedDatasource" // re-export public api types export * from "@budibase/server/api/controllers/public/mapping/types" From 0562cf511c28968e0b994702193c2b76c3d0539d Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Tue, 11 Apr 2023 15:44:00 +0100 Subject: [PATCH 2/8] Add tests for datasources --- qa-core/src/internal-api/api/apis/AppAPI.ts | 1 - .../internal-api/api/apis/DatasourcesAPI.ts | 7 +- .../src/internal-api/fixtures/datasources.ts | 36 +++++++-- .../tests/dataSources/example.spec.ts | 27 ------- .../tests/dataSources/mariaDB.spec.ts | 71 ++++++++++++++++++ .../tests/dataSources/mongoDB.spec.ts | 75 +++++++++++++++++++ .../tests/dataSources/postgresSQL.spec.ts | 21 ++++-- 7 files changed, 196 insertions(+), 42 deletions(-) delete mode 100644 qa-core/src/internal-api/tests/dataSources/example.spec.ts create mode 100644 qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts create mode 100644 qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts diff --git a/qa-core/src/internal-api/api/apis/AppAPI.ts b/qa-core/src/internal-api/api/apis/AppAPI.ts index bdbf5ba85d..992728899e 100644 --- a/qa-core/src/internal-api/api/apis/AppAPI.ts +++ b/qa-core/src/internal-api/api/apis/AppAPI.ts @@ -60,7 +60,6 @@ export default class AppAPI { const [response, json] = await this.client.post(`/applications`, { body }) expect(response).toHaveStatusCode(200) expect(json._id).toBeDefined() - this.client.state.appId = json._id return json } diff --git a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts index 15215b7ba4..f61692b02f 100644 --- a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts +++ b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts @@ -35,7 +35,6 @@ export default class DatasourcesAPI { } async add(body: any): Promise<[Response, AddedDatasource]> { - //temporarily using a hard coded datasource to test 500 error const [response, json] = await this.client.post(`/datasources`, { body }) expect(response).toHaveStatusCode(200) expect(json.datasource._id).toBeDefined() @@ -77,6 +76,12 @@ export default class DatasourcesAPI { return [response, json] } + async getQueryPermissions(queryId: string): Promise<[Response, any]> { + const [response, json] = await this.client.get(`/permissions/${queryId}`) + expect(response).toHaveStatusCode(200) + return [response, json] + } + async delete(dataSourceId: string, revId: string): Promise { const [response, json] = await this.client.del( `/datasources/${dataSourceId}/${revId}` diff --git a/qa-core/src/internal-api/fixtures/datasources.ts b/qa-core/src/internal-api/fixtures/datasources.ts index feb51add32..a8d59b88a1 100644 --- a/qa-core/src/internal-api/fixtures/datasources.ts +++ b/qa-core/src/internal-api/fixtures/datasources.ts @@ -1,5 +1,4 @@ // Add information about the data source to the fixtures file from 1password - export const mongoDB = () => { return { datasource: { @@ -7,8 +6,8 @@ export const mongoDB = () => { source: "MONGODB", type: "datasource", config: { - connectionString: "", - db: "", + connectionString: process.env.MONGODB_CONNECTION_STRING, + db: process.env.MONGODB_DB, }, }, @@ -24,12 +23,33 @@ export const postgresSQL = () => { source: "POSTGRES", type: "datasource", config: { - database: "", - host: "", - password: "", - port: 1111, + database: process.env.POSTGRES_DB, + host: process.env.POSTGRES_HOST, + password: process.env.POSTGRES_PASSWORD, + port: process.env.POSTGRES_PORT, schema: "public", - user: "", + user: process.env.POSTGRES_USER, + }, + }, + fetchSchema: true, + } +} + +// Add the data source for MariaDB to the this file in the same style as above +export const mariaDB = () => { + return { + datasource: { + name: "MariaDB", + plus: true, + source: "MYSQL", + type: "datasource", + config: { + database: process.env.MARIADB_DB, + host: process.env.MARIADB_HOST, + password: process.env.MARIADB_PASSWORD, + port: process.env.MARIADB_PORT, + schema: "public", + user: process.env.MARIADB_USER, }, }, fetchSchema: true, diff --git a/qa-core/src/internal-api/tests/dataSources/example.spec.ts b/qa-core/src/internal-api/tests/dataSources/example.spec.ts deleted file mode 100644 index 0b8bc38a45..0000000000 --- a/qa-core/src/internal-api/tests/dataSources/example.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import TestConfiguration from "../../config/TestConfiguration" -import * as fixtures from "../../fixtures" - -describe("Internal API - Data Sources", () => { - const config = new TestConfiguration() - - beforeAll(async () => { - await config.beforeAll() - }) - - afterAll(async () => { - await config.afterAll() - }) - - it("Create an app with a data source", async () => { - // Create app - await config.createApp() - - // Create Screen - const roleArray = ["BASIC", "POWER", "ADMIN", "PUBLIC"] - for (let role in roleArray) { - const [response, screen] = await config.api.screens.create( - fixtures.screens.generateScreen(roleArray[role]) - ) - } - }) -}) diff --git a/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts b/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts new file mode 100644 index 0000000000..4ff9a7cd0a --- /dev/null +++ b/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts @@ -0,0 +1,71 @@ +import TestConfiguration from "../../config/TestConfiguration" +import * as fixtures from "../../fixtures" + +describe("Internal API - Data Sources: MariaDB", () => { + const config = new TestConfiguration() + + beforeAll(async () => { + await config.beforeAll() + }) + + afterAll(async () => { + await config.afterAll() + }) + + it("Create an app with a data source - MariaDB", async () => { + // Create app + await config.createApp() + + // Add data source + const [dataSourceResponse, dataSourceJson] = + await config.api.datasources.add(fixtures.datasources.mariaDB()) + + // Update data source + const newDataSourceInfo = { + ...dataSourceJson.datasource, + name: "MariaDB2", + } + const [updatedDataSourceResponse, updatedDataSourceJson] = + await config.api.datasources.update(newDataSourceInfo) + + const dataSourceQuery = { + datasourceId: updatedDataSourceJson.datasource._id, + fields: { + sql: "SELECT * FROM employees;", + }, + name: "Query 1", + parameters: {}, + queryVerb: "read", + schema: {}, + transformer: "return data", + } + // Query data source + + const [queryResponse, queryJson] = + await config.api.datasources.previewQuery(dataSourceQuery) + + // Save query + const datasourcetoSave = { + ...dataSourceQuery, + parameters: [], + } + + const [saveQueryResponse, saveQueryJson] = + await config.api.datasources.saveQuery(datasourcetoSave) + // Get Query + const [getQueryResponse, getQueryJson] = + await config.api.datasources.getQuery(saveQueryJson._id) + + // Get Query permissions + const [getQueryPermissionsResponse, getQueryPermissionsJson] = + await config.api.datasources.getQueryPermissions( + saveQueryJson._id + ) + + // Delete data source + const deleteResponse = await config.api.datasources.delete( + updatedDataSourceJson.datasource._id, + updatedDataSourceJson.datasource._rev + ) + }) +}) diff --git a/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts b/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts new file mode 100644 index 0000000000..6c57467930 --- /dev/null +++ b/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts @@ -0,0 +1,75 @@ +import TestConfiguration from "../../config/TestConfiguration" +import * as fixtures from "../../fixtures" + +describe("Internal API - Data Sources: MongoDB", () => { + const config = new TestConfiguration() + + beforeAll(async () => { + await config.beforeAll() + }) + + afterAll(async () => { + await config.afterAll() + }) + + it("Create an app with a data source - MongoDB", async () => { + // Create app + await config.createApp() + + // Add data source + const [dataSourceResponse, dataSourceJson] = + await config.api.datasources.add(fixtures.datasources.mongoDB()) + + // Update data source + const newDataSourceInfo = { + ...dataSourceJson.datasource, + name: "MongoDB2", + } + const [updatedDataSourceResponse, updatedDataSourceJson] = + await config.api.datasources.update(newDataSourceInfo) + + const dataSourceQuery = { + datasourceId: updatedDataSourceJson.datasource._id, + fields: { + extra: { + collection: "movies", + actionType: "find", + }, + json: "", + }, + name: "Test Query", + parameters: {}, + queryVerb: "read", + schema: {}, + transformer: "return data", + } + // Query data source + + const [queryResponse, queryJson] = + await config.api.datasources.previewQuery(dataSourceQuery) + + // Save query + const datasourcetoSave = { + ...dataSourceQuery, + parameters: [], + } + + const [saveQueryResponse, saveQueryJson] = + await config.api.datasources.saveQuery(datasourcetoSave) + // Get Query + const [getQueryResponse, getQueryJson] = + await config.api.datasources.getQuery(saveQueryJson._id) + + // Get Query permissions + const [getQueryPermissionsResponse, getQueryPermissionsJson] = + await config.api.datasources.getQueryPermissions( + saveQueryJson._id + ) + + // Delete data source + const deleteResponse = await config.api.datasources.delete( + updatedDataSourceJson.datasource._id, + updatedDataSourceJson.datasource._rev + ) + }) +}) diff --git a/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts b/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts index b244cbde4b..83d1fc782d 100644 --- a/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts +++ b/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts @@ -14,14 +14,13 @@ describe("Internal API - Data Sources: PostgresSQL", () => { it("Create an app with a data source - PostgresSQL", async () => { // Create app - const app = await config.api.apps.create({ - ...fixtures.apps.generateApp(), - useTemplate: "false", - }) + await config.createApp() // Add data source const [dataSourceResponse, dataSourceJson] = await config.api.datasources.add(fixtures.datasources.postgresSQL()) + + // Update data source const newDataSourceInfo = { ...dataSourceJson.datasource, name: "PostgresSQL2", @@ -46,11 +45,23 @@ describe("Internal API - Data Sources: PostgresSQL", () => { await config.api.datasources.previewQuery(dataSourceQuery) // Save query + const datasourcetoSave = { + ...dataSourceQuery, + parameters: [], + } + const [saveQueryResponse, saveQueryJson] = - await config.api.datasources.saveQuery(dataSourceQuery) + await config.api.datasources.saveQuery(datasourcetoSave) // Get Query const [getQueryResponse, getQueryJson] = await config.api.datasources.getQuery(saveQueryJson._id) + + // Get Query permissions + const [getQueryPermissionsResponse, getQueryPermissionsJson] = + await config.api.datasources.getQueryPermissions( + saveQueryJson._id + ) + // Delete data source const deleteResponse = await config.api.datasources.delete( updatedDataSourceJson.datasource._id, From a8460169d12c4b8786186096198512b40a5f5161 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Wed, 12 Apr 2023 18:18:28 +0100 Subject: [PATCH 3/8] Improvements on types, helpers and assertions --- .../types/src/documents/app/datasource.ts | 8 ++ packages/types/src/documents/app/query.ts | 4 + qa-core/src/environment.ts | 14 ++++ .../internal-api/api/BudibaseInternalAPI.ts | 9 +++ .../internal-api/api/apis/DatasourcesAPI.ts | 11 ++- .../internal-api/api/apis/IntegrationsAPI.ts | 18 +++++ .../internal-api/api/apis/PermissionsAPI.ts | 16 ++++ .../src/internal-api/api/apis/QueriesAPI.ts | 33 ++++++++ qa-core/src/internal-api/fixtures/index.ts | 1 + qa-core/src/internal-api/fixtures/queries.ts | 75 +++++++++++++++++++ .../tests/dataSources/mariaDB.spec.ts | 46 ++++++------ .../tests/dataSources/mongoDB.spec.ts | 50 ++++++------- .../tests/dataSources/postgresSQL.spec.ts | 46 ++++++------ qa-core/src/types/addedDatasource.ts | 5 -- 14 files changed, 251 insertions(+), 85 deletions(-) create mode 100644 qa-core/src/internal-api/api/apis/IntegrationsAPI.ts create mode 100644 qa-core/src/internal-api/api/apis/PermissionsAPI.ts create mode 100644 qa-core/src/internal-api/api/apis/QueriesAPI.ts create mode 100644 qa-core/src/internal-api/fixtures/queries.ts delete mode 100644 qa-core/src/types/addedDatasource.ts diff --git a/packages/types/src/documents/app/datasource.ts b/packages/types/src/documents/app/datasource.ts index 8dfdfe6d0f..9b498fb4b3 100644 --- a/packages/types/src/documents/app/datasource.ts +++ b/packages/types/src/documents/app/datasource.ts @@ -56,3 +56,11 @@ export interface RestConfig { } ] } + +export interface CreateDatasourceResponse { + datasource: Datasource +} + +export interface UpdatedDatasourceResponse { + datasource: Datasource +} diff --git a/packages/types/src/documents/app/query.ts b/packages/types/src/documents/app/query.ts index 72b6c288a5..d0bbf05b5c 100644 --- a/packages/types/src/documents/app/query.ts +++ b/packages/types/src/documents/app/query.ts @@ -42,3 +42,7 @@ export interface PaginationValues { page: string | number | null limit: number | null } + +export interface PreviewQueryRequest extends Omit { + parameters: {} +} diff --git a/qa-core/src/environment.ts b/qa-core/src/environment.ts index 9377461a24..262f5505df 100644 --- a/qa-core/src/environment.ts +++ b/qa-core/src/environment.ts @@ -13,6 +13,20 @@ const env = { ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL, BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL, BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD, + POSTGRES_HOST: process.env.POSTGRES_HOST, + POSTGRES_PORT: process.env.POSTGRES_PORT, + POSTGRES_DB: process.env.POSTGRES_DB, + POSTGRES_USER: process.env.POSTGRES_USER, + POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD, + MONGODB_CONNECTION_STRING: process.env.MONGODB_CONNECTION_STRING, + MONGODB_DB: process.env.MONGODB_DB, + REST_API_BASE_URL: process.env.REST_API_BASE_URL, + REST_API_KEY: process.env.REST_API_KEY, + MARIADB_HOST: process.env.MARIADB_HOST, + MARIADB_PORT: process.env.MARIADB_PORT, + MARIADB_DB: process.env.MARIADB_DB, + MARIADB_USER: process.env.MARIADB_USER, + MARIADB_PASSWORD: process.env.MARIADB_PASSWORD, } export = env diff --git a/qa-core/src/internal-api/api/BudibaseInternalAPI.ts b/qa-core/src/internal-api/api/BudibaseInternalAPI.ts index 4796799396..316775b1b9 100644 --- a/qa-core/src/internal-api/api/BudibaseInternalAPI.ts +++ b/qa-core/src/internal-api/api/BudibaseInternalAPI.ts @@ -8,6 +8,9 @@ import SelfAPI from "./apis/SelfAPI" import TableAPI from "./apis/TableAPI" import UserAPI from "./apis/UserAPI" import DatasourcesAPI from "./apis/DatasourcesAPI" +import IntegrationsAPI from "./apis/IntegrationsAPI" +import QueriesAPI from "./apis/QueriesAPI" +import PermissionsAPI from "./apis/PermissionsAPI" import BudibaseInternalAPIClient from "./BudibaseInternalAPIClient" import { State } from "../../types" @@ -24,6 +27,9 @@ export default class BudibaseInternalAPI { tables: TableAPI users: UserAPI datasources: DatasourcesAPI + integrations: IntegrationsAPI + queries: QueriesAPI + permissions: PermissionsAPI constructor(state: State) { this.client = new BudibaseInternalAPIClient(state) @@ -38,5 +44,8 @@ export default class BudibaseInternalAPI { this.tables = new TableAPI(this.client) this.users = new UserAPI(this.client) this.datasources = new DatasourcesAPI(this.client) + this.integrations = new IntegrationsAPI(this.client) + this.queries = new QueriesAPI(this.client) + this.permissions = new PermissionsAPI(this.client) } } diff --git a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts index f61692b02f..7b9d7af789 100644 --- a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts +++ b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts @@ -1,6 +1,9 @@ import { Response } from "node-fetch" -import { Datasource } from "@budibase/types" -import { AddedDatasource } from "../../../types" +import { + Datasource, + CreateDatasourceResponse, + UpdatedDatasourceResponse, +} from "@budibase/types" import BudibaseInternalAPIClient from "../BudibaseInternalAPIClient" export default class DatasourcesAPI { @@ -34,7 +37,7 @@ export default class DatasourcesAPI { return [response, json] } - async add(body: any): Promise<[Response, AddedDatasource]> { + async add(body: any): Promise<[Response, CreateDatasourceResponse]> { const [response, json] = await this.client.post(`/datasources`, { body }) expect(response).toHaveStatusCode(200) expect(json.datasource._id).toBeDefined() @@ -43,7 +46,7 @@ export default class DatasourcesAPI { return [response, json] } - async update(body: any): Promise<[Response, AddedDatasource]> { + async update(body: any): Promise<[Response, UpdatedDatasourceResponse]> { const [response, json] = await this.client.put(`/datasources/${body._id}`, { body, }) diff --git a/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts b/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts new file mode 100644 index 0000000000..b42b999825 --- /dev/null +++ b/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts @@ -0,0 +1,18 @@ +import { Response } from "node-fetch" +import BudibaseInternalAPIClient from "../BudibaseInternalAPIClient" + +export default class IntegrationsAPI { + client: BudibaseInternalAPIClient + + constructor(client: BudibaseInternalAPIClient) { + this.client = client + } + + async getAll(): Promise<[Response, any]> { + const [response, json] = await this.client.get(`/integrations`) + expect(response).toHaveStatusCode(200) + const integrationsCount = Object.keys(json).length + expect(integrationsCount).toBe(16) + return [response, json] + } +} diff --git a/qa-core/src/internal-api/api/apis/PermissionsAPI.ts b/qa-core/src/internal-api/api/apis/PermissionsAPI.ts new file mode 100644 index 0000000000..e78ef7560d --- /dev/null +++ b/qa-core/src/internal-api/api/apis/PermissionsAPI.ts @@ -0,0 +1,16 @@ +import { Response } from "node-fetch" +import BudibaseInternalAPIClient from "../BudibaseInternalAPIClient" + +export default class PermissionsAPI { + client: BudibaseInternalAPIClient + + constructor(client: BudibaseInternalAPIClient) { + this.client = client + } + + async getAll(id: string): Promise<[Response, any]> { + const [response, json] = await this.client.get(`/permissions/${id}`) + expect(response).toHaveStatusCode(200) + return [response, json] + } +} diff --git a/qa-core/src/internal-api/api/apis/QueriesAPI.ts b/qa-core/src/internal-api/api/apis/QueriesAPI.ts new file mode 100644 index 0000000000..5c8ac9883e --- /dev/null +++ b/qa-core/src/internal-api/api/apis/QueriesAPI.ts @@ -0,0 +1,33 @@ +import { Response } from "node-fetch" +import BudibaseInternalAPIClient from "../BudibaseInternalAPIClient" +import { PreviewQueryRequest, Query } from "@budibase/types" + +export default class DatasourcesAPI { + client: BudibaseInternalAPIClient + + constructor(client: BudibaseInternalAPIClient) { + this.client = client + } + + async preview(body: PreviewQueryRequest): Promise<[Response, any]> { + const [response, json] = await this.client.post(`/queries/preview`, { + body, + }) + expect(response).toHaveStatusCode(200) + return [response, json] + } + + async save(body: Query): Promise<[Response, any]> { + const [response, json] = await this.client.post(`/queries`, { + body, + }) + expect(response).toHaveStatusCode(200) + return [response, json] + } + + async get(queryId: string): Promise<[Response, any]> { + const [response, json] = await this.client.get(`/queries/${queryId}`) + expect(response).toHaveStatusCode(200) + return [response, json] + } +} diff --git a/qa-core/src/internal-api/fixtures/index.ts b/qa-core/src/internal-api/fixtures/index.ts index 880ff8d3d9..38291052b8 100644 --- a/qa-core/src/internal-api/fixtures/index.ts +++ b/qa-core/src/internal-api/fixtures/index.ts @@ -5,3 +5,4 @@ export * as screens from "./screens" export * as tables from "./tables" export * as users from "./users" export * as datasources from "./datasources" +export * as queries from "./queries" diff --git a/qa-core/src/internal-api/fixtures/queries.ts b/qa-core/src/internal-api/fixtures/queries.ts new file mode 100644 index 0000000000..7ba81fc744 --- /dev/null +++ b/qa-core/src/internal-api/fixtures/queries.ts @@ -0,0 +1,75 @@ +import { PreviewQueryRequest } from "@budibase/types" + +const query = (datasourceId: string, fields: any): any => { + return { + datasourceId: datasourceId, + fields: fields, + name: "Query 1", + parameters: {}, + queryVerb: "read", + schema: {}, + transformer: "return data", + } +} + +export const mariaDB = (datasourceId: string): PreviewQueryRequest => { + const fields = { + sql: "SELECT * FROM employees LIMIT 10;", + } + return query(datasourceId, fields) +} + +export const mongoDB = (datasourceId: string): PreviewQueryRequest => { + const fields = { + extra: { + collection: "movies", + actionType: "find", + }, + json: "", + } + return query(datasourceId, fields) +} + +export const postgres = (datasourceId: string): PreviewQueryRequest => { + const fields = { + sql: "SELECT * FROM customers;", + } + return query(datasourceId, fields) +} + +export const expectedSchemaFields = { + mariaDB: { + birth_date: "string", + emp_no: "number", + first_name: "string", + gender: "string", + hire_date: "string", + last_name: "string", + }, + mongoDB: { + directors: "array", + genres: "array", + image: "string", + plot: "string", + rank: "number", + rating: "number", + release_date: "string", + running_time_secs: "number", + title: "string", + year: "number", + _id: "json", + }, + postgres: { + address: "string", + city: "string", + company_name: "string", + contact_name: "string", + contact_title: "string", + country: "string", + customer_id: "string", + fax: "string", + phone: "string", + postal_code: "string", + region: "string", + }, +} diff --git a/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts b/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts index 4ff9a7cd0a..44c2c03c8b 100644 --- a/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts +++ b/qa-core/src/internal-api/tests/dataSources/mariaDB.spec.ts @@ -1,5 +1,6 @@ import TestConfiguration from "../../config/TestConfiguration" import * as fixtures from "../../fixtures" +import { Query } from "@budibase/types" describe("Internal API - Data Sources: MariaDB", () => { const config = new TestConfiguration() @@ -16,6 +17,9 @@ describe("Internal API - Data Sources: MariaDB", () => { // Create app await config.createApp() + // Get all integrations + await config.api.integrations.getAll() + // Add data source const [dataSourceResponse, dataSourceJson] = await config.api.datasources.add(fixtures.datasources.mariaDB()) @@ -28,44 +32,38 @@ describe("Internal API - Data Sources: MariaDB", () => { const [updatedDataSourceResponse, updatedDataSourceJson] = await config.api.datasources.update(newDataSourceInfo) - const dataSourceQuery = { - datasourceId: updatedDataSourceJson.datasource._id, - fields: { - sql: "SELECT * FROM employees;", - }, - name: "Query 1", - parameters: {}, - queryVerb: "read", - schema: {}, - transformer: "return data", - } // Query data source + const [queryResponse, queryJson] = await config.api.queries.preview( + fixtures.queries.mariaDB(updatedDataSourceJson.datasource._id!) + ) - const [queryResponse, queryJson] = - await config.api.datasources.previewQuery(dataSourceQuery) + expect(queryJson.rows.length).toEqual(10) + expect(queryJson.schemaFields).toEqual( + fixtures.queries.expectedSchemaFields.mariaDB + ) // Save query - const datasourcetoSave = { - ...dataSourceQuery, + const datasourcetoSave: Query = { + ...fixtures.queries.mariaDB(updatedDataSourceJson.datasource._id!), parameters: [], } - const [saveQueryResponse, saveQueryJson] = - await config.api.datasources.saveQuery(datasourcetoSave) + const [saveQueryResponse, saveQueryJson] = await config.api.queries.save( + datasourcetoSave + ) // Get Query - const [getQueryResponse, getQueryJson] = - await config.api.datasources.getQuery(saveQueryJson._id) + const [getQueryResponse, getQueryJson] = await config.api.queries.get( + saveQueryJson._id + ) // Get Query permissions const [getQueryPermissionsResponse, getQueryPermissionsJson] = - await config.api.datasources.getQueryPermissions( - saveQueryJson._id - ) + await config.api.permissions.getAll(saveQueryJson._id!) // Delete data source const deleteResponse = await config.api.datasources.delete( - updatedDataSourceJson.datasource._id, - updatedDataSourceJson.datasource._rev + updatedDataSourceJson.datasource._id!, + updatedDataSourceJson.datasource._rev! ) }) }) diff --git a/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts b/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts index 6c57467930..ed5178b57c 100644 --- a/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts +++ b/qa-core/src/internal-api/tests/dataSources/mongoDB.spec.ts @@ -1,5 +1,6 @@ import TestConfiguration from "../../config/TestConfiguration" import * as fixtures from "../../fixtures" +import { Query } from "@budibase/types" describe("Internal API - Data Sources: MongoDB", () => { const config = new TestConfiguration() @@ -16,6 +17,9 @@ describe("Internal API - Data Sources: MongoDB", () => { // Create app await config.createApp() + // Get all integrations + await config.api.integrations.getAll() + // Add data source const [dataSourceResponse, dataSourceJson] = await config.api.datasources.add(fixtures.datasources.mongoDB()) @@ -28,48 +32,38 @@ describe("Internal API - Data Sources: MongoDB", () => { const [updatedDataSourceResponse, updatedDataSourceJson] = await config.api.datasources.update(newDataSourceInfo) - const dataSourceQuery = { - datasourceId: updatedDataSourceJson.datasource._id, - fields: { - extra: { - collection: "movies", - actionType: "find", - }, - json: "", - }, - name: "Test Query", - parameters: {}, - queryVerb: "read", - schema: {}, - transformer: "return data", - } // Query data source + const [queryResponse, queryJson] = await config.api.queries.preview( + fixtures.queries.mongoDB(updatedDataSourceJson.datasource._id!) + ) - const [queryResponse, queryJson] = - await config.api.datasources.previewQuery(dataSourceQuery) + expect(queryJson.rows.length).toBeGreaterThan(10) + expect(queryJson.schemaFields).toEqual( + fixtures.queries.expectedSchemaFields.mongoDB + ) // Save query - const datasourcetoSave = { - ...dataSourceQuery, + const datasourcetoSave: Query = { + ...fixtures.queries.mongoDB(updatedDataSourceJson.datasource._id!), parameters: [], } - const [saveQueryResponse, saveQueryJson] = - await config.api.datasources.saveQuery(datasourcetoSave) + const [saveQueryResponse, saveQueryJson] = await config.api.queries.save( + datasourcetoSave + ) // Get Query - const [getQueryResponse, getQueryJson] = - await config.api.datasources.getQuery(saveQueryJson._id) + const [getQueryResponse, getQueryJson] = await config.api.queries.get( + saveQueryJson._id + ) // Get Query permissions const [getQueryPermissionsResponse, getQueryPermissionsJson] = - await config.api.datasources.getQueryPermissions( - saveQueryJson._id - ) + await config.api.permissions.getAll(saveQueryJson._id!) // Delete data source const deleteResponse = await config.api.datasources.delete( - updatedDataSourceJson.datasource._id, - updatedDataSourceJson.datasource._rev + updatedDataSourceJson.datasource._id!, + updatedDataSourceJson.datasource._rev! ) }) }) diff --git a/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts b/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts index 83d1fc782d..bc8d86b862 100644 --- a/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts +++ b/qa-core/src/internal-api/tests/dataSources/postgresSQL.spec.ts @@ -1,5 +1,6 @@ import TestConfiguration from "../../config/TestConfiguration" import * as fixtures from "../../fixtures" +import { Query } from "@budibase/types" describe("Internal API - Data Sources: PostgresSQL", () => { const config = new TestConfiguration() @@ -16,6 +17,9 @@ describe("Internal API - Data Sources: PostgresSQL", () => { // Create app await config.createApp() + // Get all integrations + await config.api.integrations.getAll() + // Add data source const [dataSourceResponse, dataSourceJson] = await config.api.datasources.add(fixtures.datasources.postgresSQL()) @@ -28,44 +32,38 @@ describe("Internal API - Data Sources: PostgresSQL", () => { const [updatedDataSourceResponse, updatedDataSourceJson] = await config.api.datasources.update(newDataSourceInfo) - const dataSourceQuery = { - datasourceId: updatedDataSourceJson.datasource._id, - fields: { - sql: "SELECT * FROM categories;", - }, - name: "Query 1", - parameters: {}, - queryVerb: "read", - schema: {}, - transformer: "return data", - } // Query data source + const [queryResponse, queryJson] = await config.api.queries.preview( + fixtures.queries.postgres(updatedDataSourceJson.datasource._id!) + ) - const [queryResponse, queryJson] = - await config.api.datasources.previewQuery(dataSourceQuery) + expect(queryJson.rows.length).toEqual(91) + expect(queryJson.schemaFields).toEqual( + fixtures.queries.expectedSchemaFields.postgres + ) // Save query - const datasourcetoSave = { - ...dataSourceQuery, + const datasourcetoSave: Query = { + ...fixtures.queries.postgres(updatedDataSourceJson.datasource._id!), parameters: [], } - const [saveQueryResponse, saveQueryJson] = - await config.api.datasources.saveQuery(datasourcetoSave) + const [saveQueryResponse, saveQueryJson] = await config.api.queries.save( + datasourcetoSave + ) // Get Query - const [getQueryResponse, getQueryJson] = - await config.api.datasources.getQuery(saveQueryJson._id) + const [getQueryResponse, getQueryJson] = await config.api.queries.get( + saveQueryJson._id! + ) // Get Query permissions const [getQueryPermissionsResponse, getQueryPermissionsJson] = - await config.api.datasources.getQueryPermissions( - saveQueryJson._id - ) + await config.api.permissions.getAll(saveQueryJson._id!) // Delete data source const deleteResponse = await config.api.datasources.delete( - updatedDataSourceJson.datasource._id, - updatedDataSourceJson.datasource._rev + updatedDataSourceJson.datasource._id!, + updatedDataSourceJson.datasource._rev! ) }) }) diff --git a/qa-core/src/types/addedDatasource.ts b/qa-core/src/types/addedDatasource.ts deleted file mode 100644 index 65f51fd1bd..0000000000 --- a/qa-core/src/types/addedDatasource.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Datasource } from "@budibase/types" - -export interface AddedDatasource { - datasource: Datasource -} From 695f77fd1d7b0fcab0816eb47cc37e46462b0be3 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Thu, 13 Apr 2023 11:13:21 +0100 Subject: [PATCH 4/8] Add types for datasources endpoints --- .../server/src/api/controllers/datasource.ts | 20 ++++++++++++++----- packages/types/src/api/web/app/datasource.ts | 19 ++++++++++++++++++ packages/types/src/api/web/app/index.ts | 1 + 3 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 packages/types/src/api/web/app/datasource.ts diff --git a/packages/server/src/api/controllers/datasource.ts b/packages/server/src/api/controllers/datasource.ts index 3d41cd89af..b61b168980 100644 --- a/packages/server/src/api/controllers/datasource.ts +++ b/packages/server/src/api/controllers/datasource.ts @@ -12,7 +12,15 @@ import { getIntegration } from "../../integrations" import { getDatasourceAndQuery } from "./row/utils" import { invalidateDynamicVariables } from "../../threads/utils" import { db as dbCore, context, events } from "@budibase/backend-core" -import { UserCtx, Datasource, Row } from "@budibase/types" +import { + UserCtx, + Datasource, + Row, + CreateDatasourceResponse, + UpdateDatasourceResponse, + UpdateDatasourceRequest, + CreateDatasourceRequest, +} from "@budibase/types" import sdk from "../../sdk" export async function fetch(ctx: UserCtx) { @@ -146,7 +154,7 @@ async function invalidateVariables( await invalidateDynamicVariables(toInvalidate) } -export async function update(ctx: UserCtx) { +export async function update(ctx: UserCtx) { const db = context.getAppDB() const datasourceId = ctx.params.datasourceId let datasource = await sdk.datasources.get(datasourceId) @@ -187,15 +195,17 @@ export async function update(ctx: UserCtx) { } } -export async function save(ctx: UserCtx) { +export async function save( + ctx: UserCtx +) { const db = context.getAppDB() const plus = ctx.request.body.datasource.plus const fetchSchema = ctx.request.body.fetchSchema const datasource = { _id: generateDatasourceID({ plus }), - type: plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE, ...ctx.request.body.datasource, + type: plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE, } let schemaError = null @@ -218,7 +228,7 @@ export async function save(ctx: UserCtx) { } } - const response: any = { + const response: CreateDatasourceResponse = { datasource: await sdk.datasources.removeSecretSingle(datasource), } if (schemaError) { diff --git a/packages/types/src/api/web/app/datasource.ts b/packages/types/src/api/web/app/datasource.ts new file mode 100644 index 0000000000..d54259eab5 --- /dev/null +++ b/packages/types/src/api/web/app/datasource.ts @@ -0,0 +1,19 @@ +import { Datasource } from "../../../documents" + +export interface CreateDatasourceResponse { + datasource: Datasource + error?: any +} + +export interface UpdateDatasourceResponse { + datasource: Datasource +} + +export interface CreateDatasourceRequest { + datasource: Datasource + fetchSchema?: boolean +} + +export interface UpdateDatasourceRequest extends Datasource { + datasource: Datasource +} diff --git a/packages/types/src/api/web/app/index.ts b/packages/types/src/api/web/app/index.ts index 1d73755cb6..9be15ecfe3 100644 --- a/packages/types/src/api/web/app/index.ts +++ b/packages/types/src/api/web/app/index.ts @@ -1 +1,2 @@ export * from "./backup" +export * from "./datasource" From e20838fd428d3b2a887531050b8a922a261336dc Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Fri, 14 Apr 2023 17:35:13 +0100 Subject: [PATCH 5/8] Add rest test and fix type --- .../types/src/documents/app/datasource.ts | 8 --- packages/types/src/documents/app/query.ts | 3 + .../src/internal-api/fixtures/datasources.ts | 18 ++++- qa-core/src/internal-api/fixtures/queries.ts | 48 +++++++++++++ .../tests/dataSources/restAPI.spec.ts | 69 +++++++++++++++++++ 5 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 qa-core/src/internal-api/tests/dataSources/restAPI.spec.ts diff --git a/packages/types/src/documents/app/datasource.ts b/packages/types/src/documents/app/datasource.ts index 9b498fb4b3..8dfdfe6d0f 100644 --- a/packages/types/src/documents/app/datasource.ts +++ b/packages/types/src/documents/app/datasource.ts @@ -56,11 +56,3 @@ export interface RestConfig { } ] } - -export interface CreateDatasourceResponse { - datasource: Datasource -} - -export interface UpdatedDatasourceResponse { - datasource: Datasource -} diff --git a/packages/types/src/documents/app/query.ts b/packages/types/src/documents/app/query.ts index d0bbf05b5c..31a3a3ba09 100644 --- a/packages/types/src/documents/app/query.ts +++ b/packages/types/src/documents/app/query.ts @@ -45,4 +45,7 @@ export interface PaginationValues { export interface PreviewQueryRequest extends Omit { parameters: {} + flags?: { + urlName?: boolean + } } diff --git a/qa-core/src/internal-api/fixtures/datasources.ts b/qa-core/src/internal-api/fixtures/datasources.ts index a8d59b88a1..dcf6af824a 100644 --- a/qa-core/src/internal-api/fixtures/datasources.ts +++ b/qa-core/src/internal-api/fixtures/datasources.ts @@ -34,8 +34,6 @@ export const postgresSQL = () => { fetchSchema: true, } } - -// Add the data source for MariaDB to the this file in the same style as above export const mariaDB = () => { return { datasource: { @@ -55,3 +53,19 @@ export const mariaDB = () => { fetchSchema: true, } } + +export const restAPI = () => { + return { + datasource: { + name: "RestAPI", + source: "REST", + type: "datasource", + config: { + defaultHeaders: {}, + rejectUnauthorized: true, + url: process.env.REST_API_BASE_URL, + }, + }, + fetchSchema: false, + } +} diff --git a/qa-core/src/internal-api/fixtures/queries.ts b/qa-core/src/internal-api/fixtures/queries.ts index 7ba81fc744..83839a0b41 100644 --- a/qa-core/src/internal-api/fixtures/queries.ts +++ b/qa-core/src/internal-api/fixtures/queries.ts @@ -72,4 +72,52 @@ export const expectedSchemaFields = { postal_code: "string", region: "string", }, + restAPI: { + abilities: "array", + base_experience: "number", + forms: "array", + game_indices: "array", + height: "number", + held_items: "array", + id: "number", + is_default: "string", + location_area_encounters: "string", + moves: "array", + name: "string", + order: "number", + past_types: "array", + species: "json", + sprites: "json", + stats: "array", + types: "array", + weight: "number", + }, +} + +const request = (datasourceId: string, fields: any, flags: any): any => { + return { + datasourceId: datasourceId, + fields: fields, + flags: flags, + name: "Query 1", + parameters: {}, + queryVerb: "read", + schema: {}, + transformer: "return data", + } +} +export const restAPI = (datasourceId: string): PreviewQueryRequest => { + const fields = { + authConfigId: null, + bodyType: "none", + disabledHeaders: {}, + headers: {}, + pagination: {}, + path: `${process.env.REST_API_BASE_URL}/pokemon/ditto`, + queryString: "", + } + const flags = { + urlName: true, + } + return request(datasourceId, fields, flags) } diff --git a/qa-core/src/internal-api/tests/dataSources/restAPI.spec.ts b/qa-core/src/internal-api/tests/dataSources/restAPI.spec.ts new file mode 100644 index 0000000000..d7b75db514 --- /dev/null +++ b/qa-core/src/internal-api/tests/dataSources/restAPI.spec.ts @@ -0,0 +1,69 @@ +import TestConfiguration from "../../config/TestConfiguration" +import * as fixtures from "../../fixtures" +import { Query } from "@budibase/types" + +describe("Internal API - Data Sources: REST API", () => { + const config = new TestConfiguration() + + beforeAll(async () => { + await config.beforeAll() + }) + + afterAll(async () => { + await config.afterAll() + }) + + it("Create an app with a data source - REST API", async () => { + // Create app + await config.createApp() + + // Get all integrations + await config.api.integrations.getAll() + + // Add data source + const [dataSourceResponse, dataSourceJson] = + await config.api.datasources.add(fixtures.datasources.restAPI()) + + // Update data source + const newDataSourceInfo = { + ...dataSourceJson.datasource, + name: "RestAPI - Updated", + } + const [updatedDataSourceResponse, updatedDataSourceJson] = + await config.api.datasources.update(newDataSourceInfo) + + // Query data source + const [queryResponse, queryJson] = await config.api.queries.preview( + fixtures.queries.restAPI(updatedDataSourceJson.datasource._id!) + ) + + expect(queryJson.rows.length).toEqual(1) + expect(queryJson.schemaFields).toEqual( + fixtures.queries.expectedSchemaFields.restAPI + ) + + // Save query + const datasourcetoSave: Query = { + ...fixtures.queries.postgres(updatedDataSourceJson.datasource._id!), + parameters: [], + } + + const [saveQueryResponse, saveQueryJson] = await config.api.queries.save( + datasourcetoSave + ) + // Get Query + const [getQueryResponse, getQueryJson] = await config.api.queries.get( + saveQueryJson._id! + ) + + // Get Query permissions + const [getQueryPermissionsResponse, getQueryPermissionsJson] = + await config.api.permissions.getAll(saveQueryJson._id!) + + // Delete data source + const deleteResponse = await config.api.datasources.delete( + updatedDataSourceJson.datasource._id!, + updatedDataSourceJson.datasource._rev! + ) + }) +}) From f104e66acf1c9885d5706e627ffb9e7b7eeaeaa7 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Fri, 14 Apr 2023 18:14:47 +0100 Subject: [PATCH 6/8] Fix type --- qa-core/src/internal-api/api/apis/DatasourcesAPI.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts index 7b9d7af789..f29bb9d6bc 100644 --- a/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts +++ b/qa-core/src/internal-api/api/apis/DatasourcesAPI.ts @@ -2,7 +2,7 @@ import { Response } from "node-fetch" import { Datasource, CreateDatasourceResponse, - UpdatedDatasourceResponse, + UpdateDatasourceResponse, } from "@budibase/types" import BudibaseInternalAPIClient from "../BudibaseInternalAPIClient" @@ -46,7 +46,7 @@ export default class DatasourcesAPI { return [response, json] } - async update(body: any): Promise<[Response, UpdatedDatasourceResponse]> { + async update(body: any): Promise<[Response, UpdateDatasourceResponse]> { const [response, json] = await this.client.put(`/datasources/${body._id}`, { body, }) From 5226385367cd9ff353dee66c61244acf229f0870 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Wed, 26 Apr 2023 15:51:25 +0100 Subject: [PATCH 7/8] Change integration count assertion --- qa-core/src/internal-api/api/apis/IntegrationsAPI.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts b/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts index b42b999825..2478823bfa 100644 --- a/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts +++ b/qa-core/src/internal-api/api/apis/IntegrationsAPI.ts @@ -12,7 +12,7 @@ export default class IntegrationsAPI { const [response, json] = await this.client.get(`/integrations`) expect(response).toHaveStatusCode(200) const integrationsCount = Object.keys(json).length - expect(integrationsCount).toBe(16) + expect(integrationsCount).toBeGreaterThan(0) return [response, json] } } From 6e795064454d774eb7e7d8e788adbcb842abe4ca Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Wed, 26 Apr 2023 16:45:00 +0100 Subject: [PATCH 8/8] Fix failing test --- packages/server/src/integration-test/postgres.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/integration-test/postgres.spec.ts b/packages/server/src/integration-test/postgres.spec.ts index 36285e2831..78075b4e54 100644 --- a/packages/server/src/integration-test/postgres.spec.ts +++ b/packages/server/src/integration-test/postgres.spec.ts @@ -349,7 +349,7 @@ describe("row api - postgres", () => { }, plus: true, source: "POSTGRES", - type: "datasource", + type: "datasource_plus", _id: expect.any(String), _rev: expect.any(String), createdAt: expect.any(String),