@contrail/flexplm 1.3.0 → 1.3.1-alpha.3507ab6

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 (149) hide show
  1. package/lib/cli/commands/compile.d.ts +1 -0
  2. package/lib/cli/commands/compile.js +71 -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 +1 -0
  6. package/lib/cli/commands/create.js +75 -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 +10 -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 +2 -0
  14. package/lib/cli/index.js +64 -0
  15. package/lib/cli/index.spec.d.ts +1 -0
  16. package/lib/cli/index.spec.js +79 -0
  17. package/lib/cli/template/mapping-template.ts.template +62 -0
  18. package/lib/entity-processor/base-entity-processor.d.ts +89 -42
  19. package/lib/entity-processor/base-entity-processor.js +438 -385
  20. package/lib/entity-processor/base-entity-processor.spec.d.ts +1 -1
  21. package/lib/entity-processor/base-entity-processor.spec.js +398 -397
  22. package/lib/flexplm-request.d.ts +3 -3
  23. package/lib/flexplm-request.js +34 -34
  24. package/lib/flexplm-utils.d.ts +5 -5
  25. package/lib/flexplm-utils.js +33 -33
  26. package/lib/flexplm-utils.spec.d.ts +1 -1
  27. package/lib/flexplm-utils.spec.js +26 -26
  28. package/lib/index.d.ts +23 -22
  29. package/lib/index.js +39 -38
  30. package/lib/interfaces/interfaces.d.ts +105 -105
  31. package/lib/interfaces/interfaces.js +2 -2
  32. package/lib/interfaces/item-family-changes.d.ts +20 -20
  33. package/lib/interfaces/item-family-changes.js +56 -56
  34. package/lib/interfaces/mapping-file.d.ts +460 -0
  35. package/lib/interfaces/mapping-file.js +2 -0
  36. package/lib/interfaces/publish-change-data.d.ts +19 -19
  37. package/lib/interfaces/publish-change-data.js +32 -32
  38. package/lib/publish/base-process-publish-assortment-callback.d.ts +9 -9
  39. package/lib/publish/base-process-publish-assortment-callback.js +38 -38
  40. package/lib/publish/base-process-publish-assortment.d.ts +118 -93
  41. package/lib/publish/base-process-publish-assortment.js +998 -944
  42. package/lib/publish/base-process-publish-assortment.spec.d.ts +1 -1
  43. package/lib/publish/base-process-publish-assortment.spec.js +1688 -1670
  44. package/lib/publish/mockData.d.ts +1389 -1389
  45. package/lib/publish/mockData.js +4524 -4519
  46. package/lib/transform/identifier-conversion-spec-mockData.js +472 -444
  47. package/lib/transform/identifier-conversion.d.ts +51 -15
  48. package/lib/transform/identifier-conversion.js +248 -212
  49. package/lib/transform/identifier-conversion.spec.d.ts +1 -1
  50. package/lib/transform/identifier-conversion.spec.js +343 -339
  51. package/lib/util/config-defaults.d.ts +8 -8
  52. package/lib/util/config-defaults.js +88 -85
  53. package/lib/util/config-defaults.spec.d.ts +1 -1
  54. package/lib/util/config-defaults.spec.js +302 -293
  55. package/lib/util/data-converter-spec-mockData.js +219 -205
  56. package/lib/util/data-converter.d.ts +136 -39
  57. package/lib/util/data-converter.js +718 -592
  58. package/lib/util/data-converter.spec.d.ts +1 -1
  59. package/lib/util/data-converter.spec.js +906 -904
  60. package/lib/util/error-response-object.d.ts +9 -4
  61. package/lib/util/error-response-object.js +54 -47
  62. package/lib/util/error-response-object.spec.d.ts +1 -1
  63. package/lib/util/error-response-object.spec.js +99 -99
  64. package/lib/util/event-short-message-status.d.ts +19 -19
  65. package/lib/util/event-short-message-status.js +24 -23
  66. package/lib/util/federation.d.ts +15 -15
  67. package/lib/util/federation.js +157 -149
  68. package/lib/util/flexplm-connect.d.ts +29 -22
  69. package/lib/util/flexplm-connect.js +190 -176
  70. package/lib/util/flexplm-connect.spec.d.ts +1 -1
  71. package/lib/util/flexplm-connect.spec.js +88 -88
  72. package/lib/util/logger-config.d.ts +1 -1
  73. package/lib/util/logger-config.js +27 -26
  74. package/lib/util/map-util-spec-mockData.js +219 -205
  75. package/lib/util/map-utils.d.ts +33 -6
  76. package/lib/util/map-utils.js +42 -15
  77. package/lib/util/map-utils.spec.d.ts +1 -1
  78. package/lib/util/map-utils.spec.js +89 -89
  79. package/lib/util/mockData.d.ts +80 -80
  80. package/lib/util/mockData.js +103 -103
  81. package/lib/util/thumbnail-util.d.ts +55 -34
  82. package/lib/util/thumbnail-util.js +242 -215
  83. package/lib/util/thumbnail-util.spec.d.ts +1 -1
  84. package/lib/util/thumbnail-util.spec.js +440 -434
  85. package/lib/util/type-conversion-utils-spec-mockData.js +259 -259
  86. package/lib/util/type-conversion-utils.d.ts +163 -23
  87. package/lib/util/type-conversion-utils.js +408 -265
  88. package/lib/util/type-conversion-utils.spec.d.ts +1 -1
  89. package/lib/util/type-conversion-utils.spec.js +868 -868
  90. package/lib/util/type-defaults.d.ts +74 -16
  91. package/lib/util/type-defaults.js +279 -221
  92. package/lib/util/type-defaults.spec.d.ts +1 -1
  93. package/lib/util/type-defaults.spec.js +516 -516
  94. package/lib/util/type-utils.d.ts +34 -13
  95. package/lib/util/type-utils.js +137 -114
  96. package/lib/util/type-utils.spec.d.ts +1 -1
  97. package/lib/util/type-utils.spec.js +192 -190
  98. package/package.json +21 -6
  99. package/scripts/copy-template.js +10 -0
  100. package/.claude/settings.local.json +0 -8
  101. package/.github/pull_request_template.md +0 -31
  102. package/.github/workflows/flexplm-lib.yml +0 -27
  103. package/.github/workflows/publish-to-npm.yml +0 -124
  104. package/CHANGELOG.md +0 -32
  105. package/publish.bat +0 -5
  106. package/publish.sh +0 -5
  107. package/src/entity-processor/base-entity-processor.spec.ts +0 -460
  108. package/src/entity-processor/base-entity-processor.ts +0 -515
  109. package/src/flexplm-request.ts +0 -28
  110. package/src/flexplm-utils.spec.ts +0 -27
  111. package/src/flexplm-utils.ts +0 -29
  112. package/src/index.ts +0 -22
  113. package/src/interfaces/interfaces.ts +0 -122
  114. package/src/interfaces/item-family-changes.ts +0 -67
  115. package/src/interfaces/publish-change-data.ts +0 -43
  116. package/src/publish/base-process-publish-assortment-callback.ts +0 -50
  117. package/src/publish/base-process-publish-assortment.spec.ts +0 -1992
  118. package/src/publish/base-process-publish-assortment.ts +0 -1134
  119. package/src/publish/mockData.ts +0 -4561
  120. package/src/transform/identifier-conversion-spec-mockData.ts +0 -496
  121. package/src/transform/identifier-conversion.spec.ts +0 -354
  122. package/src/transform/identifier-conversion.ts +0 -282
  123. package/src/util/config-defaults.spec.ts +0 -350
  124. package/src/util/config-defaults.ts +0 -93
  125. package/src/util/data-converter-spec-mockData.ts +0 -231
  126. package/src/util/data-converter.spec.ts +0 -1041
  127. package/src/util/data-converter.ts +0 -762
  128. package/src/util/error-response-object.spec.ts +0 -116
  129. package/src/util/error-response-object.ts +0 -50
  130. package/src/util/event-short-message-status.ts +0 -22
  131. package/src/util/federation.ts +0 -172
  132. package/src/util/flexplm-connect.spec.ts +0 -132
  133. package/src/util/flexplm-connect.ts +0 -208
  134. package/src/util/logger-config.ts +0 -20
  135. package/src/util/map-util-spec-mockData.ts +0 -231
  136. package/src/util/map-utils.spec.ts +0 -103
  137. package/src/util/map-utils.ts +0 -41
  138. package/src/util/mockData.ts +0 -101
  139. package/src/util/thumbnail-util.spec.ts +0 -508
  140. package/src/util/thumbnail-util.ts +0 -272
  141. package/src/util/type-conversion-utils-spec-mockData.ts +0 -271
  142. package/src/util/type-conversion-utils.spec.ts +0 -968
  143. package/src/util/type-conversion-utils.ts +0 -460
  144. package/src/util/type-defaults.spec.ts +0 -669
  145. package/src/util/type-defaults.ts +0 -281
  146. package/src/util/type-utils.spec.ts +0 -227
  147. package/src/util/type-utils.ts +0 -144
  148. package/tsconfig.json +0 -29
  149. package/tslint.json +0 -57
@@ -1,508 +0,0 @@
1
- import { FCConfig } from '../interfaces/interfaces';
2
- import { ThumbnailUtil } from './thumbnail-util';
3
-
4
- import { empty_custom_sizes, four_custom_sizes, thumbnail_content_entity } from './mockData';
5
-
6
- const mockEntitiesGet = jest.fn();
7
- const mockEntitiesUpdate = jest.fn();
8
- const mockEntitiesDelete = jest.fn();
9
- const mockContentCreate = jest.fn();
10
-
11
- jest.mock('@contrail/sdk', () => {
12
- return {
13
- Entities: jest.fn().mockImplementation(() => ({
14
- get: mockEntitiesGet,
15
- update: mockEntitiesUpdate,
16
- delete: mockEntitiesDelete,
17
- })),
18
- Content: jest.fn().mockImplementation(() => ({
19
- create: mockContentCreate,
20
- })),
21
- };
22
- });
23
-
24
- const mockGetRequest = jest.fn();
25
- jest.mock('./flexplm-connect', () => {
26
- return {
27
- FlexPLMConnect: jest.fn().mockImplementation(() => ({
28
- getRequest: mockGetRequest,
29
- })),
30
- };
31
- });
32
-
33
- describe('ThumbnailUtil Tests', () =>{
34
- const config = {} as FCConfig;
35
- describe('setOutboundThumbnail()', () =>{
36
- const tu = new ThumbnailUtil(config);
37
- beforeEach(() =>{
38
- jest.clearAllMocks();
39
- });
40
-
41
- it('no data', async () =>{
42
- const data = {};
43
- const event = {};
44
- const results = await tu.setOutboundThumbnail(data, event);
45
- const keys = Object.keys(results);
46
-
47
- expect(results).toEqual(data);
48
- expect(keys.length).toEqual(0);
49
- });
50
-
51
- it('remove thumbnail', async () =>{
52
- const data = {};
53
- const event = {
54
- propertyDiffs: {
55
- largeViewableDownloadUrl: {
56
- oldValue: '123',
57
- newValue: null
58
- }
59
- }
60
- };
61
- const results = await tu.setOutboundThumbnail(data, event);
62
- const keys = Object.keys(results);
63
-
64
- expect(keys.length).toEqual(1);
65
- expect(keys[0]).toEqual(ThumbnailUtil.NEW_THUMBNAIL_ID);
66
- expect(results[ThumbnailUtil.NEW_THUMBNAIL_ID]).toEqual(ThumbnailUtil.REMOVE_THUMBNAIL);
67
-
68
- });
69
-
70
- it('calling getFileId - new thumbnail', async () =>{
71
- const data = {};
72
- const newDownloadUrl = 'https://api.vibeiq.com/dev/api/files/downloadUrl/w3ckfeGAD8ViOZj-%2Fcontent:E1iBQuWbr74lcdcw%2F9e30ds9o-d34b-451e-ae59-b4km36018d5a.png';
73
- const oldDownloadUrl = 'xxx';
74
- const thumbnailId = 'Eey3ZOiqdrUA84F8';
75
- const event = {
76
- newData: {
77
- primaryViewableId: 'm5bJa4RtTLUtKBP5',
78
- largeViewableDownloadUrl: newDownloadUrl
79
- },
80
- propertyDiffs: {
81
- largeViewableDownloadUrl :{
82
- newValue: newDownloadUrl,
83
- oldValue: oldDownloadUrl
84
- }
85
- }
86
- };
87
-
88
- const spyCustomSizes = jest.spyOn(tu, 'getCustomSizes');
89
- spyCustomSizes.mockReturnValue(Promise.resolve(empty_custom_sizes));
90
- const spyGetFileId = jest.spyOn(tu, 'getFileId');
91
- spyGetFileId.mockReturnValue(Promise.resolve(thumbnailId));
92
- const results = await tu.setOutboundThumbnail(data, event);
93
- const keys = Object.keys(results);
94
- expect(keys.length).toEqual(1);
95
- expect(keys[0]).toEqual(ThumbnailUtil.NEW_THUMBNAIL_ID);
96
- const thumbnailValue = results[ThumbnailUtil.NEW_THUMBNAIL_ID];
97
- expect(thumbnailValue).toEqual(thumbnailId);
98
- });
99
-
100
- it('calling getFileId - existing thumbnail', async () =>{
101
- const data = {};
102
- const newDownloadUrl = 'https://api.vibeiq.com/dev/api/files/downloadUrl/w3ckfeGAD8ViOZj-%2Fcontent:E1iBQuWbr74lcdcw%2F9e30ds9o-d34b-451e-ae59-b4km36018d5a.png';
103
- const thumbnailId = 'Eey3ZOiqdrUA84F8';
104
- const event = {
105
- newData: {
106
- primaryViewableId: 'm5bJa4RtTLUtKBP5',
107
- largeViewableDownloadUrl: newDownloadUrl
108
- },
109
- propertyDiffs: {}
110
- };
111
-
112
- const spyCustomSizes = jest.spyOn(tu, 'getCustomSizes');
113
- spyCustomSizes.mockReturnValue(Promise.resolve(empty_custom_sizes));
114
- const spyGetFileId = jest.spyOn(tu, 'getFileId');
115
- spyGetFileId.mockReturnValue(Promise.resolve(thumbnailId));
116
- const results = await tu.setOutboundThumbnail(data, event);
117
- const keys = Object.keys(results);
118
- expect(keys.length).toEqual(1);
119
- expect(keys[0]).toEqual(ThumbnailUtil.EXISTING_THUMBNAIL_ID);
120
- const thumbnailValue = results[ThumbnailUtil.EXISTING_THUMBNAIL_ID];
121
- expect(thumbnailValue).toEqual(thumbnailId);
122
- });
123
- });
124
-
125
- describe('getFileId', () =>{
126
- const primaryFileId = 'yn2d5oHD4rXHRzyB';
127
- beforeEach(() =>{
128
- jest.clearAllMocks();
129
- });
130
- it('no custom sizes, default max_thumbnail_size - result large', async () =>{
131
- const tu = new ThumbnailUtil(config);
132
- const spyCustomSizes = jest.spyOn(tu, 'getCustomSizes');
133
- spyCustomSizes.mockReturnValue(Promise.resolve(empty_custom_sizes));
134
- const spyContentEntity = jest.spyOn(tu, 'getContentEntity');
135
- const content = JSON.parse(JSON.stringify(thumbnail_content_entity));
136
-
137
- spyContentEntity.mockReturnValue(Promise.resolve(content));
138
-
139
- const results = await tu.getFileId(primaryFileId);
140
- expect(results).toEqual('vo4N4mCd-tFrw101');
141
- });
142
-
143
- it('no custom sizes, 750 * 1_024 max_thumbnail_size - result medium', async () =>{
144
- const config1 = {
145
- max_thumbnail_size: 750 * 1_024
146
- } as any as FCConfig;
147
- const tu = new ThumbnailUtil(config1);
148
- const spyCustomSizes = jest.spyOn(tu, 'getCustomSizes');
149
- spyCustomSizes.mockReturnValue(Promise.resolve(empty_custom_sizes));
150
- const spyContentEntity = jest.spyOn(tu, 'getContentEntity');
151
- const content = thumbnail_content_entity;
152
- spyContentEntity.mockReturnValue(Promise.resolve(content));
153
-
154
- const results = await tu.getFileId(primaryFileId);
155
- expect(results).toEqual('AsRvJenpeqxksUNW');
156
- });
157
-
158
- it('custom sizes, 750 * 1_024 max_thumbnail_size - result CS_500Id', async () =>{
159
- const config1 = {
160
- max_thumbnail_size: 750 * 1_024
161
- } as any as FCConfig;
162
- const tu = new ThumbnailUtil(config1);
163
- const spyCustomSizes = jest.spyOn(tu, 'getCustomSizes');
164
- spyCustomSizes.mockReturnValue(Promise.resolve(four_custom_sizes));
165
- const spyContentEntity = jest.spyOn(tu, 'getContentEntity');
166
- const content = thumbnail_content_entity;
167
- spyContentEntity.mockReturnValue(Promise.resolve(content));
168
-
169
- const results = await tu.getFileId(primaryFileId);
170
- expect(results).toEqual('rBaHc1J2xdOWdbhI');
171
- });
172
-
173
- });
174
-
175
- describe('Test isThumbnailNew', () =>{
176
- const tu = new ThumbnailUtil(config);
177
- it('no propertyDiffs', () =>{
178
- const event = {
179
- newData: {
180
- name: 'Test'
181
- },
182
- oldData:{
183
- name: 'Test'
184
- }
185
- };
186
- const results = tu.isThumbnailNew(event, undefined);
187
- expect(results).toBeFalsy();
188
- });
189
-
190
- it('empty propertyDiffs', () =>{
191
- const event = {
192
- newData: {
193
- name: 'Test'
194
- },
195
- oldData:{
196
- name: 'Test'
197
- },
198
- propertyDiffs: {}
199
- };
200
- const results = tu.isThumbnailNew(event, undefined);
201
- expect(results).toBeFalsy();
202
- });
203
-
204
- it('propertyDiffs diff property', () =>{
205
- const event = {
206
- newData: {
207
- name: 'Test1'
208
- },
209
- oldData:{
210
- name: 'Test'
211
- },
212
- propertyDiffs: {
213
- name: {
214
- propertyName: 'name',
215
- oldValue: 'Test',
216
- newValue: 'Test1'
217
- }
218
- }
219
- };
220
- const results = tu.isThumbnailNew(event, undefined);
221
- expect(results).toBeFalsy();
222
- });
223
-
224
- it('propertyDiffs OOB property', () =>{
225
- const event = {
226
- newData: {
227
- name: 'Test1'
228
- },
229
- oldData:{
230
- name: 'Test'
231
- },
232
- propertyDiffs: {
233
- mediumLargeViewableDownloadUrl: {
234
- propertyName: 'mediumLargeViewableDownloadUrl',
235
- oldValue: '',
236
- newValue: 'Test1'
237
- }
238
- }
239
- };
240
- const results = tu.isThumbnailNew(event, undefined);
241
- expect(results).toBeTruthy();
242
- });
243
-
244
- it('propertyDiffs custom property', () =>{
245
- const event = {
246
- newData: {
247
- name: 'Test1'
248
- },
249
- oldData:{
250
- name: 'Test'
251
- },
252
- propertyDiffs: {
253
- RL_1000Url: {
254
- propertyName: 'RL_1000Url',
255
- oldValue: '',
256
- newValue: 'Test1'
257
- }
258
- }
259
- };
260
- const results = tu.isThumbnailNew(event, [{slug: 'RL_1000'}]);
261
- expect(results).toBeTruthy();
262
- });
263
- });
264
-
265
- describe('logContentResults', () =>{
266
- it('no content - doesnt error', () =>{
267
- const tu = new ThumbnailUtil(config);
268
- const content = undefined;
269
- const relations = [];
270
- tu.logContentResults(content, relations);
271
- });
272
- it('no relations - doesnt error', () =>{
273
- const tu = new ThumbnailUtil(config);
274
- const content = undefined;
275
- const relations = undefined;
276
- tu.logContentResults(content, relations);
277
- });
278
-
279
- it('content and relations - logs', () =>{
280
- const tu = new ThumbnailUtil(config);
281
- const content = {
282
- id: '123',
283
- name: 'Test',
284
- primaryFile: { id:'file123'}
285
- };
286
- const relations = ['primaryFile'];
287
- tu.logContentResults(content, relations);
288
-
289
- expect(Object.keys(content)).toHaveLength(3);
290
- expect(content).toHaveProperty('primaryFile');
291
- expect(content.primaryFile).toHaveProperty('id');
292
- expect(content.primaryFile.id).toEqual('file123');
293
- });
294
-
295
- });
296
-
297
- describe('syncThumbnailToVibeIQ', () => {
298
- let tu: ThumbnailUtil;
299
-
300
- beforeEach(() => {
301
- jest.clearAllMocks();
302
- tu = new ThumbnailUtil(config);
303
- mockEntitiesGet.mockImplementation((opts) => {
304
- if (opts.entityName === 'content-custom-size') return Promise.resolve([]);
305
- return Promise.resolve({});
306
- });
307
- mockEntitiesUpdate.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
308
- mockEntitiesDelete.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
309
- });
310
-
311
- it('does not update when no thumbnail IDs in event data', async () => {
312
- const event = { data: {} };
313
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
314
-
315
- expect(mockEntitiesUpdate).not.toHaveBeenCalled();
316
- expect(mockEntitiesDelete).not.toHaveBeenCalled();
317
- expect(mockContentCreate).not.toHaveBeenCalled();
318
- });
319
-
320
- it('does not update when event.data is undefined', async () => {
321
- const event = {};
322
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
323
-
324
- expect(mockEntitiesUpdate).not.toHaveBeenCalled();
325
- expect(mockEntitiesDelete).not.toHaveBeenCalled();
326
- });
327
-
328
- it('REMOVE_THUMBNAIL with existing primaryViewableId deletes content and updates entity', async () => {
329
- const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: ThumbnailUtil.REMOVE_THUMBNAIL } };
330
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'pv1', event, entityName: 'color' });
331
-
332
- expect(mockEntitiesDelete).toHaveBeenCalledWith({ entityName: 'content', id: 'pv1' });
333
- expect(mockEntitiesUpdate).toHaveBeenCalledWith(expect.objectContaining({ entityName: 'color', id: 'entity1' }));
334
- });
335
-
336
- it('REMOVE_THUMBNAIL with no primaryViewableId updates entity without deleting', async () => {
337
- const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: ThumbnailUtil.REMOVE_THUMBNAIL } };
338
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'item' });
339
-
340
- expect(mockEntitiesDelete).not.toHaveBeenCalled();
341
- expect(mockEntitiesUpdate).toHaveBeenCalledWith(expect.objectContaining({ entityName: 'item', id: 'entity1' }));
342
- });
343
-
344
- it('creates new content when no primaryViewableId exists and updates entity', async () => {
345
- const mockResponse = {
346
- arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
347
- headers: { get: jest.fn().mockReturnValue('image/png') },
348
- };
349
- mockGetRequest.mockResolvedValue(mockResponse);
350
-
351
- const createdContent = {
352
- id: 'newContent1',
353
- contentType: 'image/png',
354
- fileName: 'thumb.png',
355
- primaryFileUrl: 'https://files/primary.png',
356
- largeViewableUrl: 'https://files/large.png',
357
- mediumLargeViewableUrl: null,
358
- mediumViewableUrl: null,
359
- smallViewableUrl: null,
360
- tinyViewableUrl: null,
361
- };
362
- mockContentCreate.mockResolvedValue(createdContent);
363
-
364
- const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/thumb.png' } };
365
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
366
-
367
- expect(mockGetRequest).toHaveBeenCalledWith({ urlPath: '/rest/thumbnail/thumb.png', includeUrlContext: false, returnFullResponse: true });
368
- expect(mockContentCreate).toHaveBeenCalledWith(
369
- expect.objectContaining({
370
- fileName: 'thumb.png',
371
- contentType: 'image/png',
372
- contentHolderReference: 'color:entity1',
373
- }),
374
- );
375
- // Updates content with flexplmThumbnailUrl
376
- expect(mockEntitiesUpdate).toHaveBeenCalledWith(
377
- expect.objectContaining({
378
- entityName: 'content',
379
- id: 'newContent1',
380
- object: { flexplmThumbnailUrl: '/rest/thumbnail/thumb.png' },
381
- }),
382
- );
383
- // Updates the main entity
384
- expect(mockEntitiesUpdate).toHaveBeenCalledWith(
385
- expect.objectContaining({
386
- entityName: 'color',
387
- id: 'entity1',
388
- }),
389
- );
390
- });
391
-
392
- it('encodes URL path segments with special characters', async () => {
393
- const mockResponse = {
394
- arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
395
- headers: { get: jest.fn().mockReturnValue('image/png') },
396
- };
397
- mockGetRequest.mockResolvedValue(mockResponse);
398
- mockContentCreate.mockResolvedValue({
399
- id: 'c1', contentType: 'image/png', fileName: 'my image.png',
400
- primaryFileUrl: 'https://files/primary.png', largeViewableUrl: null,
401
- mediumLargeViewableUrl: null, mediumViewableUrl: null, smallViewableUrl: null, tinyViewableUrl: null,
402
- });
403
-
404
- const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/my image.png' } };
405
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
406
-
407
- expect(mockGetRequest).toHaveBeenCalledWith({
408
- urlPath: '/rest/thumbnail/my%20image.png',
409
- includeUrlContext: false,
410
- returnFullResponse: true,
411
- });
412
- expect(mockContentCreate).toHaveBeenCalledWith(
413
- expect.objectContaining({ fileName: 'my image.png' }),
414
- );
415
- });
416
-
417
- it('encodes URL path segments with unicode characters', async () => {
418
- const mockResponse = {
419
- arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
420
- headers: { get: jest.fn().mockReturnValue('image/jpeg') },
421
- };
422
- mockGetRequest.mockResolvedValue(mockResponse);
423
- mockContentCreate.mockResolvedValue({
424
- id: 'c2', contentType: 'image/jpeg', fileName: 'café-logo.jpg',
425
- primaryFileUrl: 'https://files/primary.jpg', largeViewableUrl: null,
426
- mediumLargeViewableUrl: null, mediumViewableUrl: null, smallViewableUrl: null, tinyViewableUrl: null,
427
- });
428
-
429
- const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/café-logo.jpg' } };
430
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'item' });
431
-
432
- expect(mockGetRequest).toHaveBeenCalledWith({
433
- urlPath: '/rest/thumbnail/caf%C3%A9-logo.jpg',
434
- includeUrlContext: false,
435
- returnFullResponse: true,
436
- });
437
- expect(mockContentCreate).toHaveBeenCalledWith(
438
- expect.objectContaining({ fileName: 'café-logo.jpg' }),
439
- );
440
- });
441
-
442
- it('replaces content when primaryViewable.flexplmThumbnailUrl differs and updates entity', async () => {
443
- mockEntitiesGet.mockImplementation((opts) => {
444
- if (opts.entityName === 'content-custom-size') return Promise.resolve([]);
445
- if (opts.entityName === 'content' && opts.id === 'oldPv') {
446
- return Promise.resolve({ id: 'oldPv', flexplmThumbnailUrl: '/rest/thumbnail/old.png' });
447
- }
448
- return Promise.resolve({});
449
- });
450
-
451
- const mockResponse = {
452
- arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
453
- headers: { get: jest.fn().mockReturnValue('image/jpeg') },
454
- };
455
- mockGetRequest.mockResolvedValue(mockResponse);
456
-
457
- const createdContent = {
458
- id: 'newContent2',
459
- contentType: 'image/jpeg',
460
- fileName: 'new.jpg',
461
- primaryFileUrl: 'https://files/new-primary.jpg',
462
- largeViewableUrl: null,
463
- mediumLargeViewableUrl: null,
464
- mediumViewableUrl: null,
465
- smallViewableUrl: null,
466
- tinyViewableUrl: null,
467
- };
468
- mockContentCreate.mockResolvedValue(createdContent);
469
-
470
- const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/new.jpg' } };
471
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'oldPv', event, entityName: 'item' });
472
-
473
- // Creates new content
474
- expect(mockContentCreate).toHaveBeenCalled();
475
- // Updates new content with flexplmThumbnailUrl
476
- expect(mockEntitiesUpdate).toHaveBeenCalledWith(
477
- expect.objectContaining({
478
- entityName: 'content',
479
- id: 'newContent2',
480
- object: { flexplmThumbnailUrl: '/rest/thumbnail/new.jpg' },
481
- }),
482
- );
483
- // Updates the main entity
484
- expect(mockEntitiesUpdate).toHaveBeenCalledWith(
485
- expect.objectContaining({ entityName: 'item', id: 'entity1' }),
486
- );
487
- // Deletes old content
488
- expect(mockEntitiesDelete).toHaveBeenCalledWith({ entityName: 'content', id: 'oldPv' });
489
- });
490
-
491
- it('does not update when primaryViewable.flexplmThumbnailUrl matches', async () => {
492
- const thumbnailUrl = '/rest/thumbnail/same.png';
493
- mockEntitiesGet.mockImplementation((opts) => {
494
- if (opts.entityName === 'content-custom-size') return Promise.resolve([]);
495
- if (opts.entityName === 'content' && opts.id === 'pv1') {
496
- return Promise.resolve({ id: 'pv1', flexplmThumbnailUrl: thumbnailUrl });
497
- }
498
- return Promise.resolve({});
499
- });
500
-
501
- const event = { data: { [ThumbnailUtil.EXISTING_THUMBNAIL_ID]: thumbnailUrl } };
502
- await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'pv1', event, entityName: 'color' });
503
- expect(mockContentCreate).not.toHaveBeenCalled();
504
- expect(mockEntitiesUpdate).not.toHaveBeenCalled();
505
- expect(mockEntitiesDelete).not.toHaveBeenCalled();
506
- });
507
- });
508
- });