table.spec.ts passing for internal and postgres
This commit is contained in:
parent
bc072e1424
commit
bcc09bd86e
|
@ -84,8 +84,8 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
|
|||
}
|
||||
let savedTable = await api.save(ctx, renaming)
|
||||
if (!table._id) {
|
||||
await events.table.created(savedTable)
|
||||
savedTable = sdk.tables.enrichViewSchemas(savedTable)
|
||||
await events.table.created(savedTable)
|
||||
} else {
|
||||
await events.table.updated(savedTable)
|
||||
}
|
||||
|
|
|
@ -722,6 +722,39 @@ describe.each([
|
|||
})
|
||||
})
|
||||
|
||||
describe("bulkImport", () => {
|
||||
isInternal &&
|
||||
it("should update Auto ID field after bulk import", async () => {
|
||||
const table = await config.api.table.save(
|
||||
saveTableRequest({
|
||||
primary: ["autoId"],
|
||||
schema: {
|
||||
autoId: {
|
||||
name: "autoId",
|
||||
type: FieldType.NUMBER,
|
||||
subtype: AutoFieldSubType.AUTO_ID,
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: "number",
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
let row = await config.api.row.save(table._id!, {})
|
||||
expect(row.autoId).toEqual(1)
|
||||
|
||||
await config.api.row.bulkImport(table._id!, {
|
||||
rows: [{ autoId: 2 }],
|
||||
})
|
||||
|
||||
row = await config.api.row.save(table._id!, {})
|
||||
expect(row.autoId).toEqual(3)
|
||||
})
|
||||
})
|
||||
|
||||
describe("enrich", () => {
|
||||
beforeAll(async () => {
|
||||
table = await config.api.table.save(defaultTable())
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
FieldType,
|
||||
INTERNAL_TABLE_SOURCE_ID,
|
||||
InternalTable,
|
||||
NumberFieldMetadata,
|
||||
RelationshipType,
|
||||
Row,
|
||||
SaveTableRequest,
|
||||
|
@ -14,17 +13,16 @@ import {
|
|||
TableSourceType,
|
||||
User,
|
||||
ViewCalculation,
|
||||
ViewV2,
|
||||
} from "@budibase/types"
|
||||
import { checkBuilderEndpoint } from "./utilities/TestFunctions"
|
||||
import * as setup from "./utilities"
|
||||
import * as uuid from "uuid"
|
||||
|
||||
import tk from "timekeeper"
|
||||
import { generator, mocks } from "@budibase/backend-core/tests"
|
||||
import { generator } from "@budibase/backend-core/tests"
|
||||
import { DatabaseName, getDatasource } from "../../../integrations/tests/utils"
|
||||
import { tableForDatasource } from "../../../tests/utilities/structures"
|
||||
|
||||
tk.freeze(mocks.date.MOCK_DATE)
|
||||
import timekeeper from "timekeeper"
|
||||
|
||||
const { basicTable } = setup.structures
|
||||
const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
|
||||
|
@ -57,7 +55,7 @@ describe.each([
|
|||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("returns a success message when the table is successfully created", async () => {
|
||||
it("creates a table successfully", async () => {
|
||||
const name = generator.guid()
|
||||
const table = await config.api.table.save(
|
||||
tableForDatasource(datasource, { name })
|
||||
|
@ -67,64 +65,6 @@ describe.each([
|
|||
expect(events.table.created).toHaveBeenCalledWith(table)
|
||||
})
|
||||
|
||||
it("creates all the passed fields", async () => {
|
||||
const tableData = tableForDatasource(datasource, {
|
||||
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.api.table.save(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,
|
||||
},
|
||||
},
|
||||
},
|
||||
_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 () => {
|
||||
const table: SaveTableRequest = basicTable()
|
||||
table.rows = [{ name: "test-name", description: "test-desc" }]
|
||||
|
@ -165,17 +105,17 @@ describe.each([
|
|||
})
|
||||
)
|
||||
|
||||
await config.api.table.save({
|
||||
const updatedTable = await config.api.table.save({
|
||||
...table,
|
||||
name: generator.guid(),
|
||||
})
|
||||
|
||||
expect(events.table.updated).toHaveBeenCalledTimes(1)
|
||||
expect(events.table.updated).toHaveBeenCalledWith(table)
|
||||
expect(events.table.updated).toHaveBeenCalledWith(updatedTable)
|
||||
})
|
||||
|
||||
it("updates all the row fields for a table when a schema key is renamed", async () => {
|
||||
const testTable = await config.createTable()
|
||||
const testTable = await config.api.table.save(basicTable(datasource))
|
||||
await config.createLegacyView({
|
||||
name: "TestView",
|
||||
field: "Price",
|
||||
|
@ -215,9 +155,9 @@ describe.each([
|
|||
})
|
||||
|
||||
it("updates only the passed fields", async () => {
|
||||
await timekeeper.withFreeze(new Date(2021, 1, 1), async () => {
|
||||
const table = await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
name: "TestTable",
|
||||
schema: {
|
||||
autoId: {
|
||||
name: "id",
|
||||
|
@ -233,14 +173,16 @@ describe.each([
|
|||
})
|
||||
)
|
||||
|
||||
const newName = generator.guid()
|
||||
|
||||
const updatedTable = await config.api.table.save({
|
||||
...table,
|
||||
name: "UpdatedName",
|
||||
name: newName,
|
||||
})
|
||||
|
||||
let expected: Table = {
|
||||
...table,
|
||||
name: "UpdatedName",
|
||||
name: newName,
|
||||
_id: expect.any(String),
|
||||
}
|
||||
if (isInternal) {
|
||||
|
@ -252,7 +194,7 @@ describe.each([
|
|||
const persistedTable = await config.api.table.get(updatedTable._id!)
|
||||
expected = {
|
||||
...table,
|
||||
name: "UpdatedName",
|
||||
name: newName,
|
||||
_id: updatedTable._id,
|
||||
}
|
||||
if (datasource?.isSQL) {
|
||||
|
@ -263,8 +205,10 @@ describe.each([
|
|||
}
|
||||
expect(persistedTable).toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
describe("user table", () => {
|
||||
isInternal &&
|
||||
it("should add roleId and email field when adjusting user table schema", async () => {
|
||||
const table = await config.api.table.save({
|
||||
...basicTable(datasource),
|
||||
|
@ -300,7 +244,10 @@ describe.each([
|
|||
|
||||
describe("import", () => {
|
||||
it("imports rows successfully", async () => {
|
||||
const table = await config.api.table.save(basicTable(datasource))
|
||||
const name = generator.guid()
|
||||
const table = await config.api.table.save(
|
||||
basicTable(datasource, { name })
|
||||
)
|
||||
const importRequest = {
|
||||
schema: table.schema,
|
||||
rows: [{ name: "test-name", description: "test-desc" }],
|
||||
|
@ -314,43 +261,12 @@ describe.each([
|
|||
expect(events.rows.imported).toHaveBeenCalledTimes(1)
|
||||
expect(events.rows.imported).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
name: "TestTable",
|
||||
name,
|
||||
_id: table._id,
|
||||
}),
|
||||
1
|
||||
)
|
||||
})
|
||||
|
||||
it("should update Auto ID field after bulk import", async () => {
|
||||
const table = await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
name: "TestTable",
|
||||
schema: {
|
||||
autoId: {
|
||||
name: "id",
|
||||
type: FieldType.NUMBER,
|
||||
subtype: AutoFieldSubType.AUTO_ID,
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: "number",
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
let row = await config.api.row.save(table._id!, {})
|
||||
expect(row.autoId).toEqual(1)
|
||||
|
||||
await config.api.row.bulkImport(table._id!, {
|
||||
rows: [{ autoId: 2 }],
|
||||
identifierFields: [],
|
||||
})
|
||||
|
||||
row = await config.api.row.save(table._id!, {})
|
||||
expect(row.autoId).toEqual(3)
|
||||
})
|
||||
})
|
||||
|
||||
describe("fetch", () => {
|
||||
|
@ -396,7 +312,8 @@ describe.each([
|
|||
const table = res.find(t => t._id === testTable._id)
|
||||
expect(table).toBeDefined()
|
||||
expect(table!.views![viewV2.name]).toBeDefined()
|
||||
expect(table!.views![viewV2.name!]).toEqual({
|
||||
|
||||
const expectedViewV2: ViewV2 = {
|
||||
...viewV2,
|
||||
schema: {
|
||||
description: {
|
||||
|
@ -404,7 +321,7 @@ describe.each([
|
|||
type: "string",
|
||||
},
|
||||
name: "description",
|
||||
type: "string",
|
||||
type: FieldType.STRING,
|
||||
visible: false,
|
||||
},
|
||||
name: {
|
||||
|
@ -412,11 +329,22 @@ describe.each([
|
|||
type: "string",
|
||||
},
|
||||
name: "name",
|
||||
type: "string",
|
||||
type: FieldType.STRING,
|
||||
visible: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (!isInternal) {
|
||||
expectedViewV2.schema!.id = {
|
||||
name: "id",
|
||||
type: FieldType.NUMBER,
|
||||
visible: false,
|
||||
autocolumn: true,
|
||||
}
|
||||
}
|
||||
|
||||
expect(table!.views![viewV2.name!]).toEqual(expectedViewV2)
|
||||
|
||||
if (isInternal) {
|
||||
expect(table!.views![legacyView.name!]).toBeDefined()
|
||||
|
@ -440,23 +368,16 @@ describe.each([
|
|||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// expect(res).toEqual(
|
||||
// expect.arrayContaining([
|
||||
// expect.objectContaining({
|
||||
// _id: tableId,
|
||||
// views: {
|
||||
// view1: {
|
||||
// version: 2,
|
||||
// name: "view1",
|
||||
// schema: {},
|
||||
// id: "new_view_id",
|
||||
// tableId,
|
||||
// },
|
||||
// },
|
||||
// }),
|
||||
// ])
|
||||
// )
|
||||
describe("get", () => {
|
||||
it("returns a table", async () => {
|
||||
const table = await config.api.table.save(
|
||||
basicTable(datasource, { name: generator.guid() })
|
||||
)
|
||||
const res = await config.api.table.get(table._id!)
|
||||
expect(res).toEqual(table)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -781,11 +702,8 @@ describe.each([
|
|||
describe("unhappy paths", () => {
|
||||
let table: Table
|
||||
beforeAll(async () => {
|
||||
table = await config.api.table.save({
|
||||
name: "table",
|
||||
type: "table",
|
||||
sourceId: INTERNAL_TABLE_SOURCE_ID,
|
||||
sourceType: TableSourceType.INTERNAL,
|
||||
table = await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
schema: {
|
||||
"user relationship": {
|
||||
type: FieldType.LINK,
|
||||
|
@ -808,6 +726,7 @@ describe.each([
|
|||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail if the new column name is blank", async () => {
|
||||
|
|
|
@ -48,6 +48,18 @@ export async function save(
|
|||
oldTable = await getTable(tableId)
|
||||
}
|
||||
|
||||
if (
|
||||
!oldTable &&
|
||||
(tableToSave.primary == null || tableToSave.primary.length === 0)
|
||||
) {
|
||||
tableToSave.primary = ["id"]
|
||||
tableToSave.schema.id = {
|
||||
type: FieldType.NUMBER,
|
||||
autocolumn: true,
|
||||
name: "id",
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTypeChanged(tableToSave, oldTable)) {
|
||||
throw new Error("A column type has changed.")
|
||||
}
|
||||
|
@ -183,6 +195,10 @@ export async function save(
|
|||
// that the datasource definition changed
|
||||
const updatedDatasource = await datasourceSdk.get(datasource._id!)
|
||||
|
||||
if (updatedDatasource.isSQL) {
|
||||
tableToSave.sql = true
|
||||
}
|
||||
|
||||
return { datasource: updatedDatasource, table: tableToSave }
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,14 @@ import {
|
|||
} from "./constants"
|
||||
|
||||
export interface UIFieldMetadata {
|
||||
constraints?: FieldConstraints
|
||||
name?: string
|
||||
type?: FieldType
|
||||
order?: number
|
||||
width?: number
|
||||
visible?: boolean
|
||||
icon?: string
|
||||
autocolumn?: boolean
|
||||
}
|
||||
|
||||
interface BaseRelationshipFieldMetadata
|
||||
|
|
Loading…
Reference in New Issue