@contrail/flexplm 1.7.1 → 1.7.2-alpha.855d28b

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.
@@ -80,7 +80,15 @@ export declare abstract class BaseEntityProcessor {
80
80
  getRootTypePropertyKeys(rootType: any, propertyCriteria?: any): string[];
81
81
  handleIncomingDelete(event: any): Promise<void>;
82
82
  getTransformedData(event: any): Promise<any>;
83
- getUpdatesForEntity(entity: any, inboundData: any): Promise<object>;
83
+ /** Builds the updates that should be applied to the vibe entity based on the
84
+ * inbound data and the original event data.
85
+ *
86
+ * @param entity: the vibe entity that is being updated
87
+ * @param inboundData: the data that was transformed from the flexplm event
88
+ * @param eventData: the original event data from flexplm
89
+ * @returns: the updates that should be applied to the vibe entity
90
+ */
91
+ getUpdatesForEntity(entity: any, inboundData: any, eventData?: any): Promise<object>;
84
92
  getVibeOwningKeys(entity: any): Promise<any[]>;
85
93
  getVibeOwningKeysFromInbound(entity: any): Promise<any[]>;
86
94
  createEntity(entityName: any, changes: any): Promise<any>;
@@ -85,7 +85,7 @@ class BaseEntityProcessor {
85
85
  console.log(statusMsg);
86
86
  return createdEntity;
87
87
  }
88
- const diffs = await this.getUpdatesForEntity(entity, inboundData);
88
+ const diffs = await this.getUpdatesForEntity(entity, inboundData, event.data);
89
89
  const shouldSyncThumbnail = await type_conversion_utils_1.TypeConversionUtils.syncInboundImages(this.transformMapFile, this.mapFileUtil, event.data);
90
90
  let thumbnailEntity;
91
91
  if (shouldSyncThumbnail) {
@@ -278,7 +278,15 @@ class BaseEntityProcessor {
278
278
  console.debug('Transformed-inboundData: ' + JSON.stringify(inboundData));
279
279
  return inboundData;
280
280
  }
281
- async getUpdatesForEntity(entity, inboundData) {
281
+ /** Builds the updates that should be applied to the vibe entity based on the
282
+ * inbound data and the original event data.
283
+ *
284
+ * @param entity: the vibe entity that is being updated
285
+ * @param inboundData: the data that was transformed from the flexplm event
286
+ * @param eventData: the original event data from flexplm
287
+ * @returns: the updates that should be applied to the vibe entity
288
+ */
289
+ async getUpdatesForEntity(entity, inboundData, eventData = null) {
282
290
  const vibeOwningKeys = await this.getVibeOwningKeys(entity);
283
291
  let updates = {
284
292
  typeId: entity.typeId,
@@ -9,6 +9,7 @@ export declare class ThumbnailUtil {
9
9
  /** The max_thumbnail_size is for limiting the size of the thumbnail being sent to FlexPLM. It is used when checking the size of the auto generated thumbnails (smallViewable, tinyViewable, etc.). */
10
10
  private max_thumbnail_size;
11
11
  private entities;
12
+ static THUMBNAIL: string;
12
13
  static NEW_THUMBNAIL_ID: string;
13
14
  static EXISTING_THUMBNAIL_ID: string;
14
15
  static REMOVE_THUMBNAIL: string;
@@ -136,9 +136,10 @@ class ThumbnailUtil {
136
136
  const eventData = event.data || {};
137
137
  const newThumbnailId = eventData[ThumbnailUtil.NEW_THUMBNAIL_ID];
138
138
  const existingThumbnailId = eventData[ThumbnailUtil.EXISTING_THUMBNAIL_ID];
139
- const thumbnailUrl = newThumbnailId || existingThumbnailId;
139
+ const iteratedThumbnailId = eventData[ThumbnailUtil.THUMBNAIL];
140
+ const thumbnailUrl = iteratedThumbnailId || newThumbnailId || existingThumbnailId;
140
141
  // Case 1: REMOVE_THUMBNAIL
141
- if (newThumbnailId === ThumbnailUtil.REMOVE_THUMBNAIL) {
142
+ if (thumbnailUrl === ThumbnailUtil.REMOVE_THUMBNAIL) {
142
143
  if (primaryViewableId) {
143
144
  await this.entities.delete({ entityName: 'content', id: primaryViewableId });
144
145
  }
@@ -236,6 +237,8 @@ class ThumbnailUtil {
236
237
  }
237
238
  }
238
239
  exports.ThumbnailUtil = ThumbnailUtil;
240
+ // Adding Thumbnail property
241
+ ThumbnailUtil.THUMBNAIL = 'THUMBNAIL';
239
242
  ThumbnailUtil.NEW_THUMBNAIL_ID = 'NEW_THUMBNAIL_ID';
240
243
  ThumbnailUtil.EXISTING_THUMBNAIL_ID = 'EXISTING_THUMBNAIL_ID';
241
244
  ThumbnailUtil.REMOVE_THUMBNAIL = 'REMOVE_THUMBNAIL';
@@ -437,4 +437,94 @@ describe('ThumbnailUtil Tests', () => {
437
437
  expect(mockEntitiesDelete).not.toHaveBeenCalled();
438
438
  });
439
439
  });
440
+ describe('ThumbnailUtil - iteratedThumbnailId (THUMBNAIL key)', () => {
441
+ const config = {};
442
+ let tu;
443
+ beforeEach(() => {
444
+ jest.clearAllMocks();
445
+ tu = new thumbnail_util_1.ThumbnailUtil(config);
446
+ mockEntitiesGet.mockImplementation((opts) => {
447
+ if (opts.entityName === 'content-custom-size')
448
+ return Promise.resolve([]);
449
+ return Promise.resolve({});
450
+ });
451
+ mockEntitiesUpdate.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
452
+ mockEntitiesDelete.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
453
+ });
454
+ it('does not break when THUMBNAIL value is not available in the event', async () => {
455
+ // No THUMBNAIL key (and no other thumbnail keys) -> iteratedThumbnailId is undefined
456
+ const event = { data: {} };
457
+ let result;
458
+ await expect((async () => {
459
+ result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
460
+ })()).resolves.not.toThrow();
461
+ // Falls through to the "no thumbnail URL" early return
462
+ expect(result).toBeUndefined();
463
+ expect(mockContentCreate).not.toHaveBeenCalled();
464
+ expect(mockEntitiesUpdate).not.toHaveBeenCalled();
465
+ expect(mockEntitiesDelete).not.toHaveBeenCalled();
466
+ });
467
+ it('does not break when THUMBNAIL key is present but explicitly empty/falsy', async () => {
468
+ // THUMBNAIL present but falsy -> iteratedThumbnailId is falsy, no crash
469
+ const event = { data: { [thumbnail_util_1.ThumbnailUtil.THUMBNAIL]: '' } };
470
+ let result;
471
+ await expect((async () => {
472
+ result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'item' });
473
+ })()).resolves.not.toThrow();
474
+ expect(result).toBeUndefined();
475
+ expect(mockContentCreate).not.toHaveBeenCalled();
476
+ expect(mockEntitiesUpdate).not.toHaveBeenCalled();
477
+ expect(mockEntitiesDelete).not.toHaveBeenCalled();
478
+ });
479
+ it('syncs using iteratedThumbnailId when a THUMBNAIL value is available (no existing primaryViewable)', async () => {
480
+ const mockResponse = {
481
+ arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
482
+ headers: { get: jest.fn().mockReturnValue('image/png') },
483
+ };
484
+ mockGetRequest.mockResolvedValue(mockResponse);
485
+ const createdContent = {
486
+ id: 'iteratedContent1',
487
+ contentType: 'image/png',
488
+ fileName: 'iterated.png',
489
+ primaryFileUrl: 'https://files/primary.png',
490
+ largeViewableUrl: 'https://files/large.png',
491
+ mediumLargeViewableUrl: null,
492
+ mediumViewableUrl: null,
493
+ smallViewableUrl: null,
494
+ tinyViewableUrl: null,
495
+ };
496
+ mockContentCreate.mockResolvedValue(createdContent);
497
+ const thumbnailUrl = '/rest/thumbnail/iterated.png';
498
+ const event = { data: { [thumbnail_util_1.ThumbnailUtil.THUMBNAIL]: thumbnailUrl } };
499
+ await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
500
+ // Uses the THUMBNAIL value to fetch + create the content
501
+ expect(mockGetRequest).toHaveBeenCalledWith({
502
+ urlPath: thumbnailUrl,
503
+ includeUrlContext: false,
504
+ returnFullResponse: true,
505
+ });
506
+ expect(mockContentCreate).toHaveBeenCalledWith(expect.objectContaining({
507
+ fileName: 'iterated.png',
508
+ contentType: 'image/png',
509
+ contentHolderReference: 'color:entity1',
510
+ }));
511
+ // Stamps the content with the THUMBNAIL url
512
+ expect(mockEntitiesUpdate).toHaveBeenCalledWith(expect.objectContaining({
513
+ entityName: 'content',
514
+ id: 'iteratedContent1',
515
+ object: { flexplmThumbnailUrl: thumbnailUrl },
516
+ }));
517
+ // Updates the main entity
518
+ expect(mockEntitiesUpdate).toHaveBeenCalledWith(expect.objectContaining({ entityName: 'color', id: 'entity1' }));
519
+ });
520
+ it('REMOVE_THUMBNAIL via the THUMBNAIL key deletes content and clears the entity', async () => {
521
+ const event = { data: { [thumbnail_util_1.ThumbnailUtil.THUMBNAIL]: thumbnail_util_1.ThumbnailUtil.REMOVE_THUMBNAIL } };
522
+ await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'pv1', event, entityName: 'color' });
523
+ // Resolves REMOVE_THUMBNAIL from the THUMBNAIL key and removes the existing content
524
+ expect(mockEntitiesDelete).toHaveBeenCalledWith({ entityName: 'content', id: 'pv1' });
525
+ expect(mockEntitiesUpdate).toHaveBeenCalledWith(expect.objectContaining({ entityName: 'color', id: 'entity1' }));
526
+ // Does not create replacement content
527
+ expect(mockContentCreate).not.toHaveBeenCalled();
528
+ });
529
+ });
440
530
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/flexplm",
3
- "version": "1.7.1",
3
+ "version": "1.7.2-alpha.855d28b",
4
4
  "description": "Library used for integration with flexplm.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",