40306fcfd3e80144a1dd2959ec456d7fcc369ad8
[vid.git] / vid-webpack-master / cypress / integration / iFrames / instantiation-templates.e2e.ts
1 import * as _ from "lodash";
2 import {PropertyPath} from "lodash";
3
4 describe('Drawing Board: Instantiation Templates', function () {
5
6   describe('Instantiation templates ', () => {
7
8     beforeEach(() => {
9       cy.clearSessionStorage();
10       cy.setTestApiParamToGR();
11       cy.initAAIMock();
12       cy.initGetAAISubDetails();
13       cy.initVidMock();
14       cy.initDrawingBoardUserPermission();
15       cy.login();
16
17       mockAsyncBulkResponse();
18     });
19
20     afterEach(() => {
21       cy.screenshot();
22     });
23
24     describe('Load Page and Deploy', () => {
25
26       it(`Given a stored template - when click "deploy" - then a coherent request should be sent upon deploy`, () => {
27
28         loadDrawingBoardWithRecreateMode();
29
30         // Then...
31         cy.getElementByDataTestsId("node-vProbe_NC_VNF 0").should('be.visible');
32         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd();
33       });
34
35       it('Given a template - User can remove existing VNF', () => {
36
37         loadDrawingBoardWithRecreateMode();
38
39         removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
40
41         cy.getDrawingBoardDeployBtn().click();
42         cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
43           cy.deepCompare(bodyOf(xhr).vnfs, {});
44         });
45
46       });
47
48       it('Given a template - User can add new VNF', () => {
49         loadDrawingBoardWithRecreateMode();
50         // add new node
51         addNewNode('node-vProbe_NC_VNF 0-add-btn')
52           .fillVnfPopup()
53           .getDrawingBoardDeployBtn().click()
54           .wait('@expectedPostAsyncInstantiation').then(xhr => {
55           const vnfRequest = bodyOf(xhr).vnfs['vProbe_NC_VNF 0_1'];
56
57           expect(vnfRequest.action).equals("Create");
58           expect(vnfRequest.rollbackOnFailure).equals("true");
59           expect(vnfRequest.originalName).equals("vProbe_NC_VNF 0");
60           expect(vnfRequest.productFamilyId).equals("a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
61           expect(vnfRequest.lcpCloudRegionId).equals("hvf6");
62           expect(vnfRequest.lineOfBusiness).equals("zzz1");
63           expect(vnfRequest.platformName).equals("xxx1");
64           expect(vnfRequest.tenantId).equals("229bcdc6eaeb4ca59d55221141d01f8e");
65
66
67           // check instance name not change if empty
68           editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
69             .clearInput('instanceName');
70           cy.getElementByDataTestsId('form-set').click({force: true}).then((done) => {
71             editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
72               .getElementByDataTestsId('instanceName').should('be.empty')
73           });
74         });
75       });
76
77       it('Given a template - User can Duplicate VNF', () => {
78         const numberOfDuplicate: number = 4;
79         loadDrawingBoardWithRecreateMode();
80         nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
81           .getElementByDataTestsId('duplicate-amount-vfmodules').select(numberOfDuplicate.toString())
82           .getTagElementContainsText('button', 'Duplicate').click()
83           .getDrawingBoardDeployBtn().click()
84           .wait('@expectedPostAsyncInstantiation').then(xhr => {
85           expect(Object.keys(bodyOf(xhr).vnfs).length).equals(numberOfDuplicate + 1);
86         });
87       });
88
89       it('Given a stored template - when "edit" vnf and vfmodules are opened - then template’s details are visible as expected and deploy without changes', () => {
90
91         loadDrawingBoardWithRecreateMode();
92
93         // Then...
94         editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
95           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007')
96           .getElementByDataTestsId("productFamily").should('contain', 'Emanuel')
97           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
98           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
99           .getElementByDataTestsId("lineOfBusiness").should('contain', 'zzz1')
100           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
101           .checkPlatformValue('xxx1')
102           .getElementByDataTestsId("cancelButton").click();
103
104         editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
105           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007_lba_Base_01')
106           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
107           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
108           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
109           .getElementByDataTestsId("cancelButton").click();
110
111         editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
112           .getElementByDataTestsId("instanceName").should('have.value', 'my_hvf6arlba007_lba_dj_01')
113           .getElementByDataTestsId("volumeGroupName").should('have.value', 'my_special_hvf6arlba007_lba_dj_01_vol')
114           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
115           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
116           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
117           .getElementByDataTestsId("sdncPreLoad").should('have.value', 'on')
118           .getElementByDataTestsId("cancelButton").click();
119
120         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
121           {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
122         ]);
123       });
124
125       it(`Given a stored template - when "edit" service is opened - then template’s details are visible as expected`, function () {
126
127         loadDrawingBoardWithRecreateMode();
128
129         cy.openServiceContextMenu()
130           .getElementByDataTestsId("context-menu-header-edit-item").click()
131           .getElementByDataTestsId("instanceName").should('have.value', 'vProbe_NC_Service_DG_new_SI')
132           .getElementByDataTestsId("subscriberName").should('contain', 'SILVIA ROBBINS')
133           .getElementByDataTestsId("serviceType").should('contain', 'TYLER SILVIA')
134           .getElementByDataTestsId("owningEntity").should('contain', 'WayneHolland')
135           .getElementByDataTestsId("project").should('contain', 'WATKINS')
136           .getElementByDataTestsId("rollback").should('contain', 'Rollback');
137
138       });
139
140       it(`Given a stored template - add one VfModule, edit its details, and deploy - deploy is added with the vfModule details`, () => {
141         loadDrawingBoardWithRecreateMode();
142
143         let newVfModuleName = "new.vfmodule.name";
144         let module1ModelId = "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1";
145         let module1CustomizationId = `vprobe_nc_vnf0..${module1ModelId}`;
146
147         // Click target VNF on right tree
148         cy.getElementByDataTestsId('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0').click();
149
150         // Click [+] vfModule on left tree
151         cy.drawingBoardPressAddButtonByElementName(`node-${module1CustomizationId}`)
152           .click({force: true});
153
154         editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
155         cy.clearInput("instanceName");
156         cy.typeToInput("instanceName", newVfModuleName);
157         cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
158         cy.selectDropdownOptionByText('tenant', 'DN5242-Nov21-T1');
159         cy.getElementByDataTestsId('form-set').click();
160
161         // Then...
162         cy.getReduxState().then((state) => {
163           let vfModules_1Path = [
164             ...vnfPath, "vfModules", module1CustomizationId,
165           ];
166
167           let serviceInstanceElementOnRedux = state.service.serviceInstance[(templateWithVnfSetup.serviceModelId)];
168           let latestVfModule_1Path = findPathOfLatestVfModule(serviceInstanceElementOnRedux, vfModules_1Path);
169
170           // This is a funny merge, as values are already there, but that way ensures
171           // the values that selected are really deployed, while limiting the cost of
172           // maintenance, by taking other vfModule's fields as granted.
173           let latestVfModule_1ExpectedValue = _.merge(
174             _.get(serviceInstanceElementOnRedux, latestVfModule_1Path),
175             {
176               instanceName: newVfModuleName,
177               volumeGroupName: `${newVfModuleName}_vol`,
178               lcpCloudRegionId: "hvf6",
179               tenantId: "4914ab0ab3a743e58f0eefdacc1dde77",
180             }
181           );
182
183           assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
184             {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"},   // side-effect
185             {path: ["existingNames", newVfModuleName], value: ""},
186             {path: ["existingNames", `${newVfModuleName}_vol`], value: ""},
187             {path: latestVfModule_1Path, value: latestVfModule_1ExpectedValue},
188             {path: ["validationCounter"], value: null},  // side-effect
189           ]);
190         });
191
192       });
193
194       it('Given a template - User can remove existing vfmodule', function () {
195
196         loadDrawingBoardWithRecreateMode();
197         nodeAction('node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1', 'Remove');
198         let removed_vfModule_Path = [
199           ...vnfPath, "vfModules",
200           "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
201         ];
202
203         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
204           {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
205           {path: [...removed_vfModule_Path], value: undefined},
206         ]);
207       });
208
209       [
210         {desc: "with changes", modifySomeValues: true},
211         {desc: "without changes", modifySomeValues: false},
212       ].forEach((testCase) => {
213
214         it(`Given a stored template - edit service vnf and vfmodule ${testCase.desc} - deploy request should be ${testCase.desc}`, function () {
215
216           loadDrawingBoardWithRecreateMode();
217
218           //edit service
219           cy.openServiceContextMenu();
220           cy.getElementByDataTestsId("context-menu-header-edit-item").click();
221           if (testCase.modifySomeValues) {
222             cy.clearInput("instanceName");
223             cy.typeToInput("instanceName", "different.instance.name");
224           }
225           cy.getElementByDataTestsId('form-set').click();
226
227           // edit vnf
228           editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
229           if (testCase.modifySomeValues) {
230             cy.selectPlatformValue('platform');
231             cy.selectDropdownOptionByText("tenant", "CESAR-100-D-spjg61909");
232           }
233           cy.getElementByDataTestsId('form-set').click();
234
235           //edit vf module
236           editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
237           if (testCase.modifySomeValues) {
238             cy.getElementByDataTestsId('sdncPreLoad').click();
239           }
240           cy.getElementByDataTestsId('form-set').click();
241
242           // Then...
243           let vfModule_0Path = [
244             ...vnfPath, "vfModules",
245             "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0",
246             "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0ahubg",
247           ];
248
249           assertThatBodyFromDeployRequestEqualsToFile(testCase.modifySomeValues ? [
250             {path: ["instanceName"], value: "different.instance.name"},
251             {path: ["existingNames", "vprobe_nc_service_dg_new_si"], value: undefined},
252             {path: ["existingNames", "different.instance.name"], value: ""},
253
254             {path: [...vnfPath, "platformName"], value: "xxx1,platform"},
255             {path: [...vnfPath, "tenantId"], value: "f2f3830e4c984d45bcd00e1a04158a79"},
256
257             {path: [...vfModule_0Path, "sdncPreLoad"], value: true},
258           ] : []);
259         })
260
261       });
262
263       it(`Given a stored template of Network - - it is loaded`, () => {
264
265         loadDrawingBoardWithRecreateModeNetwork();
266
267         // Then...
268         cy.getElementByDataTestsId("node-SR-IOV Provider 2-1").should('be.visible');
269         cy.getElementByDataTestsId("node-SR-IOV Provider 2-2").should('be.visible');
270         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network();
271       });
272
273       it(`Given a stored template of Network - User can remove existing network`, () => {
274
275         loadDrawingBoardWithRecreateModeNetwork();
276
277         nodeAction('node-01f4c475-3f89-4f00-a2f4-39a873dba0ae-SR-IOV Provider 2-1', 'Remove');
278         let removed_network_Path = [
279           "networks", "SR-IOV Provider 2-1",
280         ];
281
282         let removed_network_counter_Path = [
283           "existingNetworksCounterMap", "f6b6d141-0d4c-427d-ad35-797f3d1abe71",
284         ];
285
286         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network([
287           {path: removed_network_Path, value: undefined},
288           {path: removed_network_counter_Path, value: 0},
289         ]);
290       });
291
292       it('Given a template - User can add a new network', () => {
293
294         loadDrawingBoardWithRecreateModeNetwork();
295
296         // add new node
297         addNewNode('node-SR-IOV Provider 2-1-add-btn')
298           .fillNetworkPopup()
299           .getDrawingBoardDeployBtn().click()
300           .wait('@expectedPostAsyncInstantiation').then(xhr => {
301           const networkRequest = bodyOf(xhr).networks['SR-IOV Provider 2-1_1'];
302
303           expect(networkRequest.action).equals("Create");
304           expect(networkRequest.rollbackOnFailure).equals("true");
305           expect(networkRequest.originalName).equals("SR-IOV Provider 2-1");
306           expect(networkRequest.productFamilyId).equals("a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
307           expect(networkRequest.lcpCloudRegionId).equals("hvf6");
308           expect(networkRequest.lineOfBusiness).equals("zzz1");
309           expect(networkRequest.platformName).equals("xxx1");
310           expect(networkRequest.tenantId).equals("229bcdc6eaeb4ca59d55221141d01f8e");
311         });
312       });
313     });
314   });
315 });
316
317 let apiTestResources = '../vid-automation/src/test/resources/asyncInstantiation/';
318
319 const templateWithVnfSetup = {
320   serviceModelId: '6cfeeb18-c2b0-49df-987a-da47493c8e38',
321   instanceTemplateFile: apiTestResources + 'templates__instance_template.json',
322   instanceTemplateSetWithoutModifyFile: apiTestResources + 'templates__instance_from_template__set_without_modify1.json',
323   serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model.json',
324 };
325
326 const templateWithNetworkSetup = {
327   serviceModelId: 'a1a14610-ee40-4049-8007-0608a20dd1fa',
328   instanceTemplateFile: apiTestResources + 'templates__instance_template_network.json',
329   serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model_network.json',
330 };
331
332 const vnfPath = [
333   "vnfs", "vProbe_NC_VNF 0"
334 ];
335
336 function loadDrawingBoardWithRecreateMode() {
337   loadDrawingBoardWithRecreateModeInternal(
338     '../../' + templateWithVnfSetup.instanceTemplateFile,
339     templateWithVnfSetup.serviceModelId,
340     templateWithVnfSetup.serviceModelFile);
341 }
342
343 function loadDrawingBoardWithRecreateModeNetwork() {
344   loadDrawingBoardWithRecreateModeInternal(
345     '../../' + templateWithNetworkSetup.instanceTemplateFile,
346     templateWithNetworkSetup.serviceModelId,
347     templateWithNetworkSetup.serviceModelFile);
348 }
349
350 function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
351   const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
352
353   const drawingBoardAction = `RECREATE`;
354   const templateTopologyEndpoint = "templateTopology";
355   cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
356     'fixture:' + serviceModel)
357     .as('serviceModel');
358
359   cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
360     'fixture:' + instanceTemplate)
361     .as('templateTopology');
362
363   // When...
364
365   cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
366     `?jobId=${templateUuid}` +
367     `&serviceModelId=${serviceModelIdToLoad}`);
368
369   cy.wait('@serviceModel');
370   cy.wait('@templateTopology');
371 }
372
373 function nodeAction(dataTestId: string, action: string, index ?: number) {
374   return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
375     .drawingBoardTreeClickOnContextMenuOptionByName(action)
376 }
377
378 function editNode(dataTestId: string, index ?: number) {
379   return nodeAction(dataTestId, 'Edit', index);
380 }
381
382 function addNewNode(dataTestId: string) {
383   return cy.getElementByDataTestsId(dataTestId).click({force: true})
384 }
385
386 function removeVNFWithVFModules(dataTestId: string) {
387   return nodeAction(dataTestId, 'Remove')
388     .getTagElementContainsText('button', 'Remove VNF').click()
389 }
390
391 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
392   assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(templateWithVnfSetup.instanceTemplateFile, deviationFromExpected);
393 }
394
395 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
396   assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(templateWithNetworkSetup.instanceTemplateFile, deviationFromExpected);
397 }
398
399 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(filePathOfExpected: string, deviationFromExpected: { path: PropertyPath; value: any }[]) {
400   cy.getDrawingBoardDeployBtn().click();
401   cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
402     cy.readFile(filePathOfExpected).then((expectedResult) => {
403       convertRollbackOnFailureValueFromStringToBoolean(expectedResult);
404
405       let xhrBodyWithoutIsDirtyField = removeIsDirtyFieldFromXhrRequestBody(xhr);
406       setDeviationInExpected(expectedResult, deviationFromExpected);
407       cy.deepCompare(xhrBodyWithoutIsDirtyField, expectedResult);
408     });
409   });
410 }
411
412
413 function assertThatBodyFromDeployRequestEqualsToFile(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
414   cy.getDrawingBoardDeployBtn().click();
415   cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
416
417     cy.readFile(templateWithVnfSetup.instanceTemplateSetWithoutModifyFile).then((expectedResult) => {
418       setDeviationInExpected(expectedResult, deviationFromExpected);
419       cy.deepCompare(xhr.request.body, expectedResult);
420     });
421
422   });
423 }
424
425 function bodyOf(xhr: Cypress.WaitXHR) {
426   return JSON.parse(JSON.stringify(xhr.request.body));
427 }
428
429 function setDeviationInExpected(expectedResult: any, deviations: { path: PropertyPath; value: any }[]) {
430   for (const deviation of deviations) {
431     _.set(expectedResult, deviation.path, deviation.value);
432   }
433 }
434
435 function findPathOfLatestVfModule(serviceInstanceElementFromRedux: any, vfModulesContainerPath: string[]) {
436   let latestVfModuleRandomlySelectedKey: string = _.last(_.keys(
437     _.get(serviceInstanceElementFromRedux, vfModulesContainerPath)
438   )) as string;
439
440   return [...vfModulesContainerPath, latestVfModuleRandomlySelectedKey];
441 }
442
443 //We use this function because the deployService() on drawing-board-header.component class
444 // changes rollbackOnFailure value from string type to boolean.
445 function convertRollbackOnFailureValueFromStringToBoolean(expectedResult: any) {
446   expectedResult.rollbackOnFailure = Boolean(expectedResult.rollbackOnFailure);
447 }
448
449 function removeIsDirtyFieldFromXhrRequestBody(xhr: any) {
450   let xhrTempBody = bodyOf(xhr);
451   delete xhrTempBody.isDirty;
452   return xhrTempBody;
453 }
454
455 function mockAsyncBulkResponse() {
456   cy.server().route({
457     url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
458     method: 'POST',
459     status: 200,
460     response: "[]",
461   }).as("expectedPostAsyncInstantiation");
462 }