Some final updates to view public API, adding test cases.

This commit is contained in:
mike12345567 2024-11-08 18:04:53 +00:00
parent a1c319a5d1
commit ce529d2f45
8 changed files with 161 additions and 37 deletions

View File

@ -456,6 +456,11 @@
"readonly": false
}
},
"query": {
"string": {
"column": "value"
}
},
"primaryDisplay": "name"
}
}
@ -484,6 +489,11 @@
"readonly": false
}
},
"query": {
"string": {
"column": "value"
}
},
"primaryDisplay": "name"
}
]
@ -2092,13 +2102,18 @@
"type": "object",
"required": [
"name",
"schema"
"schema",
"tableId"
],
"properties": {
"name": {
"description": "The name of the view.",
"type": "string"
},
"tableId": {
"description": "The ID of the table this view is based on.",
"type": "string"
},
"type": {
"description": "The type of view - standard (empty value) or calculation.",
"type": "string",
@ -2301,6 +2316,7 @@
"required": [
"name",
"schema",
"tableId",
"id"
],
"properties": {
@ -2308,6 +2324,10 @@
"description": "The name of the view.",
"type": "string"
},
"tableId": {
"description": "The ID of the table this view is based on.",
"type": "string"
},
"type": {
"description": "The type of view - standard (empty value) or calculation.",
"type": "string",
@ -2521,6 +2541,7 @@
"required": [
"name",
"schema",
"tableId",
"id"
],
"properties": {
@ -2528,6 +2549,10 @@
"description": "The name of the view.",
"type": "string"
},
"tableId": {
"description": "The ID of the table this view is based on.",
"type": "string"
},
"type": {
"description": "The type of view - standard (empty value) or calculation.",
"type": "string",

View File

@ -468,6 +468,9 @@ components:
salary:
visible: false
readonly: false
query:
string:
column: value
primaryDisplay: name
views:
value:
@ -488,6 +491,9 @@ components:
salary:
visible: false
readonly: false
query:
string:
column: value
primaryDisplay: name
securitySchemes:
ApiKeyAuth:
@ -1754,10 +1760,14 @@ components:
required:
- name
- schema
- tableId
properties:
name:
description: The name of the view.
type: string
tableId:
description: The ID of the table this view is based on.
type: string
type:
description: The type of view - standard (empty value) or calculation.
type: string
@ -1929,11 +1939,15 @@ components:
required:
- name
- schema
- tableId
- id
properties:
name:
description: The name of the view.
type: string
tableId:
description: The ID of the table this view is based on.
type: string
type:
description: The type of view - standard (empty value) or calculation.
type: string
@ -2112,11 +2126,15 @@ components:
required:
- name
- schema
- tableId
- id
properties:
name:
description: The name of the view.
type: string
tableId:
description: The ID of the table this view is based on.
type: string
type:
description: The type of view - standard (empty value) or calculation.
type: string

View File

@ -24,6 +24,11 @@ const view = {
readonly: false,
},
},
query: {
string: {
column: "value",
},
},
primaryDisplay: "name",
}
@ -66,12 +71,16 @@ const baseColumnDef = {
const viewSchema = {
description: "The view to be created/updated.",
type: "object",
required: ["name", "schema"],
required: ["name", "schema", "tableId"],
properties: {
name: {
description: "The name of the view.",
type: "string",
},
tableId: {
description: "The ID of the table this view is based on.",
type: "string",
},
type: {
description: "The type of view - standard (empty value) or calculation.",
type: "string",

View File

@ -1,23 +1,29 @@
import { View } from "./types"
import { ViewV2, Ctx } from "@budibase/types"
import { dataFilters } from "@budibase/shared-core"
function view(body: any): View {
function view(body: ViewV2): View {
return {
id: body.id,
tableId: body.tableId,
type: body.type,
name: body.name,
schema: body.schema,
schema: body.schema!,
primaryDisplay: body.primaryDisplay,
query: dataFilters.buildQuery(body.query),
sort: body.sort,
}
}
function mapView(ctx: any): { data: View } {
function mapView(ctx: Ctx<{ data: ViewV2 }>): { data: View } {
return {
data: view(ctx.body),
data: view(ctx.body.data),
}
}
function mapViews(ctx: any): { data: View[] } {
const tables = ctx.body.map((body: any) => view(body))
return { data: tables }
function mapViews(ctx: Ctx<{ data: ViewV2[] }>): { data: View[] } {
const views = ctx.body.data.map((body: ViewV2) => view(body))
return { data: views }
}
export default {

View File

@ -2,6 +2,7 @@ import { search as stringSearch } from "./utils"
import * as controller from "../view"
import { ViewV2, UserCtx } from "@budibase/types"
import { Next } from "koa"
import { merge } from "lodash"
function fixView(view: ViewV2, params?: { viewId: string }) {
if (!params || !view) {
@ -27,32 +28,41 @@ export async function search(ctx: UserCtx, next: Next) {
}
export async function create(ctx: UserCtx, next: Next) {
ctx.body = fixView(ctx.body)
await controller.v2.create(ctx)
await controller.v2.create(
merge(ctx, {
request: {
body: fixView(ctx.request.body),
},
})
)
await next()
}
export async function read(ctx: UserCtx, next: Next) {
await controller.v2.get({
...ctx,
params: {
viewId: ctx.params.viewId,
},
})
await controller.v2.get(
merge(ctx, {
params: {
viewId: ctx.params.viewId,
},
})
)
await next()
}
export async function update(ctx: UserCtx, next: Next) {
const viewId = ctx.params.viewId
await controller.v2.update({
...ctx,
body: {
data: fixView(ctx.body, { viewId }),
},
params: {
viewId,
},
})
await controller.v2.update(
merge(ctx, {
request: {
body: {
data: fixView(ctx.request.body, { viewId }),
},
},
params: {
viewId,
},
})
)
await next()
}

View File

@ -173,4 +173,18 @@ export class PublicViewAPI {
): Promise<Response<ViewV2[]>> {
return this.request.send("get", "/views", undefined, expectations)
}
async search(
viewName: string,
expectations?: PublicAPIExpectations
): Promise<Response<ViewV2[]>> {
return this.request.send(
"post",
"/views/search",
{
name: viewName,
},
expectations
)
}
}

View File

@ -2,6 +2,7 @@ import * as setup from "../../tests/utilities"
import { basicTable } from "../../../../tests/utilities/structures"
import { Table } from "@budibase/types"
import { PublicAPIRequest } from "./Request"
import { generator } from "@budibase/backend-core/tests"
describe("check public API security", () => {
const config = setup.getConfig()
@ -13,20 +14,55 @@ describe("check public API security", () => {
table = (await request.tables.create(basicTable())).data
})
it("should be able to create a view", async () => {
await request.views.create(
{
name: "view",
tableId: table._id!,
query: {},
schema: {
name: {
readonly: true,
visible: true,
},
function baseView() {
return {
name: generator.word(),
tableId: table._id!,
query: {},
schema: {
name: {
readonly: true,
visible: true,
},
},
}
}
it("should be able to create a view", async () => {
await request.views.create(baseView(), { status: 201 })
})
it("should be able to update a view", async () => {
const view = await request.views.create(baseView(), { status: 201 })
await request.views.update(
view.data.id,
{
...view.data,
name: "new name",
},
{ status: 200 }
)
})
it("should be able to search views", async () => {
const viewName = "view to search for"
const view = await request.views.create(
{
...baseView(),
name: viewName,
},
{ status: 201 }
)
const results = await request.views.search(viewName, {
status: 200,
})
expect(results.data.length).toEqual(1)
expect(results.data[0].id).toEqual(view.data.id)
})
it("should be able to delete a view", async () => {
const view = await request.views.create(baseView(), { status: 201 })
const result = await request.views.destroy(view.data.id, { status: 204 })
expect(result).toBeDefined()
})
})

View File

@ -836,6 +836,8 @@ export interface components {
view: {
/** @description The name of the view. */
name: string;
/** @description The ID of the table this view is based on. */
tableId: string;
/**
* @description The type of view - standard (empty value) or calculation.
* @enum {string}
@ -935,6 +937,8 @@ export interface components {
data: {
/** @description The name of the view. */
name: string;
/** @description The ID of the table this view is based on. */
tableId: string;
/**
* @description The type of view - standard (empty value) or calculation.
* @enum {string}
@ -1036,6 +1040,8 @@ export interface components {
data: {
/** @description The name of the view. */
name: string;
/** @description The ID of the table this view is based on. */
tableId: string;
/**
* @description The type of view - standard (empty value) or calculation.
* @enum {string}