Skip to content

Commit 9a13138

Browse files
gciavarrinirhkpJudeNiroshan
authored
test(orchestrator): add unit tests for v2 endpoints (#1300)
* Unit Test: executeWorkflow (V2) Signed-off-by: Kamlesh Panchal <[email protected]> Add Helpers.ts mock Signed-off-by: Gloria Ciavarrini <[email protected]> * Unit Test: getWorkflowResults (v2) Signed-off-by: Kamlesh Panchal <[email protected]> * Unit Test: getInstances (v2) Signed-off-by: Gloria Ciavarrini <[email protected]> * Unit Test: getInstanceById (v2) Signed-off-by: Gloria Ciavarrini <[email protected]> * Unit Test: abortWorkflow (v2) Signed-off-by: Kamlesh Panchal <[email protected]> * refactor: introduce mapToWorkflowRunStatusDTO mapper * Unit Test: mapToWorkflowRunStatusDTO and firstLetterToUppercase mapper methods * Unit Test: getWorkflowStatuses * fix unit test getWorkflowsOverview (v2) Signed-off-by: Gloria Ciavarrini <[email protected]> * fix: include annotation value in the test workflowDefinition obj * fix: add pagination to unit tests Signed-off-by: Gloria Ciavarrini <[email protected]> * fix typos Signed-off-by: Gloria Ciavarrini <[email protected]> * Move StriingUtils from orchestrator to orchestrator-common Signed-off-by: Gloria Ciavarrini <[email protected]> * fix unit test abortWorkflow Signed-off-by: Gloria Ciavarrini <[email protected]> --------- Signed-off-by: Gloria Ciavarrini <[email protected]> Signed-off-by: Kamlesh Panchal <[email protected]> Co-authored-by: Kamlesh Panchal <[email protected]> Co-authored-by: Jude Niroshan <[email protected]>
1 parent d16109a commit 9a13138

File tree

16 files changed

+797
-33
lines changed

16 files changed

+797
-33
lines changed

plugins/orchestrator-backend/src/service/api/mapping/V2Mappings.test.ts

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,93 @@
1-
import { WorkflowOverview } from '@janus-idp/backstage-plugin-orchestrator-common';
1+
import moment from 'moment';
22

3-
import { generateTestWorkflowOverview } from '../test-utils';
43
import {
4+
ProcessInstance,
5+
ProcessInstanceState,
6+
WorkflowOverview,
7+
WorkflowRunStatusDTO,
8+
} from '@janus-idp/backstage-plugin-orchestrator-common';
9+
10+
import {
11+
generateProcessInstance,
12+
generateTestExecuteWorkflowResponse,
13+
generateTestWorkflowOverview,
14+
} from '../test-utils';
15+
import assessedProcessInstanceData from './__fixtures__/assessedProcessInstance.json';
16+
import {
17+
getProcessInstancesDTOFromString,
18+
mapToExecuteWorkflowResponseDTO,
19+
mapToGetWorkflowInstanceResults,
20+
mapToProcessInstanceDTO,
521
mapToWorkflowOverviewDTO,
22+
mapToWorkflowRunStatusDTO,
623
mapWorkflowCategoryDTOFromString,
724
} from './V2Mappings';
825

26+
describe('scenarios to verify mapToGetWorkflowInstanceResults', () => {
27+
it('correctly maps positive scenario response', async () => {
28+
const assessedProcessInstance = assessedProcessInstanceData;
29+
30+
const mappedValue = mapToGetWorkflowInstanceResults(
31+
// @ts-ignore
32+
assessedProcessInstance.instance.variables,
33+
);
34+
35+
expect(mappedValue).toBeDefined();
36+
expect(mappedValue.result).toBeDefined();
37+
expect(mappedValue.preCheck).toBeDefined();
38+
expect(mappedValue.workflowOptions).toBeDefined();
39+
expect(mappedValue.repositoryUrl).toEqual('https://java.com');
40+
expect(Object.keys(mappedValue).length).toBe(4);
41+
});
42+
43+
it('correctly maps string response', async () => {
44+
const testValue = 'string_value';
45+
const mappedValue = mapToGetWorkflowInstanceResults(testValue);
46+
expect(mappedValue).toBeDefined();
47+
expect(Object.keys(mappedValue).length).toBe(1);
48+
expect(mappedValue.variables).toBeDefined();
49+
expect(mappedValue.variables).toEqual(testValue);
50+
});
51+
52+
it('correctly returns empty workflowoptions when variables property does not exist', async () => {
53+
const assessedProcessInstance = assessedProcessInstanceData;
54+
55+
// @ts-ignore
56+
delete assessedProcessInstance.instance.variables;
57+
58+
const mappedValue = mapToGetWorkflowInstanceResults(
59+
// @ts-ignore
60+
assessedProcessInstance.instance.variables,
61+
);
62+
63+
expect(mappedValue).toBeDefined();
64+
expect(Object.keys(mappedValue).length).toBe(1);
65+
expect(mappedValue.workflowoptions).toBeDefined();
66+
expect(mappedValue.workflowoptions?.length).toBe(0);
67+
});
68+
});
69+
70+
describe('scenarios to verify executeWorkflowResponseDTO', () => {
71+
it('correctly maps positive scenario response', async () => {
72+
const execWorkflowResp = generateTestExecuteWorkflowResponse();
73+
const mappedValue = mapToExecuteWorkflowResponseDTO(
74+
'test_workflowId',
75+
execWorkflowResp,
76+
);
77+
expect(mappedValue).toBeDefined();
78+
expect(mappedValue.id).toBeDefined();
79+
expect(Object.keys(mappedValue).length).toBe(1);
80+
});
81+
82+
it('throws error when no id attribute present in response', async () => {
83+
expect(() => {
84+
mapToExecuteWorkflowResponseDTO('workflowId', { id: '' });
85+
}).toThrow(
86+
`Error while mapping ExecuteWorkflowResponse to ExecuteWorkflowResponseDTO for workflow with id`,
87+
);
88+
});
89+
});
90+
991
describe('scenarios to verify mapToWorkflowOverviewDTO', () => {
1092
it('correctly maps WorkflowOverview', () => {
1193
// Arrange
@@ -47,3 +129,82 @@ describe('scenarios to verify mapWorkflowCategoryDTOFromString', () => {
47129
expect(resultCategory).toBe(expected);
48130
});
49131
});
132+
133+
describe('scenarios to verify mapToProcessInstanceDTO', () => {
134+
it('correctly maps ProcessInstanceDTO for not completed workflow', () => {
135+
// Arrange
136+
const processIntanceV1: ProcessInstance = generateProcessInstance(1);
137+
processIntanceV1.end = undefined;
138+
139+
// Act
140+
const result = mapToProcessInstanceDTO(processIntanceV1);
141+
142+
// Assert
143+
expect(result).toBeDefined();
144+
expect(result.id).toBeDefined();
145+
expect(result.start).toBeDefined();
146+
expect(result.start).toEqual(processIntanceV1.start?.toUTCString());
147+
expect(result.end).toBeUndefined();
148+
expect(result.duration).toBeUndefined();
149+
expect(result.status).toEqual(
150+
getProcessInstancesDTOFromString(processIntanceV1.state),
151+
);
152+
expect(result.description).toEqual(processIntanceV1.description);
153+
expect(result.category).toEqual('infrastructure');
154+
expect(result.workflowdata).toEqual(
155+
// @ts-ignore
156+
processIntanceV1?.variables?.workflowdata,
157+
);
158+
expect(result.workflow).toEqual(
159+
processIntanceV1.processName ?? processIntanceV1.processId,
160+
);
161+
});
162+
it('correctly maps ProcessInstanceDTO', () => {
163+
// Arrange
164+
const processIntanceV1: ProcessInstance = generateProcessInstance(1);
165+
166+
const start = moment(processIntanceV1.start);
167+
const end = moment(processIntanceV1.end);
168+
const duration = moment.duration(start.diff(end)).humanize();
169+
// Act
170+
const result = mapToProcessInstanceDTO(processIntanceV1);
171+
172+
// Assert
173+
expect(result.id).toBeDefined();
174+
expect(result.start).toEqual(processIntanceV1.start?.toUTCString());
175+
expect(result.end).toBeDefined();
176+
expect(result.end).toEqual(processIntanceV1.end!.toUTCString());
177+
expect(result.duration).toEqual(duration);
178+
179+
expect(result).toBeDefined();
180+
expect(result.status).toEqual(
181+
getProcessInstancesDTOFromString(processIntanceV1.state),
182+
);
183+
expect(result.end).toEqual(processIntanceV1.end?.toUTCString());
184+
expect(result.duration).toEqual(duration);
185+
expect(result.duration).toEqual('an hour');
186+
expect(result.description).toEqual(processIntanceV1.description);
187+
expect(result.category).toEqual('infrastructure');
188+
expect(result.workflowdata).toEqual(
189+
// @ts-ignore
190+
processIntanceV1?.variables?.workflowdata,
191+
);
192+
expect(result.workflow).toEqual(
193+
processIntanceV1.processName ?? processIntanceV1.processId,
194+
);
195+
});
196+
});
197+
198+
describe('scenarios to verify mapToWorkflowRunStatusDTO', () => {
199+
it('correctly maps ProcessInstanceState to WorkflowRunStatusDTO', async () => {
200+
const mappedValue: WorkflowRunStatusDTO = mapToWorkflowRunStatusDTO(
201+
ProcessInstanceState.Active,
202+
);
203+
204+
expect(mappedValue).toBeDefined();
205+
expect(mappedValue.key).toBeDefined();
206+
expect(mappedValue.value).toBeDefined();
207+
expect(mappedValue.key).toEqual('Active');
208+
expect(mappedValue.value).toEqual('ACTIVE');
209+
});
210+
});

plugins/orchestrator-backend/src/service/api/mapping/V2Mappings.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import moment from 'moment';
22

33
import {
4+
capitalize,
45
ExecuteWorkflowResponseDTO,
56
extractWorkflowFormat,
67
fromWorkflowSource,
@@ -18,6 +19,7 @@ import {
1819
WorkflowFormatDTO,
1920
WorkflowOverview,
2021
WorkflowOverviewDTO,
22+
WorkflowRunStatusDTO,
2123
} from '@janus-idp/backstage-plugin-orchestrator-common';
2224

2325
// Mapping functions
@@ -95,9 +97,11 @@ export function getProcessInstancesDTOFromString(
9597
export function mapToProcessInstanceDTO(
9698
processInstance: ProcessInstance,
9799
): ProcessInstanceDTO {
98-
const start = moment(processInstance.start?.toString());
99-
const end = moment(processInstance.end?.toString());
100-
const duration = moment.duration(start.diff(end));
100+
const start = moment(processInstance.start);
101+
const end = moment(processInstance.end);
102+
const duration = processInstance.end
103+
? moment.duration(start.diff(end)).humanize()
104+
: undefined;
101105

102106
let variables: Record<string, unknown> | undefined;
103107
if (typeof processInstance?.variables === 'string') {
@@ -109,13 +113,14 @@ export function mapToProcessInstanceDTO(
109113
return {
110114
category: mapWorkflowCategoryDTO(processInstance.category),
111115
description: processInstance.description,
112-
duration: duration.humanize(),
113116
id: processInstance.id,
114117
name: processInstance.processName,
115118
// To be fixed https://issues.redhat.com/browse/FLPATH-950
116119
// @ts-ignore
117120
workflowdata: variables?.workflowdata,
118-
started: start.toDate().toLocaleString(),
121+
start: processInstance.start?.toUTCString(),
122+
end: processInstance.end?.toUTCString(),
123+
duration: duration,
119124
status: getProcessInstancesDTOFromString(processInstance.state),
120125
workflow: processInstance.processName ?? processInstance.processId,
121126
};
@@ -158,3 +163,12 @@ export function mapToGetWorkflowInstanceResults(
158163

159164
return returnObject;
160165
}
166+
167+
export function mapToWorkflowRunStatusDTO(
168+
status: ProcessInstanceState,
169+
): WorkflowRunStatusDTO {
170+
return {
171+
key: capitalize(status),
172+
value: status,
173+
};
174+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
{
2+
"instance": {
3+
"id": "026f38fc-6121-46c7-9fa8-3f4b8207bab9",
4+
"processName": "Assessment",
5+
"processId": "assessment",
6+
"businessKey": null,
7+
"state": "COMPLETED",
8+
"start": "2024-02-15T16:11:35.829Z",
9+
"lastUpdate": "2024-02-15T16:11:35.829Z",
10+
"end": "2024-02-15T16:11:35.822Z",
11+
"nodes": [
12+
{
13+
"id": "3290d3c5-c7c0-4920-a1dc-7a37d98d22b7",
14+
"nodeId": "_jbpm-unique-51",
15+
"definitionId": "_jbpm-unique-51",
16+
"type": "WorkItemNode",
17+
"name": "execute",
18+
"enter": "2024-02-15T16:11:33.485Z",
19+
"exit": "2024-02-15T16:11:35.828Z"
20+
},
21+
{
22+
"id": "2813e81e-0c38-424f-a505-639b1d33341b",
23+
"nodeId": "_jbpm-unique-50",
24+
"definitionId": "_jbpm-unique-50",
25+
"type": "StartNode",
26+
"name": "EmbeddedStart",
27+
"enter": "2024-02-15T16:11:33.477Z",
28+
"exit": "2024-02-15T16:11:35.829Z"
29+
},
30+
{
31+
"id": "f15d5540-0df7-401c-991e-3c45755b1302",
32+
"nodeId": "_jbpm-unique-47",
33+
"definitionId": "_jbpm-unique-47",
34+
"type": "StartNode",
35+
"name": "Start",
36+
"enter": "2024-02-15T16:11:33.472Z",
37+
"exit": "2024-02-15T16:11:35.829Z"
38+
},
39+
{
40+
"id": "142fcd3a-64e6-4539-a6b9-5ba2064623a1",
41+
"nodeId": "_jbpm-unique-48",
42+
"definitionId": "_jbpm-unique-48",
43+
"type": "EndNode",
44+
"name": "End",
45+
"enter": "2024-02-15T16:11:35.821Z",
46+
"exit": "2024-02-15T16:11:35.827Z"
47+
},
48+
{
49+
"id": "97e209c4-ae0a-4d09-8b00-4bd9ca062126",
50+
"nodeId": "_jbpm-unique-59",
51+
"definitionId": "_jbpm-unique-59",
52+
"type": "ActionNode",
53+
"name": "Script",
54+
"enter": "2024-02-15T16:11:35.812Z",
55+
"exit": "2024-02-15T16:11:35.827Z"
56+
},
57+
{
58+
"id": "f415ddd5-ba25-4e0a-be93-797b5f0ae6f3",
59+
"nodeId": "_jbpm-unique-49",
60+
"definitionId": "_jbpm-unique-49",
61+
"type": "CompositeContextNode",
62+
"name": "AssessRepository",
63+
"enter": "2024-02-15T16:11:33.476Z",
64+
"exit": "2024-02-15T16:11:35.827Z"
65+
},
66+
{
67+
"id": "10879e09-12c0-4770-be2b-d2fd27858edc",
68+
"nodeId": "_jbpm-unique-58",
69+
"definitionId": "_jbpm-unique-58",
70+
"type": "EndNode",
71+
"name": "EmbeddedEnd",
72+
"enter": "2024-02-15T16:11:35.812Z",
73+
"exit": "2024-02-15T16:11:35.827Z"
74+
},
75+
{
76+
"id": "96bb3b01-2a4a-44b2-b29c-da6dc7448450",
77+
"nodeId": "_jbpm-unique-57",
78+
"definitionId": "_jbpm-unique-57",
79+
"type": "ActionNode",
80+
"name": "Script",
81+
"enter": "2024-02-15T16:11:35.811Z",
82+
"exit": "2024-02-15T16:11:35.827Z"
83+
},
84+
{
85+
"id": "491975f5-4d6a-4a43-ac00-1e305bfcd97a",
86+
"nodeId": "_jbpm-unique-56",
87+
"definitionId": "_jbpm-unique-56",
88+
"type": "ActionNode",
89+
"name": "logOuput",
90+
"enter": "2024-02-15T16:11:35.809Z",
91+
"exit": "2024-02-15T16:11:35.828Z"
92+
},
93+
{
94+
"id": "bc4ddb8a-f551-442a-a0d9-7f96a8332a09",
95+
"nodeId": "_jbpm-unique-55",
96+
"definitionId": "_jbpm-unique-55",
97+
"type": "ActionNode",
98+
"name": "Script",
99+
"enter": "2024-02-15T16:11:35.807Z",
100+
"exit": "2024-02-15T16:11:35.828Z"
101+
},
102+
{
103+
"id": "effbf2d7-8201-48de-8f81-3983fb26d591",
104+
"nodeId": "_jbpm-unique-54",
105+
"definitionId": "_jbpm-unique-54",
106+
"type": "WorkItemNode",
107+
"name": "preCheck",
108+
"enter": "2024-02-15T16:11:33.896Z",
109+
"exit": "2024-02-15T16:11:35.828Z"
110+
},
111+
{
112+
"id": "54c7da48-de5c-4e62-868b-ad6c7ef25ad3",
113+
"nodeId": "_jbpm-unique-53",
114+
"definitionId": "_jbpm-unique-53",
115+
"type": "ActionNode",
116+
"name": "Script",
117+
"enter": "2024-02-15T16:11:33.894Z",
118+
"exit": "2024-02-15T16:11:35.828Z"
119+
},
120+
{
121+
"id": "bfc5796c-8aa7-4c4f-aa11-dc91aee24ea2",
122+
"nodeId": "_jbpm-unique-52",
123+
"definitionId": "_jbpm-unique-52",
124+
"type": "ActionNode",
125+
"name": "Script",
126+
"enter": "2024-02-15T16:11:33.826Z",
127+
"exit": "2024-02-15T16:11:35.828Z"
128+
}
129+
],
130+
"variables": {
131+
"workflowdata": {
132+
"result": "[Object]",
133+
"preCheck": "[Object]",
134+
"repositoryUrl": "https://java.com",
135+
"workflowOptions": "[Object]"
136+
}
137+
},
138+
"parentProcessInstance": null,
139+
"error": null,
140+
"category": "assessment",
141+
"description": "undefined"
142+
}
143+
}

0 commit comments

Comments
 (0)