From 16a9fce0e104a38371a9e5a567ec611ae3fc7f33 Mon Sep 17 00:00:00 2001 From: ys9693 Date: Sun, 19 Jan 2020 13:50:02 +0200 Subject: Catalog alignment Issue-ID: SDC-2724 Signed-off-by: ys9693 Change-Id: I52b4aacb58cbd432ca0e1ff7ff1f7dd52099c6fe --- .../graph/composition-graph.component.spec.ts | 354 +++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 catalog-ui/src/app/ng2/pages/composition/graph/composition-graph.component.spec.ts (limited to 'catalog-ui/src/app/ng2/pages/composition/graph/composition-graph.component.spec.ts') diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/composition-graph.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/graph/composition-graph.component.spec.ts new file mode 100644 index 0000000000..9a15ecba69 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/composition-graph.component.spec.ts @@ -0,0 +1,354 @@ +import {NO_ERRORS_SCHEMA} from '@angular/core'; +import {async, ComponentFixture} from '@angular/core/testing'; +import {SdcUiServices} from 'onap-ui-angular'; +import 'rxjs/add/observable/of'; +import {ConfigureFn, configureTests} from '../../../../../jest/test-config.helper'; +import {CompositionGraphComponent} from "./composition-graph.component"; +import {WorkspaceService} from "../../workspace/workspace.service"; +import {ComponentInstance, GroupInstance, NodesFactory, ZoneInstance, ZoneInstanceMode} from "../../../../models"; +import {EventListenerService} from "../../../../services"; +import { + CompositionGraphGeneralUtils, + CompositionGraphNodesUtils, + CompositionGraphZoneUtils, + MatchCapabilitiesRequirementsUtils, ServicePathGraphUtils +} from "./utils"; +import {CompositionGraphLinkUtils} from "./utils/composition-graph-links-utils"; +import {ConnectionWizardService} from "./connection-wizard/connection-wizard.service"; +import {CommonGraphUtils} from "./common/common-graph-utils"; +import {CompositionGraphPaletteUtils} from "./utils/composition-graph-palette-utils"; +import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; +import {ComponentInstanceServiceNg2} from "../../../services/component-instance-services/component-instance.service"; +import {CompositionService} from "../composition.service"; +import {ModalService} from '../../../services/modal.service'; +import {Store} from '@ngxs/store'; +import {PoliciesService} from '../../../services/policies.service'; +import {GroupsService} from '../../../services/groups.service'; +import {PolicyInstance} from "../../../../models/graph/zones/policy-instance"; +import {ZoneInstanceType} from "../../../../models/graph/zones/zone-instance"; +import {GRAPH_EVENTS} from "../../../../utils/constants"; +import * as cytoscape from "cytoscape"; +import {ComponentMetadata} from "../../../../models/component-metadata"; +import {Zone} from "../../../../models/graph/zones/zone"; +import {SelectedComponentType, SetSelectedComponentAction} from "../common/store/graph.actions"; + +describe('composition graph component', () => { + + let fixture: ComponentFixture; + let instance: CompositionGraphComponent; + let eventServiceMock: Partial; + let compositionGraphZoneUtils: Partial; + let generalGraphUtils: Partial; + let workspaceServiceMock: Partial; + let policyService: Partial; + let storeStub; + let compositionGraphLinkUtils: Partial; + let nodesGraphUtils: Partial; + + let createPolicyInstance = () => { + let policy = new PolicyInstance(); + policy.targets = {COMPONENT_INSTANCES: [], GROUPS: []}; + return new ZoneInstance(policy, '', ''); + } + + beforeEach( + async(() => { + + eventServiceMock = { + notifyObservers: jest.fn(), + unRegisterObserver: jest.fn() + } + + compositionGraphZoneUtils = { + endCyTagMode: jest.fn(), + showZoneTagIndications: jest.fn(), + hideZoneTagIndications: jest.fn(), + hideGroupZoneIndications: jest.fn(), + showGroupZoneIndications: jest.fn(), + startCyTagMode: jest.fn() + } + + workspaceServiceMock = { + metadata: { + uniqueId: 'service_unique_id', + componentType: 'SERVICE' + } + } + + compositionGraphLinkUtils = { + handleLinkClick: jest.fn(), + getModifyLinkMenu: jest.fn() + } + + storeStub = { + dispatch: jest.fn() + } + policyService = { + getSpecificPolicy: jest.fn() + } + + generalGraphUtils = { + zoomGraphTo: jest.fn() + } + + nodesGraphUtils = { + onNodesPositionChanged: jest.fn() + } + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [CompositionGraphComponent], + imports: [], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: NodesFactory, useValue: {}}, + {provide: EventListenerService, useValue: eventServiceMock}, + {provide: CompositionGraphZoneUtils, useValue: compositionGraphZoneUtils}, + {provide: CompositionGraphGeneralUtils, useValue: generalGraphUtils}, + {provide: CompositionGraphLinkUtils, useValue: compositionGraphLinkUtils}, + {provide: CompositionGraphNodesUtils, useValue: nodesGraphUtils}, + {provide: ConnectionWizardService, useValue: {}}, + {provide: CommonGraphUtils, useValue: {}}, + {provide: CompositionGraphPaletteUtils, useValue: {}}, + {provide: TopologyTemplateService, useValue: {}}, + {provide: ComponentInstanceServiceNg2, useValue: {}}, + {provide: MatchCapabilitiesRequirementsUtils, useValue: {}}, + {provide: CompositionService, useValue: {}}, + {provide: SdcUiServices.LoaderService, useValue: {}}, + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: SdcUiServices.NotificationsService, useValue: {}}, + {provide: SdcUiServices.simplePopupMenuService, useValue: {}}, + {provide: ServicePathGraphUtils, useValue: {}}, + {provide: ModalService, useValue: {}}, + {provide: PoliciesService, useValue: policyService}, + {provide: GroupsService, useValue: {}}, + {provide: Store, useValue: storeStub}, + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(CompositionGraphComponent); + instance = fixture.componentInstance; + instance._cy = cytoscape({}); + }); + }) + ); + + it('composition graph component should be defined', () => { + expect(fixture).toBeDefined(); + }); + + describe('on zone instance mode changed', () => { + let newZoneInstance: ZoneInstance; + + beforeEach( + async(() => { + newZoneInstance = createPolicyInstance(); + instance.zoneTagMode = null; + instance.zones = []; + instance.zones[ZoneInstanceType.POLICY] = new Zone('Policies', 'P', ZoneInstanceType.POLICY); + instance.zones[ZoneInstanceType.GROUP] = new Zone('Groups', 'G', ZoneInstanceType.GROUP); + instance.activeZoneInstance = createPolicyInstance(); + })) + + it('zone instance in tag mode and we want to turn tag mode off', () => { + instance.zoneTagMode = 'some_zone_id'; + instance.activeZoneInstance = newZoneInstance; + instance.zoneInstanceModeChanged(ZoneInstanceMode.NONE, newZoneInstance, ZoneInstanceType.POLICY); + expect(instance.eventListenerService.notifyObservers).toHaveBeenCalledWith(GRAPH_EVENTS.ON_CANVAS_TAG_END, newZoneInstance); + expect(instance.activeZoneInstance.mode).toBe(ZoneInstanceMode.SELECTED) + }) + + it('we are not in tag mode and policy instance mode changed to NONE - group and zone tag indication need to be removed', () => { + instance.zoneInstanceModeChanged(ZoneInstanceMode.NONE, newZoneInstance, ZoneInstanceType.POLICY); + expect(instance.compositionGraphZoneUtils.hideZoneTagIndications).toHaveBeenCalledWith(instance._cy); + expect(instance.compositionGraphZoneUtils.hideGroupZoneIndications).toHaveBeenCalledWith(instance.zones[ZoneInstanceType.GROUP].instances); + }) + + it('we are not in tag mode and active zone instance gets hover/none - we dont actually change mode', () => { + let newMode = ZoneInstanceMode.SELECTED; + instance.zoneInstanceModeChanged(newMode, newZoneInstance, ZoneInstanceType.POLICY); + expect(newZoneInstance.mode).toBe(newMode); + }) + + it('we are not in tag mode and zone instance mode changed to HOVER mode', () => { + instance.zoneInstanceModeChanged(ZoneInstanceMode.HOVER, newZoneInstance, ZoneInstanceType.POLICY); + expect(instance.compositionGraphZoneUtils.showZoneTagIndications).toHaveBeenCalledWith(instance._cy, newZoneInstance); + expect(instance.compositionGraphZoneUtils.showGroupZoneIndications).toHaveBeenCalledWith(instance.zones[ZoneInstanceType.GROUP].instances, newZoneInstance); + expect(instance.eventListenerService.notifyObservers).not.toHaveBeenCalled(); + }) + + it('we are not in tag mode and mode changed to SELECTED', () => { + instance.zoneInstanceModeChanged(ZoneInstanceMode.SELECTED, newZoneInstance, ZoneInstanceType.POLICY); + expect(instance.compositionGraphZoneUtils.showZoneTagIndications).toHaveBeenCalledWith(instance._cy, newZoneInstance); + expect(instance.compositionGraphZoneUtils.showGroupZoneIndications).toHaveBeenCalledWith(instance.zones[ZoneInstanceType.GROUP].instances, newZoneInstance); + expect(instance.activeZoneInstance).toBe(newZoneInstance); + expect(instance.eventListenerService.notifyObservers).toHaveBeenCalledWith(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, newZoneInstance); + expect(instance.store.dispatch).toHaveBeenCalledWith(new SetSelectedComponentAction({ + component: newZoneInstance.instanceData, + type: SelectedComponentType[ZoneInstanceType[newZoneInstance.type]] + })); + expect(instance.eventListenerService.notifyObservers).not.toHaveBeenCalledWith(GRAPH_EVENTS.ON_CANVAS_TAG_START, ZoneInstanceType.POLICY); + }) + + + it('we are not in tag mode and and zone instance mode changed to TAG', () => { + instance.zoneInstanceModeChanged(ZoneInstanceMode.TAG, newZoneInstance, ZoneInstanceType.POLICY); + expect(instance.compositionGraphZoneUtils.showZoneTagIndications).toHaveBeenCalledWith(instance._cy, newZoneInstance); + expect(instance.compositionGraphZoneUtils.showGroupZoneIndications).toHaveBeenCalledWith(instance.zones[ZoneInstanceType.GROUP].instances, newZoneInstance); + expect(instance.activeZoneInstance).toBe(newZoneInstance); + expect(instance.eventListenerService.notifyObservers).toHaveBeenCalledWith(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, newZoneInstance); + expect(instance.store.dispatch).toHaveBeenCalledWith(new SetSelectedComponentAction({ + component: newZoneInstance.instanceData, + type: SelectedComponentType[ZoneInstanceType[newZoneInstance.type]] + })); + expect(instance.compositionGraphZoneUtils.startCyTagMode).toHaveBeenCalledWith(instance._cy); + expect(instance.eventListenerService.notifyObservers).toHaveBeenCalledWith(GRAPH_EVENTS.ON_CANVAS_TAG_START, ZoneInstanceType.POLICY); + }) + }) + + it('unset active zone instance', () => { + instance.activeZoneInstance = createPolicyInstance(); + instance.unsetActiveZoneInstance(); + expect(instance.activeZoneInstance).toBeNull(); + expect(instance.zoneTagMode).toBeNull(); + }) + + it('zone background clicked - we are not in tag mode and active zone instance exist', () => { + instance.activeZoneInstance = createPolicyInstance(); + jest.spyOn(instance, 'unsetActiveZoneInstance'); + jest.spyOn(instance, 'selectTopologyTemplate'); + instance.zoneBackgroundClicked(); + expect(instance.unsetActiveZoneInstance).toHaveBeenCalled(); + expect(instance.selectTopologyTemplate).toHaveBeenCalled(); + }) + + it('zone background clicked - we are not in tag mode and no active zone instance exist', () => { + jest.spyOn(instance, 'unsetActiveZoneInstance'); + jest.spyOn(instance, 'selectTopologyTemplate'); + instance.zoneBackgroundClicked(); + expect(instance.unsetActiveZoneInstance).not.toHaveBeenCalled(); + expect(instance.selectTopologyTemplate).not.toHaveBeenCalled(); + }) + + it('on zoom in', () => { + jest.spyOn(instance, 'zoom'); + instance.zoom(true); + expect(instance.generalGraphUtils.zoomGraphTo).toHaveBeenCalledWith(instance._cy, instance._cy.zoom() + .1); + }) + + it('on zoom out', () => { + jest.spyOn(instance, 'zoom'); + instance.zoom(false); + expect(instance.generalGraphUtils.zoomGraphTo).toHaveBeenCalledWith(instance._cy, instance._cy.zoom() - .1); + }) + + describe('cytoscape tap end event have been called', () => { + + it('canvas background was clicked while zone instance in tag mode, zone instance still selected in tag mode)', () => { + let event = {cyTarget: instance._cy}; + instance.zoneTagMode = 'instance_in_tag' + instance.onTapEnd(event); + expect(instance.zoneTagMode).toBe('instance_in_tag'); + }) + + it('canvas background was clicked and no zone instance selected, topology template is now selected', () => { + let event = {cyTarget: instance._cy}; + jest.spyOn(instance, 'selectTopologyTemplate'); + instance.onTapEnd(event); + expect(instance.selectTopologyTemplate).toHaveBeenCalled(); + expect(instance.eventListenerService.notifyObservers).toHaveBeenCalledWith(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED); + }) + + it('canvas background was clicked and zone instance was selected, topology template is now selected and zone instance is unselected', () => { + let event = {cyTarget: instance._cy}; + instance.activeZoneInstance = createPolicyInstance(); + jest.spyOn(instance, 'selectTopologyTemplate'); + jest.spyOn(instance, 'unsetActiveZoneInstance'); + instance.onTapEnd(event); + expect(instance.selectTopologyTemplate).toHaveBeenCalled(); + expect(instance.unsetActiveZoneInstance).toHaveBeenCalled(); + }) + + + it('canvas background was clicked and zone instance was selected, topology template is now selected and zone instance is unselected', () => { + let event = {cyTarget: instance._cy}; + instance.activeZoneInstance = createPolicyInstance(); + jest.spyOn(instance, 'selectTopologyTemplate'); + jest.spyOn(instance, 'unsetActiveZoneInstance'); + instance.onTapEnd(event); + expect(instance.selectTopologyTemplate).toHaveBeenCalled(); + expect(instance.unsetActiveZoneInstance).toHaveBeenCalled(); + }) + + it('on simple edge clicked, open link menu and handle link click', () => { + let event = { + cyTarget: [{ + isEdge: jest.fn().mockReturnValue(true), + data: jest.fn().mockReturnValue({type: 'simple'}) + } + }]; + instance.openModifyLinkMenu = jest.fn(); + instance.onTapEnd(event); + expect(instance.compositionGraphLinkUtils.handleLinkClick).toHaveBeenCalledWith(instance._cy, event); + expect(instance.openModifyLinkMenu).toHaveBeenCalled(); + }) + + it('on service path edge clicked, no menu is opened', () => { + let event = { + cyTarget: [{ + isEdge: jest.fn().mockReturnValue(true), + data: jest.fn().mockReturnValue({type: 'service-path-link'}) + }] + }; + instance.openModifyLinkMenu = jest.fn(); + instance.onTapEnd(event); + expect(instance.compositionGraphLinkUtils.handleLinkClick).toHaveBeenCalledWith(instance._cy, event); + expect(instance.openModifyLinkMenu).not.toHaveBeenCalled(); + }) + + it('on drop after drag event (position has changed), call onNodesPositionChanged to update node position', () => { + let event = { + cyTarget: [{ + isEdge: jest.fn().mockReturnValue(false), + position: jest.fn().mockReturnValue({x:2.11, y:2.44}) + }] + }; + instance.currentlyClickedNodePosition = {x:2.33, y:2.44}; + instance.onTapEnd(event); + let nodesMoved: Cy.CollectionNodes = instance._cy.$(':grabbed'); + expect(instance.nodesGraphUtils.onNodesPositionChanged).toHaveBeenCalledWith(instance._cy, instance.topologyTemplate, nodesMoved); + + }) + + it('on node clicked (position not changed) while zone instance selected, unset active zone and call set selected instance', () => { + let event = { + cyTarget: [{ + isEdge: jest.fn().mockReturnValue(false), + position: jest.fn().mockReturnValue({x:2.11, y:2.44}), + data: jest.fn().mockReturnValue({componentInstance: new ComponentInstance()}) + }], + }; + instance.currentlyClickedNodePosition = {x:2.11, y:2.44}; + instance.activeZoneInstance = createPolicyInstance(); + jest.spyOn(instance, 'unsetActiveZoneInstance'); + jest.spyOn(instance, 'selectComponentInstance'); + instance.onTapEnd(event); + expect(instance.unsetActiveZoneInstance).toHaveBeenCalled(); + expect(instance.selectComponentInstance).toHaveBeenCalledWith(event.cyTarget[0].data().componentInstance); + }) + }) + + it('initial view mode will turn off all cytoscape events', () => { + jest.spyOn(instance, 'isViewOnly').mockReturnValue(true); + jest.spyOn(instance._cy, 'off'); + instance.initViewMode(); + expect(instance._cy.off).toHaveBeenCalledWith('drag'); + expect(instance._cy.off).toHaveBeenCalledWith('handlemouseout'); + expect(instance._cy.off).toHaveBeenCalledWith('handlemouseover'); + expect(instance._cy.off).toHaveBeenCalledWith('canvasredraw'); + expect(instance._cy.off).toHaveBeenCalledWith('handletagclick'); + + }) +}); -- cgit 1.2.3-korg