Create tests for the row saved trigger.
This commit is contained in:
parent
18b296a850
commit
af188e1c1a
|
@ -199,6 +199,12 @@ class InMemoryQueue implements Partial<Queue> {
|
|||
return this as unknown as Queue
|
||||
}
|
||||
|
||||
off(event: string, callback: (...args: any[]) => void): Queue {
|
||||
// @ts-expect-error - this callback can be one of many types
|
||||
this._emitter.off(event, callback)
|
||||
return this as unknown as Queue
|
||||
}
|
||||
|
||||
async count() {
|
||||
return this._messages.length
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ if (descriptions.length) {
|
|||
},
|
||||
})
|
||||
|
||||
await config.api.application.publish(config.getAppId())
|
||||
await config.api.application.publish()
|
||||
const prodQuery = await config.api.query.getProd(query._id!)
|
||||
|
||||
expect(prodQuery._id).toEqual(query._id)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"
|
||||
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
|
||||
import { getQueue } from "../.."
|
||||
import { Job } from "bull"
|
||||
import { captureAutomationRuns } from "../utilities"
|
||||
|
||||
describe("cron trigger", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
@ -15,15 +14,6 @@ describe("cron trigger", () => {
|
|||
})
|
||||
|
||||
it("should queue a Bull cron job", async () => {
|
||||
const queue = getQueue()
|
||||
expect(await queue.getCompletedCount()).toEqual(0)
|
||||
|
||||
const jobPromise = new Promise<Job>(resolve => {
|
||||
queue.on("completed", async job => {
|
||||
resolve(job)
|
||||
})
|
||||
})
|
||||
|
||||
await createAutomationBuilder(config)
|
||||
.onCron({ cron: "* * * * *" })
|
||||
.serverLog({
|
||||
|
@ -31,12 +21,12 @@ describe("cron trigger", () => {
|
|||
})
|
||||
.save()
|
||||
|
||||
await config.api.application.publish(config.getAppId())
|
||||
const jobs = await captureAutomationRuns(() =>
|
||||
config.api.application.publish()
|
||||
)
|
||||
expect(jobs).toHaveLength(1)
|
||||
|
||||
expect(await queue.getCompletedCount()).toEqual(1)
|
||||
|
||||
const job = await jobPromise
|
||||
const repeat = job.opts?.repeat
|
||||
const repeat = jobs[0].opts?.repeat
|
||||
if (!repeat || !("cron" in repeat)) {
|
||||
throw new Error("Expected cron repeat")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"
|
||||
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
|
||||
import { Table } from "@budibase/types"
|
||||
import { basicTable } from "../../../tests/utilities/structures"
|
||||
import { captureAutomationRuns } from "../utilities"
|
||||
|
||||
describe("row saved trigger", () => {
|
||||
const config = new TestConfiguration()
|
||||
let table: Table
|
||||
|
||||
beforeAll(async () => {
|
||||
await config.init()
|
||||
table = await config.api.table.save(basicTable())
|
||||
await createAutomationBuilder(config)
|
||||
.onRowSaved({ tableId: table._id! })
|
||||
.serverLog({ text: "Row created!" })
|
||||
.save()
|
||||
|
||||
await config.api.application.publish()
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
config.end()
|
||||
})
|
||||
|
||||
it("should queue a Bull job when a row is created", async () => {
|
||||
const jobs = await captureAutomationRuns(() =>
|
||||
config.withProdApp(() => config.api.row.save(table._id!, { name: "foo" }))
|
||||
)
|
||||
|
||||
expect(jobs).toHaveLength(1)
|
||||
expect(jobs[0].data.event).toEqual(
|
||||
expect.objectContaining({
|
||||
tableId: table._id!,
|
||||
row: expect.objectContaining({ name: "foo" }),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should not fire for rows created in other tables", async () => {
|
||||
const otherTable = await config.api.table.save(basicTable())
|
||||
await config.api.application.publish()
|
||||
|
||||
const jobs = await captureAutomationRuns(() =>
|
||||
config.withProdApp(() =>
|
||||
config.api.row.save(otherTable._id!, { name: "foo" })
|
||||
)
|
||||
)
|
||||
|
||||
expect(jobs).toBeEmpty()
|
||||
})
|
||||
})
|
|
@ -3,8 +3,15 @@ import { context } from "@budibase/backend-core"
|
|||
import { BUILTIN_ACTION_DEFINITIONS, getAction } from "../../actions"
|
||||
import emitter from "../../../events/index"
|
||||
import env from "../../../environment"
|
||||
import { AutomationActionStepId, Datasource } from "@budibase/types"
|
||||
import {
|
||||
AutomationActionStepId,
|
||||
AutomationData,
|
||||
Datasource,
|
||||
} from "@budibase/types"
|
||||
import { Knex } from "knex"
|
||||
import { getQueue } from "../.."
|
||||
import { Job } from "bull"
|
||||
import { helpers } from "@budibase/shared-core"
|
||||
|
||||
let config: TestConfiguration
|
||||
|
||||
|
@ -63,6 +70,44 @@ export async function runStep(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture all automation runs that occur during the execution of a function.
|
||||
* This function will wait for all messages to be processed before returning.
|
||||
*/
|
||||
export async function captureAutomationRuns(
|
||||
f: () => Promise<unknown>
|
||||
): Promise<Job<AutomationData>[]> {
|
||||
const runs: Job<AutomationData>[] = []
|
||||
const queue = getQueue()
|
||||
let messagesReceived = 0
|
||||
|
||||
const completedListener = async (job: Job<AutomationData>) => {
|
||||
runs.push(job)
|
||||
messagesReceived--
|
||||
}
|
||||
const messageListener = async () => {
|
||||
messagesReceived++
|
||||
}
|
||||
queue.on("message", messageListener)
|
||||
queue.on("completed", completedListener)
|
||||
try {
|
||||
await f()
|
||||
// Queue messages tend to be send asynchronously in API handlers, so there's
|
||||
// no guarantee that awaiting this function will have queued anything yet.
|
||||
// We wait here to make sure we're queued _after_ any existing async work.
|
||||
await helpers.wait(100)
|
||||
} finally {
|
||||
// eslint-disable-next-line no-unmodified-loop-condition
|
||||
while (messagesReceived > 0) {
|
||||
await helpers.wait(50)
|
||||
}
|
||||
queue.off("completed", completedListener)
|
||||
queue.off("message", messageListener)
|
||||
}
|
||||
|
||||
return runs
|
||||
}
|
||||
|
||||
export async function saveTestQuery(
|
||||
config: TestConfiguration,
|
||||
client: Knex,
|
||||
|
|
|
@ -34,9 +34,12 @@ export class ApplicationAPI extends TestAPI {
|
|||
}
|
||||
|
||||
publish = async (
|
||||
appId: string,
|
||||
appId?: string,
|
||||
expectations?: Expectations
|
||||
): Promise<PublishResponse> => {
|
||||
if (!appId) {
|
||||
appId = this.config.getAppId()
|
||||
}
|
||||
return await this._post<PublishResponse>(
|
||||
`/api/applications/${appId}/publish`,
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue