1 import * as _ from "lodash";
2 import {PropertyPath} from "lodash";
4 describe('Drawing Board: Instantiation Templates', function () {
6 describe('Instantiation templates ', () => {
9 cy.clearSessionStorage();
10 cy.setTestApiParamToGR();
12 cy.initGetAAISubDetails();
14 cy.initDrawingBoardUserPermission();
17 mockAsyncBulkResponse();
24 describe('Load Page and Deploy', () => {
26 it(`Given a stored template - when click "deploy" - then a coherent request should be sent upon deploy`, () => {
28 loadDrawingBoardWithRecreateMode();
31 cy.getElementByDataTestsId("node-vProbe_NC_VNF 0").should('be.visible');
32 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd();
35 it('Given a template - User can remove existing VNF', () => {
37 loadDrawingBoardWithRecreateMode();
39 removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
41 cy.getDrawingBoardDeployBtn().click();
42 cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
43 cy.deepCompare(bodyOf(xhr).vnfs, {});
48 it('Given a template - User can add new VNF', () => {
49 loadDrawingBoardWithRecreateMode();
51 addNewNode('node-vProbe_NC_VNF 0-add-btn')
53 .getDrawingBoardDeployBtn().click()
54 .wait('@expectedPostAsyncInstantiation').then(xhr => {
55 const vnfRequest = bodyOf(xhr).vnfs['vProbe_NC_VNF 0_1'];
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");
68 it('Given a template - User can Duplicate VNF', () => {
69 const numberOfDuplicate: number = 4;
70 loadDrawingBoardWithRecreateMode();
71 nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
72 .getElementByDataTestsId('duplicate-amount-vfmodules').select(numberOfDuplicate.toString())
73 .getTagElementContainsText('button', 'Duplicate').click()
74 .getDrawingBoardDeployBtn().click()
75 .wait('@expectedPostAsyncInstantiation').then(xhr => {
76 expect(Object.keys(bodyOf(xhr).vnfs).length).equals(numberOfDuplicate + 1);
80 it('Given a stored template - when "edit" vnf and vfmodules are opened - then template’s details are visible as expected and deploy without changes', () => {
82 loadDrawingBoardWithRecreateMode();
85 editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
86 .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007')
87 .getElementByDataTestsId("productFamily").should('contain', 'Emanuel')
88 .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
89 .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
90 .getElementByDataTestsId("lineOfBusiness").should('contain', 'zzz1')
91 .getElementByDataTestsId("rollback").should('contain', 'Rollback')
92 .checkPlatformValue('xxx1')
93 .getElementByDataTestsId("cancelButton").click();
95 editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
96 .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007_lba_Base_01')
97 .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
98 .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
99 .getElementByDataTestsId("rollback").should('contain', 'Rollback')
100 .getElementByDataTestsId("cancelButton").click();
102 editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
103 .getElementByDataTestsId("instanceName").should('have.value', 'my_hvf6arlba007_lba_dj_01')
104 .getElementByDataTestsId("volumeGroupName").should('have.value', 'my_special_hvf6arlba007_lba_dj_01_vol')
105 .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
106 .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
107 .getElementByDataTestsId("rollback").should('contain', 'Rollback')
108 .getElementByDataTestsId("sdncPreLoad").should('have.value', 'on')
109 .getElementByDataTestsId("cancelButton").click();
111 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
112 {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
116 it(`Given a stored template - when "edit" service is opened - then template’s details are visible as expected`, function () {
118 loadDrawingBoardWithRecreateMode();
120 cy.openServiceContextMenu()
121 .getElementByDataTestsId("context-menu-header-edit-item").click()
122 .getElementByDataTestsId("instanceName").should('have.value', 'vProbe_NC_Service_DG_new_SI')
123 .getElementByDataTestsId("subscriberName").should('contain', 'SILVIA ROBBINS')
124 .getElementByDataTestsId("serviceType").should('contain', 'TYLER SILVIA')
125 .getElementByDataTestsId("owningEntity").should('contain', 'WayneHolland')
126 .getElementByDataTestsId("project").should('contain', 'WATKINS')
127 .getElementByDataTestsId("rollback").should('contain', 'Rollback');
131 it(`Given a stored template - add one VfModule, edit its details, and deploy - deploy is added with the vfModule details`, () => {
132 loadDrawingBoardWithRecreateMode();
134 let newVfModuleName = "new.vfmodule.name";
135 let module1ModelId = "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1";
136 let module1CustomizationId = `vprobe_nc_vnf0..${module1ModelId}`;
138 // Click target VNF on right tree
139 cy.getElementByDataTestsId('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0').click();
141 // Click [+] vfModule on left tree
142 cy.drawingBoardPressAddButtonByElementName(`node-${module1CustomizationId}`)
143 .click({force: true});
145 editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
146 cy.clearInput("instanceName");
147 cy.typeToInput("instanceName", newVfModuleName);
148 cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
149 cy.selectDropdownOptionByText('tenant', 'DN5242-Nov21-T1');
150 cy.getElementByDataTestsId('form-set').click();
153 cy.getReduxState().then((state) => {
154 let vfModules_1Path = [
155 ...vnfPath, "vfModules", module1CustomizationId,
158 let serviceInstanceElementOnRedux = state.service.serviceInstance[(templateWithVnfSetup.serviceModelId)];
159 let latestVfModule_1Path = findPathOfLatestVfModule(serviceInstanceElementOnRedux, vfModules_1Path);
161 // This is a funny merge, as values are already there, but that way ensures
162 // the values that selected are really deployed, while limiting the cost of
163 // maintenance, by taking other vfModule's fields as granted.
164 let latestVfModule_1ExpectedValue = _.merge(
165 _.get(serviceInstanceElementOnRedux, latestVfModule_1Path),
167 instanceName: newVfModuleName,
168 volumeGroupName: `${newVfModuleName}_vol`,
169 lcpCloudRegionId: "hvf6",
170 tenantId: "4914ab0ab3a743e58f0eefdacc1dde77",
174 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
175 {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
176 {path: ["existingNames", newVfModuleName], value: ""},
177 {path: ["existingNames", `${newVfModuleName}_vol`], value: ""},
178 {path: latestVfModule_1Path, value: latestVfModule_1ExpectedValue},
179 {path: ["validationCounter"], value: null}, // side-effect
185 it('Given a template - User can remove existing vfmodule', function () {
187 loadDrawingBoardWithRecreateMode();
188 nodeAction('node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1', 'Remove');
189 let removed_vfModule_Path = [
190 ...vnfPath, "vfModules",
191 "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
194 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
195 {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
196 {path: [...removed_vfModule_Path], value: undefined},
201 {desc: "with changes", modifySomeValues: true},
202 {desc: "without changes", modifySomeValues: false},
203 ].forEach((testCase) => {
205 it(`Given a stored template - edit service vnf and vfmodule ${testCase.desc} - deploy request should be ${testCase.desc}`, function () {
207 loadDrawingBoardWithRecreateMode();
210 cy.openServiceContextMenu();
211 cy.getElementByDataTestsId("context-menu-header-edit-item").click();
212 if (testCase.modifySomeValues) {
213 cy.clearInput("instanceName");
214 cy.typeToInput("instanceName", "different.instance.name");
216 cy.getElementByDataTestsId('form-set').click();
219 editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
220 if (testCase.modifySomeValues) {
221 cy.selectPlatformValue('platform');
222 cy.selectDropdownOptionByText("tenant", "CESAR-100-D-spjg61909");
224 cy.getElementByDataTestsId('form-set').click();
227 editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
228 if (testCase.modifySomeValues) {
229 cy.getElementByDataTestsId('sdncPreLoad').click();
231 cy.getElementByDataTestsId('form-set').click();
234 let vfModule_0Path = [
235 ...vnfPath, "vfModules",
236 "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0",
237 "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0ahubg",
240 assertThatBodyFromDeployRequestEqualsToFile(testCase.modifySomeValues ? [
241 {path: ["instanceName"], value: "different.instance.name"},
242 {path: ["existingNames", "vprobe_nc_service_dg_new_si"], value: undefined},
243 {path: ["existingNames", "different.instance.name"], value: ""},
245 {path: [...vnfPath, "platformName"], value: "xxx1,platform"},
246 {path: [...vnfPath, "tenantId"], value: "f2f3830e4c984d45bcd00e1a04158a79"},
248 {path: [...vfModule_0Path, "sdncPreLoad"], value: true},
254 it(`Given a stored template of Network - - it is loaded`, () => {
256 loadDrawingBoardWithRecreateModeNetwork();
259 cy.getElementByDataTestsId("node-SR-IOV Provider 2-1").should('be.visible');
260 cy.getElementByDataTestsId("node-SR-IOV Provider 2-2").should('be.visible');
261 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network();
264 it(`Given a stored template of Network - User can remove existing network`, () => {
266 loadDrawingBoardWithRecreateModeNetwork();
268 nodeAction('node-01f4c475-3f89-4f00-a2f4-39a873dba0ae-SR-IOV Provider 2-1', 'Remove');
269 let removed_network_Path = [
270 "networks", "SR-IOV Provider 2-1",
273 let removed_network_counter_Path = [
274 "existingNetworksCounterMap", "f6b6d141-0d4c-427d-ad35-797f3d1abe71",
277 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network([
278 {path: removed_network_Path, value: undefined},
279 {path: removed_network_counter_Path, value: 0},
287 let apiTestResources = '../vid-automation/src/test/resources/asyncInstantiation/';
289 const templateWithVnfSetup = {
290 serviceModelId: '6cfeeb18-c2b0-49df-987a-da47493c8e38',
291 instanceTemplateFile: apiTestResources + 'templates__instance_template.json',
292 instanceTemplateSetWithoutModifyFile: apiTestResources + 'templates__instance_from_template__set_without_modify1.json',
293 serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model.json',
296 const templateWithNetworkSetup = {
297 serviceModelId: 'a1a14610-ee40-4049-8007-0608a20dd1fa',
298 instanceTemplateFile: apiTestResources + 'templates__instance_template_network.json',
299 serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model_network.json',
303 "vnfs", "vProbe_NC_VNF 0"
306 function loadDrawingBoardWithRecreateMode() {
307 loadDrawingBoardWithRecreateModeInternal(
308 '../../' + templateWithVnfSetup.instanceTemplateFile,
309 templateWithVnfSetup.serviceModelId,
310 templateWithVnfSetup.serviceModelFile);
313 function loadDrawingBoardWithRecreateModeNetwork() {
314 loadDrawingBoardWithRecreateModeInternal(
315 '../../' + templateWithNetworkSetup.instanceTemplateFile,
316 templateWithNetworkSetup.serviceModelId,
317 templateWithNetworkSetup.serviceModelFile);
320 function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
321 const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
323 const drawingBoardAction = `RECREATE`;
324 const templateTopologyEndpoint = "templateTopology";
325 cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
326 'fixture:' + serviceModel)
329 cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
330 'fixture:' + instanceTemplate)
331 .as('templateTopology');
335 cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
336 `?jobId=${templateUuid}` +
337 `&serviceModelId=${serviceModelIdToLoad}`);
339 cy.wait('@serviceModel');
340 cy.wait('@templateTopology');
343 function nodeAction(dataTestId: string, action: string, index ?: number) {
344 return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
345 .drawingBoardTreeClickOnContextMenuOptionByName(action)
348 function editNode(dataTestId: string, index ?: number) {
349 return nodeAction(dataTestId, 'Edit', index);
352 function addNewNode(dataTestId: string) {
353 return cy.getElementByDataTestsId(dataTestId).click({force: true})
356 function removeVNFWithVFModules(dataTestId: string) {
357 return nodeAction(dataTestId, 'Remove')
358 .getTagElementContainsText('button', 'Remove VNF').click()
361 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
362 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(templateWithVnfSetup.instanceTemplateFile, deviationFromExpected);
365 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
366 assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(templateWithNetworkSetup.instanceTemplateFile, deviationFromExpected);
369 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(filePathOfExpected: string, deviationFromExpected: { path: PropertyPath; value: any }[]) {
370 cy.getDrawingBoardDeployBtn().click();
371 cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
372 cy.readFile(filePathOfExpected).then((expectedResult) => {
373 convertRollbackOnFailureValueFromStringToBoolean(expectedResult);
375 let xhrBodyWithoutIsDirtyField = removeIsDirtyFieldFromXhrRequestBody(xhr);
376 setDeviationInExpected(expectedResult, deviationFromExpected);
377 cy.deepCompare(xhrBodyWithoutIsDirtyField, expectedResult);
383 function assertThatBodyFromDeployRequestEqualsToFile(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
384 cy.getDrawingBoardDeployBtn().click();
385 cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
387 cy.readFile(templateWithVnfSetup.instanceTemplateSetWithoutModifyFile).then((expectedResult) => {
388 setDeviationInExpected(expectedResult, deviationFromExpected);
389 cy.deepCompare(xhr.request.body, expectedResult);
395 function bodyOf(xhr: Cypress.WaitXHR) {
396 return JSON.parse(JSON.stringify(xhr.request.body));
399 function setDeviationInExpected(expectedResult: any, deviations: { path: PropertyPath; value: any }[]) {
400 for (const deviation of deviations) {
401 _.set(expectedResult, deviation.path, deviation.value);
405 function findPathOfLatestVfModule(serviceInstanceElementFromRedux: any, vfModulesContainerPath: string[]) {
406 let latestVfModuleRandomlySelectedKey: string = _.last(_.keys(
407 _.get(serviceInstanceElementFromRedux, vfModulesContainerPath)
410 return [...vfModulesContainerPath, latestVfModuleRandomlySelectedKey];
413 //We use this function because the deployService() on drawing-board-header.component class
414 // changes rollbackOnFailure value from string type to boolean.
415 function convertRollbackOnFailureValueFromStringToBoolean(expectedResult: any) {
416 expectedResult.rollbackOnFailure = Boolean(expectedResult.rollbackOnFailure);
419 function removeIsDirtyFieldFromXhrRequestBody(xhr: any) {
420 let xhrTempBody = bodyOf(xhr);
421 delete xhrTempBody.isDirty;
425 function mockAsyncBulkResponse() {
427 url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
431 }).as("expectedPostAsyncInstantiation");