Adding test case.
This commit is contained in:
parent
676058bbbd
commit
680c68a35b
|
@ -42,6 +42,7 @@ import { Knex } from "knex"
|
|||
import { structures } from "@budibase/backend-core/tests"
|
||||
import { DEFAULT_EMPLOYEE_TABLE_SCHEMA } from "../../../db/defaultData/datasource_bb_default"
|
||||
import { generateRowIdField } from "../../../integrations/utils"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
|
||||
describe.each([
|
||||
["in-memory", undefined],
|
||||
|
@ -66,6 +67,35 @@ describe.each([
|
|||
let table: Table
|
||||
let rows: Row[]
|
||||
|
||||
async function basicRelationshipTables(type: RelationshipType) {
|
||||
const relatedTable = await createTable(
|
||||
{
|
||||
name: { name: "name", type: FieldType.STRING },
|
||||
},
|
||||
"productCategory"
|
||||
)
|
||||
table = await createTable(
|
||||
{
|
||||
name: { name: "name", type: FieldType.STRING },
|
||||
productCat: {
|
||||
type: FieldType.LINK,
|
||||
relationshipType: type,
|
||||
name: "productCat",
|
||||
fieldName: "product",
|
||||
tableId: relatedTable._id!,
|
||||
constraints: {
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
},
|
||||
"product"
|
||||
)
|
||||
return {
|
||||
relatedTable: await config.api.table.get(relatedTable._id!),
|
||||
table,
|
||||
}
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
await withCoreEnv({ TENANT_FEATURE_FLAGS: "*:SQS" }, () => config.init())
|
||||
if (isLucene) {
|
||||
|
@ -201,6 +231,7 @@ describe.each([
|
|||
// rows returned by the query will also cause the assertion to fail.
|
||||
async toMatchExactly(expectedRows: any[]) {
|
||||
const response = await this.performSearch()
|
||||
const cloned = cloneDeep(response)
|
||||
const foundRows = response.rows
|
||||
|
||||
// eslint-disable-next-line jest/no-standalone-expect
|
||||
|
@ -211,7 +242,7 @@ describe.each([
|
|||
expect.objectContaining(this.popRow(expectedRow, foundRows))
|
||||
)
|
||||
)
|
||||
return response
|
||||
return cloned
|
||||
}
|
||||
|
||||
// Asserts that the query returns rows matching exactly the set of rows
|
||||
|
@ -219,6 +250,7 @@ describe.each([
|
|||
// cause the assertion to fail.
|
||||
async toContainExactly(expectedRows: any[]) {
|
||||
const response = await this.performSearch()
|
||||
const cloned = cloneDeep(response)
|
||||
const foundRows = response.rows
|
||||
|
||||
// eslint-disable-next-line jest/no-standalone-expect
|
||||
|
@ -231,7 +263,7 @@ describe.each([
|
|||
)
|
||||
)
|
||||
)
|
||||
return response
|
||||
return cloned
|
||||
}
|
||||
|
||||
// Asserts that the query returns some property values - this cannot be used
|
||||
|
@ -239,6 +271,7 @@ describe.each([
|
|||
// typing for this has to be any, Jest doesn't expose types for matchers like expect.any(...)
|
||||
async toMatch(properties: Record<string, any>) {
|
||||
const response = await this.performSearch()
|
||||
const cloned = cloneDeep(response)
|
||||
const keys = Object.keys(properties) as Array<keyof SearchResponse<Row>>
|
||||
for (let key of keys) {
|
||||
// eslint-disable-next-line jest/no-standalone-expect
|
||||
|
@ -248,17 +281,18 @@ describe.each([
|
|||
expect(response[key]).toEqual(properties[key])
|
||||
}
|
||||
}
|
||||
return response
|
||||
return cloned
|
||||
}
|
||||
|
||||
// Asserts that the query doesn't return a property, e.g. pagination parameters.
|
||||
async toNotHaveProperty(properties: (keyof SearchResponse<Row>)[]) {
|
||||
const response = await this.performSearch()
|
||||
const cloned = cloneDeep(response)
|
||||
for (let property of properties) {
|
||||
// eslint-disable-next-line jest/no-standalone-expect
|
||||
expect(response[property]).toBeUndefined()
|
||||
}
|
||||
return response
|
||||
return cloned
|
||||
}
|
||||
|
||||
// Asserts that the query returns rows matching the set of rows passed in.
|
||||
|
@ -266,6 +300,7 @@ describe.each([
|
|||
// assertion to fail.
|
||||
async toContain(expectedRows: any[]) {
|
||||
const response = await this.performSearch()
|
||||
const cloned = cloneDeep(response)
|
||||
const foundRows = response.rows
|
||||
|
||||
// eslint-disable-next-line jest/no-standalone-expect
|
||||
|
@ -276,7 +311,7 @@ describe.each([
|
|||
)
|
||||
)
|
||||
)
|
||||
return response
|
||||
return cloned
|
||||
}
|
||||
|
||||
async toFindNothing() {
|
||||
|
@ -2196,28 +2231,10 @@ describe.each([
|
|||
let productCategoryTable: Table, productCatRows: Row[]
|
||||
|
||||
beforeAll(async () => {
|
||||
productCategoryTable = await createTable(
|
||||
{
|
||||
name: { name: "name", type: FieldType.STRING },
|
||||
},
|
||||
"productCategory"
|
||||
)
|
||||
table = await createTable(
|
||||
{
|
||||
name: { name: "name", type: FieldType.STRING },
|
||||
productCat: {
|
||||
type: FieldType.LINK,
|
||||
relationshipType: RelationshipType.ONE_TO_MANY,
|
||||
name: "productCat",
|
||||
fieldName: "product",
|
||||
tableId: productCategoryTable._id!,
|
||||
constraints: {
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
},
|
||||
"product"
|
||||
const { relatedTable } = await basicRelationshipTables(
|
||||
RelationshipType.ONE_TO_MANY
|
||||
)
|
||||
productCategoryTable = relatedTable
|
||||
|
||||
productCatRows = await Promise.all([
|
||||
config.api.row.save(productCategoryTable._id!, { name: "foo" }),
|
||||
|
@ -2262,6 +2279,31 @@ describe.each([
|
|||
}).toContainExactly([{ name: "baz", productCat: undefined }])
|
||||
})
|
||||
})
|
||||
|
||||
isSql &&
|
||||
describe("big relations", () => {
|
||||
beforeAll(async () => {
|
||||
const { relatedTable } = await basicRelationshipTables(
|
||||
RelationshipType.MANY_TO_ONE
|
||||
)
|
||||
const mainRow = await config.api.row.save(table._id!, {
|
||||
name: "foo",
|
||||
})
|
||||
for (let i = 0; i < 11; i++) {
|
||||
await config.api.row.save(relatedTable._id!, {
|
||||
name: i,
|
||||
product: [mainRow._id!],
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it("can only pull 500 related rows", async () => {
|
||||
await withCoreEnv({ SQL_MAX_RELATED_ROWS: "10" }, async () => {
|
||||
const response = await expectQuery({}).toContain([{ name: "foo" }])
|
||||
expect(response.rows[0].productCat).toBeArrayOfSize(10)
|
||||
})
|
||||
})
|
||||
})
|
||||
;(isSqs || isLucene) &&
|
||||
describe("relations to same table", () => {
|
||||
let relatedTable: Table, relatedRows: Row[]
|
||||
|
|
|
@ -198,6 +198,7 @@ export async function save(
|
|||
}
|
||||
}
|
||||
generateRelatedSchema(schema, relatedTable, tableToSave, relatedColumnName)
|
||||
tables[relatedTable.name] = relatedTable
|
||||
schema.main = true
|
||||
}
|
||||
|
||||
|
@ -231,7 +232,10 @@ export async function save(
|
|||
// remove the rename prop
|
||||
delete tableToSave._rename
|
||||
|
||||
datasource.entities[tableToSave.name] = tableToSave
|
||||
datasource.entities = {
|
||||
...datasource.entities,
|
||||
...tables,
|
||||
}
|
||||
|
||||
// store it into couch now for budibase reference
|
||||
await db.put(populateExternalTableSchemas(datasource))
|
||||
|
|
|
@ -22,12 +22,16 @@ export function cleanupRelationships(
|
|||
tables: Record<string, Table>,
|
||||
oldTable?: Table
|
||||
) {
|
||||
if (!oldTable) {
|
||||
return
|
||||
}
|
||||
const tableToIterate = oldTable ? oldTable : table
|
||||
// clean up relationships in couch table schemas
|
||||
for (let [key, schema] of Object.entries(tableToIterate.schema)) {
|
||||
if (
|
||||
schema.type === FieldType.LINK &&
|
||||
(!oldTable || table.schema[key] == null)
|
||||
oldTable.schema[key] != null &&
|
||||
table.schema[key] == null
|
||||
) {
|
||||
const schemaTableId = schema.tableId
|
||||
const relatedTable = Object.values(tables).find(
|
||||
|
|
Loading…
Reference in New Issue