Merge branch 'master' into fix/got-version

This commit is contained in:
José Vte. Calderón 2024-02-12 13:54:55 +01:00 committed by GitHub
commit 206b7c37c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 146 additions and 21 deletions

View File

@ -14,7 +14,6 @@ import { events } from "@budibase/backend-core"
import { import {
BulkImportRequest, BulkImportRequest,
BulkImportResponse, BulkImportResponse,
DocumentType,
FetchTablesResponse, FetchTablesResponse,
MigrateRequest, MigrateRequest,
MigrateResponse, MigrateResponse,
@ -25,7 +24,6 @@ import {
TableResponse, TableResponse,
TableSourceType, TableSourceType,
UserCtx, UserCtx,
SEPARATOR,
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import { jsonFromCsvString } from "../../../utilities/csv" import { jsonFromCsvString } from "../../../utilities/csv"
@ -77,9 +75,10 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
const table = ctx.request.body const table = ctx.request.body
const isImport = table.rows const isImport = table.rows
const savedTable = await pickApi({ table }).save(ctx) let savedTable = await pickApi({ table }).save(ctx)
if (!table._id) { if (!table._id) {
await events.table.created(savedTable) await events.table.created(savedTable)
savedTable = sdk.tables.enrichViewSchemas(savedTable)
} else { } else {
await events.table.updated(savedTable) await events.table.updated(savedTable)
} }

View File

@ -19,10 +19,15 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
} = { } = {
_id: generateTableID(), _id: generateTableID(),
...rest, ...rest,
type: "table", // Ensure these fields are populated, even if not sent in the request
sourceType: TableSourceType.INTERNAL, type: rest.type || "table",
views: {}, sourceType: rest.sourceType || TableSourceType.INTERNAL,
} }
if (!tableToSave.views) {
tableToSave.views = {}
}
const renaming = tableToSave._rename const renaming = tableToSave._rename
delete tableToSave._rename delete tableToSave._rename

View File

@ -5,6 +5,7 @@ import {
FieldType, FieldType,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
InternalTable, InternalTable,
NumberFieldMetadata,
RelationshipType, RelationshipType,
Row, Row,
SaveTableRequest, SaveTableRequest,
@ -18,6 +19,12 @@ import * as setup from "./utilities"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import * as uuid from "uuid" import * as uuid from "uuid"
import tk from "timekeeper"
import { mocks } from "@budibase/backend-core/tests"
import { TableToBuild } from "../../../tests/utilities/TestConfiguration"
tk.freeze(mocks.date.MOCK_DATE)
const { basicTable } = setup.structures const { basicTable } = setup.structures
describe("/tables", () => { describe("/tables", () => {
@ -60,6 +67,67 @@ describe("/tables", () => {
expect(events.table.created).toBeCalledWith(res.body) expect(events.table.created).toBeCalledWith(res.body)
}) })
it("creates all the passed fields", async () => {
const tableData: TableToBuild = {
name: "TestTable",
type: "table",
schema: {
autoId: {
name: "id",
type: FieldType.NUMBER,
subtype: AutoFieldSubType.AUTO_ID,
autocolumn: true,
constraints: {
type: "number",
presence: false,
},
},
},
views: {
"table view": {
id: "viewId",
version: 2,
name: "table view",
tableId: "tableId",
},
},
}
const testTable = await config.createTable(tableData)
const expected: Table = {
...tableData,
type: "table",
views: {
"table view": {
...tableData.views!["table view"],
schema: {
autoId: {
autocolumn: true,
constraints: {
presence: false,
type: "number",
},
name: "id",
type: FieldType.NUMBER,
subtype: AutoFieldSubType.AUTO_ID,
visible: false,
} as NumberFieldMetadata,
},
},
},
sourceType: TableSourceType.INTERNAL,
sourceId: expect.any(String),
_rev: expect.stringMatching(/^1-.+/),
_id: expect.any(String),
createdAt: mocks.date.MOCK_DATE.toISOString(),
updatedAt: mocks.date.MOCK_DATE.toISOString(),
}
expect(testTable).toEqual(expected)
const persistedTable = await config.api.table.get(testTable._id!)
expect(persistedTable).toEqual(expected)
})
it("creates a table via data import", async () => { it("creates a table via data import", async () => {
const table: SaveTableRequest = basicTable() const table: SaveTableRequest = basicTable()
table.rows = [{ name: "test-name", description: "test-desc" }] table.rows = [{ name: "test-name", description: "test-desc" }]
@ -152,6 +220,56 @@ describe("/tables", () => {
expect(res.body.name).toBeUndefined() expect(res.body.name).toBeUndefined()
}) })
it("updates only the passed fields", async () => {
const testTable = await config.createTable({
name: "TestTable",
type: "table",
schema: {
autoId: {
name: "id",
type: FieldType.NUMBER,
subtype: AutoFieldSubType.AUTO_ID,
autocolumn: true,
constraints: {
type: "number",
presence: false,
},
},
},
views: {
view1: {
id: "viewId",
version: 2,
name: "table view",
tableId: "tableId",
},
},
})
const response = await request
.post(`/api/tables`)
.send({
...testTable,
name: "UpdatedName",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(response.body).toEqual({
...testTable,
name: "UpdatedName",
_rev: expect.stringMatching(/^2-.+/),
})
const persistedTable = await config.api.table.get(testTable._id!)
expect(persistedTable).toEqual({
...testTable,
name: "UpdatedName",
_rev: expect.stringMatching(/^2-.+/),
})
})
describe("user table", () => { describe("user table", () => {
it("should add roleId and email field when adjusting user table schema", async () => { it("should add roleId and email field when adjusting user table schema", async () => {
const res = await request const res = await request
@ -230,6 +348,7 @@ describe("/tables", () => {
describe("fetch", () => { describe("fetch", () => {
let testTable: Table let testTable: Table
const enrichViewSchemasMock = jest.spyOn(sdk.tables, "enrichViewSchemas")
beforeEach(async () => { beforeEach(async () => {
testTable = await config.createTable(testTable) testTable = await config.createTable(testTable)
@ -239,6 +358,10 @@ describe("/tables", () => {
delete testTable._rev delete testTable._rev
}) })
afterAll(() => {
enrichViewSchemasMock.mockRestore()
})
it("returns all the tables for that instance in the response body", async () => { it("returns all the tables for that instance in the response body", async () => {
const res = await request const res = await request
.get(`/api/tables`) .get(`/api/tables`)
@ -287,7 +410,7 @@ describe("/tables", () => {
it("should enrich the view schemas for viewsV2", async () => { it("should enrich the view schemas for viewsV2", async () => {
const tableId = config.table!._id! const tableId = config.table!._id!
jest.spyOn(sdk.tables, "enrichViewSchemas").mockImplementation(t => ({ enrichViewSchemasMock.mockImplementation(t => ({
...t, ...t,
views: { views: {
view1: { view1: {
@ -295,7 +418,7 @@ describe("/tables", () => {
name: "view1", name: "view1",
schema: {}, schema: {},
id: "new_view_id", id: "new_view_id",
tableId, tableId: t._id!,
}, },
}, },
})) }))
@ -362,11 +485,7 @@ describe("/tables", () => {
let testTable: Table let testTable: Table
beforeEach(async () => { beforeEach(async () => {
testTable = await config.createTable(testTable) testTable = await config.createTable()
})
afterEach(() => {
delete testTable._rev
}) })
it("returns a success response when a table is deleted.", async () => { it("returns a success response when a table is deleted.", async () => {

View File

@ -75,11 +75,13 @@ export async function save(
if (!tableView) continue if (!tableView) continue
if (viewsSdk.isV2(tableView)) { if (viewsSdk.isV2(tableView)) {
table.views[view] = viewsSdk.syncSchema( if (oldTable?.views && oldTable.views[view]) {
oldTable!.views![view] as ViewV2, table.views[view] = viewsSdk.syncSchema(
table.schema, oldTable.views[view] as ViewV2,
renaming table.schema,
) renaming
)
}
continue continue
} }

View File

@ -84,12 +84,12 @@ type DefaultUserValues = {
csrfToken: string csrfToken: string
} }
interface TableToBuild extends Omit<Table, "sourceId" | "sourceType"> { export interface TableToBuild extends Omit<Table, "sourceId" | "sourceType"> {
sourceId?: string sourceId?: string
sourceType?: TableSourceType sourceType?: TableSourceType
} }
class TestConfiguration { export default class TestConfiguration {
server: any server: any
request: supertest.SuperTest<supertest.Test> | undefined request: supertest.SuperTest<supertest.Test> | undefined
started: boolean started: boolean
@ -912,4 +912,4 @@ class TestConfiguration {
} }
} }
export = TestConfiguration module.exports = TestConfiguration