diff --git a/alfa-client/libs/bescheid-shared/src/index.ts b/alfa-client/libs/bescheid-shared/src/index.ts index b7d1c9fcf88976d7bc3e4ad9edee0b49efa83262..62572912c6441e5274ad2ae08bce0651ecb1d77d 100644 --- a/alfa-client/libs/bescheid-shared/src/index.ts +++ b/alfa-client/libs/bescheid-shared/src/index.ts @@ -1,2 +1,3 @@ export * from './lib/bescheid-shared.module'; export * from './lib/bescheid.model'; +export * from './lib/bescheid.service'; diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts index edc0f3cf13e936863b5dc18fbfef37e212b7c2e3..c71a5ec087fcf8c07fbb485040890d7dacc8541d 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts @@ -4,11 +4,10 @@ import { StateResource } from '@alfa-client/tech-shared'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; - import * as CommandActions from '../../../../command-shared/src/lib/+state/command.actions'; import * as BescheidSelectors from './bescheid.selectors'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class BescheidFacade { constructor(private store: Store) {} diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts index 7492a3e30f63e7186000b6212f077a12ca26d8eb..c7dc8db99cd709ae5909a5b10db662801357276e 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts @@ -1,7 +1,7 @@ import { Resource } from '@ngxp/rest'; export interface Bescheid { - beschiedenAm: Date; + beschiedenAm: string; bewilligt: boolean; bescheidDocument?: string; attachments?: string[]; diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts index ea19e6c47512fd63d6cf026db0398c3cee7516ed..30e7f2bbd5ef6d0e92736bb6cf3d567d48d5caaa 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts @@ -1,19 +1,33 @@ import { mock, Mock, useFromMock } from '@alfa-client/test-utils'; -import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { BescheidFacade } from './+state/bescheid.facade'; import { BescheidService } from './bescheid.service'; import { buildCreateBescheidCommand } from './bescheid.util'; +import { Observable, of } from 'rxjs'; +import { createStateResource, StateResource } from '@alfa-client/tech-shared'; +import { ResourceRepository } from '../../../tech-shared/src/lib/resource/resource.repository'; describe('BescheidService', () => { + let service: BescheidService; + let facade: Mock<BescheidFacade>; + let vorgangService: Mock<VorgangService>; + let resourceRepository: Mock<ResourceRepository>; - let service: BescheidService; + const vorgangWithEingangStateResource$: Observable<StateResource<VorgangWithEingangResource>> = + of(createStateResource(createVorgangWithEingangResource())); beforeEach(() => { facade = mock(BescheidFacade); - - service = new BescheidService(useFromMock(facade)); + vorgangService = mock(VorgangService); + resourceRepository = mock(ResourceRepository); + vorgangService.getVorgangWithEingang.mockReturnValue(vorgangWithEingangStateResource$); + service = new BescheidService( + useFromMock(facade), + useFromMock(vorgangService), + useFromMock(resourceRepository), + ); }); it('should be created', () => { diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts index 331a0a49aecc555fee5b7995a4d2c0970582433d..369b6498990536510e3d806a4a2c39ae53992a8e 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts @@ -1,20 +1,60 @@ -import { Injectable } from '@angular/core'; import { CommandResource } from '@alfa-client/command-shared'; -import { StateResource } from '@alfa-client/tech-shared'; -import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { Observable } from 'rxjs'; +import { createStateResource, StateResource } from '@alfa-client/tech-shared'; +import { + VorgangService, + VorgangWithEingangLinkRel, + VorgangWithEingangResource, +} from '@alfa-client/vorgang-shared'; +import { Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { ResourceServiceConfig } from '../../../tech-shared/src/lib/resource/resource.model'; +import { ResourceRepository } from '../../../tech-shared/src/lib/resource/resource.repository'; +import { ResourceService } from '../../../tech-shared/src/lib/resource/resource.service'; import { BescheidFacade } from './+state/bescheid.facade'; +import { Bescheid, BescheidResource } from './bescheid.model'; import { buildCreateBescheidCommand } from './bescheid.util'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class BescheidService { - constructor(private facade: BescheidFacade) {} + resourceService: ResourceService<VorgangWithEingangResource, BescheidResource>; + + constructor( + private readonly facade: BescheidFacade, + private readonly vorgangService: VorgangService, + repository: ResourceRepository, + ) { + this.resourceService = new ResourceService(this.buildConfig(), repository); + } + buildConfig(): ResourceServiceConfig<VorgangWithEingangResource> { + return { + resource: this.vorgangService.getVorgangWithEingang(), + getLinkRel: VorgangWithEingangLinkRel.BESCHEID_DRAFT, + deleteLinkRel: null, + editLinkRel: null, + }; + } + + public getBescheidDraft(): Observable<StateResource<BescheidResource>> { + // temporary dummy resource + return of( + createStateResource<BescheidResource>({ + beschiedenAm: '2024-03-01', + bewilligt: true, + _links: { + self: { + href: '', + }, + }, + }), + ); + // return this.resourceService.get(); + } public getBescheidCommand(): Observable<StateResource<CommandResource>> { return this.facade.getBescheidCommand(); } - public createBescheid(vorgangWithEingang: VorgangWithEingangResource): void { - this.facade.createBescheid(vorgangWithEingang, buildCreateBescheidCommand()); + public createBescheid(vorgangWithEingang: VorgangWithEingangResource, bescheid?: Bescheid): void { + this.facade.createBescheid(vorgangWithEingang, buildCreateBescheidCommand(bescheid)); } } diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.spec.ts index 2b8a30c80b4869f5206b806254272b0c0bbb4617..5b068611fcafe6a17dfbbcd93ce1472c044ed717 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.spec.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.spec.ts @@ -1,5 +1,6 @@ import { CommandOrder, CreateCommand } from '@alfa-client/command-shared'; import { buildCreateBescheidCommand, isCreateBescheidCommand } from './bescheid.util'; +import { createBescheid } from '../test/bescheid'; describe('BescheidUtil', () => { describe('buildCreateBescheidCommand', () => { @@ -9,10 +10,18 @@ describe('BescheidUtil', () => { expect(command.order).toEqual(CommandOrder.CREATE_BESCHEID); }); - it('should have body', () => { + it('should not have body', () => { const command: CreateCommand = buildCreateBescheidCommand(); - expect(command.body).toBeNull(); + expect(command.body).toBeUndefined(); + }); + + it('should have body', () => { + const bescheid = createBescheid(); + + const command = buildCreateBescheidCommand(bescheid); + + expect(command.body).toEqual(bescheid); }); }); diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.ts index ffc13a4bec310ad87a9ecf0d706bdc740eeef6cc..16e3c6fb03d54ed5e795dca40aecb632148f981f 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.util.ts @@ -1,7 +1,8 @@ import { CommandOrder, CreateCommand } from '@alfa-client/command-shared'; +import { Bescheid } from './bescheid.model'; -export function buildCreateBescheidCommand(): CreateCommand { - return { order: CommandOrder.CREATE_BESCHEID, body: null }; +export function buildCreateBescheidCommand(bescheid?: Bescheid): CreateCommand { + return { order: CommandOrder.CREATE_BESCHEID, body: bescheid }; } export function isCreateBescheidCommand(order: CommandOrder): boolean { diff --git a/alfa-client/libs/bescheid-shared/src/test/bescheid.ts b/alfa-client/libs/bescheid-shared/src/test/bescheid.ts new file mode 100644 index 0000000000000000000000000000000000000000..447ce7902940277d309e84481a368f0d3ff9892a --- /dev/null +++ b/alfa-client/libs/bescheid-shared/src/test/bescheid.ts @@ -0,0 +1,13 @@ +import { Bescheid, BescheidResource } from '../lib/bescheid.model'; +import { toResource } from 'libs/tech-shared/test/resource'; + +export function createBescheid(): Bescheid { + return { + beschiedenAm: '2024-01-01', + bewilligt: true, + }; +} + +export function createBescheidResource(linkRel: string[] = []): BescheidResource { + return toResource(createBescheid(), linkRel); +} diff --git a/alfa-client/libs/tech-shared/src/lib/validation/tech.validation.messages.ts b/alfa-client/libs/tech-shared/src/lib/validation/tech.validation.messages.ts index 50986629811aef92ed9344ead719d4fee8d05bc7..025f01d8c6c474fda2e293c18c28fa772651b835 100644 --- a/alfa-client/libs/tech-shared/src/lib/validation/tech.validation.messages.ts +++ b/alfa-client/libs/tech-shared/src/lib/validation/tech.validation.messages.ts @@ -37,4 +37,5 @@ export const VALIDATION_MESSAGES: { [code: string]: string } = { 'Anhänge größer {max}{unit} können nicht hinzugefügt werden.', fe_only_validation_bearbeiter_not_exist: 'Der Bearbeiter existiert nicht', + validation_field_date_format_invalid: 'Geben Sie ein gültiges Datum ein', }; diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts index baf0555a24ce712c0468c1b92f8a1823ad05fef7..e7c4b6524db9932fd85899a95f299bdc788b7486 100644 --- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts +++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts @@ -1,17 +1,16 @@ import { TestBed } from '@angular/core/testing'; -import { Dialog } from '@angular/cdk/dialog'; +import { Dialog, DialogConfig } from '@angular/cdk/dialog'; import { OzgcloudDialogService } from './ozgcloud-dialog.service'; +import { mock } from '@alfa-client/test-utils'; describe('OzgcloudDialogService', () => { let service: OzgcloudDialogService; const component = <any>{ name: 'Component' }; - const dialog = { - open: jest.fn(), - getDialogById: jest.fn(), - closeAll: jest.fn(), - }; + const dialog = mock(Dialog); + const dialogData = { id: 'ZumBeispiel' }; + const dialogConfigWithData: DialogConfig = { data: dialogData }; beforeEach(() => { TestBed.configureTestingModule({ @@ -30,24 +29,42 @@ describe('OzgcloudDialogService', () => { }); describe('open', () => { - const config = <any>{ id: 'ZumBeispiel' }; + beforeEach(() => { + dialog.open.mockReset(); + }); + + it('should open dialog with data', () => { + service.open(component, dialogData); + + expect(dialog.open).toHaveBeenCalledWith(component, dialogConfigWithData); + }); - it('should call dialog open with config', () => { - service.open(component, config); + it('should open dialog wihtout data', () => { + service.open(component); - expect(dialog.open).toHaveBeenCalledWith(component, config); + expect(dialog.open).toHaveBeenCalledWith(component, undefined); }); }); - describe('openWidely', () => { - const config = <any>{ id: 'ZumBeispiel' }; + describe('openWizard', () => { + beforeEach(() => { + dialog.open.mockReset(); + }); + + it('should open wizard dialog', () => { + service.openWizard(component); + + expect(dialog.open).toHaveBeenCalledWith(component, { + ...service.WIZARD_DIALOG_CONFIG, + }); + }); - it('should call dialog open with conifg', () => { - service.openWizard(component, config); + it('should open wizard dialog with data', () => { + service.openWizard(component, dialogData); expect(dialog.open).toHaveBeenCalledWith(component, { - ...config, ...service.WIZARD_DIALOG_CONFIG, + data: dialogData, }); }); }); diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts index b8e0739b089d77ae575104790131cd4cb83c2f60..449aae405b44aa5f59152749e4e40c4e00798cfd 100644 --- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts +++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts @@ -1,6 +1,7 @@ import { Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog'; import { ComponentType } from '@angular/cdk/portal'; import { Injectable } from '@angular/core'; +import { isNil } from 'lodash-es'; @Injectable({ providedIn: 'root', @@ -13,11 +14,25 @@ export class OzgcloudDialogService { constructor(private dialog: Dialog) {} - public openWizard<T>(component: ComponentType<T>, config?: DialogConfig): DialogRef<T> { - return this.open<T>(component, { ...config, ...this.WIZARD_DIALOG_CONFIG }); + public openWizard<T, D>(component: ComponentType<T>, data?: D): DialogRef<T> { + return this.openDialog<T>( + component, + this.buildDialogConfigWithData<D>(data, this.WIZARD_DIALOG_CONFIG), + ); } - public open<T>(component: ComponentType<T>, config?: DialogConfig): DialogRef<T> { - return this.dialog.open<T>(component, config); + public open<T, D>(component: ComponentType<T>, data?: D): DialogRef<T> { + return this.openDialog(component, this.buildDialogConfigWithData(data)); + } + + private buildDialogConfigWithData<D>(data: D, dialogConfig?: DialogConfig): DialogConfig | null { + if (isNil(data)) { + return dialogConfig; + } + return { ...dialogConfig, data }; + } + + private openDialog<T>(component: ComponentType<T>, dialogConfig?: DialogConfig): DialogRef<T> { + return this.dialog.open<T>(component, dialogConfig); } } diff --git a/alfa-client/libs/vorgang-detail/src/index.ts b/alfa-client/libs/vorgang-detail/src/index.ts index f381ab63753fc51eeac42b8f5f6e6d2f682b0682..6a919f5d6ee3ecd0c55513cd54e302d2b2669352 100644 --- a/alfa-client/libs/vorgang-detail/src/index.ts +++ b/alfa-client/libs/vorgang-detail/src/index.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -export * from './lib/aktenzeichen-editable/aktenzeichen-editable.component'; export * from './lib/aktenzeichen-edit-dialog/aktenzeichen-edit-dialog.component'; +export * from './lib/aktenzeichen-editable/aktenzeichen-editable.component'; +export * from './lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model'; export * from './lib/vorgang-detail.module'; diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html index 629a451eacc28bba3ccdc1bc669f717e65277998..4f08165701d0eaf85317419d63d49443c8a412b5 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html @@ -30,7 +30,7 @@ text="Bescheiden" svgIcon="stamp" [stateResource]="commandStateResource$ | async" - (clickEmitter)="bescheiden()" + (clickEmitter)="onClick()" > </ozgcloud-stroked-button-with-spinner> @@ -40,7 +40,7 @@ svgIcon="stamp" toolTip="Vorgang bescheiden" [stateResource]="commandStateResource$ | async" - (clickEmitter)="bescheiden()" + (clickEmitter)="onClick()" > </ozgcloud-icon-button-with-spinner> </ng-container> diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts index 14fd04f1757c9d96bc80c877f6ed2f4d07365372..a60d700113e084589268d8cdc65e485646bdf1b1 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts @@ -21,7 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { HasLinkPipe } from '@alfa-client/tech-shared'; +import { BescheidService } from '@alfa-client/bescheid-shared'; +import { + createEmptyStateResource, + createStateResource, + HasLinkPipe, +} from '@alfa-client/tech-shared'; import { mock } from '@alfa-client/test-utils'; import { IconButtonWithSpinnerComponent, @@ -29,10 +34,14 @@ import { OzgcloudStrokedButtonWithSpinnerComponent, } from '@alfa-client/ui'; import { VorgangCommandService, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; +import { DialogRef } from '@angular/cdk/dialog'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; +import { createBescheidResource } from '../../../../../bescheid-shared/src/test/bescheid'; +import { VorgangDetailBescheidenComponent } from '../../vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component'; import { BescheidenButtonComponent } from './bescheiden-button.component'; describe('BescheidenButtonComponent', () => { @@ -44,6 +53,9 @@ describe('BescheidenButtonComponent', () => { const vorgangCommandService = mock(VorgangCommandService); const ozgcloudDialogService = mock(OzgcloudDialogService); + const bescheidService = mock(BescheidService); + + const dialogRef = <DialogRef<VorgangDetailBescheidenComponent>>{}; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -62,13 +74,16 @@ describe('BescheidenButtonComponent', () => { provide: OzgcloudDialogService, useValue: ozgcloudDialogService, }, + { + provide: BescheidService, + useValue: bescheidService, + }, ], - }); - }); + }).compileComponents(); - beforeEach(() => { fixture = TestBed.createComponent(BescheidenButtonComponent); component = fixture.componentInstance; + ozgcloudDialogService.openWizard = jest.fn().mockReturnValue(dialogRef); fixture.detectChanges(); }); @@ -84,48 +99,53 @@ describe('BescheidenButtonComponent', () => { }); }); - describe('bescheiden', () => { + describe('bescheiden button', () => { beforeEach(() => { - component.openBescheidenWizard = jest.fn(); - vorgangCommandService.bescheiden.mockClear(); + component.showAsIconButton = false; + fixture.detectChanges(); }); - it('should call bescheiden', () => { - component.bescheiden(); + it('should be hidden', () => { + component.vorgang = createVorgangWithEingangResource(); - expect(vorgangCommandService.bescheiden).toHaveBeenCalled(); + fixture.detectChanges(); + const buttonElement = fixture.nativeElement.querySelector(bescheidenButton); + + expect(buttonElement).not.toBeInstanceOf(HTMLElement); }); - it('should not open wizard', () => { - component.bescheiden(); + it('should be visible', () => { + component.vorgang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEIDEN]); + + fixture.detectChanges(); + const buttonElement = fixture.nativeElement.querySelector(bescheidenButton); - expect(component.openBescheidenWizard).not.toHaveBeenCalled(); + expect(buttonElement).toBeInstanceOf(HTMLElement); }); + }); - it('should open bescheid wizard', () => { + describe('onClick', () => { + it('should call openBescheidenWizard', () => { + const openBescheidenWizard = (component.openBescheidenWizard = jest.fn()); component.vorgang = createVorgangWithEingangResource([ VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT, ]); - component.bescheiden(); + component.onClick(); - expect(component.openBescheidenWizard).toHaveBeenCalled(); + expect(openBescheidenWizard).toHaveBeenCalled(); }); - it('should not call bescheiden', () => { - component.vorgang = createVorgangWithEingangResource([ - VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT, - ]); - - component.bescheiden(); + it('should call vorgangCommandService.bescheiden', () => { + component.onClick(); - expect(vorgangCommandService.bescheiden).not.toHaveBeenCalled(); + expect(vorgangCommandService.bescheiden).toHaveBeenCalled(); }); }); - describe('bescheiden button', () => { + describe('bescheiden icon button', () => { beforeEach(() => { - component.showAsIconButton = false; + component.showAsIconButton = true; fixture.detectChanges(); }); @@ -133,7 +153,7 @@ describe('BescheidenButtonComponent', () => { component.vorgang = createVorgangWithEingangResource(); fixture.detectChanges(); - const buttonElement = fixture.nativeElement.querySelector(bescheidenButton); + const buttonElement = fixture.nativeElement.querySelector(bescheidenIconButton); expect(buttonElement).not.toBeInstanceOf(HTMLElement); }); @@ -142,42 +162,80 @@ describe('BescheidenButtonComponent', () => { component.vorgang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEIDEN]); fixture.detectChanges(); - const buttonElement = fixture.nativeElement.querySelector(bescheidenButton); + const buttonElement = fixture.nativeElement.querySelector(bescheidenIconButton); expect(buttonElement).toBeInstanceOf(HTMLElement); }); }); - describe('bescheiden wizard', () => { - it('should open bescheiden wizard', () => { + describe('openBescheidenWizard', () => { + it('should open bescheiden dialog with existing draft', () => { + component.vorgang = createVorgangWithEingangResource([ + VorgangWithEingangLinkRel.BESCHEID_DRAFT, + ]); + const openBescheidenDialogWithExistingDraft = + (component.openBescheidenDialogWithExistingDraft = jest.fn()); + + component.openBescheidenWizard(); + + expect(openBescheidenDialogWithExistingDraft).toHaveBeenCalled(); + }); + + it('should open bescheiden dialog with new draft', () => { + component.vorgang = createVorgangWithEingangResource(); + const openBescheidDialogWithNewDraft = (component.openBescheidDialogWithNewDraft = jest.fn()); + + component.openBescheidenWizard(); + + expect(openBescheidDialogWithNewDraft).toHaveBeenCalled(); + }); + }); + + describe('openBescheidDialogWithNewDraft', () => { + it('should open wizard', () => { + component.vorgang = createVorgangWithEingangResource(); + component.openBescheidenWizard(); - expect(ozgcloudDialogService.openWizard).toHaveBeenCalled(); + expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith( + VorgangDetailBescheidenComponent, + { + vorgangWithEingangResource: component.vorgang, + bescheidDraftResource: null, + }, + ); }); }); - describe('bescheiden icon button', () => { + describe('openBescheidenDialogWithExistingDraft', () => { + const bescheidDraftStateResource = createStateResource(createBescheidResource()); + beforeEach(() => { - component.showAsIconButton = true; - fixture.detectChanges(); - }); + component.vorgang = createVorgangWithEingangResource([ + VorgangWithEingangLinkRel.BESCHEID_DRAFT, + ]); - it('should be hidden', () => { - component.vorgang = createVorgangWithEingangResource(); + bescheidService.getBescheidDraft.mockReturnValue(of(bescheidDraftStateResource)); + }); - fixture.detectChanges(); - const buttonElement = fixture.nativeElement.querySelector(bescheidenIconButton); + it('should open wizard if bescheid draft loaded', () => { + component.openBescheidenWizard(); - expect(buttonElement).not.toBeInstanceOf(HTMLElement); + expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith( + VorgangDetailBescheidenComponent, + { + bescheidDraftResource: bescheidDraftStateResource.resource, + vorgangWithEingangResource: component.vorgang, + }, + ); }); - it('should be visible', () => { - component.vorgang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEIDEN]); + it('should not open wizard if bescheid draft not loaded', () => { + bescheidService.getBescheidDraft.mockReturnValue(of(createEmptyStateResource())); - fixture.detectChanges(); - const buttonElement = fixture.nativeElement.querySelector(bescheidenIconButton); + component.openBescheidenWizard(); - expect(buttonElement).toBeInstanceOf(HTMLElement); + expect(ozgcloudDialogService.openWizard).not.toHaveBeenCalled(); }); }); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts index f2976da208cc06319efe040a56ef4caaaa7e49de..e7faa08933b60abb77b0850b9dd0409bc460e746 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts @@ -21,8 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { BescheidService } from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; -import { StateResource, createEmptyStateResource } from '@alfa-client/tech-shared'; +import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared'; import { OzgcloudDialogService } from '@alfa-client/ui'; import { VorgangCommandService, @@ -30,9 +31,10 @@ import { VorgangWithEingangResource, } from '@alfa-client/vorgang-shared'; import { Component, Input, OnInit } from '@angular/core'; -import { Observable, of } from 'rxjs'; -import { VorgangDetailBescheidenComponent } from '../../vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component'; import { hasLink } from '@ngxp/rest'; +import { filter, first, map, Observable, of } from 'rxjs'; +import { BescheidenDialogData } from '../../vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model'; +import { VorgangDetailBescheidenComponent } from '../../vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component'; @Component({ selector: 'alfa-bescheiden-button', @@ -52,21 +54,57 @@ export class BescheidenButtonComponent implements OnInit { constructor( private vorgangCommandService: VorgangCommandService, private ozgcloudDialogService: OzgcloudDialogService, + private bescheidService: BescheidService, ) {} ngOnInit(): void { this.commandStateResource$ = this.vorgangCommandService.getBeschiedenCommand(); } - public openBescheidenWizard(): void { - this.ozgcloudDialogService.openWizard(VorgangDetailBescheidenComponent); - } - - public bescheiden(): void { + public onClick(): void { if (hasLink(this.vorgang, VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT)) { this.openBescheidenWizard(); } else { this.vorgangCommandService.bescheiden(this.vorgang); } } + + public openBescheidenWizard(): void { + if (hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT)) { + this.openBescheidenDialogWithExistingDraft(); + } else { + this.openBescheidDialogWithNewDraft(); + } + } + + openBescheidenDialogWithExistingDraft() { + this.bescheidService + .getBescheidDraft() + .pipe( + filter((stateResource) => stateResource.loaded), + first(), + map((stateResource) => stateResource.resource), + ) + .subscribe((bescheidDraftResource) => { + const dialogData: BescheidenDialogData = { + bescheidDraftResource, + vorgangWithEingangResource: this.vorgang, + }; + this.ozgcloudDialogService.openWizard< + VorgangDetailBescheidenComponent, + BescheidenDialogData + >(VorgangDetailBescheidenComponent, dialogData); + }); + } + + openBescheidDialogWithNewDraft() { + const dialogData: BescheidenDialogData = { + bescheidDraftResource: null, + vorgangWithEingangResource: this.vorgang, + }; + this.ozgcloudDialogService.openWizard<VorgangDetailBescheidenComponent, BescheidenDialogData>( + VorgangDetailBescheidenComponent, + dialogData, + ); + } } diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts index 271a654876f6c97e32d41adba6a65ee36a05fd50..1b5791a219f69124dca4c77093010d54250cf451 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts @@ -1,22 +1,46 @@ -import { BescheidenFormService } from './bescheiden.formservice'; -import { Bescheid } from '@alfa-client/bescheid-shared'; +import { Bescheid, BescheidService } from '@alfa-client/bescheid-shared'; +import { createEmptyStateResource, formatForDatabase } from '@alfa-client/tech-shared'; +import { mock, useFromMock } from '@alfa-client/test-utils'; +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; import { UntypedFormBuilder } from '@angular/forms'; import { cold } from 'jest-marbles'; +import { of } from 'rxjs'; +import { createBescheid } from '../../../../../bescheid-shared/src/test/bescheid'; +import { createVorgangWithEingangResource } from '../../../../../vorgang-shared/test/vorgang'; +import { BescheidenFormService } from './bescheiden.formservice'; + +registerLocaleData(localeDe); describe('BescheidenFormServiceService', () => { let service: BescheidenFormService; + const bescheidService = mock(BescheidService); + const now = new Date(); Date.now = jest.fn().mockReturnValue(now); beforeEach(() => { - service = new BescheidenFormService(new UntypedFormBuilder()); + service = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); + }); + + describe('initializeFormChanges', () => { + it('should emit initial form value', () => { + expect(service.getBescheidChanges()).toBeObservable( + cold('a', { a: { beschiedenAm: now, bewilligt: true } }), + ); + }); }); describe('getValue', () => { - it('should have called getFormValue', () => { - const getFormValue = jest.spyOn(service, 'getFormValue'); + let getFormValue; + beforeEach(() => { + getFormValue = service.getFormValue = jest.fn(); + getFormValue.mockReturnValue({ beschiedenAm: now, bewilligt: 'true' }); + }); + + it('should call getFormValue', () => { service.getValue(); expect(getFormValue).toHaveBeenCalled(); @@ -25,7 +49,7 @@ describe('BescheidenFormServiceService', () => { it('should return bescheid', () => { const value = service.getValue(); - expect(value).toEqual({ bewilligt: true, beschiedenAm: now } as Bescheid); + expect(value).toEqual({ bewilligt: true, beschiedenAm: formatForDatabase(now) } as Bescheid); }); }); @@ -36,4 +60,82 @@ describe('BescheidenFormServiceService', () => { ); }); }); + + describe('patchValues', () => { + const bescheid = createBescheid(); + let patch; + + beforeEach(() => { + patch = service.patch = jest.fn(); + }); + + it('should call patch', () => { + service.patchValues(bescheid); + + expect(patch).toHaveBeenCalledWith({ + [BescheidenFormService.FIELD_BESCHIEDEN_AM]: bescheid.beschiedenAm, + [BescheidenFormService.FIELD_BEWILLIGT]: String(bescheid.bewilligt), + }); + }); + + it('should not call patch', () => { + service.patchValues(null); + + expect(patch).not.toHaveBeenCalled(); + }); + }); + + describe('submit', () => { + let getValue; + const vorgangWithEingangResource = createVorgangWithEingangResource(); + const value = createBescheid(); + const bescheidCommandStateResource = createEmptyStateResource(); + + beforeEach(() => { + getValue = service.getValue = jest.fn(); + getValue.mockReturnValue(value); + bescheidService.getBescheidCommand.mockReturnValue(of(bescheidCommandStateResource)); + service.setVorgangWithEingangResource(vorgangWithEingangResource); + }); + + it('should get value', (done) => { + service.submit().subscribe(() => { + expect(getValue).toHaveBeenCalled(); + done(); + }); + }); + + it('should create bescheid', (done) => { + service.submit().subscribe(() => { + expect(bescheidService.createBescheid).toHaveBeenCalledWith( + vorgangWithEingangResource, + value, + ); + done(); + }); + }); + + it('should get bescheid command', (done) => { + service.submit().subscribe(() => { + expect(bescheidService.getBescheidCommand).toHaveBeenCalledWith(); + done(); + }); + }); + + it('should return bescheid command', () => { + const bescheidCommand$ = service.submit(); + + expect(bescheidCommand$).toBeObservable(cold('(a|)', { a: bescheidCommandStateResource })); + }); + }); + + describe('setVorgangWithEingangResource', () => { + it('should set vorgangWithEingangResource', () => { + const vorgangWithEingangResource = createVorgangWithEingangResource(); + + service.setVorgangWithEingangResource(vorgangWithEingangResource); + + expect(service.vorgangWithEingangResource).toBe(vorgangWithEingangResource); + }); + }); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts index 47e438bcae01967adba5b97b50bd71bd10683ecd..5515fbf8f54812145bd9a6a8e943410338e109cf 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts @@ -1,23 +1,56 @@ -import { Bescheid } from '@alfa-client/bescheid-shared'; -import { AbstractFormService, asBoolean, StateResource } from '@alfa-client/tech-shared'; +import { Bescheid, BescheidService } from '@alfa-client/bescheid-shared'; +import { + AbstractFormService, + StateResource, + asBoolean, + formatForDatabase, +} from '@alfa-client/tech-shared'; +import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Injectable } from '@angular/core'; import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; -import { map, Observable, startWith } from 'rxjs'; +import { isNil } from 'lodash-es'; +import { BehaviorSubject, Observable, map, startWith } from 'rxjs'; -@Injectable({ providedIn: null }) +@Injectable() export class BescheidenFormService extends AbstractFormService { static readonly FIELD_BESCHIEDEN_AM = 'beschiedenAm'; static readonly FIELD_BEWILLIGT = 'bewilligt'; - static readonly FIELD_PATH_PREFIX = 'bescheid'; + static readonly FIELD_PATH_PREFIX = 'command.body'; - private readonly bescheid$: Observable<Bescheid>; + public readonly bescheidChanges$: BehaviorSubject<Bescheid>; - constructor(formBuilder: UntypedFormBuilder) { + vorgangWithEingangResource: VorgangWithEingangResource; + + constructor( + formBuilder: UntypedFormBuilder, + private bescheidService: BescheidService, + ) { super(formBuilder); - this.bescheid$ = this.form.valueChanges.pipe( - startWith(this.getFormValue()), - map((value) => ({ ...value, bewilligt: asBoolean(value.bewilligt) })), - ); + this.bescheidChanges$ = new BehaviorSubject<Bescheid>(this.getFormValue()); + this.initializeFormChanges(); + } + + initializeFormChanges() { + this.form.valueChanges + .pipe( + startWith(this.getFormValue()), + map((value) => ({ + ...value, + bewilligt: asBoolean(value.bewilligt), + })), + ) + .subscribe((bescheid) => this.bescheidChanges$.next(bescheid)); + } + + public patchValues(bescheid: Bescheid): void { + if (isNil(bescheid)) { + return; + } + + this.patch({ + [BescheidenFormService.FIELD_BESCHIEDEN_AM]: bescheid.beschiedenAm, + [BescheidenFormService.FIELD_BEWILLIGT]: String(bescheid.bewilligt), + }); } protected initForm(): UntypedFormGroup { @@ -32,18 +65,25 @@ export class BescheidenFormService extends AbstractFormService { } protected doSubmit(): Observable<StateResource<any>> { - return null; + this.bescheidService.createBescheid(this.vorgangWithEingangResource, this.getValue()); + return this.bescheidService.getBescheidCommand(); } public getValue(): Bescheid { const value = this.getFormValue(); return { - beschiedenAm: value.beschiedenAm, + beschiedenAm: formatForDatabase(value.beschiedenAm), bewilligt: asBoolean(value.bewilligt), }; } public getBescheidChanges(): Observable<Bescheid> { - return this.bescheid$; + return this.bescheidChanges$.asObservable(); + } + + public setVorgangWithEingangResource( + vorgangWithEingangResource: VorgangWithEingangResource, + ): void { + this.vorgangWithEingangResource = vorgangWithEingangResource; } } diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..c44625133f9a8739e215b4d72d33be87fbad044f --- /dev/null +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model.ts @@ -0,0 +1,7 @@ +import { BescheidResource } from '@alfa-client/bescheid-shared'; +import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; + +export interface BescheidenDialogData { + vorgangWithEingangResource: VorgangWithEingangResource; + bescheidDraftResource?: BescheidResource; +} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts index 890bfa0341a342d6c0e38d2826c0bb706e299a15..38d4b55a556221345205af61f2b824fe11d32b7e 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts @@ -1,3 +1,5 @@ +import { BescheidService } from '@alfa-client/bescheid-shared'; +import { mock, useFromMock } from '@alfa-client/test-utils'; import { OzgcloudSvgIconComponent } from '@alfa-client/ui'; import { registerLocaleData } from '@angular/common'; import localeDe from '@angular/common/locales/de'; @@ -15,7 +17,11 @@ describe('VorgangDetailBescheidenResultStatusComponent', () => { let component: VorgangDetailBescheidenResultStatusComponent; let fixture: ComponentFixture<VorgangDetailBescheidenResultStatusComponent>; - const formService = new BescheidenFormService(new UntypedFormBuilder()); + const bescheidService = mock(BescheidService); + const formService = new BescheidenFormService( + new UntypedFormBuilder(), + useFromMock(bescheidService), + ); const bescheidChangesMock = jest.fn(); bescheidChangesMock.mockReturnValue( new BehaviorSubject({ beschiedenAm: new Date(), bewilligt: false }), @@ -30,6 +36,10 @@ describe('VorgangDetailBescheidenResultStatusComponent', () => { provide: BescheidenFormService, useValue: formService, }, + { + provide: BescheidService, + useValue: bescheidService, + }, ], }, }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component.spec.ts index 6cbcd39be5f08e0f6726495acbfa98abd2ec6df3..85510f8c2ccc6297c0bdc3abba6a85a4224cfc23 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component.spec.ts @@ -1,3 +1,5 @@ +import { BescheidService } from '@alfa-client/bescheid-shared'; +import { mock, useFromMock } from '@alfa-client/test-utils'; import { DateEditorComponent } from '@alfa-client/ui'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; @@ -10,7 +12,12 @@ import { VorgangDetailAntragBescheidenStepComponent } from './vorgang-detail-ant describe('VorgangDetailAntragBescheidenStepComponent', () => { let component: VorgangDetailAntragBescheidenStepComponent; let fixture: ComponentFixture<VorgangDetailAntragBescheidenStepComponent>; - const formService = new BescheidenFormService(new UntypedFormBuilder()); + + const bescheidService = mock(BescheidService); + const formService = new BescheidenFormService( + new UntypedFormBuilder(), + useFromMock(bescheidService), + ); beforeEach(async () => { TestBed.overrideComponent(VorgangDetailAntragBescheidenStepComponent, { @@ -20,6 +27,10 @@ describe('VorgangDetailAntragBescheidenStepComponent', () => { provide: BescheidenFormService, useValue: formService, }, + { + provide: BescheidService, + useValue: bescheidService, + }, ], }, }); @@ -29,6 +40,7 @@ describe('VorgangDetailAntragBescheidenStepComponent', () => { MatIcon, MockComponent(RadioButtonCardComponent), MockComponent(DateEditorComponent), + MockComponent(MatIcon), ], imports: [ReactiveFormsModule], }).compileComponents(); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts index f17f3d2a879a9255efe95a6ffa70bb3757a3305e..ce71487fa6d042b8622573fce274a89fb3f20993 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts @@ -4,9 +4,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; import { VorgangDetailBescheidenStepTitleComponent } from '../vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component'; import { VorgangDetailBescheidenWeiterButtonComponent } from '../vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; +import { VorgangDetailAntragBescheidenStepComponent } from './vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component'; import { VorgangDetailBescheidenStepContentComponent } from './vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component'; import { VorgangDetailBescheidenStepsContentComponent } from './vorgang-detail-bescheiden-steps-content.component'; -import { VorgangDetailAntragBescheidenStepComponent } from './vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component'; describe('VorgangDetailBescheidenStepsContentComponent', () => { let component: VorgangDetailBescheidenStepsContentComponent; diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts index c86e8f211d93297ef577efc4434ed5471c3001f2..a70befbc6706c728275b395a3aa6d9dfa7cb3ebd 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts @@ -3,6 +3,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'alfa-vorgang-detail-bescheiden-steps-content', templateUrl: './vorgang-detail-bescheiden-steps-content.component.html', + styles: [':host {@apply flex flex-col}'], }) export class VorgangDetailBescheidenStepsContentComponent { @Input() activeStep: number = 1; diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html index 25259cc196a099d581618338f0b9b326e13a0020..a15fc997aa7ae112b668f05f34f6243cc054986a 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html @@ -1,4 +1,5 @@ <button + (click)="onWeiterClick()" type="button" class="mt-8 rounded-md bg-primary-600 px-8 py-2 text-sm text-white shadow-sm hover:bg-ozgblue-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ozgblue-800" > diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts index b6403babb88e53de1fafa3f4b75e7712dd84bf96..25e5f64656c4658d89c9e7bfc18b464502bdedc3 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts @@ -1,13 +1,24 @@ +import { mock } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BescheidenFormService } from '../../bescheiden.formservice'; import { VorgangDetailBescheidenWeiterButtonComponent } from './vorgang-detail-bescheiden-weiter-button.component'; +import { createEmptyStateResource } from '@alfa-client/tech-shared'; +import { of } from 'rxjs'; describe('VorgangDetailBescheidenWeiterButtonComponent', () => { let component: VorgangDetailBescheidenWeiterButtonComponent; let fixture: ComponentFixture<VorgangDetailBescheidenWeiterButtonComponent>; + const formService = mock(BescheidenFormService); + beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [VorgangDetailBescheidenWeiterButtonComponent], + providers: [ + { + provide: BescheidenFormService, + useValue: formService, + }, + ], }).compileComponents(); fixture = TestBed.createComponent(VorgangDetailBescheidenWeiterButtonComponent); @@ -18,4 +29,15 @@ describe('VorgangDetailBescheidenWeiterButtonComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('onWeiterClick', () => { + it('should submit form', () => { + const submit = (formService.submit = jest.fn()); + submit.mockReturnValue(of(createEmptyStateResource())); + + component.onWeiterClick(); + + expect(submit).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts index 6a793575e20d988e21a7a000ff8778e8da9c6425..e500f6f51538c346a7c09c46568f94479a807f66 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts @@ -1,7 +1,15 @@ import { Component } from '@angular/core'; +import { first } from 'rxjs'; +import { BescheidenFormService } from '../../bescheiden.formservice'; @Component({ selector: 'alfa-vorgang-detail-bescheiden-weiter-button', templateUrl: './vorgang-detail-bescheiden-weiter-button.component.html', }) -export class VorgangDetailBescheidenWeiterButtonComponent {} +export class VorgangDetailBescheidenWeiterButtonComponent { + constructor(public formService: BescheidenFormService) {} + + onWeiterClick() { + this.formService.submit().pipe(first()).subscribe(); + } +} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html index 814e4ca7d5563319965bb52e55b5418b86e177a1..a6ce3a3f1f70d9aced72ee57eacf285b09ac2324 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html @@ -9,7 +9,7 @@ <div class="relative h-full w-full max-w-7xl transform overflow-hidden rounded-lg bg-background-200 px-6 py-10 text-left shadow-xl transition-all" > - <button class="absolute right-3 top-3 text-text" (click)="dialogRef.close()"> + <button (click)="onClose()" class="absolute right-3 top-3 text-text"> <mat-icon>close</mat-icon> </button> <form [formGroup]="formService.form" class="flex h-full flex-row gap-11"> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts index 850dc62890bc10f579a496f8de3ca8d58f29e6c8..a90f0deb26966b8ff3527b381cdb5510e9bfe544 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts @@ -1,18 +1,30 @@ -import { DialogRef } from '@angular/cdk/dialog'; +import { BescheidService } from '@alfa-client/bescheid-shared'; +import { mock, useFromMock } from '@alfa-client/test-utils'; +import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; +import { MatIcon } from '@angular/material/icon'; import { MockComponent } from 'ng-mocks'; +import { createBescheidResource } from '../../../../../bescheid-shared/src/test/bescheid'; +import { createVorgangWithEingangResource } from '../../../../../vorgang-shared/test/vorgang'; +import { BescheidenFormService } from './bescheiden.formservice'; import { VorgangDetailBescheidenResultComponent } from './vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component'; import { VorgangDetailBescheidenStepsComponent } from './vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component'; import { VorgangDetailBescheidenComponent } from './vorgang-detail-bescheiden.component'; -import { MatIcon } from '@angular/material/icon'; -import { BescheidenFormService } from './bescheiden.formservice'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; describe('VorgangDetailBescheidenComponent', () => { let component: VorgangDetailBescheidenComponent; let fixture: ComponentFixture<VorgangDetailBescheidenComponent>; - const formService = new BescheidenFormService(new UntypedFormBuilder()); + const vorgangWithEingangResource = createVorgangWithEingangResource(); + const bescheidDraftResource = createBescheidResource(); + + const bescheidService = mock(BescheidService); + const formService = new BescheidenFormService( + new UntypedFormBuilder(), + useFromMock(bescheidService), + ); + const dialogRef = mock(DialogRef); beforeEach(async () => { TestBed.overrideComponent(VorgangDetailBescheidenComponent, { @@ -22,6 +34,10 @@ describe('VorgangDetailBescheidenComponent', () => { provide: BescheidenFormService, useValue: formService, }, + { + provide: BescheidService, + useValue: bescheidService, + }, ], }, }); @@ -33,9 +49,17 @@ describe('VorgangDetailBescheidenComponent', () => { MockComponent(MatIcon), ], providers: [ + { + provide: BescheidenFormService, + useValue: formService, + }, { provide: DialogRef, - useValue: {}, + useValue: dialogRef, + }, + { + provide: DIALOG_DATA, + useValue: { vorgangWithEingangResource, bescheidDraftResource }, }, ], imports: [ReactiveFormsModule], @@ -49,4 +73,30 @@ describe('VorgangDetailBescheidenComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('ngOnInit', () => { + it('should set vorgang on form service', () => { + const setVorgangWithEingangResource = (formService.setVorgangWithEingangResource = jest.fn()); + + component.ngOnInit(); + + expect(setVorgangWithEingangResource).toBeCalledWith(vorgangWithEingangResource); + }); + + it('should patch values', () => { + const patchValues = (formService.patchValues = jest.fn()); + + component.ngOnInit(); + + expect(patchValues).toBeCalledWith(bescheidDraftResource); + }); + }); + + describe('onClose', () => { + it('should call dialogRef.close', () => { + component.onClose(); + + expect(dialogRef.close).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts index 76e9f15c6ab3a0af82ab6e950c252448f4d38066..a985aa07223c5c926d6c0f8324edd80cd675791c 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts @@ -1,17 +1,33 @@ -import { DialogRef } from '@angular/cdk/dialog'; -import { Component } from '@angular/core'; +import { BescheidResource } from '@alfa-client/bescheid-shared'; +import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; +import { Component, Inject, OnInit } from '@angular/core'; import { BescheidenFormService } from './bescheiden.formservice'; +import { BescheidenDialogData } from './bescheiden.model'; @Component({ selector: 'alfa-vorgang-detail-bescheiden', templateUrl: './vorgang-detail-bescheiden.component.html', providers: [BescheidenFormService], }) -export class VorgangDetailBescheidenComponent { +export class VorgangDetailBescheidenComponent implements OnInit { + private readonly bescheidDraftResource: BescheidResource; + public activeStep: number = 1; constructor( public dialogRef: DialogRef, public formService: BescheidenFormService, - ) {} + @Inject(DIALOG_DATA) private readonly dialogData: BescheidenDialogData, + ) { + this.bescheidDraftResource = dialogData.bescheidDraftResource; + } + + ngOnInit(): void { + this.formService.setVorgangWithEingangResource(this.dialogData.vorgangWithEingangResource); + this.formService.patchValues(this.bescheidDraftResource); + } + + public onClose(): void { + this.dialogRef.close(); + } } diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts index 33ed39a1a00f0e77a1446d9f9eff206956b9ae18..8d51e40d64b5f8a1cc56566ff9a5bdcf733cfebb 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts @@ -31,11 +31,13 @@ import { } from '@alfa-client/vorgang-shared'; import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; +import { BescheidenFormService } from './vorgang-detail-bescheiden/bescheiden.formservice'; @Component({ selector: 'alfa-vorgang-detail-page', templateUrl: './vorgang-detail-page.component.html', styleUrls: ['./vorgang-detail-page.component.scss'], + providers: [BescheidenFormService], }) export class VorgangDetailPageComponent implements OnInit { vorgangStateResource$: Observable<StateResource<VorgangWithEingangResource>>; diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts index 278bde9503907ffdf9646fe88035a5f8da5cf0b8..76194ddd0d5a2534b259ccff3135060600d0b69c 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts @@ -40,6 +40,7 @@ import { WiedervorlageModule } from '@alfa-client/wiedervorlage'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { RadioButtonCardComponent } from 'design-system'; import { AktenzeichenEditDialogComponent } from './aktenzeichen-edit-dialog/aktenzeichen-edit-dialog.component'; import { AktenzeichenEditableComponent } from './aktenzeichen-editable/aktenzeichen-editable.component'; import { AbschliessenButtonComponent } from './buttons/abschliessen-button/abschliessen-button.component'; @@ -66,20 +67,19 @@ import { VorgangDetailBackButtonContainerComponent } from './vorgang-detail-page import { VorgangDetailBackButtonComponent } from './vorgang-detail-page/vorgang-detail-back-button-container/vorgang-detail-back-button/vorgang-detail-back-button.component'; import { VorgangDetailBescheidenResultStatusComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component'; import { VorgangDetailBescheidenResultComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component'; +import { VorgangDetailBescheidenStepButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component'; +import { VorgangDetailBescheidenStepButtonsComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component'; +import { VorgangDetailBescheidenStepTitleComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component'; +import { VorgangDetailAntragBescheidenStepComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component'; +import { VorgangDetailBescheidenStepContentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component'; +import { VorgangDetailBescheidenStepsContentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component'; import { VorgangDetailBescheidenStepsComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component'; +import { VorgangDetailBescheidenWeiterButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; import { VorgangDetailBescheidenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component'; import { VorgangDetailMoreMenuComponent } from './vorgang-detail-page/vorgang-detail-more-menu/vorgang-detail-more-menu.component'; import { VorgangExportContainerComponent } from './vorgang-detail-page/vorgang-detail-more-menu/vorgang-export-container/vorgang-export-container.component'; import { ProcessVorgangContainerComponent } from './vorgang-detail-page/vorgang-detail-more-menu/vorgang-process-vorgang-container/vorgang-process-vorgang-container.component'; import { VorgangDetailPageComponent } from './vorgang-detail-page/vorgang-detail-page.component'; -import { VorgangDetailBescheidenStepButtonsComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component'; -import { VorgangDetailBescheidenStepButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component'; -import { VorgangDetailBescheidenWeiterButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; -import { VorgangDetailBescheidenStepTitleComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component'; -import { VorgangDetailBescheidenStepsContentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component'; -import { VorgangDetailBescheidenStepContentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component'; -import { VorgangDetailAntragBescheidenStepComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden-step/vorgang-detail-antrag-bescheiden-step.component'; -import { RadioButtonCardComponent } from 'design-system'; const routes: Routes = [ { diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts index b25577325b0c33d2d02b844e78f8dfe2bc2e540f..3ee8483333198b707bea7ffa26c0c053bccc1499 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts @@ -61,6 +61,7 @@ export enum VorgangWithEingangLinkRel { PROCESS_VORGANG = 'processVorgang', SET_AKTENZEICHEN = 'set_aktenzeichen', + BESCHEID_DRAFT = 'bescheidDraft', } export enum LoeschAnforderungLinkRel { diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts index c18d952fcec598790bc40eee1a0522742c0eccd3..8efb82099e48fa5f69ada4435f722db6f4b79ae4 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts @@ -21,8 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { HttpErrorResponse } from '@angular/common/http'; import { ListResource, StateResource } from '@alfa-client/tech-shared'; +import { HttpErrorResponse } from '@angular/common/http'; import { TypedAction } from '@ngrx/store/src/models'; import { Resource, ResourceUri } from '@ngxp/rest'; import { diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java new file mode 100644 index 0000000000000000000000000000000000000000..0c45b6add7b914103ff595267b96e84cc38ad4a6 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/Bescheid.java @@ -0,0 +1,29 @@ +package de.ozgcloud.alfa.bescheid; + +import jakarta.validation.constraints.NotNull; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import de.ozgcloud.alfa.common.ValidationMessageCodes; +import de.ozgcloud.alfa.common.command.CommandBody; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Builder(toBuilder = true) +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@ToString +public class Bescheid implements CommandBody { + + @JsonIgnore + private String vorgangId; + + @NotNull(message = ValidationMessageCodes.FIELD_DATE_FORMAT_INVALID) + private String beschiedenAm; + private Boolean bewilligt; +} \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidController.java new file mode 100644 index 0000000000000000000000000000000000000000..8b1c6f142b90d65e65c9fca1a26788d616f7ce6c --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidController.java @@ -0,0 +1,31 @@ +package de.ozgcloud.alfa.bescheid; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.hateoas.EntityModel; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping(BescheidController.PATH) +@RequiredArgsConstructor +public class BescheidController { + + static final String PATH = "/api/bescheids"; // NOSONAR + static final String REQUEST_PARAM_STATUS_DRAFT = "draft"; + + private final BescheidModelAssembler assembler; + private final BescheidService bescheidService; + + @GetMapping + public ResponseEntity<EntityModel<Bescheid>> getDraft(@RequestParam String vorgangId, @RequestParam String status) { + if (!StringUtils.equalsIgnoreCase(status, REQUEST_PARAM_STATUS_DRAFT)) { + return ResponseEntity.badRequest().build(); + } + return ResponseEntity.of(bescheidService.getBescheidDraft(vorgangId).map(assembler::toModel)); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidMapper.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..a9e38edadc4b28eae35780380d3650222d58690d --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidMapper.java @@ -0,0 +1,13 @@ +package de.ozgcloud.alfa.bescheid; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; + +import de.ozgcloud.bescheid.GrpcBescheid; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +interface BescheidMapper { + + Bescheid fromGrpc(GrpcBescheid grpcBescheid, String vorgangId); +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java new file mode 100644 index 0000000000000000000000000000000000000000..f74b96ddc4ffa2791646e375d90f0f0de464e8f4 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidModelAssembler.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.server.RepresentationModelAssembler; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.ModelBuilder; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class BescheidModelAssembler implements RepresentationModelAssembler<Bescheid, EntityModel<Bescheid>> { + + @Override + public EntityModel<Bescheid> toModel(Bescheid bescheid) { + return ModelBuilder.fromEntity(bescheid) + .addLink(linkTo(methodOn(BescheidController.class).getDraft(bescheid.getVorgangId(), + BescheidController.REQUEST_PARAM_STATUS_DRAFT)).withSelfRel()) + .buildModel(); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidRemoteService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..372a0f5f197e2ddbc922d881c345f19b0d3e073a --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidRemoteService.java @@ -0,0 +1,39 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.GrpcUtil; +import de.ozgcloud.bescheid.BescheidServiceGrpc.BescheidServiceBlockingStub; +import de.ozgcloud.bescheid.GrpcBescheid; +import de.ozgcloud.bescheid.GrpcGetBescheidDraftRequest; +import de.ozgcloud.bescheid.GrpcGetBescheidDraftResponse; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class BescheidRemoteService { + + @GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT) + private BescheidServiceBlockingStub bescheidServiceStub; + @Autowired + private BescheidMapper bescheidMapper; + + public Optional<Bescheid> getBescheidDraft(String vorgangId) { + var request = buildGetBescheidDraftRequest(vorgangId); + var response = bescheidServiceStub.getBescheidDraft(request); + return getBescheidFromResponse(response).map(bescheid -> bescheidMapper.fromGrpc(bescheid, vorgangId)); + } + + GrpcGetBescheidDraftRequest buildGetBescheidDraftRequest(String vorgangId) { + return GrpcGetBescheidDraftRequest.newBuilder() + .setVorgangId(vorgangId) + .build(); + } + + Optional<GrpcBescheid> getBescheidFromResponse(GrpcGetBescheidDraftResponse response) { + return response.hasBescheid() ? Optional.of(response.getBescheid()) : Optional.empty(); + } + +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidService.java new file mode 100644 index 0000000000000000000000000000000000000000..67bef19968599583c09c5ab5ecde6b241aed3a4d --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidService.java @@ -0,0 +1,18 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class BescheidService { + + private final BescheidRemoteService remoteService; + + public Optional<Bescheid> getBescheidDraft(String vorgangId) { + return remoteService.getBescheidDraft(vorgangId); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidVorgangProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidVorgangProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..25e5daeeda18211fe04c4ad6c22d1ce1b3cfd142 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidVorgangProcessor.java @@ -0,0 +1,63 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import java.util.Objects; +import java.util.function.BooleanSupplier; + +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.LinkRelation; +import org.springframework.hateoas.server.RepresentationModelProcessor; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.FeatureToggleProperties; +import de.ozgcloud.alfa.common.ModelBuilder; +import de.ozgcloud.alfa.common.command.CommandController; +import de.ozgcloud.alfa.vorgang.Vorgang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +class BescheidVorgangProcessor implements RepresentationModelProcessor<EntityModel<VorgangWithEingang>> { + + static final String REL_DRAFT = "bescheidDraft"; + static final LinkRelation REL_CREATE_BESCHEID_DRAFT = LinkRelation.of("createBescheidDraft"); + + private final FeatureToggleProperties featureToggleProperties; + private final BescheidService bescheidService; + + @Override + public EntityModel<VorgangWithEingang> process(EntityModel<VorgangWithEingang> model) { + var vorgang = model.getContent(); + + if (Objects.isNull(vorgang)) { + return model; + } + + return ModelBuilder.fromModel(model) + .ifMatch(shouldAddLinkToDraft(vorgang)) + .addLink(linkTo(methodOn(BescheidController.class).getDraft(vorgang.getId(), BescheidController.REQUEST_PARAM_STATUS_DRAFT)).withRel( + REL_DRAFT)) + .ifMatch(shouldAddLinkToCreateDraft(vorgang)) + .addLink(linkTo(methodOn(CommandController.CommandByRelationController.class).createCommand(vorgang.getId(), vorgang.getId(), vorgang.getVersion(), + null)).withRel(REL_CREATE_BESCHEID_DRAFT)) + .buildModel(); + } + + BooleanSupplier shouldAddLinkToDraft(Vorgang vorgang) { + return () -> featureToggleProperties.isBescheidWizard() && isVorgangInBearbeitung(vorgang) && draftExists(vorgang); + } + + BooleanSupplier shouldAddLinkToCreateDraft(Vorgang vorgang) { + return () -> featureToggleProperties.isBescheidWizard() && isVorgangInBearbeitung(vorgang); + } + + boolean isVorgangInBearbeitung(Vorgang vorgang) { + return Vorgang.VorgangStatus.IN_BEARBEITUNG.equals(vorgang.getStatus()); + } + + boolean draftExists(Vorgang vorgang) { + return bescheidService.getBescheidDraft(vorgang.getId()).isPresent(); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/ValidationMessageCodes.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/ValidationMessageCodes.java index ba6acde6c2bb696ffa86297e5ddeede19cebe1dd..ce77fa1ca0d2cff727dcafe4df5e4c7eb2937479 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/ValidationMessageCodes.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/ValidationMessageCodes.java @@ -37,4 +37,5 @@ public class ValidationMessageCodes { public static final String FIELD_DATE_PAST = FIELD_PREFIX + "date_past"; public static final String FIELD_INVALID = FIELD_PREFIX + "invalid"; public static final String FIELD_FILE_SIZE_EXCEEDED = FIELD_PREFIX + "file_size_exceeded"; + public static final String FIELD_DATE_FORMAT_INVALID = FIELD_PREFIX + "date_format_invalid"; } \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/command/CommandBody.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/command/CommandBody.java index bb02dbc0461f3cd9e6a302b34d82a7ade6a16802..3f5f6e9622f6adf8a3d1d6c3035e4f760293fc9a 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/command/CommandBody.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/command/CommandBody.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import de.ozgcloud.alfa.aktenzeichen.AktenzeichenCommandBody; +import de.ozgcloud.alfa.bescheid.Bescheid; import de.ozgcloud.alfa.kommentar.Kommentar; import de.ozgcloud.alfa.loeschanforderung.DeleteLoeschAnforderung; import de.ozgcloud.alfa.loeschanforderung.LoeschAnforderung; @@ -46,7 +47,7 @@ import de.ozgcloud.alfa.wiedervorlage.Wiedervorlage; @Type(value = Kommentar.class, name = "KOMMENTAR"), @Type(value = LoeschAnforderung.class, name = "LOESCH_ANFORDERUNG"), @Type(value = DeleteLoeschAnforderung.class, name = "DELETE_LOESCH_ANFORDERUNG"), - @Type(value = GenericCommandBody.class, name = "CREATE_BESCHEID"), + @Type(value = Bescheid.class, name = "CREATE_BESCHEID"), @Type(value = ProcessVorgangBody.class, name = "PROCESS_VORGANG"), @Type(value = AktenzeichenCommandBody.class, name = "SET_AKTENZEICHEN") }) diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessor.java index 11514b26ef8ecf1720ade6d75e859a7db5239c25..78b09e77437d01710618ee0351819412a198a274 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessor.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessor.java @@ -62,7 +62,6 @@ class VorgangWithEingangProcessor implements RepresentationModelProcessor<Entity static final LinkRelation REL_VORGANG_FORWARDING = LinkRelation.of("forwarding"); static final LinkRelation REL_HISTORIE = LinkRelation.of("historie"); static final LinkRelation REL_BESCHEID = LinkRelation.of("createBescheid"); - static final LinkRelation REL_CREATE_BESCHEID_DRAFT = LinkRelation.of("createBescheidDraft"); static final LinkRelation REL_PROCESS_VORGANG = LinkRelation.of("processVorgang"); static final String REL_SEARCH_USER = "search-user-profiles"; @@ -116,9 +115,6 @@ class VorgangWithEingangProcessor implements RepresentationModelProcessor<Entity .ifMatch(() -> isCreateBescheidEnabled(vorgang)) .addLink(linkTo(methodOn(CommandByRelationController.class).createCommand(vorgang.getId(), vorgang.getId(), vorgang.getVersion(), null)).withRel(REL_BESCHEID)) - .ifMatch(() -> featureToggleProperties.isBescheidWizard()) - .addLink(linkTo(methodOn(CommandByRelationController.class).createCommand(vorgang.getId(), vorgang.getId(), vorgang.getVersion(), - null)).withRel(REL_CREATE_BESCHEID_DRAFT)) .ifMatch(this::isProcessable) .addLink( () -> linkTo(methodOn(CommandByRelationController.class).createCommand(vorgang.getId(), vorgang.getId(), vorgang.getVersion(), diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidCommandITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidCommandITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..d4c71d099ea22b5a27736889e0fb0aebff784a44 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidCommandITCase.java @@ -0,0 +1,90 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import de.ozgcloud.alfa.common.ValidationMessageCodes; +import de.ozgcloud.alfa.common.command.CommandController.CommandByRelationController; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandRemoteService; +import de.ozgcloud.alfa.common.command.CommandTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.common.test.TestUtils; + +@AutoConfigureMockMvc +@SpringBootTest +@WithMockUser +public class BescheidCommandITCase { + + @Autowired + private MockMvc mockMvc; + @MockBean + private CommandRemoteService commandRemoteService; + + @WithMockUser + @Nested + class TestCreateCommand { + + @BeforeEach + void init() { + when(commandRemoteService.createCommand(any())).thenReturn(CommandTestFactory.create()); + } + + @Test + void createCommandWithInvalidBeschiedenAm() throws Exception { + String content = createInvalidRequestContent(BescheidTestFactory.createBuilder().beschiedenAm(null).build()); + + doRequest(content).andExpect(status().isUnprocessableEntity()) + .andExpect(jsonPath("$.issues.length()").value(1)) + .andExpect(jsonPath("$.issues.[0].field").value("command.body.beschiedenAm")) + .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_DATE_FORMAT_INVALID)); + } + + @ParameterizedTest + @ValueSource(strings = { "01.04.2014", "1.4.2014", "1.4.14" }) + void createCommandWithValidBeschiedenAm(String beschiedenAm) throws Exception { + String content = createValidRequestContent(BescheidTestFactory.createBuilder().beschiedenAm(beschiedenAm).build()); + + doRequest(content).andExpect(status().isCreated()); + } + + private static String createValidRequestContent(Bescheid bescheid) { + return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithBescheid.json.tmpl", + CommandOrder.CREATE_BESCHEID.name(), + bescheid.getBeschiedenAm(), + String.valueOf(bescheid.getBewilligt())); + } + + private static String createInvalidRequestContent(Bescheid bescheid) { + return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithInvalidBescheid.json.tmpl", + CommandOrder.CREATE_BESCHEID.name(), + String.valueOf(bescheid.getBewilligt())); + } + + private ResultActions doRequest(String content) throws Exception { + return mockMvc.perform( + post(CommandByRelationController.COMMAND_BY_RELATION_PATH, VorgangHeaderTestFactory.ID, VorgangHeaderTestFactory.ID, + VorgangHeaderTestFactory.VERSION) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(content)); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9d0c9a32088b75a7740bce3ae34df94e55450ddc --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidControllerTest.java @@ -0,0 +1,102 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.hateoas.EntityModel; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; + +class BescheidControllerTest { + + @Mock + private BescheidModelAssembler assembler; + @Mock + private BescheidService bescheidService; + @Spy + @InjectMocks + private BescheidController controller; + + @Nested + class TestGetDraft { + + private final Bescheid draft = BescheidTestFactory.create(); + + @Test + void shouldReturnStatusBadRequestIfStatusParamIsNotRecognized() { + var response = controller.getDraft(VorgangHeaderTestFactory.ID, "dummy"); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + @Test + void shouldCallBescheidService() { + callGetDraft(); + + verify(bescheidService).getBescheidDraft(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldReturnStatusNotFoundIfDraftDoesNotExist() { + givenBescheidServiceReturnsEmpty(); + + var response = callGetDraft(); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } + + @Test + void shouldCallAssemblerIfDraftExists() { + givenBescheidServiceReturnsDraft(); + + callGetDraft(); + + verify(assembler).toModel(draft); + } + + @Test + void shouldReturnStatusOkIfDraftExists() { + givenBescheidServiceReturnsDraft(); + givenAssemblerCreatesModel(); + + var response = callGetDraft(); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + void shouldHaveEntityModelInBody() { + givenBescheidServiceReturnsDraft(); + givenAssemblerCreatesModel(); + + var response = callGetDraft(); + + assertThat(response.getBody()).isEqualTo(EntityModel.of(draft)); + } + + private void givenBescheidServiceReturnsDraft() { + when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.of(draft)); + } + + private void givenBescheidServiceReturnsEmpty() { + when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.empty()); + } + + private void givenAssemblerCreatesModel() { + when(assembler.toModel(draft)).thenReturn(EntityModel.of(draft)); + } + + private ResponseEntity<EntityModel<Bescheid>> callGetDraft() { + return controller.getDraft(VorgangHeaderTestFactory.ID, BescheidController.REQUEST_PARAM_STATUS_DRAFT); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidMapperTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9070e2d799c6a6a3aea89046c7ccabe4e818a8ef --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidMapperTest.java @@ -0,0 +1,43 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; + +class BescheidMapperTest { + + private final BescheidMapper mapper = Mappers.getMapper(BescheidMapper.class); + + @Nested + class TestFromGrpc { + + @Test + void shouldMapVorgangId() { + var bescheid = map(); + + assertThat(bescheid.getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldMapBewilligt() { + var bescheid = map(); + + assertThat(bescheid.getBewilligt()).isEqualTo(GrpcBescheidTestFactory.BEWILLIGT); + } + + @Test + void shouldMapBeschiedenAm() { + var bescheid = map(); + + assertThat(bescheid.getBeschiedenAm()).isEqualTo(GrpcBescheidTestFactory.BESCHIEDEN_AM); + } + + private Bescheid map() { + return mapper.fromGrpc(GrpcBescheidTestFactory.create(), VorgangHeaderTestFactory.ID); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..955c75f6753a884f64b737b84e0308189e963fef --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidModelAssemblerTest.java @@ -0,0 +1,39 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; +import org.springframework.hateoas.IanaLinkRelations; +import org.springframework.hateoas.Link; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; + +class BescheidModelAssemblerTest { + + @Spy + private BescheidModelAssembler assembler; + + @Nested + class TestToModel { + + private final Bescheid bescheid = BescheidTestFactory.create(); + + @Test + void shouldHaveSelfLink() { + var model = assembler.toModel(bescheid); + + assertThat(model.getLink(IanaLinkRelations.SELF)).isPresent().get().extracting(Link::getHref) + .isEqualTo(BescheidController.PATH + "?vorgangId=" + VorgangHeaderTestFactory.ID + "&status=" + + BescheidController.REQUEST_PARAM_STATUS_DRAFT); + } + + @Test + void shouldHaveBody() { + var model = assembler.toModel(bescheid); + + assertThat(model.getContent()).isEqualTo(bescheid); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidRemoteServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidRemoteServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2671618ca8384dc7119815e353aa77ea092da361 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidRemoteServiceTest.java @@ -0,0 +1,122 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.bescheid.BescheidServiceGrpc.BescheidServiceBlockingStub; +import de.ozgcloud.bescheid.GrpcGetBescheidDraftRequest; +import de.ozgcloud.bescheid.GrpcGetBescheidDraftResponse; + +class BescheidRemoteServiceTest { + + @Spy + @InjectMocks + private BescheidRemoteService service; + @Mock + private BescheidServiceBlockingStub bescheidServiceStub; + @Mock + private BescheidMapper bescheidMapper; + + @Nested + class GetBescheidDraftTest { + + private final GrpcGetBescheidDraftRequest request = GrpcGetBescheidDraftRequestTestFactory.create(); + private final GrpcGetBescheidDraftResponse response = GrpcGetBescheidDraftResponseTestFactory.create(); + private final Bescheid bescheidDraft = BescheidTestFactory.create(); + + @BeforeEach + void setUp() { + doReturn(request).when(service).buildGetBescheidDraftRequest(VorgangHeaderTestFactory.ID); + when(bescheidServiceStub.getBescheidDraft(request)).thenReturn(response); + } + + @Test + void shouldBuildGrpcGetBescheidRequest() { + service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + verify(service).buildGetBescheidDraftRequest(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldCallGrpcService() { + service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + verify(bescheidServiceStub).getBescheidDraft(request); + } + + @Test + void shouldCallMapper() { + doReturn(Optional.of(GrpcGetBescheidDraftResponseTestFactory.GRPC_BESCHEID)).when(service).getBescheidFromResponse(response); + + service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + verify(bescheidMapper).fromGrpc(GrpcGetBescheidDraftResponseTestFactory.GRPC_BESCHEID, VorgangHeaderTestFactory.ID); + } + + @Test + void shouldReturnBescheid() { + when(bescheidMapper.fromGrpc(GrpcGetBescheidDraftResponseTestFactory.GRPC_BESCHEID, VorgangHeaderTestFactory.ID)).thenReturn( + bescheidDraft); + + var bescheidDraft = service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + assertThat(bescheidDraft).hasValue(this.bescheidDraft); + } + + @Test + void shouldReturnEmpty() { + doReturn(Optional.empty()).when(service).getBescheidFromResponse(response); + + var bescheidDraft = service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + assertThat(bescheidDraft).isEmpty(); + } + + @Test + void shouldGetBescheidFromResponse() { + service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + verify(service).getBescheidFromResponse(response); + } + } + + @Nested + class GrpcGetBescheidDraftRequestTest { + + @Test + void shouldHaveVorgangId() { + var request = service.buildGetBescheidDraftRequest(VorgangHeaderTestFactory.ID); + + assertThat(request.getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID); + } + } + + @Nested + class GetBescheidFromResponseTest { + + @Test + void shouldReturnEmpty() { + var bescheid = service.getBescheidFromResponse(GrpcGetBescheidDraftResponse.getDefaultInstance()); + + assertThat(bescheid).isEmpty(); + } + + @Test + void shouldReturnBescheid() { + var bescheid = service.getBescheidFromResponse(GrpcGetBescheidDraftResponseTestFactory.create()); + + assertThat(bescheid).hasValue(GrpcGetBescheidDraftResponseTestFactory.GRPC_BESCHEID); + } + } + +} \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6241bdce4c6a7c514c9e6273a7235d11736156ba --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidServiceTest.java @@ -0,0 +1,44 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; + +class BescheidServiceTest { + + @Spy + @InjectMocks + private BescheidService service; + @Mock + private BescheidRemoteService remoteService; + + @Nested + class TestGetBescheidDraft { + + @Test + void shouldCallRemoteService() { + service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + verify(remoteService).getBescheidDraft(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldReturnResultFromRemoteService() { + var remoteServiceResult = Optional.of(BescheidTestFactory.create()); + when(remoteService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(remoteServiceResult); + + var result = service.getBescheidDraft(VorgangHeaderTestFactory.ID); + + assertThat(result).isEqualTo(remoteServiceResult); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..a14aee0bcd8a5c1c5dd2f1030985e089d4a0b72d --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidTestFactory.java @@ -0,0 +1,21 @@ +package de.ozgcloud.alfa.bescheid; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; + +public class BescheidTestFactory { + + public static final String VORGANG_ID = VorgangHeaderTestFactory.ID; + public static final String BESCHIEDEN_AM = "01.04.2024"; + public static final boolean BEWILLIGT = true; + + public static Bescheid.BescheidBuilder createBuilder() { + return Bescheid.builder() + .vorgangId(VORGANG_ID) + .beschiedenAm(BESCHIEDEN_AM) + .bewilligt(BEWILLIGT); + } + + public static Bescheid create() { + return createBuilder().build(); + } +} \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidVorgangProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidVorgangProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e535a2a8a1e894837959ce2cf87ada9ee7f33c37 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidVorgangProcessorTest.java @@ -0,0 +1,270 @@ +package de.ozgcloud.alfa.bescheid; + +import static de.ozgcloud.alfa.common.UserProfileUrlProviderTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; +import java.util.function.BooleanSupplier; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; + +import de.ozgcloud.alfa.common.FeatureToggleProperties; +import de.ozgcloud.alfa.common.UserProfileUrlProvider; +import de.ozgcloud.alfa.vorgang.Vorgang; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import lombok.NoArgsConstructor; + +class BescheidVorgangProcessorTest { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @Mock + private FeatureToggleProperties featureToggleProperties; + @Mock + private BescheidService bescheidService; + @Spy + @InjectMocks + private BescheidVorgangProcessor processor; + + @Nested + class TestProcess { + + @Test + void shouldReturnTheSameModelOnNullVorgang() { + var inputModel = new NullableEntityModel(); + + var processedModel = processor.process(inputModel); + + assertThat(processedModel).isEqualTo(inputModel); + } + + @Nested + class TestLinks { + + @BeforeEach + void init() { + initUserProfileUrlProvider(new UserProfileUrlProvider()); + } + + @Test + void shouldNotHaveLinkToDraft() { + givenLinkToDraftShouldBeAdded(false); + + var model = callProcess(); + + assertThat(model.getLink(BescheidVorgangProcessor.REL_DRAFT)).isEmpty(); + } + + @Test + void shouldHaveLinkToDraft() { + givenLinkToDraftShouldBeAdded(true); + + var model = callProcess(); + + assertThat(model.getLink(BescheidVorgangProcessor.REL_DRAFT)).isPresent().get().extracting(Link::getHref) + .isEqualTo(BescheidController.PATH + "?vorgangId=" + VorgangHeaderTestFactory.ID + "&status=" + + BescheidController.REQUEST_PARAM_STATUS_DRAFT); + } + + @Test + void shouldHaveLinkToCreateBescheidDraft() { + givenLinkToCrateDraftShouldBeAdded(true); + + var model = callProcess(); + + assertThat(model.getLink(BescheidVorgangProcessor.REL_CREATE_BESCHEID_DRAFT)).isPresent().get() + .extracting(Link::getHref) + .isEqualTo("/api/vorgangs/" + VorgangHeaderTestFactory.ID + "/relations/" + VorgangHeaderTestFactory.ID + "/" + + VorgangHeaderTestFactory.VERSION + "/commands"); + } + + @Test + void shouldNotHaveLinkToCreateBescheidDraft() { + givenLinkToCrateDraftShouldBeAdded(false); + + var model = callProcess(); + + assertThat(model.getLink(BescheidVorgangProcessor.REL_CREATE_BESCHEID_DRAFT)).isEmpty(); + } + + private void givenLinkToDraftShouldBeAdded(boolean shouldBeAdded) { + doReturn((BooleanSupplier) () -> shouldBeAdded).when(processor).shouldAddLinkToDraft(vorgang); + } + + private void givenLinkToCrateDraftShouldBeAdded(boolean shouldBeAdded) { + doReturn((BooleanSupplier) () -> shouldBeAdded).when(processor).shouldAddLinkToCreateDraft(vorgang); + } + + private EntityModel<? extends Vorgang> callProcess() { + return processor.process(EntityModel.of(vorgang)); + } + } + + @NoArgsConstructor + private static class NullableEntityModel extends EntityModel<VorgangWithEingang> { + + } + } + + @Nested + class TestShouldAddLinkToDraft { + + @Test + void shouldReturnTrue() { + givenFeatureToggleEnabled(true); + givenVorgangInBearbeitung(true); + givenDraftExists(true); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isTrue(); + } + + @Test + void shouldReturnFalseIfFeatureToggleIsDisabled() { + givenFeatureToggleEnabled(false); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isFalse(); + } + + @Test + void shouldReturnFalseIfVorgangNotInBearbeitung() { + givenFeatureToggleEnabled(true); + givenVorgangInBearbeitung(false); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isFalse(); + } + + @Test + void shouldReturnFalseIfDraftDoesNotExist() { + givenFeatureToggleEnabled(true); + givenVorgangInBearbeitung(true); + givenDraftExists(false); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isFalse(); + } + + private void givenDraftExists(boolean exists) { + doReturn(exists).when(processor).draftExists(vorgang); + } + + private BooleanSupplier callMethod() { + return processor.shouldAddLinkToDraft(vorgang); + } + } + + @Nested + class TestShouldAddLinkToCreateDraft { + + @Test + void shouldReturnTrue() { + givenFeatureToggleEnabled(true); + givenVorgangInBearbeitung(true); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isTrue(); + } + + @Test + void shouldReturnFalseIfFeatureToggleIsDisabled() { + givenFeatureToggleEnabled(false); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isFalse(); + } + + @Test + void shouldReturnFalseIfVorgangNotInBearbeitung() { + givenFeatureToggleEnabled(true); + givenVorgangInBearbeitung(false); + + var booleanSupplier = callMethod(); + + assertThat(booleanSupplier.getAsBoolean()).isFalse(); + } + + private BooleanSupplier callMethod() { + return processor.shouldAddLinkToCreateDraft(vorgang); + } + } + + @Nested + class TestIsVorgangInBearbeitung { + + @ParameterizedTest + @EnumSource(mode = EnumSource.Mode.EXCLUDE, names = { "IN_BEARBEITUNG" }) + void shouldReturnFalse(Vorgang.VorgangStatus vorgangStatus) { + var vorgang = VorgangWithEingangTestFactory.createBuilder().status(vorgangStatus).build(); + + var inBearbeitung = processor.isVorgangInBearbeitung(vorgang); + + assertThat(inBearbeitung).isFalse(); + } + + @Test + void shouldReturnTrue() { + var vorgang = VorgangWithEingangTestFactory.createBuilder().status(Vorgang.VorgangStatus.IN_BEARBEITUNG).build(); + + var inBearbeitung = processor.isVorgangInBearbeitung(vorgang); + + assertThat(inBearbeitung).isTrue(); + } + } + + @Nested + class TestDraftExists { + + @Test + void shouldCallBescheidService() { + processor.draftExists(vorgang); + + verify(bescheidService).getBescheidDraft(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldReturnFalse() { + when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.empty()); + + var result = processor.draftExists(vorgang); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnTrue() { + when(bescheidService.getBescheidDraft(VorgangHeaderTestFactory.ID)).thenReturn(Optional.of(BescheidTestFactory.create())); + + var result = processor.draftExists(vorgang); + + assertThat(result).isTrue(); + } + } + + private void givenFeatureToggleEnabled(boolean enabled) { + when(featureToggleProperties.isBescheidWizard()).thenReturn(enabled); + } + + private void givenVorgangInBearbeitung(boolean inBearbeitung) { + doReturn(inBearbeitung).when(processor).isVorgangInBearbeitung(vorgang); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcBescheidTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcBescheidTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..1177c9ebb06c2f5242baf6c8810cf687fedddfad --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcBescheidTestFactory.java @@ -0,0 +1,19 @@ +package de.ozgcloud.alfa.bescheid; + +import de.ozgcloud.bescheid.GrpcBescheid; + +public class GrpcBescheidTestFactory { + + public static final boolean BEWILLIGT = true; + public static final String BESCHIEDEN_AM = "01.04.2024"; + + public static GrpcBescheid create() { + return createBuilder().build(); + } + + public static GrpcBescheid.Builder createBuilder() { + return GrpcBescheid.newBuilder() + .setBewilligt(BEWILLIGT) + .setBeschiedenAm(BESCHIEDEN_AM); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcGetBescheidDraftRequestTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcGetBescheidDraftRequestTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..3c3c4f8c4d8e9295f8a905b66d3fb79271a18f50 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcGetBescheidDraftRequestTestFactory.java @@ -0,0 +1,17 @@ +package de.ozgcloud.alfa.bescheid; + +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.bescheid.GrpcGetBescheidDraftRequest; + +public class GrpcGetBescheidDraftRequestTestFactory { + + public static GrpcGetBescheidDraftRequest create() { + return createBuilder().build(); + } + + public static GrpcGetBescheidDraftRequest.Builder createBuilder() { + return GrpcGetBescheidDraftRequest.newBuilder() + .setVorgangId(VorgangHeaderTestFactory.ID); + } + +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcGetBescheidDraftResponseTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcGetBescheidDraftResponseTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..bec1bc0df500eac54f7fd72cde9755632d589501 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/GrpcGetBescheidDraftResponseTestFactory.java @@ -0,0 +1,18 @@ +package de.ozgcloud.alfa.bescheid; + +import de.ozgcloud.bescheid.GrpcBescheid; +import de.ozgcloud.bescheid.GrpcGetBescheidDraftResponse; + +public class GrpcGetBescheidDraftResponseTestFactory { + + public static final GrpcBescheid GRPC_BESCHEID = GrpcBescheidTestFactory.create(); + + public static GrpcGetBescheidDraftResponse create() { + return createBuilder().build(); + } + + public static GrpcGetBescheidDraftResponse.Builder createBuilder() { + return GrpcGetBescheidDraftResponse.newBuilder() + .setBescheid(GRPC_BESCHEID); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/common/command/CommandByRelationControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/common/command/CommandByRelationControllerTest.java index 2583c28c72e74b143a21a0a9f21cad9602e97954..2f1b7878ca48c0daf968e58720e25be65a0ecb18 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/common/command/CommandByRelationControllerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/common/command/CommandByRelationControllerTest.java @@ -46,7 +46,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import de.ozgcloud.alfa.common.command.CommandController.CommandByRelationController; import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; import de.ozgcloud.common.test.TestUtils; @@ -103,18 +102,6 @@ class CommandByRelationControllerTest { .andExpect(header().stringValues("location", "http://localhost" + COMMANDS_PATH + "/" + CommandTestFactory.ID)); } - @Test - void shouldFillGenericBody() throws Exception { - var content = TestUtils.loadTextFile("jsonTemplates/command/createCommandWithBody.json.tmpl", CommandOrder.CREATE_BESCHEID.name(), - "{\"bescheidVom\":\"2023-06-26\"}"); - - doRequest(content); - - verify(service).createCommand(createCommandCaptor.capture(), anyLong()); - var body = (GenericCommandBody) createCommandCaptor.getValue().getBody(); - assertThat(body).isNotNull().contains(entry("bescheidVom", "2023-06-26")); - } - private ResultActions doRequest() throws Exception { return doRequest( TestUtils.loadTextFile("jsonTemplates/command/createVorgangCommand.json.tmpl", CommandOrder.VORGANG_ANNEHMEN.name())); diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessorTest.java index bbe3a84215e725c40c4d99d621f290fdf19af694..1022eb3a27b1e8dfc262aafc25ab99b4d80883c0 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessorTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangWithEingangProcessorTest.java @@ -569,38 +569,4 @@ class VorgangWithEingangProcessorTest { } } } - - @Nested - class TestCreateBescheidDraftLink { - - private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); - private final EntityModel<VorgangWithEingang> vorgangEntityModel = EntityModel.of(vorgang); - - @BeforeEach - void activateFeature() { - initUserProfileUrlProvider(urlProvider); - } - - @Test - void shouldHaveCreateBescheidDraftLink() { - when(featureToggleProperties.isBescheidWizard()).thenReturn(true); - - var model = processor.process(vorgangEntityModel); - - assertThat(model.getLink(VorgangWithEingangProcessor.REL_CREATE_BESCHEID_DRAFT)).isPresent().get() - .extracting(Link::getHref) - .isEqualTo("/api/vorgangs/" + VorgangHeaderTestFactory.ID + "/relations/" + VorgangHeaderTestFactory.ID + "/" - + VorgangHeaderTestFactory.VERSION + "/commands"); - } - - @Test - void shouldNotHaveCreateBescheidDraftLink() { - when(featureToggleProperties.isBescheidWizard()).thenReturn(false); - - var model = processor.process(vorgangEntityModel); - - assertThat(model.getLink(VorgangWithEingangProcessor.REL_CREATE_BESCHEID_DRAFT)).isEmpty(); - } - } - } \ No newline at end of file diff --git a/alfa-service/src/test/resources/jsonTemplates/command/createCommandWithBescheid.json.tmpl b/alfa-service/src/test/resources/jsonTemplates/command/createCommandWithBescheid.json.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..440597de52230f9a1db024d2ad5854db23a39dcc --- /dev/null +++ b/alfa-service/src/test/resources/jsonTemplates/command/createCommandWithBescheid.json.tmpl @@ -0,0 +1,7 @@ +{ + "order": "%s", + "body": { + "beschiedenAm": "%s", + "bewilligt": "%s" + } +} \ No newline at end of file diff --git a/alfa-service/src/test/resources/jsonTemplates/command/createCommandWithInvalidBescheid.json.tmpl b/alfa-service/src/test/resources/jsonTemplates/command/createCommandWithInvalidBescheid.json.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..98cbb1c3360deae091b8e4b28d3efc3ff4345348 --- /dev/null +++ b/alfa-service/src/test/resources/jsonTemplates/command/createCommandWithInvalidBescheid.json.tmpl @@ -0,0 +1,7 @@ +{ + "order": "%s", + "body": { + "beschiedenAm": null, + "bewilligt": "%s" + } +} \ No newline at end of file