@nocobase/plugin-workflow-manual 0.20.0-alpha.16 → 0.20.0-alpha.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@ import {
10
10
  apiUpdateWorkflowTrigger,
11
11
  appendJsonCollectionName,
12
12
  generalWithNoRelationalFields,
13
+ apiGetDataSourceCount,
13
14
  } from '@nocobase/plugin-workflow-test/e2e';
14
15
  import { expect, test } from '@nocobase/test/e2e';
15
16
  import { dayjs } from '@nocobase/utils';
@@ -97,6 +98,10 @@ test.describe('field data update', () => {
97
98
  await manualNode.configureUserInterfaceButton.click();
98
99
  await manualNode.addBlockButton.hover();
99
100
  await manualNode.updateRecordFormMenu.hover();
101
+ const dataSourcesCount = await apiGetDataSourceCount();
102
+ if (dataSourcesCount > 1) {
103
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
104
+ }
100
105
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
101
106
  await page.mouse.move(300, 0, { steps: 100 });
102
107
  await page
@@ -249,6 +254,10 @@ test.describe('field data update', () => {
249
254
  await manualNode.configureUserInterfaceButton.click();
250
255
  await manualNode.addBlockButton.hover();
251
256
  await manualNode.updateRecordFormMenu.hover();
257
+ const dataSourcesCount = await apiGetDataSourceCount();
258
+ if (dataSourcesCount > 1) {
259
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
260
+ }
252
261
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
253
262
  await page.mouse.move(300, 0, { steps: 100 });
254
263
  await page
@@ -401,6 +410,10 @@ test.describe('field data update', () => {
401
410
  await manualNode.configureUserInterfaceButton.click();
402
411
  await manualNode.addBlockButton.hover();
403
412
  await manualNode.updateRecordFormMenu.hover();
413
+ const dataSourcesCount = await apiGetDataSourceCount();
414
+ if (dataSourcesCount > 1) {
415
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
416
+ }
404
417
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
405
418
  await page.mouse.move(300, 0, { steps: 100 });
406
419
  await page
@@ -553,6 +566,10 @@ test.describe('field data update', () => {
553
566
  await manualNode.configureUserInterfaceButton.click();
554
567
  await manualNode.addBlockButton.hover();
555
568
  await manualNode.updateRecordFormMenu.hover();
569
+ const dataSourcesCount = await apiGetDataSourceCount();
570
+ if (dataSourcesCount > 1) {
571
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
572
+ }
556
573
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
557
574
  await page.mouse.move(300, 0, { steps: 100 });
558
575
  await page
@@ -705,6 +722,10 @@ test.describe('field data update', () => {
705
722
  await manualNode.configureUserInterfaceButton.click();
706
723
  await manualNode.addBlockButton.hover();
707
724
  await manualNode.updateRecordFormMenu.hover();
725
+ const dataSourcesCount = await apiGetDataSourceCount();
726
+ if (dataSourcesCount > 1) {
727
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
728
+ }
708
729
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
709
730
  await page.mouse.move(300, 0, { steps: 100 });
710
731
  await page
@@ -857,6 +878,10 @@ test.describe('field data update', () => {
857
878
  await manualNode.configureUserInterfaceButton.click();
858
879
  await manualNode.addBlockButton.hover();
859
880
  await manualNode.updateRecordFormMenu.hover();
881
+ const dataSourcesCount = await apiGetDataSourceCount();
882
+ if (dataSourcesCount > 1) {
883
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
884
+ }
860
885
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
861
886
  await page.mouse.move(300, 0, { steps: 100 });
862
887
  await page
@@ -1025,6 +1050,10 @@ test.describe('field data update', () => {
1025
1050
  await manualNode.configureUserInterfaceButton.click();
1026
1051
  await manualNode.addBlockButton.hover();
1027
1052
  await manualNode.updateRecordFormMenu.hover();
1053
+ const dataSourcesCount = await apiGetDataSourceCount();
1054
+ if (dataSourcesCount > 1) {
1055
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
1056
+ }
1028
1057
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
1029
1058
  await page.mouse.move(300, 0, { steps: 100 });
1030
1059
  await page
@@ -1193,6 +1222,10 @@ test.describe('field data update', () => {
1193
1222
  await manualNode.configureUserInterfaceButton.click();
1194
1223
  await manualNode.addBlockButton.hover();
1195
1224
  await manualNode.updateRecordFormMenu.hover();
1225
+ const dataSourcesCount = await apiGetDataSourceCount();
1226
+ if (dataSourcesCount > 1) {
1227
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
1228
+ }
1196
1229
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
1197
1230
  await page.mouse.move(300, 0, { steps: 100 });
1198
1231
  await page
@@ -1361,6 +1394,10 @@ test.describe('field data update', () => {
1361
1394
  await manualNode.configureUserInterfaceButton.click();
1362
1395
  await manualNode.addBlockButton.hover();
1363
1396
  await manualNode.updateRecordFormMenu.hover();
1397
+ const dataSourcesCount = await apiGetDataSourceCount();
1398
+ if (dataSourcesCount > 1) {
1399
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
1400
+ }
1364
1401
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
1365
1402
  await page.mouse.move(300, 0, { steps: 100 });
1366
1403
  await page
@@ -1530,6 +1567,10 @@ test.describe('field data update', () => {
1530
1567
  await manualNode.configureUserInterfaceButton.click();
1531
1568
  await manualNode.addBlockButton.hover();
1532
1569
  await manualNode.updateRecordFormMenu.hover();
1570
+ const dataSourcesCount = await apiGetDataSourceCount();
1571
+ if (dataSourcesCount > 1) {
1572
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
1573
+ }
1533
1574
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
1534
1575
  await page.mouse.move(300, 0, { steps: 100 });
1535
1576
  await page
@@ -1707,6 +1748,10 @@ test.describe('field data update', () => {
1707
1748
  await manualNode.configureUserInterfaceButton.click();
1708
1749
  await manualNode.addBlockButton.hover();
1709
1750
  await manualNode.updateRecordFormMenu.hover();
1751
+ const dataSourcesCount = await apiGetDataSourceCount();
1752
+ if (dataSourcesCount > 1) {
1753
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
1754
+ }
1710
1755
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
1711
1756
  await page.mouse.move(300, 0, { steps: 100 });
1712
1757
  await page
@@ -1875,6 +1920,10 @@ test.describe('field data update', () => {
1875
1920
  await manualNode.configureUserInterfaceButton.click();
1876
1921
  await manualNode.addBlockButton.hover();
1877
1922
  await manualNode.updateRecordFormMenu.hover();
1923
+ const dataSourcesCount = await apiGetDataSourceCount();
1924
+ if (dataSourcesCount > 1) {
1925
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
1926
+ }
1878
1927
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
1879
1928
  await page.mouse.move(300, 0, { steps: 100 });
1880
1929
  await page
@@ -2049,6 +2098,10 @@ test.describe('field data update', () => {
2049
2098
  await manualNode.configureUserInterfaceButton.click();
2050
2099
  await manualNode.addBlockButton.hover();
2051
2100
  await manualNode.updateRecordFormMenu.hover();
2101
+ const dataSourcesCount = await apiGetDataSourceCount();
2102
+ if (dataSourcesCount > 1) {
2103
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
2104
+ }
2052
2105
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
2053
2106
  await page.mouse.move(300, 0, { steps: 100 });
2054
2107
  await page
@@ -8,6 +8,7 @@ import {
8
8
  apiUpdateWorkflowTrigger,
9
9
  appendJsonCollectionName,
10
10
  generalWithNoRelationalFields,
11
+ apiGetDataSourceCount,
11
12
  } from '@nocobase/plugin-workflow-test/e2e';
12
13
  import { expect, test } from '@nocobase/test/e2e';
13
14
  import { dayjs } from '@nocobase/utils';
@@ -69,6 +70,10 @@ test('filter task node', async ({ page, mockPage, mockCollections, mockRecords }
69
70
  await manualNode.configureUserInterfaceButton.click();
70
71
  await manualNode.addBlockButton.hover();
71
72
  await manualNode.createRecordFormMenu.hover();
73
+ const dataSourcesCount = await apiGetDataSourceCount();
74
+ if (dataSourcesCount > 1) {
75
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
76
+ }
72
77
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
73
78
  await page.mouse.move(300, 0, { steps: 100 });
74
79
  await page
@@ -179,6 +184,10 @@ test('filter workflow name', async ({ page, mockPage, mockCollections, mockRecor
179
184
  await manualNode.configureUserInterfaceButton.click();
180
185
  await manualNode.addBlockButton.hover();
181
186
  await manualNode.createRecordFormMenu.hover();
187
+ const dataSourcesCount = await apiGetDataSourceCount();
188
+ if (dataSourcesCount > 1) {
189
+ await page.getByRole('menuitem', { name: 'Main right' }).hover();
190
+ }
182
191
  await page.getByRole('menuitem', { name: manualNodeCollectionDisplayName }).click();
183
192
  await page.mouse.move(300, 0, { steps: 100 });
184
193
  await page
@@ -35,6 +35,8 @@ import {
35
35
  } from '@nocobase/client';
36
36
  import WorkflowPlugin, {
37
37
  JOB_STATUS,
38
+ DetailsBlockProvider,
39
+ SimpleDesigner,
38
40
  useAvailableUpstreams,
39
41
  useFlowContext,
40
42
  useNodeContext,
@@ -44,7 +46,6 @@ import WorkflowPlugin, {
44
46
  import { Registry, lodash } from '@nocobase/utils/client';
45
47
 
46
48
  import { NAMESPACE, useLang } from '../../locale';
47
- import { DetailsBlockProvider } from './DetailsBlockProvider';
48
49
  import { FormBlockProvider } from './FormBlockProvider';
49
50
  import createRecordForm from './forms/create';
50
51
  import customRecordForm from './forms/custom';
@@ -104,24 +105,6 @@ const blockTypeNames = {
104
105
  record: `{{t("Data record", { ns: "${NAMESPACE}" })}}`,
105
106
  };
106
107
 
107
- function SimpleDesigner() {
108
- const schema = useFieldSchema();
109
- const title = blockTypeNames[schema['x-designer-props']?.type] ?? '{{t("Block")}}';
110
- const compile = useCompile();
111
- return (
112
- <GeneralSchemaDesigner title={compile(title)}>
113
- <SchemaSettingsBlockTitleItem />
114
- <SchemaSettingsDivider />
115
- <SchemaSettingsRemove
116
- removeParentsIfNoChildren
117
- breakRemoveOn={{
118
- 'x-component': 'Grid',
119
- }}
120
- />
121
- </GeneralSchemaDesigner>
122
- );
123
- }
124
-
125
108
  /**
126
109
  * @deprecated
127
110
  */
@@ -153,7 +136,7 @@ export const addBlockButton_deprecated = new CompatibleSchemaInitializer({
153
136
  {
154
137
  name: 'nodes',
155
138
  type: 'subMenu',
156
- title: `{{t("Node result", { ns: "${NAMESPACE}" })}}`,
139
+ title: `{{t("Node result", { ns: "workflow" })}}`,
157
140
  children: nodeBlockInitializers,
158
141
  },
159
142
  ]
@@ -3,7 +3,7 @@ import React, { useContext, useMemo, useState } from 'react';
3
3
  import { ArrayTable } from '@formily/antd-v5';
4
4
  import { Field, createForm } from '@formily/core';
5
5
  import { useField, useFieldSchema, useForm } from '@formily/react';
6
- import lodash from 'lodash';
6
+ import { cloneDeep, pick, set } from 'lodash';
7
7
 
8
8
  import {
9
9
  ActionContextProvider,
@@ -161,7 +161,7 @@ function getOptions(interfaces) {
161
161
  const schema = interfaces[type];
162
162
  const { group = 'others' } = schema;
163
163
  fields[group] = fields[group] || {};
164
- lodash.set(fields, [group, type], schema);
164
+ set(fields, [group, type], schema);
165
165
  });
166
166
 
167
167
  return Object.keys(GroupLabels)
@@ -208,33 +208,51 @@ const CustomItemsComponent = (props) => {
208
208
  const items = useCommonInterfaceInitializers();
209
209
  const collection = useCollection_deprecated();
210
210
  const { setCollectionFields } = useContext(FormBlockContext);
211
+ const form = useMemo(() => createForm(), [interfaceOptions]);
211
212
 
212
213
  return (
213
214
  <AddCustomFormFieldButtonContext.Provider
214
215
  value={{
215
216
  onAddField(item) {
217
+ const fieldInterface: Record<string, any> = pick(item, [
218
+ 'name',
219
+ 'group',
220
+ 'title',
221
+ 'default',
222
+ 'validateSchema',
223
+ ]);
216
224
  const {
217
- properties: { unique, type, ...properties },
218
- ...options
219
- } = lodash.cloneDeep(item);
220
- delete properties.name['x-disabled'];
221
- setInterface({
222
- ...options,
223
- properties,
224
- });
225
+ properties: { unique, type, layout, autoIncrement, ...properties },
226
+ } = item;
227
+ fieldInterface.properties = properties;
228
+ const result = cloneDeep(fieldInterface);
229
+ delete result.properties.name['x-disabled'];
230
+ setInterface(result);
225
231
  },
226
232
  setCallback,
227
233
  }}
228
234
  >
229
235
  <SchemaInitializerItems {...props} items={items} />
230
- <ActionContextProvider value={{ visible: Boolean(interfaceOptions) }}>
236
+ <ActionContextProvider
237
+ value={{
238
+ visible: Boolean(interfaceOptions),
239
+ setVisible(v) {
240
+ if (!v) {
241
+ setInterface(null);
242
+ }
243
+ },
244
+ }}
245
+ >
231
246
  {interfaceOptions ? (
232
247
  <SchemaComponent
233
248
  schema={{
234
249
  type: 'void',
235
250
  name: 'drawer',
236
251
  title: '{{t("Configure field")}}',
237
- 'x-decorator': 'Form',
252
+ 'x-decorator': 'FormV2',
253
+ 'x-decorator-props': {
254
+ form,
255
+ },
238
256
  'x-component': 'Action.Drawer',
239
257
  properties: {
240
258
  ...interfaceOptions.properties,
@@ -266,7 +284,7 @@ const CustomItemsComponent = (props) => {
266
284
  'x-component-props': {
267
285
  type: 'primary',
268
286
  useAction() {
269
- const { values, query } = useForm();
287
+ const { values, query, reset } = useForm();
270
288
  const messages = [useLang('Field name existed in form')];
271
289
  return {
272
290
  async run() {
@@ -301,6 +319,7 @@ const CustomItemsComponent = (props) => {
301
319
  'x-toolbar': 'FormItemSchemaToolbar',
302
320
  'x-settings': 'fieldSettings:FormItem',
303
321
  });
322
+ reset();
304
323
  setCallback(null);
305
324
  setInterface(null);
306
325
  },
@@ -138,7 +138,7 @@ export default class extends Instruction {
138
138
  title: form.title ?? formKey,
139
139
  Component: CollectionBlockInitializer,
140
140
  collection: form.collection,
141
- dataSource: `{{$jobsMapByNodeKey.${node.key}.${formKey}}}`,
141
+ dataPath: `$jobsMapByNodeKey.${node.key}.${formKey}`,
142
142
  } as SchemaInitializerItemType)
143
143
  : null;
144
144
  })
@@ -0,0 +1,223 @@
1
+ import Database from '@nocobase/database';
2
+ import { EXECUTION_STATUS, JOB_STATUS } from '@nocobase/plugin-workflow';
3
+ import { getApp, sleep } from '@nocobase/plugin-workflow-test';
4
+ import { MockServer } from '@nocobase/test';
5
+
6
+ // NOTE: skipped because time is not stable on github ci, but should work in local
7
+ describe('workflow > instructions > manual', () => {
8
+ let app: MockServer;
9
+ let agent;
10
+ let userAgents;
11
+ let db: Database;
12
+ let PostRepo;
13
+ let AnotherPostRepo;
14
+ let WorkflowModel;
15
+ let workflow;
16
+ let UserModel;
17
+ let users;
18
+ let UserJobModel;
19
+
20
+ beforeEach(async () => {
21
+ app = await getApp({
22
+ plugins: ['users', 'auth', 'workflow-manual'],
23
+ });
24
+ // await app.getPlugin('auth').install();
25
+ agent = app.agent();
26
+ db = app.db;
27
+ WorkflowModel = db.getCollection('workflows').model;
28
+ PostRepo = db.getCollection('posts').repository;
29
+ AnotherPostRepo = app.dataSourceManager.dataSources.get('another').collectionManager.getRepository('posts');
30
+ UserModel = db.getCollection('users').model;
31
+ UserJobModel = db.getModel('users_jobs');
32
+
33
+ users = await UserModel.bulkCreate([
34
+ { id: 2, nickname: 'a' },
35
+ { id: 3, nickname: 'b' },
36
+ ]);
37
+
38
+ userAgents = users.map((user) => app.agent().login(user));
39
+
40
+ workflow = await WorkflowModel.create({
41
+ enabled: true,
42
+ type: 'collection',
43
+ config: {
44
+ mode: 1,
45
+ collection: 'posts',
46
+ },
47
+ });
48
+ });
49
+
50
+ afterEach(() => app.destroy());
51
+
52
+ describe('multiple data source', () => {
53
+ describe('create', () => {
54
+ it('create as configured', async () => {
55
+ const n1 = await workflow.createNode({
56
+ type: 'manual',
57
+ config: {
58
+ assignees: [users[0].id],
59
+ forms: {
60
+ f1: {
61
+ type: 'create',
62
+ actions: [{ status: JOB_STATUS.RESOLVED, key: 'resolve' }],
63
+ collection: 'posts',
64
+ dataSource: 'another',
65
+ },
66
+ },
67
+ },
68
+ });
69
+
70
+ const post = await PostRepo.create({ values: { title: 't1' } });
71
+
72
+ await sleep(500);
73
+
74
+ const UserJobModel = db.getModel('users_jobs');
75
+ const pendingJobs = await UserJobModel.findAll({
76
+ order: [['userId', 'ASC']],
77
+ });
78
+ expect(pendingJobs.length).toBe(1);
79
+
80
+ const res1 = await userAgents[0].resource('users_jobs').submit({
81
+ filterByTk: pendingJobs[0].get('id'),
82
+ values: {
83
+ result: { f1: { title: 't1' }, _: 'resolve' },
84
+ },
85
+ });
86
+ expect(res1.status).toBe(202);
87
+
88
+ await sleep(500);
89
+
90
+ const [e1] = await workflow.getExecutions();
91
+ expect(e1.status).toBe(EXECUTION_STATUS.RESOLVED);
92
+ const [j1] = await e1.getJobs();
93
+ expect(j1.status).toBe(JOB_STATUS.RESOLVED);
94
+ expect(j1.result).toMatchObject({ f1: { title: 't1' } });
95
+
96
+ const posts = await AnotherPostRepo.find();
97
+ expect(posts.length).toBe(1);
98
+ expect(posts[0]).toMatchObject({ title: 't1' });
99
+ });
100
+
101
+ it('save first and then commit', async () => {
102
+ const n1 = await workflow.createNode({
103
+ type: 'manual',
104
+ config: {
105
+ assignees: [users[0].id],
106
+ forms: {
107
+ f1: {
108
+ type: 'create',
109
+ actions: [
110
+ { status: JOB_STATUS.RESOLVED, key: 'resolve' },
111
+ { status: JOB_STATUS.PENDING, key: 'pending' },
112
+ ],
113
+ collection: 'posts',
114
+ dataSource: 'another',
115
+ },
116
+ },
117
+ },
118
+ });
119
+
120
+ const post = await PostRepo.create({ values: { title: 't1' } });
121
+
122
+ await sleep(500);
123
+
124
+ const UserJobModel = db.getModel('users_jobs');
125
+ const pendingJobs = await UserJobModel.findAll({
126
+ order: [['userId', 'ASC']],
127
+ });
128
+ expect(pendingJobs.length).toBe(1);
129
+
130
+ const res1 = await userAgents[0].resource('users_jobs').submit({
131
+ filterByTk: pendingJobs[0].get('id'),
132
+ values: {
133
+ result: { f1: { title: 't1' }, _: 'pending' },
134
+ },
135
+ });
136
+ expect(res1.status).toBe(202);
137
+
138
+ await sleep(500);
139
+
140
+ const [e1] = await workflow.getExecutions();
141
+ expect(e1.status).toBe(EXECUTION_STATUS.STARTED);
142
+ const [j1] = await e1.getJobs();
143
+ expect(j1.status).toBe(JOB_STATUS.PENDING);
144
+ expect(j1.result).toMatchObject({ f1: { title: 't1' } });
145
+
146
+ const c1 = await AnotherPostRepo.find();
147
+ expect(c1.length).toBe(0);
148
+
149
+ const res2 = await userAgents[0].resource('users_jobs').submit({
150
+ filterByTk: pendingJobs[0].get('id'),
151
+ values: {
152
+ result: { f1: { title: 't2' }, _: 'resolve' },
153
+ },
154
+ });
155
+
156
+ await sleep(500);
157
+
158
+ const [e2] = await workflow.getExecutions();
159
+ expect(e2.status).toBe(EXECUTION_STATUS.RESOLVED);
160
+ const [j2] = await e2.getJobs();
161
+ expect(j2.status).toBe(JOB_STATUS.RESOLVED);
162
+ expect(j2.result).toMatchObject({ f1: { title: 't2' } });
163
+
164
+ const c2 = await AnotherPostRepo.find();
165
+ expect(c2.length).toBe(1);
166
+ });
167
+ });
168
+
169
+ describe('update', () => {
170
+ it('update as configured', async () => {
171
+ const post = await AnotherPostRepo.create({ values: { title: 't1' } });
172
+
173
+ const n1 = await workflow.createNode({
174
+ type: 'manual',
175
+ config: {
176
+ assignees: [users[0].id],
177
+ forms: {
178
+ f1: {
179
+ type: 'update',
180
+ actions: [{ status: JOB_STATUS.RESOLVED, key: 'resolve' }],
181
+ collection: 'posts',
182
+ dataSource: 'another',
183
+ filter: {
184
+ id: post.id,
185
+ },
186
+ },
187
+ },
188
+ },
189
+ });
190
+
191
+ await PostRepo.create({ values: { title: 't1' } });
192
+
193
+ await sleep(500);
194
+
195
+ const UserJobModel = db.getModel('users_jobs');
196
+ const pendingJobs = await UserJobModel.findAll({
197
+ order: [['userId', 'ASC']],
198
+ });
199
+ expect(pendingJobs.length).toBe(1);
200
+
201
+ const res1 = await userAgents[0].resource('users_jobs').submit({
202
+ filterByTk: pendingJobs[0].get('id'),
203
+ values: {
204
+ result: { f1: { title: 't2' }, _: 'resolve' },
205
+ },
206
+ });
207
+ expect(res1.status).toBe(202);
208
+
209
+ await sleep(500);
210
+
211
+ const [e2] = await workflow.getExecutions();
212
+ expect(e2.status).toBe(EXECUTION_STATUS.RESOLVED);
213
+ const [j1] = await e2.getJobs();
214
+ expect(j1.status).toBe(JOB_STATUS.RESOLVED);
215
+ expect(j1.result).toMatchObject({ f1: { title: 't2' } });
216
+
217
+ const postsAfter = await AnotherPostRepo.find();
218
+ expect(postsAfter.length).toBe(1);
219
+ expect(postsAfter[0]).toMatchObject({ title: 't2' });
220
+ });
221
+ });
222
+ });
223
+ });