diff --git a/projects/grid-failure-information-app/src/app/app-config.service.spec.ts b/projects/grid-failure-information-app/src/app/app-config.service.spec.ts index 8dd4c896bc0800d942960468527f7f3c71059e7d..088f839b9b27a4a3265139121ed373a5840b12f4 100644 --- a/projects/grid-failure-information-app/src/app/app-config.service.spec.ts +++ b/projects/grid-failure-information-app/src/app/app-config.service.spec.ts @@ -12,6 +12,7 @@ ********************************************************************************/ import { async } from '@angular/core/testing'; import { ConfigService } from '@grid-failure-information-app/app/app-config.service'; +import { of } from 'rxjs/observable/of'; describe('ConfigService', () => { let component: ConfigService; @@ -19,14 +20,44 @@ describe('ConfigService', () => { let baseHref: any; beforeEach(async(() => { - http = {} as any; + http = { + get: () => + of({ + json: () => of({ env: 'env_json' }), + }), + } as any; })); beforeEach(() => { + baseHref = '/test'; component = new ConfigService(http, baseHref); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should get env', () => { + const keyValue = 'test'; + (component as any).env = { key: keyValue }; + const key: any = 'key'; + const res = component.getEnv(key); + expect(res).toBe(keyValue); + }); + + it('should get config key', () => { + const keyValue = 'test'; + (component as any).config = { key: keyValue }; + const key: any = 'key'; + const res = component.get(key); + expect(res).toBe(keyValue); + }); + + it('should load the config file', () => { + const keyValue = 'test'; + (component as any).config = { key: keyValue }; + (component as any).env = { key: keyValue }; + component.load(); + expect((component as any).config).toBeDefined(); + }); }); diff --git a/projects/grid-failure-information-app/src/app/app-config.service.ts b/projects/grid-failure-information-app/src/app/app-config.service.ts index b2f133dd6017d6d2e8d05eb8cc21bc1557beedce..1fdbf2606a84411411bfd4d41c97f6f22829ff3f 100644 --- a/projects/grid-failure-information-app/src/app/app-config.service.ts +++ b/projects/grid-failure-information-app/src/app/app-config.service.ts @@ -1,4 +1,4 @@ - /******************************************************************************** +/******************************************************************************** * Copyright (c) 2020 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional @@ -10,29 +10,28 @@ * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ -import { Injectable, Inject } from '@angular/core'; +import { APP_BASE_HREF } from '@angular/common'; +import { Inject, Injectable } from '@angular/core'; +import { Headers, Http } from '@angular/http'; import { Observable } from 'rxjs'; -import { Http, Headers, RequestOptions } from '@angular/http'; -import { APP_BASE_HREF } from '@angular/common'; @Injectable() export class ConfigService { private config: Object; - private env: Object; + private env: Object; - constructor(private http: Http, - @Inject(APP_BASE_HREF) private baseHref: string) {} + constructor(private http: Http, @Inject(APP_BASE_HREF) private baseHref: string) {} /** * Loads the environment config file first. Reads the environment variable from the file * and based on that loads the appropriate configuration file - development or production */ - load() { + load() { return new Promise((resolve, reject) => { const headers = new Headers({ Accept: 'application/json', 'Content-Type': 'application/json', - DataType: 'application/json' + DataType: 'application/json', }); this.http diff --git a/projects/grid-failure-information-app/src/app/app.component.spec.ts b/projects/grid-failure-information-app/src/app/app.component.spec.ts index 1c7d463df00a8cca4fde66c9f8a80dc995bcbf68..cde624b7162956ed454b044f5c31683051dd900a 100644 --- a/projects/grid-failure-information-app/src/app/app.component.spec.ts +++ b/projects/grid-failure-information-app/src/app/app.component.spec.ts @@ -12,13 +12,13 @@ ********************************************************************************/ import { async } from '@angular/core/testing'; -import { AppComponent } from './app.component'; import { User } from '@grid-failure-information-app/shared/models/user'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; +import { of } from 'rxjs'; +import { AppComponent } from '@grid-failure-information-app/app/app.component'; class FakeRouter { - public events = new Observable(); + public events: any = of({ url: '/overview' }); + navigate(commands: any[]) { return commands[0]; } @@ -36,10 +36,10 @@ describe('AppComponent', () => { let component: AppComponent; const fakeRouter: any = new FakeRouter(); const sandbox = new FakeSandbox(); - const fakeRoute = new ActivatedRoute(); + const fakeActivatedRoute: any = { params: of(1) }; beforeEach(() => { - component = new AppComponent(fakeRouter, sandbox as any, fakeRoute); + component = new AppComponent(fakeRouter, sandbox as any, fakeActivatedRoute); }); it('should create the app', async(() => { @@ -91,4 +91,36 @@ describe('AppComponent', () => { const param1 = inkognito._getParametersFromUrl(); expect(param1).toBe(null); }); + + it('should set up componet on ngOnInit call', () => { + const spy = spyOn(sandbox, 'setupLanguage'); + const spy2 = spyOn(component as any, '_extractTokenFromParameters'); + const spy3 = spyOn(component as any, '_registerEvents'); + + component.ngOnInit(); + expect(spy).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalled(); + expect(spy3).toHaveBeenCalled(); + }); + + it('should extract token from parameters', () => { + const spy = spyOn(component as any, '_getParametersFromUrl').and.returnValue('im_an_accessToken'); + const spy2 = spyOn(component as any, '_processAccessToken'); + (component as any)._extractTokenFromParameters(); + expect(spy).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalled(); + }); + + it('should set user if _getParametersFromUrl doeasnt return an accestoken', () => { + const spy = spyOn(component as any, '_getParametersFromUrl'); + const spy2 = spyOn(sandbox, 'setUser'); + (component as any)._extractTokenFromParameters(); + expect(spy).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalled(); + }); + + it('should register events', () => { + (component as any)._registerEvents(); + expect(component.isLoginPage).toBeTruthy(); + }); }); diff --git a/projects/grid-failure-information-app/src/app/app.component.ts b/projects/grid-failure-information-app/src/app/app.component.ts index 14b60b77da54e56da682fff2008abe94a5610515..bb664636e8403a393593f0702e8e4da0f7f05afc 100644 --- a/projects/grid-failure-information-app/src/app/app.component.ts +++ b/projects/grid-failure-information-app/src/app/app.component.ts @@ -13,7 +13,7 @@ import { Component, OnInit, HostBinding } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; -import { AppSandbox } from './app.sandbox'; +import { AppSandbox } from '@grid-failure-information-app/app/app.sandbox'; import { JwtHelperService } from '@auth0/angular-jwt'; import { User } from '@grid-failure-information-app/shared/models/user'; diff --git a/projects/grid-failure-information-app/src/app/app.module.ts b/projects/grid-failure-information-app/src/app/app.module.ts index 25c1ec0a60eee8659b2de5566ab1d4a2012a4b56..b966b313c3612390ba6cf6b49dbf882d16ee2d46 100644 --- a/projects/grid-failure-information-app/src/app/app.module.ts +++ b/projects/grid-failure-information-app/src/app/app.module.ts @@ -48,7 +48,7 @@ import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { HttpClient, HttpClientModule } from '@angular/common/http'; import { environment } from '@grid-failure-information-app/environments/environment'; -import { ContainersModule } from '@grid-failure-information-app/shared/containers'; +import { ContainersModule } from '@grid-failure-information-app/shared/containers/containers.module'; import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; import { SimpleNotificationsModule } from 'angular2-notifications'; diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts index 8833305072a2a7679548e3e09eee6d32a263f782..08523db1e9a2d75f055274d64c687ed23fc21b0c 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts @@ -31,7 +31,7 @@ describe('GridFailureDetailsSandbox', () => { beforeEach(() => { appState = { dispatch: () => {}, pipe: () => of(true), select: () => of(true) } as any; - actionSubject = { pipe: () => of(true) } as any; + actionSubject = { pipe: () => of(true), map: () => ({}) } as any; utilService = { displayNotification() {} } as any; router = { navigateByUrl() {} } as any; modalService = { open() {} } as any; @@ -49,6 +49,36 @@ describe('GridFailureDetailsSandbox', () => { expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureDetail({ payload: 'id' })); }); + it('should dispatch loadGridFailureBranches Action via loadGridFailureBranches()', () => { + service.loadGridFailureBranches(); + expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureBranches()); + }); + + it('should dispatch loadGridFailureClassifications Action via loadGridFailureClassifications()', () => { + service.loadGridFailureClassifications(); + expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureClassifications()); + }); + + it('should dispatch loadGridFailureTypes Action via loadGridFailureTypes()', () => { + service.loadGridFailureTypes(); + expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureTypes()); + }); + + it('should dispatch loadGridFailureStates Action via loadGridFailureStates()', () => { + service.loadGridFailureStates(); + expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureStates()); + }); + + it('should dispatch loadGridFailureRadii Action via loadGridFailureRadii()', () => { + service.loadGridFailureRadii(); + expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureRadii()); + }); + + it('should dispatch loadGridFailurePublicationTexts Action via loadGridFailurePublicationTexts()', () => { + service.loadGridFailurePublicationTexts(); + expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailurePublicationTexts()); + }); + it('should dispatch loadGridFailureVersions Action via loadGridFailureVersions(id)', () => { service.loadGridFailureVersions('id'); expect(appState.dispatch).toHaveBeenCalledWith(gridFailureActions.loadGridFailureVersions({ payload: 'id' })); @@ -150,4 +180,17 @@ describe('GridFailureDetailsSandbox', () => { service.saveGridFailure(); expect(spy1).toHaveBeenCalled(); }); + + it('should qqq', () => { + let gridFailureDetailsFormResponse: any = { + value: { + failureBegin: 'test1', + failureEndPlanned: 'test2', + failureEndResupplied: 'test3', + }, + }; + service.gridFailureDetailsFormState$ = of(gridFailureDetailsFormResponse); + service.registerEvents(); + expect(service.currentFormState).toBeDefined; + }); }); diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts index a0d1aa95f49827f530e5b9cc44a0e27ccecf6d2f..ba584f9ca31a732f53de9338a38ac5454764068c 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts @@ -21,14 +21,14 @@ import { CommonModule } from '@angular/common'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; -import { ComponentsModule } from '@grid-failure-information-app/shared/components'; +import { ComponentsModule } from '@grid-failure-information-app/shared/components/components.module'; import { TranslateModule } from '@ngx-translate/core'; import { NgrxFormsModule } from 'ngrx-forms'; import { FormsModule } from '@angular/forms'; import { AgGridModule } from 'ag-grid-angular'; import { DirectivesModule } from '@grid-failure-information-app/shared/directives'; -import { FiltersModule } from '@grid-failure-information-app/shared/filters/index.module'; -import { ContainersModule } from '@grid-failure-information-app/shared/containers'; +import { FiltersModule } from '@grid-failure-information-app/shared/filters/filters.module'; +import { ContainersModule } from '@grid-failure-information-app/shared/containers/containers.module'; import { SetFilterComponent } from '@grid-failure-information-app/shared/filters/ag-grid/set-filter/set-filter.component'; import { GridFailureService } from '@grid-failure-information-app/pages/grid-failure/grid-failure.service'; import { GridFailureApiClient } from '@grid-failure-information-app/pages/grid-failure/grid-failure-api-client'; @@ -39,7 +39,7 @@ import { StoreModule } from '@ngrx/store'; import { gridFailureReducers } from '@grid-failure-information-app/shared/store'; import { NgbDatepickerModule, NgbTimepickerModule } from '@ng-bootstrap/ng-bootstrap'; import { UtilityModule } from '@grid-failure-information-app/shared/utility'; -import { PipesModule } from '@grid-failure-information-app/shared/pipes'; +import { PipesModule } from '@grid-failure-information-app/shared/pipes/pipes.module'; import { GridFailureInformationMapModule } from 'openk/grid-failure-information-map/src/public-api'; @NgModule({ diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.spec.ts index 69fe92e5b08df70a23890a6f5f72506f70983801..282ddb18998670bc4b99f9b53f96c0a610f51fea 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.spec.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.spec.ts @@ -10,7 +10,15 @@ * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ -import { GridFailure } from '@grid-failure-information-app/shared/models'; +import { + GridFailure, + FailureBranch, + FailureClassification, + FailureType, + FailureState, + FailureRadius, + FailurePublicationText, +} from '@grid-failure-information-app/shared/models'; import { GridFailureService } from '@grid-failure-information-app/pages/grid-failure/grid-failure.service'; describe(' GridFailureService', () => { @@ -29,4 +37,46 @@ describe(' GridFailureService', () => { expect(item.id).toBe(response.id); }); + + it('should transform branches api response', () => { + const response = [new FailureBranch()]; + response[0].id = 'X'; + + expect(GridFailureService.branchListAdapter(response)[0].id).toBe('X'); + }); + + it('should transform classifications api response', () => { + const response = [new FailureClassification()]; + response[0].id = 'X'; + + expect(GridFailureService.classificationListAdapter(response)[0].id).toBe('X'); + }); + + it('should transform types api response', () => { + const response = [new FailureType()]; + response[0].id = 'X'; + + expect(GridFailureService.typeListAdapter(response)[0].id).toBe('X'); + }); + + it('should transform states api response', () => { + const response = [new FailureState()]; + response[0].id = 'X'; + + expect(GridFailureService.stateListAdapter(response)[0].id).toBe('X'); + }); + + it('should transform radii api response', () => { + const response = [new FailureRadius()]; + response[0].id = 'X'; + + expect(GridFailureService.radiusListAdapter(response)[0].id).toBe('X'); + }); + + it('should transform publication texts api response', () => { + const response = [new FailurePublicationText()]; + response[0].id = 'X'; + + expect(GridFailureService.publicationTextListAdapter(response)[0].id).toBe('X'); + }); }); diff --git a/projects/grid-failure-information-app/src/app/pages/imported-grid-failure/imported-grid-failure.module.ts b/projects/grid-failure-information-app/src/app/pages/imported-grid-failure/imported-grid-failure.module.ts index c270d25178d391f8e4020c1888d3acf937853ce2..cb66ea134291da602321dbd9797cd2895e743667 100644 --- a/projects/grid-failure-information-app/src/app/pages/imported-grid-failure/imported-grid-failure.module.ts +++ b/projects/grid-failure-information-app/src/app/pages/imported-grid-failure/imported-grid-failure.module.ts @@ -13,11 +13,11 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; -import { ComponentsModule } from '@grid-failure-information-app/shared/components'; +import { ComponentsModule } from '@grid-failure-information-app/shared/components/components.module'; import { TranslateModule } from '@ngx-translate/core'; import { FormsModule } from '@angular/forms'; import { DirectivesModule } from '@grid-failure-information-app/shared/directives'; -import { ContainersModule } from '@grid-failure-information-app/shared/containers'; +import { ContainersModule } from '@grid-failure-information-app/shared/containers/containers.module'; import { ImportedGridFailureListComponent } from '@grid-failure-information-app/app/pages/imported-grid-failure/imported-grid-failure-list/imported-grid-failure-list.component'; import { ImportedGridFailureListSandbox } from '@grid-failure-information-app/app/pages/imported-grid-failure/imported-grid-failure-list/imported-grid-failure-list.sandbox'; import { ImportedGridFailureApiClient } from '@grid-failure-information-app/app/pages/imported-grid-failure/imported-grid-failure-api-client'; diff --git a/projects/grid-failure-information-app/src/app/pages/logout/logout.module.ts b/projects/grid-failure-information-app/src/app/pages/logout/logout.module.ts index a98356ed011f3bcb2a6b4c79dcaf0d67d805546e..615669dada6d00ed4584bf578cd97d64dfd0dc60 100644 --- a/projects/grid-failure-information-app/src/app/pages/logout/logout.module.ts +++ b/projects/grid-failure-information-app/src/app/pages/logout/logout.module.ts @@ -13,11 +13,11 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; -import { ComponentsModule } from '@grid-failure-information-app/shared/components'; +import { ComponentsModule } from '@grid-failure-information-app/shared/components/components.module'; import { TranslateModule } from '@ngx-translate/core'; import { FormsModule } from '@angular/forms'; import { DirectivesModule } from '@grid-failure-information-app/shared/directives'; -import { ContainersModule } from '@grid-failure-information-app/shared/containers'; +import { ContainersModule } from '@grid-failure-information-app/shared/containers/containers.module'; import { LogoutPageSandbox } from '@grid-failure-information-app/pages/logout/logout/logout.sandbox'; import { LogoutPageComponent } from '@grid-failure-information-app/pages/logout/logout/logout.component'; import { LoggedOutPageComponent } from '@grid-failure-information-app/pages/logout/logged-out/logged-out.component'; diff --git a/projects/grid-failure-information-app/src/app/shared/async-services/http/http.adapter.spec.ts b/projects/grid-failure-information-app/src/app/shared/async-services/http/http.adapter.spec.ts index 89e48c173cbcc049ef01c83678e14a9c8c38310f..ae56a2b81650695c7f5be1133afbad019a9b9d46 100644 --- a/projects/grid-failure-information-app/src/app/shared/async-services/http/http.adapter.spec.ts +++ b/projects/grid-failure-information-app/src/app/shared/async-services/http/http.adapter.spec.ts @@ -10,44 +10,20 @@ * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ -/* import { async, TestBed } from '@angular/core/testing'; -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; -import { ConfigService } from '@grid-failure-information-app/app/app-config.service'; -import { of } from 'rxjs/observable/of'; -import { HttpAdapter } from './http.adapter'; -import { Response } from '@angular/http'; +import { HttpAdapter } from '@grid-failure-information-app/shared/async-services/http/http.adapter'; describe('HttpAdapter', () => { + beforeEach(() => {}); - - let responseHandlerMock: any; - let httpMock: any; - let configserviceMock: any; - - beforeEach(() => { - - - }); - - it('should call getBaseUrl', () => { - const spy1 = spyOn(configserviceMock, 'get').and.callThrough(); - (httpService as any).getBaseUrl(); - expect(spy1).toHaveBeenCalled(); - }); - - it('should call getDefaultHeaders', () => { - const spy1 = spyOn((httpService as any), 'getDefaultHeaders').and.callThrough(); - let response = (httpService as any).getDefaultHeaders(); - expect(response).toBeNull(); - expect(spy1).toHaveBeenCalled(); + it('should call baseAdapter without result if response is not 200', () => { + const response: any = { status: 999 }; + const result = HttpAdapter.baseAdapter(response); + expect(result).toBe(undefined); }); - it('should call getDefaultHeaders', () => { - const observableRes = of( {} as any ); - const spy1 = spyOn((httpService as any), 'responseInterceptor').and.callThrough(); - const spy2 = spyOn(HttpAdapter, 'baseAdapter'); - let observable = (httpService as any).responseInterceptor(observableRes); - expect(spy1).toHaveBeenCalled(); + it('should call baseAdapter an give the response as result back', () => { + const response: any = { status: 200 }; + const result = HttpAdapter.baseAdapter(response); + expect(result).toBe(response); }); - -}); */ +}); diff --git a/projects/grid-failure-information-app/src/app/shared/async-services/http/http.service.ts b/projects/grid-failure-information-app/src/app/shared/async-services/http/http.service.ts index 03095a8b571a955aefbb33d480b7dc44249d1702..28303ba77e5a802ef719d82d3283f18699caecd5 100644 --- a/projects/grid-failure-information-app/src/app/shared/async-services/http/http.service.ts +++ b/projects/grid-failure-information-app/src/app/shared/async-services/http/http.service.ts @@ -12,10 +12,10 @@ ********************************************************************************/ import { Injectable } from '@angular/core'; import { Http, Request } from '@angular/http'; +import { ConfigService } from '@grid-failure-information-app/app/app-config.service'; +import { HttpAdapter } from '@grid-failure-information-app/shared/async-services/http/http.adapter'; +import { HttpResponseHandler } from '@grid-failure-information-app/shared/async-services/http/httpResponseHandler.service'; import { Observable } from 'rxjs'; -import { HttpResponseHandler } from './httpResponseHandler.service'; -import { HttpAdapter } from './http.adapter'; -import { ConfigService } from '../../../app-config.service'; /** * Supported @Produces media types diff --git a/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.spec.ts b/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..e5bb980da1d41c938b954b9a9323422e886705d0 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.spec.ts @@ -0,0 +1,266 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ + +import { HttpResponseHandler } from '@grid-failure-information-app/shared/async-services/http/httpResponseHandler.service'; + +describe('HttpResponseHandler with undefined configService->unauthorizedEndpoints', () => { + let component: HttpResponseHandler; + let router: any; + let translateService: any; + let notificationsService: any; + let configService: any; + + beforeEach(() => { + router = { + navigate() {}, + } as any; + translateService = { + instant() {}, + }; + notificationsService = { + error() {}, + info() {}, + }; + configService = { + get: () => ({ options: 'options', unauthorizedEndpoints: [] }), + }; + + component = new HttpResponseHandler(router, translateService, notificationsService, configService); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should call handleBadRequest when response status is 400', () => { + const spy = spyOn(component as any, 'handleBadRequest'); + const response = { status: 400 }; + component.onCatch(response, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should call handleUnauthorized when response status is 401', () => { + const spy = spyOn(component as any, 'handleUnauthorized'); + const response = { status: 401 }; + component.onCatch(response, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should call handleForbidden when response status is 403', () => { + const spy = spyOn(component as any, 'handleForbidden'); + const response = { status: 403 }; + component.onCatch(response, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should call handleNotFound when response status is 404', () => { + const spy = spyOn(component as any, 'handleNotFound'); + const response = { status: 404 }; + component.onCatch(response, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should call handleRefExists when response status is 409', () => { + const spy = spyOn(component as any, 'handleRefExists'); + const response = { status: 409 }; + component.onCatch(response, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should call handleServerError when response status is 500', () => { + const spy = spyOn(component as any, 'handleServerError'); + const response = { status: 500 }; + component.onCatch(response, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should break when response status is not one from the defined', () => { + const spy = spyOn(component as any, 'handleBadRequest'); + const spy2 = spyOn(component as any, 'handleUnauthorized'); + const spy3 = spyOn(component as any, 'handleForbidden'); + const spy4 = spyOn(component as any, 'handleNotFound'); + const spy5 = spyOn(component as any, 'handleRefExists'); + const spy6 = spyOn(component as any, 'handleServerError'); + const response = { status: 999 }; + component.onCatch(response, {} as any); + expect(spy).not.toHaveBeenCalled(); + expect(spy2).not.toHaveBeenCalled(); + expect(spy3).not.toHaveBeenCalled(); + expect(spy4).not.toHaveBeenCalled(); + expect(spy5).not.toHaveBeenCalled(); + expect(spy6).not.toHaveBeenCalled(); + }); + + it('should handle an error message when calling handleBadRequest with a valid body', () => { + const spy = spyOn(component as any, 'handleErrorMessages'); + const responseBody: any = { + _body: { + timestamp: '2020-03-26T09:05:01.564+0000', + status: 400, + }, + json() {}, + }; + (component as any).handleBadRequest(responseBody); + expect(spy).toHaveBeenCalled(); + }); + + it('should handle a server error when calling handleBadRequest with a not valid body', () => { + const spy = spyOn(component as any, 'handleServerError'); + const responseBody: any = { + _body: null, + json() {}, + }; + (component as any).handleBadRequest(responseBody); + expect(spy).toHaveBeenCalled(); + }); + + it('should not show a 401 notification when calling handleUnauthorized without unauthorizedEndpoints', () => { + const spy = spyOn(translateService, 'instant'); + const spy1 = spyOn(notificationsService, 'info'); + const spy2 = spyOn(router, 'navigate'); + + const responseBody: any = { + url: 'endpoint1' as string, + }; + (component as any).handleUnauthorized(responseBody); + expect(spy).not.toHaveBeenCalledWith('ServerError401'); + expect(spy1).not.toHaveBeenCalled(); + expect(spy2).toHaveBeenCalledWith(['/login']); + }); + + it('should show a 403 notification and navigate to login when calling handleForbidden', () => { + const spy = spyOn(translateService, 'instant'); + const spy2 = spyOn(notificationsService, 'error'); + const spy3 = spyOn(router, 'navigate'); + + (component as any).handleForbidden(); + expect(spy).toHaveBeenCalledWith('ServerError403'); + expect(spy2).toHaveBeenCalled(); + expect(spy3).toHaveBeenCalledWith(['/login']); + }); + + it('should show an 404 error notification when calling handleNotFound', () => { + const spy = spyOn(translateService, 'instant'); + const spy2 = spyOn(component as any, 'showNotificationError'); + + (component as any).handleNotFound(); + expect(spy).toHaveBeenCalledWith('ServerError404'); + expect(spy2).toHaveBeenCalled(); + }); + + it('should show an error notification when calling handleRefExists', () => { + const spy = spyOn(translateService, 'instant'); + const spy2 = spyOn(component as any, 'showNotificationError'); + + (component as any).handleRefExists(); + expect(spy).toHaveBeenCalledWith('ServerError409'); + expect(spy2).toHaveBeenCalled(); + }); + + it('should show an 500 error notification when calling handleServerError', () => { + const spy = spyOn(translateService, 'instant'); + const spy2 = spyOn(component as any, 'showNotificationError'); + + (component as any).handleServerError(); + expect(spy).toHaveBeenCalledWith('ServerError500'); + expect(spy2).toHaveBeenCalled(); + }); + + it('should return without action calling handleErrorMessages with undefined response', () => { + const spy = spyOn(component as any, 'showNotificationError'); + const spy2 = spyOn(component as any, 'getTranslatedValue'); + + const response: any = undefined; + + (component as any).handleErrorMessages(response); + expect(spy).not.toHaveBeenCalled(); + expect(spy2).not.toHaveBeenCalled(); + }); + + it('should show one error notification when calling handleErrorMessages and there is only one error', () => { + const spy = spyOn(component as any, 'showNotificationError'); + const response: any = { + key: '[value1]', + }; + + (component as any).handleErrorMessages(response); + expect(spy).toHaveBeenCalled(); + }); + + it('should show as many error notification as responses when calling handleErrorMessages and there are more than one errors', () => { + const spy = spyOn(component as any, 'showNotificationError'); + const spy2 = spyOn(component as any, 'getTranslatedValue'); + + const response: any = { key: ['[value1]', '[value2]', '[value3]'] }; + + (component as any).handleErrorMessages(response); + expect(spy).toHaveBeenCalledTimes(3); + expect(spy2).toHaveBeenCalled(); + }); + + it('should get the translated value when calling getTranslatedValue', () => { + const value: string = 'value'; + + const result = (component as any).getTranslatedValue(value); + expect(result).toBe(value); + }); + + it('should call notifications service with an error message when calling showNotificationError', () => { + const title: string = 'title'; + const message: string = 'message'; + const spy = spyOn(notificationsService, 'error'); + + (component as any).showNotificationError(title, message); + expect(spy).toHaveBeenCalled(); + }); +}); + +describe('HttpResponseHandler with defined configService->unauthorizedEndpoints', () => { + let component: HttpResponseHandler; + let router: any; + let translateService: any; + let notificationsService: any; + let configService: any; + + beforeEach(() => { + router = { + navigate() {}, + } as any; + translateService = { + instant() {}, + }; + notificationsService = { + error() {}, + info() {}, + }; + configService = { + get: () => ({ options: 'options', unauthorizedEndpoints: ['endpoint1', 'endpoint2'] }), + }; + + component = new HttpResponseHandler(router, translateService, notificationsService, configService); + }); + + it('should show a 401 notification when calling handleUnauthorized with unauthorizedEndpoints', () => { + const spy = spyOn(translateService, 'instant'); + const spy1 = spyOn(notificationsService, 'info'); + const spy2 = spyOn(router, 'navigate'); + + const responseBody: any = { + url: 'endpoint1' as string, + }; + (component as any).handleUnauthorized(responseBody); + expect(spy).toHaveBeenCalledWith('ServerError401'); + expect(spy1).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalledWith(['/login']); + }); +}); diff --git a/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.ts b/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.ts index d5b163aafe5889cdba05d8880e1a396c568a2b18..91dc5dc3a0b0008cfc5e510dba6589e7ecbe019e 100644 --- a/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.ts +++ b/projects/grid-failure-information-app/src/app/shared/async-services/http/httpResponseHandler.service.ts @@ -16,6 +16,7 @@ import { NotificationsService } from 'angular2-notifications'; import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { ConfigService } from '@grid-failure-information-app/app/app-config.service'; +import { throwError } from 'rxjs'; @Injectable() export class HttpResponseHandler { @@ -63,7 +64,7 @@ export class HttpResponseHandler { break; } - return Observable.throw(response); + return throwError(response); } /** diff --git a/projects/grid-failure-information-app/src/app/shared/components/index.ts b/projects/grid-failure-information-app/src/app/shared/components/components.module.ts similarity index 94% rename from projects/grid-failure-information-app/src/app/shared/components/index.ts rename to projects/grid-failure-information-app/src/app/shared/components/components.module.ts index 59a3ab1fcab0e515404b4a14f9c05f7a38c2191e..3a14379915a90b4b8b63c8c23c28e59bcc7cc378 100644 --- a/projects/grid-failure-information-app/src/app/shared/components/index.ts +++ b/projects/grid-failure-information-app/src/app/shared/components/components.module.ts @@ -10,31 +10,30 @@ * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ -import { SafetyQueryDialogComponent } from '@grid-failure-information-app/shared/components/dialogs/safety-query-dialog/safety-query-dialog.component'; -import { BoolCellRendererComponent } from '@grid-failure-information-app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component'; -import { IconCellRendererComponent } from '@grid-failure-information-app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component'; -import { PaginationComponent } from '@grid-failure-information-app/shared/components/pagination/pagination.component'; -import { LoadingSpinnerComponent } from '@grid-failure-information-app/shared/components/loading-spinner/loading-spinner.component'; +import { CommonModule, DatePipe } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; -import { CommonModule, DatePipe } from '@angular/common'; -import { PipesModule } from '@grid-failure-information-app/shared/pipes'; -import { TranslateModule } from '@ngx-translate/core'; -import { SpinnerComponent } from '@grid-failure-information-app/shared/components/spinner/spinner.component'; +import { BoolCellRendererComponent } from '@grid-failure-information-app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component'; +import { DateCellRendererComponent } from '@grid-failure-information-app/shared/components/cell-renderer/date-cell-renderer/date-cell-renderer.component'; +import { IconCellRendererComponent } from '@grid-failure-information-app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component'; +import { DateTimePickerComponent } from '@grid-failure-information-app/shared/components/date-time-picker/date-time-picker.component'; +import { SafetyQueryDialogComponent } from '@grid-failure-information-app/shared/components/dialogs/safety-query-dialog/safety-query-dialog.component'; +import { ExpandableComponent } from '@grid-failure-information-app/shared/components/expandable/expandable.component'; import { HeaderComponent } from '@grid-failure-information-app/shared/components/header/header.component'; -import { PageNotFoundComponent } from '@grid-failure-information-app/shared/components/page-not-found/pageNotFound.component'; import { LoadingPlaceholderComponent } from '@grid-failure-information-app/shared/components/loading-placeholder/loading-placeholder.component'; +import { LoadingSpinnerComponent } from '@grid-failure-information-app/shared/components/loading-spinner/loading-spinner.component'; +import { PageNotFoundComponent } from '@grid-failure-information-app/shared/components/page-not-found/pageNotFound.component'; +import { PaginationComponent } from '@grid-failure-information-app/shared/components/pagination/pagination.component'; +import { SpinnerComponent } from '@grid-failure-information-app/shared/components/spinner/spinner.component'; import { VersionInfo } from '@grid-failure-information-app/shared/components/version-info/version-info.component'; -import { AngularFontAwesomeModule } from 'angular-font-awesome'; -import { ExpandableComponent } from '@grid-failure-information-app/shared/components/expandable/expandable.component'; +import { DirectivesModule } from '@grid-failure-information-app/shared/directives/index'; +import { PipesModule } from '@grid-failure-information-app/shared/pipes/pipes.module'; +import { NgbDatepickerModule, NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule } from '@ngx-translate/core'; import { AgGridModule } from 'ag-grid-angular'; +import { AngularFontAwesomeModule } from 'angular-font-awesome'; import { NgrxFormsModule } from 'ngrx-forms'; -import { DirectivesModule } from '@grid-failure-information-app/shared/directives/index'; -import { NgbModule, NgbDateParserFormatter, NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; -import { NgbDateCustomParserFormatter } from '@grid-failure-information-app/shared/pipes/ngb-date-custom-parser-formatter'; -import { DateCellRendererComponent } from '@grid-failure-information-app/shared/components/cell-renderer/date-cell-renderer/date-cell-renderer.component'; -import { DateTimePickerComponent } from '@grid-failure-information-app/shared/components/date-time-picker/date-time-picker.component'; export const COMPONENTS = [ SpinnerComponent, diff --git a/projects/grid-failure-information-app/src/app/shared/containers/index.ts b/projects/grid-failure-information-app/src/app/shared/containers/containers.module.ts similarity index 88% rename from projects/grid-failure-information-app/src/app/shared/containers/index.ts rename to projects/grid-failure-information-app/src/app/shared/containers/containers.module.ts index 3fe9e6bdcbd86cdb8192cec97c278c6174d3de1e..a3988ed184cde8630bbf76b932f14b85875e9992 100644 --- a/projects/grid-failure-information-app/src/app/shared/containers/index.ts +++ b/projects/grid-failure-information-app/src/app/shared/containers/containers.module.ts @@ -1,4 +1,4 @@ - /******************************************************************************** +/******************************************************************************** * Copyright (c) 2020 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional @@ -13,7 +13,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ComponentsModule } from '../components'; +import { ComponentsModule } from '../components/components.module'; import { LayoutContainerComponent } from './layout/layout.container'; import { LayoutSandbox } from './layout/layout.sandbox'; import { TranslateModule } from '@ngx-translate/core'; diff --git a/projects/grid-failure-information-app/src/app/shared/filters/index.module.ts b/projects/grid-failure-information-app/src/app/shared/filters/filters.module.ts similarity index 100% rename from projects/grid-failure-information-app/src/app/shared/filters/index.module.ts rename to projects/grid-failure-information-app/src/app/shared/filters/filters.module.ts diff --git a/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.spec.ts b/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..d7ccfe148d601ad742cabee9f8671945759a1679 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.spec.ts @@ -0,0 +1,57 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ + +import { AdminGuard } from '@grid-failure-information-app/shared/guards/admin.guard'; +import { of } from 'rxjs/observable/of'; +import { User } from '@grid-failure-information-app/shared/models/user'; + +describe('AdminGuard', () => { + let component: AdminGuard; + let appState: any; + let router: any; + + beforeEach(() => { + appState = { + pipe: () => of(1), + dispatch: () => {}, + select: () => of(1), + }; + router = { + navigate() {}, + } as any; + + component = new AdminGuard(router, appState); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should call _checkAdminRight wehn calling canActivate', () => { + const spy = spyOn(component as any, '_checkAdminRight'); + component.canActivate({} as any, {} as any); + expect(spy).toHaveBeenCalled(); + }); + + it('should check if has admin right', () => { + const user: User = new User(); + user.id = '123'; + user.roles = ['admin', 'reader']; + + const spy = spyOn(appState, 'select').and.returnValue(of(user)); + const spy2 = spyOn(router, 'navigate'); + (component as any)._checkAdminRight(); + expect(spy).toHaveBeenCalled(); + expect(spy2).toHaveBeenCalledWith(['/grid-failures']); + }); +}); diff --git a/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.ts b/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.ts index 45d24b2aaa87c45c004d46dc338260f1a9a183ae..7b715275a7ce25fa812fb0fc180b163069af824c 100644 --- a/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.ts +++ b/projects/grid-failure-information-app/src/app/shared/guards/admin.guard.ts @@ -33,7 +33,7 @@ export class AdminGuard implements CanActivate { .select(store.getUser) .pipe(takeUntil(this._endSubscriptions$), take(1)) .map((user: User) => new PermissionsModel(user.roles).admin); - isAdmin$.subscribe(isAdmin => !isAdmin && this._router.navigate(['/overview'])); + isAdmin$.subscribe(isAdmin => !isAdmin && this._router.navigate(['/grid-failures'])); return isAdmin$.pipe(take(1)); } } diff --git a/projects/grid-failure-information-app/src/app/shared/pipes/index.ts b/projects/grid-failure-information-app/src/app/shared/pipes/pipes.module.ts similarity index 100% rename from projects/grid-failure-information-app/src/app/shared/pipes/index.ts rename to projects/grid-failure-information-app/src/app/shared/pipes/pipes.module.ts diff --git a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts index 18de492c3f8f11cc1d9a5f3b88caa3a69357b8e4..93faddc542cda2778d7d99d33d182d324078fdf5 100644 --- a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts +++ b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts @@ -13,7 +13,15 @@ import { take } from 'rxjs/operators'; import { GridFailuresEffects } from '@grid-failure-information-app/shared/store/effects/grid-failures.effect'; import { Subject, of, throwError } from 'rxjs'; -import { GridFailure } from '@grid-failure-information-app/shared/models'; +import { + GridFailure, + FailureBranch, + FailureClassification, + FailureType, + FailureState, + FailureRadius, + FailurePublicationText, +} from '@grid-failure-information-app/shared/models'; import * as gridFailureActions from '@grid-failure-information-app/shared/store/actions/grid-failures.action'; import { GridFailureApiClient } from '@grid-failure-information-app/pages/grid-failure/grid-failure-api-client'; import { Store } from '@ngrx/store'; @@ -33,6 +41,12 @@ describe('GridFailure Effects', () => { postGridFailure() {}, getGridFailureVersions() {}, getGridFailureVersion() {}, + getGridFailureBranches() {}, + getGridFailureClassifications() {}, + getGridFailureTypes() {}, + getGridFailureStates() {}, + getGridFailureRadii() {}, + getGridFailurePublicationTexts() {}, } as any; store = { dispatch() {}, @@ -139,4 +153,64 @@ describe('GridFailure Effects', () => { done(); actions$.next(gridFailureActions.loadGridFailureVersion({ gridFailureId: '1', versionNumber: 1 })); }); + + it('should equal loadGridFailureBranchesSuccess after getGridFailureBranches', done => { + apiResponse = [new FailureBranch({ id: '1' })]; + spyOn(apiClient, 'getGridFailureBranches').and.returnValue(of(apiResponse)); + effects.getGridFailureBranches$.pipe(take(1)).subscribe(result => { + expect(result).toEqual(gridFailureActions.loadGridFailureBranchesSuccess({ payload: apiResponse })); + }); + done(); + actions$.next(gridFailureActions.loadGridFailureBranches()); + }); + + it('should equal loadGridFailureClassifications after getGridFailureClassifications', done => { + apiResponse = [new FailureClassification({ id: '1' })]; + spyOn(apiClient, 'getGridFailureClassifications').and.returnValue(of(apiResponse)); + effects.getGridFailureClassifications$.pipe(take(1)).subscribe(result => { + expect(result).toEqual(gridFailureActions.loadGridFailureClassificationsSuccess({ payload: apiResponse })); + }); + done(); + actions$.next(gridFailureActions.loadGridFailureClassifications()); + }); + + it('should equal loadGridFailureTypes after getGridFailureTypes', done => { + apiResponse = [new FailureType({ id: '1' })]; + spyOn(apiClient, 'getGridFailureTypes').and.returnValue(of(apiResponse)); + effects.getGridFailureTypes$.pipe(take(1)).subscribe(result => { + expect(result).toEqual(gridFailureActions.loadGridFailureTypesSuccess({ payload: apiResponse })); + }); + done(); + actions$.next(gridFailureActions.loadGridFailureTypes()); + }); + + it('should equal loadGridFailureStates after getGridFailureStates', done => { + apiResponse = [new FailureState({ id: '1' })]; + spyOn(apiClient, 'getGridFailureStates').and.returnValue(of(apiResponse)); + effects.getGridFailureStates$.pipe(take(1)).subscribe(result => { + expect(result).toEqual(gridFailureActions.loadGridFailureStatesSuccess({ payload: apiResponse })); + }); + done(); + actions$.next(gridFailureActions.loadGridFailureStates()); + }); + + it('should equal loadGridFailureRadii after getGridFailureRadii', done => { + apiResponse = [new FailureRadius({ id: '1' })]; + spyOn(apiClient, 'getGridFailureRadii').and.returnValue(of(apiResponse)); + effects.getGridFailureRadii$.pipe(take(1)).subscribe(result => { + expect(result).toEqual(gridFailureActions.loadGridFailureRadiiSuccess({ payload: apiResponse })); + }); + done(); + actions$.next(gridFailureActions.loadGridFailureRadii()); + }); + + it('should equal loadGridFailurePublicationTexts after getGridFailurePublicationTexts', done => { + apiResponse = [new FailurePublicationText({ id: '1' })]; + spyOn(apiClient, 'getGridFailurePublicationTexts').and.returnValue(of(apiResponse)); + effects.getGridFailurePublicationTexts$.pipe(take(1)).subscribe(result => { + expect(result).toEqual(gridFailureActions.loadGridFailurePublicationTextsSuccess({ payload: apiResponse })); + }); + done(); + actions$.next(gridFailureActions.loadGridFailurePublicationTexts()); + }); });