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

Merge pull request 'OZG-5812-download-button-in-status-abgeschlossen' (#640)...

Merge pull request 'OZG-5812-download-button-in-status-abgeschlossen' (#640) from OZG-5812-download-button-in-status-abgeschlossen into master

Reviewed-on: https://git.ozg-sh.de/ozgcloud-app/alfa/pulls/640


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents 8dc5351f 473b8317
No related branches found
No related tags found
No related merge requests found
Showing
with 168 additions and 51 deletions
...@@ -13,7 +13,7 @@ export * from './lib/icons/attachment-icon/attachment-icon.component'; ...@@ -13,7 +13,7 @@ export * from './lib/icons/attachment-icon/attachment-icon.component';
export * from './lib/icons/bescheid-generate-icon/bescheid-generate-icon.component'; export * from './lib/icons/bescheid-generate-icon/bescheid-generate-icon.component';
export * from './lib/icons/bescheid-upload-icon/bescheid-upload-icon.component'; export * from './lib/icons/bescheid-upload-icon/bescheid-upload-icon.component';
export * from './lib/icons/close-icon/close-icon.component'; export * from './lib/icons/close-icon/close-icon.component';
export * from './lib/icons/exclamate-icon/exclamate-icon.component'; export * from './lib/icons/exclamation-icon/exclamation-icon.component';
export * from './lib/icons/file-icon/file-icon.component'; export * from './lib/icons/file-icon/file-icon.component';
export * from './lib/icons/save-icon/save-icon.component'; export * from './lib/icons/save-icon/save-icon.component';
export * from './lib/icons/send-icon/send-icon.component'; export * from './lib/icons/send-icon/send-icon.component';
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ExclamateIconComponent } from '../../icons/exclamate-icon/exclamate-icon.component'; import { ExclamationIconComponent } from '../../icons/exclamation-icon/exclamation-icon.component';
import { ErrorMessageComponent } from './error-message.component'; import { ErrorMessageComponent } from './error-message.component';
describe('ErrorMessageComponent', () => { describe('ErrorMessageComponent', () => {
...@@ -8,7 +8,7 @@ describe('ErrorMessageComponent', () => { ...@@ -8,7 +8,7 @@ describe('ErrorMessageComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [ErrorMessageComponent, ExclamateIconComponent], imports: [ErrorMessageComponent, ExclamationIconComponent],
}).compileComponents(); }).compileComponents();
fixture = TestBed.createComponent(ErrorMessageComponent); fixture = TestBed.createComponent(ErrorMessageComponent);
......
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { ExclamateIconComponent } from '../../icons/exclamate-icon/exclamate-icon.component'; import { ExclamationIconComponent } from '../../icons/exclamation-icon/exclamation-icon.component';
@Component({ @Component({
selector: 'ods-error-message', selector: 'ods-error-message',
standalone: true, standalone: true,
imports: [CommonModule, ExclamateIconComponent], imports: [CommonModule, ExclamationIconComponent],
styles: [':host {@apply flex text-error my-2 text-sm items-center font-medium}'], styles: [':host {@apply flex text-error my-2 text-sm items-center font-medium}'],
template: `<ods-exclamate-icon class="mr-1"></ods-exclamate-icon> template: `<ods-exclamation-icon class="mr-1"></ods-exclamation-icon>
<div class="flex-grow break-all"> <div class="flex-grow break-all">
{{ text }} {{ text }}
<br *ngIf="subText" aria-hidden="true" /> <br *ngIf="subText" aria-hidden="true" />
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ExclamateIconComponent } from './exclamate-icon.component'; import { ExclamationIconComponent } from './exclamation-icon.component';
describe('ExclamateIconComponent', () => { describe('ExclamationIconComponent', () => {
let component: ExclamateIconComponent; let component: ExclamationIconComponent;
let fixture: ComponentFixture<ExclamateIconComponent>; let fixture: ComponentFixture<ExclamationIconComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [ExclamateIconComponent], imports: [ExclamationIconComponent],
}).compileComponents(); }).compileComponents();
fixture = TestBed.createComponent(ExclamateIconComponent); fixture = TestBed.createComponent(ExclamationIconComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });
......
...@@ -5,7 +5,7 @@ import { twMerge } from 'tailwind-merge'; ...@@ -5,7 +5,7 @@ import { twMerge } from 'tailwind-merge';
import { IconVariants, iconVariants } from '../IconClasses'; import { IconVariants, iconVariants } from '../IconClasses';
@Component({ @Component({
selector: 'ods-exclamate-icon', selector: 'ods-exclamation-icon',
standalone: true, standalone: true,
imports: [NgClass], imports: [NgClass],
template: `<svg template: `<svg
...@@ -20,7 +20,7 @@ import { IconVariants, iconVariants } from '../IconClasses'; ...@@ -20,7 +20,7 @@ import { IconVariants, iconVariants } from '../IconClasses';
/> />
</svg>`, </svg>`,
}) })
export class ExclamateIconComponent { export class ExclamationIconComponent {
@Input() size: IconVariants['size'] = 'medium'; @Input() size: IconVariants['size'] = 'medium';
@Input() class: string = undefined; @Input() class: string = undefined;
......
import type { Meta, StoryObj } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular';
import { ExclamateIconComponent } from './exclamate-icon.component'; import { ExclamationIconComponent } from './exclamation-icon.component';
const meta: Meta<ExclamateIconComponent> = { const meta: Meta<ExclamationIconComponent> = {
title: 'Icons/Exclamate icon', title: 'Icons/Exclamation icon',
component: ExclamateIconComponent, component: ExclamationIconComponent,
excludeStories: /.*Data$/, excludeStories: /.*Data$/,
tags: ['autodocs'], tags: ['autodocs'],
}; };
export default meta; export default meta;
type Story = StoryObj<ExclamateIconComponent>; type Story = StoryObj<ExclamationIconComponent>;
export const Default: Story = { export const Default: Story = {
args: { size: 'medium' }, args: { size: 'medium' },
......
...@@ -74,6 +74,19 @@ function getDebugElementFromFixtureByDirective( ...@@ -74,6 +74,19 @@ function getDebugElementFromFixtureByDirective(
return fixture.debugElement.query(By.directive(query)); return fixture.debugElement.query(By.directive(query));
} }
function getAllDebugElementsFromFixtureByDirective(
fixture: ComponentFixture<any>,
query: Type<any>,
): DebugElement[] {
return fixture.debugElement.queryAll(By.directive(query));
}
export function getMockComponent<T>(fixture: ComponentFixture<unknown>, component: Type<T>): T { export function getMockComponent<T>(fixture: ComponentFixture<unknown>, component: Type<T>): T {
return <T>getDebugElementFromFixtureByDirective(fixture, component).componentInstance; return <T>getDebugElementFromFixtureByDirective(fixture, component).componentInstance;
} }
export function getMockComponents<T>(fixture: ComponentFixture<unknown>, component: Type<T>): T[] {
return getAllDebugElementsFromFixtureByDirective(fixture, component).map(
(debugElement) => <T>debugElement.componentInstance,
);
}
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
</button> </button>
<ozgcloud-menu #moreMenu data-test-id="more-menu"> <ozgcloud-menu #moreMenu data-test-id="more-menu">
<ozgcloud-menu-item <ozgcloud-menu-item
*ngIf="vorgangWithEingang | hasLink: vorgangWithEingangLinkRel.EXPORT"
data-test-id="vorgang-exportieren-button" data-test-id="vorgang-exportieren-button"
headline="Vorgang exportieren" headline="Vorgang exportieren"
text="Alle Informationen und Anhänge des Vorgangs zur Archivierung im DMS." text="Alle Informationen und Anhänge des Vorgangs zur Archivierung im DMS."
......
...@@ -2,6 +2,7 @@ import { ...@@ -2,6 +2,7 @@ import {
getElementFromDomRoot, getElementFromDomRoot,
getElementFromFixture, getElementFromFixture,
getMockComponent, getMockComponent,
getMockComponents,
} from '@alfa-client/test-utils'; } from '@alfa-client/test-utils';
import { MenuItemComponent, OzgcloudIconComponent, UiModule } from '@alfa-client/ui'; import { MenuItemComponent, OzgcloudIconComponent, UiModule } from '@alfa-client/ui';
import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
...@@ -122,7 +123,7 @@ describe('VorgangDetailMoreMenuComponent', () => { ...@@ -122,7 +123,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should be visible if link exists', () => { it('should be visible', () => {
component.vorgangWithEingang = vorgangWithEingang; component.vorgangWithEingang = vorgangWithEingang;
fixture.detectChanges(); fixture.detectChanges();
getElementFromFixture(fixture, moreMenuButton).click(); getElementFromFixture(fixture, moreMenuButton).click();
...@@ -132,16 +133,6 @@ describe('VorgangDetailMoreMenuComponent', () => { ...@@ -132,16 +133,6 @@ describe('VorgangDetailMoreMenuComponent', () => {
expect(element).toBeInTheDocument(); 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', () => { describe('input property', () => {
beforeEach(() => { beforeEach(() => {
component.vorgangWithEingang = vorgangWithEingang; component.vorgangWithEingang = vorgangWithEingang;
...@@ -236,7 +227,7 @@ describe('VorgangDetailMoreMenuComponent', () => { ...@@ -236,7 +227,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains headline', () => { it('should contains headline', () => {
getElementFromFixture(fixture, moreMenuButton).click(); 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'); expect(menuItem.headline).toBe('Vorgang automatisiert vorprüfen');
}); });
...@@ -244,7 +235,7 @@ describe('VorgangDetailMoreMenuComponent', () => { ...@@ -244,7 +235,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains text', () => { it('should contains text', () => {
getElementFromFixture(fixture, moreMenuButton).click(); getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent); const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.text).toBe( expect(menuItem.text).toBe(
'Eine Vorprüfung wird durchgeführt. Das Ergebnis wird als Kommentar hinzugefügt.', 'Eine Vorprüfung wird durchgeführt. Das Ergebnis wird als Kommentar hinzugefügt.',
...@@ -254,7 +245,7 @@ describe('VorgangDetailMoreMenuComponent', () => { ...@@ -254,7 +245,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains icon', () => { it('should contains icon', () => {
getElementFromFixture(fixture, moreMenuButton).click(); getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent); const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.icon).toBe('vorgang_vorpruefen'); expect(menuItem.icon).toBe('vorgang_vorpruefen');
}); });
...@@ -262,7 +253,7 @@ describe('VorgangDetailMoreMenuComponent', () => { ...@@ -262,7 +253,7 @@ describe('VorgangDetailMoreMenuComponent', () => {
it('should contains iconSizeBig', () => { it('should contains iconSizeBig', () => {
getElementFromFixture(fixture, moreMenuButton).click(); getElementFromFixture(fixture, moreMenuButton).click();
const menuItem: MenuItemComponent = getMockComponent(fixture, MenuItemComponent); const menuItem: MenuItemComponent = getMockComponents(fixture, MenuItemComponent)[1];
expect(menuItem.iconSizeBig).toBeTruthy(); expect(menuItem.iconSizeBig).toBeTruthy();
}); });
......
<ng-container>
<ozgcloud-button-with-spinner <ozgcloud-button-with-spinner
*ngIf="canExport"
dataTestId="export-vorgang" dataTestId="export-vorgang"
[showSpinner]="(exportStateResource$ | async)?.loading" [showSpinner]="(exportStateResource$ | async)?.loading"
(clickEmitter)="export()" (clickEmitter)="export()"
text="Herunterladen" text="Herunterladen"
icon="save_alt" 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 { 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 { 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 { MockComponent } from 'ng-mocks';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { VorgangExportContainerComponent } from './vorgang-export-container.component'; import { VorgangExportContainerComponent } from './vorgang-export-container.component';
...@@ -15,12 +18,14 @@ describe('VorgangExportContainerComponent', () => { ...@@ -15,12 +18,14 @@ describe('VorgangExportContainerComponent', () => {
const vorgangService = mock(VorgangService); const vorgangService = mock(VorgangService);
const buttonWithSpinner: string = '[dataTestId="export-vorgang"]'; const buttonWithSpinner: string = '[dataTestId="export-vorgang"]';
const cannotExportMessageDataTestId: string = getDataTestIdOf('cannot-export-vorgang');
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ declarations: [
VorgangExportContainerComponent, VorgangExportContainerComponent,
MockComponent(OzgcloudButtonWithSpinnerComponent), MockComponent(OzgcloudButtonWithSpinnerComponent),
MockComponent(ExclamationIconComponent),
], ],
providers: [ providers: [
{ {
...@@ -60,9 +65,49 @@ describe('VorgangExportContainerComponent', () => { ...@@ -60,9 +65,49 @@ describe('VorgangExportContainerComponent', () => {
describe('export', () => { describe('export', () => {
it('should call vorgangService.export', () => { it('should call vorgangService.export', () => {
dispatchEventFromFixture(fixture, buttonWithSpinner, 'clickEmitter'); component.export();
expect(vorgangService.export).toHaveBeenCalled(); 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 { 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'; import { Observable, tap } from 'rxjs';
@Component({ @Component({
...@@ -9,11 +14,14 @@ import { Observable, tap } from 'rxjs'; ...@@ -9,11 +14,14 @@ import { Observable, tap } from 'rxjs';
styleUrls: ['./vorgang-export-container.component.scss'], styleUrls: ['./vorgang-export-container.component.scss'],
}) })
export class VorgangExportContainerComponent implements OnInit { 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(); @Output() public closeMenu: EventEmitter<void> = new EventEmitter();
public exportStateResource$: Observable<StateResource<boolean>>; public exportStateResource$: Observable<StateResource<boolean>>;
public canExport: boolean = false;
constructor(private vorgangService: VorgangService) {} constructor(private vorgangService: VorgangService) {}
......
...@@ -57,6 +57,7 @@ import { ...@@ -57,6 +57,7 @@ import {
ButtonComponent, ButtonComponent,
CloseIconComponent, CloseIconComponent,
ErrorMessageComponent, ErrorMessageComponent,
ExclamationIconComponent,
RadioButtonCardComponent, RadioButtonCardComponent,
SaveIconComponent, SaveIconComponent,
SendIconComponent, SendIconComponent,
...@@ -146,6 +147,7 @@ const routes: Routes = [ ...@@ -146,6 +147,7 @@ const routes: Routes = [
ButtonComponent, ButtonComponent,
ButtonCardComponent, ButtonCardComponent,
CloseIconComponent, CloseIconComponent,
ExclamationIconComponent,
SaveIconComponent, SaveIconComponent,
SendIconComponent, SendIconComponent,
StampIconComponent, StampIconComponent,
......
...@@ -35,7 +35,7 @@ public interface Vorgang { ...@@ -35,7 +35,7 @@ public interface Vorgang {
enum VorgangStatus { enum VorgangStatus {
NEU, ANGENOMMEN, VERWORFEN, IN_BEARBEITUNG, BESCHIEDEN, ABGESCHLOSSEN, WEITERGELEITET, ZU_LOESCHEN; 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 { static {
NEU.allowedFollowStatusByRole.put(UserRole.EINHEITLICHER_ANSPRECHPARTNER, Set.of(WEITERGELEITET, VERWORFEN)); NEU.allowedFollowStatusByRole.put(UserRole.EINHEITLICHER_ANSPRECHPARTNER, Set.of(WEITERGELEITET, VERWORFEN));
......
...@@ -3,6 +3,7 @@ package de.ozgcloud.alfa.export; ...@@ -3,6 +3,7 @@ package de.ozgcloud.alfa.export;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import java.util.Objects; import java.util.Objects;
import java.util.function.Predicate;
import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.LinkRelation;
...@@ -11,6 +12,7 @@ import org.springframework.stereotype.Component; ...@@ -11,6 +12,7 @@ import org.springframework.stereotype.Component;
import de.ozgcloud.alfa.common.FeatureToggleProperties; import de.ozgcloud.alfa.common.FeatureToggleProperties;
import de.ozgcloud.alfa.common.ModelBuilder; import de.ozgcloud.alfa.common.ModelBuilder;
import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
import de.ozgcloud.alfa.vorgang.VorgangWithEingang; import de.ozgcloud.alfa.vorgang.VorgangWithEingang;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
...@@ -18,6 +20,9 @@ import lombok.RequiredArgsConstructor; ...@@ -18,6 +20,9 @@ import lombok.RequiredArgsConstructor;
@Component @Component
class ExportVorgangProcessor implements RepresentationModelProcessor<EntityModel<VorgangWithEingang>> { 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"); static final LinkRelation REL_EXPORT = LinkRelation.of("export");
private final FeatureToggleProperties featureToggleProperties; private final FeatureToggleProperties featureToggleProperties;
...@@ -31,9 +36,12 @@ class ExportVorgangProcessor implements RepresentationModelProcessor<EntityModel ...@@ -31,9 +36,12 @@ class ExportVorgangProcessor implements RepresentationModelProcessor<EntityModel
} }
return ModelBuilder.fromModel(model) return ModelBuilder.fromModel(model)
.ifMatch(featureToggleProperties::isVorgangExport) .ifMatch(isExportEnabled.and(IS_VORGANG_ABGESCHLOSSEN))
.addLink(linkTo(methodOn(ExportVorgangController.class).exportToXdomea(vorgang.getId())).withRel(REL_EXPORT)) .addLink(linkTo(methodOn(ExportVorgangController.class).exportToXdomea(vorgang.getId())).withRel(REL_EXPORT))
.buildModel(); .buildModel();
}
private boolean isExportEnabled() {
return featureToggleProperties.isVorgangExport();
} }
} }
...@@ -8,6 +8,8 @@ import org.junit.jupiter.api.BeforeEach; ...@@ -8,6 +8,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; 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.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.EntityModel;
...@@ -15,7 +17,9 @@ import org.springframework.hateoas.Link; ...@@ -15,7 +17,9 @@ import org.springframework.hateoas.Link;
import de.ozgcloud.alfa.common.FeatureToggleProperties; import de.ozgcloud.alfa.common.FeatureToggleProperties;
import de.ozgcloud.alfa.common.UserProfileUrlProvider; import de.ozgcloud.alfa.common.UserProfileUrlProvider;
import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus;
import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory;
import de.ozgcloud.alfa.vorgang.VorgangWithEingang;
import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory;
class ExportVorgangProcessorTest { class ExportVorgangProcessorTest {
...@@ -26,7 +30,7 @@ class ExportVorgangProcessorTest { ...@@ -26,7 +30,7 @@ class ExportVorgangProcessorTest {
@Mock @Mock
private FeatureToggleProperties featureToggleProperties; private FeatureToggleProperties featureToggleProperties;
private UserProfileUrlProvider urlProvider = new UserProfileUrlProvider(); private final UserProfileUrlProvider urlProvider = new UserProfileUrlProvider();
@Nested @Nested
class TestProcess { class TestProcess {
...@@ -41,23 +45,40 @@ class ExportVorgangProcessorTest { ...@@ -41,23 +45,40 @@ class ExportVorgangProcessorTest {
} }
@Test @Test
void shouldAddLink() { void shouldAddLinkWhenExportIsEnabledAndVorgangIsAbgeschlossen() {
when(featureToggleProperties.isVorgangExport()).thenReturn(true); 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) assertThat(model.getLink(ExportVorgangProcessor.REL_EXPORT)).isPresent().get().extracting(Link::getHref)
.isEqualTo(ExportVorgangController.PATH + "/" + VorgangHeaderTestFactory.ID); .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 @Test
void shouldNotAddLink() { void shouldNotAddLinkWhenExportIsDisabled() {
when(featureToggleProperties.isVorgangExport()).thenReturn(false); 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(); 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