Merge pull request #13408 from Budibase/BUDI-8122/tests

Tests and handle imports
This commit is contained in:
Adria Navarro 2024-04-10 10:16:54 +02:00 committed by GitHub
commit 8f9dea43a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 133 additions and 24 deletions

View File

@ -6,14 +6,17 @@ import * as setup from "./utilities"
import { context, InternalTable, tenancy } from "@budibase/backend-core" import { context, InternalTable, tenancy } from "@budibase/backend-core"
import { quotas } from "@budibase/pro" import { quotas } from "@budibase/pro"
import { import {
AttachmentFieldMetadata,
AutoFieldSubType, AutoFieldSubType,
Datasource, Datasource,
DateFieldMetadata,
DeleteRow, DeleteRow,
FieldSchema, FieldSchema,
FieldType, FieldType,
FieldTypeSubtypes, FieldTypeSubtypes,
FormulaType, FormulaType,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
NumberFieldMetadata,
QuotaUsageType, QuotaUsageType,
RelationshipType, RelationshipType,
Row, Row,
@ -232,9 +235,14 @@ describe.each([
name: "str", name: "str",
constraints: { type: "string", presence: false }, constraints: { type: "string", presence: false },
} }
const attachment: FieldSchema = { const singleAttachment: FieldSchema = {
type: FieldType.ATTACHMENT_SINGLE,
name: "single attachment",
constraints: { presence: false },
}
const attachmentList: AttachmentFieldMetadata = {
type: FieldType.ATTACHMENTS, type: FieldType.ATTACHMENTS,
name: "attachment", name: "attachments",
constraints: { type: "array", presence: false }, constraints: { type: "array", presence: false },
} }
const bool: FieldSchema = { const bool: FieldSchema = {
@ -242,12 +250,12 @@ describe.each([
name: "boolean", name: "boolean",
constraints: { type: "boolean", presence: false }, constraints: { type: "boolean", presence: false },
} }
const number: FieldSchema = { const number: NumberFieldMetadata = {
type: FieldType.NUMBER, type: FieldType.NUMBER,
name: "str", name: "str",
constraints: { type: "number", presence: false }, constraints: { type: "number", presence: false },
} }
const datetime: FieldSchema = { const datetime: DateFieldMetadata = {
type: FieldType.DATETIME, type: FieldType.DATETIME,
name: "datetime", name: "datetime",
constraints: { constraints: {
@ -297,10 +305,12 @@ describe.each([
boolUndefined: bool, boolUndefined: bool,
boolString: bool, boolString: bool,
boolBool: bool, boolBool: bool,
attachmentNull: attachment, singleAttachmentNull: singleAttachment,
attachmentUndefined: attachment, singleAttachmentUndefined: singleAttachment,
attachmentEmpty: attachment, attachmentListNull: attachmentList,
attachmentEmptyArrayStr: attachment, attachmentListUndefined: attachmentList,
attachmentListEmpty: attachmentList,
attachmentListEmptyArrayStr: attachmentList,
arrayFieldEmptyArrayStr: arrayField, arrayFieldEmptyArrayStr: arrayField,
arrayFieldArrayStrKnown: arrayField, arrayFieldArrayStrKnown: arrayField,
arrayFieldNull: arrayField, arrayFieldNull: arrayField,
@ -336,10 +346,12 @@ describe.each([
boolString: "true", boolString: "true",
boolBool: true, boolBool: true,
tableId: table._id, tableId: table._id,
attachmentNull: null, singleAttachmentNull: null,
attachmentUndefined: undefined, singleAttachmentUndefined: undefined,
attachmentEmpty: "", attachmentListNull: null,
attachmentEmptyArrayStr: "[]", attachmentListUndefined: undefined,
attachmentListEmpty: "",
attachmentListEmptyArrayStr: "[]",
arrayFieldEmptyArrayStr: "[]", arrayFieldEmptyArrayStr: "[]",
arrayFieldUndefined: undefined, arrayFieldUndefined: undefined,
arrayFieldNull: null, arrayFieldNull: null,
@ -368,10 +380,12 @@ describe.each([
expect(row.boolUndefined).toBe(undefined) expect(row.boolUndefined).toBe(undefined)
expect(row.boolString).toBe(true) expect(row.boolString).toBe(true)
expect(row.boolBool).toBe(true) expect(row.boolBool).toBe(true)
expect(row.attachmentNull).toEqual([]) expect(row.singleAttachmentNull).toEqual(null)
expect(row.attachmentUndefined).toBe(undefined) expect(row.singleAttachmentUndefined).toBe(undefined)
expect(row.attachmentEmpty).toEqual([]) expect(row.attachmentListNull).toEqual([])
expect(row.attachmentEmptyArrayStr).toEqual([]) expect(row.attachmentListUndefined).toBe(undefined)
expect(row.attachmentListEmpty).toEqual([])
expect(row.attachmentListEmptyArrayStr).toEqual([])
expect(row.arrayFieldEmptyArrayStr).toEqual([]) expect(row.arrayFieldEmptyArrayStr).toEqual([])
expect(row.arrayFieldNull).toEqual([]) expect(row.arrayFieldNull).toEqual([])
expect(row.arrayFieldUndefined).toEqual(undefined) expect(row.arrayFieldUndefined).toEqual(undefined)
@ -817,7 +831,39 @@ describe.each([
isInternal && isInternal &&
describe("attachments", () => { describe("attachments", () => {
it("should allow enriching attachment rows", async () => { it("should allow enriching single attachment rows", async () => {
const table = await config.api.table.save(
defaultTable({
schema: {
attachment: {
type: FieldType.ATTACHMENT_SINGLE,
name: "attachment",
constraints: { presence: false },
},
},
})
)
const attachmentId = `${uuid.v4()}.csv`
const row = await config.api.row.save(table._id!, {
name: "test",
description: "test",
attachment: {
key: `${config.getAppId()}/attachments/${attachmentId}`,
},
tableId: table._id,
})
await config.withEnv({ SELF_HOSTED: "true" }, async () => {
return context.doInAppContext(config.getAppId(), async () => {
const enriched = await outputProcessing(table, [row])
expect((enriched as Row[])[0].attachment.url).toBe(
`/files/signed/prod-budi-app-assets/${config.getProdAppId()}/attachments/${attachmentId}`
)
})
})
})
it("should allow enriching attachment list rows", async () => {
const table = await config.api.table.save( const table = await config.api.table.save(
defaultTable({ defaultTable({
schema: { schema: {

View File

@ -5,6 +5,7 @@ import {
Automation, Automation,
AutomationTriggerStepId, AutomationTriggerStepId,
RowAttachment, RowAttachment,
FieldType,
} from "@budibase/types" } from "@budibase/types"
import { getAutomationParams } from "../../../db/utils" import { getAutomationParams } from "../../../db/utils"
import { budibaseTempDir } from "../../../utilities/budibaseDir" import { budibaseTempDir } from "../../../utilities/budibaseDir"
@ -58,10 +59,19 @@ export async function updateAttachmentColumns(prodAppId: string, db: Database) {
updatedRows = updatedRows.concat( updatedRows = updatedRows.concat(
rows.map(row => { rows.map(row => {
for (let column of columns) { for (let column of columns) {
if (Array.isArray(row[column])) { const columnType = table.schema[column].type
if (
columnType === FieldType.ATTACHMENTS &&
Array.isArray(row[column])
) {
row[column] = row[column].map((attachment: RowAttachment) => row[column] = row[column].map((attachment: RowAttachment) =>
rewriteAttachmentUrl(prodAppId, attachment) rewriteAttachmentUrl(prodAppId, attachment)
) )
} else if (
columnType === FieldType.ATTACHMENT_SINGLE &&
row[column]
) {
row[column] = rewriteAttachmentUrl(prodAppId, row[column])
} }
} }
return row return row

View File

@ -30,7 +30,10 @@ export async function getRowsWithAttachments(appId: string, table: Table) {
const db = dbCore.getDB(appId) const db = dbCore.getDB(appId)
const attachmentCols: string[] = [] const attachmentCols: string[] = []
for (let [key, column] of Object.entries(table.schema)) { for (let [key, column] of Object.entries(table.schema)) {
if (column.type === FieldType.ATTACHMENTS) { if (
column.type === FieldType.ATTACHMENTS ||
column.type === FieldType.ATTACHMENT_SINGLE
) {
attachmentCols.push(key) attachmentCols.push(key)
} }
} }

View File

@ -31,9 +31,13 @@ describe("should be able to re-write attachment URLs", () => {
sourceType: TableSourceType.INTERNAL, sourceType: TableSourceType.INTERNAL,
schema: { schema: {
photo: { photo: {
type: FieldType.ATTACHMENTS, type: FieldType.ATTACHMENT_SINGLE,
name: "photo", name: "photo",
}, },
gallery: {
type: FieldType.ATTACHMENTS,
name: "gallery",
},
otherCol: { otherCol: {
type: FieldType.STRING, type: FieldType.STRING,
name: "otherCol", name: "otherCol",
@ -43,7 +47,8 @@ describe("should be able to re-write attachment URLs", () => {
for (let i = 0; i < FIND_LIMIT * 4; i++) { for (let i = 0; i < FIND_LIMIT * 4; i++) {
await config.api.row.save(table._id!, { await config.api.row.save(table._id!, {
photo: [attachment], photo: { ...attachment },
gallery: [{ ...attachment }, { ...attachment }],
otherCol: "string", otherCol: "string",
}) })
} }
@ -56,8 +61,12 @@ describe("should be able to re-write attachment URLs", () => {
) )
for (const row of rows) { for (const row of rows) {
expect(row.otherCol).toBe("string") expect(row.otherCol).toBe("string")
expect(row.photo[0].url).toBe("") expect(row.photo.url).toBe("")
expect(row.photo[0].key).toBe(`${db.name}/attachments/a.png`) expect(row.photo.key).toBe(`${db.name}/attachments/a.png`)
expect(row.gallery[0].url).toBe("")
expect(row.gallery[0].key).toBe(`${db.name}/attachments/a.png`)
expect(row.gallery[1].url).toBe("")
expect(row.gallery[1].key).toBe(`${db.name}/attachments/a.png`)
} }
}) })
}) })

View File

@ -73,7 +73,7 @@ describe("rowProcessor - outputProcessing", () => {
) )
}) })
it("should handle attachments correctly", async () => { it("should handle attachment list correctly", async () => {
const table: Table = { const table: Table = {
_id: generator.guid(), _id: generator.guid(),
name: "TestTable", name: "TestTable",
@ -116,6 +116,47 @@ describe("rowProcessor - outputProcessing", () => {
expect(output3.attach[0].url).toBe("aaaa") expect(output3.attach[0].url).toBe("aaaa")
}) })
it("should handle single attachment correctly", async () => {
const table: Table = {
_id: generator.guid(),
name: "TestTable",
type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: {
attach: {
type: FieldType.ATTACHMENT_SINGLE,
name: "attach",
constraints: {},
},
},
}
const row: { attach: RowAttachment } = {
attach: {
size: 10,
name: "test",
extension: "jpg",
key: "test.jpg",
},
}
const output = await outputProcessing(table, row, { squash: false })
expect(output.attach.url).toBe(
"/files/signed/prod-budi-app-assets/test.jpg"
)
row.attach.url = ""
const output2 = await outputProcessing(table, row, { squash: false })
expect(output2.attach.url).toBe(
"/files/signed/prod-budi-app-assets/test.jpg"
)
row.attach.url = "aaaa"
const output3 = await outputProcessing(table, row, { squash: false })
expect(output3.attach.url).toBe("aaaa")
})
it("process output even when the field is not empty", async () => { it("process output even when the field is not empty", async () => {
const table: Table = { const table: Table = {
_id: generator.guid(), _id: generator.guid(),