From 00a7a52611c471304bcdd53b69d2e6cc82f4c619 Mon Sep 17 00:00:00 2001 From: Junyi Date: Mon, 22 Jul 2024 16:47:02 +0800 Subject: [PATCH] fix(plugin-workflow): fix or condition bug in collection trigger (#4925) --- .../__tests__/triggers/collection.test.ts | 156 ++++++++++++++++++ .../src/server/triggers/CollectionTrigger.ts | 6 +- 2 files changed, 160 insertions(+), 2 deletions(-) diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/collection.test.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/collection.test.ts index 84a36e1ca1..f793519dab 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/collection.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/collection.test.ts @@ -280,6 +280,162 @@ describe('workflow > triggers > collection', () => { }); }); + describe('config.condition', () => { + it('empty condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: {}, + }, + }); + + const post = await PostRepo.create({ values: { title: 't1' } }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + + it('and empty condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: { + $and: [], + }, + }, + }); + + const post = await PostRepo.create({ values: { title: 't1' } }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + + it('and deep empty condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: { + $and: [{}], + }, + }, + }); + + const post = await PostRepo.create({ values: { title: 't1' } }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + + it('and condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: { + $and: [{ title: 't1' }], + }, + }, + }); + + const post1 = await PostRepo.create({ values: { title: 't1' } }); + const post2 = await PostRepo.create({ values: { title: 't2' } }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + + it('or empty condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: { + $or: [], + }, + }, + }); + + const post = await PostRepo.create({ values: { title: 't1' } }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + + it('or deep empty condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: { + $or: [{}], + }, + }, + }); + + const post = await PostRepo.create({ values: { title: 't1' } }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + + it('or condition', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'collection', + config: { + mode: 1, + collection: 'posts', + condition: { + $or: [{ title: { $notEmpty: true } }], + }, + }, + }); + + const post1 = await PostRepo.create({ values: { title: 't1' } }); + const post2 = await PostRepo.create({ values: {} }); + + await sleep(500); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(1); + expect(executions[0].context.data.title).toBe('t1'); + }); + }); + describe('config.appends', () => { it('non-appended association could not be accessed', async () => { const workflow = await WorkflowModel.create({ diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts index 44f28797f5..b64a426e13 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts @@ -12,6 +12,7 @@ import Trigger from '.'; import { toJSON } from '../utils'; import type { WorkflowModel } from '../types'; import { ICollection, parseCollectionName } from '@nocobase/data-source-manager'; +import { isValidFilter } from '@nocobase/utils'; export interface CollectionChangeTriggerConfig { collection: string; @@ -65,8 +66,9 @@ async function handler(this: CollectionTrigger, workflow: WorkflowModel, data: M ) { return; } - // NOTE: if no configured condition match, do not trigger - if (condition && condition.$and?.length) { + + // NOTE: if no configured condition, or not match, do not trigger + if (isValidFilter(condition)) { // TODO: change to map filter format to calculation format // const calculation = toCalculation(condition); const count = await repository.count({