When feature toggle is active then SDNC preload files is enable. 84/100584/11
authorYoav Schneiderman <yoav.schneiderman@intl.att.com>
Wed, 22 Jan 2020 09:07:00 +0000 (11:07 +0200)
committerYoav Schneiderman <yoav.schneiderman@intl.att.com>
Mon, 27 Jan 2020 15:36:26 +0000 (17:36 +0200)
Issue-ID: VID-752

Change-Id: I96ef914bfe37d82da20085227b930523fcdba8fc
Signed-off-by: Yoav Schneiderman <yoav.schneiderman@intl.att.com>
33 files changed:
features.properties.md
vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/properties/Features.java
vid-automation/src/main/java/vid/automation/test/infra/Features.java
vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts
vid-webpack-master/cypress/integration/iFrames/sdncPreload.e2e.ts [new file with mode: 0644]
vid-webpack-master/cypress/support/index.js
vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
vid-webpack-master/cypress/support/steps/drawingBoard/drawingBoardRecreate.steps.ts [new file with mode: 0644]
vid-webpack-master/cypress/support/steps/drawingBoard/general.steps.ts
vid-webpack-master/cypress/support/uploadFiles/sdncPreLoadFileExample.json [new file with mode: 0644]
vid-webpack-master/package.cypress.json
vid-webpack-master/package.json
vid-webpack-master/src/app/shared/components/formControls/component/checkbox/checkbox.formControl.component.html
vid-webpack-master/src/app/shared/components/formControls/component/checkbox/checkbox.formControl.component.scss
vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/sharedControlles/shared.controllers.service.ts
vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vfModuleGenerator/vfModule.control.generator.spec.ts
vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vfModuleGenerator/vfModule.control.generator.ts
vid-webpack-master/src/app/shared/components/genericForm/generic-form.component.html
vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.html [new file with mode: 0644]
vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.scss [new file with mode: 0644]
vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.model.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/components/messageModal/message-modal.model.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/components/messageModal/message-modal.service.spec.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/components/messageModal/message-modal.service.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/models/formControlModels/checkboxFormControl.model.ts
vid-webpack-master/src/app/shared/models/formControlModels/formControl.model.ts
vid-webpack-master/src/app/shared/services/aaiService/aai.service.ts
vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts
vid-webpack-master/src/app/shared/shared.module.ts
vid-webpack-master/src/app/shared/utils/constants.ts
vid-webpack-master/src/styles.scss

index b2e453c..ce153b8 100644 (file)
 * FLAG_2004_INSTANTIATION_TEMPLATES_POPUP
   Enables a designated Templates selection modal, accessible when creating a new instance through "Browse SDC".
 
+* FLAG_2006_VFM_SDNC_PRELOAD_FILES
+  Enables upload files when SDNC preload checkbox is checked
+
 * FLAG_2002_UNLIMITED_MAX 
   when flag is true and max_instances is not declare than user can add unlimited VND, NETWORK, VFMODULE,
   User can duplicate up to 10 record in single time.
 * FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO
   On the "audit info" modal (available on Instantiation Status page), shows a link navigating to
   the read-only RETRY page with more audit info.
-  
-*FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY 
-  When flag is true the user will be provided with edit permissions by owning entity id even the user have no permission by Subscriber,
-   when the flag is false the user provided with edit permission by Subscriber.
-  
\ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java b/vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java
new file mode 100644 (file)
index 0000000..ba20997
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.controller;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping(PreLoadController.PRE_LOAD)
+public class PreLoadController extends VidRestrictedBaseController{
+    public static final String PRE_LOAD = "preload";
+
+    @PostMapping()
+    public Boolean postPreload (HttpServletRequest request) {
+        return true;
+    }
+}
index fd50321..2719046 100644 (file)
@@ -82,6 +82,7 @@ public enum Features implements Feature {
     FLAG_2004_INSTANTIATION_STATUS_FILTER,
     FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
     FLAG_2004_INSTANTIATION_TEMPLATES_POPUP,
+    FLAG_2006_VFM_SDNC_PRELOAD_FILES,
     FLAG_2002_UNLIMITED_MAX,
     FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO,
     FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY,
index 8495ceb..d981034 100644 (file)
@@ -57,7 +57,7 @@ public enum Features implements Feature {
     FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
     FLAG_2002_UNLIMITED_MAX,
     FLAG_2004_INSTANTIATION_TEMPLATES_POPUP,
-    FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY,
+    FLAG_2006_VFM_SDNC_PRELOAD_FILES,
     ;
 
     public boolean isActive() {
index d1bee9c..f7419ef 100644 (file)
@@ -25,7 +25,7 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it(`Given a stored template - when click "deploy" - then a coherent request should be sent upon deploy`, () => {
 
-        loadDrawingBoardWithRecreateMode();
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
 
         // Then...
         cy.getElementByDataTestsId("node-vProbe_NC_VNF 0").should('be.visible');
@@ -34,7 +34,7 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it('Given a template - User can remove existing VNF', () => {
 
-        loadDrawingBoardWithRecreateMode();
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
 
         removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
         removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
@@ -47,7 +47,7 @@ describe('Drawing Board: Instantiation Templates', function () {
       });
 
       it('Given a template - User can add new VNF', () => {
-        loadDrawingBoardWithRecreateMode();
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
         // add new node
         addNewNode('node-vProbe_NC_VNF 0-add-btn')
           .fillVnfPopup()
@@ -66,10 +66,10 @@ describe('Drawing Board: Instantiation Templates', function () {
 
 
           // check instance name not change if empty
-          editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
+          cy.editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
             .clearInput('instanceName');
           cy.getElementByDataTestsId('form-set').click({force: true}).then((done) => {
-            editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
+            cy.editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
               .getElementByDataTestsId('instanceName').should('be.empty')
           });
         });
@@ -77,8 +77,8 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it('Given a template - User can Duplicate VNF', () => {
         const numberOfDuplicate: number = 4;
-        loadDrawingBoardWithRecreateMode();
-        nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+        cy.nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
           .getElementByDataTestsId('duplicate-amount-vfmodules').select(numberOfDuplicate.toString())
           .getTagElementContainsText('button', 'Duplicate').click()
           .getDrawingBoardDeployBtn().click()
@@ -89,10 +89,10 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it('Given a stored template - when "edit" vnf and vfmodules are opened - then template’s details are visible as expected and deploy without changes', () => {
 
-        loadDrawingBoardWithRecreateMode();
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
 
         // Then...
-        editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
+        cy.editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007')
           .getElementByDataTestsId("productFamily").should('contain', 'Emanuel')
           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
@@ -102,14 +102,14 @@ describe('Drawing Board: Instantiation Templates', function () {
           .checkPlatformValue('xxx1')
           .getElementByDataTestsId("cancelButton").click();
 
-        editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
+        cy.editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007_lba_Base_01')
           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
           .getElementByDataTestsId("cancelButton").click();
 
-        editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
+        cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
           .getElementByDataTestsId("instanceName").should('have.value', 'my_hvf6arlba007_lba_dj_01')
           .getElementByDataTestsId("volumeGroupName").should('have.value', 'my_special_hvf6arlba007_lba_dj_01_vol')
           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
@@ -126,7 +126,7 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it(`Given a stored template - when "edit" service is opened - then template’s details are visible as expected`, function () {
 
-        loadDrawingBoardWithRecreateMode();
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
 
         cy.openServiceContextMenu()
           .getElementByDataTestsId("context-menu-header-edit-item").click()
@@ -140,7 +140,7 @@ describe('Drawing Board: Instantiation Templates', function () {
       });
 
       it(`Given a stored template - add one VfModule, edit its details, and deploy - deploy is added with the vfModule details`, () => {
-        loadDrawingBoardWithRecreateMode();
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
 
         let newVfModuleName = "new.vfmodule.name";
         let module1ModelId = "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1";
@@ -153,7 +153,7 @@ describe('Drawing Board: Instantiation Templates', function () {
         cy.drawingBoardPressAddButtonByElementName(`node-${module1CustomizationId}`)
           .click({force: true});
 
-        editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
+        cy.editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
         cy.clearInput("instanceName");
         cy.typeToInput("instanceName", newVfModuleName);
         cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
@@ -196,8 +196,8 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it('Given a template - User can remove existing vfmodule', function () {
 
-        loadDrawingBoardWithRecreateMode();
-        nodeAction('node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1', 'Remove');
+        cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+        cy.nodeAction('node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1', 'Remove');
         let removed_vfModule_Path = [
           ...vnfPath, "vfModules",
           "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
@@ -217,7 +217,7 @@ describe('Drawing Board: Instantiation Templates', function () {
 
         it(`Given a stored template - edit service vnf and vfmodule ${testCase.desc} - deploy request should be ${testCase.desc}`, function () {
 
-          loadDrawingBoardWithRecreateMode();
+          cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
 
           //edit service
           cy.openServiceContextMenu();
@@ -229,7 +229,7 @@ describe('Drawing Board: Instantiation Templates', function () {
           cy.getElementByDataTestsId('form-set').click();
 
           // edit vnf
-          editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
+          cy.editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
           if (testCase.modifySomeValues) {
             cy.selectPlatformValue('platform');
             cy.selectDropdownOptionByText("tenant", "CESAR-100-D-spjg61909");
@@ -237,7 +237,7 @@ describe('Drawing Board: Instantiation Templates', function () {
           cy.getElementByDataTestsId('form-set').click();
 
           //edit vf module
-          editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
+          cy.editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
           if (testCase.modifySomeValues) {
             cy.getElementByDataTestsId('sdncPreLoad').click();
           }
@@ -266,7 +266,7 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it(`Given a stored template of Network - - it is loaded`, () => {
 
-        loadDrawingBoardWithRecreateModeNetwork();
+        cy.loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup);
 
         // Then...
         cy.getElementByDataTestsId("node-SR-IOV Provider 2-1").should('be.visible');
@@ -276,9 +276,9 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it(`Given a stored template of Network - User can remove existing network`, () => {
 
-        loadDrawingBoardWithRecreateModeNetwork();
+        cy.loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup);
 
-        nodeAction('node-01f4c475-3f89-4f00-a2f4-39a873dba0ae-SR-IOV Provider 2-1', 'Remove');
+        cy.nodeAction('node-01f4c475-3f89-4f00-a2f4-39a873dba0ae-SR-IOV Provider 2-1', 'Remove');
         let removed_network_Path = [
           "networks", "SR-IOV Provider 2-1",
         ];
@@ -295,7 +295,7 @@ describe('Drawing Board: Instantiation Templates', function () {
 
       it('Given a template - User can add a new network', () => {
 
-        loadDrawingBoardWithRecreateModeNetwork();
+        cy.loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup);
 
         // add new node
         addNewNode('node-SR-IOV Provider 2-1-add-btn')
@@ -341,58 +341,14 @@ const vnfPath2 = [
   "vnfs", "vProbe_NC_VNF 0_1"
 ];
 
-function loadDrawingBoardWithRecreateMode() {
-  loadDrawingBoardWithRecreateModeInternal(
-    '../../' + templateWithVnfSetup.instanceTemplateFile,
-    templateWithVnfSetup.serviceModelId,
-    templateWithVnfSetup.serviceModelFile);
-}
-
-function loadDrawingBoardWithRecreateModeNetwork() {
-  loadDrawingBoardWithRecreateModeInternal(
-    '../../' + templateWithNetworkSetup.instanceTemplateFile,
-    templateWithNetworkSetup.serviceModelId,
-    templateWithNetworkSetup.serviceModelFile);
-}
-
-function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
-  const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
-
-  const drawingBoardAction = `RECREATE`;
-  const templateTopologyEndpoint = "templateTopology";
-  cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
-    'fixture:' + serviceModel)
-    .as('serviceModel');
-
-  cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
-    'fixture:' + instanceTemplate)
-    .as('templateTopology');
-
-  // When...
 
-  cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
-    `?jobId=${templateUuid}` +
-    `&serviceModelId=${serviceModelIdToLoad}`);
-
-  cy.wait('@serviceModel');
-  cy.wait('@templateTopology');
-}
-
-function nodeAction(dataTestId: string, action: string, index ?: number) {
-  return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
-    .drawingBoardTreeClickOnContextMenuOptionByName(action)
-}
-
-function editNode(dataTestId: string, index ?: number) {
-  return nodeAction(dataTestId, 'Edit', index);
-}
 
 function addNewNode(dataTestId: string) {
   return cy.getElementByDataTestsId(dataTestId).click({force: true})
 }
 
 function removeVNFWithVFModules(dataTestId: string) {
-  return nodeAction(dataTestId, 'Remove')
+  return cy.nodeAction(dataTestId, 'Remove')
     .getTagElementContainsText('button', 'Remove VNF').click()
 }
 
@@ -465,6 +421,7 @@ function mockAsyncBulkResponse() {
     url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
     method: 'POST',
     status: 200,
-    response: "[]",
+    response: true,
   }).as("expectedPostAsyncInstantiation");
 }
+
diff --git a/vid-webpack-master/cypress/integration/iFrames/sdncPreload.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/sdncPreload.e2e.ts
new file mode 100644 (file)
index 0000000..877506c
--- /dev/null
@@ -0,0 +1,92 @@
+describe('SDNC preload ', () => {
+
+  beforeEach(() => {
+    cy.clearSessionStorage();
+    cy.setTestApiParamToGR();
+    cy.initAAIMock();
+    cy.initGetAAISubDetails();
+    cy.initVidMock();
+    cy.initDrawingBoardUserPermission();
+    cy.login();
+  });
+
+  afterEach(() => {
+    cy.screenshot();
+  });
+
+  it('feature toggle is on and SDNC is checked then SDNC preload file is enable : upload success' , () => {
+    mockPreloadResult(true, 200);
+    cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+    cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1");
+    checkUploadLinkLogic();
+
+    uploadFile().then(() => {
+      cy.get('.sdc-modal__content').should('contain', 'The pre-load file(s) have been uploaded successfully.');
+      cy.getElementByDataTestsId('button-ok').click()
+        .getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload another')
+    });
+  });
+
+  it('feature toggle is on and SDNC is checked then SDNC preload file is enable : upload fail', () => {
+    mockPreloadResult(false, 200);
+    cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+
+    cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1");
+    checkUploadLinkLogic();
+
+    uploadFile().then(() => {
+      cy.get('.sdc-modal__content').should('contain', 'Failed to upload one or more of the files, please retry.');
+      cy.getElementByDataTestsId('button-ok').click()
+        .getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload')
+    });
+  });
+});
+
+
+let apiTestResources = '../vid-automation/src/test/resources/asyncInstantiation/';
+
+const templateWithVnfSetup = {
+  serviceModelId: '6cfeeb18-c2b0-49df-987a-da47493c8e38',
+  instanceTemplateFile: apiTestResources + 'templates__instance_template.json',
+  instanceTemplateSetWithoutModifyFile: apiTestResources + 'templates__instance_from_template__set_without_modify1.json',
+  serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model.json',
+};
+
+function mockAsyncBulkResponse() {
+  cy.server().route({
+    url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
+    method: 'POST',
+    status: 200,
+    response: true,
+  }).as("expectedPostAsyncInstantiation");
+}
+
+function mockPreloadResult(response: boolean, status?: number) {
+  cy.server().route({
+    url: Cypress.config('baseUrl') + '/preload',
+    method: 'POST',
+    status: status ? status : 200,
+    response: response,
+  }).as("preload");
+}
+
+
+function uploadFile() {
+  // @ts-ignore
+  return new Promise((resolve) => {
+    const fileName = '../support/uploadFiles/sdncPreLoadFileExample.json';
+    cy.fixture(fileName).then(fileContent => {
+      // @ts-ignore
+      cy.get('input[type=file]').eq(0).upload({fileContent, fileName, mimeType: 'application/json'}).then(() => {
+        resolve();
+      });
+    })
+  });
+}
+
+function checkUploadLinkLogic() {
+  cy.getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload').should('not.have.class', 'disabled')
+    .getElementByDataTestsId('sdncPreLoad').click()
+    .getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload').should('have.class', 'disabled')
+    .getElementByDataTestsId('sdncPreLoad').click()
+}
index 5062f51..d9e64c0 100644 (file)
@@ -15,6 +15,7 @@
 
 // Import commands.js using ES2015 syntax:
 import './commands';
+import 'cypress-file-upload';
 import './steps/login.step';
 import './steps/fill.service.popup.step';
 import './steps/fill.vnf.popup.step';
@@ -36,12 +37,14 @@ import './steps/drawingBoard/drawingBoardModel.steps';
 import './steps/drawingBoard/drawingBoardTree.steps';
 import './steps/genericForm/genericFormAction.steps';
 import './steps/genericForm/popupViewport.step';
-import './steps/drawingBoard/drawingBoardHeader.steps';
 import './steps/drawingBoard/general.steps';
+import './steps/drawingBoard/drawingBoardRecreate.steps';
+import './steps/drawingBoard/drawingBoardHeader.steps';
 import './steps/general/clickOutside.step';
 import './steps/drawingBoard/drawingBoardComponentInfo.steps';
 import './steps/genericForm/checkPopover.step';
 
+
 // Alternatively you can use CommonJS syntax:
 // require('./commands')
 
index bd9fb90..e2b9d8a 100644 (file)
@@ -23,5 +23,5 @@
   "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP" : false,
   "FLAG_2002_UNLIMITED_MAX" : true,
   "FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE": true,
-  "FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY": true
+  "FLAG_2006_VFM_SDNC_PRELOAD_FILES" : true
 }
diff --git a/vid-webpack-master/cypress/support/steps/drawingBoard/drawingBoardRecreate.steps.ts b/vid-webpack-master/cypress/support/steps/drawingBoard/drawingBoardRecreate.steps.ts
new file mode 100644 (file)
index 0000000..16f418b
--- /dev/null
@@ -0,0 +1,52 @@
+declare namespace Cypress {
+  interface Chainable {
+    loadDrawingBoardWithRecreateMode: typeof loadDrawingBoardWithRecreateMode ,
+    loadDrawingBoardWithRecreateModeNetwork: typeof loadDrawingBoardWithRecreateModeNetwork,
+    loadDrawingBoardWithRecreateModeInternal: typeof loadDrawingBoardWithRecreateModeInternal
+  }
+}
+
+function loadDrawingBoardWithRecreateMode(templateWithVnfSetup : any) {
+  cy.loadDrawingBoardWithRecreateModeInternal(
+    '../../' + templateWithVnfSetup.instanceTemplateFile,
+    templateWithVnfSetup.serviceModelId,
+    templateWithVnfSetup.serviceModelFile);
+}
+
+function loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup : any) {
+  cy.loadDrawingBoardWithRecreateModeInternal(
+    '../../' + templateWithNetworkSetup.instanceTemplateFile,
+    templateWithNetworkSetup.serviceModelId,
+    templateWithNetworkSetup.serviceModelFile);
+}
+
+function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
+  const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
+
+  const drawingBoardAction = `RECREATE`;
+  const templateTopologyEndpoint = "templateTopology";
+  cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
+    'fixture:' + serviceModel)
+    .as('serviceModel');
+
+  cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
+    'fixture:' + instanceTemplate)
+    .as('templateTopology');
+
+  // When...
+
+  cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
+    `?jobId=${templateUuid}` +
+    `&serviceModelId=${serviceModelIdToLoad}`);
+
+  cy.wait('@serviceModel');
+  cy.wait('@templateTopology');
+}
+
+
+
+
+
+Cypress.Commands.add('loadDrawingBoardWithRecreateMode', loadDrawingBoardWithRecreateMode);
+Cypress.Commands.add('loadDrawingBoardWithRecreateModeNetwork', loadDrawingBoardWithRecreateModeNetwork);
+Cypress.Commands.add('loadDrawingBoardWithRecreateModeInternal', loadDrawingBoardWithRecreateModeInternal);
index 8d2bb8a..797fff0 100644 (file)
@@ -1,7 +1,10 @@
 declare namespace Cypress {
   interface Chainable {
     updateServiceShouldNotOverrideChild: typeof updateServiceShouldNotOverrideChild
-    openServiceContextMenu: typeof openServiceContextMenu
+    openServiceContextMenu: typeof openServiceContextMenu,
+    drawingBoardTreeClickOnContextMenuOptionByName : typeof  drawingBoardTreeClickOnContextMenuOptionByName,
+    nodeAction: typeof nodeAction,
+    editNode : typeof editNode
   }
 }
 
@@ -18,7 +21,6 @@ function updateServiceShouldNotOverrideChild() : void  {
           });
         });
     });
-
 }
 
 
@@ -26,5 +28,36 @@ function openServiceContextMenu() :  Chainable<any> {
  return cy.getElementByDataTestsId('openMenuBtn').click({force: true});
 }
 
+function nodeAction(dataTestId: string, action: string, index ?: number) {
+  return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
+    .drawingBoardTreeClickOnContextMenuOptionByName(action)
+}
+
+function drawingBoardTreeClickOnContextMenuOptionByName(optionName : string) : Chainable<any>  {
+  switch (optionName) {
+    case 'Duplicate':
+      return cy.getElementByDataTestsId('context-menu-duplicate').click({force : true});
+    case 'Remove':
+      return cy.getElementByDataTestsId('context-menu-remove').click({force : true});
+    case 'Edit':
+      return cy.getElementByDataTestsId('context-menu-edit').click({force : true});
+    case 'Delete':
+      return cy.getElementByDataTestsId('context-menu-delete').trigger('mouseover').click();
+    case 'Upgrade':
+      return cy.getElementByDataTestsId('context-menu-upgrade').trigger('mouseover').click();
+    case 'Undo Upgrade':
+      return cy.getElementByDataTestsId('context-menu-undoUpgrade').trigger('mouseover').click();
+    default:
+      return cy.getElementByDataTestsId('context-menu-duplicate').click({force : true});
+  }
+}
+
+function editNode(dataTestId: string, index ?: number) {
+  return cy.nodeAction(dataTestId, 'Edit', index);
+}
+
 Cypress.Commands.add('updateServiceShouldNotOverrideChild', updateServiceShouldNotOverrideChild);
 Cypress.Commands.add('openServiceContextMenu', openServiceContextMenu);
+Cypress.Commands.add('drawingBoardTreeClickOnContextMenuOptionByName', drawingBoardTreeClickOnContextMenuOptionByName);
+Cypress.Commands.add('nodeAction', nodeAction);
+Cypress.Commands.add('editNode', editNode);
diff --git a/vid-webpack-master/cypress/support/uploadFiles/sdncPreLoadFileExample.json b/vid-webpack-master/cypress/support/uploadFiles/sdncPreLoadFileExample.json
new file mode 100644 (file)
index 0000000..c317c41
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "comment" : "invalid file, just for upload mock file"
+}
index da6aa60..8ce197f 100644 (file)
@@ -16,6 +16,7 @@
     "cypress": "3.6.1",
     "typescript": "3.1.6",
     "rxjs": "^6.3.3",
-    "rxjs-compat": "^6.3.3"
+    "rxjs-compat": "^6.3.3",
+    "cypress-file-upload": "^3.5.3"
   }
 }
index 1843de0..fdaf3e3 100755 (executable)
@@ -59,6 +59,7 @@
     "moment": "^2.24.0",
     "ng-multiselect-dropdown": "0.1.3",
     "ng2-bootstrap-modal": "1.0.1",
+    "ng2-file-upload": "^1.4.0",
     "ngx-bootstrap": "^2.0.2",
     "ngx-contextmenu": "^5.1.1",
     "ngx-datatable": "1.0.3",
     "@types/node": "^10.12.18",
     "angular2-template-loader": "0.6.2",
     "babel-jest": "24.1.0",
+    "blueimp-file-upload": "^10.7.0",
     "codelyzer": "^5.0.1",
     "cypress": "3.6.1",
+    "cypress-file-upload": "^3.5.3",
     "hammerjs": "2.0.8",
     "husky": "^1.3.1",
     "istanbul-reports": "2.1.1",
index 26362eb..fe7744e 100644 (file)
@@ -8,4 +8,9 @@
          data-toggle="toggle">
   <label class="checkbox-label"
          for="{{data?.dataTestId}}">{{data?.displayName}}</label>
+  <div *ngFor="let extraContent of data?.extraContents" class="form-conrtols">
+    <div [ngSwitch]="extraContent.type">
+      <upload-files *ngSwitchCase="'UPLOAD_FILE'" [uploadFilesModel]="extraContent" [form]="form"></upload-files>
+    </div>
+  </div>
 </div>
index acfaf78..83f7227 100644 (file)
@@ -133,13 +133,14 @@ export class SharedControllersService {
     })
   };
 
-  getSDNCControl = (instance: any): FormControlModel => {
+  getSDNCControl = (instance: any, extraContents? : object[]): FormControlModel => {
     return new CheckboxFormControl({
       controlName: SDN_C_PRE_LOAD,
       displayName: 'SDN-C pre-load',
       dataTestId: 'sdncPreLoad',
       value: instance ? instance.sdncPreLoad : false,
-      validations: [new ValidatorModel(ValidatorOptions.required, 'is required')]
+      validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
+      extraContents
     })
   };
 
index b3bb1fe..49deb3a 100644 (file)
@@ -4,7 +4,7 @@ import {NgRedux} from '@angular-redux/store';
 import {ControlGeneratorUtil, SDN_C_PRE_LOAD} from "../control.generator.util.service";
 import {AaiService} from "../../../../services/aaiService/aai.service";
 import {GenericFormService} from "../../generic-form.service";
-import {FormBuilder} from "@angular/forms";
+import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
 import {LogService} from "../../../../utils/log/log.service";
 import {
   FormControlModel,
@@ -16,6 +16,7 @@ import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flag
 import {VfModuleInstance} from "../../../../models/vfModuleInstance";
 import {VfModule} from "../../../../models/vfModule";
 import {SharedControllersService} from "../sharedControlles/shared.controllers.service";
+import {AppState} from "../../../../store/reducers";
 import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
 
 class MockAppStore<T> {
@@ -919,6 +920,7 @@ describe('VFModule Control Generator', () => {
   let injector;
   let service: VfModuleControlGenerator;
   let httpMock: HttpTestingController;
+  let store : NgRedux<AppState>;
 
   beforeAll(done => (async () => {
     TestBed.configureTestingModule({
@@ -939,6 +941,7 @@ describe('VFModule Control Generator', () => {
     injector = getTestBed();
     service = injector.get(VfModuleControlGenerator);
     httpMock = injector.get(HttpTestingController);
+    store = injector.get(NgRedux);
     jest.spyOn(console, 'error');
 
   })().then(done).catch(done.fail));
@@ -1164,5 +1167,29 @@ describe('VFModule Control Generator', () => {
       expect(controls[i].controlName).toEqual(orderedControls[i]);
     }
   });
+
+
+  test('when flag is active - response should contains upload file', ()=>{
+    spyOn(store, 'getState').and.returnValue( {
+      "global": {
+        "flags": {
+          "FLAG_2006_VFM_SDNC_PRELOAD_FILES" : true
+        }
+      }
+    });
+
+    const extraContent = service.getSdncExtraContents();
+    console.log("extraContent", extraContent);
+    const uploadFileData = <any>extraContent[0];
+
+    expect(uploadFileData.type).toEqual('UPLOAD_FILE');
+    expect(uploadFileData.dataTestId).toEqual('sdnc_pereload_upload_link');
+    expect(uploadFileData.uploadMethod).toBeDefined();
+    expect(uploadFileData.isDisabled).toBeDefined();
+    expect(uploadFileData.onSuccess).toBeDefined();
+    expect(uploadFileData.onFailed).toBeDefined();
+
+  })
+
 });
 
index b00312d..5189af0 100644 (file)
@@ -3,7 +3,7 @@ import {GenericFormService} from "../../generic-form.service";
 import {AaiService} from "../../../../services/aaiService/aai.service";
 import {NgRedux} from "@angular-redux/store";
 import {HttpClient} from "@angular/common/http";
-import {ControlGeneratorUtil} from "../control.generator.util.service";
+import {ControlGeneratorUtil, SDN_C_PRE_LOAD} from "../control.generator.util.service";
 import {
   CustomValidatorOptions,
   FormControlModel,
@@ -20,6 +20,8 @@ import {VNFModel} from "../../../../models/vnfModel";
 import {VnfInstance} from "../../../../models/vnfInstance";
 import * as _ from 'lodash';
 import {SharedControllersService} from "../sharedControlles/shared.controllers.service";
+import {MessageModal} from "../../../messageModal/message-modal.service";
+import {ButtonType} from "../../../customModal/models/button.type";
 import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
 
 export enum FormControlNames {
@@ -36,7 +38,7 @@ export enum FormControlNames {
 export class VfModuleControlGenerator {
   aaiService: AaiService;
   vfModuleModel: VfModule;
-  isUpdateMode : boolean;
+  isUpdateMode: boolean;
 
   constructor(private genericFormService: GenericFormService,
               private _basicControlGenerator: ControlGeneratorUtil,
@@ -54,7 +56,7 @@ export class VfModuleControlGenerator {
     if (isUpdateMode && this.store.getState().service.serviceInstance[serviceId] &&
       _.has(this.store.getState().service.serviceInstance[serviceId].vnfs, vnfStoreKey) &&
       _.has(this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules, UUIDData['modelName'])) {
-       vfModuleInstance = Object.assign({},this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules[UUIDData['modelName']][UUIDData['vFModuleStoreKey']]);
+      vfModuleInstance = Object.assign({}, this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules[UUIDData['modelName']][UUIDData['vFModuleStoreKey']]);
     }
     return vfModuleInstance;
   };
@@ -65,11 +67,11 @@ export class VfModuleControlGenerator {
     return vfModule;
   }
 
-  getMacroFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
+  getMacroFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData: Object, isUpdateMode: boolean): FormControlModel[] {
     this.isUpdateMode = isUpdateMode;
     this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
     if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
-      if(isUpdateMode){
+      if (isUpdateMode) {
         this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
         return [];
       }
@@ -85,7 +87,7 @@ export class VfModuleControlGenerator {
     if (!_.isNil(vfModuleModel)) {
       result = this.pushInstanceAndVGToForm(result, vfModuleInstance, serviceId, vnfModel, false);
     }
-    if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
+    if (this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
       result = this._basicControlGenerator.concatSupplementaryFile(result, vfModuleInstance);
     }
     return result;
@@ -99,7 +101,7 @@ export class VfModuleControlGenerator {
     return new VNFModel(model);
   }
 
-  pushInstanceAndVGToForm(result: FormControlModel[], vfModuleElement: any, serviceId: string, vnfModel: any, isALaCarte: boolean) :FormControlModel[]{
+  pushInstanceAndVGToForm(result: FormControlModel[], vfModuleElement: any, serviceId: string, vnfModel: any, isALaCarte: boolean): FormControlModel[] {
     result.push(this.getInstanceName(vfModuleElement, serviceId, vnfModel.isEcompGeneratedNaming));
     if (this.vfModuleModel.volumeGroupAllowed) {
       result.push(this.getVolumeGroupData(vfModuleElement, serviceId, vnfModel.isEcompGeneratedNaming, isALaCarte));
@@ -107,16 +109,16 @@ export class VfModuleControlGenerator {
     return result;
   }
 
-  getAlaCarteFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
+  getAlaCarteFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData: Object, isUpdateMode: boolean): FormControlModel[] {
     this.isUpdateMode = isUpdateMode;
     this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
     if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
-      if(isUpdateMode){
+      if (isUpdateMode) {
         this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
         return [];
       }
     }
-    const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey] ;
+    const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
     const vnfModel = this.newVNFModel(serviceId, vnf);
 
     const vfModuleInstance = this._basicControlGenerator.retrieveInstanceIfUpdateMode(this.store, this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode));
@@ -126,26 +128,64 @@ export class VfModuleControlGenerator {
     result.push(this._sharedControllersService.getLegacyRegion(vfModuleInstance));
     result.push(this._sharedControllersService.getTenantControl(serviceId, vfModuleInstance));
     result.push(this._sharedControllersService.getRollbackOnFailureControl(vfModuleInstance));
-    result.push(this._sharedControllersService.getSDNCControl(vfModuleInstance));
-    if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
+    result.push(this._sharedControllersService.getSDNCControl(vfModuleInstance, this.getSdncExtraContents()));
+    if (this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
       result = this._basicControlGenerator.concatSupplementaryFile(result, vfModuleInstance);
     }
     return result;
   }
 
-  getInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): FormControlModel {
-    let formControlModel:FormControlModel = this._sharedControllersService.getInstanceNameController(instance, serviceId, isEcompGeneratedNaming, this.vfModuleModel);
-    formControlModel.onBlur = (event, form : FormGroup) => {
-        if(!_.isNil(form.controls['volumeGroupName'])&& event.target.value.length > 0){
-          form.controls['volumeGroupName'].setValue(event.target.value + "_vol");
+  getSdncExtraContents() : object[] {
+    return _.compact([
+      !!this.store.getState().global.flags['FLAG_2006_VFM_SDNC_PRELOAD_FILES'] ? {
+        type: 'UPLOAD_FILE',
+        dataTestId: 'sdnc_pereload_upload_link',
+        uploadMethod: (form: FormGroup) : Promise<boolean> => {
+          // this -> files item
+          return this._aaiService.sdncPreload().toPromise()
+            .then((response : boolean)=>{
+              return response;
+            }).catch(err => {
+              return false;
+            });
+        },
+        isDisabled: (form: FormGroup): boolean => {
+          return !form.controls[SDN_C_PRE_LOAD].value;
+        },
+        onSuccess: (form: FormGroup): void => {
+          MessageModal.showMessageModal({
+            text: 'The pre-load file(s) have been uploaded successfully.',
+            type: "success",
+            title: 'Success',
+            buttons: [{type: ButtonType.success, size: 'large', text: 'OK', closeModal: true}]
+          })
+        },
+        onFailed: (form: FormGroup) : void=> {
+          MessageModal.showMessageModal({
+            text: 'Failed to upload one or more of the files, please retry.',
+            type: "error",
+            title: 'Failure',
+            buttons: [{type: ButtonType.error, size: 'large', text: 'OK', closeModal: true}]
+          })
         }
-      };
+      } : null
+    ]);
+  }
+
+
+  getInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): FormControlModel {
+    let formControlModel: FormControlModel = this._sharedControllersService.getInstanceNameController(instance, serviceId, isEcompGeneratedNaming, this.vfModuleModel);
+    formControlModel.onBlur = (event, form: FormGroup) => {
+      if (!_.isNil(form.controls['volumeGroupName']) && event.target.value.length > 0) {
+        form.controls['volumeGroupName'].setValue(event.target.value + "_vol");
+      }
+    };
 
     return formControlModel;
   }
 
   getDefaultVolumeGroupName(instance: any, isEcompGeneratedNaming: boolean): string {
-    if ((!_.isNil(instance) && instance.volumeGroupName))  {
+    if ((!_.isNil(instance) && instance.volumeGroupName)) {
       return instance.volumeGroupName;
     }
     if (isEcompGeneratedNaming) {
@@ -165,12 +205,12 @@ export class VfModuleControlGenerator {
       displayName: 'Volume Group Name',
       dataTestId: 'volumeGroupName',
       validations: validations,
-      tooltip : 'When filled, VID will create a Volume Group by this name and associate with this module.\n' +
-                'When empty, the module is created without a Volume Group.',
-      isVisible: this.shouldVGNameBeVisible(isEcompGeneratedNaming,isALaCarte),
+      tooltip: 'When filled, VID will create a Volume Group by this name and associate with this module.\n' +
+        'When empty, the module is created without a Volume Group.',
+      isVisible: this.shouldVGNameBeVisible(isEcompGeneratedNaming, isALaCarte),
       value: this.getDefaultVolumeGroupName(instance, isEcompGeneratedNaming),
       onKeypress: (event) => {
-        const pattern:RegExp = ControlGeneratorUtil.INSTANCE_NAME_REG_EX;
+        const pattern: RegExp = ControlGeneratorUtil.INSTANCE_NAME_REG_EX;
         if (pattern) {
           if (!pattern.test(event['key'])) {
             event.preventDefault();
@@ -182,7 +222,7 @@ export class VfModuleControlGenerator {
   }
 
   private shouldVGNameBeVisible(isEcompGeneratedNaming: boolean, isALaCarte: boolean) {
-    if((!isALaCarte && !isEcompGeneratedNaming) || isALaCarte){
+    if ((!isALaCarte && !isEcompGeneratedNaming) || isALaCarte) {
       return true;
     }
     return false;
index edf8682..627f642 100644 (file)
@@ -3,7 +3,7 @@
     <div *ngFor="let formControl of formControls" class="form-conrtols">
       <div [ngSwitch]="formControl.type">
         <form-control-input  *ngSwitchCase="'INPUT'"   [data]="formControl" [form]="dynamicFormGroup"></form-control-input>
-        <checkbox-form-control *ngSwitchCase="'CHECKBOX'"  [data]="formControl" [form]="dynamicFormGroup" ></checkbox-form-control>
+        <checkbox-form-control *ngSwitchCase="'CHECKBOX'"  [data]="formControl" [form]="dynamicFormGroup"></checkbox-form-control>
         <dropdown-form-control *ngSwitchCase="'DROPDOWN'" [data]="formControl" [form]="dynamicFormGroup" ></dropdown-form-control>
         <file-form-control *ngSwitchCase="'FILE'" [data]="formControl" [form]="dynamicFormGroup"></file-form-control>
         <multiselect-form-control *ngSwitchCase="'MULTI_SELECT'"
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.html b/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.html
new file mode 100644 (file)
index 0000000..6f59c0c
--- /dev/null
@@ -0,0 +1,15 @@
+<div>
+  <a [attr.data-tests-id]="uploadFilesModel.dataTestId"
+     (click)="uploadFilesTrigger()"
+     href="javascript:void(0)"
+     class="upload-text"
+     [class.disabled]="uploadFilesModel.isDisabled &&  uploadFilesModel.isDisabled(form)">{{uploadFilesModel.uploadText || 'Upload'}}</a>
+  <span class="hide-span">
+     <input
+       type="file"
+       #fileInput
+       ng2FileSelect
+       [uploader]="uploader"
+       [attr.data-tests-id]="uploadFilesModel.dataTestId + '-input'"/>
+  </span>
+</div>
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.scss b/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.scss
new file mode 100644 (file)
index 0000000..ce9e14f
--- /dev/null
@@ -0,0 +1,23 @@
+.upload-text {
+  margin-left: 30px;
+  font-family: OpenSans-Semibold;
+  font-size: 14px;
+  line-height: 23px;
+}
+
+a.disabled {
+  color: gray;
+  cursor: not-allowed;
+  text-decoration: underline;
+}
+
+.hide-span {
+  visibility: hidden;
+  position: absolute;
+  overflow: hidden;
+  width: 0px;
+  height: 0px;
+  border: none;
+  margin: 0;
+  padding: 0
+}
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.ts b/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component.ts
new file mode 100644 (file)
index 0000000..803d5d0
--- /dev/null
@@ -0,0 +1,41 @@
+import {Component, ElementRef, Input, OnInit, ViewChild} from "@angular/core";
+import {FileItem, FileUploader} from "ng2-file-upload";
+import {UploadFilesLinkModel} from "./upload-files-link.model";
+import {FormGroup} from "@angular/forms";
+
+@Component({
+  selector: 'upload-files',
+  templateUrl: './upload-files-link.component.html',
+  styleUrls: ['./upload-files-link.component.scss']
+})
+export class UploadFilesLinkComponent implements OnInit {
+  uploader: FileUploader;
+  @Input() uploadFilesModel: UploadFilesLinkModel;
+  @Input() form: FormGroup;
+  @ViewChild('fileInput', {static: false}) fileInput: ElementRef;
+
+  ngOnInit(): void {
+    this.uploader = new FileUploader({});
+
+    this.uploader.onAfterAddingAll = async (files: FileItem[]) => {
+      const result = await this.uploadFilesModel.uploadMethod.call(files, this.form);
+      if (result && this.uploadFilesModel.onSuccess) {
+        this.uploadFilesModel.onSuccess.call(this.form);
+      } else if (!result && this.uploadFilesModel.onFailed) {
+        this.uploadFilesModel.onFailed.call(this.form);
+      }
+      this.uploadFilesModel.uploadText = result ? 'Upload another' : 'Upload'
+    };
+    this.resetUpload();
+  }
+
+  resetUpload(): void {
+    this.fileInput.nativeElement.value = '';
+  }
+
+  uploadFilesTrigger() {
+    if (this.uploadFilesModel.isDisabled && !this.uploadFilesModel.isDisabled(this.form)) {
+      this.fileInput.nativeElement.click();
+    }
+  }
+}
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.model.ts b/vid-webpack-master/src/app/shared/components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.model.ts
new file mode 100644 (file)
index 0000000..beb54f4
--- /dev/null
@@ -0,0 +1,30 @@
+import {FileItem} from "ng2-file-upload";
+
+export class UploadFilesLinkModel {
+  uploadText?: string;
+
+  /*********************************************************************
+   Implement success method - run after uploadMethod return true result
+   **********************************************************************/
+  onSuccess?: (...args) => void;
+
+  /*********************************************************************
+   Implement failed method - run after uploadMethod return false result
+   **********************************************************************/
+  onFailed?: (...args) => void;
+
+  /*********************************************************************************
+   Implement upload method and return the upload result status (false/true)
+   *********************************************************************************/
+  uploadMethod: (file: FileItem[], ...args) => Promise<boolean>;
+
+  /********************************
+   Should upload file be disabled
+   ********************************/
+  isDisabled?: (...args) => boolean;
+
+  /********************************
+   a tag data test id
+   ********************************/
+  dataTestId : string;
+}
diff --git a/vid-webpack-master/src/app/shared/components/messageModal/message-modal.model.ts b/vid-webpack-master/src/app/shared/components/messageModal/message-modal.model.ts
new file mode 100644 (file)
index 0000000..d291440
--- /dev/null
@@ -0,0 +1,15 @@
+import {ButtonType} from "../customModal/models/button.type";
+
+export class MessageModalModel {
+  title : string;
+  text : string;
+  type : 'error' | 'info' | 'success';
+  buttons :  {text: string, size: string, type : ButtonType, closeModal: boolean}[];
+
+  constructor( title : string, text : string, type , buttons : {text: string, size: string, type : ButtonType, closeModal: boolean}[]){
+    this.title = title;
+    this.text = text;
+    this.type = type;
+    this.buttons = buttons;
+  }
+}
diff --git a/vid-webpack-master/src/app/shared/components/messageModal/message-modal.service.spec.ts b/vid-webpack-master/src/app/shared/components/messageModal/message-modal.service.spec.ts
new file mode 100644 (file)
index 0000000..ffaccb1
--- /dev/null
@@ -0,0 +1,56 @@
+import {MessageModal} from "./message-modal.service";
+import {getTestBed, TestBed} from "@angular/core/testing";
+import {SdcUiCommon} from "onap-ui-angular";
+import each from "jest-each";
+import {MessageBoxService} from "../messageBox/messageBox.service";
+import {MessageModalModel} from "./message-modal.model";
+import {MessageBoxData} from "../messageBox/messageBox.data";
+
+
+describe('Message Modal Service', () => {
+  let injector;
+  let service: MessageModal;
+
+  beforeAll(done => (async () => {
+    TestBed.configureTestingModule({
+      imports: [],
+      providers: [MessageModal]
+    });
+    await TestBed.compileComponents();
+
+    injector = getTestBed();
+    service = injector.get(MessageModal);
+  })().then(done).catch(done.fail));
+
+
+  each([
+    ["error", SdcUiCommon.ModalType.error],
+    ["info", SdcUiCommon.ModalType.info],
+    ["success", SdcUiCommon.ModalType.success]
+  ]).test('getModalType with type %s should return %s', (inputMessageType, expectedResult) => {
+
+    let message = {
+      type: inputMessageType
+    };
+
+    const type = MessageModal.getModalType(<any>message)
+    expect(type).toEqual(expectedResult);
+  });
+
+  test('showMessageModal should call open modal with all data' , async (done)=>{
+    spyOn(MessageBoxService.openModal, 'next');
+    let message : MessageModalModel  = new MessageModalModel('title', 'text',  "success", []);
+
+    MessageModal.showMessageModal(message);
+    setTimeout(()=>{
+      const messageBoxData = new MessageBoxData( message.title,
+        message.text,
+        SdcUiCommon.ModalType.success,
+        SdcUiCommon.ModalSize.medium,
+        message.buttons)
+      expect(MessageBoxService.openModal.next).toHaveBeenCalledWith(messageBoxData);
+      done();
+    }, 500)
+  });
+
+});
diff --git a/vid-webpack-master/src/app/shared/components/messageModal/message-modal.service.ts b/vid-webpack-master/src/app/shared/components/messageModal/message-modal.service.ts
new file mode 100644 (file)
index 0000000..e1f85bd
--- /dev/null
@@ -0,0 +1,39 @@
+import {Injectable} from "@angular/core";
+import {MessageBoxService} from '../messageBox/messageBox.service';
+import {MessageBoxData} from '../messageBox/messageBox.data';
+import {SdcUiCommon} from "onap-ui-angular";
+import {MessageModalModel} from "./message-modal.model";
+
+@Injectable()
+export class MessageModal {
+  static showMessageModal(message: MessageModalModel): void {
+    setTimeout(() => {
+        let messageBoxData: MessageBoxData = new MessageBoxData(
+          message.title,
+          message.text,
+          this.getModalType(message),
+          SdcUiCommon.ModalSize.medium,
+          message.buttons);
+        MessageBoxService.openModal.next(messageBoxData);
+      }
+      , 500);
+  };
+
+
+  static getModalType = (message: MessageModalModel): string => {
+    switch (message.type) {
+      case "error": {
+        return SdcUiCommon.ModalType.error
+      }
+      case "info": {
+        return  SdcUiCommon.ModalType.info;
+      }
+      case "success":  {
+        return  SdcUiCommon.ModalType.success;
+      }
+    }
+  };
+}
+
+
+
index f505b56..1675917 100644 (file)
@@ -1,11 +1,13 @@
 import {FormControlModel} from "./formControl.model";
 import {FormControlType} from "./formControlTypes.enum";
+import * as _ from "lodash";
 
 export class CheckboxFormControl extends FormControlModel{
-
+  extraContents : object[];
   constructor(data) {
     super(data);
     this.type = FormControlType.CHECKBOX;
     this.validations = [];
+    this.extraContents = !_.isNil(data.extraContents)  ? data.extraContents : null;
   }
 }
index 2411654..b3a53d9 100644 (file)
@@ -43,6 +43,7 @@ export class  FormControlModel {
     this.preventionsAttribute = data.preventionsAttribute || [];
     this.onBlur = function(){};
     this.onChange = data.onChange ? data.onChange: function () {}
+
   }
 
   isRequired() : boolean {
index 1cc5593..9026a56 100644 (file)
@@ -44,6 +44,11 @@ export class AaiService {
 
   }
 
+  sdncPreload(): Observable<boolean> {
+    let pathQuery: string = Constants.Path.PRE_LOAD;
+    return this.http.post<boolean>(pathQuery, {})
+  }
+
   getServiceModelById = (serviceModelId: string): Observable<any> => {
     if (_.has(this.store.getState().service.serviceHierarchy, serviceModelId)) {
       return of(<any> JSON.parse(JSON.stringify(this.store.getState().service.serviceHierarchy[serviceModelId])));
index db270de..722deca 100644 (file)
@@ -15,6 +15,7 @@ export enum Features {
   FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS ='FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS',
   FLAG_2004_INSTANTIATION_STATUS_FILTER ='FLAG_2004_INSTANTIATION_STATUS_FILTER',
   FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE = 'FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE',
+  FLAG_2006_VFM_SDNC_PRELOAD_FILES = 'FLAG_2006_VFM_SDNC_PRELOAD_FILES',
   FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO = 'FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO',
   FLAG_2004_INSTANTIATION_TEMPLATES_POPUP = 'FLAG_2004_INSTANTIATION_TEMPLATES_POPUP',
   FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY= 'FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY'
index 08b7fe5..bae7c11 100644 (file)
@@ -93,6 +93,9 @@ import {SvgIconComponent} from "./components/customIcon/custom-icon.component";
 import {TooltipTemplateComponent} from "./components/customTooltip/custom-tooltip.component";
 import {TooltipDirective} from "./components/customTooltip/tooltip.directive";
 import {SdcUiComponentsModule} from "onap-ui-angular";
+import {UploadFilesLinkComponent} from "./components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component";
+import { FileUploadModule } from 'ng2-file-upload';
+import {MessageModal} from "./components/messageModal/message-modal.service";
 
 
 
@@ -111,7 +114,8 @@ import {SdcUiComponentsModule} from "onap-ui-angular";
     AngularMultiSelectModule,
     BootstrapModalModule,
     DataTableModule,
-    ModalModule.forRoot()
+    ModalModule.forRoot(),
+    FileUploadModule
   ],
   declarations: [
     PopoverComponent,
@@ -156,7 +160,8 @@ import {SdcUiComponentsModule} from "onap-ui-angular";
     CustomModalButtonComponent,
     LoaderComponent,
     SvgIconComponent,
-    TooltipTemplateComponent
+    TooltipTemplateComponent,
+    UploadFilesLinkComponent
   ],
   exports: [
     PopoverComponent,
@@ -197,7 +202,8 @@ import {SdcUiComponentsModule} from "onap-ui-angular";
     CustomModalButtonComponent,
     LoaderComponent,
     SvgIconComponent,
-    TooltipTemplateComponent
+    TooltipTemplateComponent,
+    UploadFilesLinkComponent
   ],
   entryComponents : [
     GenericFormPopupComponent,
@@ -248,7 +254,8 @@ import {SdcUiComponentsModule} from "onap-ui-angular";
     ModelInformationService,
     MultiselectFormControlService,
     InstantiationTemplatesModalService,
-    LoaderService
+    LoaderService,
+    MessageModal
   ]
 })
 export class SharedModule {
index da717c8..01466f1 100644 (file)
@@ -97,6 +97,7 @@ export module Constants {
     public static SERVICE_MODEL_ID = 'serviceModelId';
     public static SERVICES_RETRY_TOPOLOGY = '../../asyncInstantiation/bulkForRetry';
     public static INSTANTIATION_TEMPLATE_TOPOLOGY = '../../instantiationTemplates/templateTopology';
+    public static PRE_LOAD = '../../preload';
     public static CONFIGURATION_PATH = '../../get_property/{name}/defaultvalue';
     public static SERVICES_JOB_AUDIT_PATH = '/auditStatus';
     public static SERVICES_PROBE_PATH = "../../probe";
index f170f35..1d332ed 100644 (file)
@@ -239,4 +239,6 @@ sdc-checkbox {
   display: none !important;
 }
 
-
+sdc-modal {
+  z-index:  10000 !important;
+}