2023-07-12 16:13:00 +02:00
|
|
|
import * as setup from "./utilities"
|
2023-07-19 15:43:21 +02:00
|
|
|
import {
|
|
|
|
CreateViewRequest,
|
2024-03-14 18:11:09 +01:00
|
|
|
Datasource,
|
2023-08-01 12:08:40 +02:00
|
|
|
FieldSchema,
|
2023-07-19 15:43:21 +02:00
|
|
|
FieldType,
|
2023-10-26 14:19:09 +02:00
|
|
|
INTERNAL_TABLE_SOURCE_ID,
|
2024-03-14 18:11:09 +01:00
|
|
|
SaveTableRequest,
|
2023-10-12 17:31:32 +02:00
|
|
|
SearchQueryOperators,
|
2023-07-19 15:43:21 +02:00
|
|
|
SortOrder,
|
|
|
|
SortType,
|
|
|
|
Table,
|
2023-10-26 14:19:09 +02:00
|
|
|
TableSourceType,
|
2023-09-12 20:17:21 +02:00
|
|
|
UIFieldMetadata,
|
2023-08-02 13:37:58 +02:00
|
|
|
UpdateViewRequest,
|
2023-07-19 15:43:21 +02:00
|
|
|
ViewV2,
|
|
|
|
} from "@budibase/types"
|
2023-10-12 20:00:53 +02:00
|
|
|
import { generator } from "@budibase/backend-core/tests"
|
2024-03-14 18:11:09 +01:00
|
|
|
import * as uuid from "uuid"
|
|
|
|
import { databaseTestProviders } from "../../../integrations/tests/utils"
|
|
|
|
import merge from "lodash/merge"
|
2023-07-12 16:13:00 +02:00
|
|
|
|
2024-03-14 18:11:09 +01:00
|
|
|
jest.unmock("mysql2")
|
|
|
|
jest.unmock("mysql2/promise")
|
|
|
|
jest.unmock("mssql")
|
|
|
|
jest.unmock("pg")
|
2023-08-29 16:13:44 +02:00
|
|
|
|
|
|
|
describe.each([
|
2024-03-14 18:11:09 +01:00
|
|
|
["internal", undefined],
|
|
|
|
["postgres", databaseTestProviders.postgres],
|
|
|
|
["mysql", databaseTestProviders.mysql],
|
|
|
|
["mssql", databaseTestProviders.mssql],
|
|
|
|
["mariadb", databaseTestProviders.mariadb],
|
|
|
|
])("/v2/views (%s)", (_, dsProvider) => {
|
|
|
|
const config = setup.getConfig()
|
2023-07-12 16:13:00 +02:00
|
|
|
|
2023-08-29 16:13:44 +02:00
|
|
|
let table: Table
|
2024-03-14 18:11:09 +01:00
|
|
|
let datasource: Datasource
|
|
|
|
|
|
|
|
function saveTableRequest(
|
|
|
|
...overrides: Partial<SaveTableRequest>[]
|
|
|
|
): SaveTableRequest {
|
|
|
|
const req: SaveTableRequest = {
|
|
|
|
name: uuid.v4().substring(0, 16),
|
|
|
|
type: "table",
|
|
|
|
sourceType: datasource
|
|
|
|
? TableSourceType.EXTERNAL
|
|
|
|
: TableSourceType.INTERNAL,
|
|
|
|
sourceId: datasource ? datasource._id! : INTERNAL_TABLE_SOURCE_ID,
|
|
|
|
primary: ["id"],
|
|
|
|
schema: {
|
|
|
|
id: {
|
|
|
|
type: FieldType.AUTO,
|
|
|
|
name: "id",
|
|
|
|
autocolumn: true,
|
|
|
|
constraints: {
|
|
|
|
presence: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return merge(req, ...overrides)
|
|
|
|
}
|
|
|
|
|
|
|
|
function priceTable(): SaveTableRequest {
|
|
|
|
return saveTableRequest({
|
|
|
|
schema: {
|
|
|
|
Price: {
|
|
|
|
type: FieldType.NUMBER,
|
|
|
|
name: "Price",
|
|
|
|
constraints: {},
|
|
|
|
},
|
|
|
|
Category: {
|
|
|
|
type: FieldType.STRING,
|
|
|
|
name: "Category",
|
|
|
|
constraints: {
|
|
|
|
type: "string",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
2023-07-12 16:13:00 +02:00
|
|
|
|
|
|
|
beforeAll(async () => {
|
2024-03-14 18:11:09 +01:00
|
|
|
await config.init()
|
|
|
|
|
|
|
|
if (dsProvider) {
|
|
|
|
datasource = await config.createDatasource({
|
|
|
|
datasource: await dsProvider.datasource(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
table = await config.api.table.save(priceTable())
|
2023-07-12 16:13:00 +02:00
|
|
|
})
|
|
|
|
|
2024-03-14 18:11:09 +01:00
|
|
|
afterAll(async () => {
|
|
|
|
if (dsProvider) {
|
|
|
|
await dsProvider.stop()
|
|
|
|
}
|
|
|
|
setup.afterAll()
|
|
|
|
})
|
2023-08-29 16:13:44 +02:00
|
|
|
|
2023-07-12 16:13:00 +02:00
|
|
|
describe("create", () => {
|
|
|
|
it("persist the view when the view is successfully created", async () => {
|
2023-07-19 15:43:21 +02:00
|
|
|
const newView: CreateViewRequest = {
|
2023-07-18 10:14:13 +02:00
|
|
|
name: generator.name(),
|
2023-08-29 16:13:44 +02:00
|
|
|
tableId: table._id!,
|
2023-07-18 10:14:13 +02:00
|
|
|
}
|
2023-07-19 18:26:24 +02:00
|
|
|
const res = await config.api.viewV2.create(newView)
|
2023-07-12 16:13:00 +02:00
|
|
|
|
2023-07-19 12:38:01 +02:00
|
|
|
expect(res).toEqual({
|
|
|
|
...newView,
|
2023-08-29 16:13:44 +02:00
|
|
|
id: expect.stringMatching(new RegExp(`${table._id!}_`)),
|
2023-07-19 15:43:21 +02:00
|
|
|
version: 2,
|
2023-07-12 16:13:00 +02:00
|
|
|
})
|
|
|
|
})
|
2023-07-18 14:34:23 +02:00
|
|
|
|
2023-08-02 13:37:58 +02:00
|
|
|
it("can persist views with all fields", async () => {
|
|
|
|
const newView: Required<CreateViewRequest> = {
|
2023-07-18 14:34:23 +02:00
|
|
|
name: generator.name(),
|
2023-08-29 16:13:44 +02:00
|
|
|
tableId: table._id!,
|
2023-08-02 13:37:58 +02:00
|
|
|
primaryDisplay: generator.word(),
|
2023-10-12 20:00:53 +02:00
|
|
|
query: [
|
|
|
|
{
|
|
|
|
operator: SearchQueryOperators.EQUAL,
|
|
|
|
field: "field",
|
|
|
|
value: "value",
|
|
|
|
},
|
|
|
|
],
|
2023-08-02 13:37:58 +02:00
|
|
|
sort: {
|
|
|
|
field: "fieldToSort",
|
|
|
|
order: SortOrder.DESCENDING,
|
|
|
|
type: SortType.STRING,
|
|
|
|
},
|
|
|
|
schema: {
|
|
|
|
name: {
|
|
|
|
visible: true,
|
|
|
|
},
|
|
|
|
},
|
2023-07-18 14:34:23 +02:00
|
|
|
}
|
2023-07-19 18:26:24 +02:00
|
|
|
const res = await config.api.viewV2.create(newView)
|
2023-07-18 14:34:23 +02:00
|
|
|
|
2023-07-19 12:50:52 +02:00
|
|
|
expect(res).toEqual({
|
|
|
|
...newView,
|
2023-08-11 16:52:13 +02:00
|
|
|
schema: newView.schema,
|
2023-07-19 15:43:21 +02:00
|
|
|
id: expect.any(String),
|
|
|
|
version: 2,
|
2023-07-18 14:34:23 +02:00
|
|
|
})
|
|
|
|
})
|
2023-08-01 10:45:00 +02:00
|
|
|
|
2023-08-01 10:57:03 +02:00
|
|
|
it("persist only UI schema overrides", async () => {
|
2023-08-01 10:45:00 +02:00
|
|
|
const newView: CreateViewRequest = {
|
|
|
|
name: generator.name(),
|
2023-08-29 16:13:44 +02:00
|
|
|
tableId: table._id!,
|
2023-08-01 10:45:00 +02:00
|
|
|
schema: {
|
2023-08-01 11:31:58 +02:00
|
|
|
Price: {
|
|
|
|
name: "Price",
|
|
|
|
type: FieldType.NUMBER,
|
2023-08-01 10:45:00 +02:00
|
|
|
visible: true,
|
2023-08-01 10:57:03 +02:00
|
|
|
order: 1,
|
|
|
|
width: 100,
|
2023-08-01 10:45:00 +02:00
|
|
|
},
|
2023-08-01 11:31:58 +02:00
|
|
|
Category: {
|
|
|
|
name: "Category",
|
2023-08-01 10:45:00 +02:00
|
|
|
type: FieldType.STRING,
|
|
|
|
visible: false,
|
2023-08-01 10:57:03 +02:00
|
|
|
icon: "ic",
|
2023-08-01 10:45:00 +02:00
|
|
|
},
|
2023-08-01 12:08:40 +02:00
|
|
|
} as Record<string, FieldSchema>,
|
2023-08-01 10:45:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const createdView = await config.api.viewV2.create(newView)
|
|
|
|
|
|
|
|
expect(await config.api.viewV2.get(createdView.id)).toEqual({
|
|
|
|
...newView,
|
2023-08-11 16:52:13 +02:00
|
|
|
schema: {
|
2023-08-01 11:31:58 +02:00
|
|
|
Price: {
|
2023-08-01 10:45:00 +02:00
|
|
|
visible: true,
|
2023-08-01 10:57:03 +02:00
|
|
|
order: 1,
|
|
|
|
width: 100,
|
2023-08-01 10:45:00 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
id: createdView.id,
|
|
|
|
version: 2,
|
|
|
|
})
|
|
|
|
})
|
2023-08-01 11:31:58 +02:00
|
|
|
|
|
|
|
it("will not throw an exception if the schema is 'deleting' non UI fields", async () => {
|
|
|
|
const newView: CreateViewRequest = {
|
|
|
|
name: generator.name(),
|
2023-08-29 16:13:44 +02:00
|
|
|
tableId: table._id!,
|
2023-08-01 11:31:58 +02:00
|
|
|
schema: {
|
|
|
|
Price: {
|
|
|
|
name: "Price",
|
|
|
|
type: FieldType.NUMBER,
|
|
|
|
visible: true,
|
|
|
|
},
|
|
|
|
Category: {
|
|
|
|
name: "Category",
|
|
|
|
type: FieldType.STRING,
|
|
|
|
},
|
2023-08-01 12:08:40 +02:00
|
|
|
} as Record<string, FieldSchema>,
|
2023-08-01 11:31:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
await config.api.viewV2.create(newView, {
|
2024-03-01 18:35:51 +01:00
|
|
|
status: 201,
|
2023-08-01 11:31:58 +02:00
|
|
|
})
|
|
|
|
})
|
2023-07-12 16:13:00 +02:00
|
|
|
})
|
2023-07-12 18:09:13 +02:00
|
|
|
|
2023-07-25 15:34:25 +02:00
|
|
|
describe("update", () => {
|
|
|
|
let view: ViewV2
|
|
|
|
|
2023-07-25 15:41:04 +02:00
|
|
|
beforeEach(async () => {
|
2024-03-14 18:11:09 +01:00
|
|
|
table = await config.api.table.save(priceTable())
|
2023-08-29 16:39:19 +02:00
|
|
|
|
2024-03-14 18:11:09 +01:00
|
|
|
view = await config.api.viewV2.create({
|
|
|
|
tableId: table._id!,
|
|
|
|
name: "View A",
|
|
|
|
})
|
2023-07-25 15:34:25 +02:00
|
|
|
})
|
|
|
|
|
2023-07-25 15:35:48 +02:00
|
|
|
it("can update an existing view data", async () => {
|
2023-08-29 16:13:44 +02:00
|
|
|
const tableId = table._id!
|
2023-07-25 15:35:48 +02:00
|
|
|
await config.api.viewV2.update({
|
|
|
|
...view,
|
2023-10-12 20:00:53 +02:00
|
|
|
query: [
|
|
|
|
{
|
|
|
|
operator: SearchQueryOperators.EQUAL,
|
|
|
|
field: "newField",
|
|
|
|
value: "thatValue",
|
|
|
|
},
|
|
|
|
],
|
2023-07-25 15:35:48 +02:00
|
|
|
})
|
|
|
|
|
2023-08-29 16:39:19 +02:00
|
|
|
expect((await config.api.table.get(tableId)).views).toEqual({
|
|
|
|
[view.name]: {
|
|
|
|
...view,
|
|
|
|
query: [{ operator: "equal", field: "newField", value: "thatValue" }],
|
|
|
|
schema: expect.anything(),
|
2023-07-25 15:35:48 +02:00
|
|
|
},
|
2023-08-02 13:37:58 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it("can update all fields", async () => {
|
2023-08-29 16:13:44 +02:00
|
|
|
const tableId = table._id!
|
2023-08-02 13:37:58 +02:00
|
|
|
|
|
|
|
const updatedData: Required<UpdateViewRequest> = {
|
|
|
|
version: view.version,
|
|
|
|
id: view.id,
|
|
|
|
tableId,
|
|
|
|
name: view.name,
|
|
|
|
primaryDisplay: generator.word(),
|
2023-08-07 13:16:23 +02:00
|
|
|
query: [
|
|
|
|
{
|
2023-10-12 17:31:32 +02:00
|
|
|
operator: SearchQueryOperators.EQUAL,
|
2023-08-07 13:16:23 +02:00
|
|
|
field: generator.word(),
|
|
|
|
value: generator.word(),
|
|
|
|
},
|
|
|
|
],
|
2023-08-02 13:37:58 +02:00
|
|
|
sort: {
|
|
|
|
field: generator.word(),
|
|
|
|
order: SortOrder.DESCENDING,
|
|
|
|
type: SortType.STRING,
|
|
|
|
},
|
|
|
|
schema: {
|
|
|
|
Category: {
|
|
|
|
visible: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
await config.api.viewV2.update(updatedData)
|
|
|
|
|
2023-08-29 16:39:19 +02:00
|
|
|
expect((await config.api.table.get(tableId)).views).toEqual({
|
|
|
|
[view.name]: {
|
|
|
|
...updatedData,
|
|
|
|
schema: {
|
|
|
|
...table.schema,
|
2024-03-14 18:11:09 +01:00
|
|
|
id: expect.objectContaining({
|
|
|
|
visible: false,
|
|
|
|
}),
|
2023-08-29 16:39:19 +02:00
|
|
|
Category: expect.objectContaining({
|
|
|
|
visible: false,
|
|
|
|
}),
|
|
|
|
Price: expect.objectContaining({
|
|
|
|
visible: false,
|
|
|
|
}),
|
2023-08-02 13:37:58 +02:00
|
|
|
},
|
|
|
|
},
|
2023-07-25 15:35:48 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2023-07-25 15:34:25 +02:00
|
|
|
it("can update an existing view name", async () => {
|
2023-08-29 16:13:44 +02:00
|
|
|
const tableId = table._id!
|
2023-07-25 15:34:25 +02:00
|
|
|
await config.api.viewV2.update({ ...view, name: "View B" })
|
|
|
|
|
2023-07-25 15:41:04 +02:00
|
|
|
expect(await config.api.table.get(tableId)).toEqual(
|
|
|
|
expect.objectContaining({
|
|
|
|
views: {
|
|
|
|
"View B": { ...view, name: "View B", schema: expect.anything() },
|
|
|
|
},
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("cannot update an unexisting views nor edit ids", async () => {
|
2023-08-29 16:13:44 +02:00
|
|
|
const tableId = table._id!
|
2023-07-25 15:41:04 +02:00
|
|
|
await config.api.viewV2.update(
|
|
|
|
{ ...view, id: generator.guid() },
|
2024-03-01 18:35:51 +01:00
|
|
|
{ status: 404 }
|
2023-07-25 15:41:04 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
expect(await config.api.table.get(tableId)).toEqual(
|
|
|
|
expect.objectContaining({
|
|
|
|
views: {
|
|
|
|
[view.name]: {
|
|
|
|
...view,
|
|
|
|
schema: expect.anything(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("cannot update views with the wrong tableId", async () => {
|
2023-08-29 16:13:44 +02:00
|
|
|
const tableId = table._id!
|
2023-07-25 15:41:04 +02:00
|
|
|
await config.api.viewV2.update(
|
|
|
|
{
|
|
|
|
...view,
|
|
|
|
tableId: generator.guid(),
|
2023-10-12 20:00:53 +02:00
|
|
|
query: [
|
|
|
|
{
|
|
|
|
operator: SearchQueryOperators.EQUAL,
|
|
|
|
field: "newField",
|
|
|
|
value: "thatValue",
|
|
|
|
},
|
|
|
|
],
|
2023-07-25 15:34:25 +02:00
|
|
|
},
|
2024-03-01 18:35:51 +01:00
|
|
|
{ status: 404 }
|
2023-07-25 15:41:04 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
expect(await config.api.table.get(tableId)).toEqual(
|
|
|
|
expect.objectContaining({
|
|
|
|
views: {
|
|
|
|
[view.name]: {
|
|
|
|
...view,
|
|
|
|
schema: expect.anything(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
)
|
2023-07-25 15:34:25 +02:00
|
|
|
})
|
2023-07-25 15:49:32 +02:00
|
|
|
|
|
|
|
it("cannot update views v1", async () => {
|
2024-03-14 18:11:09 +01:00
|
|
|
const viewV1 = await config.api.legacyView.save({
|
|
|
|
tableId: table._id!,
|
|
|
|
name: generator.guid(),
|
|
|
|
filters: [],
|
|
|
|
schema: {},
|
|
|
|
})
|
|
|
|
|
|
|
|
await config.api.viewV2.update(viewV1 as unknown as ViewV2, {
|
|
|
|
status: 400,
|
|
|
|
body: {
|
|
|
|
message: "Only views V2 can be updated",
|
2024-03-01 18:35:51 +01:00
|
|
|
status: 400,
|
2024-03-14 18:11:09 +01:00
|
|
|
},
|
|
|
|
})
|
2023-07-25 15:49:32 +02:00
|
|
|
})
|
2023-07-25 19:46:46 +02:00
|
|
|
|
|
|
|
it("cannot update the a view with unmatching ids between url and body", async () => {
|
2024-03-14 18:11:09 +01:00
|
|
|
const anotherView = await config.api.viewV2.create({
|
|
|
|
tableId: table._id!,
|
|
|
|
name: generator.guid(),
|
|
|
|
})
|
2023-07-25 19:46:46 +02:00
|
|
|
const result = await config
|
|
|
|
.request!.put(`/api/v2/views/${anotherView.id}`)
|
|
|
|
.send(view)
|
|
|
|
.set(config.defaultHeaders())
|
|
|
|
.expect("Content-Type", /json/)
|
|
|
|
.expect(400)
|
|
|
|
|
|
|
|
expect(result.body).toEqual({
|
|
|
|
message: "View id does not match between the body and the uri path",
|
|
|
|
status: 400,
|
|
|
|
})
|
|
|
|
})
|
2023-08-01 11:38:36 +02:00
|
|
|
|
|
|
|
it("updates only UI schema overrides", async () => {
|
|
|
|
await config.api.viewV2.update({
|
|
|
|
...view,
|
|
|
|
schema: {
|
|
|
|
Price: {
|
|
|
|
name: "Price",
|
|
|
|
type: FieldType.NUMBER,
|
|
|
|
visible: true,
|
|
|
|
order: 1,
|
|
|
|
width: 100,
|
|
|
|
},
|
|
|
|
Category: {
|
|
|
|
name: "Category",
|
|
|
|
type: FieldType.STRING,
|
|
|
|
visible: false,
|
|
|
|
icon: "ic",
|
|
|
|
},
|
2023-08-01 12:08:40 +02:00
|
|
|
} as Record<string, FieldSchema>,
|
2023-08-01 11:38:36 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
expect(await config.api.viewV2.get(view.id)).toEqual({
|
|
|
|
...view,
|
2023-08-11 16:52:13 +02:00
|
|
|
schema: {
|
2023-08-01 11:38:36 +02:00
|
|
|
Price: {
|
|
|
|
visible: true,
|
|
|
|
order: 1,
|
|
|
|
width: 100,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
id: view.id,
|
|
|
|
version: 2,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it("will not throw an exception if the schema is 'deleting' non UI fields", async () => {
|
|
|
|
await config.api.viewV2.update(
|
|
|
|
{
|
|
|
|
...view,
|
|
|
|
schema: {
|
|
|
|
Price: {
|
|
|
|
name: "Price",
|
|
|
|
type: FieldType.NUMBER,
|
|
|
|
visible: true,
|
|
|
|
},
|
|
|
|
Category: {
|
|
|
|
name: "Category",
|
|
|
|
type: FieldType.STRING,
|
|
|
|
},
|
2023-08-01 12:08:40 +02:00
|
|
|
} as Record<string, FieldSchema>,
|
2023-08-01 11:38:36 +02:00
|
|
|
},
|
|
|
|
{
|
2024-03-01 18:35:51 +01:00
|
|
|
status: 200,
|
2023-08-01 11:38:36 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
2023-07-25 15:34:25 +02:00
|
|
|
})
|
|
|
|
|
2023-07-12 18:09:13 +02:00
|
|
|
describe("delete", () => {
|
2023-07-18 09:58:43 +02:00
|
|
|
let view: ViewV2
|
2023-07-12 18:09:13 +02:00
|
|
|
|
|
|
|
beforeAll(async () => {
|
2024-03-14 18:11:09 +01:00
|
|
|
view = await config.api.viewV2.create({
|
|
|
|
tableId: table._id!,
|
|
|
|
name: generator.guid(),
|
|
|
|
})
|
2023-07-12 18:09:13 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
it("can delete an existing view", async () => {
|
2023-08-29 16:13:44 +02:00
|
|
|
const tableId = table._id!
|
2023-07-19 15:47:45 +02:00
|
|
|
const getPersistedView = async () =>
|
|
|
|
(await config.api.table.get(tableId)).views![view.name]
|
2023-07-12 18:09:13 +02:00
|
|
|
|
2023-07-19 15:47:45 +02:00
|
|
|
expect(await getPersistedView()).toBeDefined()
|
2023-07-12 18:09:13 +02:00
|
|
|
|
2023-07-19 18:02:15 +02:00
|
|
|
await config.api.viewV2.delete(view.id)
|
2023-07-19 15:47:45 +02:00
|
|
|
|
|
|
|
expect(await getPersistedView()).toBeUndefined()
|
2023-07-12 18:09:13 +02:00
|
|
|
})
|
|
|
|
})
|
2023-08-11 16:16:33 +02:00
|
|
|
|
|
|
|
describe("fetch view (through table)", () => {
|
|
|
|
it("should be able to fetch a view V2", async () => {
|
|
|
|
const newView: CreateViewRequest = {
|
|
|
|
name: generator.name(),
|
|
|
|
tableId: table._id!,
|
|
|
|
schema: {
|
|
|
|
Price: { visible: false },
|
|
|
|
Category: { visible: true },
|
|
|
|
},
|
|
|
|
}
|
|
|
|
const res = await config.api.viewV2.create(newView)
|
|
|
|
const view = await config.api.viewV2.get(res.id)
|
2023-08-11 16:52:13 +02:00
|
|
|
expect(view!.schema?.Price).toBeUndefined()
|
2023-09-12 20:17:21 +02:00
|
|
|
const updatedTable = await config.api.table.get(table._id!)
|
|
|
|
const viewSchema = updatedTable.views![view!.name!].schema as Record<
|
|
|
|
string,
|
|
|
|
UIFieldMetadata
|
|
|
|
>
|
|
|
|
expect(viewSchema.Price?.visible).toEqual(false)
|
2023-08-11 16:16:33 +02:00
|
|
|
})
|
|
|
|
})
|
2024-03-14 18:11:09 +01:00
|
|
|
|
|
|
|
describe("read", () => {
|
|
|
|
it("views have extra data trimmed", async () => {
|
|
|
|
const table = await config.api.table.save(
|
|
|
|
saveTableRequest({
|
|
|
|
name: "orders",
|
|
|
|
schema: {
|
|
|
|
Country: {
|
|
|
|
type: FieldType.STRING,
|
|
|
|
name: "Country",
|
|
|
|
},
|
|
|
|
Story: {
|
|
|
|
type: FieldType.STRING,
|
|
|
|
name: "Story",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
|
|
|
const view = await config.api.viewV2.create({
|
|
|
|
tableId: table._id!,
|
|
|
|
name: uuid.v4(),
|
|
|
|
schema: {
|
|
|
|
Country: {
|
|
|
|
visible: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
let row = await config.api.row.save(view.id, {
|
|
|
|
Country: "Aussy",
|
|
|
|
Story: "aaaaa",
|
|
|
|
})
|
|
|
|
|
|
|
|
row = await config.api.row.get(table._id!, row._id!)
|
|
|
|
expect(row.Story).toBeUndefined()
|
|
|
|
expect(row.Country).toEqual("Aussy")
|
|
|
|
})
|
|
|
|
})
|
2023-07-12 16:13:00 +02:00
|
|
|
})
|