diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts index 1018a1081b39f524092d92c8d3449c9bdeb2d363..45a24946fded8a238f1d92fa39d4c057b28a5573 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts @@ -30,6 +30,7 @@ import { dropCollections, intercept, scrollToWindowBottom, + scrollToWindowTop, waitOfInterceptor, } from '../../../support/cypress-helper'; import { generateIds } from '../../../support/tech.util'; @@ -72,13 +73,8 @@ describe('VorgangList Pages', () => { it('should show 1 page with 100 vorgaenge NEU', () => { waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEU_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangNEU_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEU_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangNEU_' + PAGE_SIZE); }); }); }); @@ -95,14 +91,8 @@ describe('VorgangList Pages', () => { waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangNEUAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangNEUAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEUAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangNEUAssigned_' + PAGE_SIZE); }); waitForSpinnerToDisappear(); }); @@ -120,14 +110,8 @@ describe('VorgangList Pages', () => { waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangANGENOMMEN_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangANGENOMMEN_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangANGENOMMEN_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangANGENOMMEN_' + PAGE_SIZE); }); waitForSpinnerToDisappear(); }); @@ -140,20 +124,18 @@ describe('VorgangList Pages', () => { intercept(HttpMethodE2E.GET, buildVorgangPageLink(4)).as(loadNextPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 3 page with 100 vorgaenge ANGENOMMEN ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { scrollToWindowBottom(); assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangANGENOMMENAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangANGENOMMENAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangANGENOMMENAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangANGENOMMENAssigned_' + PAGE_SIZE); }); }); }); @@ -176,14 +158,8 @@ describe('VorgangList Pages', () => { waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangNEUAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangNEUAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEUAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangNEUAssigned_' + PAGE_SIZE); }); }); }); @@ -195,19 +171,17 @@ describe('VorgangList Pages', () => { intercept(HttpMethodE2E.GET, buildVorgangPageLink(2)).as(loadNextPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 2 page with 100 vorgaenge ANGENOMMEN ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangANGENOMMENAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangANGENOMMENAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangANGENOMMENAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangANGENOMMENAssigned_' + PAGE_SIZE); }); waitForSpinnerToDisappear(); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts index c1ffd8afacb43b5f408688fc2da1c2a0bbe849c3..db83669a5bb144828aa67a60d4f89a8271fc8972 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts @@ -31,7 +31,13 @@ import { VorgangViewsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/v import { HttpMethodE2E } from 'apps/alfa-e2e/src/model/util'; import { ClientAttributeNameE2E, VorgangE2E } from 'apps/alfa-e2e/src/model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from 'apps/alfa-e2e/src/page-objects/main.po'; -import { dropCollections, intercept, scrollToWindowBottom, waitOfInterceptor } from 'apps/alfa-e2e/src/support/cypress-helper'; +import { + dropCollections, + intercept, + scrollToWindowBottom, + scrollToWindowTop, + waitOfInterceptor, +} from 'apps/alfa-e2e/src/support/cypress-helper'; import { exist } from 'apps/alfa-e2e/src/support/cypress.util'; import { createDateToday, generateIds } from 'apps/alfa-e2e/src/support/tech.util'; import { getUserSabineId, initUsermanagerUsers, loginAsSabine } from 'apps/alfa-e2e/src/support/user-util'; @@ -161,6 +167,10 @@ describe('VorgangList View Wiedervorlagen', () => { intercept(HttpMethodE2E.GET, buildVorgangWithOpenWiedervorlagenPageLink(3)).as(loadPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 3 page with 10 vorgaenge with open wiedervorlagen ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); @@ -203,6 +213,10 @@ describe('VorgangList View Wiedervorlagen', () => { intercept(HttpMethodE2E.GET, buildVorgangWithOpenWiedervorlagenAssignedPageLink(2)).as(loadPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 2 page with 10 vorgaenge with open wiedervorlagen and 90 vorgaenge with open wiedervorlagen ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts index 5a91a0813ffbe8dec5a89c9f526382168481bdcd..3928e72cc9b20e768c905eedb69dc48c4ecfba3b 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts @@ -40,6 +40,9 @@ describe('KeycloakResourceService', () => { const dummyObject: Dummy = createDummy(); const dummyAction: Observable<Dummy> = of(dummyObject); + const dummyError: Error = new Error('Test error'); + const dummyErrorAction: Observable<Error> = new Observable((observer) => observer.error(dummyError)); + beforeEach(() => { TestBed.configureTestingModule({ providers: [TestResourceService], @@ -52,7 +55,7 @@ describe('KeycloakResourceService', () => { const stateResource: StateResource<unknown> = createStateResource([]); beforeEach(() => { - service.handleChanges = jest.fn().mockReturnValue(singleCold(stateResource)); + service._handleChanges = jest.fn().mockReturnValue(singleCold(stateResource)); }); it('should return stateResource', () => { @@ -64,7 +67,7 @@ describe('KeycloakResourceService', () => { it('should call handleChanges ', fakeAsync(() => { service.getAll().subscribe(); - expect(service.handleChanges).toHaveBeenCalled(); + expect(service._handleChanges).toHaveBeenCalled(); })); }); @@ -76,7 +79,7 @@ describe('KeycloakResourceService', () => { }); it('should call doIfLoadingRequired', () => { - service.handleChanges(emptyStateResource); + service._handleChanges(emptyStateResource); expect(doIfLoadingRequiredSpy).toHaveBeenCalled(); }); @@ -84,7 +87,7 @@ describe('KeycloakResourceService', () => { it('should return stateResource', (done) => { service.stateResource.next(createStateResource([])); - service.handleChanges(emptyStateResource).subscribe((stateResource: StateResource<[]>) => { + service._handleChanges(emptyStateResource).subscribe((stateResource: StateResource<[]>) => { expect(stateResource).toEqual(createStateResource([])); done(); }); @@ -93,18 +96,18 @@ describe('KeycloakResourceService', () => { describe('loadResource', () => { it('should call set loading', () => { - service.setLoading = jest.fn(); + service._setLoading = jest.fn(); - service.loadResource(); + service._loadResource(); - expect(service.setLoading).toHaveBeenCalled(); + expect(service._setLoading).toHaveBeenCalled(); }); it('should update Resource', fakeAsync(() => { const dummyItems = [createDummy(), createDummy()]; jest.spyOn(service, '_getItemsFromKeycloak' as any).mockReturnValue(of(dummyItems)); - service.loadResource(); + service._loadResource(); tick(); expect(service.stateResource.value.resource).toEqual(dummyItems); @@ -115,11 +118,11 @@ describe('KeycloakResourceService', () => { const saveObject: Dummy = createDummy(); it('should call handleLoading', () => { - service.handleLoading = jest.fn(); + service._handleLoading = jest.fn(); service.create(saveObject); - expect(service.handleLoading).toHaveBeenCalled(); + expect(service._handleLoading).toHaveBeenCalled(); }); it('should call createInKeycloak', () => { @@ -133,11 +136,11 @@ describe('KeycloakResourceService', () => { describe('save', () => { it('should call handleLoading', () => { - service.handleLoading = jest.fn(); + service._handleLoading = jest.fn(); service.save(dummyObject); - expect(service.handleLoading).toHaveBeenCalled(); + expect(service._handleLoading).toHaveBeenCalled(); }); it('should call createInKeycloak', () => { @@ -151,11 +154,11 @@ describe('KeycloakResourceService', () => { describe('delete', () => { it('should call handleLoading', () => { - service.handleLoading = jest.fn(); + service._handleLoading = jest.fn(); service.delete(id); - expect(service.handleLoading).toHaveBeenCalled(); + expect(service._handleLoading).toHaveBeenCalled(); }); it('should call createInKeycloak', () => { @@ -169,42 +172,57 @@ describe('KeycloakResourceService', () => { describe('handleLoading', () => { it('should set loading', () => { - service.handleLoading(dummyAction); + service._handleLoading(dummyAction); expect(service.stateResource.value.loading).toBe(true); }); it('should call refreshAfterFirstEmit', () => { - service.refreshAfterFirstEmit = jest.fn().mockReturnValue(dummyAction); + service._refreshAfterEmit = jest.fn().mockReturnValue(dummyAction); - service.handleLoading(dummyAction); + service._handleLoading(dummyAction); - expect(service.refreshAfterFirstEmit).toHaveBeenCalled(); + expect(service._refreshAfterEmit).toHaveBeenCalled(); }); it('should call progress', () => { - service.setLoadingInStateResource = jest.fn().mockReturnValue(dummyAction); + service._setLoadingInStateResource = jest.fn().mockReturnValue(dummyAction); - service.handleLoading(dummyAction); + service._handleLoading(dummyAction); - expect(service.setLoadingInStateResource).toHaveBeenCalled(); + expect(service._setLoadingInStateResource).toHaveBeenCalled(); }); }); - describe('refreshAfterFirstEmit', () => { - it('should call refresh after first emit', fakeAsync(() => { + describe('refreshAfterEmit', () => { + it('should call refresh after first emit', () => { service.refresh = jest.fn(); - service.refreshAfterFirstEmit(dummyAction).subscribe(); - tick(); + service._refreshAfterEmit(dummyAction).subscribe(); expect(service.refresh).toHaveBeenCalled(); - })); + }); + + it('should call refresh on error', () => { + service.refresh = jest.fn(); + + service._refreshAfterEmit(dummyErrorAction).subscribe(); + + expect(service.refresh).toHaveBeenCalled(); + }); + + it('should throw error refresh on error', () => { + service.refresh = jest.fn(); + + const result: Observable<unknown> = service._refreshAfterEmit(dummyErrorAction); + + expect(result).toBeObservable(cold('#', null, dummyError)); + }); }); describe('setLoadingInStateResource', () => { it('should emit emptyState first with loading and then state without loading', () => { - const result: Observable<StateResource<Dummy>> = service.setLoadingInStateResource<Dummy>(cold('--x', { x: dummyObject })); + const result: Observable<StateResource<Dummy>> = service._setLoadingInStateResource<Dummy>(cold('--x', { x: dummyObject })); expect(result).toBeObservable(cold('a-b', { a: createEmptyStateResource(true), b: createStateResource(dummyObject) })); }); @@ -214,7 +232,7 @@ describe('KeycloakResourceService', () => { it('should set loading in state to true without parameter', () => { service.stateResource.value.loading = false; - service.setLoading(); + service._setLoading(); expect(service.stateResource.value.loading).toEqual(true); }); diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts index ae74c73ee2c59c989a0db77dbaa1b881c4061448..2b6255aa9bba1e4ac1424de5a9b56282cb683349 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts @@ -22,7 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { createEmptyStateResource, createStateResource, doIfLoadingRequired, StateResource } from '@alfa-client/tech-shared'; -import { BehaviorSubject, first, map, Observable, startWith, switchMap, tap } from 'rxjs'; +import { BehaviorSubject, catchError, first, map, Observable, startWith, switchMap, tap, throwError } from 'rxjs'; export abstract class KeycloakResourceService<T> { readonly stateResource: BehaviorSubject<StateResource<T[]>> = new BehaviorSubject(createEmptyStateResource()); @@ -30,16 +30,16 @@ export abstract class KeycloakResourceService<T> { public getAll(): Observable<StateResource<T[]>> { return this.stateResource .asObservable() - .pipe(switchMap((stateResource: StateResource<T[]>) => this.handleChanges(stateResource))); + .pipe(switchMap((stateResource: StateResource<T[]>) => this._handleChanges(stateResource))); } - handleChanges(stateResource: StateResource<T[]>): Observable<StateResource<T[]>> { - doIfLoadingRequired(stateResource, (): void => this.loadResource()); + _handleChanges(stateResource: StateResource<T[]>): Observable<StateResource<T[]>> { + doIfLoadingRequired(stateResource, (): void => this._loadResource()); return this.stateResource.asObservable(); } - loadResource(): void { - this.setLoading(); + _loadResource(): void { + this._setLoading(); this._getItemsFromKeycloak() .pipe(first()) .subscribe((items: T[]): void => this.updateResource(items)); @@ -52,43 +52,49 @@ export abstract class KeycloakResourceService<T> { } public create(item: Partial<T>): Observable<StateResource<T>> { - return this.handleLoading<T>(this._createInKeycloak(item)); + return this._handleLoading<T>(this._createInKeycloak(item)); } protected abstract _createInKeycloak(item: Partial<T>): Observable<T>; public save(item: T): Observable<StateResource<T>> { - return this.handleLoading<T>(this._saveInKeycloak(item)); + return this._handleLoading<T>(this._saveInKeycloak(item)); } protected abstract _saveInKeycloak(item: T): Observable<T>; public delete(id: string): Observable<StateResource<void>> { - return this.handleLoading(this._deleteInKeycloak(id)); + return this._handleLoading(this._deleteInKeycloak(id)); } protected abstract _deleteInKeycloak(id: string): Observable<void>; - handleLoading<D>(action: Observable<D>): Observable<StateResource<D>> { - this.setLoading(); - return this.setLoadingInStateResource<D>(this.refreshAfterFirstEmit<D>(action)); + _handleLoading<D>(action: Observable<D>): Observable<StateResource<D>> { + this._setLoading(); + return this._setLoadingInStateResource<D>(this._refreshAfterEmit<D>(action)); } - refreshAfterFirstEmit<D>(action: Observable<D>): Observable<D> { + _refreshAfterEmit<D>(action: Observable<D>): Observable<D> { return action.pipe( first(), tap((): void => this.refresh()), + catchError((err: Error) => this.handleError(err)), ); } - setLoadingInStateResource<D>(action: Observable<D>): Observable<StateResource<D>> { + handleError(err: Error): Observable<never> { + this.refresh(); + return throwError(() => err); + } + + _setLoadingInStateResource<D>(action: Observable<D>): Observable<StateResource<D>> { return action.pipe( map((value: D): StateResource<D> => createStateResource<D>(value)), startWith(createEmptyStateResource<D>(true)), ); } - setLoading(): void { + _setLoading(): void { this.stateResource.next({ ...this.stateResource.value, loading: true }); } diff --git a/alfa-client/libs/command-shared/src/lib/command.model.ts b/alfa-client/libs/command-shared/src/lib/command.model.ts index a64cb0dd5f581ff2a55b66d3ab9e56f22223841a..b86ac920fbeab00514c3cf45b7ae0f88e7ff7ce3 100644 --- a/alfa-client/libs/command-shared/src/lib/command.model.ts +++ b/alfa-client/libs/command-shared/src/lib/command.model.ts @@ -73,6 +73,7 @@ export enum CommandOrder { VORGANG_ZURUECKHOLEN = 'VORGANG_ZURUECKHOLEN', VORGANG_BEARBEITEN = 'VORGANG_BEARBEITEN', VORGANG_BESCHEIDEN = 'VORGANG_BESCHEIDEN', + FORWARD_VORGANG = 'FORWARD_VORGANG', VORGANG_ZURUECKSTELLEN = 'VORGANG_ZURUECKSTELLEN', VORGANG_ABSCHLIESSEN = 'VORGANG_ABSCHLIESSEN', VORGANG_WIEDEREROEFFNEN = 'VORGANG_WIEDEREROEFFNEN', @@ -98,3 +99,5 @@ export interface CreateCommandProps { snackBarMessage?: string; snackBarErrorMessage?: string; } + +export type CreateCommandPropsWithoutResource = Omit<CreateCommandProps, 'resource'>; diff --git a/alfa-client/libs/command-shared/test/command.ts b/alfa-client/libs/command-shared/test/command.ts index ff7aae6c8ba99ae02f921c49b9a789c675e404bd..05fec9de4806f6473cf2d4204ee196ed71db5da0 100644 --- a/alfa-client/libs/command-shared/test/command.ts +++ b/alfa-client/libs/command-shared/test/command.ts @@ -35,6 +35,7 @@ import { CommandStatus, CreateCommand, CreateCommandProps, + CreateCommandPropsWithoutResource, } from '../src/lib/command.model'; export function createCommand(): Command { @@ -85,8 +86,11 @@ export function createCreateCommand(order: CommandOrder = CommandOrder.VORGANG_A } export function createCreateCommandProps(): CreateCommandProps { + return { ...createCreateCommandPropsWithoutResource(), resource: createCommandResource() }; +} + +export function createCreateCommandPropsWithoutResource(): CreateCommandPropsWithoutResource { return { - resource: createCommandResource(), linkRel: faker.internet.url(), command: createCreateCommand(), snackBarMessage: faker.word.sample(5), diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts index 34a7bd065f0c85b3ddc80a39d2fbe195e9c33655..8c472b9da3215b624913bf869c367887ab97c27f 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts @@ -21,8 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { LinkRelationName } from '@alfa-client/tech-shared'; import { mock, useFromMock } from '@alfa-client/test-utils'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { faker } from '@faker-js/faker/.'; import { ResourceFactory } from '@ngxp/rest'; import { cold, hot } from 'jest-marbles'; import { createForwardingListResource } from 'libs/forwarding-shared/test/forwarding'; @@ -45,25 +47,26 @@ describe('ForwardingRepository', () => { describe('getForwardings', () => { const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.FORWARD_BY_EMAIL]); const commandList: ForwardingListResource = createForwardingListResource(); + const linkRel: LinkRelationName = faker.string.alpha(5); beforeEach(() => { resourceWrapper.get.mockReturnValue(hot('a', { a: commandList })); }); it('should call resourceFactory', () => { - repository.getForwardings(vorgang); + repository.getForwardings(vorgang, linkRel); expect(resourceFactory.from).toHaveBeenCalledWith(vorgang); }); it('should call resourceWrapper', () => { - repository.getForwardings(vorgang); + repository.getForwardings(vorgang, linkRel); - expect(resourceWrapper.get).toHaveBeenCalledWith(VorgangWithEingangLinkRel.FORWARD_BY_EMAIL); + expect(resourceWrapper.get).toHaveBeenCalledWith(linkRel); }); it('should return result', () => { - let result = repository.getForwardings(vorgang); + let result = repository.getForwardings(vorgang, linkRel); expect(result).not.toBeNull(); expect(result).toBeObservable(cold('a', { a: commandList })); diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts index a83ca3536dabe921ff4dc10719dbbdd1f5c74943..acd33b4bc2523a2761e420640d1d422cbdbca088 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts @@ -21,7 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { LinkRelationName } from '@alfa-client/tech-shared'; +import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Injectable } from '@angular/core'; import { ResourceFactory } from '@ngxp/rest'; import { Observable } from 'rxjs'; @@ -31,7 +32,7 @@ import { ForwardingListResource } from './forwarding.model'; export class ForwardingRepository { constructor(private resourceFactory: ResourceFactory) {} - public getForwardings(vorgang: VorgangWithEingangResource): Observable<ForwardingListResource> { - return this.resourceFactory.from(vorgang).get(VorgangWithEingangLinkRel.FORWARD_BY_EMAIL); + public getForwardings(vorgang: VorgangWithEingangResource, linkRel: LinkRelationName): Observable<ForwardingListResource> { + return this.resourceFactory.from(vorgang).get(linkRel); } } diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts index afb141693929a6b51c1d096d58510076816fdc0a..f3f631dfbcb316d354a18b2c2fab9299d347cd91 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { CommandOrder, CommandResource, CommandService } from '@alfa-client/command-shared'; +import { CommandOrder, CommandResource, CommandService, CreateCommandPropsWithoutResource } from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { + EMPTY_STRING, StateResource, createEmptyStateResource, createErrorStateResource, @@ -38,16 +39,19 @@ import { VorgangWithEingangLinkRel, VorgangWithEingangResource, } from '@alfa-client/vorgang-shared'; -import { cold, hot } from 'jest-marbles'; +import { faker } from '@faker-js/faker/.'; +import { ResourceUri } from '@ngxp/rest'; +import { hot } from 'jest-marbles'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { createCommandResource } from 'libs/command-shared/test/command'; +import { createCommandResource, createCreateCommandPropsWithoutResource } from 'libs/command-shared/test/command'; import { createVorgangForwardRequest, createVorgangResource, createVorgangWithEingangResource, } from 'libs/vorgang-shared/test/vorgang'; -import { of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { createApiError } from '../../../tech-shared/test/error'; +import { multipleCold, singleColdCompleted } from '../../../tech-shared/test/marbles'; import { createForwardingListResource, createForwardingResource } from '../../test/forwarding'; import { ForwardingLinkRel } from './forwarding.linkrel'; import { ForwardingListResource, ForwardingResource } from './forwarding.model'; @@ -82,10 +86,9 @@ describe('ForwardingService', () => { expect(service).toBeTruthy(); }); - describe('forward', () => { + describe('forward by email', () => { const vorgang: VorgangResource = createVorgangResource(); - const commandStateResource: StateResource<CommandResource> = - createStateResource(createCommandResource()); + const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); beforeEach(() => { commandService.createCommand.mockReturnValue(of(commandStateResource)); @@ -99,31 +102,27 @@ describe('ForwardingService', () => { body: null, }; - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); - expect(commandService.createCommand).toHaveBeenCalledWith( - vorgang, - VorgangWithEingangLinkRel.FORWARD, - command, - ); + expect(commandService.createCommand).toHaveBeenCalledWith(vorgang, VorgangWithEingangLinkRel.FORWARD, command); }); it('should call reloadCurrentVorgang', () => { service.reloadCurrentVorgang = jest.fn(); - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); expect(service.reloadCurrentVorgang).toHaveBeenCalled(); }); it('should call setPendingForwardSingleCommandLoading', () => { - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); expect(vorgangService.setPendingForwardSingleCommandLoading).toHaveBeenCalled(); }); it('should call setPendingForwardSingleCommand', () => { - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); expect(vorgangService.setPendingForwardSingleCommand).toHaveBeenCalled(); }); @@ -169,16 +168,12 @@ describe('ForwardingService', () => { }); it('should call vorgangservice on command is done', () => { - const commandServiceReturnValue = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); + const commandServiceReturnValue = createStateResource(createCommandResource([CommandLinkRel.EFFECTED_RESOURCE])); commandService.pollCommand.mockReturnValue(of(commandServiceReturnValue)); service.pollPendingForwardCommand(createStateResource(commandResourceWithUpdateLink)); - expect(vorgangService.setPendingForwardSingleCommand).toHaveBeenCalledWith( - commandServiceReturnValue, - ); + expect(vorgangService.setPendingForwardSingleCommand).toHaveBeenCalledWith(commandServiceReturnValue); }); it('should call not vorgangservice on pending command', () => { @@ -237,7 +232,7 @@ describe('ForwardingService', () => { }); }); - describe('getForwardings', () => { + describe('get forwardings by email', () => { const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource(); const listResource: ForwardingListResource = createForwardingListResource(); @@ -246,17 +241,15 @@ describe('ForwardingService', () => { }); it('should return value', () => { - const result = service.getForwardings(vorgang); + const result: Observable<StateResource<ForwardingListResource>> = service.getForwardingsByEmail(vorgang); - expect(result).toBeObservable( - cold('ab', { a: createEmptyStateResource(true), b: createStateResource(listResource) }), - ); + expect(result).toBeObservable(multipleCold(createEmptyStateResource(true), createStateResource(listResource))); }); it('should call repository', () => { - service.getForwardings(vorgang); + service.getForwardingsByEmail(vorgang); - expect(forwardingRepository.getForwardings).toHaveBeenCalledWith(vorgang); + expect(forwardingRepository.getForwardings).toHaveBeenCalledWith(vorgang, VorgangWithEingangLinkRel.FORWARD_BY_EMAIL); }); }); @@ -273,10 +266,7 @@ describe('ForwardingService', () => { order: CommandOrder.FORWARD_SUCCESSFULL, body: null, }); - - expect(result).toBeObservable( - cold('ab', { a: createEmptyStateResource(true), b: stateResource }), - ); + expect(result).toBeObservable(multipleCold(createEmptyStateResource(true), stateResource)); }); }); @@ -284,11 +274,10 @@ describe('ForwardingService', () => { it('should call command service', () => { service.markAsSuccess(forwading); - expect(commandService.createCommand).toHaveBeenCalledWith( - forwading, - ForwardingLinkRel.MARK_AS_SUCCESS, - { order: CommandOrder.FORWARD_SUCCESSFULL, body: null }, - ); + expect(commandService.createCommand).toHaveBeenCalledWith(forwading, ForwardingLinkRel.MARK_AS_SUCCESS, { + order: CommandOrder.FORWARD_SUCCESSFULL, + body: null, + }); }); it('should update list on valid response', () => { @@ -306,11 +295,10 @@ describe('ForwardingService', () => { it('should call command service', () => { service.markAsFail(forwading); - expect(commandService.createCommand).toHaveBeenCalledWith( - forwading, - ForwardingLinkRel.MARK_AS_FAIL, - { order: CommandOrder.FORWARD_FAILED, body: null }, - ); + expect(commandService.createCommand).toHaveBeenCalledWith(forwading, ForwardingLinkRel.MARK_AS_FAIL, { + order: CommandOrder.FORWARD_FAILED, + body: null, + }); }); it('should update vorgang on valid response', () => { @@ -368,4 +356,60 @@ describe('ForwardingService', () => { expect(service.setList).toHaveBeenCalledWith(list); }); }); + + describe('forward', () => { + const forwardingToUri: ResourceUri = faker.internet.url(); + + const createCommandProps: CreateCommandPropsWithoutResource = createCreateCommandPropsWithoutResource(); + const commandResource: CommandResource = createCommandResource(); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); + + beforeEach(() => { + vorgangService.createCommand.mockReturnValue(of(commandStateResource)); + service._buildForwardCreateCommandProps = jest.fn().mockReturnValue(createCommandProps); + }); + + it('should call build forward create command', () => { + service.forward(forwardingToUri).subscribe(); + + expect(service._buildForwardCreateCommandProps).toHaveBeenCalledWith(forwardingToUri); + }); + + it('should call vorgang service to create command', () => { + service.forward(forwardingToUri).subscribe(); + + expect(vorgangService.createCommand).toHaveBeenCalledWith(createCommandProps, true); + }); + + it('should return response from command service', () => { + const forwardCommand$: Observable<StateResource<CommandResource>> = service.forward(forwardingToUri); + + expect(forwardCommand$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + }); + + describe('build forward command props', () => { + const forwardingToUri: ResourceUri = faker.internet.url(); + + it('should contains linkrel', () => { + const commandProps: CreateCommandPropsWithoutResource = service._buildForwardCreateCommandProps(forwardingToUri); + + expect(commandProps.linkRel).toBe(VorgangWithEingangLinkRel.FORWARD_BY_OZGCLOUD); + }); + + it('should contains command', () => { + const commandProps: CreateCommandPropsWithoutResource = service._buildForwardCreateCommandProps(forwardingToUri); + + expect(commandProps.command).toEqual({ + order: CommandOrder.FORWARD_VORGANG, + body: { organisationEinheitId: forwardingToUri }, + }); + }); + + it('should contains empty snackbar message', () => { + const commandProps: CreateCommandPropsWithoutResource = service._buildForwardCreateCommandProps(forwardingToUri); + + expect(commandProps.snackBarMessage).toBe(EMPTY_STRING); + }); + }); }); diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts index 73510b902a2a9408905b9af3124bba1ab81efe47..b84c9d5c0ee51ea7e6464997fd24106a8c91fbf4 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts @@ -21,17 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Injectable, OnDestroy } from '@angular/core'; -import { Params } from '@angular/router'; import { + CommandOrder, CommandResource, CommandService, CreateCommand, + CreateCommandPropsWithoutResource, isDone, isPending, } from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { + EMPTY_STRING, StateResource, createEmptyStateResource, createStateResource, @@ -45,21 +46,22 @@ import { VorgangWithEingangResource, createForwardCommand, } from '@alfa-client/vorgang-shared'; +import { Injectable, OnDestroy } from '@angular/core'; +import { Params } from '@angular/router'; +import { ResourceUri } from '@ngxp/rest'; import { isNil } from 'lodash-es'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { first, map, startWith, tap } from 'rxjs/operators'; import { ForwardingLinkRel } from './forwarding.linkrel'; import { ForwardingListResource, ForwardingResource } from './forwarding.model'; import { ForwardingRepository } from './forwarding.repository'; -import { - createForwardingMarkAsFailCommand, - createForwardingMarkAsSuccessCommand, -} from './forwarding.util'; +import { createForwardingMarkAsFailCommand, createForwardingMarkAsSuccessCommand } from './forwarding.util'; @Injectable({ providedIn: 'root' }) export class ForwardingService implements OnDestroy { - private readonly forwardingList$: BehaviorSubject<StateResource<ForwardingListResource>> = - new BehaviorSubject(createEmptyStateResource<ForwardingListResource>()); + private readonly forwardingList$: BehaviorSubject<StateResource<ForwardingListResource>> = new BehaviorSubject( + createEmptyStateResource<ForwardingListResource>(), + ); private navigationSubscription: Subscription; private subscription: Subscription; @@ -71,15 +73,15 @@ export class ForwardingService implements OnDestroy { private forwardingRepository: ForwardingRepository, ) {} - getForwardings( - vorgang: VorgangWithEingangResource, - ): Observable<StateResource<ForwardingListResource>> { + getForwardingsByEmail(vorgang: VorgangWithEingangResource): Observable<StateResource<ForwardingListResource>> { this.forwardingList$.next(createEmptyStateResource(true)); - const subscription = this.forwardingRepository.getForwardings(vorgang).subscribe((list) => { - this.forwardingList$.next(createStateResource(list)); - subscription.unsubscribe(); - }); + const subscription = this.forwardingRepository + .getForwardings(vorgang, VorgangWithEingangLinkRel.FORWARD_BY_EMAIL) + .subscribe((listResource: ForwardingListResource) => { + this.forwardingList$.next(createStateResource(listResource)); + subscription.unsubscribe(); + }); return this.forwardingList$.asObservable(); } @@ -94,9 +96,7 @@ export class ForwardingService implements OnDestroy { listenToNavigation(): void { this.unsubscribe(); - this.navigationSubscription = this.navigationService - .urlChanged() - .subscribe((params) => this.onNavigation(params)); + this.navigationSubscription = this.navigationService.urlChanged().subscribe((params) => this.onNavigation(params)); } onNavigation(params: Params): void { @@ -105,19 +105,15 @@ export class ForwardingService implements OnDestroy { } } - pollPendingForwardCommand( - command: StateResource<CommandResource>, - ): StateResource<CommandResource> { + pollPendingForwardCommand(command: StateResource<CommandResource>): StateResource<CommandResource> { if (this.shouldPoll(command)) { - this.subscription = this.commandService - .pollCommand(command.resource) - .subscribe((updatedCommand) => { - if (isDone(updatedCommand.resource)) { - this.vorgangService.setPendingForwardSingleCommand(updatedCommand); - this.reloadCurrentVorgang(updatedCommand); - this.subscription.unsubscribe(); - } - }); + this.subscription = this.commandService.pollCommand(command.resource).subscribe((updatedCommand) => { + if (isDone(updatedCommand.resource)) { + this.vorgangService.setPendingForwardSingleCommand(updatedCommand); + this.reloadCurrentVorgang(updatedCommand); + this.subscription.unsubscribe(); + } + }); } return command; } @@ -126,10 +122,7 @@ export class ForwardingService implements OnDestroy { return command.loaded && isPending(command.resource); } - public forward( - vorgang: VorgangResource, - request: ForwardRequest, - ): Observable<StateResource<CommandResource>> { + public forwardByEmail(vorgang: VorgangResource, request: ForwardRequest): Observable<StateResource<CommandResource>> { this.vorgangService.setPendingForwardSingleCommandLoading(); const subscription: Subscription = this.commandService .createCommand(vorgang, VorgangWithEingangLinkRel.FORWARD, createForwardCommand(request)) @@ -142,19 +135,13 @@ export class ForwardingService implements OnDestroy { } markAsSuccess(forward: ForwardingResource): Observable<StateResource<CommandResource>> { - return this.createMarkAsCommand( - forward, - ForwardingLinkRel.MARK_AS_SUCCESS, - createForwardingMarkAsSuccessCommand(), - ).pipe(tap((command) => this.updateForwardingList(command))); + return this.createMarkAsCommand(forward, ForwardingLinkRel.MARK_AS_SUCCESS, createForwardingMarkAsSuccessCommand()).pipe( + tap((command) => this.updateForwardingList(command)), + ); } markAsFail(forward: ForwardingResource): Observable<StateResource<CommandResource>> { - return this.createMarkAsCommand( - forward, - ForwardingLinkRel.MARK_AS_FAIL, - createForwardingMarkAsFailCommand(), - ).pipe( + return this.createMarkAsCommand(forward, ForwardingLinkRel.MARK_AS_FAIL, createForwardingMarkAsFailCommand()).pipe( tap((command) => { if (isDone(command.resource)) this.reloadCurrentVorgang(command); }), @@ -192,6 +179,22 @@ export class ForwardingService implements OnDestroy { this.forwardingList$.next(createStateResource(list)); } + public forward(forwardingToUri: ResourceUri): Observable<StateResource<CommandResource>> { + return this.vorgangService.createCommand(this._buildForwardCreateCommandProps(forwardingToUri), true); + } + + _buildForwardCreateCommandProps(forwardingToUri: ResourceUri): CreateCommandPropsWithoutResource { + return { + linkRel: VorgangWithEingangLinkRel.FORWARD_BY_OZGCLOUD, + command: this.createBuildForwardCommand(forwardingToUri), + snackBarMessage: EMPTY_STRING, + }; + } + + private createBuildForwardCommand(forwardingToUri: ResourceUri): CreateCommand { + return { order: CommandOrder.FORWARD_VORGANG, body: { organisationEinheitId: forwardingToUri } }; + } + ngOnDestroy(): void { this.unsubscribe(); } diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts index a4dd016d064b1e6d4c377d4f37518d8f9811eb84..b7387f11528fc118117ad6ca0cb51e11850ec1e8 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts @@ -120,7 +120,7 @@ describe('ForwardingByEmailContainerComponent', () => { component.getForwardings(); - expect(service.getForwardings).not.toHaveBeenCalled(); + expect(service.getForwardingsByEmail).not.toHaveBeenCalled(); }); it('should call service get forward commands', () => { @@ -129,7 +129,7 @@ describe('ForwardingByEmailContainerComponent', () => { component.getForwardings(); - expect(service.getForwardings).toHaveBeenCalled(); + expect(service.getForwardingsByEmail).toHaveBeenCalled(); }); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts index f38fe66d56f971eef30db7804b5f8eea516853f1..bfc76dd9bd7bcb57c775bf38f8b60ab924c8f31b 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts @@ -65,7 +65,7 @@ export class ForwardingByEmailContainerComponent implements OnChanges { getForwardings(): void { if (hasLink(this.vorgang, VorgangWithEingangLinkRel.FORWARD_BY_EMAIL)) { - this.forwardingStateResources$ = this.forwardingService.getForwardings(this.vorgang); + this.forwardingStateResources$ = this.forwardingService.getForwardingsByEmail(this.vorgang); } } diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts index 9cbe55ce655a5df52ab295788a8879602a7d9bb9..364d7e506e6e6b54ec5a84ecfb01f98ffebb9d9c 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts @@ -61,7 +61,7 @@ export class ForwardingByEmailFormService extends AbstractFormService<CommandRes } protected doSubmit(): Observable<StateResource<CommandResource>> { - return this.forwardingService.forward(this.vorgang, this.getFormValue()); + return this.forwardingService.forwardByEmail(this.vorgang, this.getFormValue()); } patchField(fieldName: string, value: string) { diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts index a20bed0488696ecb79c97108a03d0c2b5f1a36f8..26483f43dbf893769e87f2c6589ff88744c84461 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts @@ -22,7 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { ForwardingService } from '@alfa-client/forwarding-shared'; -import { mock, useFromMock } from '@alfa-client/test-utils'; +import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang'; import { of } from 'rxjs'; @@ -30,7 +30,8 @@ import { ForwardingByEmailFormService } from './forwarding-by-email-form.service describe('ForwardingByEmailFormService', () => { let formService: ForwardingByEmailFormService; - let service; + + let service: Mock<ForwardingService>; const formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); @@ -48,8 +49,7 @@ describe('ForwardingByEmailFormService', () => { const returnValue = {}; beforeEach(() => { - service.forward.mockReturnValue(of(returnValue)); - service.doSubmit = jest.fn(); + service.forwardByEmail.mockReturnValue(of(returnValue)); }); it('should call service', () => { @@ -57,7 +57,7 @@ describe('ForwardingByEmailFormService', () => { formService.submit(); - expect(service.forward).toHaveBeenCalledWith(formService.vorgang, formService.form.value); + expect(service.forwardByEmail).toHaveBeenCalledWith(formService.vorgang, formService.form.value); }); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html index ad97972cd9cc4c7e7f135d96b2b755378f953b3e..e6c65fbf4d123859056d2b834c6b45107a620683 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html @@ -1 +1,6 @@ -<alfa-forwarding-dialog [selectedSearchResult]="selectedSearchResult$ | async" data-test-id="forwarding-dialog"/> \ No newline at end of file +<alfa-forwarding-dialog + [forwardCommandStateResource]="forwardCommandStateResource$ | async" + [selectedSearchResult]="selectedSearchResult$ | async" + (forward)="forward($event)" + data-test-id="forwarding-dialog" +/> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts index 355c614cc694333be2f34a629eac5ad5b527035e..2dbd1a86402ade740cfbef6bc23460542baec559 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts @@ -1,9 +1,18 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { mock, Mock } from '@alfa-client/test-utils'; +import { CommandLinkRel, CommandResource } from '@alfa-client/command-shared'; +import { ForwardingService } from '@alfa-client/forwarding-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { mock, Mock, triggerEvent } from '@alfa-client/test-utils'; +import { OzgcloudDialogService } from '@alfa-client/ui'; import { OrganisationsEinheitService, ZUSTAENDIGE_STELLE_SERVICE } from '@alfa-client/zustaendige-stelle-shared'; import { AsyncPipe } from '@angular/common'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { faker } from '@faker-js/faker/.'; +import { ResourceUri } from '@ngxp/rest'; +import { createCommandStateResource } from 'libs/command-shared/test/command'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { singleColdCompleted } from 'libs/tech-shared/test/marbles'; import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; import { ForwardingDialogContainerComponent } from './forwarding-dialog-container.component'; import { ForwardingDialogComponent } from './forwarding-dialog/forwarding-dialog.component'; @@ -11,14 +20,30 @@ describe('ForwardingDialogContainerComponent', () => { let component: ForwardingDialogContainerComponent; let fixture: ComponentFixture<ForwardingDialogContainerComponent>; + const forwardingDialog: string = getDataTestIdOf('forwarding-dialog'); + + let service: Mock<ForwardingService>; let organisationsEinheitService: Mock<OrganisationsEinheitService>; + let dialogService: Mock<OzgcloudDialogService>; beforeEach(async () => { + service = mock(ForwardingService); organisationsEinheitService = mock(OrganisationsEinheitService); + dialogService = mock(OzgcloudDialogService); await TestBed.configureTestingModule({ imports: [ForwardingDialogContainerComponent, AsyncPipe], declarations: [MockComponent(ForwardingDialogComponent)], + providers: [ + { + provide: ForwardingService, + useValue: service, + }, + { + provide: OzgcloudDialogService, + useValue: dialogService, + }, + ], }) .overrideComponent(ForwardingDialogContainerComponent, { set: { @@ -40,4 +65,45 @@ describe('ForwardingDialogContainerComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('forward button', () => { + const targetUri: ResourceUri = faker.internet.url(); + + it('should call forward on click', () => { + component.forward = jest.fn(); + + triggerEvent({ fixture, elementSelector: forwardingDialog, name: 'forward', data: targetUri }); + + expect(component.forward).toHaveBeenCalledWith(targetUri); + }); + }); + + describe('forward', () => { + const targetUri: ResourceUri = faker.internet.url(); + + const commandStateResource: StateResource<CommandResource> = createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE]); + + beforeEach(() => { + service.forward.mockReturnValue(of(commandStateResource)); + }); + + it('should call service with uri', () => { + component.forward(targetUri); + + expect(service.forward).toHaveBeenCalledWith(targetUri); + }); + + it('should set service response', () => { + component.forward(targetUri); + + expect(component.forwardCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + + it('should call dialog service to close all if command is done', () => { + component.forward(targetUri); + component.forwardCommandStateResource$.subscribe(); + + expect(dialogService.closeAll).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts index afb2a3d5a97213615dcc22a98195e82fd916ed50..726320a3498c9e9b3ede988f28d84feee3cbcc24 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts @@ -1,4 +1,7 @@ -import { ResourceRepository } from '@alfa-client/tech-shared'; +import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; +import { ForwardingService } from '@alfa-client/forwarding-shared'; +import { createEmptyStateResource, ResourceRepository, StateResource } from '@alfa-client/tech-shared'; +import { OzgcloudDialogService } from '@alfa-client/ui'; import { VorgangService } from '@alfa-client/vorgang-shared'; import { createOrganisationEinheitService } from '@alfa-client/zustaendige-stelle'; import { @@ -6,15 +9,16 @@ import { OrganisationsEinheitService, ZUSTAENDIGE_STELLE_SERVICE, } from '@alfa-client/zustaendige-stelle-shared'; -import { AsyncPipe } from '@angular/common'; +import { AsyncPipe, CommonModule } from '@angular/common'; import { Component, inject, OnInit } from '@angular/core'; -import { Observable } from 'rxjs'; +import { ResourceUri } from '@ngxp/rest'; +import { Observable, of } from 'rxjs'; import { ForwardingDialogComponent } from './forwarding-dialog/forwarding-dialog.component'; @Component({ selector: 'alfa-forwarding-dialog-container', standalone: true, - imports: [ForwardingDialogComponent, AsyncPipe], + imports: [ForwardingDialogComponent, AsyncPipe, CommonModule], templateUrl: './forwarding-dialog-container.component.html', providers: [ { @@ -26,10 +30,22 @@ import { ForwardingDialogComponent } from './forwarding-dialog/forwarding-dialog }) export class ForwardingDialogContainerComponent implements OnInit { private readonly organisationsEinheitService = inject(ZUSTAENDIGE_STELLE_SERVICE) as OrganisationsEinheitService; + private readonly forwardingService = inject(ForwardingService); + private readonly dialogService = inject(OzgcloudDialogService); public selectedSearchResult$: Observable<OrganisationsEinheitResource>; + public forwardCommandStateResource$: Observable<StateResource<CommandResource>> = + of(createEmptyStateResource<CommandResource>()); ngOnInit(): void { this.selectedSearchResult$ = this.organisationsEinheitService.getSelectedResult(); } + + public forward(targetUri: ResourceUri): void { + this.forwardCommandStateResource$ = this.forwardingService.forward(targetUri).pipe( + tapOnCommandSuccessfullyDone(() => { + this.dialogService.closeAll(); + }), + ); + } } diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html index 495c9518c7dcf25b3d222ee59cf774e01cc04a5a..731af238fd4decf585699b9a964017fe9f028a88 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html @@ -1,9 +1,12 @@ <ods-button-with-spinner + [stateResource]="stateResource" [disabled]="disabled" - text="Jetzt weiterleiten" [tooltip]="tooltip" + (clickEmitter)="clickEmitter.emit()" + text="Jetzt weiterleiten" tooltipPosition="above" dataTestId="forwarding-dialog-button" + data-test-id="forwarding-button-container" > <ods-forward-vorgang-icon icon class="fill-whitetext" /> </ods-button-with-spinner> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts index 9a3db6373c7684f12cddad89ba28689a306b1ee5..0b9cd364d11a620b543e98204b4449c500669605 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts @@ -1,7 +1,8 @@ +import { dispatchEventFromFixture, MockEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; - import { ButtonWithSpinnerComponent } from '@ods/component'; import { ForwardVorgangIconComponent } from '@ods/system'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; import { ForwardingButtonComponent } from './forwarding-button.component'; @@ -9,6 +10,8 @@ describe('ForwardingButtonComponent', () => { let component: ForwardingButtonComponent; let fixture: ComponentFixture<ForwardingButtonComponent>; + const button: string = getDataTestIdOf('forwarding-button-container'); + beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ForwardingButtonComponent], @@ -39,4 +42,16 @@ describe('ForwardingButtonComponent', () => { }); }); }); + + describe('template', () => { + describe('on button click', () => { + it('should emit', () => { + component.clickEmitter.emit = jest.fn(); + + dispatchEventFromFixture(fixture, button, MockEvent.CLICK); + + expect(component.clickEmitter.emit).toHaveBeenCalled(); + }); + }); + }); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts index 05e20b8b4d98e7c1b1988a5920c2d8d446a621de..3e0cb495d9c1e5af0b41e48876584a6be9c2ff55 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts @@ -1,4 +1,6 @@ -import { Component, Input } from '@angular/core'; +import { CommandResource } from '@alfa-client/command-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ButtonWithSpinnerComponent } from '@ods/component'; import { ForwardVorgangIconComponent, TooltipDirective } from '@ods/system'; @@ -13,6 +15,9 @@ export class ForwardingButtonComponent { this._disabled = value; this.tooltip = value ? 'Bitte ein Amt oder Stelle auswählen' : ''; } + @Input() stateResource: StateResource<CommandResource>; + + @Output() clickEmitter: EventEmitter<void> = new EventEmitter(); public tooltip: string; private _disabled: boolean; diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html index 524484a46440eaca0ee48c72473e1878cb7d05ab..7811a8e2d1683829746b372210bbba4f91fca440 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html @@ -13,7 +13,12 @@ </div> <div class="flex gap-4"> - <alfa-forwarding-button [disabled]="!selectedSearchResult" /> + <alfa-forwarding-button + [stateResource]="forwardCommandStateResource" + [disabled]="!selectedSearchResult" + (clickEmitter)="onForwarding()" + data-test-id="foward-dialog-forward-button" + /> <ods-cancel-dialog-button /> </div> </div> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts index 42aa015eeeab4f68a8eee06636128ecbc05a5674..cc001a9f05bbd8f28c5427187c6b990e7bf7bbf5 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts @@ -1,6 +1,13 @@ -import { existsAsHtmlElement, getMockComponent, notExistsAsHtmlElement } from '@alfa-client/test-utils'; +import { + dispatchEventFromFixture, + existsAsHtmlElement, + getMockComponent, + MockEvent, + notExistsAsHtmlElement, +} from '@alfa-client/test-utils'; import { OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { getUrl } from '@ngxp/rest'; import { CancelDialogButtonComponent } from '@ods/component'; import { MockComponent } from 'ng-mocks'; import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; @@ -16,6 +23,7 @@ describe('ForwardingDialogComponent', () => { const organisationsEinheitSearch: string = getDataTestIdOf('organisations-einheit-search'); const searchItemSelected: string = getDataTestIdOf('search-item-selected'); + const forwardButton: string = getDataTestIdOf('foward-dialog-forward-button'); const organisationsEinheitResource: OrganisationsEinheitResource = createOrganisationsEinheitResource(); @@ -65,23 +73,21 @@ describe('ForwardingDialogComponent', () => { fixture.detectChanges(); }); - describe('template', () => { - describe('forwarding item', () => { - it('should render if selectedSearchResult is NOT null', () => { - component.selectedSearchResult = organisationsEinheitResource; + describe('forwarding item', () => { + it('should render if selectedSearchResult is NOT null', () => { + component.selectedSearchResult = organisationsEinheitResource; - fixture.detectChanges(); + fixture.detectChanges(); - existsAsHtmlElement(fixture, searchItemSelected); - }); + existsAsHtmlElement(fixture, searchItemSelected); + }); - it('should NOT render if selectedSearchResult is null', () => { - component.selectedSearchResult = null; + it('should NOT render if selectedSearchResult is null', () => { + component.selectedSearchResult = null; - fixture.detectChanges(); + fixture.detectChanges(); - notExistsAsHtmlElement(fixture, searchItemSelected); - }); + notExistsAsHtmlElement(fixture, searchItemSelected); }); }); @@ -104,4 +110,15 @@ describe('ForwardingDialogComponent', () => { expect(forwardingButton.disabled).toBeFalsy(); }); }); + + describe('forward button', () => { + it('should emit on click', () => { + component.selectedSearchResult = organisationsEinheitResource; + component.forward.emit = jest.fn(); + + dispatchEventFromFixture(fixture, forwardButton, MockEvent.CLICK); + + expect(component.forward.emit).toHaveBeenCalledWith(getUrl(organisationsEinheitResource)); + }); + }); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts index 2350186c3531b19ee69e6f5ec8f341dc4758d9d8..58ab3e2f5429a1bef251ae99fd816e5503bf6983 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts @@ -1,8 +1,11 @@ +import { CommandResource } from '@alfa-client/command-shared'; +import { StateResource } from '@alfa-client/tech-shared'; import { ZustaendigeStelleModule } from '@alfa-client/zustaendige-stelle'; import { OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; import { A11yModule } from '@angular/cdk/a11y'; -import { Component, Input } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; +import { getUrl, ResourceUri } from '@ngxp/rest'; import { CancelDialogButtonComponent } from '@ods/component'; import { DialogContainerComponent } from '@ods/system'; import { ForwardingButtonComponent } from './forwarding-button/forwarding-button.component'; @@ -26,4 +29,11 @@ import { ForwardingSearchOrganisationsEinheitComponent } from './search-organisa }) export class ForwardingDialogComponent { @Input() selectedSearchResult: OrganisationsEinheitResource; + @Input() forwardCommandStateResource: StateResource<CommandResource>; + + @Output() forward: EventEmitter<ResourceUri> = new EventEmitter(); + + public onForwarding(): void { + this.forward.emit(getUrl(this.selectedSearchResult)); + } } diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts index 0aa3ead988609bc5416e593f13cfdf6e44bd8a6e..5e9995262ed38703521d02d10ee078a330163cbd 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts @@ -23,27 +23,33 @@ */ import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared'; import { BinaryFileListResource } from '@alfa-client/binary-file-shared'; -import { CommandOrder, CommandResource, CommandService, CreateCommandProps } from '@alfa-client/command-shared'; +import { + CommandOrder, + CommandResource, + CommandService, + CreateCommandProps, + CreateCommandPropsWithoutResource, +} from '@alfa-client/command-shared'; import { Environment } from '@alfa-client/environment-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { EMPTY_STRING, StateResource, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { HttpErrorResponse } from '@angular/common/http'; +import { faker } from '@faker-js/faker'; import { ResourceUri, getUrl } from '@ngxp/rest'; import { cold, hot } from 'jest-marbles'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { createBinaryFileListResource } from 'libs/binary-file-shared/test/binary-file'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { createCommandResource } from 'libs/command-shared/test/command'; +import { createCommandResource, createCreateCommandPropsWithoutResource } from 'libs/command-shared/test/command'; +import { singleColdCompleted } from 'libs/tech-shared/test/marbles'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { Observable, of } from 'rxjs'; import { VorgangFacade } from './+state/vorgang.facade'; import { VorgangWithEingangLinkRel } from './vorgang.linkrel'; -import { AdditionalActions, VorgangWithEingangResource } from './vorgang.model'; +import { AdditionalActions, VorgangResource, VorgangWithEingangResource } from './vorgang.model'; import { VorgangService } from './vorgang.service'; -import { faker } from '@faker-js/faker'; - import * as VorgangNavigationUtil from './vorgang-navigation.util'; describe('VorgangService', () => { @@ -515,4 +521,64 @@ describe('VorgangService', () => { }); }); }); + + describe('select vorgang with eingang', () => { + const vorgangStateResource: StateResource<VorgangResource> = createStateResource(createVorgangWithEingangResource()); + + beforeEach(() => { + facade.getVorgangWithEingang.mockReturnValue(of(vorgangStateResource)); + }); + + it('should call facade to get vorgang with eingang', () => { + service.selectVorgangWithEingang(); + + expect(facade.getVorgangWithEingang).toHaveBeenCalled(); + }); + + it('should return value', () => { + const vorgangWithEingangStateResource$: Observable<StateResource<VorgangWithEingangResource>> = + service.selectVorgangWithEingang(); + + expect(vorgangWithEingangStateResource$).toBeObservable(singleColdCompleted(vorgangStateResource)); + }); + }); + + describe('create command', () => { + const vorgangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); + + const createCommandProps: CreateCommandPropsWithoutResource = createCreateCommandPropsWithoutResource(); + const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); + + beforeEach(() => { + facade.getVorgangWithEingang.mockReturnValue(of(createStateResource(vorgangResource))); + commandService.createCommandByProps.mockReturnValue(of(commandStateResource)); + }); + + it('should call facade to get vorgang with eingang', () => { + service.createCommand(createCommandProps).subscribe(); + + expect(facade.getVorgangWithEingang).toHaveBeenCalled(); + }); + + it('should call command service to create command', () => { + service.createCommand(createCommandProps).subscribe(); + + expect(commandService.createCommandByProps).toHaveBeenCalledWith({ ...createCommandProps, resource: vorgangResource }); + }); + + it('should return response from command service', () => { + const forwardCommand$: Observable<StateResource<CommandResource>> = service.createCommand(createCommandProps); + + expect(forwardCommand$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + + it('should call reload if command is done and reload flag is true', () => { + service.reloadVorgang = jest.fn(); + + service.createCommand(createCommandProps, true).subscribe(); + + expect(service.reloadVorgang).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts index 1af6e12ff7877e9e221d05730199423689663082..7e43262e9757d58e030c4bbe2900aae791255e96 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts @@ -28,15 +28,17 @@ import { CommandResource, CommandService, CreateCommandProps, + CreateCommandPropsWithoutResource, getEffectedResourceUrl, + tapOnCommandSuccessfullyDone, } from '@alfa-client/command-shared'; import { ENVIRONMENT_CONFIG, Environment } from '@alfa-client/environment-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { StateResource, createEmptyStateResource, doIfLoadingRequired, isNotNull } from '@alfa-client/tech-shared'; +import { StateResource, createEmptyStateResource, doIfLoadingRequired, isNotNull, mapToResource } from '@alfa-client/tech-shared'; import { Inject, Injectable } from '@angular/core'; import { ResourceUri, hasLink } from '@ngxp/rest'; import { Observable, combineLatest } from 'rxjs'; -import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators'; +import { filter, first, map, startWith, switchMap, tap, withLatestFrom } from 'rxjs/operators'; import { VorgangFacade } from './+state/vorgang.facade'; import { buildLinkRelFromPathSegments } from './vorgang-navigation.util'; import { VorgangWithEingangLinkRel } from './vorgang.linkrel'; @@ -142,10 +144,6 @@ export class VorgangService { return this.facade.getAssignUserCommand(); } - public reloadVorgang(commandResource: CommandResource): void { - this.facade.loadVorgangWithEingang(getEffectedResourceUrl(commandResource)); - } - public getBackButtonUrl(): Observable<string> { return this.facade.getBackButtonUrl(); } @@ -198,4 +196,28 @@ export class VorgangService { const createCommand = { order: CommandOrder.SET_AKTENZEICHEN, body: { aktenzeichen } }; return this.commandService.createCommand(vorgang, VorgangWithEingangLinkRel.SET_AKTENZEICHEN, createCommand); } + + public createCommand( + createCommandProps: CreateCommandPropsWithoutResource, + reloadResource: boolean = false, + ): Observable<StateResource<CommandResource>> { + return this.selectVorgangWithEingang().pipe( + first(), + mapToResource(), + switchMap((vorgang: VorgangWithEingangResource) => + this.commandService.createCommandByProps({ ...createCommandProps, resource: vorgang }), + ), + tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => { + if (reloadResource) this.reloadVorgang(commandStateResource.resource); + }), + ); + } + + public selectVorgangWithEingang(): Observable<StateResource<VorgangWithEingangResource>> { + return this.facade.getVorgangWithEingang(); + } + + public reloadVorgang(commandResource: CommandResource): void { + this.facade.loadVorgangWithEingang(getEffectedResourceUrl(commandResource)); + } }