diff --git a/packages/server/src/api/routes/tests/couchTestUtils.js b/packages/server/src/api/routes/tests/couchTestUtils.js deleted file mode 100644 index 90d15612f0..0000000000 --- a/packages/server/src/api/routes/tests/couchTestUtils.js +++ /dev/null @@ -1,326 +0,0 @@ -const CouchDB = require("../../../db") -const supertest = require("supertest") -const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles") -const packageJson = require("../../../../package") -const jwt = require("jsonwebtoken") -const env = require("../../../environment") -const { - BUILTIN_PERMISSION_IDS, -} = require("../../../utilities/security/permissions") - -const TEST_CLIENT_ID = "test-client-id" - -exports.TEST_CLIENT_ID = TEST_CLIENT_ID -exports.supertest = async () => { - let request - let server - env.PORT = 4002 - server = require("../../../app") - - request = supertest(server) - return { request, server } -} - -exports.defaultHeaders = appId => { - const builderUser = { - userId: "BUILDER", - roleId: BUILTIN_ROLE_IDS.BUILDER, - } - - const builderToken = jwt.sign(builderUser, env.JWT_SECRET) - - const headers = { - Accept: "application/json", - Cookie: [`budibase:builder:local=${builderToken}`], - } - if (appId) { - headers["x-budibase-app-id"] = appId - } - - return headers -} - -exports.publicHeaders = appId => { - const headers = { - Accept: "application/json", - } - if (appId) { - headers["x-budibase-app-id"] = appId - } - - return headers -} - -exports.BASE_TABLE = { - name: "TestTable", - type: "table", - key: "name", - schema: { - name: { - type: "string", - constraints: { - type: "string", - }, - }, - description: { - type: "string", - constraints: { - type: "string", - }, - }, - }, -} - -exports.createTable = async (request, appId, table, removeId = true) => { - if (removeId && table != null && table._id) { - delete table._id - } - table = table || exports.BASE_TABLE - - const res = await request - .post(`/api/tables`) - .set(exports.defaultHeaders(appId)) - .send(table) - return res.body -} - -exports.makeBasicRow = tableId => { - return { - name: "Test Contact", - description: "original description", - status: "new", - tableId: tableId, - } -} - -exports.createRow = async (request, appId, tableId, row = null) => { - row = row || exports.makeBasicRow(tableId) - const res = await request - .post(`/api/${tableId}/rows`) - .send(row) - .set(exports.defaultHeaders(appId)) - .expect("Content-Type", /json/) - .expect(200) - return res.body -} - -exports.createRole = async (request, appId) => { - const roleBody = { - name: "NewRole", - inherits: BUILTIN_ROLE_IDS.BASIC, - permissionId: BUILTIN_PERMISSION_IDS.READ_ONLY, - } - const res = await request - .post(`/api/roles`) - .send(roleBody) - .set(exports.defaultHeaders(appId)) - .expect("Content-Type", /json/) - .expect(200) - return res.body -} - -exports.addPermission = async ( - request, - appId, - role, - resource, - level = "read" -) => { - const res = await request - .post(`/api/permission/${role}/${resource}/${level}`) - .set(exports.defaultHeaders(appId)) - .expect("Content-Type", /json/) - .expect(200) - return res.body -} - -exports.createLinkedTable = async (request, appId) => { - // get the ID to link to - const table = await exports.createTable(request, appId) - table.primaryDisplay = "name" - table.schema.link = { - type: "link", - fieldName: "link", - tableId: table._id, - } - return exports.createTable(request, appId, table, false) -} - -exports.createAttachmentTable = async (request, appId) => { - const table = await exports.createTable(request, appId) - table.schema.attachment = { - type: "attachment", - } - return exports.createTable(request, appId, table, false) -} - -exports.getAllFromTable = async (request, appId, tableId) => { - const res = await request - .get(`/api/${tableId}/rows`) - .set(exports.defaultHeaders(appId)) - return res.body -} - -exports.createView = async (request, appId, tableId, view) => { - view = view || { - map: "function(doc) { emit(doc[doc.key], doc._id); } ", - tableId: tableId, - } - - const res = await request - .post(`/api/views`) - .set(exports.defaultHeaders(appId)) - .send(view) - return res.body -} - -exports.createApplication = async (request, name = "test_application") => { - const res = await request - .post("/api/applications") - .send({ - name, - }) - .set(exports.defaultHeaders()) - return res.body -} - -exports.clearApplications = async request => { - const res = await request - .get("/api/applications") - .set(exports.defaultHeaders()) - for (let app of res.body) { - const appId = app._id - await request - .delete(`/api/applications/${appId}`) - .set(exports.defaultHeaders(appId)) - } -} - -exports.createUser = async ( - request, - appId, - email = "babs@babs.com", - password = "babs_password" -) => { - const res = await request - .post(`/api/users`) - .set(exports.defaultHeaders(appId)) - .send({ - name: "Bill", - email, - password, - roleId: BUILTIN_ROLE_IDS.POWER, - }) - return res.body -} - -const createUserWithRole = async (request, appId, roleId, email) => { - const password = `password_${email}` - await request - .post(`/api/users`) - .set(exports.defaultHeaders(appId)) - .send({ - email, - password, - roleId, - }) - - const anonUser = { - userId: "ANON", - roleId: BUILTIN_ROLE_IDS.PUBLIC, - appId: appId, - version: packageJson.version, - } - - const anonToken = jwt.sign(anonUser, env.JWT_SECRET) - - const loginResult = await request - .post(`/api/authenticate`) - .set({ - Cookie: `budibase:${appId}:local=${anonToken}`, - "x-budibase-app-id": appId, - }) - .send({ email, password }) - - // returning necessary request headers - return { - Accept: "application/json", - Cookie: loginResult.headers["set-cookie"], - } -} - -exports.testPermissionsForEndpoint = async ({ - request, - method, - url, - body, - appId, - passRole, - failRole, -}) => { - const passHeader = await createUserWithRole( - request, - appId, - passRole, - "passUser@budibase.com" - ) - - await createRequest(request, method, url, body) - .set(passHeader) - .expect(200) - - const failHeader = await createUserWithRole( - request, - appId, - failRole, - "failUser@budibase.com" - ) - - await createRequest(request, method, url, body) - .set(failHeader) - .expect(403) -} - -exports.builderEndpointShouldBlockNormalUsers = async ({ - request, - method, - url, - body, - appId, -}) => { - const headers = await createUserWithRole( - request, - appId, - BUILTIN_ROLE_IDS.BASIC, - "basicUser@budibase.com" - ) - - await createRequest(request, method, url, body) - .set(headers) - .expect(403) -} - -const createRequest = (request, method, url, body) => { - let req - - if (method === "POST") req = request.post(url).send(body) - else if (method === "GET") req = request.get(url) - else if (method === "DELETE") req = request.delete(url) - else if (method === "PATCH") req = request.patch(url).send(body) - else if (method === "PUT") req = request.put(url).send(body) - - return req -} - -exports.insertDocument = async (databaseId, document) => { - const { id, ...documentFields } = document - return await new CouchDB(databaseId).put({ _id: id, ...documentFields }) -} - -exports.destroyDocument = async (databaseId, documentId) => { - return await new CouchDB(databaseId).destroy(documentId) -} - -exports.getDocument = async (databaseId, documentId) => { - return await new CouchDB(databaseId).get(documentId) -} diff --git a/packages/server/src/api/routes/tests/view.spec.js b/packages/server/src/api/routes/tests/view.spec.js index f1ee5d8218..8a7f9579a0 100644 --- a/packages/server/src/api/routes/tests/view.spec.js +++ b/packages/server/src/api/routes/tests/view.spec.js @@ -1,65 +1,67 @@ -const { - createApplication, - createTable, - supertest, - defaultHeaders, - getDocument -} = require("./couchTestUtils") +const TestConfig = require("./utilities/TestConfiguration"); describe("/views", () => { - let request - let server - let app - let appId - let table - - const createView = async (config = { - name: "TestView", - field: "Price", - calculation: "stats", - tableId: table._id - }) => - await request - .post(`/api/views`) - .send(config) - .set(defaultHeaders(appId)) - .expect('Content-Type', /json/) - .expect(200) - - const createRow = async row => request - .post(`/api/${table._id}/rows`) - .send(row) - .set(defaultHeaders(appId)) - .expect('Content-Type', /json/) - .expect(200) + let request; + let server; + let app; + let config; + let appId; + let table; beforeAll(async () => { - ({ request, server } = await supertest()) - }) + config = new TestConfig(); + request = config.request; + }); beforeEach(async () => { - app = await createApplication(request) - appId = app.instance._id - }) + app = await config.init(); + appId = app.instance._id; + }); afterAll(() => { - server.close() - }) + config.end(); + }); describe("create", () => { beforeEach(async () => { - table = await createTable(request, appId); - }) + table = await config.createTable(); + }); it("returns a success message when the view is successfully created", async () => { - const res = await createView() - expect(res.res.statusMessage).toEqual("View TestView saved successfully."); - }) + const res = await request + .post(`/api/views`) + .send({ + name: "TestView", + field: "Price", + calculation: "stats", + tableId: table._id, + }) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200); + + expect(res.res.statusMessage).toEqual( + "View TestView saved successfully." + ); + }); it("updates the table row with the new view metadata", async () => { - const res = await createView() - expect(res.res.statusMessage).toEqual("View TestView saved successfully."); - const updatedTable = await getDocument(appId, table._id) + const res = await request + .post(`/api/views`) + .send({ + name: "TestView", + field: "Price", + calculation: "stats", + tableId: table._id, + }) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200); + + expect(res.res.statusMessage).toEqual( + "View TestView saved successfully." + ); + const updatedTable = await config.getTable(table._id); expect(updatedTable.views).toEqual({ TestView: { field: "Price", @@ -88,88 +90,98 @@ describe("/views", () => { field: { type: "string", }, - } - } + }, + }, }); - }) + }); }); describe("fetch", () => { beforeEach(async () => { - table = await createTable(request, appId); + table = await config.createTable(); }); it("returns only custom views", async () => { - await createView() + await config.createView({ + name: "TestView", + field: "Price", + calculation: "stats", + tableId: table._id, + }); const res = await request .get(`/api/views`) - .set(defaultHeaders(appId)) - .expect('Content-Type', /json/) - .expect(200) - expect(res.body.length).toBe(1) - expect(res.body.find(({ name }) => name === "TestView")).toBeDefined() - }) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200); + expect(res.body.length).toBe(1); + expect(res.body.find(({ name }) => name === "TestView")).toBeDefined(); + }); }); describe("query", () => { beforeEach(async () => { - table = await createTable(request, appId); + table = await config.createTable(); }); it("returns data for the created view", async () => { - await createView() - await createRow({ + await config.createView({ + name: "TestView", + field: "Price", + calculation: "stats", tableId: table._id, - Price: 1000 - }) - await createRow({ + }); + await config.createRow({ tableId: table._id, - Price: 2000 - }) - await createRow({ + Price: 1000, + }); + await config.createRow({ tableId: table._id, - Price: 4000 - }) + Price: 2000, + }); + await config.createRow({ + tableId: table._id, + Price: 4000, + }); const res = await request .get(`/api/views/TestView?calculation=stats`) - .set(defaultHeaders(appId)) - .expect('Content-Type', /json/) - .expect(200) - expect(res.body.length).toBe(1) - expect(res.body).toMatchSnapshot() - }) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200); + expect(res.body.length).toBe(1); + expect(res.body).toMatchSnapshot(); + }); it("returns data for the created view using a group by", async () => { - await createView({ + await config.createView({ calculation: "stats", name: "TestView", field: "Price", groupBy: "Category", - tableId: table._id - }) - await createRow({ + tableId: table._id, + }); + await config.createRow({ tableId: table._id, Price: 1000, - Category: "One" - }) - await createRow({ + Category: "One", + }); + await config.createRow({ tableId: table._id, Price: 2000, - Category: "One" - }) - await createRow({ + Category: "One", + }); + await config.createRow({ tableId: table._id, Price: 4000, - Category: "Two" - }) + Category: "Two", + }); const res = await request .get(`/api/views/TestView?calculation=stats&group=Category`) - .set(defaultHeaders(appId)) - .expect('Content-Type', /json/) - .expect(200) - - expect(res.body.length).toBe(2) - expect(res.body).toMatchSnapshot() - }) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200); + + expect(res.body.length).toBe(2); + expect(res.body).toMatchSnapshot(); + }); }); -}); \ No newline at end of file +});