diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts index 914091bca0..2b0e6a867d 100644 --- a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts @@ -485,6 +485,18 @@ describe('workflow > action-trigger', () => { expect(e1s.length).toBe(1); expect(e1s[0].status).toBe(EXECUTION_STATUS.RESOLVED); expect(e1s[0].context.data).toMatchObject({ title: 'p1', categoryId: c1.id }); + + const res2 = await userAgents[0] + .post(`/categories/${c1.id}/posts:create`) + .query({ triggerWorkflows: `${workflow.key}` }) + .send({ + data: { title: 'p2' }, + }); + + await sleep(500); + + const e2s = await workflow.getExecutions(); + expect(e2s.length).toBe(2); }); }); diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/executions.test.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/executions.test.ts index 408e7a70ab..5cc9b2210f 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/executions.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/executions.test.ts @@ -1,7 +1,7 @@ import { MockServer } from '@nocobase/test'; import Database from '@nocobase/database'; import { getApp, sleep } from '@nocobase/plugin-workflow-test'; -import { EXECUTION_STATUS } from '../../constants'; +import { EXECUTION_STATUS, JOB_STATUS } from '../../constants'; describe('workflow > actions > executions', () => { let app: MockServer; @@ -71,4 +71,52 @@ describe('workflow > actions > executions', () => { expect(e2.length).toBe(1); }); }); + + describe('cancel', () => { + it('execution not exists could not be canceled', async () => { + const { status } = await agent.resource('executions').cancel({ + filterByTk: -1, + }); + + expect(status).toBe(404); + }); + + it('completed execution could not be canceled', async () => { + const post = await PostRepo.create({ values: { title: 't1' } }); + await sleep(500); + + const e1 = await workflow.getExecutions(); + expect(e1.length).toBe(1); + expect(e1[0].get('status')).toBe(EXECUTION_STATUS.RESOLVED); + + const { status } = await agent.resource('executions').cancel({ + filterByTk: e1.id, + }); + + expect(status).toBe(400); + }); + + it('pending execution could be cancel', async () => { + await workflow.createNode({ + type: 'pending', + }); + + const post = await PostRepo.create({ values: { title: 't1' } }); + await sleep(500); + + const e1 = await workflow.getExecutions(); + expect(e1.length).toBe(1); + expect(e1[0].get('status')).toBe(EXECUTION_STATUS.STARTED); + + await agent.resource('executions').cancel({ + filterByTk: e1.id, + }); + + const e2 = await workflow.getExecutions(); + expect(e2.length).toBe(1); + expect(e2[0].get('status')).toBe(EXECUTION_STATUS.CANCELED); + const jobs = await e2[0].getJobs(); + expect(jobs[0].status).toBe(JOB_STATUS.CANCELED); + }); + }); }); diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/nodes.test.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/nodes.test.ts index b8b8343932..1c2d806647 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/nodes.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/actions/nodes.test.ts @@ -21,6 +21,127 @@ describe('workflow > actions > workflows', () => { afterEach(() => app.destroy()); + describe('create', () => { + it('create in unexecuted workflow', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'asyncTrigger', + }); + + const { + status, + body: { data }, + } = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + }, + }); + expect(status).toBe(200); + expect(data.type).toBe('echo'); + }); + + it('create in executed workflow', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'asyncTrigger', + executed: 1, + allExecuted: 1, + }); + + const { status } = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + }, + }); + expect(status).toBe(400); + }); + + it('create as head', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'asyncTrigger', + }); + + const res1 = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + }, + }); + expect(res1.status).toBe(200); + expect(res1.body.data.type).toBe('echo'); + expect(res1.body.data.upstreamId).toBeFalsy(); + + const res2 = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + }, + }); + expect(res2.status).toBe(200); + expect(res2.body.data.type).toBe('echo'); + expect(res2.body.data.upstreamId).toBeFalsy(); + expect(res2.body.data.downstreamId).toBe(res1.body.data.id); + + const nodes = await workflow.getNodes({ order: [['id', 'asc']] }); + expect(nodes.length).toBe(2); + expect(nodes[0].upstreamId).toBe(nodes[1].id); + expect(nodes[1].downstreamId).toBe(nodes[0].id); + }); + + it('create after other node', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'asyncTrigger', + }); + + const res1 = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + }, + }); + + const res2 = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + upstreamId: res1.body.data.id, + }, + }); + expect(res2.body.data.upstreamId).toBe(res1.body.data.id); + + const nodes = await workflow.getNodes({ order: [['id', 'asc']] }); + expect(nodes.length).toBe(2); + expect(nodes[0].downstreamId).toBe(nodes[1].id); + expect(nodes[1].upstreamId).toBe(nodes[0].id); + }); + + it('create as branch', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'asyncTrigger', + }); + + const res1 = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + }, + }); + + const res2 = await agent.resource('workflows.nodes', workflow.id).create({ + values: { + type: 'echo', + upstreamId: res1.body.data.id, + branchIndex: 0, + }, + }); + expect(res2.body.data.upstreamId).toBe(res1.body.data.id); + expect(res2.body.data.branchIndex).toBe(0); + + const nodes = await workflow.getNodes({ order: [['id', 'asc']] }); + expect(nodes.length).toBe(2); + expect(nodes[0].downstreamId).toBeNull(); + expect(nodes[1].upstreamId).toBe(nodes[0].id); + }); + }); + describe('destroy', () => { it('node in executed workflow could not be destroyed', async () => { const workflow = await WorkflowModel.create({