add create another one menu item to instantiationStatus page

Issue-ID: VID-724
Signed-off-by: Eylon Malin <eylon.malin@intl.att.com>
Change-Id: I205bc276ec7ba59eae37207f0976867bd496043f
Signed-off-by: Eylon Malin <eylon.malin@intl.att.com>
diff --git a/features.properties.md b/features.properties.md
index a8fac83..8b80184 100644
--- a/features.properties.md
+++ b/features.properties.md
@@ -188,4 +188,10 @@
   When flag is true the platform will appear as a multi select field, if false the platform will be dropdown list.
   
 * FLAG_2004_INSTANTIATION_STATUS_FILTER
-  when flag is true the user can filter rows in instantiation status by using text input 
+  When flag is true the user can filter rows in instantiation status by using text input
+  
+* FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE
+  When flag is true, the user see in instantiation status page, an option to recreate another instance.
+  This option is enabled only for instantiate jobs.
+  IF the user click on this option, the previous instantiation is opened in drawing board, 
+  and the user can create another one from this template.
diff --git a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
index d1a0cf9..26bfec5 100644
--- a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
+++ b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
@@ -80,6 +80,7 @@
     FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS,
     FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
     FLAG_2004_INSTANTIATION_STATUS_FILTER,
+    FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
     FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER,
     ;
 
diff --git a/vid-webpack-master/cypress/integration/iFrames/instantiationStatus.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/instantiationStatus.e2e.ts
index 7e1311b..9610d68 100644
--- a/vid-webpack-master/cypress/integration/iFrames/instantiationStatus.e2e.ts
+++ b/vid-webpack-master/cypress/integration/iFrames/instantiationStatus.e2e.ts
@@ -7,6 +7,7 @@
 describe('Instantiation status', function () {
   var jsonBuilderInstantiationBuilder : JsonBuilder<AsyncInstantiationModel> = new JsonBuilder<AsyncInstantiationModel>();
   var asyncRes: Array<any>;
+  const contextMenuCreateAnotherOne = 'context-menu-recreate';
 
   beforeEach(() => {
       cy.clearSessionStorage();
@@ -70,7 +71,7 @@
     cy.get('table#instantiation-status tbody tr').should('have.length', 2);
   });
 
-  function getDropDownMenuByDataTestId(testId:String) {
+  function getDisabledDropDownItemByDataTestId(testId:String) {
     return cy.get('.dropdown-menu').find('.disabled').find(`[data-tests-id='${testId}']`);
   }
 
@@ -79,37 +80,56 @@
     cy.get('#' + jobId).find('.menu-div').click();
   }
 
-  it('should enable correct menu items', function () {
+  it('should disabled correct menu items', function () {
 
     cy.openIframe('app/ui/#/instantiationStatus');
 
     // Instantiate action with Job status FAILED - isRetry = true
 
     clickOnTitleAndThenOnMenuWithJobId('5c2cd8e5-27d0-42e3-85a1-85db5eaba459');
-    getDropDownMenuByDataTestId('context-menu-retry').should('not.exist');
-    getDropDownMenuByDataTestId('context-menu-remove').should('exist');
-    getDropDownMenuByDataTestId('context-menu-open').should('exist');
-    getDropDownMenuByDataTestId('context-menu-hide').should('not.exist');
-    getDropDownMenuByDataTestId('context-menu-audit-info').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-retry').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-remove').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-open').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-hide').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-audit-info').should('not.exist');
+    getDisabledDropDownItemByDataTestId(contextMenuCreateAnotherOne).should('not.exist');
 
     // Instantiate action with Job status FAILED - isRetry = false
     clickOnTitleAndThenOnMenuWithJobId('e1db03c3-6274-4ff7-84cf-7bd3a3946de7');
-    getDropDownMenuByDataTestId('context-menu-retry').should('not.be.visible');
-    getDropDownMenuByDataTestId('context-menu-open').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-retry').should('not.be.visible');
+    getDisabledDropDownItemByDataTestId('context-menu-open').should('exist');
+    getDisabledDropDownItemByDataTestId(contextMenuCreateAnotherOne).should('not.exist');
 
     //Delete action with Job status IN_PROGRESS
     clickOnTitleAndThenOnMenuWithJobId('850dc7d2-5240-437f-9bcd-b1ed7dc339c2');
-    getDropDownMenuByDataTestId('context-menu-remove').should('exist');
-    getDropDownMenuByDataTestId('context-menu-open').should('exist');
-    getDropDownMenuByDataTestId('context-menu-hide').should('exist');
-    getDropDownMenuByDataTestId('context-menu-audit-info').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-remove').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-open').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-hide').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-audit-info').should('not.exist');
+    getDisabledDropDownItemByDataTestId(contextMenuCreateAnotherOne).should('exist');
 
     //Update action with Job status COMPLETED
     clickOnTitleAndThenOnMenuWithJobId('850dc7d2-5240-437f-9bcd-b1ed7dc339c1');
-    getDropDownMenuByDataTestId('context-menu-remove').should('exist');
-    getDropDownMenuByDataTestId('context-menu-open').should('not.exist');
-    getDropDownMenuByDataTestId('context-menu-hide').should('not.exist');
-    getDropDownMenuByDataTestId('context-menu-audit-info').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-remove').should('exist');
+    getDisabledDropDownItemByDataTestId('context-menu-open').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-hide').should('not.exist');
+    getDisabledDropDownItemByDataTestId('context-menu-audit-info').should('not.exist');
+    getDisabledDropDownItemByDataTestId(contextMenuCreateAnotherOne).should('exist');
+  });
+
+  it('clicking on create another one item, go to expected url', function () {
+    //see cypress/support/jsonBuilders/mocks/jsons/asyncInstantiation.json id:8
+    const jobId = '5c2cd8e5-27d0-42e3-85a1-85db5eaba459';
+    const serviceModelId = 'e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0';
+    const vidBaseUrl = `http://localhost:8080/vid/serviceModels.htm`;
+
+    cy.openIframe('app/ui/#/instantiationStatus');
+
+    clickOnTitleAndThenOnMenuWithJobId(jobId);
+    cy.get('.dropdown-menu').getElementByDataTestsId(contextMenuCreateAnotherOne).click();
+    cy.location().should((loc) => {
+      expect(loc.toString()).to.eq(`${vidBaseUrl}#/servicePlanning/RECREATE?serviceModelId=${serviceModelId}&jobId=${jobId}`);
+    });
   });
 
 });
diff --git a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json b/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
index c7412ed..5e92e4f 100644
--- a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
+++ b/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
@@ -21,5 +21,6 @@
   "FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS": true,
   "FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER": true,
   "FLAG_2004_INSTANTIATION_STATUS_FILTER": true,
-  "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP" : false
+  "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP" : false,
+  "FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE": true
 }
diff --git a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.html b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.html
index 9ef98e5..8e9e536 100644
--- a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.html
+++ b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.html
@@ -74,7 +74,7 @@
             </svg-icon>
 
           </custom-popover>
-          <div class="menu-div" (click)="onContextMenu($event, data)">
+          <div class="menu-div" (click)="onContextMenu($event, data)" [attr.data-tests-id]="'menu-'+data.jobId">
             <span class="icon-menu"></span>
             <context-menu>
               <ng-template *ngFor="let action of contextMenuActions" contextMenuItem let-item
diff --git a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.spec.ts b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.spec.ts
index 29adfa9..eedd46d 100644
--- a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.spec.ts
+++ b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.spec.ts
@@ -5,36 +5,25 @@
 import {MsoService} from "../shared/services/msoService/mso.service";
 import {NgRedux} from "@angular-redux/store";
 import {HttpClientTestingModule} from "@angular/common/http/testing";
-import {FeatureFlagsService} from "../shared/services/featureFlag/feature-flags.service";
+import {FeatureFlagsService, Features} from "../shared/services/featureFlag/feature-flags.service";
 import {DrawingBoardModes} from "../drawingBoard/service-planning/drawing-board.modes";
 import {RouterTestingModule} from "@angular/router/testing";
 import {of} from "rxjs";
 import {UrlTree} from "@angular/router";
 import each from "jest-each";
 import {ServiceAction} from "../shared/models/serviceInstanceActions";
+import {instance, mock, when} from "ts-mockito";
 
 class MockAppStore<T> {
-
-  getState() {
-    return {
-      global: {
-        flags: {
-          'FLAG_1902_NEW_VIEW_EDIT': true,
-
-        }
-      }
-    }
-  }
-
-  dispatch() {
-
-  }
+  dispatch() {}
 }
+
 describe('Instantiation Status Service', () => {
   let injector;
   let aaiService: AaiService;
   let msoService: MsoService;
   let service: InstantiationStatusComponentService;
+  let mockFeatureFlagsService: FeatureFlagsService = mock(FeatureFlagsService);
 
 
   beforeAll(done => (async () => {
@@ -48,7 +37,9 @@
         AaiService,
         MsoService,
         FeatureFlagsService,
-        {provide: NgRedux, useClass: MockAppStore}]
+        {provide: NgRedux, useClass: MockAppStore},
+        {provide: FeatureFlagsService, useValue: instance(mockFeatureFlagsService)}
+      ]
     });
     await TestBed.compileComponents();
 
@@ -172,6 +163,15 @@
     expect(service.isRecreateEnabled(serviceInfoModel)).toBe(expected);
   });
 
+  each([
+    [true, true],
+    [false, false],
+  ]).
+  test('isRecreateVisible: should be %s if flag is %s', (expected:boolean, flag:boolean) => {
+    when(mockFeatureFlagsService.getFlagState(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)).thenReturn(flag);
+    expect(service.isRecreateVisible()).toEqual(expected);
+  });
+
   test('getStatusTooltip should return correct icon per job status', () => {
     let result : ServiceStatus  = service.getStatus('pending');
     expect(result.iconClassName).toEqual(PENDING);
diff --git a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.ts b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.ts
index 227fff1..4bfedd9 100644
--- a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.ts
+++ b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.service.ts
@@ -29,7 +29,8 @@
   constructor( private _aaiService: AaiService,
                private _msoService: MsoService,
                private _router : Router,
-               private _store: NgRedux<AppState>) {
+               private _store: NgRedux<AppState>,
+               private _featureFlagsService:FeatureFlagsService) {
   }
 
   generateServiceInfoDataMapping(arr: ServiceInfoModel[]) : { [serviceInstanceId: string]: ServiceInfoModel[]}{
@@ -70,7 +71,7 @@
   }
 
   open(item: ServiceInfoModel): void {
-    if (FeatureFlagsService.getFlagState(Features.FLAG_1902_VNF_GROUPING, this._store)) {
+    if (this._featureFlagsService.getFlagState(Features.FLAG_1902_VNF_GROUPING)) {
       this._aaiService.getServiceModelById(item['serviceModelId']).subscribe((result)=>{
         const serviceModel =  new ServiceModel(result);
 
@@ -92,7 +93,7 @@
   }
 
   navigateToNewViewOnlyOrOldEditView(item: ServiceInfoModel) {
-    if (FeatureFlagsService.getFlagState(Features.FLAG_1902_NEW_VIEW_EDIT, this._store)) {
+    if (this._featureFlagsService.getFlagState(Features.FLAG_1902_NEW_VIEW_EDIT)) {
       this.navigateToNewViewEdit(item, DrawingBoardModes.VIEW);
     }
     else {
@@ -184,6 +185,9 @@
     return item.action === ServiceAction.INSTANTIATE;
   }
 
+  isRecreateVisible(): boolean {
+    return this._featureFlagsService.getFlagState(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE);
+  }
 }
 
 
diff --git a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.ts b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.ts
index ba26716..58227c9 100644
--- a/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.ts
+++ b/vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.ts
@@ -59,6 +59,14 @@
       visible: () =>  true,
     },
     {
+      name: "Recreate",
+      dataTestId: "context-menu-recreate",
+      className: "fa-clone",
+      click: (item: ServiceInfoModel) => this.instantiationStatusComponentService.recreate(item),
+      enabled: (item: ServiceInfoModel) =>  this.instantiationStatusComponentService.isRecreateEnabled(item),
+      visible: () =>  this.instantiationStatusComponentService.isRecreateVisible(),
+    },
+    {
       name: "Audit info",
       dataTestId: "context-menu-audit-info",
       className: "fa-info-circle",
diff --git a/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts b/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts
index 8570b08..7e0575b 100644
--- a/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts
+++ b/vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts
@@ -14,6 +14,7 @@
   FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT ='FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT',
   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_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER ='FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER',
 }