diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts index ecf4387ceee6a3dbdd6775f8ef4fa3a306144002..d00e6923b00a28a9022ac67bf1531555e852f713 100644 --- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts +++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts @@ -1,6 +1,7 @@ -import { StateResource, createStateResource } from '@alfa-client/tech-shared'; +import { createStateResource, StateResource } from '@alfa-client/tech-shared'; import { Mock, mock } from '@alfa-client/test-utils'; import { TestBed } from '@angular/core/testing'; +import { expect } from '@jest/globals'; import { singleCold } from 'libs/tech-shared/test/marbles'; import { Observable } from 'rxjs'; import { @@ -76,4 +77,14 @@ describe('AggregationMappingService', () => { expect(loadedAggregationMappingResource).toBeObservable(singleCold(aggregationMappingStateResource)); }); }); + + describe('refresh list', () => { + it('should call list resource service', () => { + listResourceService.refresh = jest.fn(); + + service.refreshList(); + + expect(listResourceService.refresh).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts index 20a8ce6c1ccda133323bac99a671d887e77afb8e..00402e238cce0455a7a0a25ced6fb70219216d24 100644 --- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts +++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts @@ -1,5 +1,5 @@ import { StateResource } from '@alfa-client/tech-shared'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { AggregationMappingListResourceService } from './aggregation-mapping-resource.service'; import { AggregationMapping, AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model'; @@ -15,4 +15,8 @@ export class AggregationMappingService { public create(toCreate: AggregationMapping): Observable<StateResource<AggregationMappingResource>> { return this.listService.create(toCreate); } + + public refreshList(): void { + this.listService.refresh(); + } } diff --git a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts index baee873bfd7c0db07a9295de75844d638edaead5..1d3a06aa4f424ac78ca5898dbe7b55354ccdeba2 100644 --- a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts +++ b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts @@ -1,20 +1,32 @@ import { ADMIN_FORMSERVICE } from '@admin-client/shared'; -import { AbstractFormService, createStateResource, StateResource } from '@alfa-client/tech-shared'; -import { dispatchEventFromFixture, getMockComponent, Mock, MockEvent } from '@alfa-client/test-utils'; +import { NavigationService } from '@alfa-client/navigation-shared'; +import { AbstractFormService, createStateResource, isValidStateResource, StateResource } from '@alfa-client/tech-shared'; +import { dispatchEventFromFixture, getMockComponent, mock, Mock, MockEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { faker } from '@faker-js/faker/.'; +import { expect } from '@jest/globals'; import { Resource } from '@ngxp/rest'; import { ButtonWithSpinnerComponent } from '@ods/component'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { singleCold } from 'libs/tech-shared/test/marbles'; +import { singleColdCompleted } from 'libs/tech-shared/test/marbles'; import { createDummyResource } from 'libs/tech-shared/test/resource'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; import { AdminSaveButtonComponent } from './admin-save-button.component'; +jest.mock('@alfa-client/tech-shared', () => { + return { + ...jest.requireActual('@alfa-client/tech-shared'), + isValidStateResource: jest.fn(), + }; +}); +const isValidStateResourceMock: jest.Mock = isValidStateResource as jest.Mock; + describe('AdminSaveButtonComponent', () => { let component: AdminSaveButtonComponent; let fixture: ComponentFixture<AdminSaveButtonComponent>; + let navigationService: Mock<NavigationService>; let formService: Mock<AbstractFormService<Resource>>; const saveButton: string = getDataTestIdOf('save'); @@ -22,7 +34,8 @@ describe('AdminSaveButtonComponent', () => { const stateResource: StateResource<Resource> = createStateResource(createDummyResource()); beforeEach(async () => { - formService = <any>{ submit: jest.fn().mockReturnValue(singleCold(stateResource)) }; + formService = <any>{ submit: jest.fn().mockReturnValue(of(stateResource)) }; + navigationService = mock(NavigationService); await TestBed.configureTestingModule({ imports: [AdminSaveButtonComponent], @@ -32,6 +45,10 @@ describe('AdminSaveButtonComponent', () => { provide: ADMIN_FORMSERVICE, useValue: formService, }, + { + provide: NavigationService, + useValue: navigationService, + }, ], }).compileComponents(); @@ -54,7 +71,26 @@ describe('AdminSaveButtonComponent', () => { it('should assign state resource', () => { dispatchEventFromFixture(fixture, saveButton, MockEvent.CLICK); - expect(component.stateResource$).toBeObservable(singleCold(stateResource)); + expect(component.stateResource$).toBeObservable(singleColdCompleted(stateResource)); + }); + + it('should navigate on successful submit', () => { + isValidStateResourceMock.mockReturnValue(true); + const linkPath: string = faker.internet.url(); + component.successLinkPath = linkPath; + + dispatchEventFromFixture(fixture, saveButton, MockEvent.CLICK); + component.stateResource$.subscribe(); + + expect(navigationService.navigate).toHaveBeenCalledWith(linkPath); + }); + + it('should NOT navigate on invalid state resource', () => { + isValidStateResourceMock.mockReturnValue(false); + dispatchEventFromFixture(fixture, saveButton, MockEvent.CLICK); + component.stateResource$.subscribe(); + + expect(navigationService.navigate).not.toHaveBeenCalled(); }); }); diff --git a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts index 60abd08c7f311ecabe6d56ecc47fbfcd16412877..7f0ff88dcdf4fe78991bff1390a17e1f17da1bef 100644 --- a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts +++ b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts @@ -1,10 +1,11 @@ import { ADMIN_FORMSERVICE } from '@admin-client/shared'; -import { AbstractFormService, createEmptyStateResource, StateResource } from '@alfa-client/tech-shared'; +import { NavigationService } from '@alfa-client/navigation-shared'; +import { AbstractFormService, createEmptyStateResource, isValidStateResource, StateResource } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; -import { Component, inject } from '@angular/core'; +import { Component, inject, Input } from '@angular/core'; import { Resource } from '@ngxp/rest'; import { ButtonWithSpinnerComponent } from '@ods/component'; -import { Observable, of } from 'rxjs'; +import { Observable, of, tap } from 'rxjs'; @Component({ selector: 'admin-save-button', @@ -13,11 +14,20 @@ import { Observable, of } from 'rxjs'; templateUrl: './admin-save-button.component.html', }) export class AdminSaveButtonComponent { - private formService: AbstractFormService<Resource> = inject(ADMIN_FORMSERVICE); + @Input() successLinkPath: string; + + private readonly formService: AbstractFormService<Resource> = inject(ADMIN_FORMSERVICE); + private readonly navigationService: NavigationService = inject(NavigationService); public stateResource$: Observable<StateResource<Resource>> = of(createEmptyStateResource<Resource>()); public submit(): void { - this.stateResource$ = this.formService.submit(); + this.stateResource$ = this.formService.submit().pipe( + tap((stateResource: StateResource<Resource>) => { + if (isValidStateResource(stateResource)) { + this.navigationService.navigate(this.successLinkPath); + } + }), + ); } } diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts index 014109b6a80633ea7665c6d1e488aeecc1e96211..146cfa8b5cdf2b4409e400afae66bf1631266add 100644 --- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts @@ -93,6 +93,14 @@ describe('StatistikContainerComponent', () => { }); }); + describe('on destroy', () => { + it('should refresh aggregation mapping list', () => { + component.ngOnDestroy(); + + expect(aggregationMappingService.refreshList).toHaveBeenCalled(); + }); + }); + describe('template', () => { describe('aggregation mapping list', () => { it('should exists', () => { diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts index 70db01b592c64a8a2afc8b59d6bb50b4e63c93d9..00226c7c85cab1000876463edc043ab96cec4aaa 100644 --- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts @@ -25,7 +25,7 @@ import { AggregationMappingListResource, AggregationMappingService } from '@admi import { ROUTES } from '@admin-client/shared'; import { StateResource } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; -import { Component, inject, OnInit } from '@angular/core'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; import { RoutingButtonComponent } from '@ods/component'; import { Observable } from 'rxjs'; import { AggregationMappingListComponent } from '../aggregation-mapping-list/aggregation-mapping-list.component'; @@ -37,7 +37,7 @@ import { AggregationMappingListComponent } from '../aggregation-mapping-list/agg imports: [CommonModule, RoutingButtonComponent, AggregationMappingListComponent], providers: [AggregationMappingService], }) -export class StatistikContainerComponent implements OnInit { +export class StatistikContainerComponent implements OnInit, OnDestroy { private service = inject(AggregationMappingService); public listStateResource$: Observable<StateResource<AggregationMappingListResource>>; @@ -47,4 +47,8 @@ export class StatistikContainerComponent implements OnInit { ngOnInit(): void { this.listStateResource$ = this.service.getList(); } + + ngOnDestroy(): void { + this.service.refreshList(); + } } diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html index a2922837c1bea1dc0f8a3344183f0ffc8e46eb8c..f81771fedaf501971ef73be12b7b34bad5ac7fa4 100644 --- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html +++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html @@ -37,7 +37,7 @@ </ods-button> <div class="mt-4 flex gap-4"> - <admin-save-button /> + <admin-save-button [successLinkPath]="Routes.STATISTIK" /> <admin-cancel-button [linkPath]="Routes.STATISTIK" /> </div> </div>