@contrail/flexplm 1.5.1-alpha.64caad7 → 1.6.0-alpha.6f15d4e

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.
Files changed (111) hide show
  1. package/lib/cli/commands/compile.d.ts +4 -0
  2. package/lib/cli/commands/compile.js +73 -0
  3. package/lib/cli/commands/compile.spec.d.ts +1 -0
  4. package/lib/cli/commands/compile.spec.js +80 -0
  5. package/lib/cli/commands/create.d.ts +5 -0
  6. package/lib/cli/commands/create.js +77 -0
  7. package/lib/cli/commands/create.spec.d.ts +1 -0
  8. package/lib/cli/commands/create.spec.js +78 -0
  9. package/lib/cli/commands/upload.d.ts +17 -0
  10. package/lib/cli/commands/upload.js +228 -0
  11. package/lib/cli/commands/upload.spec.d.ts +1 -0
  12. package/lib/cli/commands/upload.spec.js +88 -0
  13. package/lib/cli/index.d.ts +5 -0
  14. package/lib/cli/index.js +70 -0
  15. package/lib/cli/index.spec.d.ts +1 -0
  16. package/lib/cli/index.spec.js +85 -0
  17. package/lib/cli/template/mapping-template.ts.template +62 -0
  18. package/lib/entity-processor/base-entity-processor.d.ts +65 -0
  19. package/lib/entity-processor/base-entity-processor.js +71 -0
  20. package/lib/entity-processor/base-entity-processor.spec.js +1 -0
  21. package/lib/index.d.ts +1 -0
  22. package/lib/index.js +1 -0
  23. package/lib/interfaces/mapping-file.d.ts +460 -0
  24. package/lib/interfaces/mapping-file.js +2 -0
  25. package/lib/publish/base-process-publish-assortment.d.ts +25 -1
  26. package/lib/publish/base-process-publish-assortment.js +67 -48
  27. package/lib/publish/base-process-publish-assortment.spec.js +22 -143
  28. package/lib/publish/mockData.js +5 -0
  29. package/lib/transform/identifier-conversion-spec-mockData.js +34 -6
  30. package/lib/transform/identifier-conversion.d.ts +36 -0
  31. package/lib/transform/identifier-conversion.js +36 -0
  32. package/lib/transform/identifier-conversion.spec.js +4 -0
  33. package/lib/util/config-defaults.js +3 -0
  34. package/lib/util/config-defaults.spec.js +9 -0
  35. package/lib/util/data-converter-spec-mockData.js +17 -3
  36. package/lib/util/data-converter.d.ts +97 -0
  37. package/lib/util/data-converter.js +127 -1
  38. package/lib/util/data-converter.spec.js +2 -0
  39. package/lib/util/error-response-object.d.ts +5 -0
  40. package/lib/util/error-response-object.js +7 -0
  41. package/lib/util/event-short-message-status.js +1 -0
  42. package/lib/util/federation.js +8 -0
  43. package/lib/util/flexplm-connect.d.ts +7 -0
  44. package/lib/util/flexplm-connect.js +14 -0
  45. package/lib/util/logger-config.js +1 -0
  46. package/lib/util/map-util-spec-mockData.js +17 -3
  47. package/lib/util/map-utils.d.ts +27 -0
  48. package/lib/util/map-utils.js +27 -0
  49. package/lib/util/thumbnail-util.d.ts +21 -0
  50. package/lib/util/thumbnail-util.js +28 -1
  51. package/lib/util/thumbnail-util.spec.js +6 -0
  52. package/lib/util/type-conversion-utils-spec-mockData.js +3 -3
  53. package/lib/util/type-conversion-utils.d.ts +151 -0
  54. package/lib/util/type-conversion-utils.js +154 -0
  55. package/lib/util/type-defaults.d.ts +66 -0
  56. package/lib/util/type-defaults.js +66 -0
  57. package/lib/util/type-defaults.spec.js +5 -5
  58. package/lib/util/type-utils.d.ts +21 -0
  59. package/lib/util/type-utils.js +23 -0
  60. package/lib/util/type-utils.spec.js +2 -0
  61. package/package.json +21 -6
  62. package/scripts/copy-template.js +10 -0
  63. package/.github/pull_request_template.md +0 -31
  64. package/.github/workflows/flexplm-lib.yml +0 -27
  65. package/.github/workflows/publish-to-npm.yml +0 -121
  66. package/CHANGELOG.md +0 -49
  67. package/publish.bat +0 -5
  68. package/publish.sh +0 -5
  69. package/src/entity-processor/base-entity-processor.spec.ts +0 -689
  70. package/src/entity-processor/base-entity-processor.ts +0 -583
  71. package/src/flexplm-request.ts +0 -28
  72. package/src/flexplm-utils.spec.ts +0 -27
  73. package/src/flexplm-utils.ts +0 -29
  74. package/src/index.ts +0 -22
  75. package/src/interfaces/interfaces.ts +0 -122
  76. package/src/interfaces/item-family-changes.ts +0 -67
  77. package/src/interfaces/publish-change-data.ts +0 -43
  78. package/src/publish/base-process-publish-assortment-callback.ts +0 -50
  79. package/src/publish/base-process-publish-assortment.spec.ts +0 -2154
  80. package/src/publish/base-process-publish-assortment.ts +0 -1173
  81. package/src/publish/mockData.ts +0 -4561
  82. package/src/transform/identifier-conversion-spec-mockData.ts +0 -496
  83. package/src/transform/identifier-conversion.spec.ts +0 -386
  84. package/src/transform/identifier-conversion.ts +0 -282
  85. package/src/util/config-defaults.spec.ts +0 -445
  86. package/src/util/config-defaults.ts +0 -106
  87. package/src/util/data-converter-spec-mockData.ts +0 -231
  88. package/src/util/data-converter.spec.ts +0 -1622
  89. package/src/util/data-converter.ts +0 -819
  90. package/src/util/error-response-object.spec.ts +0 -116
  91. package/src/util/error-response-object.ts +0 -50
  92. package/src/util/event-short-message-status.ts +0 -22
  93. package/src/util/federation.ts +0 -172
  94. package/src/util/flexplm-connect.spec.ts +0 -132
  95. package/src/util/flexplm-connect.ts +0 -208
  96. package/src/util/logger-config.ts +0 -20
  97. package/src/util/map-util-spec-mockData.ts +0 -231
  98. package/src/util/map-utils.spec.ts +0 -103
  99. package/src/util/map-utils.ts +0 -41
  100. package/src/util/mockData.ts +0 -101
  101. package/src/util/thumbnail-util.spec.ts +0 -508
  102. package/src/util/thumbnail-util.ts +0 -272
  103. package/src/util/type-conversion-utils-spec-mockData.ts +0 -272
  104. package/src/util/type-conversion-utils.spec.ts +0 -1031
  105. package/src/util/type-conversion-utils.ts +0 -490
  106. package/src/util/type-defaults.spec.ts +0 -797
  107. package/src/util/type-defaults.ts +0 -320
  108. package/src/util/type-utils.spec.ts +0 -227
  109. package/src/util/type-utils.ts +0 -144
  110. package/tsconfig.json +0 -24
  111. package/tslint.json +0 -57
@@ -1,2154 +0,0 @@
1
- import { BaseProcessPublishAssortment } from './base-process-publish-assortment';
2
- import { apc_2bOWR2j9R0QThDVu_delete_history, fall_2003_deleteChanges_run2, fall_2003_fedMapping, fall_2003_fullChange, fall_2003_fullChange_run2, fall_2003_hydratedDetails, fall_2003_hydratedDetails_run2, plan1_across_month_DST, plan1_history } from './mockData';
3
- import { FCConfig, SeasonFederation } from '../interfaces/interfaces';
4
- import { DataConverter } from '../util/data-converter';
5
- import { PublishChangeData } from '../interfaces/publish-change-data';
6
- import { MapFileUtil } from '@contrail/transform-data';
7
- import { Entities } from '@contrail/sdk';
8
- import { TypeConversionUtils } from '../util/type-conversion-utils';
9
- import { MapUtil } from '../util/map-utils';
10
- import { ItemFamilyChanges } from '../interfaces/item-family-changes';
11
- import { FlexPLMConnect } from '../util/flexplm-connect';
12
-
13
- let federatedId = '';
14
- jest.mock('../util/data-converter', () => {
15
- return {
16
- DataConverter: class {
17
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
18
- getFlexPLMObjectData(newData, dataToSkip: string[], inflateObjRef: boolean) {
19
- return newData;
20
- }
21
- }
22
- };
23
- });
24
-
25
- jest.mock('../util/federation', () => {
26
- return {
27
- Federation: class {
28
- getFederatedMappedRefId() {
29
- return federatedId;
30
- }
31
- }
32
- };
33
- });
34
- let entityObject = {};
35
- let getOptionsObject = {};
36
- let createCallArg: any = undefined;
37
- let fileUploadCalls: any[] = [];
38
- let fileUploadResult: any = {
39
- id: 'file-123',
40
- downloadUrl: 'https://download.url',
41
- adminDownloadUrl: 'https://admin.download.url'
42
- };
43
- jest.mock('@contrail/sdk', () => {
44
- return {
45
- Entities: class{
46
- get(_getOtionsObject){
47
- getOptionsObject = _getOtionsObject;
48
- return entityObject;
49
- }
50
- create(arg){
51
- createCallArg = arg;
52
- return Promise.resolve({});
53
- }
54
- },
55
- Files: class{
56
- createAndUploadFileFromBuffer(buffer, mimeType, fileName, _x, ttl){
57
- fileUploadCalls.push({ buffer, mimeType, fileName, ttl });
58
- return Promise.resolve(fileUploadResult);
59
- }
60
- },
61
- Request: class{}
62
- };
63
- });
64
- describe('process publish assortment', () => {
65
- const config = { } as unknown as FCConfig;
66
- beforeEach(() => {
67
- federatedId = '';
68
- entityObject = {publishToFlexPLM:true};
69
- getOptionsObject = {};
70
- });
71
- afterEach(() => {
72
- jest.restoreAllMocks();
73
- });
74
- it('No Federation Info', async () => {
75
- const event = {
76
- assortmentId: 'B3oRQpYVYzcJAJtQ'
77
- };
78
- const identifierKeys = ['flexPLMSeasonName'];
79
- const informationKeys = ['name'];
80
- const spyTCU_id_keys = jest.spyOn(TypeConversionUtils, 'getIdentifierProperties')
81
- .mockImplementation(async () => identifierKeys);
82
- const spyTCU_info_keys = jest.spyOn(TypeConversionUtils, 'getInformationalProperties')
83
- .mockImplementation(async () => informationKeys);
84
-
85
- const mapFileUtil = new MapFileUtil(new Entities());
86
- const dc = new DataConverter(config, mapFileUtil);
87
- const results = await new BaseProcessPublishAssortment(config, dc, mapFileUtil).process(event);
88
- expect(results['results']['message']).toEqual(BaseProcessPublishAssortment.ASSORTMENT_NO_FED_INFO + identifierKeys);
89
- });
90
- });
91
-
92
- describe('getPublishInfo', () =>{
93
- const config = {} as FCConfig;
94
- const mapFileUtil = new MapFileUtil(new Entities());
95
- const dc = new DataConverter(config, mapFileUtil);
96
-
97
- const assortmentId = 'oqIFX3ELRy8sFRd0';
98
- const versionName = 'Version 1';
99
- const versionComments = 'Some Comments';
100
- const createdOn = '2023-01-15T19:13:58.902Z';
101
- const plan_history = [
102
- {
103
- id: 'sJbGx1Fpq1v2MmcI',
104
- versionName,
105
- versionComments,
106
- createdOn
107
-
108
- }
109
- ];
110
- it('All Publish Info', async () =>{
111
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
112
-
113
- const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
114
- const publisher = {
115
- email: 'chris@vibeiq.com'
116
- };
117
- const assortmentName = 'VibeIQ Fall 2023';
118
- const versionHistoryNumber = 1234;
119
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
120
- .mockImplementation(async (assortmentId) => {
121
- return {id: assortmentId, name: assortmentName};
122
- });
123
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
124
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
125
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
126
- return versionHistoryNumber;
127
- });
128
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, plan_history, publisher);
129
- expect(publishInfo.assortmentName).toEqual(assortmentName);
130
- expect(publishInfo.versionName).toEqual(versionName);
131
- expect(publishInfo.versionComments).toEqual(versionComments);
132
- expect(publishInfo.publishDate).toEqual(createdOn);
133
- expect(publishInfo.publisher).toEqual(publisher);
134
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
135
- spyGetAssortment.mockRestore();
136
- spyyGetSnapshotVersion.mockRestore();
137
- });
138
-
139
- it('No Assortment Name', async () =>{
140
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
141
-
142
- const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
143
- const publisher = {
144
- email: 'chris@vibeiq.com'
145
- };
146
- const versionHistoryNumber = 1234;
147
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
148
- .mockImplementation(async (assortmentId) => {
149
- return {id: assortmentId, name: undefined};
150
- });
151
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
152
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
153
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
154
- return versionHistoryNumber;
155
- });
156
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, plan_history, publisher);
157
- expect(publishInfo.assortmentName).toBeUndefined;
158
- expect(publishInfo.versionName).toEqual(versionName);
159
- expect(publishInfo.versionComments).toEqual(versionComments);
160
- expect(publishInfo.publishDate).toEqual(createdOn);
161
- expect(publishInfo.publisher).toEqual(publisher);
162
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
163
- spyGetAssortment.mockRestore();
164
- spyyGetSnapshotVersion.mockRestore();
165
- });
166
-
167
- it('No Assortment', async () =>{
168
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
169
-
170
- const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
171
- const publisher = {
172
- email: 'chris@vibeiq.com'
173
- };
174
- const versionHistoryNumber = 1234;
175
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
176
- .mockImplementation(async (assortmentId) => {
177
- return undefined;
178
- });
179
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
180
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
181
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
182
- return versionHistoryNumber;
183
- });
184
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, plan_history, publisher);
185
- expect(publishInfo.assortmentName).toBeUndefined();
186
- expect(publishInfo.versionName).toEqual(versionName);
187
- expect(publishInfo.versionComments).toEqual(versionComments);
188
- expect(publishInfo.publishDate).toEqual(createdOn);
189
- expect(publishInfo.publisher).toEqual(publisher);
190
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
191
- spyGetAssortment.mockRestore();
192
- spyyGetSnapshotVersion.mockRestore();
193
- });
194
-
195
- it('Empty Version Name & Comments', async () =>{
196
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
197
- const history = [
198
- {
199
- id: 'sJbGx1Fpq1v2MmcI',
200
- versionName: '',
201
- versionComments: '',
202
- createdOn
203
- }
204
- ];
205
- const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
206
- const publisher = {
207
- email: 'chris@vibeiq.com'
208
- };
209
- const assortmentName = 'VibeIQ Fall 2023';
210
- const versionHistoryNumber = 1234;
211
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
212
- .mockImplementation(async (assortmentId) => {
213
- return {id: assortmentId, name: assortmentName};
214
- });
215
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
216
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
217
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
218
- return versionHistoryNumber;
219
- });
220
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, history, publisher);
221
- expect(publishInfo.assortmentName).toEqual(assortmentName);
222
- expect(publishInfo.versionName).toEqual('');
223
- expect(publishInfo.versionComments).toEqual('');
224
- expect(publishInfo.publishDate).toEqual(createdOn);
225
- expect(publishInfo.publisher).toEqual(publisher);
226
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
227
- spyGetAssortment.mockRestore();
228
- spyyGetSnapshotVersion.mockRestore();
229
- });
230
-
231
- it('Undefined Publisher', async () =>{
232
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
233
-
234
- const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
235
- const publisher = undefined;
236
- const assortmentName = 'VibeIQ Fall 2023';
237
- const versionHistoryNumber = 1234;
238
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
239
- .mockImplementation(async (assortmentId) => {
240
- return {id: assortmentId, name: assortmentName};
241
- });
242
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
243
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
244
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
245
- return versionHistoryNumber;
246
- });
247
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, plan_history, publisher);
248
- expect(publishInfo.assortmentName).toEqual(assortmentName);
249
- expect(publishInfo.versionName).toEqual(versionName);
250
- expect(publishInfo.versionComments).toEqual(versionComments);
251
- expect(publishInfo.publishDate).toEqual(createdOn);
252
- expect(publishInfo.publisher).toBeUndefined();
253
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
254
- spyGetAssortment.mockRestore();
255
- spyyGetSnapshotVersion.mockRestore();
256
- });
257
-
258
- it('No APC', async () =>{
259
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
260
-
261
- const assortmentPublishChangeId = 'bad-id';
262
- const publisher = {
263
- email: 'chris@vibeiq.com'
264
- };
265
- const assortmentName = 'VibeIQ Fall 2023';
266
- const versionHistoryNumber = 1234;
267
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
268
- .mockImplementation(async (assortmentId) => {
269
- return {id: assortmentId, name: assortmentName};
270
- });
271
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
272
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
273
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
274
- return versionHistoryNumber;
275
- });
276
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, plan_history, publisher);
277
- expect(publishInfo.assortmentName).toEqual(assortmentName);
278
- expect(publishInfo.versionName).toBeUndefined();
279
- expect(publishInfo.versionComments).toBeUndefined();
280
- expect(publishInfo.publishDate).toBeUndefined();
281
- expect(publishInfo.publisher).toEqual(publisher);
282
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
283
- spyGetAssortment.mockRestore();
284
- spyyGetSnapshotVersion.mockRestore();
285
- });
286
-
287
- it('No APC history', async () =>{
288
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
289
-
290
- const assortmentPublishChangeId = 'bad-id';
291
- const publisher = {
292
- email: 'chris@vibeiq.com'
293
- };
294
- const assortmentName = 'VibeIQ Fall 2023';
295
- const versionHistoryNumber = 1234;
296
- const spyGetAssortment = jest.spyOn(ppa, 'getAssortment')
297
- .mockImplementation(async (assortmentId) => {
298
- return {id: assortmentId, name: assortmentName};
299
- });
300
- const spyyGetSnapshotVersion = jest.spyOn(ppa, 'getSnapshotVersion')
301
- // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
302
- .mockImplementation(async (assortmentId, assortmentPublishChangeId) => {
303
- return versionHistoryNumber;
304
- });
305
- const publishInfo = await ppa.getPublishInfo(assortmentId, assortmentPublishChangeId, undefined, publisher);
306
- expect(publishInfo.assortmentName).toEqual(assortmentName);
307
- expect(publishInfo.versionName).toBeUndefined();
308
- expect(publishInfo.versionComments).toBeUndefined();
309
- expect(publishInfo.publishDate).toBeUndefined();
310
- expect(publishInfo.publisher).toEqual(publisher);
311
- expect(publishInfo.versionHistoryNumber).toEqual(versionHistoryNumber);
312
- spyGetAssortment.mockRestore();
313
- spyyGetSnapshotVersion.mockRestore();
314
- });
315
-
316
- });
317
-
318
- describe('getSnapshotVersion', () =>{
319
- const config = {
320
- identifierAtts: {
321
- LCSSeason: ['flexPLMSeasonName']
322
- }
323
- } as unknown as FCConfig;
324
- const mapFileUtil = new MapFileUtil(new Entities());
325
- const dc = new DataConverter(config, mapFileUtil);
326
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
327
- beforeEach(() =>{
328
- federatedId = '';
329
- entityObject = { publishToFlexPLM:true};
330
- getOptionsObject = {};
331
- });
332
-
333
- it('has snapshot version', async () =>{
334
- const assortment = {
335
- id: 'rm35clTNxvS4wm6y',
336
- name: 'VibeIQ Fall 2023',
337
- createdForReference: 'plan:w23wre'
338
- };
339
- const assortmentChangeId = 'sJbGx1Fpq1v2MmcI';
340
- const apc = {
341
- id: assortmentChangeId,
342
- versionName: 'Version 1',
343
- versionComments: 'Some Comments',
344
- createdOn: '2023-01-15T19:13:58.902Z'
345
- };
346
-
347
- const versionNumber = 1234;
348
- const snapshots = [
349
- {
350
- id: 'qewrwer',
351
- assortmentChangeId,
352
- versionNumber
353
- }
354
- ];
355
-
356
- entityObject = snapshots;
357
-
358
- const versionHistoryNumber = await ppa.getSnapshotVersion(assortment, apc);
359
-
360
- expect(versionHistoryNumber).toEqual(versionNumber);
361
- expect(getOptionsObject['entityName']).toEqual('entity-snapshot');
362
- expect(getOptionsObject['criteria']['entityReference']).toEqual(assortment.createdForReference);
363
- expect(getOptionsObject['criteria']['createdOn'].indexOf('ISGREATERTHAN')).toEqual(0);
364
- });
365
-
366
- it('doesnt find snapshot version, last snapshot after apc', async () =>{
367
- const assortment = {
368
- id: 'rm35clTNxvS4wm6y',
369
- name: 'VibeIQ Fall 2023',
370
- createdForReference: 'plan:w23wre'
371
- };
372
- const assortmentChangeId = 'sJbGx1Fpq1v2MmcI';
373
- const apc = {
374
- id: assortmentChangeId,
375
- versionName: 'Version 1',
376
- versionComments: 'Some Comments',
377
- createdOn: '2023-01-15T19:13:58.902Z'
378
- };
379
-
380
- const versionNumber = 1234;
381
- const snapshots = [
382
- {
383
- id: 'qewrwer',
384
- assortmentChangeId: 'bad-id',
385
- createdOn: '2024-01-15T19:13:58.902Z',
386
- versionNumber
387
- }
388
- ];
389
-
390
- entityObject = snapshots;
391
-
392
- const versionHistoryNumber = await ppa.getSnapshotVersion(assortment, apc);
393
-
394
- expect(versionHistoryNumber).toEqual('unknown');
395
- expect(getOptionsObject['entityName']).toEqual('entity-snapshot');
396
- expect(getOptionsObject['criteria']['entityReference']).toEqual(assortment.createdForReference);
397
- expect(getOptionsObject['criteria']['createdOn'].indexOf('ISGREATERTHAN')).toEqual(0);
398
- });
399
-
400
- it('doesnt find snapshot version, last snapshot before apc', async () =>{
401
- const assortment = {
402
- id: 'rm35clTNxvS4wm6y',
403
- name: 'VibeIQ Fall 2023',
404
- createdForReference: 'plan:w23wre'
405
- };
406
- const assortmentChangeId = 'sJbGx1Fpq1v2MmcI';
407
- const apc = {
408
- id: assortmentChangeId,
409
- versionName: 'Version 1',
410
- versionComments: 'Some Comments',
411
- createdOn: '2023-01-15T19:13:58.902Z'
412
- };
413
-
414
- const versionNumber = 1234;
415
- const snapshots = [
416
- {
417
- id: 'qewrwer',
418
- assortmentChangeId: 'bad-id',
419
- createdOn: '2023-01-14T19:13:58.902Z',
420
- versionNumber
421
- }
422
- ];
423
-
424
- entityObject = snapshots;
425
-
426
- const versionHistoryNumber = await ppa.getSnapshotVersion(assortment, apc);
427
-
428
- expect(versionHistoryNumber).toEqual('after: '+ versionNumber);
429
- expect(getOptionsObject['entityName']).toEqual('entity-snapshot');
430
- expect(getOptionsObject['criteria']['entityReference']).toEqual(assortment.createdForReference);
431
- expect(getOptionsObject['criteria']['createdOn'].indexOf('ISGREATERTHAN')).toEqual(0);
432
- });
433
-
434
- it('doesnt find snapshot version, no snapshots returned', async () =>{
435
- const assortment = {
436
- id: 'rm35clTNxvS4wm6y',
437
- name: 'VibeIQ Fall 2023',
438
- createdForReference: 'plan:w23wre'
439
- };
440
- const assortmentChangeId = 'sJbGx1Fpq1v2MmcI';
441
- const apc = {
442
- id: assortmentChangeId,
443
- versionName: 'Version 1',
444
- versionComments: 'Some Comments',
445
- createdOn: '2023-01-15T19:13:58.902Z'
446
- };
447
-
448
- const snapshots = [];
449
-
450
- entityObject = snapshots;
451
-
452
- const versionHistoryNumber = await ppa.getSnapshotVersion(assortment, apc);
453
-
454
- expect(versionHistoryNumber).toEqual('unknown');
455
- expect(getOptionsObject['entityName']).toEqual('entity-snapshot');
456
- expect(getOptionsObject['criteria']['entityReference']).toEqual(assortment.createdForReference);
457
- expect(getOptionsObject['criteria']['createdOn'].indexOf('ISGREATERTHAN')).toEqual(0);
458
- });
459
-
460
- it('doesnt find snapshot version, last snapshot no createdOn', async () =>{
461
- const assortment = {
462
- id: 'rm35clTNxvS4wm6y',
463
- name: 'VibeIQ Fall 2023',
464
- createdForReference: 'plan:w23wre'
465
- };
466
- const assortmentChangeId = 'sJbGx1Fpq1v2MmcI';
467
- const apc = {
468
- id: assortmentChangeId,
469
- versionName: 'Version 1',
470
- versionComments: 'Some Comments',
471
- createdOn: '2023-01-15T19:13:58.902Z'
472
- };
473
-
474
- const versionNumber = 1234;
475
- const snapshots = [
476
- {
477
- id: 'qewrwer',
478
- assortmentChangeId: 'bad-id',
479
- // createdOn: '2023-01-14T19:13:58.902Z',
480
- versionNumber
481
- }
482
- ];
483
-
484
- entityObject = snapshots;
485
-
486
- const versionHistoryNumber = await ppa.getSnapshotVersion(assortment, apc);
487
-
488
- expect(versionHistoryNumber).toEqual('unknown');
489
- expect(getOptionsObject['entityName']).toEqual('entity-snapshot');
490
- expect(getOptionsObject['criteria']['entityReference']).toEqual(assortment.createdForReference);
491
- expect(getOptionsObject['criteria']['createdOn'].indexOf('ISGREATERTHAN')).toEqual(0);
492
- });
493
-
494
- });
495
-
496
- describe('getSeasonFederation', () =>{
497
- const config = {
498
- identifierAtts: {
499
- LCSSeason: ['flexPLMSeasonName']
500
- }
501
- } as unknown as FCConfig;
502
- beforeEach(() => {
503
- federatedId = '';
504
- entityObject = { publishToFlexPLM:true};
505
- getOptionsObject = {};
506
- });
507
- afterEach(() => {
508
- jest.restoreAllMocks();
509
- });
510
- it('No Federation Info', async () => {
511
- const assortmentId = 'B3oRQpYVYzcJAJtQ';
512
-
513
- try {
514
- const identifierKeys = ['flexPLMSeasonName'];
515
- const informationKeys = ['name'];
516
- const spyTCU_id_keys = jest.spyOn(TypeConversionUtils, 'getIdentifierProperties')
517
- .mockImplementation(async () => identifierKeys);
518
- const spyTCU_info_keys = jest.spyOn(TypeConversionUtils, 'getInformationalProperties')
519
- .mockImplementation(async () => informationKeys);
520
-
521
- const mapFileUtil = new MapFileUtil(new Entities());
522
- const dc = new DataConverter(config, mapFileUtil);
523
- await new BaseProcessPublishAssortment(config, dc, mapFileUtil).getSeasonFederation(assortmentId);
524
- } catch (e) {
525
- expect(e.message).toEqual(BaseProcessPublishAssortment.ASSORTMENT_NO_FED_INFO + config.identifierAtts.LCSSeason);
526
- }
527
-
528
- });
529
-
530
- });
531
-
532
- describe('Test getSinceDate', () =>{
533
- it('getSinceDate from getSinceDateFromAPCs', async () =>{
534
- const history = new Array(...plan1_history);
535
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
536
- const matchDate = new Date('2023-01-17T22:40:07.288Z');
537
-
538
- const config = {} as FCConfig;
539
-
540
- const mapFileUtil = new MapFileUtil(new Entities());
541
- const dc = new DataConverter(config, mapFileUtil);
542
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
543
- ppa.getApcHistory = async () =>{
544
- return history;
545
- };
546
-
547
- const sinceDate = await ppa.getSinceDate('oqIFX3ELRy8sFRd0', lastAPCId, history);
548
- expect(sinceDate).toEqual(matchDate);
549
- });
550
- it('getSinceDate date from config as year', async () =>{
551
- const history = new Array(...plan1_history);
552
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
553
- const matchDate = new Date('2023-01-16T21:50:42.742Z');
554
-
555
- const config = {sinceDate: '2023-01-17' } as any as FCConfig;
556
-
557
- const mapFileUtil = new MapFileUtil(new Entities());
558
- const dc = new DataConverter(config, mapFileUtil);
559
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
560
- ppa.getApcHistory = async () =>{
561
- return history;
562
- };
563
-
564
- const sinceDate = await ppa.getSinceDate('oqIFX3ELRy8sFRd0', lastAPCId, history);
565
- expect(sinceDate).toEqual(matchDate);
566
- });
567
-
568
- it('getSinceDate date from config numberofdays-cross month', async () =>{
569
- const count = 10;
570
- const history = new Array(...plan1_across_month_DST);
571
- const lastAPCId = '_mj--7nlyp7mmDrK';
572
- const matchDate = new Date('2023-02-25T19:13:58.902Z');
573
- const config = {sinceDate: 'numberofdays:'+ count } as any as FCConfig;
574
- const mapFileUtil = new MapFileUtil(new Entities());
575
- const dc = new DataConverter(config, mapFileUtil);
576
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
577
- const sinceDate = await ppa.getSinceDate('oqIFX3ELRy8sFRd0', lastAPCId, history);
578
- expect(sinceDate).toEqual(matchDate);
579
- });
580
- it('getSinceDate date from config numberofdays-cross DST', async () =>{
581
- const count = 11;
582
- const history = new Array(...plan1_across_month_DST);
583
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
584
- const matchDate = new Date('2023-03-06T21:50:42.742Z');
585
- const config = {sinceDate: 'numberofdays:'+ count } as any as FCConfig;
586
- const mapFileUtil = new MapFileUtil(new Entities());
587
- const dc = new DataConverter(config, mapFileUtil);
588
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
589
- const sinceDate = await ppa.getSinceDate('oqIFX3ELRy8sFRd0', lastAPCId, history);
590
- expect(sinceDate).toEqual(matchDate);
591
- });
592
- it('getSinceDate date from config numberofpublishes', async () =>{
593
- const count = 3;
594
- const history = new Array(...plan1_history);
595
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
596
- const matchDate = new Date('2023-01-17T22:35:20.517Z');
597
- const config = {sinceDate: 'numberofpublishes:'+ count } as any as FCConfig;
598
- const mapFileUtil = new MapFileUtil(new Entities());
599
- const dc = new DataConverter(config, mapFileUtil);
600
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
601
- const sinceDate = await ppa.getSinceDate('oqIFX3ELRy8sFRd0', lastAPCId, history);
602
- expect(sinceDate).toEqual(matchDate);
603
- });
604
-
605
- it('getSinceDate date from config numberofpublishes', async () =>{
606
- const count = 3;
607
- const history = new Array(...plan1_history);
608
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
609
- const matchDate = new Date('2023-01-17T22:35:20.517Z');
610
- const config = {sinceDate: 'numberofpublishes:'+ count } as any as FCConfig;
611
- const mapFileUtil = new MapFileUtil(new Entities());
612
- const dc = new DataConverter(config, mapFileUtil);
613
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
614
- ppa.getApcHistory = async () =>{
615
- return history;
616
- };
617
- const sinceDate = await ppa.getSinceDate('oqIFX3ELRy8sFRd0', lastAPCId, history);
618
- expect(sinceDate).toEqual(matchDate);
619
- });
620
- });
621
-
622
- describe('getSinceDateFromAPCSpecificDate', () =>{
623
- it('last apc - one day', () =>{
624
- const history = new Array(...plan1_history);
625
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
626
- const matchDate = new Date('2023-01-16T21:50:42.742Z');
627
-
628
- const config = {} as FCConfig;
629
- const mapFileUtil = new MapFileUtil(new Entities());
630
- const dc = new DataConverter(config, mapFileUtil);
631
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
632
-
633
- const sinceDate = ppa.getSinceDateFromAPCSpecificDate(history, lastAPCId, new Date('2023-01-17T00:00:00.000Z'));
634
- expect(sinceDate).toEqual(matchDate);
635
- });
636
-
637
- it('apc in the middle - one day', () =>{
638
- const history = new Array(...plan1_history);
639
- const lastAPCId = 'GiT9CZXZGVljoYMR';
640
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
641
-
642
- const config = {} as FCConfig;
643
- const mapFileUtil = new MapFileUtil(new Entities());
644
- const dc = new DataConverter(config, mapFileUtil);
645
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
646
-
647
- const sinceDate = ppa.getSinceDateFromAPCSpecificDate(history, lastAPCId, new Date('2023-01-16T00:00:00.000Z'));
648
- expect(sinceDate).toEqual(matchDate);
649
- });
650
- it('before initial publish', () => {
651
- const history = new Array(...plan1_history);
652
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
653
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
654
- const config = {} as FCConfig;
655
- const mapFileUtil = new MapFileUtil(new Entities());
656
- const dc = new DataConverter(config, mapFileUtil);
657
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
658
- const sinceDate = ppa.getSinceDateFromAPCSpecificDate(history, lastAPCId, new Date('2021-01-17T00:00:00.000Z'));
659
- expect(sinceDate).toEqual(matchDate);
660
- });
661
- it('numberofdays at 2 ', () => {
662
- const history = new Array(...plan1_history);
663
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
664
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
665
- const config = {} as FCConfig;
666
- const mapFileUtil = new MapFileUtil(new Entities());
667
- const dc = new DataConverter(config, mapFileUtil);
668
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
669
- const sinceDate = ppa.getSinceDateFromAPCSpecificDate(history, lastAPCId, new Date('2023-01-16T00:00:00.000Z'));
670
- expect(sinceDate).toEqual(matchDate);
671
- });
672
-
673
- });
674
-
675
- describe('getSinceDateDaysPrevious', () =>{
676
- it('last apc - one day', () =>{
677
- const history = new Array(...plan1_history);
678
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
679
- const matchDate = new Date('2023-01-16T21:50:42.742Z');
680
-
681
- const config = {} as FCConfig;
682
- const mapFileUtil = new MapFileUtil(new Entities());
683
- const dc = new DataConverter(config, mapFileUtil);
684
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
685
-
686
- const sinceDate = ppa.getSinceDateDaysPrevious(history, lastAPCId, 1);
687
- expect(sinceDate).toEqual(matchDate);
688
- });
689
-
690
- it('apc in the middle - one day', () =>{
691
- const history = new Array(...plan1_history);
692
- const lastAPCId = 'GiT9CZXZGVljoYMR';
693
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
694
-
695
- const config = {} as FCConfig;
696
- const mapFileUtil = new MapFileUtil(new Entities());
697
- const dc = new DataConverter(config, mapFileUtil);
698
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
699
-
700
- const sinceDate = ppa.getSinceDateDaysPrevious(history, lastAPCId, 1);
701
- expect(sinceDate).toEqual(matchDate);
702
- });
703
- it('numberofdays greater than array size', () => {
704
- const history = new Array(...plan1_history);
705
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
706
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
707
- const config = {} as FCConfig;
708
- const mapFileUtil = new MapFileUtil(new Entities());
709
- const dc = new DataConverter(config, mapFileUtil);
710
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
711
- const sinceDate = ppa.getSinceDateDaysPrevious(history, lastAPCId, 5);
712
- expect(sinceDate).toEqual(matchDate);
713
- });
714
- it('numberofdays at 2 ', () => {
715
- const history = new Array(...plan1_history);
716
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
717
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
718
- const config = {} as FCConfig;
719
- const mapFileUtil = new MapFileUtil(new Entities());
720
- const dc = new DataConverter(config, mapFileUtil);
721
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
722
- const sinceDate = ppa.getSinceDateDaysPrevious(history, lastAPCId, 2);
723
- expect(sinceDate).toEqual(matchDate);
724
- });
725
-
726
- });
727
-
728
- describe('getSinceDateFromAPCs', () => {
729
- it('first / only apc', () => {
730
- const history = new Array(...plan1_history).slice(0, 1);
731
- const lastAPCId = 'v9BKkHo-tpL0wUZN';
732
- const matchDate = new Date(0);
733
-
734
- const config = {} as FCConfig;
735
-
736
- const mapFileUtil = new MapFileUtil(new Entities());
737
- const dc = new DataConverter(config, mapFileUtil);
738
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
739
-
740
- const sinceDate = ppa.getSinceDateFromAPCs(history, lastAPCId);
741
- expect(sinceDate).toEqual(matchDate);
742
- });
743
-
744
- it('first / multiple apcs in history', () => {
745
- const history = new Array(...plan1_history).slice(0, 3);
746
- const lastAPCId = 'v9BKkHo-tpL0wUZN';
747
- const matchDate = new Date(0);
748
-
749
- const config = {} as FCConfig;
750
-
751
- const mapFileUtil = new MapFileUtil(new Entities());
752
- const dc = new DataConverter(config, mapFileUtil);
753
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
754
-
755
- const sinceDate = ppa.getSinceDateFromAPCs(history, lastAPCId);
756
- expect(sinceDate).toEqual(matchDate);
757
- });
758
-
759
- it('last apc', () => {
760
- const history = new Array(...plan1_history);
761
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
762
- const matchDate = new Date('2023-01-17T22:40:07.288Z');
763
-
764
- const config = {} as FCConfig;
765
-
766
- const mapFileUtil = new MapFileUtil(new Entities());
767
- const dc = new DataConverter(config, mapFileUtil);
768
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
769
-
770
- const sinceDate = ppa.getSinceDateFromAPCs(history, lastAPCId);
771
- expect(sinceDate).toEqual(matchDate);
772
- });
773
-
774
- it('apc in the middle', () => {
775
- const history = new Array(...plan1_history);
776
- const lastAPCId = 'GiT9CZXZGVljoYMR';
777
- const matchDate = new Date('2023-01-16T21:50:42.742Z');
778
-
779
- const config = {} as FCConfig;
780
-
781
- const mapFileUtil = new MapFileUtil(new Entities());
782
- const dc = new DataConverter(config, mapFileUtil);
783
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
784
-
785
- const sinceDate = ppa.getSinceDateFromAPCs(history, lastAPCId);
786
- expect(sinceDate).toEqual(matchDate);
787
- });
788
-
789
- it('pastPublishCount greater than array size', () => {
790
- const history = new Array(...plan1_history);
791
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
792
- const matchDate = new Date('2023-01-15T19:13:58.902Z');
793
-
794
- const config = {} as FCConfig;
795
-
796
- const mapFileUtil = new MapFileUtil(new Entities());
797
- const dc = new DataConverter(config, mapFileUtil);
798
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
799
-
800
- const sinceDate = ppa.getSinceDateFromAPCs(history, lastAPCId, 20);
801
- expect(sinceDate).toEqual(matchDate);
802
- });
803
-
804
- it('pastPublishCount at 3 ', () => {
805
- const history = new Array(...plan1_history);
806
- const lastAPCId = 'sJbGx1Fpq1v2MmcI';
807
- const matchDate = new Date('2023-01-17T22:35:20.517Z');
808
-
809
- const config = {} as FCConfig;
810
-
811
- const mapFileUtil = new MapFileUtil(new Entities());
812
- const dc = new DataConverter(config, mapFileUtil);
813
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
814
-
815
- const sinceDate = ppa.getSinceDateFromAPCs(history, lastAPCId, 3);
816
- expect(sinceDate).toEqual(matchDate);
817
- });
818
- });
819
-
820
- describe('getDeleteChanges', () =>{
821
- const config = {} as FCConfig;
822
- const mapFileUtil = new MapFileUtil(new Entities());
823
- const dc = new DataConverter(config, mapFileUtil);
824
-
825
- it('no deletes - 1 apc', async () =>{
826
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
827
- const lastAPCId ='SYHfQzYWlfXDqK7r';
828
- const apcIndex = history.findIndex( pc => pc.id === lastAPCId);
829
- const apc = history[apcIndex];
830
- const previousApc = (apcIndex > 0)
831
- ? history[apcIndex -1]
832
- : undefined;
833
- const apcDate = (previousApc)? new Date(previousApc['createdOn']): new Date(0);
834
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
835
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
836
- .mockImplementation(async (assortmentPublishChange) => {
837
- let deleteChanges = [];
838
- if(assortmentPublishChange){
839
- const apcId = assortmentPublishChange['id'];
840
- const apc = history.find(apc => apc['id'] === apcId);
841
- deleteChanges = apc['deleteData'];
842
- }
843
- return deleteChanges;
844
- });
845
- const deleteChanges = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
846
- expect(deleteChanges).toEqual([]);
847
- spy.mockRestore();
848
- });
849
-
850
- it('1 delete - 1 apc', async () =>{
851
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
852
- const lastAPCId ='JreGRNvoJ3FsoRZI';
853
- const apcIndex = history.findIndex( pc => pc.id === lastAPCId);
854
- const apc = history[apcIndex];
855
- const previousApc = (apcIndex > 0)
856
- ? history[apcIndex -1]
857
- : undefined;
858
- const apcDate = (previousApc)? new Date(previousApc['createdOn']): new Date(0);
859
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
860
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
861
- .mockImplementation(async (assortmentPublishChange) => {
862
- let deleteChanges = [];
863
- if(assortmentPublishChange){
864
- const apcId = assortmentPublishChange['id'];
865
- const apc = history.find(apc => apc['id'] === apcId);
866
- deleteChanges = apc['deleteData'];
867
- }
868
- return deleteChanges;
869
- });
870
- const deleteChanges = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
871
- expect(deleteChanges).toHaveLength(1);
872
- spy.mockRestore();
873
- });
874
-
875
- it('no deletes - testing #3 apc', async () =>{
876
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
877
- const lastAPCId ='NaPUhAdEzKB-5tQ3';
878
- const apcIndex = history.findIndex( pc => pc.id === lastAPCId);
879
- const apc = history[apcIndex];
880
- const previousApc = (apcIndex > 0)
881
- ? history[apcIndex -1]
882
- : undefined;
883
- const apcDate = (previousApc)? new Date(previousApc['createdOn']): new Date(0);
884
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
885
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
886
- .mockImplementation(async (assortmentPublishChange) => {
887
- let deleteChanges = [];
888
- if(assortmentPublishChange){
889
- const apcId = assortmentPublishChange['id'];
890
- const apc = history.find(apc => apc['id'] === apcId);
891
- deleteChanges = apc['deleteData'];
892
- }
893
- return deleteChanges;
894
- });
895
- const deleteChanges = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
896
- expect(deleteChanges).toEqual([]);
897
- spy.mockRestore();
898
- });
899
-
900
- it('1 delete - 1 apc', async () =>{
901
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
902
- const lastAPCId ='CHGKSCT358qyh1Nu';
903
- const apcIndex = history.findIndex( pc => pc.id === lastAPCId);
904
- const apc = history[apcIndex];
905
- const previousApc = (apcIndex > 0)
906
- ? history[apcIndex -1]
907
- : undefined;
908
- const apcDate = (previousApc)? new Date(previousApc['createdOn']): new Date(0);
909
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
910
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
911
- .mockImplementation(async (assortmentPublishChange) => {
912
- let deleteChanges = [];
913
- if(assortmentPublishChange){
914
- const apcId = assortmentPublishChange['id'];
915
- const apc = history.find(apc => apc['id'] === apcId);
916
- deleteChanges = apc['deleteData'];
917
- }
918
- return deleteChanges;
919
- });
920
- const deleteChanges = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
921
- expect(deleteChanges).toHaveLength(1);
922
- spy.mockRestore();
923
- });
924
-
925
- it('1 delete - 2 apc (most recent delete apc, no change earlier apc)', async () =>{
926
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
927
- const lastAPCId ='CHGKSCT358qyh1Nu';
928
- const apc = history.find( pc => pc.id === lastAPCId);
929
- const baseApcId = 'JreGRNvoJ3FsoRZI';
930
- const baseApc = history.find(pc => pc.id === baseApcId);
931
- const apcDate = new Date(baseApc['createdOn']);
932
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
933
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
934
- .mockImplementation(async (assortmentPublishChange) => {
935
- let deleteChanges = [];
936
- if(assortmentPublishChange){
937
- const apcId = assortmentPublishChange['id'];
938
- const apc = history.find(apc => apc['id'] === apcId);
939
- deleteChanges = apc['deleteData'];
940
- }
941
- return deleteChanges;
942
- });
943
- const deleteChanges :object[]= await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
944
- expect(deleteChanges).toHaveLength(1);
945
- const item = deleteChanges[0];
946
- expect(item).not.toBeNull();
947
- expect(item['itemId']).toEqual('qNCQmTFcFxwbT-oG');
948
- spy.mockRestore();
949
- });
950
-
951
- it('1 delete - 2 apc (most recent no change, 1 delete earlier apc)', async () =>{
952
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
953
- const lastAPCId ='NaPUhAdEzKB-5tQ3';
954
- const apc = history.find( pc => pc.id === lastAPCId);
955
- const baseApcId = 'SYHfQzYWlfXDqK7r';
956
- const baseApc = history.find(pc => pc.id === baseApcId);
957
- const apcDate = new Date(baseApc['createdOn']);
958
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
959
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
960
- .mockImplementation(async (assortmentPublishChange) => {
961
- let deleteChanges = [];
962
- if(assortmentPublishChange){
963
- const apcId = assortmentPublishChange['id'];
964
- const apc = history.find(apc => apc['id'] === apcId);
965
- deleteChanges = apc['deleteData'];
966
- }
967
- return deleteChanges;
968
- });
969
- const deleteChanges :object[] = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
970
- expect(deleteChanges).toHaveLength(1);
971
- const item = deleteChanges[0];
972
- expect(item).not.toBeNull();
973
- expect(item['itemId']).toEqual('SfUAZy_Hj631h2Kg');
974
- spy.mockRestore();
975
- });
976
-
977
- it('2 delete - 3 apc (most recent delete apc, no change middle apc, 1 delete)', async () =>{
978
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
979
- const lastAPCId ='CHGKSCT358qyh1Nu';
980
- const apc = history.find( pc => pc.id === lastAPCId);
981
- const baseApcId = 'SYHfQzYWlfXDqK7r';
982
- const baseApc = history.find(pc => pc.id === baseApcId);
983
- const apcDate = new Date(baseApc['createdOn']);
984
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
985
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
986
- .mockImplementation(async (assortmentPublishChange) => {
987
- let deleteChanges = [];
988
- if(assortmentPublishChange){
989
- const apcId = assortmentPublishChange['id'];
990
- const apc = history.find(apc => apc['id'] === apcId);
991
- deleteChanges = apc['deleteData'];
992
- }
993
- return deleteChanges;
994
- });
995
- const deleteChanges :object[] = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
996
-
997
- expect(deleteChanges).toHaveLength(2);
998
- const itemIds = deleteChanges.map(dItem => dItem['itemId']);
999
- expect(itemIds).toContain('SfUAZy_Hj631h2Kg');
1000
- expect(itemIds).toContain('qNCQmTFcFxwbT-oG');
1001
- spy.mockRestore();
1002
- });
1003
-
1004
- it('1 delete - 4 apc (most recent re-add, 1 delete, no change middle apc, 1 delete)', async () =>{
1005
- console.log('1 delete - 4 apc (most recent re-add, 1 delete, no change middle apc, 1 delete)');
1006
- const history = new Array(...apc_2bOWR2j9R0QThDVu_delete_history);
1007
- const lastAPCId ='H4L4dHziO6WZRIwa';
1008
- const apc = history.find( pc => pc.id === lastAPCId);
1009
- const baseApcId = 'SYHfQzYWlfXDqK7r';
1010
- const baseApc = history.find(pc => pc.id === baseApcId);
1011
- const apcDate = new Date(baseApc['createdOn']);
1012
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1013
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
1014
- .mockImplementation(async (assortmentPublishChange) => {
1015
- let deleteChanges = [];
1016
- if(assortmentPublishChange){
1017
- const apcId = assortmentPublishChange['id'];
1018
- const apc = history.find(apc => apc['id'] === apcId);
1019
- deleteChanges = apc['deleteData'];
1020
- }
1021
- return deleteChanges;
1022
- });
1023
- const deleteChanges :object[] = await ppa.getDeleteChanges(apc, history, apc['assortmentBaseline'], apcDate);
1024
-
1025
- expect(deleteChanges).toHaveLength(1);
1026
- const itemIds = deleteChanges.map(dItem => dItem['itemId']);
1027
- expect(itemIds).toContain('qNCQmTFcFxwbT-oG');
1028
- spy.mockRestore();
1029
- });
1030
-
1031
- });
1032
-
1033
- describe('buildDeleteChanges', () =>{
1034
- const config = {} as FCConfig;
1035
- const mapFileUtil = new MapFileUtil(new Entities());
1036
- const dc = new DataConverter(config, mapFileUtil);
1037
-
1038
- beforeEach( ()=>{
1039
- jest.clearAllMocks();
1040
- });
1041
-
1042
- it('apc has valid deleteDataDownloadLink', async () =>{
1043
- const returnedDeleteData = [
1044
- {}
1045
- ];
1046
- const apc = {
1047
- deleteDataDownloadLink: 'deleteDataDownloadLink',
1048
- returnedDeleteData
1049
- };
1050
- const previousApc = {
1051
-
1052
- };
1053
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1054
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
1055
- .mockImplementation(async (assortmentPublishChange) => {
1056
- return assortmentPublishChange['returnedDeleteData'];
1057
- });
1058
- const deleteChanges = await ppa.buildDeleteChanges(apc, previousApc);
1059
- expect (deleteChanges).toHaveLength(returnedDeleteData.length);
1060
- expect(spy).toBeCalledWith(apc);
1061
- spy.mockRestore();
1062
- });
1063
-
1064
- it('apc no deleteDataDownloadLink, but fullAPC has valid link', async () =>{
1065
- const returnedDeleteData = [
1066
- {}
1067
- ];
1068
- const apc ={};
1069
- const fullAPC = {
1070
- deleteDataDownloadLink: 'deleteDataDownloadLink',
1071
- returnedDeleteData
1072
- };
1073
- const previousApc = {};
1074
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1075
- const spy = jest.spyOn(ppa, 'downloadDeleteChanges')
1076
- .mockImplementation(async (assortmentPublishChange) => {
1077
- return assortmentPublishChange['returnedDeleteData'];
1078
- });
1079
-
1080
- const spy2 = jest.spyOn(ppa, 'downloadAssortmentPublishChange')
1081
- .mockImplementation(async () => {
1082
- return fullAPC;
1083
- });
1084
-
1085
- const deleteChanges = await ppa.buildDeleteChanges(apc, previousApc);
1086
- expect (deleteChanges).toHaveLength(returnedDeleteData.length);
1087
- expect(spy).toBeCalledWith(fullAPC);
1088
-
1089
- spy.mockRestore();
1090
- spy2.mockRestore();
1091
- });
1092
-
1093
- it('apc & fullAPC no deleteDataDownloadLink, error no previousApc', async () =>{
1094
- const returnedDeleteData = [
1095
- {}
1096
- ];
1097
- const apc ={};
1098
- const fullAPC = {
1099
- returnedDeleteData
1100
- };
1101
- const previousApc = undefined;
1102
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1103
-
1104
- const spy2 = jest.spyOn(ppa, 'downloadAssortmentPublishChange')
1105
- .mockImplementation(async () => {
1106
- return fullAPC;
1107
- });
1108
-
1109
- expect( async () =>{await ppa.buildDeleteChanges(apc, previousApc);}).rejects.toThrow(new Error(BaseProcessPublishAssortment.NOT_ABLE_TO_PROCESS_DELETE_CHANGES));
1110
-
1111
- spy2.mockRestore();
1112
- });
1113
-
1114
- it('apc & fullAPC no deleteDataDownloadLink, use previousApc.assortmentBaselineDownloadLink', async () =>{
1115
- const assortmentId = '123';
1116
- const apcId = '456';
1117
- const previousApcId = '987';
1118
- const apc ={
1119
- assortmentId,
1120
- id: apcId,
1121
- detail: {
1122
- deletes: [{id:'1'}, {id:'3'}]
1123
- }
1124
- };
1125
- const fullAPC = {
1126
- assortmentId,
1127
- id: apcId,
1128
- detail: {
1129
- deletes: [{id:'1'}, {id:'3'}]
1130
- }
1131
-
1132
- };
1133
- const previousApc = {
1134
- };
1135
- const fullPreviousApc = {
1136
- id: previousApcId,
1137
- assortmentBaselineDownloadLink: 'assortmentBaselineDownloadLink'
1138
- };
1139
- const previousApcBaseline = {
1140
- assortmentItems: [
1141
- { itemId: '1' },
1142
- { itemId: '2' },
1143
- { itemId: '3' }
1144
- ]
1145
- };
1146
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1147
- const spyDownloadDeleteChanges = jest.spyOn(ppa, 'downloadDeleteChanges')
1148
- .mockImplementation(async (assortmentPublishChange) => {
1149
- return assortmentPublishChange['returnedDeleteData'];
1150
- });
1151
-
1152
- const spyDownloadAssortmentPublishChange = jest.spyOn(ppa, 'downloadAssortmentPublishChange')
1153
- .mockImplementation(async (assortmentId, id) => {
1154
- if(id === apcId){
1155
- return fullAPC;
1156
- }else{
1157
- return fullPreviousApc;
1158
- }
1159
- });
1160
-
1161
- const spyDownloadAssortmentBaseline = jest.spyOn(ppa, 'downloadAssortmentBaseline')
1162
- .mockImplementation(async () =>{
1163
- return previousApcBaseline;
1164
- });
1165
-
1166
- const deleteChanges = await ppa.buildDeleteChanges(apc, previousApc);
1167
- expect (deleteChanges).toHaveLength(apc.detail.deletes.length);
1168
- expect(spyDownloadAssortmentBaseline).toBeCalledWith(fullPreviousApc);
1169
-
1170
- spyDownloadDeleteChanges.mockRestore();
1171
- spyDownloadAssortmentPublishChange.mockRestore();
1172
- spyDownloadAssortmentBaseline.mockRestore();
1173
- });
1174
-
1175
- it('apc & fullAPC no deleteDataDownloadLink, use fullPreviousApc.assortmentBaselineDownloadLink', async () =>{
1176
- const assortmentId = '123';
1177
- const apcId = '456';
1178
- const apc ={
1179
- assortmentId,
1180
- id: apcId,
1181
- detail: {
1182
- deletes: [{id:'1'}, {id:'3'}]
1183
- }
1184
- };
1185
- const fullAPC = {
1186
- assortmentId,
1187
- id: apcId,
1188
- detail: {
1189
- deletes: [{id:'1'}, {id:'3'}]
1190
- }
1191
-
1192
- };
1193
- const previousApc = {
1194
- assortmentBaselineDownloadLink: 'assortmentBaselineDownloadLink'
1195
- };
1196
- const previousApcBaseline = {
1197
- assortmentItems: [
1198
- { itemId: '1' },
1199
- { itemId: '2' },
1200
- { itemId: '3' }
1201
- ]
1202
- };
1203
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1204
- const spyDownloadDeleteChanges = jest.spyOn(ppa, 'downloadDeleteChanges')
1205
- .mockImplementation(async (assortmentPublishChange) => {
1206
- return assortmentPublishChange['returnedDeleteData'];
1207
- });
1208
-
1209
- const spyDownloadAssortmentPublishChange = jest.spyOn(ppa, 'downloadAssortmentPublishChange')
1210
- .mockImplementation(async () => {
1211
- return fullAPC;
1212
- });
1213
-
1214
- const spyDownloadAssortmentBaseline = jest.spyOn(ppa, 'downloadAssortmentBaseline')
1215
- .mockImplementation(async () =>{
1216
- return previousApcBaseline;
1217
- });
1218
-
1219
- const deleteChanges = await ppa.buildDeleteChanges(apc, previousApc);
1220
- expect (deleteChanges).toHaveLength(apc.detail.deletes.length);
1221
- expect(spyDownloadAssortmentBaseline).toBeCalledWith(previousApc);
1222
-
1223
- spyDownloadDeleteChanges.mockRestore();
1224
- spyDownloadAssortmentPublishChange.mockRestore();
1225
- spyDownloadAssortmentBaseline.mockRestore();
1226
- });
1227
-
1228
- });
1229
-
1230
- describe('getItemFamilyChanges', () => {
1231
- const filterFullChange = (fullChange, itemFamilyIds: string[]) => {
1232
- const fChange = Object.assign({}, fullChange);
1233
- fChange['assortmentItems'] = fChange['assortmentItems']
1234
- .filter(assortItem => itemFamilyIds.includes(assortItem['item']['itemFamilyId']));
1235
-
1236
- return fChange;
1237
- };
1238
- const filterDeleteChange = (deleteChange, itemFamilyIds: string[]) =>{
1239
- let dChange = Array.from(deleteChange);
1240
- dChange = dChange.filter( assortItem => itemFamilyIds.includes(assortItem['item']['itemFamilyId']));
1241
- return dChange;
1242
- };
1243
- const filterHydratedDetails = (hydratedDetails, itemFamilyIds: string[]) => {
1244
- const hDetails = Object.assign({}, hydratedDetails);
1245
- hDetails['adds'] = hDetails['adds']
1246
- .filter(assortItem => itemFamilyIds.includes(assortItem['item']['itemFamilyId']));
1247
- hDetails['deletes'] = hDetails['deletes']
1248
- .filter(assortItem => itemFamilyIds.includes(assortItem['item']['itemFamilyId']));
1249
- hDetails['familyItemsRemoved'] = hDetails['familyItemsRemoved']
1250
- .filter(assortItem => itemFamilyIds.includes(assortItem['item']['itemFamilyId']));
1251
-
1252
- return hDetails;
1253
- };
1254
- it('Feb 3 - No Option A', () => {
1255
- const itemFamilyId = 'kh1Rtb7kie7Vk5vo';
1256
- const fullChange = filterFullChange(fall_2003_fullChange, [itemFamilyId]);
1257
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails, [itemFamilyId]);
1258
- const seasonFed: SeasonFederation = {
1259
- entityReference: 'assortment:' + fullChange['id'],
1260
- objectClass: 'LCSSeason',
1261
- federationId: 'VR:...LCSSeason:1'
1262
- };
1263
-
1264
- const itemToFederatedIdMapping = new Map<string, string>();
1265
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1266
-
1267
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1268
- const config = {} as FCConfig;
1269
-
1270
- const mapFileUtil = new MapFileUtil(new Entities());
1271
- const dc = new DataConverter(config, mapFileUtil);
1272
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1273
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1274
- const assortmentItemDeleteMap = new Map<string, object>();
1275
-
1276
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'i-OONhGKbJAfRKo-', sinceDate);
1277
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1278
- pcd.releasedForDevelopmentItemIds.push(itemFamilyId);
1279
-
1280
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1281
-
1282
- const ifcs = pcd.itemFamilyChanges;
1283
- expect(ifcs.size).toEqual(1);
1284
- const ifc = ifcs.get(itemFamilyId);
1285
- expect(ifc.familyAdd).toBe(true);
1286
- expect(ifc.colorAdds.length).toEqual(0);
1287
- });
1288
-
1289
- it('Feb 3 - 1 Option A', () => {
1290
- const itemFamilyId = 'U9QryfGVOYMAkBP_';
1291
- const fullChange = filterFullChange(fall_2003_fullChange, [itemFamilyId]);
1292
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails, [itemFamilyId]);
1293
- const seasonFed: SeasonFederation = {
1294
- entityReference: 'assortment:' + fullChange['id'],
1295
- objectClass: 'LCSSeason',
1296
- federationId: 'VR:...LCSSeason:1'
1297
- };
1298
-
1299
- const itemToFederatedIdMapping = new Map<string, string>();
1300
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1301
-
1302
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1303
- const config = {} as FCConfig;
1304
-
1305
- const mapFileUtil = new MapFileUtil(new Entities());
1306
- const dc = new DataConverter(config, mapFileUtil);
1307
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1308
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1309
- const assortmentItemDeleteMap = new Map<string, object>();
1310
-
1311
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'i-OONhGKbJAfRKo-', sinceDate);
1312
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1313
- pcd.releasedForDevelopmentItemIds.push('jFAp5SmYqhXoX-ZI');
1314
- pcd.releasedForDevelopmentItemIds.push('U9QryfGVOYMAkBP_');
1315
-
1316
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1317
-
1318
- const ifcs = pcd.itemFamilyChanges;
1319
- expect(ifcs.size).toEqual(1);
1320
- const ifc = ifcs.get(itemFamilyId);
1321
- // expect(ifc.familyAdd).toBe(true);
1322
- expect(ifc.colorAdds.length).toEqual(1);
1323
- });
1324
-
1325
- it('Feb 3 - 2+ Option A', () => {
1326
- const itemFamilyId = 'tvCyTuL6hF3MwbjJ';
1327
- const fullChange = filterFullChange(fall_2003_fullChange, [itemFamilyId]);
1328
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails, [itemFamilyId]);
1329
- const seasonFed: SeasonFederation = {
1330
- entityReference: 'assortment:' + fullChange['id'],
1331
- objectClass: 'LCSSeason',
1332
- federationId: 'VR:...LCSSeason:1'
1333
- };
1334
-
1335
- const itemToFederatedIdMapping = new Map<string, string>();
1336
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1337
-
1338
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1339
-
1340
- const config = {} as FCConfig;
1341
-
1342
- const mapFileUtil = new MapFileUtil(new Entities());
1343
- const dc = new DataConverter(config, mapFileUtil);
1344
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1345
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1346
- const assortmentItemDeleteMap = new Map<string, object>();
1347
-
1348
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'i-OONhGKbJAfRKo-', sinceDate);
1349
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1350
- pcd.releasedForDevelopmentItemIds.push('jezonPsoRUlA52iz');
1351
- pcd.releasedForDevelopmentItemIds.push('VGo0fWmBBEZoghgk');
1352
- pcd.releasedForDevelopmentItemIds.push('tvCyTuL6hF3MwbjJ');
1353
-
1354
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1355
-
1356
- const ifcs = pcd.itemFamilyChanges;
1357
- expect(ifcs.size).toEqual(1);
1358
- const ifc = ifcs.get(itemFamilyId);
1359
- // expect(ifc.familyAdd).toBe(true);
1360
- expect(ifc.colorAdds.length).toEqual(2);
1361
- });
1362
-
1363
- it('Feb 3 - 2+ Option A & Feb 3 - 1 Option A', () => {
1364
- const oneOption_itemFamilyId = 'U9QryfGVOYMAkBP_';
1365
- const twoOption_itemFamilyId = 'tvCyTuL6hF3MwbjJ';
1366
- const bothFamilyIds = [oneOption_itemFamilyId, twoOption_itemFamilyId];
1367
- const fullChange = filterFullChange(fall_2003_fullChange, bothFamilyIds);
1368
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails, bothFamilyIds);
1369
- const seasonFed: SeasonFederation = {
1370
- entityReference: 'assortment:' + fullChange['id'],
1371
- objectClass: 'LCSSeason',
1372
- federationId: 'VR:...LCSSeason:1'
1373
- };
1374
-
1375
- const itemToFederatedIdMapping = new Map<string, string>();
1376
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1377
-
1378
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1379
-
1380
- const config = {} as FCConfig;
1381
-
1382
- const mapFileUtil = new MapFileUtil(new Entities());
1383
- const dc = new DataConverter(config, mapFileUtil);
1384
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1385
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1386
- const assortmentItemDeleteMap = new Map<string, object>();
1387
-
1388
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'i-OONhGKbJAfRKo-', sinceDate);
1389
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1390
- pcd.releasedForDevelopmentItemIds.push('jFAp5SmYqhXoX-ZI');
1391
- pcd.releasedForDevelopmentItemIds.push('jezonPsoRUlA52iz');
1392
- pcd.releasedForDevelopmentItemIds.push('VGo0fWmBBEZoghgk');
1393
- pcd.releasedForDevelopmentItemIds.push('U9QryfGVOYMAkBP_');
1394
- pcd.releasedForDevelopmentItemIds.push('tvCyTuL6hF3MwbjJ');
1395
-
1396
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1397
-
1398
- const ifcs = pcd.itemFamilyChanges;
1399
- expect(ifcs.size).toEqual(2);
1400
- let ifc = ifcs.get(oneOption_itemFamilyId);
1401
- expect(ifc.colorAdds.length).toEqual(1);
1402
- ifc = ifcs.get(twoOption_itemFamilyId);
1403
- expect(ifc.colorAdds.length).toEqual(2);
1404
- });
1405
-
1406
- it('Feb 3 - 2+ Option A & Feb 3 - No Option A', () => {
1407
- const noOption_itemFamilyId = 'kh1Rtb7kie7Vk5vo';
1408
- const twoOption_itemFamilyId = 'tvCyTuL6hF3MwbjJ';
1409
- const bothFamilyIds = [noOption_itemFamilyId, twoOption_itemFamilyId];
1410
- const fullChange = filterFullChange(fall_2003_fullChange, bothFamilyIds);
1411
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails, bothFamilyIds);
1412
- const seasonFed: SeasonFederation = {
1413
- entityReference: 'assortment:' + fullChange['id'],
1414
- objectClass: 'LCSSeason',
1415
- federationId: 'VR:...LCSSeason:1'
1416
- };
1417
-
1418
- const itemToFederatedIdMapping = new Map<string, string>();
1419
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1420
-
1421
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1422
-
1423
- const config = {} as FCConfig;
1424
-
1425
- const mapFileUtil = new MapFileUtil(new Entities());
1426
- const dc = new DataConverter(config, mapFileUtil);
1427
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1428
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1429
- const assortmentItemDeleteMap = new Map<string, object>();
1430
-
1431
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'i-OONhGKbJAfRKo-', sinceDate);
1432
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1433
- pcd.releasedForDevelopmentItemIds.push(noOption_itemFamilyId);
1434
- pcd.releasedForDevelopmentItemIds.push('jezonPsoRUlA52iz');
1435
- pcd.releasedForDevelopmentItemIds.push('VGo0fWmBBEZoghgk');
1436
- pcd.releasedForDevelopmentItemIds.push('kh1Rtb7kie7Vk5vo');
1437
- pcd.releasedForDevelopmentItemIds.push('tvCyTuL6hF3MwbjJ');
1438
-
1439
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1440
-
1441
- const ifcs = pcd.itemFamilyChanges;
1442
- expect(ifcs.size).toEqual(2);
1443
- let ifc = ifcs.get(noOption_itemFamilyId);
1444
- expect(ifc.familyAdd).toBe(true);
1445
- expect(ifc.colorAdds.length).toEqual(0);
1446
- ifc = ifcs.get(twoOption_itemFamilyId);
1447
- expect(ifc.colorAdds.length).toEqual(2);
1448
- });
1449
-
1450
- it('Feb 3 - 1 Option B -remove option - leave family', () => {
1451
- const itemFamilyId = 'EejAxj-KK_GGr5Kh';
1452
- const fullChange = filterFullChange(fall_2003_fullChange_run2, [itemFamilyId]);
1453
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails_run2, [itemFamilyId]);
1454
- const deleteChanges = filterDeleteChange(fall_2003_deleteChanges_run2, [itemFamilyId]);
1455
- const seasonFed: SeasonFederation = {
1456
- entityReference: 'assortment:' + fullChange['id'],
1457
- objectClass: 'LCSSeason',
1458
- federationId: 'VR:...LCSSeason:1'
1459
- };
1460
-
1461
- const itemToFederatedIdMapping = new Map<string, string>();
1462
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1463
-
1464
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1465
-
1466
- const config = {} as FCConfig;
1467
-
1468
- const mapFileUtil = new MapFileUtil(new Entities());
1469
- const dc = new DataConverter(config, mapFileUtil);
1470
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1471
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1472
- const assortmentItemDeleteMap = ppa.getDeleteChangesAssortmentMap(deleteChanges);
1473
-
1474
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'nPxkQJrFlTikr00h', sinceDate);
1475
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1476
- pcd.releasedForDevelopmentItemIds.push(itemFamilyId);
1477
- pcd.releasedForDevelopmentItemIds.push('yLhrIHYaP7B4nlkh');
1478
-
1479
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1480
-
1481
- const ifcs = pcd.itemFamilyChanges;
1482
- expect(ifcs.size).toEqual(1);
1483
- const ifc = ifcs.get(itemFamilyId);
1484
- expect(ifc.familyAdd).toBe(true);
1485
- expect(ifc.colorAdds.length).toEqual(0);
1486
- expect(ifc.colorDeletes.length).toEqual(1);
1487
- });
1488
-
1489
- it('Feb 3 - 1 Option C -remove family & option', () => {
1490
- const itemFamilyId = 'JEY86MOuRFv7f9OY';
1491
- const fullChange = filterFullChange(fall_2003_fullChange_run2, [itemFamilyId]);
1492
- const hydratedDetails = filterHydratedDetails(fall_2003_hydratedDetails_run2, [itemFamilyId]);
1493
- const deleteChanges = filterDeleteChange(fall_2003_deleteChanges_run2, [itemFamilyId]);
1494
- const seasonFed: SeasonFederation = {
1495
- entityReference: 'assortment:' + fullChange['id'],
1496
- objectClass: 'LCSSeason',
1497
- federationId: 'VR:...LCSSeason:1'
1498
- };
1499
-
1500
- const itemToFederatedIdMapping = new Map<string, string>();
1501
- fall_2003_fedMapping.forEach(mapping => itemToFederatedIdMapping.set(mapping.reference, mapping.mappedReference));
1502
-
1503
- const sinceDate = new Date('2023-02-01T00:00:00.000Z');
1504
-
1505
- const config = {} as FCConfig;
1506
-
1507
- const mapFileUtil = new MapFileUtil(new Entities());
1508
- const dc = new DataConverter(config, mapFileUtil);
1509
- const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1510
-
1511
- const assortmentItemFullChangeMap = ppa.getFullChangeAssortmentMap(fullChange);
1512
- const assortmentItemDeleteMap = ppa.getDeleteChangesAssortmentMap(deleteChanges);
1513
-
1514
- const pcd = new PublishChangeData(fullChange['id'], seasonFed, 'nPxkQJrFlTikr00h', sinceDate);
1515
- pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
1516
- pcd.releasedForDevelopmentItemIds.push(itemFamilyId);
1517
- pcd.releasedForDevelopmentItemIds.push('eZL2ChJRBlvbu3yG');
1518
-
1519
- pcd.itemFamilyChanges = ppa.getItemFamilyChanges(pcd, hydratedDetails, assortmentItemFullChangeMap, assortmentItemDeleteMap);
1520
-
1521
- const ifcs = pcd.itemFamilyChanges;
1522
- expect(ifcs.size).toEqual(1);
1523
- const ifc = ifcs.get(itemFamilyId);
1524
- //TODO fix
1525
- // expect(ifc.familyDelete).toBe(true);
1526
- expect(ifc.colorAdds.length).toEqual(0);
1527
- expect(ifc.colorDeletes.length).toEqual(1);
1528
- });
1529
-
1530
- });
1531
-
1532
- describe('getProjectItem', () =>{
1533
- const config = {
1534
- identifierAtts: {
1535
- LCSSeason: ['flexPLMSeasonName']
1536
- }
1537
- } as unknown as FCConfig;
1538
- const mapFileUtil = new MapFileUtil(new Entities());
1539
- const dc = new DataConverter(config, mapFileUtil);
1540
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1541
-
1542
- it('family assortment item in assortmentItemFullChangeMap', () =>{
1543
- const familyId = 'w43t4';
1544
- const sinceDate = new Date();
1545
- const ifc = new ItemFamilyChanges(familyId, sinceDate);
1546
- const projectItem = {
1547
- id: '4md02m:' + familyId
1548
- };
1549
- ifc.assortmentItemFullChangeMap.set(familyId, {
1550
- projectItem
1551
- });
1552
-
1553
- const fpi = bppa.getProjectItem(ifc, familyId);
1554
-
1555
- expect(fpi).toEqual(projectItem);
1556
- });
1557
-
1558
- it('family assortment item NOT in assortmentItemFullChangeMap', () =>{
1559
- const familyId = 'w43t4';
1560
- const optionId = 'l3mci2';
1561
- const sinceDate = new Date();
1562
- const ifc = new ItemFamilyChanges(familyId, sinceDate);
1563
- const familyProjectItem = {
1564
- id: '4md02m:' + familyId
1565
- };
1566
- ifc.assortmentItemFullChangeMap.set(optionId, {
1567
- familyProjectItem
1568
- });
1569
-
1570
- const fpi = bppa.getProjectItem(ifc, familyId);
1571
-
1572
- expect(fpi).toEqual(familyProjectItem);
1573
- });
1574
-
1575
- it('option assortment item in assortmentItemFullChangeMap', () =>{
1576
- const familyId = 'w43t4';
1577
- const optionId = 'l3mci2';
1578
- const sinceDate = new Date();
1579
- const ifc = new ItemFamilyChanges(familyId, sinceDate);
1580
- const projectItem = {
1581
- id: '4md02m:' + optionId
1582
- };
1583
- ifc.assortmentItemFullChangeMap.set(optionId, {
1584
- projectItem
1585
- });
1586
-
1587
- const fpi = bppa.getProjectItem(ifc, optionId);
1588
-
1589
- expect(fpi).toEqual(projectItem);
1590
- });
1591
-
1592
- });
1593
-
1594
- describe('getCarriedFromSeason', () =>{
1595
- const config = {
1596
- identifierAtts: {
1597
- LCSSeason: ['flexPLMSeasonName']
1598
- }
1599
- } as unknown as FCConfig;
1600
- const mapFileUtil = new MapFileUtil(new Entities());
1601
- const dc = new DataConverter(config, mapFileUtil);
1602
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1603
-
1604
- it('cache hit', async () =>{
1605
- const projectItem = {
1606
- addedFromAssortment: 123
1607
- };
1608
- const origGetAssormentEntityFromId = bppa.getAssormentEntityFromId;
1609
- const origGetSeasonFederationFromAssortment = bppa.getSeasonFederationFromAssortment;
1610
- try{
1611
- const assortmentEntity = {};
1612
- const seasonFed: SeasonFederation = {
1613
- entityReference: 'assortment:123',
1614
- objectClass: 'LCSSeason'
1615
- };
1616
- bppa.getAssormentEntityFromId = async (assortmentId: any) => { return assortmentEntity};
1617
- bppa.getSeasonFederationFromAssortment = async(assortment: any) => { return seasonFed};
1618
-
1619
- const spyGetAssortment = jest.spyOn(bppa, 'getAssormentEntityFromId');
1620
- const spyGetSeasonFed = jest.spyOn(bppa, 'getSeasonFederationFromAssortment');
1621
-
1622
- let sFed = await bppa.getCarriedFromSeason(projectItem);
1623
-
1624
- sFed = await bppa.getCarriedFromSeason(projectItem);
1625
-
1626
- expect(spyGetAssortment).toHaveBeenCalledTimes(1);
1627
- expect(spyGetSeasonFed).toHaveBeenCalledTimes(1);
1628
- } finally{
1629
- bppa.getAssormentEntityFromId = origGetAssormentEntityFromId;
1630
- bppa.getSeasonFederationFromAssortment = origGetSeasonFederationFromAssortment;
1631
- }
1632
-
1633
- const sf: SeasonFederation = await bppa.getCarriedFromSeason(projectItem);
1634
-
1635
- });
1636
-
1637
- describe('getSeasonFederationFromAssortment', () =>{
1638
- it('Test conversion', async () =>{
1639
-
1640
- const assortment = {
1641
- id: '2we4',
1642
- name: 'Object Name',
1643
- notTransferred: 'This shouldnt be in the returned object'
1644
- };
1645
- const typePath = 'Path';
1646
- const identifierKeys = ['name'];
1647
- const informationKeys = [];
1648
- const mapKey = 'mapKey';
1649
-
1650
- const spyTCU_type_path = jest.spyOn(TypeConversionUtils, 'getObjectTypePath')
1651
- .mockImplementation(async () => typePath);
1652
-
1653
- const spyDC_get_data = jest.spyOn(dc, 'getFlexPLMObjectData')
1654
- .mockImplementation(async (data) => data);
1655
-
1656
- const spyTCU_id_keys = jest.spyOn(TypeConversionUtils, 'getIdentifierProperties')
1657
- .mockImplementation(async () => identifierKeys);
1658
-
1659
- const spyTCU_info_keys = jest.spyOn(TypeConversionUtils, 'getInformationalProperties')
1660
- .mockImplementation(async () => informationKeys);
1661
-
1662
- const spyTCU_get_map_key = jest.spyOn(TypeConversionUtils, 'getMapKey')
1663
- .mockImplementation(async () => mapKey);
1664
-
1665
- const spyMU_apply_map = jest.spyOn(MapUtil, 'applyTransformMap')
1666
- .mockImplementation(async (...args) => args[2]);
1667
-
1668
- const results = await bppa.getSeasonFederationFromAssortment(assortment);
1669
-
1670
- console.log('Test conversion: ' + JSON.stringify(results));
1671
- expect(results['entityReference']).toBe('assortment:2we4');
1672
- expect(results['name']).toBe('Object Name');
1673
- expect(results['flexPLMTypePath']).toBe('Path');
1674
- expect(results['objectClass']).toBe('LCSSeason');
1675
- expect(results).not.toHaveProperty('notTransferred');
1676
- });
1677
-
1678
-
1679
-
1680
-
1681
- });
1682
-
1683
- });
1684
-
1685
- describe('meetsCriteria', () =>{
1686
- const config = {
1687
- identifierAtts: {
1688
- LCSSeason: ['flexPLMSeasonName']
1689
- },
1690
- itemPreDevelopmentLifecycleStages: ['concept']
1691
- } as unknown as FCConfig;
1692
- const mapFileUtil = new MapFileUtil(new Entities());
1693
- const dc = new DataConverter(config, mapFileUtil);
1694
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1695
- it('no item', () =>{
1696
- const aItem = {};
1697
-
1698
- const results = bppa.meetsCriteria(aItem);
1699
- expect(results).toBeFalsy();
1700
- });
1701
-
1702
- it('item - no lifecycle stage', () =>{
1703
- const aItem = {
1704
- item: {
1705
- lifecycleStage: ''
1706
- }
1707
- };
1708
-
1709
- const results = bppa.meetsCriteria(aItem);
1710
- expect(results).toBeFalsy();
1711
- });
1712
-
1713
- it('item - concept lifecycle stage', () =>{
1714
- const aItem = {
1715
- item: {
1716
- lifecycleStage: 'concept'
1717
- }
1718
- };
1719
-
1720
- const results = bppa.meetsCriteria(aItem);
1721
- expect(results).toBeFalsy();
1722
- });
1723
-
1724
- it('item - delevopment lifecycle stage', () =>{
1725
- const aItem = {
1726
- item: {
1727
- lifecycleStage: 'delevopment'
1728
- }
1729
- };
1730
-
1731
- const results = bppa.meetsCriteria(aItem);
1732
- expect(results).toBeTruthy();
1733
- });
1734
-
1735
- });
1736
-
1737
- describe('getEventsForItemFamilyChanges - conditional eventType', () => {
1738
- const config = {
1739
- identifierAtts: {
1740
- LCSSeason: ['flexPLMSeasonName']
1741
- },
1742
- itemPreDevelopmentLifecycleStages: ['concept']
1743
- } as unknown as FCConfig;
1744
- const mapFileUtil = new MapFileUtil(new Entities());
1745
- const dc = new DataConverter(config, mapFileUtil);
1746
-
1747
- afterEach(() => {
1748
- jest.restoreAllMocks();
1749
- });
1750
-
1751
- it('should use UPSERT_ON_SEASON for LCSProductSeasonLink when isOutboundCreatableFromEntity returns true', async () => {
1752
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1753
-
1754
- const itemFamilyId = 'family123';
1755
- const prodEntityData = { id: itemFamilyId, identifier: 'FAM-123', itemNumber: 'FAM-123' };
1756
- const projectItem = { id: 'proj1', updatedOn: '2023-01-15T00:00:00.000Z' };
1757
- const assortment = { id: 'assort123', name: 'Fall 2023 Assortment', publishToFlexPLM: true };
1758
- const seasonFed: SeasonFederation = {
1759
- entityReference: 'assortment:assort123',
1760
- objectClass: 'LCSSeason',
1761
- flexPLMSeasonName: 'Fall 2023'
1762
- };
1763
-
1764
- const itemFamilyChanges = new ItemFamilyChanges(itemFamilyId, new Date('2023-01-01T00:00:00.000Z'));
1765
- itemFamilyChanges.familyAdd = true;
1766
- itemFamilyChanges.assortmentItemFullChangeMap.set(itemFamilyId, {
1767
- item: prodEntityData,
1768
- projectItem
1769
- });
1770
-
1771
- jest.spyOn(bppa, 'getAssortment').mockResolvedValue(assortment);
1772
- jest.spyOn(bppa, 'getProjectItem').mockReturnValue(projectItem);
1773
- jest.spyOn(bppa, 'getSeasonalData').mockResolvedValue({ someData: 'value' });
1774
- jest.spyOn(MapUtil, 'applyTransformMap').mockResolvedValue({ transformedData: 'value' });
1775
- jest.spyOn(TypeConversionUtils, 'getIdentifierProperties').mockResolvedValue(['identifier']);
1776
- jest.spyOn(TypeConversionUtils, 'getInformationalProperties').mockResolvedValue([]);
1777
- jest.spyOn(TypeConversionUtils, 'isOutboundCreatableFromEntity').mockResolvedValue(true);
1778
-
1779
- const events = await bppa.getEventsForItemFamilyChanges(itemFamilyChanges, 'assort123', seasonFed, new Map());
1780
-
1781
- expect(events).toHaveLength(1);
1782
- expect(events[0].eventType).toBe('UPSERT_ON_SEASON');
1783
- expect(events[0].objectClass).toBe('LCSProductSeasonLink');
1784
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenCalledWith(
1785
- undefined,
1786
- mapFileUtil,
1787
- projectItem,
1788
- { item: prodEntityData, assortment }
1789
- );
1790
- });
1791
-
1792
- it('should use UPDATE_ON_SEASON for LCSProductSeasonLink when isOutboundCreatableFromEntity returns false', async () => {
1793
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1794
-
1795
- const itemFamilyId = 'family123';
1796
- const prodEntityData = { id: itemFamilyId, identifier: 'FAM-123', itemNumber: 'FAM-123' };
1797
- const projectItem = { id: 'proj1', updatedOn: '2023-01-15T00:00:00.000Z' };
1798
- const assortment = { id: 'assort123', name: 'Fall 2023 Assortment', publishToFlexPLM: true };
1799
- const seasonFed: SeasonFederation = {
1800
- entityReference: 'assortment:assort123',
1801
- objectClass: 'LCSSeason',
1802
- flexPLMSeasonName: 'Fall 2023'
1803
- };
1804
-
1805
- const itemFamilyChanges = new ItemFamilyChanges(itemFamilyId, new Date('2023-01-01T00:00:00.000Z'));
1806
- itemFamilyChanges.familyUpdate = true;
1807
- itemFamilyChanges.assortmentItemFullChangeMap.set(itemFamilyId, {
1808
- item: prodEntityData,
1809
- projectItem
1810
- });
1811
-
1812
- jest.spyOn(bppa, 'getAssortment').mockResolvedValue(assortment);
1813
- jest.spyOn(bppa, 'getProjectItem').mockReturnValue(projectItem);
1814
- jest.spyOn(bppa, 'getSeasonalData').mockResolvedValue({ someData: 'value' });
1815
- jest.spyOn(MapUtil, 'applyTransformMap').mockResolvedValue({ transformedData: 'value' });
1816
- jest.spyOn(TypeConversionUtils, 'getIdentifierProperties').mockResolvedValue(['identifier']);
1817
- jest.spyOn(TypeConversionUtils, 'getInformationalProperties').mockResolvedValue([]);
1818
- jest.spyOn(TypeConversionUtils, 'isOutboundCreatableFromEntity').mockResolvedValue(false);
1819
-
1820
- const events = await bppa.getEventsForItemFamilyChanges(itemFamilyChanges, 'assort123', seasonFed, new Map());
1821
-
1822
- expect(events).toHaveLength(1);
1823
- expect(events[0].eventType).toBe('UPDATE_ON_SEASON');
1824
- expect(events[0].objectClass).toBe('LCSProductSeasonLink');
1825
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenCalledWith(
1826
- undefined,
1827
- mapFileUtil,
1828
- projectItem,
1829
- { item: prodEntityData, assortment }
1830
- );
1831
- });
1832
-
1833
- it('should use UPSERT_ON_SEASON for LCSSKUSeasonLink when isOutboundCreatableFromEntity returns true', async () => {
1834
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1835
-
1836
- const itemFamilyId = 'family123';
1837
- const colorId = 'color456';
1838
- const familyItemData = { id: itemFamilyId, identifier: 'FAM-123', itemNumber: 'FAM-123' };
1839
- const itemData = { id: colorId, identifier: 'COLOR-456', itemNumber: 'COLOR-456' };
1840
- const familyProjectItem = { id: 'proj0', updatedOn: '2023-01-14T00:00:00.000Z' };
1841
- const projectItem = { id: 'proj1', updatedOn: '2023-01-15T00:00:00.000Z' };
1842
- const assortment = { id: 'assort123', name: 'Fall 2023 Assortment', publishToFlexPLM: true };
1843
- const seasonFed: SeasonFederation = {
1844
- entityReference: 'assortment:assort123',
1845
- objectClass: 'LCSSeason',
1846
- flexPLMSeasonName: 'Fall 2023'
1847
- };
1848
-
1849
- const itemFamilyChanges = new ItemFamilyChanges(itemFamilyId, new Date('2023-01-01T00:00:00.000Z'));
1850
- itemFamilyChanges.colorAdds.push(colorId);
1851
- itemFamilyChanges.assortmentItemFullChangeMap.set(itemFamilyId, {
1852
- item: familyItemData,
1853
- projectItem: familyProjectItem
1854
- });
1855
- itemFamilyChanges.assortmentItemFullChangeMap.set(colorId, {
1856
- item: itemData,
1857
- projectItem
1858
- });
1859
-
1860
- jest.spyOn(bppa, 'getAssortment').mockResolvedValue(assortment);
1861
- jest.spyOn(bppa, 'getProjectItem')
1862
- .mockReturnValueOnce(familyProjectItem)
1863
- .mockReturnValueOnce(projectItem);
1864
- jest.spyOn(bppa, 'getSeasonalData').mockResolvedValue({ someData: 'value' });
1865
- jest.spyOn(MapUtil, 'applyTransformMap').mockResolvedValue({ transformedData: 'value' });
1866
- jest.spyOn(TypeConversionUtils, 'getIdentifierProperties').mockResolvedValue(['identifier']);
1867
- jest.spyOn(TypeConversionUtils, 'getInformationalProperties').mockResolvedValue([]);
1868
- jest.spyOn(TypeConversionUtils, 'isOutboundCreatableFromEntity')
1869
- .mockResolvedValueOnce(true) // for family
1870
- .mockResolvedValueOnce(true); // for SKU
1871
-
1872
- const events = await bppa.getEventsForItemFamilyChanges(itemFamilyChanges, 'assort123', seasonFed, new Map());
1873
-
1874
- // Should have both family and SKU events because familyAssortmentItem is true when colorAdds.length > 0
1875
- expect(events).toHaveLength(2);
1876
-
1877
- const skuEvent = events.find(e => e.objectClass === 'LCSSKUSeasonLink');
1878
- expect(skuEvent.eventType).toBe('UPSERT_ON_SEASON');
1879
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenCalledWith(
1880
- undefined,
1881
- mapFileUtil,
1882
- projectItem,
1883
- { item: itemData, assortment }
1884
- );
1885
- });
1886
-
1887
- it('should use UPDATE_ON_SEASON for LCSSKUSeasonLink when isOutboundCreatableFromEntity returns false', async () => {
1888
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1889
-
1890
- const itemFamilyId = 'family123';
1891
- const colorId = 'color456';
1892
- const familyItemData = { id: itemFamilyId, identifier: 'FAM-123', itemNumber: 'FAM-123' };
1893
- const itemData = { id: colorId, identifier: 'COLOR-456', itemNumber: 'COLOR-456' };
1894
- const familyProjectItem = { id: 'proj0', updatedOn: '2023-01-14T00:00:00.000Z' };
1895
- const projectItem = { id: 'proj1', updatedOn: '2023-01-15T00:00:00.000Z' };
1896
- const assortment = { id: 'assort123', name: 'Fall 2023 Assortment', publishToFlexPLM: true };
1897
- const seasonFed: SeasonFederation = {
1898
- entityReference: 'assortment:assort123',
1899
- objectClass: 'LCSSeason',
1900
- flexPLMSeasonName: 'Fall 2023'
1901
- };
1902
-
1903
- const itemFamilyChanges = new ItemFamilyChanges(itemFamilyId, new Date('2023-01-01T00:00:00.000Z'));
1904
- itemFamilyChanges.colorUpdates.push(colorId);
1905
- itemFamilyChanges.assortmentItemFullChangeMap.set(itemFamilyId, {
1906
- item: familyItemData,
1907
- projectItem: familyProjectItem
1908
- });
1909
- itemFamilyChanges.assortmentItemFullChangeMap.set(colorId, {
1910
- item: itemData,
1911
- projectItem
1912
- });
1913
-
1914
- jest.spyOn(bppa, 'getAssortment').mockResolvedValue(assortment);
1915
- jest.spyOn(bppa, 'getProjectItem')
1916
- .mockReturnValueOnce(familyProjectItem)
1917
- .mockReturnValueOnce(projectItem);
1918
- jest.spyOn(bppa, 'getSeasonalData').mockResolvedValue({ someData: 'value' });
1919
- jest.spyOn(MapUtil, 'applyTransformMap').mockResolvedValue({ transformedData: 'value' });
1920
- jest.spyOn(TypeConversionUtils, 'getIdentifierProperties').mockResolvedValue(['identifier']);
1921
- jest.spyOn(TypeConversionUtils, 'getInformationalProperties').mockResolvedValue([]);
1922
- jest.spyOn(TypeConversionUtils, 'isOutboundCreatableFromEntity')
1923
- .mockResolvedValueOnce(false) // for family
1924
- .mockResolvedValueOnce(false); // for SKU
1925
-
1926
- const events = await bppa.getEventsForItemFamilyChanges(itemFamilyChanges, 'assort123', seasonFed, new Map());
1927
-
1928
- // Should have both family and SKU events because familyAssortmentItem is true when colorUpdates.length > 0
1929
- expect(events).toHaveLength(2);
1930
-
1931
- const skuEvent = events.find(e => e.objectClass === 'LCSSKUSeasonLink');
1932
- expect(skuEvent.eventType).toBe('UPDATE_ON_SEASON');
1933
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenCalledWith(
1934
- undefined,
1935
- mapFileUtil,
1936
- projectItem,
1937
- { item: itemData, assortment }
1938
- );
1939
- });
1940
-
1941
- it('should create both product and SKU events with correct eventTypes based on isOutboundCreatableFromEntity', async () => {
1942
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
1943
-
1944
- const itemFamilyId = 'family123';
1945
- const colorId = 'color456';
1946
- const prodEntityData = { id: itemFamilyId, identifier: 'FAM-123', itemNumber: 'FAM-123' };
1947
- const itemData = { id: colorId, identifier: 'COLOR-456', itemNumber: 'COLOR-456' };
1948
- const familyProjectItem = { id: 'proj1', updatedOn: '2023-01-15T00:00:00.000Z' };
1949
- const colorProjectItem = { id: 'proj2', updatedOn: '2023-01-15T00:00:00.000Z' };
1950
- const assortment = { id: 'assort123', name: 'Fall 2023 Assortment', publishToFlexPLM: true };
1951
- const seasonFed: SeasonFederation = {
1952
- entityReference: 'assortment:assort123',
1953
- objectClass: 'LCSSeason',
1954
- flexPLMSeasonName: 'Fall 2023'
1955
- };
1956
-
1957
- const itemFamilyChanges = new ItemFamilyChanges(itemFamilyId, new Date('2023-01-01T00:00:00.000Z'));
1958
- itemFamilyChanges.familyAdd = true;
1959
- itemFamilyChanges.colorAdds.push(colorId);
1960
- itemFamilyChanges.assortmentItemFullChangeMap.set(itemFamilyId, {
1961
- item: prodEntityData,
1962
- projectItem: familyProjectItem
1963
- });
1964
- itemFamilyChanges.assortmentItemFullChangeMap.set(colorId, {
1965
- item: itemData,
1966
- projectItem: colorProjectItem
1967
- });
1968
-
1969
- jest.spyOn(bppa, 'getAssortment').mockResolvedValue(assortment);
1970
- jest.spyOn(bppa, 'getProjectItem')
1971
- .mockReturnValueOnce(familyProjectItem)
1972
- .mockReturnValueOnce(colorProjectItem);
1973
- jest.spyOn(bppa, 'getSeasonalData').mockResolvedValue({ someData: 'value' });
1974
- jest.spyOn(MapUtil, 'applyTransformMap').mockResolvedValue({ transformedData: 'value' });
1975
- jest.spyOn(TypeConversionUtils, 'getIdentifierProperties').mockResolvedValue(['identifier']);
1976
- jest.spyOn(TypeConversionUtils, 'getInformationalProperties').mockResolvedValue([]);
1977
- // Product is creatable (true), SKU is not (false)
1978
- jest.spyOn(TypeConversionUtils, 'isOutboundCreatableFromEntity')
1979
- .mockResolvedValueOnce(true)
1980
- .mockResolvedValueOnce(false);
1981
-
1982
- const events = await bppa.getEventsForItemFamilyChanges(itemFamilyChanges, 'assort123', seasonFed, new Map());
1983
-
1984
- expect(events).toHaveLength(2);
1985
-
1986
- const productEvent = events.find(e => e.objectClass === 'LCSProductSeasonLink');
1987
- const skuEvent = events.find(e => e.objectClass === 'LCSSKUSeasonLink');
1988
-
1989
- expect(productEvent.eventType).toBe('UPSERT_ON_SEASON');
1990
- expect(skuEvent.eventType).toBe('UPDATE_ON_SEASON');
1991
-
1992
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenCalledTimes(2);
1993
- // Verify product event called with assortment entity
1994
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenNthCalledWith(
1995
- 1,
1996
- undefined,
1997
- mapFileUtil,
1998
- familyProjectItem,
1999
- { item: prodEntityData, assortment }
2000
- );
2001
- // Verify SKU event called with assortment entity
2002
- expect(TypeConversionUtils.isOutboundCreatableFromEntity).toHaveBeenNthCalledWith(
2003
- 2,
2004
- undefined,
2005
- mapFileUtil,
2006
- colorProjectItem,
2007
- { item: itemData, assortment }
2008
- );
2009
- });
2010
-
2011
- });
2012
-
2013
- describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
2014
- const config = {
2015
- taskId: 'task-abc',
2016
- event: '{"sourceEventId":"src-1"}'
2017
- } as unknown as FCConfig;
2018
- const mapFileUtil = new MapFileUtil(new Entities());
2019
- const dc = new DataConverter(config, mapFileUtil);
2020
- const events = [{ objectClass: 'LCSProductSeasonLink' }] as any;
2021
- const eventType = 'ASYNC_PUBLISH_SEASON';
2022
-
2023
- beforeEach(() => {
2024
- createCallArg = undefined;
2025
- fileUploadCalls = [];
2026
- fileUploadResult = {
2027
- id: 'file-123',
2028
- downloadUrl: 'https://download.url',
2029
- adminDownloadUrl: 'https://admin.download.url'
2030
- };
2031
- });
2032
- afterEach(() => {
2033
- jest.restoreAllMocks();
2034
- });
2035
-
2036
- it('sendToFlexPLM merges outboundPublishEvent into result and calls sendPublishPayloadEvent in parallel', async () => {
2037
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2038
- const flexResponse = { status: 200, data: { ok: true } };
2039
-
2040
- let flexResolved = false;
2041
- let eventResolved = false;
2042
- const spyFlex = jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM')
2043
- .mockImplementation(async () => {
2044
- await new Promise(r => setTimeout(r, 5));
2045
- flexResolved = true;
2046
- return flexResponse as any;
2047
- });
2048
- const spyEvent = jest.spyOn(bppa as any, 'sendPublishPayloadEvent')
2049
- .mockImplementation(async () => {
2050
- await new Promise(r => setTimeout(r, 5));
2051
- eventResolved = true;
2052
- });
2053
-
2054
- const result = await (bppa as any).sendToFlexPLM(events, eventType);
2055
-
2056
- expect(spyFlex).toHaveBeenCalledTimes(1);
2057
- expect(spyEvent).toHaveBeenCalledTimes(1);
2058
- expect(flexResolved).toBe(true);
2059
- expect(eventResolved).toBe(true);
2060
-
2061
- const passedOutboundPublishEvent = spyFlex.mock.calls[0][0] as any;
2062
- expect(passedOutboundPublishEvent.taskId).toBe('task-abc');
2063
- expect(passedOutboundPublishEvent.eventType).toBe(eventType);
2064
- expect(passedOutboundPublishEvent.objectClass).toBe('LCSSeason');
2065
- expect(passedOutboundPublishEvent.events).toBe(events);
2066
- expect(spyEvent).toHaveBeenCalledWith(passedOutboundPublishEvent);
2067
- expect(result).toEqual({ ...flexResponse, outboundPublishEvent: passedOutboundPublishEvent });
2068
- });
2069
-
2070
- it('handleVibeIQFile (vibeiqfile) merges outboundPublishEvent into FlexPLM result and calls sendPublishPayloadEvent', async () => {
2071
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2072
- const flexResponse = { status: 200, data: { ok: true } };
2073
-
2074
- const spyFlex = jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM')
2075
- .mockResolvedValue(flexResponse as any);
2076
- const spyEvent = jest.spyOn(bppa as any, 'sendPublishPayloadEvent')
2077
- .mockResolvedValue(undefined as any);
2078
-
2079
- const result = await (bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile');
2080
-
2081
- expect(fileUploadCalls).toHaveLength(1);
2082
- expect(fileUploadCalls[0].fileName).toBe('ASYNC_PUBLISH_SEASON-events.json');
2083
- expect(fileUploadCalls[0].mimeType).toBe('application/json');
2084
-
2085
- const passedOutboundPublishEvent = spyFlex.mock.calls[0][0] as any;
2086
- expect(passedOutboundPublishEvent.taskId).toBe('task-abc');
2087
- expect(passedOutboundPublishEvent.eventType).toBe(eventType);
2088
- expect(passedOutboundPublishEvent.objectClass).toBe('LCSSeason');
2089
- expect(passedOutboundPublishEvent.eventsFileId).toBe('file-123');
2090
- expect(passedOutboundPublishEvent.eventsDownloadLink).toBe('https://download.url');
2091
- expect(passedOutboundPublishEvent.eventsAdminDownloadLink).toBe('https://admin.download.url');
2092
-
2093
- expect(spyFlex).toHaveBeenCalledTimes(1);
2094
- expect(spyEvent).toHaveBeenCalledTimes(1);
2095
- expect(spyEvent).toHaveBeenCalledWith(passedOutboundPublishEvent);
2096
- expect(result).toEqual({ ...flexResponse, outboundPublishEvent: passedOutboundPublishEvent });
2097
- });
2098
-
2099
- it('handleVibeIQFile (vibeiqfile-dontsendtoflexplm) skips FlexPLM but still calls sendPublishPayloadEvent', async () => {
2100
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2101
-
2102
- const spyFlex = jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM')
2103
- .mockResolvedValue({} as any);
2104
- const spyEvent = jest.spyOn(bppa as any, 'sendPublishPayloadEvent')
2105
- .mockResolvedValue(undefined as any);
2106
-
2107
- const result = await (bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile-dontsendtoflexplm');
2108
-
2109
- expect(spyFlex).not.toHaveBeenCalled();
2110
- expect(spyEvent).toHaveBeenCalledTimes(1);
2111
-
2112
- const passedOutboundPublishEvent = spyEvent.mock.calls[0][0] as any;
2113
- expect(passedOutboundPublishEvent.eventsFileId).toBe('file-123');
2114
- expect(result).toEqual({
2115
- message: 'Successfully Uploaded File.',
2116
- outboundPublishEvent: passedOutboundPublishEvent
2117
- });
2118
- });
2119
-
2120
- it('sendPublishPayloadEvent creates an external-event with initialEvent parsed from config', async () => {
2121
- const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2122
- const outboundPublishEvent = { foo: 'bar' };
2123
-
2124
- await (bppa as any).sendPublishPayloadEvent(outboundPublishEvent);
2125
-
2126
- expect(createCallArg).toEqual({
2127
- entityName: 'external-event',
2128
- object: {
2129
- originSystemType: 'VibeIQ',
2130
- objectClass: 'AssortmentPublishedToFlexPLM',
2131
- outboundPublishEvent,
2132
- initialEvent: { sourceEventId: 'src-1' }
2133
- }
2134
- });
2135
- });
2136
-
2137
- it('sendPublishPayloadEvent defaults initialEvent to {} when config has no event', async () => {
2138
- const bareConfig = { taskId: 'task-x' } as unknown as FCConfig;
2139
- const bppa = new BaseProcessPublishAssortment(bareConfig, dc, mapFileUtil);
2140
- const outboundPublishEvent = { hello: 'world' };
2141
-
2142
- await (bppa as any).sendPublishPayloadEvent(outboundPublishEvent);
2143
-
2144
- expect(createCallArg).toEqual({
2145
- entityName: 'external-event',
2146
- object: {
2147
- originSystemType: 'VibeIQ',
2148
- objectClass: 'AssortmentPublishedToFlexPLM',
2149
- outboundPublishEvent,
2150
- initialEvent: {}
2151
- }
2152
- });
2153
- });
2154
- });