Improve some typing around automation testing.

This commit is contained in:
Sam Rose 2025-01-20 18:08:14 +00:00
parent 5afab49e18
commit 31fc2e45c9
No known key found for this signature in database
5 changed files with 86 additions and 31 deletions

View File

@ -1,5 +1,4 @@
import { v4 as uuidv4 } from "uuid"
import { testAutomation } from "../../../api/routes/tests/utilities/TestFunctions"
import { BUILTIN_ACTION_DEFINITIONS } from "../../actions"
import { TRIGGER_DEFINITIONS } from "../../triggers"
import {
@ -7,7 +6,6 @@ import {
AppActionTriggerOutputs,
Automation,
AutomationActionStepId,
AutomationResults,
AutomationStep,
AutomationStepInputs,
AutomationTrigger,
@ -24,6 +22,7 @@ import {
ExecuteQueryStepInputs,
ExecuteScriptStepInputs,
FilterStepInputs,
isDidNotTriggerResponse,
LoopStepInputs,
OpenAIStepInputs,
QueryRowsStepInputs,
@ -36,6 +35,7 @@ import {
SearchFilters,
ServerLogStepInputs,
SmtpEmailStepInputs,
TestAutomationRequest,
UpdateRowStepInputs,
WebhookTriggerInputs,
WebhookTriggerOutputs,
@ -279,7 +279,7 @@ class StepBuilder extends BaseStepBuilder {
class AutomationBuilder extends BaseStepBuilder {
private automationConfig: Automation
private config: TestConfiguration
private triggerOutputs: any
private triggerOutputs: TriggerOutputs
private triggerSet = false
constructor(
@ -398,21 +398,19 @@ class AutomationBuilder extends BaseStepBuilder {
async run() {
const automation = await this.save()
const results = await testAutomation(
this.config,
automation,
this.triggerOutputs
const response = await this.config.api.automation.test(
automation._id!,
this.triggerOutputs as TestAutomationRequest
)
return this.processResults(results)
}
private processResults(results: {
body: AutomationResults
}): AutomationResults {
results.body.steps.shift()
if (isDidNotTriggerResponse(response)) {
throw new Error(response.message)
}
response.steps.shift()
return {
trigger: results.body.trigger,
steps: results.body.steps,
trigger: response.trigger,
steps: response.steps,
}
}
}

View File

@ -21,6 +21,7 @@ import {
AutomationRowEvent,
UserBindings,
AutomationResults,
DidNotTriggerResponse,
} from "@budibase/types"
import { executeInThread } from "../threads/automation"
import { dataFilters, sdk } from "@budibase/shared-core"
@ -33,14 +34,6 @@ const JOB_OPTS = {
import * as automationUtils from "../automations/automationUtils"
import { doesTableExist } from "../sdk/app/tables/getters"
type DidNotTriggerResponse = {
outputs: {
success: false
status: AutomationStatus.STOPPED
}
message: AutomationStoppedReason.TRIGGER_FILTER_NOT_MET
}
async function getAllAutomations() {
const db = context.getAppDB()
let automations = await db.allDocs<Automation>(
@ -156,14 +149,26 @@ export function isAutomationResults(
)
}
interface AutomationTriggerParams {
fields: Record<string, any>
timeout?: number
appId?: string
user?: UserBindings
}
export async function externalTrigger(
automation: Automation,
params: {
fields: Record<string, any>
timeout?: number
appId?: string
user?: UserBindings
},
params: AutomationTriggerParams,
options: { getResponses: true }
): Promise<AutomationResults | DidNotTriggerResponse>
export async function externalTrigger(
automation: Automation,
params: AutomationTriggerParams,
options?: { getResponses: false }
): Promise<AutomationJob | DidNotTriggerResponse>
export async function externalTrigger(
automation: Automation,
params: AutomationTriggerParams,
{ getResponses }: { getResponses?: boolean } = {}
): Promise<AutomationResults | DidNotTriggerResponse | AutomationJob> {
if (automation.disabled) {

View File

@ -1,4 +1,11 @@
import { Automation, FetchAutomationResponse } from "@budibase/types"
import {
Automation,
FetchAutomationResponse,
TestAutomationRequest,
TestAutomationResponse,
TestAutomationStepRequest,
TestAutomationStepResponse,
} from "@budibase/types"
import { Expectations, TestAPI } from "./base"
export class AutomationAPI extends TestAPI {
@ -33,4 +40,33 @@ export class AutomationAPI extends TestAPI {
})
return result
}
test = async (
id: string,
body: TestAutomationRequest,
expectations?: Expectations
): Promise<TestAutomationResponse> => {
return await this._post<TestAutomationResponse>(
`/api/automations/${id}/test`,
{
body,
expectations,
}
)
}
testStep = async (
id: string,
stepId: string,
body: TestAutomationStepRequest,
expectations?: Expectations
): Promise<TestAutomationStepResponse> => {
return await this._post<TestAutomationStepResponse>(
`/api/automations/${id}/steps/${stepId}/test`,
{
body,
expectations,
}
)
}
}

View File

@ -2,10 +2,12 @@ import {
Automation,
AutomationActionStepId,
AutomationLogPage,
AutomationResults,
AutomationStatus,
AutomationStepDefinition,
AutomationTriggerDefinition,
AutomationTriggerStepId,
DidNotTriggerResponse,
Row,
} from "../../../documents"
import { DocumentDestroyResponse } from "@budibase/nano"
@ -74,7 +76,13 @@ export interface TestAutomationRequest {
fields: Record<string, any>
row?: Row
}
export interface TestAutomationResponse {}
export type TestAutomationResponse = AutomationResults | DidNotTriggerResponse
export function isDidNotTriggerResponse(
response: TestAutomationResponse
): response is DidNotTriggerResponse {
return !!("message" in response && response.message)
}
export interface TestAutomationStepRequest {
inputs: Record<string, any>

View File

@ -205,6 +205,14 @@ export interface AutomationResults {
}[]
}
export interface DidNotTriggerResponse {
outputs: {
success: false
status: AutomationStatus.STOPPED
}
message: AutomationStoppedReason.TRIGGER_FILTER_NOT_MET
}
export interface AutomationLog extends AutomationResults, Document {
automationName: string
_rev?: string