@contrail/flexplm 1.1.37 → 1.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/entity-processor/base-entity-processor.d.ts +0 -3
- package/lib/entity-processor/base-entity-processor.js +0 -35
- package/lib/publish/base-process-publish-assortment.d.ts +3 -0
- package/lib/publish/base-process-publish-assortment.js +38 -15
- package/lib/publish/base-process-publish-assortment.spec.js +153 -0
- package/lib/util/config-defaults.js +3 -0
- package/lib/util/config-defaults.spec.js +26 -0
- package/package.json +3 -2
- package/src/entity-processor/base-entity-processor.ts +0 -55
- package/src/publish/base-process-publish-assortment.spec.ts +168 -0
- package/src/publish/base-process-publish-assortment.ts +45 -14
- package/src/util/config-defaults.spec.ts +31 -0
- package/src/util/config-defaults.ts +2 -0
- package/src/util/thumbnail-util.ts +0 -4
|
@@ -31,7 +31,4 @@ export declare abstract class BaseEntityProcessor {
|
|
|
31
31
|
getOutboundEntityUpdates(event: any, flexResponse: any): Promise<any>;
|
|
32
32
|
handleOutgoingDelete(entityType: any, event: any): Promise<void>;
|
|
33
33
|
protected abstract getOutgoingUpsertPayload(entityType: any, event: any): Promise<EntityPayloadType>;
|
|
34
|
-
protected triggerSendEvent(triggerKey: string, event: any): Promise<any>;
|
|
35
|
-
protected sendUpsertToFlexPLM(event: any): Promise<any>;
|
|
36
|
-
protected getEntityUpsertPayload(event: any): Promise<EntityPayloadType>;
|
|
37
34
|
}
|
|
@@ -133,8 +133,6 @@ class BaseEntityProcessor {
|
|
|
133
133
|
return await this.handleOutgoingUpsert(entityType, event);
|
|
134
134
|
case 'delete':
|
|
135
135
|
return await this.handleOutgoingDelete(entityType, event);
|
|
136
|
-
case 'sendUpsertToFlexPLM':
|
|
137
|
-
return await this.sendUpsertToFlexPLM(event);
|
|
138
136
|
default:
|
|
139
137
|
console.log(UNSUPPORTED_TYPE);
|
|
140
138
|
return {
|
|
@@ -173,38 +171,5 @@ class BaseEntityProcessor {
|
|
|
173
171
|
async handleOutgoingDelete(entityType, event) {
|
|
174
172
|
console.warn('delete is not configured', entityType, event.oldData);
|
|
175
173
|
}
|
|
176
|
-
async triggerSendEvent(triggerKey, event) {
|
|
177
|
-
const newEvent = {
|
|
178
|
-
entityName: 'event-workflow-request',
|
|
179
|
-
object: {
|
|
180
|
-
triggerKey,
|
|
181
|
-
event
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
const response = await this.entities.create(newEvent);
|
|
185
|
-
return response;
|
|
186
|
-
}
|
|
187
|
-
async sendUpsertToFlexPLM(event) {
|
|
188
|
-
const payload = await this.getEntityUpsertPayload(event);
|
|
189
|
-
if (!payload) {
|
|
190
|
-
const message = 'No payload to send to FlexPLM';
|
|
191
|
-
console.log(message);
|
|
192
|
-
return {
|
|
193
|
-
status: 500,
|
|
194
|
-
data: { message }
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
;
|
|
198
|
-
const flexResponse = await new flexplm_connect_1.FlexPLMConnect(this.config).sendToFlexPLM(payload);
|
|
199
|
-
const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
|
|
200
|
-
if (outboundEntityUpdates) {
|
|
201
|
-
flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
|
|
202
|
-
}
|
|
203
|
-
return flexResponse;
|
|
204
|
-
}
|
|
205
|
-
async getEntityUpsertPayload(event) {
|
|
206
|
-
console.warn('getEntityUpsertPayload is not configured', JSON.stringify(event));
|
|
207
|
-
return undefined;
|
|
208
|
-
}
|
|
209
174
|
}
|
|
210
175
|
exports.BaseEntityProcessor = BaseEntityProcessor;
|
|
@@ -13,6 +13,7 @@ export declare class BaseProcessPublishAssortment {
|
|
|
13
13
|
private mapFileUtil;
|
|
14
14
|
private transformMapFile;
|
|
15
15
|
private cache;
|
|
16
|
+
private assortment;
|
|
16
17
|
constructor(_config: FCConfig, _dc: DataConverter, _mapFileUtil: MapFileUtil);
|
|
17
18
|
process(event: any): Promise<{
|
|
18
19
|
results: {
|
|
@@ -23,7 +24,9 @@ export declare class BaseProcessPublishAssortment {
|
|
|
23
24
|
results: any;
|
|
24
25
|
skip_await?: undefined;
|
|
25
26
|
}>;
|
|
27
|
+
getPublishInfo(assortmentPublishChangeId: any, apcHistory: any, publisher: any): Promise<any>;
|
|
26
28
|
getSeasonFederation(assortmentId: any): Promise<SeasonFederation>;
|
|
29
|
+
getAssortment(assortmentId: any): Promise<any>;
|
|
27
30
|
getSinceDate(assortmentId: any, assortmentPublishChangeId: any, apcHistory: object[]): Promise<Date>;
|
|
28
31
|
getApcHistory(assortmentId: any): Promise<any>;
|
|
29
32
|
protected updatedSinceDate(entity: any, sinceDate: Date): boolean;
|
|
@@ -22,6 +22,9 @@ class BaseProcessPublishAssortment {
|
|
|
22
22
|
this.transformMapFile = this.config['transformMapFile'];
|
|
23
23
|
}
|
|
24
24
|
async process(event) {
|
|
25
|
+
const assortmentPublishChangeId = event.assortmentPublishChangeId;
|
|
26
|
+
let apcHistory;
|
|
27
|
+
let publisher;
|
|
25
28
|
try {
|
|
26
29
|
console.info('process-start!');
|
|
27
30
|
const assortmentId = event.assortmentId;
|
|
@@ -38,40 +41,50 @@ class BaseProcessPublishAssortment {
|
|
|
38
41
|
};
|
|
39
42
|
return output;
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
const apcHistory = await this.getApcHistory(assortmentId);
|
|
44
|
+
apcHistory = await this.getApcHistory(assortmentId);
|
|
43
45
|
const sinceDate = await this.getSinceDate(assortmentId, assortmentPublishChangeId, apcHistory);
|
|
44
46
|
const assortmentPublishChange = await this.downloadAssortmentPublishChange(assortmentId, assortmentPublishChangeId);
|
|
47
|
+
publisher = this.getPublisher(assortmentPublishChange);
|
|
45
48
|
const changeDetail = await this.downloadHydratedChangeDetail(assortmentPublishChange);
|
|
46
49
|
const assortmentBaseline = await this.downloadAssortmentBaseline(assortmentPublishChange);
|
|
47
50
|
const deleteChanges = await this.getDeleteChanges(assortmentPublishChange, apcHistory, assortmentBaseline, sinceDate);
|
|
48
51
|
const releasedForDevelopmentItemIds = this.getReleasedForDevelopmentItemAndFamilyIds(assortmentBaseline, deleteChanges);
|
|
49
52
|
const itemToFederatedIdMapping = await this.getItemFederatedIds();
|
|
50
|
-
const publisher = this.getPublisher(assortmentPublishChange);
|
|
51
53
|
const pcd = new publish_change_data_1.PublishChangeData(assortmentId, seasonFed, assortmentPublishChangeId, sinceDate, publisher);
|
|
52
54
|
pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
|
|
53
55
|
pcd.releasedForDevelopmentItemIds = releasedForDevelopmentItemIds;
|
|
54
56
|
const output = await this.processPublish(pcd, changeDetail, assortmentBaseline, deleteChanges);
|
|
57
|
+
output['publishInfo'] = await this.getPublishInfo(assortmentPublishChangeId, apcHistory, publisher);
|
|
55
58
|
console.info('process-end');
|
|
56
59
|
return output;
|
|
57
60
|
}
|
|
58
61
|
catch (e) {
|
|
62
|
+
try {
|
|
63
|
+
const publishInfo = await this.getPublishInfo(assortmentPublishChangeId, apcHistory, publisher);
|
|
64
|
+
e.publishInfo = publishInfo;
|
|
65
|
+
}
|
|
66
|
+
catch (e2) {
|
|
67
|
+
console.log('catch e2: ' + e2.message);
|
|
68
|
+
}
|
|
59
69
|
console.log('catch e: ' + e.message);
|
|
60
70
|
throw e;
|
|
61
71
|
}
|
|
62
72
|
}
|
|
73
|
+
async getPublishInfo(assortmentPublishChangeId, apcHistory, publisher) {
|
|
74
|
+
const apc = apcHistory?.find(apc => apc?.id === assortmentPublishChangeId) || {};
|
|
75
|
+
const assortmentName = (await this.getAssortment(assortmentPublishChangeId))?.name;
|
|
76
|
+
const publishInfo = {
|
|
77
|
+
assortmentName,
|
|
78
|
+
versionName: apc?.versionName,
|
|
79
|
+
versionComments: apc?.versionComments,
|
|
80
|
+
publishDate: apc?.createdOn,
|
|
81
|
+
publisher
|
|
82
|
+
};
|
|
83
|
+
return publishInfo;
|
|
84
|
+
}
|
|
63
85
|
async getSeasonFederation(assortmentId) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
assortment = await new sdk_1.Entities().get({
|
|
67
|
-
entityName: 'assortment',
|
|
68
|
-
id: assortmentId
|
|
69
|
-
});
|
|
70
|
-
console.info('assortment-name: ' + assortment['name']);
|
|
71
|
-
}
|
|
72
|
-
catch (e) {
|
|
73
|
-
console.warn(`No Assortment found for id: ${assortmentId}`);
|
|
74
|
-
}
|
|
86
|
+
const assortment = await this.getAssortment(assortmentId);
|
|
87
|
+
console.error('assortment-name: ' + assortment?.name);
|
|
75
88
|
const publishToFlexPLM = assortment?.publishToFlexPLM;
|
|
76
89
|
if (!publishToFlexPLM) {
|
|
77
90
|
throw new Error(BaseProcessPublishAssortment.ASSORTMENT_NOT_PUBLISHABLE);
|
|
@@ -95,6 +108,16 @@ class BaseProcessPublishAssortment {
|
|
|
95
108
|
seasonObj = await map_utils_1.MapUtil.applyTransformMap(this.transformMapFile, this.mapFileUtil, seasonObj, 'LCSSeason', 'vibe2flex');
|
|
96
109
|
return seasonObj;
|
|
97
110
|
}
|
|
111
|
+
async getAssortment(assortmentId) {
|
|
112
|
+
if (this.assortment != undefined) {
|
|
113
|
+
return this.assortment;
|
|
114
|
+
}
|
|
115
|
+
this.assortment = await new sdk_1.Entities().get({
|
|
116
|
+
entityName: 'assortment',
|
|
117
|
+
id: assortmentId
|
|
118
|
+
});
|
|
119
|
+
return this.assortment;
|
|
120
|
+
}
|
|
98
121
|
async getSinceDate(assortmentId, assortmentPublishChangeId, apcHistory) {
|
|
99
122
|
let sinceDate = null;
|
|
100
123
|
let pastPublishCount = 1;
|
|
@@ -226,7 +249,7 @@ class BaseProcessPublishAssortment {
|
|
|
226
249
|
return publisher;
|
|
227
250
|
}
|
|
228
251
|
async downloadAssortmentPublishChange(assortmentId, assortmentPublishChangeId) {
|
|
229
|
-
const resourceString = '/assortments/' + assortmentId + '/history/' + assortmentPublishChangeId;
|
|
252
|
+
const resourceString = '/assortments/' + assortmentId + '/history/' + assortmentPublishChangeId + '?relations=createdBy';
|
|
230
253
|
return await sdk_1.Request.request(resourceString, {
|
|
231
254
|
method: 'GET',
|
|
232
255
|
Headers: {
|
|
@@ -57,6 +57,159 @@ describe('process publish assortment', () => {
|
|
|
57
57
|
expect(results['results']['message']).toEqual(base_process_publish_assortment_1.BaseProcessPublishAssortment.ASSORTMENT_NO_FED_INFO + config.identifierAtts.LCSSeason);
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
|
+
describe('getPublishInfo', () => {
|
|
61
|
+
const config = {};
|
|
62
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
63
|
+
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
64
|
+
const versionName = 'Version 1';
|
|
65
|
+
const versionComments = 'Some Comments';
|
|
66
|
+
const createdOn = '2023-01-15T19:13:58.902Z';
|
|
67
|
+
const plan_history = [
|
|
68
|
+
{
|
|
69
|
+
id: 'sJbGx1Fpq1v2MmcI',
|
|
70
|
+
versionName,
|
|
71
|
+
versionComments,
|
|
72
|
+
createdOn
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
it('All Publish Info', async () => {
|
|
76
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
77
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
78
|
+
const publisher = {
|
|
79
|
+
email: 'chris@vibeiq.com'
|
|
80
|
+
};
|
|
81
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
82
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
83
|
+
.mockImplementation(async (assortmentId) => {
|
|
84
|
+
return { id: assortmentId, name: assortmentName };
|
|
85
|
+
});
|
|
86
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
87
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
88
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
89
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
90
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
91
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
92
|
+
spy.mockRestore();
|
|
93
|
+
});
|
|
94
|
+
it('No Assortment Name', async () => {
|
|
95
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
96
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
97
|
+
const publisher = {
|
|
98
|
+
email: 'chris@vibeiq.com'
|
|
99
|
+
};
|
|
100
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
101
|
+
.mockImplementation(async (assortmentId) => {
|
|
102
|
+
return { id: assortmentId, name: undefined };
|
|
103
|
+
});
|
|
104
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
105
|
+
expect(publishInfo.assortmentName).toBeUndefined;
|
|
106
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
107
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
108
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
109
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
110
|
+
spy.mockRestore();
|
|
111
|
+
});
|
|
112
|
+
it('No Assortment', async () => {
|
|
113
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
114
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
115
|
+
const publisher = {
|
|
116
|
+
email: 'chris@vibeiq.com'
|
|
117
|
+
};
|
|
118
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
119
|
+
.mockImplementation(async (assortmentId) => {
|
|
120
|
+
return undefined;
|
|
121
|
+
});
|
|
122
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
123
|
+
expect(publishInfo.assortmentName).toBeUndefined();
|
|
124
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
125
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
126
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
127
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
128
|
+
spy.mockRestore();
|
|
129
|
+
});
|
|
130
|
+
it('Empty Version Name & Comments', async () => {
|
|
131
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
132
|
+
const history = [
|
|
133
|
+
{
|
|
134
|
+
id: 'sJbGx1Fpq1v2MmcI',
|
|
135
|
+
versionName: '',
|
|
136
|
+
versionComments: '',
|
|
137
|
+
createdOn
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
141
|
+
const publisher = {
|
|
142
|
+
email: 'chris@vibeiq.com'
|
|
143
|
+
};
|
|
144
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
145
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
146
|
+
.mockImplementation(async (assortmentId) => {
|
|
147
|
+
return { id: assortmentId, name: assortmentName };
|
|
148
|
+
});
|
|
149
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, history, publisher);
|
|
150
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
151
|
+
expect(publishInfo.versionName).toEqual('');
|
|
152
|
+
expect(publishInfo.versionComments).toEqual('');
|
|
153
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
154
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
155
|
+
spy.mockRestore();
|
|
156
|
+
});
|
|
157
|
+
it('Undefined Publisher', async () => {
|
|
158
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
159
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
160
|
+
const publisher = undefined;
|
|
161
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
162
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
163
|
+
.mockImplementation(async (assortmentId) => {
|
|
164
|
+
return { id: assortmentId, name: assortmentName };
|
|
165
|
+
});
|
|
166
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
167
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
168
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
169
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
170
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
171
|
+
expect(publishInfo.publisher).toBeUndefined();
|
|
172
|
+
spy.mockRestore();
|
|
173
|
+
});
|
|
174
|
+
it('No APC', async () => {
|
|
175
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
176
|
+
const assortmentPublishChangeId = 'bad-id';
|
|
177
|
+
const publisher = {
|
|
178
|
+
email: 'chris@vibeiq.com'
|
|
179
|
+
};
|
|
180
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
181
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
182
|
+
.mockImplementation(async (assortmentId) => {
|
|
183
|
+
return { id: assortmentId, name: assortmentName };
|
|
184
|
+
});
|
|
185
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
186
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
187
|
+
expect(publishInfo.versionName).toBeUndefined();
|
|
188
|
+
expect(publishInfo.versionComments).toBeUndefined();
|
|
189
|
+
expect(publishInfo.publishDate).toBeUndefined();
|
|
190
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
191
|
+
spy.mockRestore();
|
|
192
|
+
});
|
|
193
|
+
it('No APC history', async () => {
|
|
194
|
+
const ppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
195
|
+
const assortmentPublishChangeId = 'bad-id';
|
|
196
|
+
const publisher = {
|
|
197
|
+
email: 'chris@vibeiq.com'
|
|
198
|
+
};
|
|
199
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
200
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
201
|
+
.mockImplementation(async (assortmentId) => {
|
|
202
|
+
return { id: assortmentId, name: assortmentName };
|
|
203
|
+
});
|
|
204
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, undefined, publisher);
|
|
205
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
206
|
+
expect(publishInfo.versionName).toBeUndefined();
|
|
207
|
+
expect(publishInfo.versionComments).toBeUndefined();
|
|
208
|
+
expect(publishInfo.publishDate).toBeUndefined();
|
|
209
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
210
|
+
spy.mockRestore();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
60
213
|
describe('getSeasonFederation', () => {
|
|
61
214
|
const config = {
|
|
62
215
|
identifierAtts: {
|
|
@@ -11,6 +11,9 @@ class ConfigDefaults {
|
|
|
11
11
|
if (config?.itemPreDevelopmentLifecycleStages && !(config?.itemPreDevelopmentLifecycleStages instanceof Array)) {
|
|
12
12
|
config.itemPreDevelopmentLifecycleStages = config.itemPreDevelopmentLifecycleStages.split(',');
|
|
13
13
|
}
|
|
14
|
+
else if (Object.keys(config).includes('itemPreDevelopmentLifecycleStages')) {
|
|
15
|
+
delete config['itemPreDevelopmentLifecycleStages'];
|
|
16
|
+
}
|
|
14
17
|
const defaultConfig = {
|
|
15
18
|
urlContext: '/Windchill',
|
|
16
19
|
sendMode: {
|
|
@@ -159,6 +159,32 @@ describe('all tests', () => {
|
|
|
159
159
|
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
160
160
|
expect(itemPreDevelopmentLifecycleStages.includes(development));
|
|
161
161
|
});
|
|
162
|
+
it('itemPreDevelopmentLifecycleStages as empty string', async () => {
|
|
163
|
+
console.log('itemPreDevelopmentLifecycleStages as empty string');
|
|
164
|
+
const concept = 'concept';
|
|
165
|
+
const startConfig = Object.assign({}, config);
|
|
166
|
+
startConfig['itemPreDevelopmentLifecycleStages'] = '';
|
|
167
|
+
console.log('startConfig: ' + JSON.stringify(startConfig));
|
|
168
|
+
const fcConfig = await config_defaults_1.ConfigDefaults.setConfigDefaults(startConfig);
|
|
169
|
+
console.log('fcConfig: ' + JSON.stringify(fcConfig));
|
|
170
|
+
const itemPreDevelopmentLifecycleStages = fcConfig['itemPreDevelopmentLifecycleStages'];
|
|
171
|
+
expect(itemPreDevelopmentLifecycleStages instanceof Array).toBeTruthy();
|
|
172
|
+
expect(itemPreDevelopmentLifecycleStages.length).toBe(1);
|
|
173
|
+
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
174
|
+
});
|
|
175
|
+
it('itemPreDevelopmentLifecycleStages as empty array', async () => {
|
|
176
|
+
console.log('itemPreDevelopmentLifecycleStages as empty string');
|
|
177
|
+
const concept = 'concept';
|
|
178
|
+
const startConfig = Object.assign({}, config);
|
|
179
|
+
startConfig['itemPreDevelopmentLifecycleStages'] = [];
|
|
180
|
+
console.log('startConfig: ' + JSON.stringify(startConfig));
|
|
181
|
+
const fcConfig = await config_defaults_1.ConfigDefaults.setConfigDefaults(startConfig);
|
|
182
|
+
console.log('fcConfig: ' + JSON.stringify(fcConfig));
|
|
183
|
+
const itemPreDevelopmentLifecycleStages = fcConfig['itemPreDevelopmentLifecycleStages'];
|
|
184
|
+
expect(itemPreDevelopmentLifecycleStages instanceof Array).toBeTruthy();
|
|
185
|
+
expect(itemPreDevelopmentLifecycleStages.length).toBe(1);
|
|
186
|
+
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
187
|
+
});
|
|
162
188
|
it('identifierAtts-LCSProduct-get default', async () => {
|
|
163
189
|
const startConfig = Object.assign({}, config);
|
|
164
190
|
const objectClass = 'LCSProduct';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrail/flexplm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.39",
|
|
4
4
|
"description": "Library used for integration with flexplm.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
|
|
10
10
|
"lint": "tslint -p tsconfig.json",
|
|
11
11
|
"test": "jest",
|
|
12
|
-
"test-watch": "jest --watch"
|
|
12
|
+
"test-watch": "jest --watch",
|
|
13
|
+
"test-debug": "jest --runInBand"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [],
|
|
15
16
|
"author": "",
|
|
@@ -176,8 +176,6 @@ export abstract class BaseEntityProcessor {
|
|
|
176
176
|
return await this.handleOutgoingUpsert(entityType, event);
|
|
177
177
|
case 'delete':
|
|
178
178
|
return await this.handleOutgoingDelete(entityType, event);
|
|
179
|
-
case 'sendUpsertToFlexPLM':
|
|
180
|
-
return await this.sendUpsertToFlexPLM(event);
|
|
181
179
|
default:
|
|
182
180
|
console.log(UNSUPPORTED_TYPE);
|
|
183
181
|
return {
|
|
@@ -225,57 +223,4 @@ export abstract class BaseEntityProcessor {
|
|
|
225
223
|
|
|
226
224
|
// This method must be implemented by derived classes
|
|
227
225
|
protected abstract getOutgoingUpsertPayload(entityType, event): Promise<EntityPayloadType>;
|
|
228
|
-
|
|
229
|
-
/** Create a new event-workflow-request to rerun sending the entity to FlexPLM
|
|
230
|
-
* The event must contain any information needed to ensure it is put in the correct queue for the entity
|
|
231
|
-
*
|
|
232
|
-
* @param triggerKey Ex: event.entityType + '|sendUpsertToFlexPLM'
|
|
233
|
-
* @param event
|
|
234
|
-
* @returns
|
|
235
|
-
*/
|
|
236
|
-
|
|
237
|
-
protected async triggerSendEvent(triggerKey: string, event: any) {
|
|
238
|
-
const newEvent = {
|
|
239
|
-
entityName: 'event-workflow-request',
|
|
240
|
-
object: {
|
|
241
|
-
triggerKey,
|
|
242
|
-
event
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
const response = await this.entities.create(newEvent);
|
|
246
|
-
|
|
247
|
-
return response;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/** Sends the current state of the entity to FlexPLM.
|
|
251
|
-
* So any changes made in Vibe between the event being generated and the event being processed are sent to FlexPLM.
|
|
252
|
-
*
|
|
253
|
-
* @param event must contain entityType, id; which are used to query for the entity
|
|
254
|
-
* @returns results of sending the entity to FlexPLM
|
|
255
|
-
*/
|
|
256
|
-
protected async sendUpsertToFlexPLM(event) {
|
|
257
|
-
const payload = await this.getEntityUpsertPayload(event);
|
|
258
|
-
if(!payload){
|
|
259
|
-
const message = 'No payload to send to FlexPLM';
|
|
260
|
-
console.log(message);
|
|
261
|
-
return {
|
|
262
|
-
status: 500,
|
|
263
|
-
data: {message}
|
|
264
|
-
};
|
|
265
|
-
};
|
|
266
|
-
const flexResponse: any = await new FlexPLMConnect(this.config).sendToFlexPLM(payload);
|
|
267
|
-
|
|
268
|
-
const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
|
|
269
|
-
if(outboundEntityUpdates){
|
|
270
|
-
flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return flexResponse;
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
protected async getEntityUpsertPayload(event: any): Promise<EntityPayloadType> {
|
|
278
|
-
console.warn('getEntityUpsertPayload is not configured', JSON.stringify(event));
|
|
279
|
-
return undefined;
|
|
280
|
-
}
|
|
281
226
|
}
|
|
@@ -60,6 +60,174 @@ describe('process publish assortment', () => {
|
|
|
60
60
|
});
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
describe('getPublishInfo', () =>{
|
|
64
|
+
const config = {} as FCConfig;
|
|
65
|
+
const mapFileUtil = new MapFileUtil(new Entities());
|
|
66
|
+
const dc = new DataConverter(config, mapFileUtil);
|
|
67
|
+
|
|
68
|
+
const versionName = 'Version 1';
|
|
69
|
+
const versionComments = 'Some Comments';
|
|
70
|
+
const createdOn = '2023-01-15T19:13:58.902Z';
|
|
71
|
+
const plan_history = [
|
|
72
|
+
{
|
|
73
|
+
id: 'sJbGx1Fpq1v2MmcI',
|
|
74
|
+
versionName,
|
|
75
|
+
versionComments,
|
|
76
|
+
createdOn
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
];
|
|
80
|
+
it('All Publish Info', async () =>{
|
|
81
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
82
|
+
|
|
83
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
84
|
+
const publisher = {
|
|
85
|
+
email: 'chris@vibeiq.com'
|
|
86
|
+
};
|
|
87
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
88
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
89
|
+
.mockImplementation(async (assortmentId) => {
|
|
90
|
+
return {id: assortmentId, name: assortmentName};
|
|
91
|
+
});
|
|
92
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
93
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
94
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
95
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
96
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
97
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
98
|
+
spy.mockRestore();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('No Assortment Name', async () =>{
|
|
102
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
103
|
+
|
|
104
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
105
|
+
const publisher = {
|
|
106
|
+
email: 'chris@vibeiq.com'
|
|
107
|
+
};
|
|
108
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
109
|
+
.mockImplementation(async (assortmentId) => {
|
|
110
|
+
return {id: assortmentId, name: undefined};
|
|
111
|
+
});
|
|
112
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
113
|
+
expect(publishInfo.assortmentName).toBeUndefined;
|
|
114
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
115
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
116
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
117
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
118
|
+
spy.mockRestore();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('No Assortment', async () =>{
|
|
122
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
123
|
+
|
|
124
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
125
|
+
const publisher = {
|
|
126
|
+
email: 'chris@vibeiq.com'
|
|
127
|
+
};
|
|
128
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
129
|
+
.mockImplementation(async (assortmentId) => {
|
|
130
|
+
return undefined;
|
|
131
|
+
});
|
|
132
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
133
|
+
expect(publishInfo.assortmentName).toBeUndefined();
|
|
134
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
135
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
136
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
137
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
138
|
+
spy.mockRestore();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('Empty Version Name & Comments', async () =>{
|
|
142
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
143
|
+
const history = [
|
|
144
|
+
{
|
|
145
|
+
id: 'sJbGx1Fpq1v2MmcI',
|
|
146
|
+
versionName: '',
|
|
147
|
+
versionComments: '',
|
|
148
|
+
createdOn
|
|
149
|
+
}
|
|
150
|
+
];
|
|
151
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
152
|
+
const publisher = {
|
|
153
|
+
email: 'chris@vibeiq.com'
|
|
154
|
+
};
|
|
155
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
156
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
157
|
+
.mockImplementation(async (assortmentId) => {
|
|
158
|
+
return {id: assortmentId, name: assortmentName};
|
|
159
|
+
});
|
|
160
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, history, publisher);
|
|
161
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
162
|
+
expect(publishInfo.versionName).toEqual('');
|
|
163
|
+
expect(publishInfo.versionComments).toEqual('');
|
|
164
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
165
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
166
|
+
spy.mockRestore();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('Undefined Publisher', async () =>{
|
|
170
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
171
|
+
|
|
172
|
+
const assortmentPublishChangeId = 'sJbGx1Fpq1v2MmcI';
|
|
173
|
+
const publisher = undefined;
|
|
174
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
175
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
176
|
+
.mockImplementation(async (assortmentId) => {
|
|
177
|
+
return {id: assortmentId, name: assortmentName};
|
|
178
|
+
});
|
|
179
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
180
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
181
|
+
expect(publishInfo.versionName).toEqual(versionName);
|
|
182
|
+
expect(publishInfo.versionComments).toEqual(versionComments);
|
|
183
|
+
expect(publishInfo.publishDate).toEqual(createdOn);
|
|
184
|
+
expect(publishInfo.publisher).toBeUndefined();
|
|
185
|
+
spy.mockRestore();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('No APC', async () =>{
|
|
189
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
190
|
+
|
|
191
|
+
const assortmentPublishChangeId = 'bad-id';
|
|
192
|
+
const publisher = {
|
|
193
|
+
email: 'chris@vibeiq.com'
|
|
194
|
+
};
|
|
195
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
196
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
197
|
+
.mockImplementation(async (assortmentId) => {
|
|
198
|
+
return {id: assortmentId, name: assortmentName};
|
|
199
|
+
});
|
|
200
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, plan_history, publisher);
|
|
201
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
202
|
+
expect(publishInfo.versionName).toBeUndefined();
|
|
203
|
+
expect(publishInfo.versionComments).toBeUndefined();
|
|
204
|
+
expect(publishInfo.publishDate).toBeUndefined();
|
|
205
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
206
|
+
spy.mockRestore();
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('No APC history', async () =>{
|
|
210
|
+
const ppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
|
|
211
|
+
|
|
212
|
+
const assortmentPublishChangeId = 'bad-id';
|
|
213
|
+
const publisher = {
|
|
214
|
+
email: 'chris@vibeiq.com'
|
|
215
|
+
};
|
|
216
|
+
const assortmentName = 'VibeIQ Fall 2023';
|
|
217
|
+
const spy = jest.spyOn(ppa, 'getAssortment')
|
|
218
|
+
.mockImplementation(async (assortmentId) => {
|
|
219
|
+
return {id: assortmentId, name: assortmentName};
|
|
220
|
+
});
|
|
221
|
+
const publishInfo = await ppa.getPublishInfo(assortmentPublishChangeId, undefined, publisher);
|
|
222
|
+
expect(publishInfo.assortmentName).toEqual(assortmentName);
|
|
223
|
+
expect(publishInfo.versionName).toBeUndefined();
|
|
224
|
+
expect(publishInfo.versionComments).toBeUndefined();
|
|
225
|
+
expect(publishInfo.publishDate).toBeUndefined();
|
|
226
|
+
expect(publishInfo.publisher).toEqual(publisher);
|
|
227
|
+
spy.mockRestore();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
});
|
|
63
231
|
describe('getSeasonFederation', () => {
|
|
64
232
|
const config = {
|
|
65
233
|
identifierAtts: {
|
|
@@ -25,6 +25,8 @@ export class BaseProcessPublishAssortment {
|
|
|
25
25
|
private cache = {
|
|
26
26
|
carriedFromSeason: {}
|
|
27
27
|
};
|
|
28
|
+
private assortment: any;
|
|
29
|
+
|
|
28
30
|
constructor(_config: FCConfig, _dc: DataConverter, _mapFileUtil: MapFileUtil) {
|
|
29
31
|
this.config = _config;
|
|
30
32
|
this.dc = _dc;
|
|
@@ -33,6 +35,10 @@ export class BaseProcessPublishAssortment {
|
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
public async process(event) {
|
|
38
|
+
|
|
39
|
+
const assortmentPublishChangeId = event.assortmentPublishChangeId;
|
|
40
|
+
let apcHistory;
|
|
41
|
+
let publisher;
|
|
36
42
|
try {
|
|
37
43
|
console.info('process-start!');
|
|
38
44
|
const assortmentId = event.assortmentId;
|
|
@@ -49,12 +55,13 @@ export class BaseProcessPublishAssortment {
|
|
|
49
55
|
return output;
|
|
50
56
|
}
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
apcHistory = await this.getApcHistory(assortmentId);
|
|
59
|
+
|
|
54
60
|
const sinceDate = await this.getSinceDate(assortmentId, assortmentPublishChangeId, apcHistory);
|
|
55
61
|
|
|
56
62
|
//Get detail information
|
|
57
63
|
const assortmentPublishChange = await this.downloadAssortmentPublishChange(assortmentId, assortmentPublishChangeId);
|
|
64
|
+
publisher = this.getPublisher(assortmentPublishChange);
|
|
58
65
|
|
|
59
66
|
const changeDetail = await this.downloadHydratedChangeDetail(assortmentPublishChange);
|
|
60
67
|
|
|
@@ -65,33 +72,45 @@ export class BaseProcessPublishAssortment {
|
|
|
65
72
|
const releasedForDevelopmentItemIds = this.getReleasedForDevelopmentItemAndFamilyIds(assortmentBaseline, deleteChanges);
|
|
66
73
|
const itemToFederatedIdMapping = await this.getItemFederatedIds(/*allItemIds*/);
|
|
67
74
|
|
|
68
|
-
const publisher = this.getPublisher(assortmentPublishChange);
|
|
69
75
|
const pcd = new PublishChangeData(assortmentId, seasonFed, assortmentPublishChangeId, sinceDate, publisher);
|
|
70
76
|
pcd.itemToFederatedIdMapping = itemToFederatedIdMapping;
|
|
71
77
|
|
|
72
78
|
pcd.releasedForDevelopmentItemIds = releasedForDevelopmentItemIds;
|
|
73
79
|
|
|
74
80
|
const output = await this.processPublish(pcd, changeDetail, assortmentBaseline, deleteChanges);
|
|
81
|
+
output ['publishInfo'] = await this.getPublishInfo(assortmentPublishChangeId, apcHistory, publisher);
|
|
75
82
|
console.info('process-end');
|
|
76
83
|
|
|
77
84
|
return output;
|
|
78
85
|
} catch (e) {
|
|
86
|
+
try {
|
|
87
|
+
const publishInfo = await this.getPublishInfo(assortmentPublishChangeId, apcHistory, publisher);
|
|
88
|
+
e.publishInfo = publishInfo;
|
|
89
|
+
}catch(e2){
|
|
90
|
+
console.log('catch e2: ' + e2.message);
|
|
91
|
+
}
|
|
79
92
|
console.log('catch e: ' + e.message);
|
|
80
93
|
throw e;
|
|
81
94
|
}
|
|
82
95
|
}
|
|
96
|
+
async getPublishInfo(assortmentPublishChangeId: any, apcHistory: any, publisher: any): Promise<any> {
|
|
97
|
+
const apc = apcHistory?.find(apc => apc?.id === assortmentPublishChangeId) || {};
|
|
98
|
+
const assortmentName = (await this.getAssortment(assortmentPublishChangeId))?.name;
|
|
99
|
+
const publishInfo = {
|
|
100
|
+
assortmentName,
|
|
101
|
+
versionName: apc?.versionName,
|
|
102
|
+
versionComments: apc?.versionComments,
|
|
103
|
+
publishDate: apc?.createdOn,
|
|
104
|
+
publisher
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
return publishInfo;
|
|
108
|
+
}
|
|
83
109
|
|
|
84
110
|
async getSeasonFederation(assortmentId): Promise<SeasonFederation> {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
entityName: 'assortment',
|
|
89
|
-
id: assortmentId
|
|
90
|
-
});
|
|
91
|
-
console.info('assortment-name: ' + assortment['name']);
|
|
92
|
-
} catch (e) {
|
|
93
|
-
console.warn(`No Assortment found for id: ${assortmentId}`);
|
|
94
|
-
}
|
|
111
|
+
const assortment = await this.getAssortment(assortmentId);
|
|
112
|
+
console.error('assortment-name: ' + assortment?.name);
|
|
113
|
+
|
|
95
114
|
const publishToFlexPLM = assortment?.publishToFlexPLM;
|
|
96
115
|
if (!publishToFlexPLM) {
|
|
97
116
|
throw new Error(BaseProcessPublishAssortment.ASSORTMENT_NOT_PUBLISHABLE);
|
|
@@ -120,6 +139,18 @@ export class BaseProcessPublishAssortment {
|
|
|
120
139
|
return seasonObj as SeasonFederation;
|
|
121
140
|
}
|
|
122
141
|
|
|
142
|
+
async getAssortment(assortmentId: any) {
|
|
143
|
+
if(this.assortment != undefined){
|
|
144
|
+
return this.assortment;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.assortment = await new Entities().get({
|
|
148
|
+
entityName: 'assortment',
|
|
149
|
+
id: assortmentId
|
|
150
|
+
});
|
|
151
|
+
return this.assortment;
|
|
152
|
+
}
|
|
153
|
+
|
|
123
154
|
public async getSinceDate(assortmentId: any, assortmentPublishChangeId: any, apcHistory: object[]): Promise<Date> {
|
|
124
155
|
|
|
125
156
|
let sinceDate = null;
|
|
@@ -265,7 +296,7 @@ export class BaseProcessPublishAssortment {
|
|
|
265
296
|
}
|
|
266
297
|
|
|
267
298
|
async downloadAssortmentPublishChange(assortmentId: string, assortmentPublishChangeId: string) {
|
|
268
|
-
const resourceString = '/assortments/' + assortmentId + '/history/' + assortmentPublishChangeId;
|
|
299
|
+
const resourceString = '/assortments/' + assortmentId + '/history/' + assortmentPublishChangeId + '?relations=createdBy';
|
|
269
300
|
return await Request.request(
|
|
270
301
|
resourceString,
|
|
271
302
|
{
|
|
@@ -190,6 +190,37 @@ describe('all tests', () => {
|
|
|
190
190
|
expect(itemPreDevelopmentLifecycleStages.includes(development));
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
+
it('itemPreDevelopmentLifecycleStages as empty string', async () => {
|
|
194
|
+
console.log('itemPreDevelopmentLifecycleStages as empty string');
|
|
195
|
+
const concept = 'concept';
|
|
196
|
+
const startConfig = Object.assign({}, config);
|
|
197
|
+
startConfig['itemPreDevelopmentLifecycleStages'] = '';
|
|
198
|
+
console.log('startConfig: ' + JSON.stringify(startConfig));
|
|
199
|
+
|
|
200
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
201
|
+
console.log('fcConfig: ' + JSON.stringify(fcConfig));
|
|
202
|
+
const itemPreDevelopmentLifecycleStages = fcConfig['itemPreDevelopmentLifecycleStages'];
|
|
203
|
+
expect(itemPreDevelopmentLifecycleStages instanceof Array).toBeTruthy();
|
|
204
|
+
expect(itemPreDevelopmentLifecycleStages.length).toBe(1);
|
|
205
|
+
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
206
|
+
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('itemPreDevelopmentLifecycleStages as empty array', async () => {
|
|
210
|
+
console.log('itemPreDevelopmentLifecycleStages as empty string');
|
|
211
|
+
const concept = 'concept';
|
|
212
|
+
const startConfig = Object.assign({}, config);
|
|
213
|
+
startConfig['itemPreDevelopmentLifecycleStages'] = [];
|
|
214
|
+
console.log('startConfig: ' + JSON.stringify(startConfig));
|
|
215
|
+
|
|
216
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
217
|
+
console.log('fcConfig: ' + JSON.stringify(fcConfig));
|
|
218
|
+
const itemPreDevelopmentLifecycleStages = fcConfig['itemPreDevelopmentLifecycleStages'];
|
|
219
|
+
expect(itemPreDevelopmentLifecycleStages instanceof Array).toBeTruthy();
|
|
220
|
+
expect(itemPreDevelopmentLifecycleStages.length).toBe(1);
|
|
221
|
+
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
222
|
+
|
|
223
|
+
});
|
|
193
224
|
it('identifierAtts-LCSProduct-get default', async () => {
|
|
194
225
|
const startConfig = Object.assign({}, config);
|
|
195
226
|
const objectClass = 'LCSProduct';
|
|
@@ -13,6 +13,8 @@ export class ConfigDefaults {
|
|
|
13
13
|
//List will be comma separated list in UI, so convert to array
|
|
14
14
|
if(config?.itemPreDevelopmentLifecycleStages && !(config?.itemPreDevelopmentLifecycleStages instanceof Array)){
|
|
15
15
|
config.itemPreDevelopmentLifecycleStages = config.itemPreDevelopmentLifecycleStages.split(',');
|
|
16
|
+
} else if(Object.keys(config).includes('itemPreDevelopmentLifecycleStages')){
|
|
17
|
+
delete config['itemPreDevelopmentLifecycleStages'];
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
const defaultConfig = {
|
|
@@ -37,10 +37,6 @@ export class ThumbnailUtil {
|
|
|
37
37
|
}
|
|
38
38
|
/** Determines if a new image has been generated. If any viewable is new, there might be a better
|
|
39
39
|
* sized image. So send the fileId as new.
|
|
40
|
-
*
|
|
41
|
-
* @param event
|
|
42
|
-
* @param customSizes
|
|
43
|
-
* @returns boolean
|
|
44
40
|
*/
|
|
45
41
|
public isThumbnailNew(event, customSizes: any[]): boolean {
|
|
46
42
|
const propertyDiffs = event?.propertyDiffs;
|