Updating test cases, fixes based on running through view/row API.
This commit is contained in:
parent
2011e1693e
commit
0abd1deb34
|
@ -15,6 +15,7 @@ import {
|
|||
UserCtx,
|
||||
} from "@budibase/types"
|
||||
import sdk from "../../../sdk"
|
||||
import * as utils from "./utils"
|
||||
|
||||
export async function handleRequest(
|
||||
operation: Operation,
|
||||
|
@ -43,7 +44,7 @@ export async function handleRequest(
|
|||
}
|
||||
|
||||
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const { _id, ...rowData } = ctx.request.body
|
||||
|
||||
const validateResult = await sdk.rows.utils.validate({
|
||||
|
@ -70,7 +71,7 @@ export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
|||
|
||||
export async function save(ctx: UserCtx) {
|
||||
const inputs = ctx.request.body
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const validateResult = await sdk.rows.utils.validate({
|
||||
row: inputs,
|
||||
tableId,
|
||||
|
@ -98,12 +99,12 @@ export async function save(ctx: UserCtx) {
|
|||
|
||||
export async function find(ctx: UserCtx) {
|
||||
const id = ctx.params.rowId
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
return sdk.rows.external.getRow(tableId, id)
|
||||
}
|
||||
|
||||
export async function destroy(ctx: UserCtx) {
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const _id = ctx.request.body._id
|
||||
const { row } = (await handleRequest(Operation.DELETE, tableId, {
|
||||
id: breakRowIdField(_id),
|
||||
|
@ -114,7 +115,7 @@ export async function destroy(ctx: UserCtx) {
|
|||
|
||||
export async function bulkDestroy(ctx: UserCtx) {
|
||||
const { rows } = ctx.request.body
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
let promises: Promise<Row[] | { row: Row; table: Table }>[] = []
|
||||
for (let row of rows) {
|
||||
promises.push(
|
||||
|
@ -130,7 +131,7 @@ export async function bulkDestroy(ctx: UserCtx) {
|
|||
|
||||
export async function fetchEnrichedRow(ctx: UserCtx) {
|
||||
const id = ctx.params.rowId
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
||||
const datasource: Datasource = await sdk.datasources.get(datasourceId!)
|
||||
if (!tableName) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
import { FieldTypes } from "../../../constants"
|
||||
import * as utils from "./utils"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import { context, db as dbCore } from "@budibase/backend-core"
|
||||
import { context } from "@budibase/backend-core"
|
||||
import { finaliseRow, updateRelatedFormula } from "./staticFormula"
|
||||
import {
|
||||
UserCtx,
|
||||
|
@ -26,8 +26,8 @@ import {
|
|||
import sdk from "../../../sdk"
|
||||
|
||||
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const inputs = ctx.request.body
|
||||
const tableId = inputs.tableId
|
||||
const isUserTable = tableId === InternalTables.USER_METADATA
|
||||
let oldRow
|
||||
const dbTable = await sdk.tables.getTable(tableId)
|
||||
|
@ -94,7 +94,8 @@ export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
|||
|
||||
export async function save(ctx: UserCtx) {
|
||||
let inputs = ctx.request.body
|
||||
inputs.tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
inputs.tableId = tableId
|
||||
|
||||
if (!inputs._rev && !inputs._id) {
|
||||
inputs._id = generateRowID(inputs.tableId)
|
||||
|
@ -132,20 +133,22 @@ export async function save(ctx: UserCtx) {
|
|||
}
|
||||
|
||||
export async function find(ctx: UserCtx) {
|
||||
const db = dbCore.getDB(ctx.appId)
|
||||
const table = await sdk.tables.getTable(ctx.params.tableId)
|
||||
let row = await utils.findRow(ctx, ctx.params.tableId, ctx.params.rowId)
|
||||
const tableId = utils.getTableId(ctx),
|
||||
rowId = ctx.params.rowId
|
||||
const table = await sdk.tables.getTable(tableId)
|
||||
let row = await utils.findRow(ctx, tableId, rowId)
|
||||
row = await outputProcessing(table, row)
|
||||
return row
|
||||
}
|
||||
|
||||
export async function destroy(ctx: UserCtx) {
|
||||
const db = context.getAppDB()
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const { _id } = ctx.request.body
|
||||
let row = await db.get<Row>(_id)
|
||||
let _rev = ctx.request.body._rev || row._rev
|
||||
|
||||
if (row.tableId !== ctx.params.tableId) {
|
||||
if (row.tableId !== tableId) {
|
||||
throw "Supplied tableId doesn't match the row's tableId"
|
||||
}
|
||||
const table = await sdk.tables.getTable(row.tableId)
|
||||
|
@ -163,7 +166,7 @@ export async function destroy(ctx: UserCtx) {
|
|||
await updateRelatedFormula(table, row)
|
||||
|
||||
let response
|
||||
if (ctx.params.tableId === InternalTables.USER_METADATA) {
|
||||
if (tableId === InternalTables.USER_METADATA) {
|
||||
ctx.params = {
|
||||
id: _id,
|
||||
}
|
||||
|
@ -176,7 +179,7 @@ export async function destroy(ctx: UserCtx) {
|
|||
}
|
||||
|
||||
export async function bulkDestroy(ctx: UserCtx) {
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const table = await sdk.tables.getTable(tableId)
|
||||
let { rows } = ctx.request.body
|
||||
|
||||
|
@ -216,7 +219,7 @@ export async function bulkDestroy(ctx: UserCtx) {
|
|||
|
||||
export async function fetchEnrichedRow(ctx: UserCtx) {
|
||||
const db = context.getAppDB()
|
||||
const tableId = ctx.params.tableId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
const rowId = ctx.params.rowId
|
||||
// need table to work out where links go in row
|
||||
let [table, row] = await Promise.all([
|
||||
|
|
|
@ -45,15 +45,19 @@ export async function findRow(ctx: UserCtx, tableId: string, rowId: string) {
|
|||
}
|
||||
|
||||
export function getTableId(ctx: Ctx) {
|
||||
if (ctx.request.body?.tableId) {
|
||||
return ctx.request.body.tableId
|
||||
}
|
||||
// top priority, use the URL first
|
||||
if (ctx.params?.sourceId) {
|
||||
return ctx.params.sourceId
|
||||
}
|
||||
// check body for a table ID
|
||||
if (ctx.request.body?.tableId) {
|
||||
return ctx.request.body.tableId
|
||||
}
|
||||
// now check for old way of specifying table ID
|
||||
if (ctx.params?.tableId) {
|
||||
return ctx.params.tableId
|
||||
}
|
||||
// now check if a specific view name
|
||||
if (ctx.params?.viewName) {
|
||||
return ctx.params.viewName
|
||||
}
|
||||
|
|
|
@ -16,15 +16,12 @@ import {
|
|||
FieldType,
|
||||
SortType,
|
||||
SortOrder,
|
||||
DeleteRow,
|
||||
} from "@budibase/types"
|
||||
import {
|
||||
expectAnyInternalColsAttributes,
|
||||
generator,
|
||||
structures,
|
||||
} from "@budibase/backend-core/tests"
|
||||
import trimViewRowInfoMiddleware from "../../../middleware/trimViewRowInfo"
|
||||
import router from "../row"
|
||||
|
||||
describe("/rows", () => {
|
||||
let request = setup.getRequest()
|
||||
|
@ -393,18 +390,6 @@ describe("/rows", () => {
|
|||
expect(saved.arrayFieldArrayStrKnown).toEqual(["One"])
|
||||
expect(saved.optsFieldStrKnown).toEqual("Alpha")
|
||||
})
|
||||
|
||||
it("should throw an error when creating a table row with view id data", async () => {
|
||||
const res = await request
|
||||
.post(`/api/${row.tableId}/rows`)
|
||||
.send({ ...row, _viewId: generator.guid() })
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(400)
|
||||
expect(res.body.message).toEqual(
|
||||
"Table row endpoints cannot contain view info"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("patch", () => {
|
||||
|
@ -454,25 +439,6 @@ describe("/rows", () => {
|
|||
await assertRowUsage(rowUsage)
|
||||
await assertQueryUsage(queryUsage)
|
||||
})
|
||||
|
||||
it("should throw an error when creating a table row with view id data", async () => {
|
||||
const existing = await config.createRow()
|
||||
|
||||
const res = await config.api.row.patch(
|
||||
table._id!,
|
||||
{
|
||||
...existing,
|
||||
_id: existing._id!,
|
||||
_rev: existing._rev!,
|
||||
tableId: table._id!,
|
||||
_viewId: generator.guid(),
|
||||
},
|
||||
{ expectStatus: 400 }
|
||||
)
|
||||
expect(res.body.message).toEqual(
|
||||
"Table row endpoints cannot contain view info"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("destroy", () => {
|
||||
|
@ -741,7 +707,7 @@ describe("/rows", () => {
|
|||
})
|
||||
// the environment needs configured for this
|
||||
await setup.switchToSelfHosted(async () => {
|
||||
context.doInAppContext(config.getAppId(), async () => {
|
||||
return context.doInAppContext(config.getAppId(), async () => {
|
||||
const enriched = await outputProcessing(table, [row])
|
||||
expect((enriched as Row[])[0].attachment[0].url).toBe(
|
||||
`/files/signed/prod-budi-app-assets/${config.getProdAppId()}/attachments/${attachmentId}`
|
||||
|
@ -847,7 +813,7 @@ describe("/rows", () => {
|
|||
})
|
||||
|
||||
const data = randomRowData()
|
||||
const newRow = await config.api.viewV2.row.create(view.id, {
|
||||
const newRow = await config.api.row.save(view.id, {
|
||||
tableId: config.table!._id,
|
||||
_viewId: view.id,
|
||||
...data,
|
||||
|
@ -869,16 +835,6 @@ describe("/rows", () => {
|
|||
expect(row.body.age).toBeUndefined()
|
||||
expect(row.body.jobTitle).toBeUndefined()
|
||||
})
|
||||
|
||||
it("should setup the trimViewRowInfo middleware", async () => {
|
||||
const route = router.stack.find(
|
||||
r =>
|
||||
r.methods.includes("POST") &&
|
||||
r.path === "/api/v2/views/:viewId/rows"
|
||||
)
|
||||
expect(route).toBeDefined()
|
||||
expect(route?.stack).toContainEqual(trimViewRowInfoMiddleware)
|
||||
})
|
||||
})
|
||||
|
||||
describe("patch", () => {
|
||||
|
@ -893,13 +849,13 @@ describe("/rows", () => {
|
|||
},
|
||||
})
|
||||
|
||||
const newRow = await config.api.viewV2.row.create(view.id, {
|
||||
const newRow = await config.api.row.save(view.id, {
|
||||
tableId,
|
||||
_viewId: view.id,
|
||||
...randomRowData(),
|
||||
})
|
||||
const newData = randomRowData()
|
||||
await config.api.viewV2.row.update(view.id, newRow._id!, {
|
||||
await config.api.row.patch(view.id, {
|
||||
tableId,
|
||||
_viewId: view.id,
|
||||
_id: newRow._id!,
|
||||
|
@ -922,16 +878,6 @@ describe("/rows", () => {
|
|||
expect(row.body.age).toBeUndefined()
|
||||
expect(row.body.jobTitle).toBeUndefined()
|
||||
})
|
||||
|
||||
it("should setup the trimViewRowInfo middleware", async () => {
|
||||
const route = router.stack.find(
|
||||
r =>
|
||||
r.methods.includes("PATCH") &&
|
||||
r.path === "/api/v2/views/:viewId/rows/:rowId"
|
||||
)
|
||||
expect(route).toBeDefined()
|
||||
expect(route?.stack).toContainEqual(trimViewRowInfoMiddleware)
|
||||
})
|
||||
})
|
||||
|
||||
describe("destroy", () => {
|
||||
|
@ -950,10 +896,7 @@ describe("/rows", () => {
|
|||
const rowUsage = await getRowUsage()
|
||||
const queryUsage = await getQueryUsage()
|
||||
|
||||
const body: DeleteRow = {
|
||||
_id: createdRow._id!,
|
||||
}
|
||||
await config.api.viewV2.row.delete(view.id, body)
|
||||
await config.api.row.delete(view.id, [createdRow])
|
||||
|
||||
await assertRowUsage(rowUsage - 1)
|
||||
await assertQueryUsage(queryUsage + 1)
|
||||
|
@ -982,9 +925,7 @@ describe("/rows", () => {
|
|||
const rowUsage = await getRowUsage()
|
||||
const queryUsage = await getQueryUsage()
|
||||
|
||||
await config.api.viewV2.row.delete(view.id, {
|
||||
rows: [rows[0], rows[2]],
|
||||
})
|
||||
await config.api.row.delete(view.id, [rows[0], rows[2]])
|
||||
|
||||
await assertRowUsage(rowUsage - 2)
|
||||
await assertQueryUsage(queryUsage + 1)
|
||||
|
|
|
@ -3,26 +3,35 @@ import * as utils from "../db/utils"
|
|||
import sdk from "../sdk"
|
||||
import { db } from "@budibase/backend-core"
|
||||
import { Next } from "koa"
|
||||
import { getTableId } from "../api/controllers/row/utils"
|
||||
|
||||
export default async (ctx: Ctx<Row>, next: Next) => {
|
||||
const { body } = ctx.request
|
||||
const { _viewId: viewId } = body
|
||||
let { _viewId: viewId } = body
|
||||
|
||||
const possibleViewId = ctx.params.tableId
|
||||
const possibleViewId = getTableId(ctx)
|
||||
if (utils.isViewID(possibleViewId)) {
|
||||
viewId = possibleViewId
|
||||
}
|
||||
|
||||
// nothing to do, it is not a view (just a table ID)
|
||||
if (!viewId || !utils.isViewID(possibleViewId)) {
|
||||
if (!viewId) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const { tableId } = utils.extractViewInfoFromID(possibleViewId)
|
||||
const { _viewId, ...trimmedView } = await trimViewFields(
|
||||
viewId,
|
||||
tableId,
|
||||
body
|
||||
)
|
||||
ctx.request.body = trimmedView
|
||||
ctx.params.tableId = tableId
|
||||
const { tableId } = utils.extractViewInfoFromID(viewId)
|
||||
|
||||
// don't need to trim delete requests
|
||||
if (ctx.method.toLowerCase() !== "delete") {
|
||||
const { _viewId, ...trimmedView } = await trimViewFields(
|
||||
viewId,
|
||||
tableId,
|
||||
body
|
||||
)
|
||||
ctx.request.body = trimmedView
|
||||
}
|
||||
|
||||
ctx.params.sourceId = tableId
|
||||
|
||||
return next()
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PatchRowRequest } from "@budibase/types"
|
||||
import { PatchRowRequest, SaveRowRequest, Row } from "@budibase/types"
|
||||
import TestConfiguration from "../TestConfiguration"
|
||||
import { TestAPI } from "./base"
|
||||
|
||||
|
@ -8,12 +8,12 @@ export class RowAPI extends TestAPI {
|
|||
}
|
||||
|
||||
get = async (
|
||||
tableId: string,
|
||||
sourceId: string,
|
||||
rowId: string,
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
) => {
|
||||
const request = this.request
|
||||
.get(`/api/${tableId}/rows/${rowId}`)
|
||||
.get(`/api/${sourceId}/rows/${rowId}`)
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect(expectStatus)
|
||||
if (expectStatus !== 404) {
|
||||
|
@ -22,16 +22,43 @@ export class RowAPI extends TestAPI {
|
|||
return request
|
||||
}
|
||||
|
||||
save = async (
|
||||
sourceId: string,
|
||||
row: SaveRowRequest,
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
): Promise<Row> => {
|
||||
const resp = await this.request
|
||||
.post(`/api/${sourceId}/rows`)
|
||||
.send(row)
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(expectStatus)
|
||||
return resp.body as Row
|
||||
}
|
||||
|
||||
patch = async (
|
||||
tableId: string,
|
||||
sourceId: string,
|
||||
row: PatchRowRequest,
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
) => {
|
||||
return this.request
|
||||
.patch(`/api/${tableId}/rows`)
|
||||
.patch(`/api/${sourceId}/rows`)
|
||||
.send(row)
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(expectStatus)
|
||||
}
|
||||
|
||||
delete = async (
|
||||
sourceId: string,
|
||||
rows: Row[],
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
) => {
|
||||
return this.request
|
||||
.delete(`/api/${sourceId}/rows`)
|
||||
.send({ rows })
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(expectStatus)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import {
|
||||
CreateViewRequest,
|
||||
UpdateViewRequest,
|
||||
DeleteRowRequest,
|
||||
PatchRowRequest,
|
||||
PatchRowResponse,
|
||||
Row,
|
||||
ViewV2,
|
||||
SearchViewRowRequest,
|
||||
} from "@budibase/types"
|
||||
|
@ -90,46 +86,4 @@ export class ViewV2API extends TestAPI {
|
|||
.expect("Content-Type", /json/)
|
||||
.expect(expectStatus)
|
||||
}
|
||||
|
||||
row = {
|
||||
create: async (
|
||||
viewId: string,
|
||||
row: Row,
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
): Promise<Row> => {
|
||||
const result = await this.request
|
||||
.post(`/api/v2/views/${viewId}/rows`)
|
||||
.send(row)
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(expectStatus)
|
||||
return result.body as Row
|
||||
},
|
||||
update: async (
|
||||
viewId: string,
|
||||
rowId: string,
|
||||
row: PatchRowRequest,
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
): Promise<PatchRowResponse> => {
|
||||
const result = await this.request
|
||||
.patch(`/api/v2/views/${viewId}/rows/${rowId}`)
|
||||
.send(row)
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(expectStatus)
|
||||
return result.body as PatchRowResponse
|
||||
},
|
||||
delete: async (
|
||||
viewId: string,
|
||||
body: DeleteRowRequest,
|
||||
{ expectStatus } = { expectStatus: 200 }
|
||||
): Promise<any> => {
|
||||
const result = await this.request
|
||||
.delete(`/api/v2/views/${viewId}/rows`)
|
||||
.send(body)
|
||||
.set(this.config.defaultHeaders())
|
||||
.expect(expectStatus)
|
||||
return result.body
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { SearchParams } from "../../../sdk"
|
||||
import { Row } from "../../../documents"
|
||||
|
||||
export interface SaveRowRequest extends Row {}
|
||||
|
||||
export interface PatchRowRequest extends Row {
|
||||
_id: string
|
||||
_rev: string
|
||||
|
|
Loading…
Reference in New Issue