@axinom/mosaic-graphql-common 0.28.0-rc.8 → 0.28.0
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.
- package/dist/plugins/bulk-edit/bulk-edit-async-plugin-factory.d.ts +49 -1
- package/dist/plugins/bulk-edit/bulk-edit-async-plugin-factory.d.ts.map +1 -1
- package/dist/plugins/bulk-edit/bulk-edit-async-plugin-factory.js +121 -26
- package/dist/plugins/bulk-edit/bulk-edit-async-plugin-factory.js.map +1 -1
- package/dist/plugins/bulk-edit/bulk-edit-item-change-handler-helpers.d.ts +8 -1
- package/dist/plugins/bulk-edit/bulk-edit-item-change-handler-helpers.d.ts.map +1 -1
- package/dist/plugins/bulk-edit/bulk-edit-item-change-handler-helpers.js +45 -39
- package/dist/plugins/bulk-edit/bulk-edit-item-change-handler-helpers.js.map +1 -1
- package/package.json +8 -8
- package/src/plugins/bulk-edit/bulk-edit-async-plugin-factory.spec.ts +1047 -0
- package/src/plugins/bulk-edit/bulk-edit-async-plugin-factory.ts +209 -34
- package/src/plugins/bulk-edit/bulk-edit-item-change-handler-helpers.spec.ts +360 -0
- package/src/plugins/bulk-edit/bulk-edit-item-change-handler-helpers.ts +67 -47
|
@@ -0,0 +1,1047 @@
|
|
|
1
|
+
import { PerformItemChangeCommand } from '@axinom/mosaic-messages';
|
|
2
|
+
import { StoreInboxMessage } from '@axinom/mosaic-transactional-inbox-outbox';
|
|
3
|
+
import { DatabaseClient } from 'pg-transactional-outbox';
|
|
4
|
+
import { asyncResolverImplementation } from './bulk-edit-async-plugin-factory';
|
|
5
|
+
|
|
6
|
+
// Mock the dependencies
|
|
7
|
+
jest.mock('@axinom/mosaic-db-common', () => ({
|
|
8
|
+
buildPgSettings: jest.fn(() => ({
|
|
9
|
+
role: 'test_role',
|
|
10
|
+
'mosaic.subject': 'test_user',
|
|
11
|
+
})),
|
|
12
|
+
transactionWithContext: jest.fn(
|
|
13
|
+
async (_pool, _isolationLevel, _pgSettings, callback) => {
|
|
14
|
+
// Execute the callback with a mock transaction client
|
|
15
|
+
const mockTxn = {} as DatabaseClient;
|
|
16
|
+
await callback(mockTxn);
|
|
17
|
+
},
|
|
18
|
+
),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
describe('bulk-edit-async-plugin-factory', () => {
|
|
22
|
+
describe('asyncResolverImplementation', () => {
|
|
23
|
+
let capturedMessages: PerformItemChangeCommand[];
|
|
24
|
+
let mockStoreInboxMessage: jest.MockedFunction<StoreInboxMessage>;
|
|
25
|
+
let mockOwnerPool: any;
|
|
26
|
+
let mockEnvOwnerPool: any;
|
|
27
|
+
let mockConfig: any;
|
|
28
|
+
let mockSubject: any;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
capturedMessages = [];
|
|
32
|
+
|
|
33
|
+
// Mock storeInboxMessage to capture messages
|
|
34
|
+
mockStoreInboxMessage = jest
|
|
35
|
+
.fn()
|
|
36
|
+
.mockImplementation(
|
|
37
|
+
async (
|
|
38
|
+
_aggregateId: string,
|
|
39
|
+
_messageSettings: any,
|
|
40
|
+
payload: PerformItemChangeCommand,
|
|
41
|
+
_client: DatabaseClient,
|
|
42
|
+
_options?: any,
|
|
43
|
+
) => {
|
|
44
|
+
capturedMessages.push(payload);
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
mockOwnerPool = {};
|
|
49
|
+
mockEnvOwnerPool = {};
|
|
50
|
+
mockConfig = {
|
|
51
|
+
serviceId: 'test-service',
|
|
52
|
+
dbOwner: 'test_owner',
|
|
53
|
+
dbEnvOwner: 'test_env_owner',
|
|
54
|
+
};
|
|
55
|
+
mockSubject = {
|
|
56
|
+
userId: 'test-user-id',
|
|
57
|
+
tenantId: 'test-tenant-id',
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
afterEach(() => {
|
|
62
|
+
jest.clearAllMocks();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('SET_FIELD_VALUES action', () => {
|
|
66
|
+
it('should generate SET_FIELD_VALUES message with correct structure', async () => {
|
|
67
|
+
// Arrange
|
|
68
|
+
const payload = {
|
|
69
|
+
set: {
|
|
70
|
+
mainTableName: 'images',
|
|
71
|
+
gqlFieldNameToColumnNameMap: {
|
|
72
|
+
title: 'title',
|
|
73
|
+
description: 'description',
|
|
74
|
+
},
|
|
75
|
+
inputData: {
|
|
76
|
+
title: 'Updated Title',
|
|
77
|
+
description: 'Updated Description',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
clears: {},
|
|
81
|
+
removals: {},
|
|
82
|
+
additions: {},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Act
|
|
86
|
+
await asyncResolverImplementation(
|
|
87
|
+
payload,
|
|
88
|
+
['image-123'],
|
|
89
|
+
mockConfig,
|
|
90
|
+
mockOwnerPool,
|
|
91
|
+
mockEnvOwnerPool,
|
|
92
|
+
'long-lived-token',
|
|
93
|
+
mockSubject,
|
|
94
|
+
mockStoreInboxMessage,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// Assert
|
|
98
|
+
expect(capturedMessages).toHaveLength(1);
|
|
99
|
+
expect(capturedMessages[0]).toEqual({
|
|
100
|
+
table_name: 'images',
|
|
101
|
+
action: 'SET_FIELD_VALUES',
|
|
102
|
+
stringified_condition: JSON.stringify({ id: 'image-123' }),
|
|
103
|
+
stringified_payload: JSON.stringify({
|
|
104
|
+
title: 'Updated Title',
|
|
105
|
+
description: 'Updated Description',
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should handle NULL values in SET_FIELD_VALUES', async () => {
|
|
111
|
+
// Arrange
|
|
112
|
+
const payload = {
|
|
113
|
+
set: {
|
|
114
|
+
mainTableName: 'images',
|
|
115
|
+
gqlFieldNameToColumnNameMap: {
|
|
116
|
+
description: 'description',
|
|
117
|
+
},
|
|
118
|
+
inputData: {
|
|
119
|
+
description: null,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
clears: {},
|
|
123
|
+
removals: {},
|
|
124
|
+
additions: {},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Act
|
|
128
|
+
await asyncResolverImplementation(
|
|
129
|
+
payload,
|
|
130
|
+
['image-123'],
|
|
131
|
+
mockConfig,
|
|
132
|
+
mockOwnerPool,
|
|
133
|
+
mockEnvOwnerPool,
|
|
134
|
+
'token',
|
|
135
|
+
mockSubject,
|
|
136
|
+
mockStoreInboxMessage,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Assert
|
|
140
|
+
expect(capturedMessages).toHaveLength(1);
|
|
141
|
+
expect(JSON.parse(capturedMessages[0].stringified_payload)).toEqual({
|
|
142
|
+
description: null,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('CLEAR_RELATED_ENTITIES action', () => {
|
|
148
|
+
it('should generate CLEAR_RELATED_ENTITIES message with correct structure', async () => {
|
|
149
|
+
// Arrange
|
|
150
|
+
const payload = {
|
|
151
|
+
set: {
|
|
152
|
+
mainTableName: 'images',
|
|
153
|
+
gqlFieldNameToColumnNameMap: {},
|
|
154
|
+
inputData: undefined,
|
|
155
|
+
},
|
|
156
|
+
clears: {
|
|
157
|
+
images_tags: {
|
|
158
|
+
parentKeyColumnName: 'image_id',
|
|
159
|
+
shouldClear: true,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
removals: {},
|
|
163
|
+
additions: {},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Act
|
|
167
|
+
await asyncResolverImplementation(
|
|
168
|
+
payload,
|
|
169
|
+
['image-123'],
|
|
170
|
+
mockConfig,
|
|
171
|
+
mockOwnerPool,
|
|
172
|
+
mockEnvOwnerPool,
|
|
173
|
+
'token',
|
|
174
|
+
mockSubject,
|
|
175
|
+
mockStoreInboxMessage,
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
// Assert
|
|
179
|
+
expect(capturedMessages).toHaveLength(1);
|
|
180
|
+
expect(capturedMessages[0]).toEqual({
|
|
181
|
+
table_name: 'images_tags',
|
|
182
|
+
action: 'CLEAR_RELATED_ENTITIES',
|
|
183
|
+
stringified_condition: JSON.stringify({ image_id: 'image-123' }),
|
|
184
|
+
stringified_payload: JSON.stringify({}),
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should support multiple relations cleared simultaneously', async () => {
|
|
189
|
+
// Arrange
|
|
190
|
+
const payload = {
|
|
191
|
+
set: {
|
|
192
|
+
mainTableName: 'user_roles',
|
|
193
|
+
gqlFieldNameToColumnNameMap: {},
|
|
194
|
+
inputData: undefined,
|
|
195
|
+
},
|
|
196
|
+
clears: {
|
|
197
|
+
user_role_parent_assignments: {
|
|
198
|
+
parentKeyColumnName: 'user_role_id',
|
|
199
|
+
shouldClear: true,
|
|
200
|
+
},
|
|
201
|
+
user_role_permission_assignments: {
|
|
202
|
+
parentKeyColumnName: 'user_role_id',
|
|
203
|
+
shouldClear: true,
|
|
204
|
+
},
|
|
205
|
+
user_role_tag_assignments: {
|
|
206
|
+
parentKeyColumnName: 'user_role_id',
|
|
207
|
+
shouldClear: true,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
removals: {},
|
|
211
|
+
additions: {},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// Act
|
|
215
|
+
await asyncResolverImplementation(
|
|
216
|
+
payload,
|
|
217
|
+
['role-1'],
|
|
218
|
+
mockConfig,
|
|
219
|
+
mockOwnerPool,
|
|
220
|
+
mockEnvOwnerPool,
|
|
221
|
+
'token',
|
|
222
|
+
mockSubject,
|
|
223
|
+
mockStoreInboxMessage,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// Assert
|
|
227
|
+
expect(capturedMessages).toHaveLength(3);
|
|
228
|
+
expect(
|
|
229
|
+
capturedMessages.every((m) => m.action === 'CLEAR_RELATED_ENTITIES'),
|
|
230
|
+
).toBe(true);
|
|
231
|
+
capturedMessages.forEach((msg) => {
|
|
232
|
+
const condition = JSON.parse(msg.stringified_condition);
|
|
233
|
+
expect(condition.user_role_id).toBe('role-1');
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should skip clear when shouldClear is false', async () => {
|
|
238
|
+
// Arrange
|
|
239
|
+
const payload = {
|
|
240
|
+
set: {
|
|
241
|
+
mainTableName: 'images',
|
|
242
|
+
gqlFieldNameToColumnNameMap: {},
|
|
243
|
+
inputData: undefined,
|
|
244
|
+
},
|
|
245
|
+
clears: {
|
|
246
|
+
images_tags: {
|
|
247
|
+
parentKeyColumnName: 'image_id',
|
|
248
|
+
shouldClear: false,
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
removals: {},
|
|
252
|
+
additions: {},
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// Act
|
|
256
|
+
await asyncResolverImplementation(
|
|
257
|
+
payload,
|
|
258
|
+
['image-123'],
|
|
259
|
+
mockConfig,
|
|
260
|
+
mockOwnerPool,
|
|
261
|
+
mockEnvOwnerPool,
|
|
262
|
+
'token',
|
|
263
|
+
mockSubject,
|
|
264
|
+
mockStoreInboxMessage,
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
// Assert
|
|
268
|
+
expect(capturedMessages).toHaveLength(0);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
describe('REMOVE_RELATED_ENTITY action', () => {
|
|
273
|
+
it('should generate REMOVE_RELATED_ENTITY message with correct structure', async () => {
|
|
274
|
+
// Arrange
|
|
275
|
+
const payload = {
|
|
276
|
+
set: {
|
|
277
|
+
mainTableName: 'images',
|
|
278
|
+
gqlFieldNameToColumnNameMap: {},
|
|
279
|
+
inputData: undefined,
|
|
280
|
+
},
|
|
281
|
+
clears: {},
|
|
282
|
+
removals: {
|
|
283
|
+
images_tags: {
|
|
284
|
+
parentKeyColumnName: 'image_id',
|
|
285
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
286
|
+
name: 'name',
|
|
287
|
+
},
|
|
288
|
+
inputData: [{ name: 'tag-to-remove' }],
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
additions: {},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// Act
|
|
295
|
+
await asyncResolverImplementation(
|
|
296
|
+
payload,
|
|
297
|
+
['image-123'],
|
|
298
|
+
mockConfig,
|
|
299
|
+
mockOwnerPool,
|
|
300
|
+
mockEnvOwnerPool,
|
|
301
|
+
'token',
|
|
302
|
+
mockSubject,
|
|
303
|
+
mockStoreInboxMessage,
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Assert
|
|
307
|
+
expect(capturedMessages).toHaveLength(1);
|
|
308
|
+
expect(capturedMessages[0]).toEqual({
|
|
309
|
+
table_name: 'images_tags',
|
|
310
|
+
action: 'REMOVE_RELATED_ENTITY',
|
|
311
|
+
stringified_condition: '',
|
|
312
|
+
stringified_payload: JSON.stringify({
|
|
313
|
+
image_id: 'image-123',
|
|
314
|
+
name: 'tag-to-remove',
|
|
315
|
+
}),
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('should generate multiple REMOVE messages for multiple items', async () => {
|
|
320
|
+
// Arrange
|
|
321
|
+
const payload = {
|
|
322
|
+
set: {
|
|
323
|
+
mainTableName: 'images',
|
|
324
|
+
gqlFieldNameToColumnNameMap: {},
|
|
325
|
+
inputData: undefined,
|
|
326
|
+
},
|
|
327
|
+
clears: {},
|
|
328
|
+
removals: {
|
|
329
|
+
images_tags: {
|
|
330
|
+
parentKeyColumnName: 'image_id',
|
|
331
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
332
|
+
name: 'name',
|
|
333
|
+
},
|
|
334
|
+
inputData: [{ name: 'tag1' }, { name: 'tag2' }, { name: 'tag3' }],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
additions: {},
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// Act
|
|
341
|
+
await asyncResolverImplementation(
|
|
342
|
+
payload,
|
|
343
|
+
['image-123'],
|
|
344
|
+
mockConfig,
|
|
345
|
+
mockOwnerPool,
|
|
346
|
+
mockEnvOwnerPool,
|
|
347
|
+
'token',
|
|
348
|
+
mockSubject,
|
|
349
|
+
mockStoreInboxMessage,
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
// Assert
|
|
353
|
+
expect(capturedMessages).toHaveLength(3);
|
|
354
|
+
expect(
|
|
355
|
+
capturedMessages.every((m) => m.action === 'REMOVE_RELATED_ENTITY'),
|
|
356
|
+
).toBe(true);
|
|
357
|
+
expect(
|
|
358
|
+
capturedMessages.every((m) => m.table_name === 'images_tags'),
|
|
359
|
+
).toBe(true);
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
describe('ADD_RELATED_ENTITY action', () => {
|
|
364
|
+
it('should generate ADD_RELATED_ENTITY message with correct structure', async () => {
|
|
365
|
+
// Arrange
|
|
366
|
+
const payload = {
|
|
367
|
+
set: {
|
|
368
|
+
mainTableName: 'images',
|
|
369
|
+
gqlFieldNameToColumnNameMap: {},
|
|
370
|
+
inputData: undefined,
|
|
371
|
+
},
|
|
372
|
+
clears: {},
|
|
373
|
+
removals: {},
|
|
374
|
+
additions: {
|
|
375
|
+
images_tags: {
|
|
376
|
+
parentKeyColumnName: 'image_id',
|
|
377
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
378
|
+
name: 'name',
|
|
379
|
+
},
|
|
380
|
+
inputData: [{ name: 'new-tag' }],
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
// Act
|
|
386
|
+
await asyncResolverImplementation(
|
|
387
|
+
payload,
|
|
388
|
+
['image-123'],
|
|
389
|
+
mockConfig,
|
|
390
|
+
mockOwnerPool,
|
|
391
|
+
mockEnvOwnerPool,
|
|
392
|
+
'token',
|
|
393
|
+
mockSubject,
|
|
394
|
+
mockStoreInboxMessage,
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
// Assert
|
|
398
|
+
expect(capturedMessages).toHaveLength(1);
|
|
399
|
+
expect(capturedMessages[0]).toEqual({
|
|
400
|
+
table_name: 'images_tags',
|
|
401
|
+
action: 'ADD_RELATED_ENTITY',
|
|
402
|
+
stringified_condition: '',
|
|
403
|
+
stringified_payload: JSON.stringify({
|
|
404
|
+
image_id: 'image-123',
|
|
405
|
+
name: 'new-tag',
|
|
406
|
+
}),
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it('should generate multiple ADD messages for multiple items', async () => {
|
|
411
|
+
// Arrange
|
|
412
|
+
const payload = {
|
|
413
|
+
set: {
|
|
414
|
+
mainTableName: 'images',
|
|
415
|
+
gqlFieldNameToColumnNameMap: {},
|
|
416
|
+
inputData: undefined,
|
|
417
|
+
},
|
|
418
|
+
clears: {},
|
|
419
|
+
removals: {},
|
|
420
|
+
additions: {
|
|
421
|
+
images_tags: {
|
|
422
|
+
parentKeyColumnName: 'image_id',
|
|
423
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
424
|
+
name: 'name',
|
|
425
|
+
},
|
|
426
|
+
inputData: [{ name: 'tag1' }, { name: 'tag2' }],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
// Act
|
|
432
|
+
await asyncResolverImplementation(
|
|
433
|
+
payload,
|
|
434
|
+
['image-123'],
|
|
435
|
+
mockConfig,
|
|
436
|
+
mockOwnerPool,
|
|
437
|
+
mockEnvOwnerPool,
|
|
438
|
+
'token',
|
|
439
|
+
mockSubject,
|
|
440
|
+
mockStoreInboxMessage,
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
// Assert
|
|
444
|
+
expect(capturedMessages).toHaveLength(2);
|
|
445
|
+
expect(
|
|
446
|
+
capturedMessages.every((m) => m.action === 'ADD_RELATED_ENTITY'),
|
|
447
|
+
).toBe(true);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
describe('Message ordering', () => {
|
|
452
|
+
it('should send messages in order: SET → CLEAR → REMOVE → ADD', async () => {
|
|
453
|
+
// Arrange
|
|
454
|
+
const payload = {
|
|
455
|
+
set: {
|
|
456
|
+
mainTableName: 'images',
|
|
457
|
+
gqlFieldNameToColumnNameMap: {
|
|
458
|
+
title: 'title',
|
|
459
|
+
},
|
|
460
|
+
inputData: {
|
|
461
|
+
title: 'Updated',
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
clears: {
|
|
465
|
+
images_tags: {
|
|
466
|
+
parentKeyColumnName: 'image_id',
|
|
467
|
+
shouldClear: true,
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
removals: {
|
|
471
|
+
images_casts: {
|
|
472
|
+
parentKeyColumnName: 'image_id',
|
|
473
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
474
|
+
castId: 'cast_id',
|
|
475
|
+
},
|
|
476
|
+
inputData: [{ castId: 'cast-1' }],
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
additions: {
|
|
480
|
+
images_licenses: {
|
|
481
|
+
parentKeyColumnName: 'image_id',
|
|
482
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
483
|
+
licenseId: 'license_id',
|
|
484
|
+
},
|
|
485
|
+
inputData: [{ licenseId: 'license-1' }],
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// Act
|
|
491
|
+
await asyncResolverImplementation(
|
|
492
|
+
payload,
|
|
493
|
+
['img-1'],
|
|
494
|
+
mockConfig,
|
|
495
|
+
mockOwnerPool,
|
|
496
|
+
mockEnvOwnerPool,
|
|
497
|
+
'token',
|
|
498
|
+
mockSubject,
|
|
499
|
+
mockStoreInboxMessage,
|
|
500
|
+
);
|
|
501
|
+
|
|
502
|
+
// Assert
|
|
503
|
+
expect(capturedMessages).toHaveLength(4);
|
|
504
|
+
expect(capturedMessages[0].action).toBe('SET_FIELD_VALUES');
|
|
505
|
+
expect(capturedMessages[0].table_name).toBe('images');
|
|
506
|
+
expect(capturedMessages[1].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
507
|
+
expect(capturedMessages[1].table_name).toBe('images_tags');
|
|
508
|
+
expect(capturedMessages[2].action).toBe('REMOVE_RELATED_ENTITY');
|
|
509
|
+
expect(capturedMessages[2].table_name).toBe('images_casts');
|
|
510
|
+
expect(capturedMessages[3].action).toBe('ADD_RELATED_ENTITY');
|
|
511
|
+
expect(capturedMessages[3].table_name).toBe('images_licenses');
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
describe('Optimization: Skip REMOVE when CLEAR is present', () => {
|
|
516
|
+
it('should skip REMOVE messages when CLEAR is present for same relation', async () => {
|
|
517
|
+
// Arrange - Both clear and remove specified for same relation
|
|
518
|
+
const payload = {
|
|
519
|
+
set: {
|
|
520
|
+
mainTableName: 'images',
|
|
521
|
+
gqlFieldNameToColumnNameMap: {},
|
|
522
|
+
inputData: undefined,
|
|
523
|
+
},
|
|
524
|
+
clears: {
|
|
525
|
+
images_tags: {
|
|
526
|
+
parentKeyColumnName: 'image_id',
|
|
527
|
+
shouldClear: true,
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
removals: {
|
|
531
|
+
images_tags: {
|
|
532
|
+
parentKeyColumnName: 'image_id',
|
|
533
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
534
|
+
name: 'name',
|
|
535
|
+
},
|
|
536
|
+
inputData: [{ name: 'tag1' }, { name: 'tag2' }],
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
additions: {},
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
// Act
|
|
543
|
+
await asyncResolverImplementation(
|
|
544
|
+
payload,
|
|
545
|
+
['image-123'],
|
|
546
|
+
mockConfig,
|
|
547
|
+
mockOwnerPool,
|
|
548
|
+
mockEnvOwnerPool,
|
|
549
|
+
'token',
|
|
550
|
+
mockSubject,
|
|
551
|
+
mockStoreInboxMessage,
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
// Assert - Only CLEAR message sent, no REMOVE messages
|
|
555
|
+
expect(capturedMessages).toHaveLength(1);
|
|
556
|
+
expect(capturedMessages[0].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
557
|
+
expect(capturedMessages[0].table_name).toBe('images_tags');
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
it('should NOT skip REMOVE when CLEAR is for different relation', async () => {
|
|
561
|
+
// Arrange - Clear tags, remove casts
|
|
562
|
+
const payload = {
|
|
563
|
+
set: {
|
|
564
|
+
mainTableName: 'images',
|
|
565
|
+
gqlFieldNameToColumnNameMap: {},
|
|
566
|
+
inputData: undefined,
|
|
567
|
+
},
|
|
568
|
+
clears: {
|
|
569
|
+
images_tags: {
|
|
570
|
+
parentKeyColumnName: 'image_id',
|
|
571
|
+
shouldClear: true,
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
removals: {
|
|
575
|
+
images_casts: {
|
|
576
|
+
parentKeyColumnName: 'image_id',
|
|
577
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
578
|
+
castId: 'cast_id',
|
|
579
|
+
},
|
|
580
|
+
inputData: [{ castId: 'cast-1' }],
|
|
581
|
+
},
|
|
582
|
+
},
|
|
583
|
+
additions: {},
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
// Act
|
|
587
|
+
await asyncResolverImplementation(
|
|
588
|
+
payload,
|
|
589
|
+
['image-123'],
|
|
590
|
+
mockConfig,
|
|
591
|
+
mockOwnerPool,
|
|
592
|
+
mockEnvOwnerPool,
|
|
593
|
+
'token',
|
|
594
|
+
mockSubject,
|
|
595
|
+
mockStoreInboxMessage,
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
// Assert - Both CLEAR and REMOVE messages sent
|
|
599
|
+
expect(capturedMessages).toHaveLength(2);
|
|
600
|
+
expect(capturedMessages[0].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
601
|
+
expect(capturedMessages[0].table_name).toBe('images_tags');
|
|
602
|
+
expect(capturedMessages[1].action).toBe('REMOVE_RELATED_ENTITY');
|
|
603
|
+
expect(capturedMessages[1].table_name).toBe('images_casts');
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
describe('Multi-entity operations', () => {
|
|
608
|
+
it('should process all entity IDs and send messages for each', async () => {
|
|
609
|
+
// Arrange
|
|
610
|
+
const payload = {
|
|
611
|
+
set: {
|
|
612
|
+
mainTableName: 'images',
|
|
613
|
+
gqlFieldNameToColumnNameMap: {
|
|
614
|
+
title: 'title',
|
|
615
|
+
},
|
|
616
|
+
inputData: {
|
|
617
|
+
title: 'Updated',
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
clears: {
|
|
621
|
+
images_tags: {
|
|
622
|
+
parentKeyColumnName: 'image_id',
|
|
623
|
+
shouldClear: true,
|
|
624
|
+
},
|
|
625
|
+
},
|
|
626
|
+
removals: {},
|
|
627
|
+
additions: {},
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// Act - 3 entities
|
|
631
|
+
await asyncResolverImplementation(
|
|
632
|
+
payload,
|
|
633
|
+
['img-1', 'img-2', 'img-3'],
|
|
634
|
+
mockConfig,
|
|
635
|
+
mockOwnerPool,
|
|
636
|
+
mockEnvOwnerPool,
|
|
637
|
+
'token',
|
|
638
|
+
mockSubject,
|
|
639
|
+
mockStoreInboxMessage,
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
// Assert - 2 messages per entity * 3 entities = 6 messages
|
|
643
|
+
expect(capturedMessages).toHaveLength(6);
|
|
644
|
+
|
|
645
|
+
// Verify messages for img-1
|
|
646
|
+
expect(capturedMessages[0].action).toBe('SET_FIELD_VALUES');
|
|
647
|
+
expect(JSON.parse(capturedMessages[0].stringified_condition).id).toBe(
|
|
648
|
+
'img-1',
|
|
649
|
+
);
|
|
650
|
+
expect(capturedMessages[1].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
651
|
+
expect(
|
|
652
|
+
JSON.parse(capturedMessages[1].stringified_condition).image_id,
|
|
653
|
+
).toBe('img-1');
|
|
654
|
+
|
|
655
|
+
// Verify messages for img-2
|
|
656
|
+
expect(capturedMessages[2].action).toBe('SET_FIELD_VALUES');
|
|
657
|
+
expect(JSON.parse(capturedMessages[2].stringified_condition).id).toBe(
|
|
658
|
+
'img-2',
|
|
659
|
+
);
|
|
660
|
+
expect(capturedMessages[3].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
661
|
+
expect(
|
|
662
|
+
JSON.parse(capturedMessages[3].stringified_condition).image_id,
|
|
663
|
+
).toBe('img-2');
|
|
664
|
+
|
|
665
|
+
// Verify messages for img-3
|
|
666
|
+
expect(capturedMessages[4].action).toBe('SET_FIELD_VALUES');
|
|
667
|
+
expect(JSON.parse(capturedMessages[4].stringified_condition).id).toBe(
|
|
668
|
+
'img-3',
|
|
669
|
+
);
|
|
670
|
+
expect(capturedMessages[5].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
671
|
+
expect(
|
|
672
|
+
JSON.parse(capturedMessages[5].stringified_condition).image_id,
|
|
673
|
+
).toBe('img-3');
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
it('should calculate correct message count for complex bulk operation', async () => {
|
|
677
|
+
// Arrange - Operation with all action types
|
|
678
|
+
const payload = {
|
|
679
|
+
set: {
|
|
680
|
+
mainTableName: 'images',
|
|
681
|
+
gqlFieldNameToColumnNameMap: {
|
|
682
|
+
title: 'title',
|
|
683
|
+
},
|
|
684
|
+
inputData: {
|
|
685
|
+
title: 'Updated',
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
clears: {
|
|
689
|
+
images_tags: {
|
|
690
|
+
parentKeyColumnName: 'image_id',
|
|
691
|
+
shouldClear: true,
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
removals: {
|
|
695
|
+
images_casts: {
|
|
696
|
+
parentKeyColumnName: 'image_id',
|
|
697
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
698
|
+
castId: 'cast_id',
|
|
699
|
+
},
|
|
700
|
+
inputData: [{ castId: 'cast-1' }],
|
|
701
|
+
},
|
|
702
|
+
},
|
|
703
|
+
additions: {
|
|
704
|
+
images_licenses: {
|
|
705
|
+
parentKeyColumnName: 'image_id',
|
|
706
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
707
|
+
licenseId: 'license_id',
|
|
708
|
+
},
|
|
709
|
+
inputData: [{ licenseId: 'lic-1' }, { licenseId: 'lic-2' }],
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
// Act - 2 entities
|
|
715
|
+
await asyncResolverImplementation(
|
|
716
|
+
payload,
|
|
717
|
+
['img-1', 'img-2'],
|
|
718
|
+
mockConfig,
|
|
719
|
+
mockOwnerPool,
|
|
720
|
+
mockEnvOwnerPool,
|
|
721
|
+
'token',
|
|
722
|
+
mockSubject,
|
|
723
|
+
mockStoreInboxMessage,
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
// Assert
|
|
727
|
+
// Per entity: 1 SET + 1 CLEAR + 1 REMOVE + 2 ADD = 5 messages
|
|
728
|
+
// 5 messages * 2 entities = 10 total
|
|
729
|
+
expect(capturedMessages).toHaveLength(10);
|
|
730
|
+
});
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
describe('Real-world use cases', () => {
|
|
734
|
+
it('should support "replace all tags" operation', async () => {
|
|
735
|
+
// Arrange
|
|
736
|
+
const payload = {
|
|
737
|
+
set: {
|
|
738
|
+
mainTableName: 'images',
|
|
739
|
+
gqlFieldNameToColumnNameMap: {},
|
|
740
|
+
inputData: undefined,
|
|
741
|
+
},
|
|
742
|
+
clears: {
|
|
743
|
+
images_tags: {
|
|
744
|
+
parentKeyColumnName: 'image_id',
|
|
745
|
+
shouldClear: true,
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
removals: {},
|
|
749
|
+
additions: {
|
|
750
|
+
images_tags: {
|
|
751
|
+
parentKeyColumnName: 'image_id',
|
|
752
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
753
|
+
name: 'name',
|
|
754
|
+
},
|
|
755
|
+
inputData: [{ name: 'new-tag-1' }, { name: 'new-tag-2' }],
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
// Act
|
|
761
|
+
await asyncResolverImplementation(
|
|
762
|
+
payload,
|
|
763
|
+
['image-123'],
|
|
764
|
+
mockConfig,
|
|
765
|
+
mockOwnerPool,
|
|
766
|
+
mockEnvOwnerPool,
|
|
767
|
+
'token',
|
|
768
|
+
mockSubject,
|
|
769
|
+
mockStoreInboxMessage,
|
|
770
|
+
);
|
|
771
|
+
|
|
772
|
+
// Assert - CLEAR followed by 2 ADDs
|
|
773
|
+
expect(capturedMessages).toHaveLength(3);
|
|
774
|
+
expect(capturedMessages[0].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
775
|
+
expect(capturedMessages[1].action).toBe('ADD_RELATED_ENTITY');
|
|
776
|
+
expect(capturedMessages[2].action).toBe('ADD_RELATED_ENTITY');
|
|
777
|
+
expect(
|
|
778
|
+
capturedMessages.every((m) => m.table_name === 'images_tags'),
|
|
779
|
+
).toBe(true);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
it('should support "reset permissions" operation', async () => {
|
|
783
|
+
// Arrange
|
|
784
|
+
const payload = {
|
|
785
|
+
set: {
|
|
786
|
+
mainTableName: 'user_roles',
|
|
787
|
+
gqlFieldNameToColumnNameMap: {},
|
|
788
|
+
inputData: undefined,
|
|
789
|
+
},
|
|
790
|
+
clears: {
|
|
791
|
+
user_role_permission_assignments: {
|
|
792
|
+
parentKeyColumnName: 'user_role_id',
|
|
793
|
+
shouldClear: true,
|
|
794
|
+
},
|
|
795
|
+
},
|
|
796
|
+
removals: {},
|
|
797
|
+
additions: {
|
|
798
|
+
user_role_permission_assignments: {
|
|
799
|
+
parentKeyColumnName: 'user_role_id',
|
|
800
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
801
|
+
permissionId: 'permission_id',
|
|
802
|
+
},
|
|
803
|
+
inputData: [
|
|
804
|
+
{ permissionId: 'perm-read' },
|
|
805
|
+
{ permissionId: 'perm-write' },
|
|
806
|
+
],
|
|
807
|
+
},
|
|
808
|
+
},
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
// Act
|
|
812
|
+
await asyncResolverImplementation(
|
|
813
|
+
payload,
|
|
814
|
+
['role-admin'],
|
|
815
|
+
mockConfig,
|
|
816
|
+
mockOwnerPool,
|
|
817
|
+
mockEnvOwnerPool,
|
|
818
|
+
'token',
|
|
819
|
+
mockSubject,
|
|
820
|
+
mockStoreInboxMessage,
|
|
821
|
+
);
|
|
822
|
+
|
|
823
|
+
// Assert
|
|
824
|
+
expect(capturedMessages).toHaveLength(3);
|
|
825
|
+
expect(capturedMessages[0].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
826
|
+
expect(capturedMessages[1].action).toBe('ADD_RELATED_ENTITY');
|
|
827
|
+
expect(capturedMessages[2].action).toBe('ADD_RELATED_ENTITY');
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it('should support "update and clear multiple relations" operation', async () => {
|
|
831
|
+
// Arrange
|
|
832
|
+
const payload = {
|
|
833
|
+
set: {
|
|
834
|
+
mainTableName: 'images',
|
|
835
|
+
gqlFieldNameToColumnNameMap: {
|
|
836
|
+
title: 'title',
|
|
837
|
+
description: 'description',
|
|
838
|
+
},
|
|
839
|
+
inputData: {
|
|
840
|
+
title: 'Updated Title',
|
|
841
|
+
description: null,
|
|
842
|
+
},
|
|
843
|
+
},
|
|
844
|
+
clears: {
|
|
845
|
+
images_tags: {
|
|
846
|
+
parentKeyColumnName: 'image_id',
|
|
847
|
+
shouldClear: true,
|
|
848
|
+
},
|
|
849
|
+
images_casts: {
|
|
850
|
+
parentKeyColumnName: 'image_id',
|
|
851
|
+
shouldClear: true,
|
|
852
|
+
},
|
|
853
|
+
},
|
|
854
|
+
removals: {},
|
|
855
|
+
additions: {},
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
// Act
|
|
859
|
+
await asyncResolverImplementation(
|
|
860
|
+
payload,
|
|
861
|
+
['image-123'],
|
|
862
|
+
mockConfig,
|
|
863
|
+
mockOwnerPool,
|
|
864
|
+
mockEnvOwnerPool,
|
|
865
|
+
'token',
|
|
866
|
+
mockSubject,
|
|
867
|
+
mockStoreInboxMessage,
|
|
868
|
+
);
|
|
869
|
+
|
|
870
|
+
// Assert
|
|
871
|
+
expect(capturedMessages).toHaveLength(3);
|
|
872
|
+
expect(capturedMessages[0].action).toBe('SET_FIELD_VALUES');
|
|
873
|
+
expect(capturedMessages[0].table_name).toBe('images');
|
|
874
|
+
expect(capturedMessages[1].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
875
|
+
expect(capturedMessages[2].action).toBe('CLEAR_RELATED_ENTITIES');
|
|
876
|
+
expect(capturedMessages[1].table_name).not.toBe(
|
|
877
|
+
capturedMessages[2].table_name,
|
|
878
|
+
);
|
|
879
|
+
});
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
describe('Field name mapping', () => {
|
|
883
|
+
it('should map GraphQL field names to SQL column names', async () => {
|
|
884
|
+
// Arrange - GraphQL uses camelCase, SQL uses snake_case
|
|
885
|
+
const payload = {
|
|
886
|
+
set: {
|
|
887
|
+
mainTableName: 'images',
|
|
888
|
+
gqlFieldNameToColumnNameMap: {
|
|
889
|
+
originalTitle: 'original_title',
|
|
890
|
+
externalId: 'external_id',
|
|
891
|
+
},
|
|
892
|
+
inputData: {
|
|
893
|
+
originalTitle: 'Test',
|
|
894
|
+
externalId: 'ext-123',
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
clears: {},
|
|
898
|
+
removals: {},
|
|
899
|
+
additions: {},
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
// Act
|
|
903
|
+
await asyncResolverImplementation(
|
|
904
|
+
payload,
|
|
905
|
+
['img-1'],
|
|
906
|
+
mockConfig,
|
|
907
|
+
mockOwnerPool,
|
|
908
|
+
mockEnvOwnerPool,
|
|
909
|
+
'token',
|
|
910
|
+
mockSubject,
|
|
911
|
+
mockStoreInboxMessage,
|
|
912
|
+
);
|
|
913
|
+
|
|
914
|
+
// Assert
|
|
915
|
+
expect(capturedMessages).toHaveLength(1);
|
|
916
|
+
const payload_parsed = JSON.parse(
|
|
917
|
+
capturedMessages[0].stringified_payload,
|
|
918
|
+
);
|
|
919
|
+
expect(payload_parsed).toEqual({
|
|
920
|
+
original_title: 'Test',
|
|
921
|
+
external_id: 'ext-123',
|
|
922
|
+
});
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
it('should map GraphQL field names in FK additions', async () => {
|
|
926
|
+
// Arrange
|
|
927
|
+
const payload = {
|
|
928
|
+
set: {
|
|
929
|
+
mainTableName: 'images',
|
|
930
|
+
gqlFieldNameToColumnNameMap: {},
|
|
931
|
+
inputData: undefined,
|
|
932
|
+
},
|
|
933
|
+
clears: {},
|
|
934
|
+
removals: {},
|
|
935
|
+
additions: {
|
|
936
|
+
images_tags: {
|
|
937
|
+
parentKeyColumnName: 'image_id',
|
|
938
|
+
fkGqlFieldNameToColumnNameMap: {
|
|
939
|
+
tagName: 'name',
|
|
940
|
+
tagValue: 'value',
|
|
941
|
+
},
|
|
942
|
+
inputData: [{ tagName: 'genre', tagValue: 'action' }],
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
// Act
|
|
948
|
+
await asyncResolverImplementation(
|
|
949
|
+
payload,
|
|
950
|
+
['img-1'],
|
|
951
|
+
mockConfig,
|
|
952
|
+
mockOwnerPool,
|
|
953
|
+
mockEnvOwnerPool,
|
|
954
|
+
'token',
|
|
955
|
+
mockSubject,
|
|
956
|
+
mockStoreInboxMessage,
|
|
957
|
+
);
|
|
958
|
+
|
|
959
|
+
// Assert
|
|
960
|
+
const payload_parsed = JSON.parse(
|
|
961
|
+
capturedMessages[0].stringified_payload,
|
|
962
|
+
);
|
|
963
|
+
expect(payload_parsed).toEqual({
|
|
964
|
+
image_id: 'img-1',
|
|
965
|
+
name: 'genre',
|
|
966
|
+
value: 'action',
|
|
967
|
+
});
|
|
968
|
+
});
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
describe('Edge cases', () => {
|
|
972
|
+
it('should handle empty entity IDs array', async () => {
|
|
973
|
+
// Arrange
|
|
974
|
+
const payload = {
|
|
975
|
+
set: {
|
|
976
|
+
mainTableName: 'images',
|
|
977
|
+
gqlFieldNameToColumnNameMap: {
|
|
978
|
+
title: 'title',
|
|
979
|
+
},
|
|
980
|
+
inputData: {
|
|
981
|
+
title: 'Updated',
|
|
982
|
+
},
|
|
983
|
+
},
|
|
984
|
+
clears: {},
|
|
985
|
+
removals: {},
|
|
986
|
+
additions: {},
|
|
987
|
+
};
|
|
988
|
+
|
|
989
|
+
// Act
|
|
990
|
+
await asyncResolverImplementation(
|
|
991
|
+
payload,
|
|
992
|
+
[], // Empty array
|
|
993
|
+
mockConfig,
|
|
994
|
+
mockOwnerPool,
|
|
995
|
+
mockEnvOwnerPool,
|
|
996
|
+
'token',
|
|
997
|
+
mockSubject,
|
|
998
|
+
mockStoreInboxMessage,
|
|
999
|
+
);
|
|
1000
|
+
|
|
1001
|
+
// Assert - No messages sent
|
|
1002
|
+
expect(capturedMessages).toHaveLength(0);
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
it('should handle undefined inputData arrays', async () => {
|
|
1006
|
+
// Arrange
|
|
1007
|
+
const payload = {
|
|
1008
|
+
set: {
|
|
1009
|
+
mainTableName: 'images',
|
|
1010
|
+
gqlFieldNameToColumnNameMap: {},
|
|
1011
|
+
inputData: undefined,
|
|
1012
|
+
},
|
|
1013
|
+
clears: {},
|
|
1014
|
+
removals: {
|
|
1015
|
+
images_tags: {
|
|
1016
|
+
parentKeyColumnName: 'image_id',
|
|
1017
|
+
fkGqlFieldNameToColumnNameMap: {},
|
|
1018
|
+
inputData: undefined, // undefined data
|
|
1019
|
+
},
|
|
1020
|
+
},
|
|
1021
|
+
additions: {
|
|
1022
|
+
images_licenses: {
|
|
1023
|
+
parentKeyColumnName: 'image_id',
|
|
1024
|
+
fkGqlFieldNameToColumnNameMap: {},
|
|
1025
|
+
inputData: undefined, // undefined data
|
|
1026
|
+
},
|
|
1027
|
+
},
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
// Act
|
|
1031
|
+
await asyncResolverImplementation(
|
|
1032
|
+
payload,
|
|
1033
|
+
['img-1'],
|
|
1034
|
+
mockConfig,
|
|
1035
|
+
mockOwnerPool,
|
|
1036
|
+
mockEnvOwnerPool,
|
|
1037
|
+
'token',
|
|
1038
|
+
mockSubject,
|
|
1039
|
+
mockStoreInboxMessage,
|
|
1040
|
+
);
|
|
1041
|
+
|
|
1042
|
+
// Assert - No messages sent since all inputData is undefined
|
|
1043
|
+
expect(capturedMessages).toHaveLength(0);
|
|
1044
|
+
});
|
|
1045
|
+
});
|
|
1046
|
+
});
|
|
1047
|
+
});
|