Skip to content
Snippets Groups Projects
Commit 5d1faeb6 authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' into OZG-5243-E2E-Fixes

parents 27011f3a 4bb3726b
No related branches found
No related tags found
No related merge requests found
Showing
with 295 additions and 136 deletions
......@@ -21,17 +21,16 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AktenzeichenEditableComponent } from '@alfa-client/vorgang-detail';
import { DialogService } from '@alfa-client/ui';
import { HasLinkPipe } from '@alfa-client/tech-shared';
import { mock } from '@alfa-client/test-utils';
import { MockComponent } from 'ng-mocks';
import { OzgcloudIconButtonPrimaryComponent } from '@alfa-client/ui';
import { DialogService, OzgcloudIconButtonPrimaryComponent } from '@alfa-client/ui';
import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared';
import { AktenzeichenComponent } from '@alfa-client/vorgang-shared-ui';
import { AktenzeichenEditDialogComponent } from '@alfa-client/vorgang-detail';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
import { createEmptyStateResource, HasLinkPipe } from '@alfa-client/tech-shared';
import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared';
import { MockComponent } from 'ng-mocks';
import { AktenzeichenEditDialogComponent } from '../aktenzeichen-edit-dialog/aktenzeichen-edit-dialog.component';
import { AktenzeichenEditableComponent } from './aktenzeichen-editable.component';
describe('AktenzeichenComponent', () => {
let component: AktenzeichenEditableComponent;
......
......@@ -23,72 +23,81 @@
unter der Lizenz sind dem Lizenztext zu entnehmen.
-->
<h3>Antragstellerdaten</h3>
<mat-list *ngIf="antragstellerExists; else noAntragsteller" data-test-id="antragsteller-mat-list">
<mat-list-item *ngIf="name">
<mat-icon matListItemIcon class="material-icons-outlined" aria-label="Name" aria-hidden="false"
>assignment_ind</mat-icon
<h3 class="font-medium leading-6 mb-2">Antragsteller</h3>
<ul
*ngIf="antragstellerExists; else noAntragsteller"
data-test-id="antragsteller-list"
class="text-sm leading-6 my-1"
>
<div matListItemLine data-test-id="antragsteller-name">
<div class="font-medium mb-2">
<h4 *ngIf="!isFirma && name" data-test-id="antragsteller-name" class="my-1">
{{ name }}
</h4>
<h4 *ngIf="isFirma" data-test-id="antragsteller-firma-name" class="my-1">
{{ antragsteller.firmaName }}
</h4>
</div>
</mat-list-item>
<mat-list-item *ngIf="antragsteller.email">
<li
*ngIf="antragstellerStrasseHausnummer || antragstellerPlzOrt"
data-test-id="antragsteller-adresse"
class="flex gap-2 my-2"
>
<mat-icon
class="material-icons-outlined"
aria-label="Adresse"
aria-hidden="false"
>location_on</mat-icon
>
<div class="flex flex-col">
<p data-test-id="antragsteller-strasse-hausnummer">
{{ antragstellerStrasseHausnummer }}
</p>
<p data-test-id="antragsteller-plz-ort">
{{ antragstellerPlzOrt }}
</p>
</div>
</li>
<div *ngIf="isFirma && name" class="mb-1">
<h4 class="my-1 font-medium">
Ansprechpartner
</h4>
<p class="my-1" data-test-id="antragsteller-ansprechpartner-name">{{ name }}</p>
</div>
<li *ngIf="antragsteller.email" [title]="antragsteller.email" class="flex gap-2 my-2">
<mat-icon
matListItemIcon
class="material-icons-outlined"
aria-label="E-Mail-Adresse"
aria-hidden="false"
>email</mat-icon
>
<div matListItemLine data-test-id="antragsteller-email">
<p data-test-id="antragsteller-email">
{{ antragsteller.email }}
</div>
</mat-list-item>
<mat-list-item *ngIf="antragsteller.telefon">
</p>
</li>
<li *ngIf="antragsteller.telefon" class="flex gap-2 my-2">
<mat-icon
matListItemIcon
class="material-icons-outlined"
aria-label="Telefonnummer"
aria-hidden="false"
>call_black</mat-icon
>
<div matListItemLine data-test-id="antragsteller-telefon">
<p data-test-id="antragsteller-telefon">
{{ antragsteller.telefon }}
</div>
</mat-list-item>
<mat-list-item
*ngIf="antragstellerStrasseHausnummer || antragstellerPlzOrt"
data-test-id="antragsteller-adresse"
>
<mat-icon
matListItemIcon
class="material-icons-outlined"
aria-label="Adresse"
aria-hidden="false"
>location_on</mat-icon
>
<div matListItemLine data-test-id="antragsteller-strasse-hausnummer">
{{ antragstellerStrasseHausnummer }}
</div>
<div matListItemLine data-test-id="antragsteller-plz-ort">
{{ antragstellerPlzOrt }}
</div>
</mat-list-item>
<mat-list-item *ngIf="geburt">
</p>
</li>
<li *ngIf="geburt" class="flex gap-2 my-2">
<mat-icon
matListItemIcon
class="material-icons-outlined"
aria-label="Geburtsdatum und Geburtsort"
aria-hidden="false"
>cake</mat-icon
>
<div matListItemLine data-test-id="antragsteller-geburt">
<p data-test-id="antragsteller-geburt">
{{ geburt }}
</div>
</mat-list-item>
</mat-list>
</p>
</li>
</ul>
<ng-template #noAntragsteller>
<div data-test-id="no-antragsteller">Nicht vorhanden.</div>
<p data-test-id="no-antragsteller" class="text-sm leading-6">Nicht vorhanden.</p>
</ng-template>
/**
* Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
h3 {
font-weight: 500;
}
......@@ -40,6 +40,9 @@ describe('VorgangDetailAntragstellerComponent', () => {
let fixture: ComponentFixture<VorgangDetailAntragstellerComponent>;
const antragstellerName: string = '[data-test-id="antragsteller-name"]';
const antragstellerAnsprechspartnerName: string =
'[data-test-id="antragsteller-ansprechpartner-name"]';
const antragstellerFirmaName: string = '[data-test-id="antragsteller-firma-name"]';
const antragstellerEmail: string = '[data-test-id="antragsteller-email"]';
const antragstellerTelefon: string = '[data-test-id="antragsteller-telefon"]';
const antragstellerStrasseHausnummer: string =
......@@ -47,10 +50,11 @@ describe('VorgangDetailAntragstellerComponent', () => {
const antragstellerPlzOrt: string = '[data-test-id="antragsteller-plz-ort"]';
const antragstellerGeburt: string = '[data-test-id="antragsteller-geburt"]';
const antragstellerAdresse: string = '[data-test-id="antragsteller-adresse"]';
const antragstellerMatList: string = '[data-test-id="antragsteller-mat-list"]';
const antragstellerList: string = '[data-test-id="antragsteller-list"]';
const noAntragsteller: string = '[data-test-id="no-antragsteller"]';
const antragsteller: Antragsteller = createAntragsteller();
const antragstellerWithoutCompany = { ...antragsteller, firmaName: '' };
beforeEach(async () => {
await TestBed.configureTestingModule({
......@@ -71,8 +75,8 @@ describe('VorgangDetailAntragstellerComponent', () => {
});
describe('full name', () => {
it('should be visible', () => {
component.antragsteller = antragsteller;
it('should be visible, if applicant is not company', () => {
component.antragsteller = antragstellerWithoutCompany;
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerName);
......@@ -80,8 +84,22 @@ describe('VorgangDetailAntragstellerComponent', () => {
expect(element).toHaveTextContent(component.name);
});
it('should not be visible', () => {
component.antragsteller = { ...antragsteller, anrede: '', vorname: '', nachname: '' };
it('should not be visible, if applicant is company', () => {
component.antragsteller = antragsteller;
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerName);
expect(element).not.toBeInstanceOf(HTMLElement);
});
it('should not be visible, if contact person name is empty', () => {
component.antragsteller = {
...antragstellerWithoutCompany,
anrede: '',
vorname: '',
nachname: '',
};
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerName);
......@@ -101,6 +119,72 @@ describe('VorgangDetailAntragstellerComponent', () => {
});
});
describe('full name contact person', () => {
it('should be visible, if applicant is company', () => {
component.antragsteller = antragsteller;
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerAnsprechspartnerName);
expect(element).toHaveTextContent(component.name);
});
it('should not be visible, if applicant is not company', () => {
component.antragsteller = antragstellerWithoutCompany;
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerAnsprechspartnerName);
expect(element).not.toBeInstanceOf(HTMLElement);
});
it('should not be visible, if name is empty', () => {
component.antragsteller = { ...antragsteller, anrede: '', vorname: '', nachname: '' };
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerName);
expect(element).not.toBeInstanceOf(HTMLElement);
});
});
describe('firma name', () => {
it('should be visible', () => {
component.antragsteller = antragsteller;
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerFirmaName);
expect(element).toHaveTextContent(component.antragsteller.firmaName);
});
it('should not be visible', () => {
component.antragsteller = antragstellerWithoutCompany;
fixture.detectChanges();
const element = getElementFromFixture(fixture, antragstellerFirmaName);
expect(element).not.toBeInstanceOf(HTMLElement);
});
});
describe('isFirma', () => {
it('should return true', () => {
component.antragsteller = antragsteller;
const isFirma = component.isFirma;
expect(isFirma).toBeTruthy;
});
it('should return false', () => {
component.antragsteller = antragstellerWithoutCompany;
const isFirma = component.isFirma;
expect(isFirma).toBeFalsy;
});
});
describe('email', () => {
it('should be visible', () => {
component.antragsteller = antragsteller;
......@@ -184,7 +268,7 @@ describe('VorgangDetailAntragstellerComponent', () => {
it('should be visible', () => {
const element = getElementFromFixture(fixture, antragstellerAdresse);
expect(element).toHaveClass('mdc-list-item');
expect(element).toBeInstanceOf(HTMLElement);
});
it('should not be visible', () => {
......@@ -204,7 +288,7 @@ describe('VorgangDetailAntragstellerComponent', () => {
});
it('mat-list should be visible', () => {
const element = getElementFromFixture(fixture, antragstellerMatList);
const element = getElementFromFixture(fixture, antragstellerList);
expect(element).toBeInstanceOf(HTMLElement);
});
......@@ -230,6 +314,7 @@ describe('VorgangDetailAntragstellerComponent', () => {
geburtsort: EMPTY_STRING,
nachname: EMPTY_STRING,
vorname: EMPTY_STRING,
firmaName: EMPTY_STRING,
email: EMPTY_STRING,
telefon: EMPTY_STRING,
strasse: EMPTY_STRING,
......@@ -241,7 +326,7 @@ describe('VorgangDetailAntragstellerComponent', () => {
}
it('mat-list should not be visible', () => {
const element = getElementFromFixture(fixture, antragstellerMatList);
const element = getElementFromFixture(fixture, antragstellerList);
expect(element).not.toBeInstanceOf(HTMLElement);
});
......@@ -260,7 +345,7 @@ describe('VorgangDetailAntragstellerComponent', () => {
});
it('mat-list should not be visible', () => {
const element = getElementFromFixture(fixture, antragstellerMatList);
const element = getElementFromFixture(fixture, antragstellerList);
expect(element).not.toBeInstanceOf(HTMLElement);
});
......
......@@ -21,15 +21,14 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
import { Component, Input } from '@angular/core';
import { allEmpty, formatFullDate, isParsableToDate } from '@alfa-client/tech-shared';
import { Antragsteller } from '@alfa-client/vorgang-shared';
import { Component, Input } from '@angular/core';
import { isNull } from 'lodash-es';
@Component({
selector: 'alfa-vorgang-detail-antragsteller',
templateUrl: './vorgang-detail-antragsteller.component.html',
styleUrls: ['./vorgang-detail-antragsteller.component.scss'],
})
export class VorgangDetailAntragstellerComponent {
private readonly TRIM_TO_ONE_SPACE = /\s{2,}/g;
......@@ -43,6 +42,7 @@ export class VorgangDetailAntragstellerComponent {
if (
allEmpty(
this.name,
this.antragsteller.firmaName,
this.antragstellerStrasseHausnummer,
this.antragstellerPlzOrt,
this.geburt,
......@@ -82,4 +82,8 @@ export class VorgangDetailAntragstellerComponent {
}
return this.antragsteller.geburtsdatum;
}
get isFirma(): boolean {
return !!this.antragsteller.firmaName;
}
}
......@@ -24,7 +24,6 @@
import { BeschiedenDateInVorgangContainerComponent } from '@alfa-client/bescheid';
import { EMPTY_STRING, EnumToLabelPipe, HasLinkPipe } from '@alfa-client/tech-shared';
import { getDebugElementFromFixtureByCss } from '@alfa-client/test-utils';
import { AktenzeichenEditableComponent } from '@alfa-client/vorgang-detail';
import { VorgangHeaderLinkRel } from '@alfa-client/vorgang-shared';
import {
VorgangNummerComponent,
......@@ -35,10 +34,11 @@ import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatIcon } from '@angular/material/icon';
import { MatIconTestingModule } from '@angular/material/icon/testing';
import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
import { UserProfileInVorgangContainerComponent } from 'libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang-container.component';
import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
import { MockComponent } from 'ng-mocks';
import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
import { UserProfileInVorgangContainerComponent } from '../../../../../../user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang-container.component';
import { createVorgangWithEingangResource } from '../../../../../../vorgang-shared/test/vorgang';
import { AktenzeichenEditableComponent } from '../../../aktenzeichen-editable/aktenzeichen-editable.component';
import { VorgangDetailHeaderComponent } from './vorgang-detail-header.component';
describe('VorgangDetailHeaderComponent', () => {
......
......@@ -9,7 +9,6 @@
</button>
<ozgcloud-menu #moreMenu data-test-id="more-menu">
<ozgcloud-menu-item
*ngIf="vorgangWithEingang | hasLink: vorgangWithEingangLinkRel.EXPORT"
data-test-id="vorgang-exportieren-button"
headline="Vorgang exportieren"
text="Alle Informationen und Anhänge des Vorgangs zur Archivierung im DMS."
......
......@@ -2,6 +2,7 @@ import {
getElementFromDomRoot,
getElementFromFixture,
getMockComponent,
getMockComponents,
} from '@alfa-client/test-utils';
import { MenuItemComponent, OzgcloudIconComponent, UiModule } from '@alfa-client/ui';
import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
......@@ -122,7 +123,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
fixture.detectChanges();
});
it('should be visible if link exists', () => {
it('should be visible', () => {
component.vorgangWithEingang = vorgangWithEingang;
fixture.detectChanges();
getElementFromFixture(fixture, moreMenuButton).click();
......@@ -132,16 +133,6 @@ describe('VorgangDetailMoreMenuComponent', () => {
expect(element).toBeInTheDocument();
});
it('should NOT be visible if link is missing', () => {
component.vorgangWithEingang = createVorgangWithEingangResource();
fixture.detectChanges();
getElementFromFixture(fixture, moreMenuButton).click();
const element = getElementFromDomRoot(fixture, exportMenuItem);
expect(element).not.toBeInTheDocument();
});
describe('input property', () => {
beforeEach(() => {
component.vorgangWithEingang = vorgangWithEingang;
......@@ -236,7 +227,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains headline', () => {
getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent);
const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.headline).toBe('Vorgang automatisiert vorprüfen');
});
......@@ -244,7 +235,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains text', () => {
getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent);
const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.text).toBe(
'Eine Vorprüfung wird durchgeführt. Das Ergebnis wird als Kommentar hinzugefügt.',
......@@ -254,7 +245,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains icon', () => {
getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent);
const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.icon).toBe('vorgang_vorpruefen');
});
......@@ -262,7 +253,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains iconSizeBig', () => {
getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent);
const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.iconSizeBig).toBeTruthy();
});
......
<ng-container>
<ozgcloud-button-with-spinner
*ngIf="canExport"
dataTestId="export-vorgang"
[showSpinner]="(exportStateResource$ | async)?.loading"
(clickEmitter)="export()"
text="Herunterladen"
icon="save_alt"
>
</ozgcloud-button-with-spinner>
/>
<div *ngIf="!canExport" class="flex gap-2 items-start" data-test-id="cannot-export-vorgang">
<ods-exclamation-icon />
<div>
<p class="text-error font-medium text-sm">Vorgang exportieren nicht möglich.</p>
<p class="text-sm">Die xdomea-Datei kann nur im <strong class="font-medium">Status Abgeschlossen</strong> heruntergeladen werden.</p>
</div>
</div>
</ng-container>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { StateResource, createStateResource } from '@alfa-client/tech-shared';
import { dispatchEventFromFixture, mock } from '@alfa-client/test-utils';
import { getElementFromFixture, mock } from '@alfa-client/test-utils';
import { OzgcloudButtonWithSpinnerComponent } from '@alfa-client/ui';
import { VorgangService } from '@alfa-client/vorgang-shared';
import { VorgangService, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ExclamationIconComponent } from '@ods/system';
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 { VorgangExportContainerComponent } from './vorgang-export-container.component';
......@@ -15,12 +18,14 @@ describe('VorgangExportContainerComponent', () => {
const vorgangService = mock(VorgangService);
const buttonWithSpinner: string = '[dataTestId="export-vorgang"]';
const cannotExportMessageDataTestId: string = getDataTestIdOf('cannot-export-vorgang');
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
VorgangExportContainerComponent,
MockComponent(OzgcloudButtonWithSpinnerComponent),
MockComponent(ExclamationIconComponent),
],
providers: [
{
......@@ -60,9 +65,49 @@ describe('VorgangExportContainerComponent', () => {
describe('export', () => {
it('should call vorgangService.export', () => {
dispatchEventFromFixture(fixture, buttonWithSpinner, 'clickEmitter');
component.export();
expect(vorgangService.export).toHaveBeenCalled();
});
});
describe('set vorgang with eingang property', () => {
it('should set canExport to true', () => {
const vorgangResourceWithExportLink = createVorgangWithEingangResource([
VorgangWithEingangLinkRel.EXPORT,
]);
component.vorgangWithEingang = vorgangResourceWithExportLink;
expect(component.canExport).toBeTruthy();
});
it('should set canExport to false', () => {
const vorgangResource = createVorgangWithEingangResource();
component.vorgangWithEingang = vorgangResource;
expect(component.canExport).toBeFalsy();
});
});
describe('show export button or message', () => {
it('should show button, if canExport is true', () => {
component.canExport = true;
fixture.detectChanges();
const element = getElementFromFixture(fixture, buttonWithSpinner);
expect(element).toBeInstanceOf(HTMLElement);
});
it('should show message, if canExport is false', () => {
component.canExport = false;
fixture.detectChanges();
const element = getElementFromFixture(fixture, cannotExportMessageDataTestId);
expect(element).toBeInstanceOf(HTMLElement);
});
});
});
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { StateResource } from '@alfa-client/tech-shared';
import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
import {
VorgangService,
VorgangWithEingangLinkRel,
VorgangWithEingangResource,
} from '@alfa-client/vorgang-shared';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { hasLink } from '@ngxp/rest';
import { Observable, tap } from 'rxjs';
@Component({
......@@ -9,11 +14,14 @@ import { Observable, tap } from 'rxjs';
styleUrls: ['./vorgang-export-container.component.scss'],
})
export class VorgangExportContainerComponent implements OnInit {
@Input() vorgangWithEingang: VorgangWithEingangResource;
@Input() set vorgangWithEingang(vorgang: VorgangWithEingangResource) {
this.canExport = hasLink(vorgang, VorgangWithEingangLinkRel.EXPORT);
}
@Output() public closeMenu: EventEmitter<void> = new EventEmitter();
public exportStateResource$: Observable<StateResource<boolean>>;
public canExport: boolean = false;
constructor(private vorgangService: VorgangService) {}
......
......@@ -56,6 +56,8 @@ import {
ButtonCardComponent,
ButtonComponent,
CloseIconComponent,
ErrorMessageComponent,
ExclamationIconComponent,
RadioButtonCardComponent,
SaveIconComponent,
SendIconComponent,
......@@ -145,6 +147,7 @@ const routes: Routes = [
ButtonComponent,
ButtonCardComponent,
CloseIconComponent,
ExclamationIconComponent,
SaveIconComponent,
SendIconComponent,
StampIconComponent,
......@@ -159,6 +162,7 @@ const routes: Routes = [
TextEditorComponent,
TextareaEditorComponent,
BescheidStatusTextComponent,
ErrorMessageComponent,
],
declarations: [
VorgangDetailPageComponent,
......
......@@ -64,6 +64,7 @@ export interface Antragsteller {
geburtsort: string;
nachname: string;
vorname: string;
firmaName: string;
email: string;
telefon: string;
strasse: string;
......
......@@ -21,6 +21,11 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
import { faker } from '@faker-js/faker';
import { times } from 'lodash-es';
import { toResource } from '../../tech-shared/test/resource';
import { VorgangListLinkRel } from '../src/lib/vorgang.linkrel';
import {
Antragsteller,
ByStatus,
......@@ -28,7 +33,6 @@ import {
EingangHeader,
ForwardRequest,
Vorgang,
VorgangListLinkRel,
VorgangListResource,
VorgangResource,
VorgangStatistic,
......@@ -36,10 +40,7 @@ import {
VorgangWithEingang,
VorgangWithEingangResource,
ZustaendigeStelle,
} from '@alfa-client/vorgang-shared';
import { faker } from '@faker-js/faker';
import { toResource } from 'libs/tech-shared/test/resource';
import { times } from 'lodash-es';
} from '../src/lib/vorgang.model';
export function createVorgang(): Vorgang {
return {
......@@ -88,6 +89,7 @@ export function createAntragsteller(): Antragsteller {
geburtsort: faker.address.city(),
nachname: faker.name.lastName(),
vorname: faker.name.firstName(),
firmaName: faker.company.companyName(),
email: faker.internet.email(),
telefon: `+ ${faker.datatype.number(10)}`,
strasse: faker.address.streetName(),
......
......@@ -20,7 +20,7 @@ public class BescheidService {
}
public Stream<Bescheid> findByVorgangId(String vorgangId) {
return sortBescheids(remoteService.findByVorgangId(vorgangId));
return remoteService.findByVorgangId(vorgangId);
}
public Stream<Bescheid> findByVorgangIdSorted(String vorgangId) {
......
......@@ -35,7 +35,7 @@ public interface Vorgang {
enum VorgangStatus {
NEU, ANGENOMMEN, VERWORFEN, IN_BEARBEITUNG, BESCHIEDEN, ABGESCHLOSSEN, WEITERGELEITET, ZU_LOESCHEN;
private Map<String, Set<VorgangStatus>> allowedFollowStatusByRole = new HashMap<>();
private final Map<String, Set<VorgangStatus>> allowedFollowStatusByRole = new HashMap<>();
static {
NEU.allowedFollowStatusByRole.put(UserRole.EINHEITLICHER_ANSPRECHPARTNER, Set.of(WEITERGELEITET, VERWORFEN));
......
......@@ -3,6 +3,7 @@ package de.ozgcloud.alfa.export;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import java.util.Objects;
import java.util.function.Predicate;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.LinkRelation;
......@@ -11,6 +12,7 @@ import org.springframework.stereotype.Component;
import de.ozgcloud.alfa.common.FeatureToggleProperties;
import de.ozgcloud.alfa.common.ModelBuilder;
import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
import de.ozgcloud.alfa.vorgang.VorgangWithEingang;
import lombok.RequiredArgsConstructor;
......@@ -18,6 +20,9 @@ import lombok.RequiredArgsConstructor;
@Component
class ExportVorgangProcessor implements RepresentationModelProcessor<EntityModel<VorgangWithEingang>> {
private final Predicate<VorgangWithEingang> isExportEnabled = vorgang -> isExportEnabled();
private static final Predicate<VorgangWithEingang> IS_VORGANG_ABGESCHLOSSEN = vorgang -> vorgang.getStatus() == VorgangStatus.ABGESCHLOSSEN;
static final LinkRelation REL_EXPORT = LinkRelation.of("export");
private final FeatureToggleProperties featureToggleProperties;
......@@ -31,9 +36,12 @@ class ExportVorgangProcessor implements RepresentationModelProcessor<EntityModel
}
return ModelBuilder.fromModel(model)
.ifMatch(featureToggleProperties::isVorgangExport)
.ifMatch(isExportEnabled.and(IS_VORGANG_ABGESCHLOSSEN))
.addLink(linkTo(methodOn(ExportVorgangController.class).exportToXdomea(vorgang.getId())).withRel(REL_EXPORT))
.buildModel();
}
private boolean isExportEnabled() {
return featureToggleProperties.isVorgangExport();
}
}
......@@ -8,6 +8,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
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.springframework.hateoas.EntityModel;
......@@ -15,7 +17,9 @@ import org.springframework.hateoas.Link;
import de.ozgcloud.alfa.common.FeatureToggleProperties;
import de.ozgcloud.alfa.common.UserProfileUrlProvider;
import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory;
import de.ozgcloud.alfa.vorgang.VorgangWithEingang;
import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory;
class ExportVorgangProcessorTest {
......@@ -26,7 +30,7 @@ class ExportVorgangProcessorTest {
@Mock
private FeatureToggleProperties featureToggleProperties;
private UserProfileUrlProvider urlProvider = new UserProfileUrlProvider();
private final UserProfileUrlProvider urlProvider = new UserProfileUrlProvider();
@Nested
class TestProcess {
......@@ -41,23 +45,40 @@ class ExportVorgangProcessorTest {
}
@Test
void shouldAddLink() {
void shouldAddLinkWhenExportIsEnabledAndVorgangIsAbgeschlossen() {
when(featureToggleProperties.isVorgangExport()).thenReturn(true);
var vorgang = vorgangInStatus(VorgangStatus.ABGESCHLOSSEN);
var model = processor.process(EntityModel.of(VorgangWithEingangTestFactory.create()));
var model = processor.process(EntityModel.of(vorgang));
assertThat(model.getLink(ExportVorgangProcessor.REL_EXPORT)).isPresent().get().extracting(Link::getHref)
.isEqualTo(ExportVorgangController.PATH + "/" + VorgangHeaderTestFactory.ID);
}
@ParameterizedTest
@EnumSource(mode = EnumSource.Mode.EXCLUDE, names = "ABGESCHLOSSEN")
void shouldNotAddLinkWhenVorgangIsNotAbgeschlossen(VorgangStatus status) {
when(featureToggleProperties.isVorgangExport()).thenReturn(true);
var vorgang = vorgangInStatus(status);
var model = processor.process(EntityModel.of(vorgang));
assertThat(model.getLink(ExportVorgangProcessor.REL_EXPORT)).isEmpty();
}
@Test
void shouldNotAddLink() {
void shouldNotAddLinkWhenExportIsDisabled() {
when(featureToggleProperties.isVorgangExport()).thenReturn(false);
var vorgang = vorgangInStatus(VorgangStatus.ABGESCHLOSSEN);
var model = processor.process(EntityModel.of(VorgangWithEingangTestFactory.create()));
var model = processor.process(EntityModel.of(vorgang));
assertThat(model.getLink(ExportVorgangProcessor.REL_EXPORT)).isEmpty();
}
private VorgangWithEingang vorgangInStatus(VorgangStatus status) {
return VorgangWithEingangTestFactory.createBuilder().status(status).build();
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment