Merge pull request #14859 from Budibase/BUDI-8774/row-actions-dont-get-deleted-when-removing-a-datasource

Delete row actions when removing a datasource
This commit is contained in:
Adria Navarro 2024-10-24 18:04:52 +02:00 committed by GitHub
commit b05f35f58f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 93 additions and 19 deletions

View File

@ -267,6 +267,8 @@ export async function destroy(ctx: UserCtx) {
const datasource = await sdk.datasources.get(datasourceId) const datasource = await sdk.datasources.get(datasourceId)
// Delete all queries for the datasource // Delete all queries for the datasource
await sdk.rowActions.deleteAllForDatasource(datasourceId)
if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) { if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {
await destroyInternalTablesBySourceId(datasourceId) await destroyInternalTablesBySourceId(datasourceId)
} else { } else {

View File

@ -1,17 +1,24 @@
import _ from "lodash" import _ from "lodash"
import tk from "timekeeper" import tk from "timekeeper"
import {
context,
DEFAULT_BB_DATASOURCE_ID,
roles,
} from "@budibase/backend-core"
import { automations } from "@budibase/pro"
import { import {
CreateRowActionRequest, CreateRowActionRequest,
DocumentType, DocumentType,
PermissionLevel, PermissionLevel,
RowActionResponse, RowActionResponse,
TableRowActions,
} from "@budibase/types" } from "@budibase/types"
import * as setup from "./utilities" import * as setup from "./utilities"
import { generator, mocks } from "@budibase/backend-core/tests" import { generator, mocks } from "@budibase/backend-core/tests"
import { Expectations } from "../../../tests/utilities/api/base" import { Expectations } from "../../../tests/utilities/api/base"
import { roles } from "@budibase/backend-core" import { DatabaseName, getDatasource } from "../../../integrations/tests/utils"
import { automations } from "@budibase/pro" import { generateRowActionsID } from "../../../db/utils"
const expectAutomationId = () => const expectAutomationId = () =>
expect.stringMatching(`^${DocumentType.AUTOMATION}_.+`) expect.stringMatching(`^${DocumentType.AUTOMATION}_.+`)
@ -958,9 +965,74 @@ describe("/rowsActions", () => {
// document was not being cleaned up. This meant there existed code paths // document was not being cleaned up. This meant there existed code paths
// that would find it and try to reference the tables within it, resulting // that would find it and try to reference the tables within it, resulting
// in errors. // in errors.
await config.api.automation.fetchEnriched({ await config.api.automation.fetch({
status: 200, status: 200,
}) })
}) })
it.each([
[
"internal",
async () => {
await config.newTenant()
await config.api.application.addSampleData(config.getAppId())
const tables = await config.api.table.fetch()
const table = tables.find(
t => t.sourceId === DEFAULT_BB_DATASOURCE_ID
)!
return table
},
],
[
"external",
async () => {
await config.newTenant()
const ds = await config.createDatasource({
datasource: await getDatasource(DatabaseName.POSTGRES),
})
const table = await config.api.table.save(
setup.structures.tableForDatasource(ds)
)
return table
},
],
])(
"should delete all the row actions (and automations) for its tables when a datasource is deleted",
async (_, getTable) => {
async function getRowActionsFromDb(tableId: string) {
return await context.doInAppContext(config.getAppId(), async () => {
const db = context.getAppDB()
const tableDoc = await db.tryGet<TableRowActions>(
generateRowActionsID(tableId)
)
return tableDoc
})
}
const table = await getTable()
const tableId = table._id!
await config.api.rowAction.save(tableId, {
name: generator.guid(),
})
await config.api.rowAction.save(tableId, {
name: generator.guid(),
})
const { actions } = (await getRowActionsFromDb(tableId))!
expect(Object.entries(actions)).toHaveLength(2)
const { automations } = await config.api.automation.fetch()
expect(automations).toHaveLength(2)
const datasource = await config.api.datasource.get(table.sourceId)
await config.api.datasource.delete(datasource)
const automationsResp = await config.api.automation.fetch()
expect(automationsResp.automations).toHaveLength(0)
expect(await getRowActionsFromDb(tableId)).toBeUndefined()
}
)
}) })
}) })

View File

@ -7,11 +7,11 @@ import {
User, User,
VirtualDocumentType, VirtualDocumentType,
} from "@budibase/types" } from "@budibase/types"
import { generateRowActionsID } from "../../db/utils" import { generateRowActionsID } from "../../../db/utils"
import automations from "./automations" import automations from "../automations"
import { definitions as TRIGGER_DEFINITIONS } from "../../automations/triggerInfo" import { definitions as TRIGGER_DEFINITIONS } from "../../../automations/triggerInfo"
import * as triggers from "../../automations/triggers" import * as triggers from "../../../automations/triggers"
import sdk from ".." import sdk from "../.."
async function ensureUniqueAndThrow( async function ensureUniqueAndThrow(
doc: TableRowActions, doc: TableRowActions,

View File

@ -0,0 +1,2 @@
export * from "./crud"
export * from "./utils"

View File

@ -0,0 +1,9 @@
import sdk from "../../../sdk"
export async function deleteAllForDatasource(datasourceId: string) {
const allTables = await sdk.tables.getAllTables()
const tables = allTables.filter(t => t.sourceId === datasourceId)
for (const table of Object.values(tables)) {
await sdk.rowActions.deleteAll(table._id!)
}
}

View File

@ -23,17 +23,6 @@ export class AutomationAPI extends TestAPI {
}) })
} }
fetchEnriched = async (
expectations?: Expectations
): Promise<FetchAutomationResponse> => {
return await this._get<FetchAutomationResponse>(
`/api/automations?enrich=true`,
{
expectations,
}
)
}
post = async ( post = async (
body: Automation, body: Automation,
expectations?: Expectations expectations?: Expectations