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:
parent
f69e06870b
commit
163d24a767
|
@ -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",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -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
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -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())}`)
|
||||
|
|
|
@ -9,7 +9,6 @@ class TestConfiguration {
|
|||
this.ctx = {
|
||||
config: {},
|
||||
auth: {},
|
||||
request: {},
|
||||
cookies: {
|
||||
set: jest.fn(),
|
||||
get: jest.fn()
|
||||
|
|
Loading…
Reference in New Issue