Updating row tests, reducing console logging during tests for speed and clarity, testing some misc endpoints and updating search functionality to use a starts with operator when working with strings on rows.

This commit is contained in:
mike12345567 2021-03-10 17:55:42 +00:00
parent f69e06870b
commit 163d24a767
10 changed files with 204 additions and 61 deletions

View File

@ -33,7 +33,7 @@
},
"scripts": {
"test": "jest --testPathIgnorePatterns=routes && npm run test:integration",
"test:integration": "jest routes --runInBand --coverage",
"test:integration": "jest --runInBand --coverage",
"test:watch": "jest --watch",
"run:docker": "node src/index",
"dev:builder": "cross-env PORT=4001 nodemon src/index.js",

View File

@ -3,21 +3,14 @@ const { join } = require("../../utilities/centralPath")
const readline = require("readline")
const { budibaseAppsDir } = require("../../utilities/budibaseDir")
const env = require("../../environment")
const selfhost = require("../../selfhost")
const ENV_FILE_PATH = "/.env"
exports.fetch = async function(ctx) {
ctx.status = 200
if (env.SELF_HOSTED) {
ctx.body = {
selfhost: await selfhost.getSelfHostAPIKey(),
}
} else {
ctx.body = {
budibase: env.BUDIBASE_API_KEY,
userId: env.USERID_API_KEY,
}
}
}
exports.update = async function(ctx) {

View File

@ -224,6 +224,7 @@ exports.fetchView = async function(ctx) {
try {
table = await db.get(viewInfo.meta.tableId)
} catch (err) {
/* istanbul ignore next */
table = {
schema: {},
}
@ -255,16 +256,24 @@ exports.fetchView = async function(ctx) {
exports.search = async function(ctx) {
const appId = ctx.user.appId
const db = new CouchDB(appId)
const {
query,
pagination: { pageSize = 10, page },
} = ctx.request.body
query.tableId = ctx.params.tableId
// make all strings a starts with operation rather than pure equality
for (const [key, queryVal] of Object.entries(query)) {
if (typeof queryVal === "string") {
query[key] = {
$gt: queryVal,
$lt: `${queryVal}\uffff`,
}
}
}
// pure equality for table
query.tableId = ctx.params.tableId
const response = await db.find({
selector: query,
limit: pageSize,
@ -324,7 +333,6 @@ exports.destroy = async function(ctx) {
const row = await db.get(ctx.params.rowId)
if (row.tableId !== ctx.params.tableId) {
ctx.throw(400, "Supplied tableId doesn't match the row's tableId")
return
}
await linkRows.updateLinks({
appId,
@ -376,15 +384,6 @@ exports.fetchEnrichedRow = async function(ctx) {
const db = new CouchDB(appId)
const tableId = ctx.params.tableId
const rowId = ctx.params.rowId
if (appId == null || tableId == null || rowId == null) {
ctx.status = 400
ctx.body = {
status: 400,
error:
"Cannot handle request, URI params have not been successfully prepared.",
}
return
}
// need table to work out where links go in row
let [table, row] = await Promise.all([
db.get(tableId),

View File

@ -41,14 +41,16 @@ router.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.log.error(err)
ctx.status = err.status || err.statusCode || 500
ctx.body = {
message: err.message,
status: ctx.status,
}
if (env.NODE_ENV !== "jest") {
ctx.log.error(err)
console.trace(err)
}
}
})
router.get("/health", ctx => (ctx.status = 200))

View File

@ -8,6 +8,7 @@ const usage = require("../../middleware/usageQuota")
const router = Router()
/* istanbul ignore next */
router.param("file", async (file, ctx, next) => {
ctx.file = file && file.includes(".") ? file : "index.html"

View File

@ -35,7 +35,7 @@ describe("/api/keys", () => {
describe("update", () => {
it("should allow updating a value", async () => {
fs.writeFileSync(path.join(budibaseAppsDir(), ".env"), "")
fs.writeFileSync(path.join(budibaseAppsDir(), ".env"), "TEST_API_KEY=thing")
const res = await request
.put(`/api/keys/TEST`)
.send({

View File

@ -0,0 +1,16 @@
const setup = require("./utilities")
describe("test things in the Cloud/Self hosted", () => {
describe("test self hosted static page", () => {
it("should be able to load the static page", async () => {
await setup.switchToCloudForFunction(async () => {
let request = setup.getRequest()
let config = setup.getConfig()
await config.init()
const res = await request.get(`/`).expect(200)
expect(res.text.includes("<title>Budibase self hosting</title>")).toEqual(true)
setup.afterAll()
})
})
})
})

View File

@ -17,15 +17,15 @@ describe("/rows", () => {
row = basicRow(table._id)
})
const loadRow = async id =>
const loadRow = async (id, status = 200) =>
await request
.get(`/api/${table._id}/rows/${id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
.expect(status)
describe("save, load, update, delete", () => {
describe("save, load, update", () => {
it("returns a success message when the row is created", async () => {
const res = await request
.post(`/api/${row.tableId}/rows`)
@ -217,38 +217,152 @@ describe("/rows", () => {
expect(savedRow.body.description).toEqual(existing.description)
expect(savedRow.body.name).toEqual("Updated Name")
})
it("should throw an error when given improper types", async () => {
const existing = await config.createRow()
await request
.patch(`/api/${table._id}/rows/${existing._id}`)
.send({
_id: existing._id,
_rev: existing._rev,
tableId: table._id,
name: 1,
})
.set(config.defaultHeaders())
.expect(400)
})
})
describe("destroy", () => {
it("should be able to delete a row", async () => {
const createdRow = await config.createRow(row)
const res = await request
.delete(`/api/${table._id}/rows/${createdRow._id}/${createdRow._rev}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(res.body.ok).toEqual(true)
})
it("shouldn't allow deleting a row in a table which is different to the one the row was created on", async () => {
const createdRow = await config.createRow(row)
await request
.delete(`/api/wrong_table/rows/${createdRow._id}/${createdRow._rev}`)
.set(config.defaultHeaders())
.expect(400)
})
})
describe("validate", () => {
it("should return no errors on valid row", async () => {
const result = await request
const res = await request
.post(`/api/${table._id}/rows/validate`)
.send({ name: "ivan" })
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(result.body.valid).toBe(true)
expect(Object.keys(result.body.errors)).toEqual([])
expect(res.body.valid).toBe(true)
expect(Object.keys(res.body.errors)).toEqual([])
})
it("should errors on invalid row", async () => {
const result = await request
const res = await request
.post(`/api/${table._id}/rows/validate`)
.send({ name: 1 })
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(result.body.valid).toBe(false)
expect(Object.keys(result.body.errors)).toEqual(["name"])
expect(res.body.valid).toBe(false)
expect(Object.keys(res.body.errors)).toEqual(["name"])
})
})
describe("enrich row unit test", () => {
describe("bulkDelete", () => {
it("should be able to delete a bulk set of rows", async () => {
const row1 = await config.createRow()
const row2 = await config.createRow()
const res = await request
.post(`/api/${table._id}/rows`)
.send({
type: "delete",
rows: [
row1,
row2,
]
})
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(res.body.length).toEqual(2)
await loadRow(row1._id, 404)
})
})
describe("search", () => {
it("should run a search on the table", async () => {
const row = await config.createRow()
// add another row that shouldn't be found
await config.createRow({
...basicRow(),
name: "Other Contact",
})
const res = await request
.post(`/api/${table._id}/rows/search`)
.send({
query: {
name: "Test",
},
pagination: { pageSize: 25, page: 0 }
})
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(res.body.length).toEqual(1)
expect(res.body[0]._id).toEqual(row._id)
})
})
describe("fetchView", () => {
it("should be able to fetch tables contents via 'view'", async () => {
const row = await config.createRow()
const res = await request
.get(`/api/views/all_${table._id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(res.body.length).toEqual(1)
expect(res.body[0]._id).toEqual(row._id)
})
it("should throw an error if view doesn't exist", async () => {
await request
.get(`/api/views/derp`)
.set(config.defaultHeaders())
.expect(400)
})
it("should be able to run on a view", async () => {
const view = await config.createView()
const row = await config.createRow()
const res = await request
.get(`/api/views/${view._id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(res.body.length).toEqual(1)
expect(res.body[0]._id).toEqual(row._id)
})
})
describe("user testing", () => {
})
describe("fetchEnrichedRows", () => {
it("should allow enriching some linked rows", async () => {
const table = await config.createLinkedTable()
const firstRow = await config.createRow({
@ -262,13 +376,30 @@ describe("/rows", () => {
link: [{_id: firstRow._id}],
tableId: table._id,
})
const enriched = await outputProcessing(config.getAppId(), table, [secondRow])
expect(enriched[0].link.length).toBe(1)
expect(enriched[0].link[0]._id).toBe(firstRow._id)
expect(enriched[0].link[0].primaryDisplay).toBe("Test Contact")
// test basic enrichment
const resBasic = await request
.get(`/api/${table._id}/rows/${secondRow._id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(resBasic.body.link[0]._id).toBe(firstRow._id)
expect(resBasic.body.link[0].primaryDisplay).toBe("Test Contact")
// test full enrichment
const resEnriched = await request
.get(`/api/${table._id}/${secondRow._id}/enrich`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect(200)
expect(resEnriched.body.link.length).toBe(1)
expect(resEnriched.body.link[0]._id).toBe(firstRow._id)
expect(resEnriched.body.link[0].name).toBe("Test Contact")
expect(resEnriched.body.link[0].description).toBe("original description")
})
})
describe("attachments", () => {
it("should allow enriching attachment rows", async () => {
const table = await config.createAttachmentTable()
const row = await config.createRow({
@ -280,12 +411,10 @@ describe("/rows", () => {
tableId: table._id,
})
// the environment needs configured for this
env.CLOUD = 1
env.SELF_HOSTED = 1
await setup.switchToCloudForFunction(async () => {
const enriched = await outputProcessing(config.getAppId(), table, [row])
expect(enriched[0].attachment[0].url).toBe(`/app-assets/assets/${config.getAppId()}/test/thing`)
// remove env config
env.CLOUD = undefined
env.SELF_HOSTED = undefined
})
})
})
})

View File

@ -56,7 +56,11 @@ if (electron.app && electron.app.isPackaged) {
const server = http.createServer(app.callback())
destroyable(server)
server.on("close", () => console.log("Server Closed"))
server.on("close", () => {
if (env.NODE_ENV !== "jest") {
console.log("Server Closed")
}
})
module.exports = server.listen(env.PORT || 0, async () => {
console.log(`Budibase running on ${JSON.stringify(server.address())}`)

View File

@ -9,7 +9,6 @@ class TestConfiguration {
this.ctx = {
config: {},
auth: {},
request: {},
cookies: {
set: jest.fn(),
get: jest.fn()