1
0
Fork 0
mirror of synced 2024-06-28 02:50:50 +12:00

Add tests for exporting data

This commit is contained in:
Andrew Kingston 2022-08-19 13:54:08 +01:00
parent 8634d88b05
commit 1d0125fb94

View file

@ -3,7 +3,12 @@ const setup = require("./utilities")
const { basicRow } = setup.structures
const { doInAppContext } = require("@budibase/backend-core/context")
const { doInTenant } = require("@budibase/backend-core/tenancy")
const { quotas, QuotaUsageType, StaticQuotaName, MonthlyQuotaName } = require("@budibase/pro")
const {
quotas,
QuotaUsageType,
StaticQuotaName,
MonthlyQuotaName,
} = require("@budibase/pro")
describe("/rows", () => {
let request = setup.getRequest()
@ -23,23 +28,30 @@ describe("/rows", () => {
await request
.get(`/api/${table._id}/rows/${id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(status)
const getRowUsage = async () => {
return config.doInContext(null, () => quotas.getCurrentUsageValue(QuotaUsageType.STATIC, StaticQuotaName.ROWS))
return config.doInContext(null, () =>
quotas.getCurrentUsageValue(QuotaUsageType.STATIC, StaticQuotaName.ROWS)
)
}
const getQueryUsage = async () => {
return config.doInContext(null, () => quotas.getCurrentUsageValue(QuotaUsageType.MONTHLY, MonthlyQuotaName.QUERIES))
return config.doInContext(null, () =>
quotas.getCurrentUsageValue(
QuotaUsageType.MONTHLY,
MonthlyQuotaName.QUERIES
)
)
}
const assertRowUsage = async (expected) => {
const assertRowUsage = async expected => {
const usage = await getRowUsage()
expect(usage).toBe(expected)
}
const assertQueryUsage = async (expected) => {
const assertQueryUsage = async expected => {
const usage = await getQueryUsage()
expect(usage).toBe(expected)
}
@ -76,10 +88,12 @@ describe("/rows", () => {
name: "Updated Name",
})
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.res.statusMessage).toEqual(`${table.name} updated successfully.`)
expect(res.res.statusMessage).toEqual(
`${table.name} updated successfully.`
)
expect(res.body.name).toEqual("Updated Name")
// await assertRowUsage(rowUsage)
// await assertQueryUsage(queryUsage + 1)
@ -92,7 +106,7 @@ describe("/rows", () => {
const res = await request
.get(`/api/${table._id}/rows/${existing._id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body).toEqual({
@ -110,7 +124,7 @@ describe("/rows", () => {
const newRow = {
tableId: table._id,
name: "Second Contact",
status: "new"
status: "new",
}
await config.createRow()
await config.createRow(newRow)
@ -119,7 +133,7 @@ describe("/rows", () => {
const res = await request
.get(`/api/${table._id}/rows`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.length).toBe(2)
@ -135,17 +149,36 @@ describe("/rows", () => {
await request
.get(`/api/${table._id}/rows/not-a-valid-id`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(404)
await assertQueryUsage(queryUsage) // no change
})
it("row values are coerced", async () => {
const str = {type:"string", constraints: { type: "string", presence: false }}
const attachment = {type:"attachment", constraints: { type: "array", presence: false }}
const bool = {type:"boolean", constraints: { type: "boolean", presence: false }}
const number = {type:"number", constraints: { type: "number", presence: false }}
const datetime = {type:"datetime", constraints: { type: "string", presence: false, datetime: {earliest:"", latest: ""} }}
const str = {
type: "string",
constraints: { type: "string", presence: false },
}
const attachment = {
type: "attachment",
constraints: { type: "array", presence: false },
}
const bool = {
type: "boolean",
constraints: { type: "boolean", presence: false },
}
const number = {
type: "number",
constraints: { type: "number", presence: false },
}
const datetime = {
type: "datetime",
constraints: {
type: "string",
presence: false,
datetime: { earliest: "", latest: "" },
},
}
table = await config.createTable({
name: "TestTable2",
@ -171,9 +204,9 @@ describe("/rows", () => {
boolUndefined: bool,
boolString: bool,
boolBool: bool,
attachmentNull : attachment,
attachmentUndefined : attachment,
attachmentEmpty : attachment,
attachmentNull: attachment,
attachmentUndefined: attachment,
attachmentEmpty: attachment,
},
})
@ -198,9 +231,9 @@ describe("/rows", () => {
boolString: "true",
boolBool: true,
tableId: table._id,
attachmentNull : null,
attachmentUndefined : undefined,
attachmentEmpty : "",
attachmentNull: null,
attachmentUndefined: undefined,
attachmentEmpty: "",
}
const id = (await config.createRow(row))._id
@ -218,7 +251,9 @@ describe("/rows", () => {
expect(saved.datetimeEmptyString).toBe(null)
expect(saved.datetimeNull).toBe(null)
expect(saved.datetimeUndefined).toBe(undefined)
expect(saved.datetimeString).toBe(new Date(row.datetimeString).toISOString())
expect(saved.datetimeString).toBe(
new Date(row.datetimeString).toISOString()
)
expect(saved.datetimeDate).toBe(row.datetimeDate.toISOString())
expect(saved.boolNull).toBe(null)
expect(saved.boolEmpty).toBe(null)
@ -247,10 +282,12 @@ describe("/rows", () => {
name: "Updated Name",
})
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.res.statusMessage).toEqual(`${table.name} updated successfully.`)
expect(res.res.statusMessage).toEqual(
`${table.name} updated successfully.`
)
expect(res.body.name).toEqual("Updated Name")
expect(res.body.description).toEqual(existing.description)
@ -292,16 +329,14 @@ describe("/rows", () => {
const res = await request
.delete(`/api/${table._id}/rows`)
.send({
rows: [
createdRow
]
rows: [createdRow],
})
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body[0]._id).toEqual(createdRow._id)
await assertRowUsage(rowUsage -1)
await assertQueryUsage(queryUsage +1)
await assertRowUsage(rowUsage - 1)
await assertQueryUsage(queryUsage + 1)
})
})
@ -314,9 +349,9 @@ describe("/rows", () => {
.post(`/api/${table._id}/rows/validate`)
.send({ name: "ivan" })
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.valid).toBe(true)
expect(Object.keys(res.body.errors)).toEqual([])
await assertRowUsage(rowUsage)
@ -331,9 +366,9 @@ describe("/rows", () => {
.post(`/api/${table._id}/rows/validate`)
.send({ name: 1 })
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.valid).toBe(false)
expect(Object.keys(res.body.errors)).toEqual(["name"])
await assertRowUsage(rowUsage)
@ -351,19 +386,16 @@ describe("/rows", () => {
const res = await request
.delete(`/api/${table._id}/rows`)
.send({
rows: [
row1,
row2,
]
rows: [row1, row2],
})
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.length).toEqual(2)
await loadRow(row1._id, 404)
await assertRowUsage(rowUsage - 2)
await assertQueryUsage(queryUsage +1)
await assertQueryUsage(queryUsage + 1)
})
})
@ -376,12 +408,12 @@ describe("/rows", () => {
const res = await request
.get(`/api/views/${table._id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.length).toEqual(1)
expect(res.body[0]._id).toEqual(row._id)
await assertRowUsage(rowUsage)
await assertQueryUsage(queryUsage +1)
await assertQueryUsage(queryUsage + 1)
})
it("should throw an error if view doesn't exist", async () => {
@ -406,7 +438,7 @@ describe("/rows", () => {
const res = await request
.get(`/api/views/${view.name}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.length).toEqual(1)
expect(res.body[0]._id).toEqual(row._id)
@ -418,21 +450,24 @@ describe("/rows", () => {
describe("fetchEnrichedRows", () => {
it("should allow enriching some linked rows", async () => {
const { table, firstRow, secondRow } = await doInTenant(setup.structures.TENANT_ID, async () => {
const table = await config.createLinkedTable()
const firstRow = await config.createRow({
name: "Test Contact",
description: "original description",
tableId: table._id
})
const secondRow = await config.createRow({
name: "Test 2",
description: "og desc",
link: [{_id: firstRow._id}],
tableId: table._id,
})
return { table, firstRow, secondRow }
})
const { table, firstRow, secondRow } = await doInTenant(
setup.structures.TENANT_ID,
async () => {
const table = await config.createLinkedTable()
const firstRow = await config.createRow({
name: "Test Contact",
description: "original description",
tableId: table._id,
})
const secondRow = await config.createRow({
name: "Test 2",
description: "og desc",
link: [{ _id: firstRow._id }],
tableId: table._id,
})
return { table, firstRow, secondRow }
}
)
const rowUsage = await getRowUsage()
const queryUsage = await getQueryUsage()
@ -440,7 +475,7 @@ describe("/rows", () => {
const resBasic = await request
.get(`/api/${table._id}/rows/${secondRow._id}`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.expect("Content-Type", /json/)
.expect(200)
expect(resBasic.body.link[0]._id).toBe(firstRow._id)
expect(resBasic.body.link[0].primaryDisplay).toBe("Test Contact")
@ -449,14 +484,14 @@ describe("/rows", () => {
const resEnriched = await request
.get(`/api/${table._id}/${secondRow._id}/enrich`)
.set(config.defaultHeaders())
.expect('Content-Type', /json/)
.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")
await assertRowUsage(rowUsage)
await assertQueryUsage(queryUsage +2)
await assertQueryUsage(queryUsage + 2)
})
})
@ -466,9 +501,11 @@ describe("/rows", () => {
const row = await config.createRow({
name: "test",
description: "test",
attachment: [{
key: `${config.getAppId()}/attachments/test/thing.csv`,
}],
attachment: [
{
key: `${config.getAppId()}/attachments/test/thing.csv`,
},
],
tableId: table._id,
})
// the environment needs configured for this
@ -482,4 +519,49 @@ describe("/rows", () => {
})
})
})
describe("exportData", () => {
it("should allow exporting all columns", async () => {
const existing = await config.createRow()
const res = await request
.post(`/api/${table._id}/rows/exportRows?format=json`)
.set(config.defaultHeaders())
.send({
rows: [existing._id],
})
.expect("Content-Type", /json/)
.expect(200)
const results = JSON.parse(res.text)
expect(results.length).toEqual(1)
const row = results[0]
// Ensure all original columns were exported
expect(Object.keys(row).length).toBeGreaterThanOrEqual(
Object.keys(existing).length
)
Object.keys(existing).forEach(key => {
expect(row[key]).toEqual(existing[key])
})
})
it("should allow exporting only certain columns", async () => {
const existing = await config.createRow()
const res = await request
.post(`/api/${table._id}/rows/exportRows?format=json`)
.set(config.defaultHeaders())
.send({
rows: [existing._id],
columns: ["_id"],
})
.expect("Content-Type", /json/)
.expect(200)
const results = JSON.parse(res.text)
expect(results.length).toEqual(1)
const row = results[0]
// Ensure only the _id column was exported
expect(Object.keys(row).length).toEqual(1)
expect(row._id).toEqual(existing._id)
})
})
})