diff --git a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts index 8ebcdfe95dd85b0788e1848725b2ac353450099d..474b719fef02f95377505bb0d34c85df693b46ae 100644 --- a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts @@ -1,10 +1,8 @@ -export class PostfachE2EComponent { - private readonly benutzerTabelle: string = ''; - private readonly benutzerHinzufuegenButton: string = ''; +import { exist } from '../../support/cypress.util'; - public getUserTable(): any { - return cy.getTestElement(this.benutzerTabelle); - } +export class BenutzerE2EComponent { + private readonly benutzerHinzufuegenButton: string = 'add-user-button'; + private readonly userEntry: string = 'user-entry-'; public getHinzufuegenButton(): Cypress.Chainable<Element> { return cy.getTestElement(this.benutzerHinzufuegenButton); @@ -14,5 +12,14 @@ export class PostfachE2EComponent { this.getHinzufuegenButton().click(); } - public tableContains(compare: string): void {} + public getUserEntry(user: string): Cypress.Chainable<Element> { + user = this.userEntry + user; + return cy.getTestElement(user); + } + + public stringExistsInUserEntry(phrase: string, user: string): void { + this.getUserEntry(user).within(() => { + exist(cy.contains(phrase)); + }); + } } diff --git a/alfa-client/apps/admin-e2e/src/components/postfach/postfach.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/postfach/postfach.e2e.component.ts index ee1c8dfa6b0f77f723d0ce4a5dacd699e816fff8..c0b20783ba77f5247d66f50e4c1b21cab2c4271e 100644 --- a/alfa-client/apps/admin-e2e/src/components/postfach/postfach.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/postfach/postfach.e2e.component.ts @@ -24,7 +24,7 @@ export class PostfachE2EComponent { this.getSaveButton().click(); } - public signatureContains(compare: string): void { + public signatureIs(compare: string): void { haveValue(this.getSignaturText(), compare); } diff --git a/alfa-client/apps/admin-e2e/src/components/user-profile/current-user-profile.component.e2e.ts b/alfa-client/apps/admin-e2e/src/components/user-profile/current-user-profile.component.e2e.ts index cec3ba5cd2928c558706cab247d47efcebff6e4b..8456a21b82e3976f16f597e35080c00910d8f7b0 100644 --- a/alfa-client/apps/admin-e2e/src/components/user-profile/current-user-profile.component.e2e.ts +++ b/alfa-client/apps/admin-e2e/src/components/user-profile/current-user-profile.component.e2e.ts @@ -1,7 +1,7 @@ import { UserProfileE2EComponent } from './user-profile.component.e2e'; export class CurrentUserProfileE2EComponent { - private readonly locatorUserIconButton: string = 'popup-button'; + private readonly locatorUserIconButton: string = 'popup-button-content'; private readonly locatorLogoutButton: string = 'popup-logout-button'; private readonly locatorRoot: string = 'current-user'; diff --git a/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts index fe3c7a872af5c83ece40d73e3160a6953df0795d..45b22031b07206ebfc1b7a5ce62c288c99f62e95 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts @@ -1,30 +1,40 @@ -import { HeaderE2EComponent } from '../../page-objects/header.po'; +import { BenutzerE2EComponent } from '../../components/benutzer/benutzer.e2e.component'; import { MainPage } from '../../page-objects/main.po'; import { exist } from '../../support/cypress.util'; import { loginAsAriane } from '../../support/user-util'; const mainPage: MainPage = new MainPage(); -const header: HeaderE2EComponent = mainPage.getHeader(); +const benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); +const role1: string = 'VERWALTUNG_USER'; +const role2: string = 'VERWALTUNG_LOESCHEN'; +const role3: string = 'VERWALTUNG_POSTSTELLE'; +const orga1: string = 'Ordnungsamt'; +const orga2: string = 'Landesamt für Denkmalpflege'; +const orga3: string = 'Wirtschaftsförderung'; +const orga_none: string = 'keine zuständige Stelle zugewiesen'; +const mail1: string = 'peter.von.der.post@ozg-sh.de'; describe('Benutzer und Rollen', () => { before(() => { loginAsAriane(); }); - it('should display logo', () => { - // waitForSpinnerToDisappear(); + it('should open Benutzer tab and show Hinzufuegen button', () => { + mainPage.clickBenutzerTab(); - exist(header.getLogo()); + exist(benutzerPage.getHinzufuegenButton()); }); - it('should show Benutzer tab', () => { - // waitForSpinnerToDisappear(); - //klick auf Benutzer tab - //Benutzer hinzufügen Button ist sichtbar - //Tabelle ist sichtbar - }); - - it('should show existing users in table', () => { - //Inhalt der Tabelle kontrollieren + it('should show users and attributes in table', () => { + exist(benutzerPage.getUserEntry('ariane')); + benutzerPage.stringExistsInUserEntry(role1, 'dorothea'); + benutzerPage.stringExistsInUserEntry(orga1, 'ludwig'); + benutzerPage.stringExistsInUserEntry(role1, 'zelda'); + benutzerPage.stringExistsInUserEntry(role2, 'zelda'); + benutzerPage.stringExistsInUserEntry(orga2, 'zelda'); + benutzerPage.stringExistsInUserEntry(orga3, 'zelda'); + benutzerPage.stringExistsInUserEntry(orga_none, 'adelheit'); + benutzerPage.stringExistsInUserEntry(mail1, 'peter'); + benutzerPage.stringExistsInUserEntry(role3, 'peter'); }); }); diff --git a/alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts index 3b7f65abd5b8b89e6f6caed25bb3ab8af375de56..1a9d07d9cd02a699d33ad6f24e3df8fb94d24d89 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts @@ -15,18 +15,21 @@ describe('Signatur', () => { loginAsAriane(); }); - it('should show Signatur input', () => { + it('should clear current signature0', () => { waitForSpinnerToDisappear(); - exist(postfachTab.getSignaturText()); postfachTab.clearSignatur(); + postfachTab.signatureIs(''); + + postfachTab.saveSignatur(); + }); + + it('should show Signatur input', () => { postfachTab.setSignatur(signaturText); postfachTab.saveSignatur(); - postfachTab.signatureContains(signaturText); + postfachTab.signatureIs(signaturText); postfachTab.scrollbarIsPresent(); - - header.getCurrentUserProfile().logout(); }); }); diff --git a/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts b/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts index 8a32afeb1969570dd1dd3fce5a954aa61797f9ad..14c867e8b121a71674c1ef602bf52b8a5234ed31 100644 --- a/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts +++ b/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts @@ -4,6 +4,8 @@ import { HeaderE2EComponent } from './header.po'; export class MainPage { private readonly buildInfo: BuildInfoE2EComponent = new BuildInfoE2EComponent(); private readonly header: HeaderE2EComponent = new HeaderE2EComponent(); + private readonly benutzerTab: string = 'nav-item-Benutzer__Rollen'; + private readonly postfachTab: string = 'nav-item-Postfach'; public getBuildInfo(): BuildInfoE2EComponent { return this.buildInfo; @@ -12,6 +14,14 @@ export class MainPage { public getHeader(): HeaderE2EComponent { return this.header; } + + public getBenutzerTab(): Cypress.Chainable<Element> { + return cy.getTestElement(this.benutzerTab); + } + + public clickBenutzerTab(): void { + this.getBenutzerTab().click(); + } } export function waitForSpinnerToDisappear(): boolean { diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-more-menu.e2e.components.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-more-menu.e2e.components.ts index cb6f501de05aeae9d46d44ccbcc9c53c37127a28..f064652c55847f3c0afdbb7b7a418653172f9d33 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-more-menu.e2e.components.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-more-menu.e2e.components.ts @@ -38,7 +38,10 @@ export class VorgangMoreMenuE2EComponent { public getButton() { return this.getRoot().getTestElementWithOid(this.buttonLocator); } - // + + public openMenu(): void { + this.getButton().click(); + } public getExportierenItem(): VorgangMoreMenuExportierenItemE2EComponent { return this.exportierenItem; diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-exportieren.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-exportieren.cy.ts similarity index 92% rename from alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-exportieren.cy.ts rename to alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-exportieren.cy.ts index 768acbc0f79869d9a834fd236fcc25232232808e..d11aeed9a9bbb1d38b1c7660d73773ea320084d4 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-exportieren.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-exportieren.cy.ts @@ -76,7 +76,7 @@ describe('Vorgang exportieren', () => { dropCollections(); }); - describe('exportieren', () => { + describe('export file', () => { const menuItem: VorgangMoreMenuExportierenItemE2EComponent = vorgangMoreMenu.getExportierenItem(); @@ -103,7 +103,7 @@ describe('Vorgang exportieren', () => { vorgangMoreMenu.getButton().click({ force: true }); }); - it('should handle snackbar after abschliessen', () => { + it('should show "Herunterladen" button in Abgeschlossen status', () => { vorgangFormularButtons.getAbschliessenButton().click(); waitForSpinnerToDisappear(); @@ -119,19 +119,18 @@ describe('Vorgang exportieren', () => { vorgangMoreMenu.getButton().click({ force: true }); }); - it('should have 1 file in download folder after download', () => { - vorgangMoreMenu.getButton().click(); + it('should delete the downloads folder and click on download', () => { deleteDownloadFolder().then(() => { menuItem.getButton().click({ force: true }); waitForSpinnerToDisappear(); - - countDownloadFiles().then((count) => { - expect(count).to.eq(1); - }); }); }); - it('should close menu after download', () => { + it('should have 1 file in download folder after download and close menu', () => { + countDownloadFiles().then((count) => { + expect(count).to.eq(1); + }); + notExist(menuItem.getRoot()); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..e1ec775a98bb267f6958d829d7163570aed65949 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts @@ -0,0 +1,286 @@ +/* + * 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. + */ +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; +import localeDeExtra from '@angular/common/locales/extra/de'; +import { VorgangBescheidWizardE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-bescheid-wizard.e2e.component'; +import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; +import { + VorgangMoreMenuE2EComponent, + VorgangMoreMenuExportierenItemE2EComponent, +} from 'apps/alfa-e2e/src/components/vorgang/vorgang-more-menu.e2e.components'; +import { CommandE2E, CommandOrderE2E } from 'apps/alfa-e2e/src/model/command'; +import { KommentarE2E } from 'apps/alfa-e2e/src/model/kommentar'; +import { VorgangAttachedItemE2E } from 'apps/alfa-e2e/src/model/vorgang-attached-item'; +import { buildCommand, initCommands } from 'apps/alfa-e2e/src/support/command-util'; +import { TEST_FILE_BESCHEID_VALID } from 'apps/alfa-e2e/src/support/data.util'; +import { uploadFile } from 'apps/alfa-e2e/src/support/file-upload'; +import { + createKommentar, + createKommentarAttachedItem, +} from 'apps/alfa-e2e/src/support/kommentar.util'; +import { initVorgangAttachedItem } from 'apps/alfa-e2e/src/support/vorgang-attached-item-util'; +import { objectIds } from 'apps/alfa-e2e/src/support/vorgang-util'; +import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; +import { VorgangE2E, VorgangStatusE2E } from '../../../model/vorgang'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; +import { VorgangPage } from '../../../page-objects/vorgang.po'; +import { + deleteDownloadFolder, + dropCollections, + getDownloadFileAt, + getDownloadFiles, + unzipDownloadFile, +} from '../../../support/cypress-helper'; +import { exist, notExist } from '../../../support/cypress.util'; +import { parseXml } from '../../../support/tech.util'; +import { getUserDorotheaId, initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; +import { createVorgang, initVorgang } from '../../../support/vorgang-util'; + +registerLocaleData(localeDe, 'de', localeDeExtra); + +describe('check xDomea contents', () => { + const mainPage: MainPage = new MainPage(); + const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); + + const vorgangPage: VorgangPage = new VorgangPage(); + const vorgangMoreMenu: VorgangMoreMenuE2EComponent = vorgangPage.getMoreMenu(); + const menuItem: VorgangMoreMenuExportierenItemE2EComponent = vorgangMoreMenu.getExportierenItem(); + + const xdomeaNamespace: string = 'urn:xoev-de:xdomea:schema:3.0.0'; + //const ns3Namespace: string = 'urn:ozgcloud-de:xdomea:schema:1.0.0'; + + const kommentarText: string = 'Kommentar zum Export'; + let xdomeaFile: string; + + const vorgangExportieren: VorgangE2E = { + ...createVorgang(), + status: VorgangStatusE2E.IN_BEARBEITUNG, + name: 'DoExportieren', + }; + + const assignUserCommand: CommandE2E = { + ...buildCommand( + CommandOrderE2E.ASSIGN_USER, + vorgangExportieren._id.$oid, + vorgangExportieren._id.$oid, + ), + bodyObject: { assignedTo: getUserDorotheaId() }, + finishedAt: { $date: '2024-06-20T07:25:30.000Z' }, + }; + + const changeStatusCommand: CommandE2E = { + ...buildCommand( + CommandOrderE2E.VORGANG_WIEDEREROEFFNEN, + vorgangExportieren._id.$oid, + + vorgangExportieren._id.$oid, + ), + order: CommandOrderE2E.VORGANG_WIEDEREROEFFNEN, + finishedAt: { $date: '2024-06-18T07:25:30.000Z' }, + }; + + const setAktenzeichenCommand: CommandE2E = { + ...buildCommand( + CommandOrderE2E.SET_AKTENZEICHEN, + vorgangExportieren._id.$oid, + vorgangExportieren._id.$oid, + ), + order: CommandOrderE2E.SET_AKTENZEICHEN, + bodyObject: { aktenzeichen: 'AKT_ENZ_EIC_HEN1' }, + finishedAt: { $date: '2024-06-19T07:25:30.000Z' }, + }; + + const kommentar: KommentarE2E = { + ...createKommentar(), + text: kommentarText, + }; + const kommentarAttachedItem: VorgangAttachedItemE2E = { + ...createKommentarAttachedItem(objectIds[1], vorgangExportieren._id.$oid), + item: kommentar, + }; + + const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = + vorgangPage.getFormularButtons(); + + const bescheidWizard: VorgangBescheidWizardE2EComponent = vorgangPage.getBescheidWizard(); + + before(() => { + initVorgang(vorgangExportieren); + initCommands([assignUserCommand, changeStatusCommand, setAktenzeichenCommand]); + initVorgangAttachedItem([kommentarAttachedItem]); + initUsermanagerUsers(); + + loginAsSabine(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }); + + after(() => { + dropCollections(); + }); + + describe('create Bescheid, export and unzip file', () => { + it('should create a Bescheid', () => { + vorgangList.getListItem(vorgangExportieren.name).getRoot().click(); + vorgangFormularButtons.getBescheidenButton().click(); + bescheidWizard.weiter(); + uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); + notExist(bescheidWizard.getBescheidUploadSpinner()); + bescheidWizard.weiter(); + bescheidWizard.getSendButton().click(); + waitForSpinnerToDisappear(); + vorgangFormularButtons.getAbschliessenButton().click(); + }); + + it('should download and unzip the xdomea file', () => { + waitForSpinnerToDisappear(); + openXdomeaFile(); + }); + + it('should read the xdomea content', () => { + readXdomeaFile(); + }); + }); + + describe('check contents of xdomea file', () => { + it('should contain entries for AnwendungsspezifischeErweiterung', () => { + const xmlMap: Map<XmlTypePosition, string> = new Map<XmlTypePosition, string>(); + xmlMap.set({ type: 'Kennung', position: 0 }, 'IDOZGCloud1234567'); + xmlMap.set({ type: 'Name', position: 6 }, 'Anwendungsspezifische Erweiterung OZGCloud Basis'); + xmlMap.set({ type: 'Wert', position: 0 }, '2021-02-11T17:17:28Z'); + xmlMap.set({ type: 'Wert', position: 1 }, 'Testermann'); + xmlMap.set({ type: 'Wert', position: 2 }, 'Max'); + xmlMap.set({ type: 'Wert', position: 3 }, '1995-03-21'); + xmlMap.set({ type: 'Wert', position: 4 }, '66X00'); + compareXmlEntry(xdomeaFile, xmlMap); + }); + + it('should contain change of Vorgang Status', () => { + const xmlMap: Map<XmlTypePosition, string> = new Map<XmlTypePosition, string>(); + xmlMap.set({ type: 'MetadatumNeuerWert', position: 0 }, 'In Bearbeitung'); + xmlMap.set({ type: 'DatumUhrzeit', position: 0 }, '2024-06-18T07:25:30.000Z'); + xmlMap.set({ type: 'Aktion', position: 0 }, CommandOrderE2E.VORGANG_WIEDEREROEFFNEN); + compareXmlEntry(xdomeaFile, xmlMap); + }); + + it('should contain change of Aktenzeichen', () => { + const xmlMap: Map<XmlTypePosition, string> = new Map<XmlTypePosition, string>(); + xmlMap.set({ type: 'MetadatumNeuerWert', position: 3 }, 'AKT_ENZ_EIC_HEN1'); + xmlMap.set({ type: 'DatumUhrzeit', position: 3 }, '2024-06-19T07:25:30.000Z'); + xmlMap.set({ type: 'Aktion', position: 3 }, 'SET_AKTENZEICHEN'); + compareXmlEntry(xdomeaFile, xmlMap); + }); + + it('should contain change of Bearbeiter', () => { + const xmlMap: Map<XmlTypePosition, string> = new Map<XmlTypePosition, string>(); + xmlMap.set({ type: 'MetadatumNeuerWert', position: 4 }, 'Dorothea Doe; 9030229'); + xmlMap.set({ type: 'DatumUhrzeit', position: 4 }, '2024-06-20T07:25:30.000Z'); + xmlMap.set({ type: 'Aktion', position: 4 }, 'ASSIGN_USER'); + compareXmlEntry(xdomeaFile, xmlMap); + }); + + it('should contain creation of Kommentar', () => { + const xmlMap: Map<XmlTypePosition, string> = new Map<XmlTypePosition, string>(); + xmlMap.set({ type: 'Typ', position: 0 }, 'Notiz'); + xmlMap.set({ type: 'Akteur', position: 5 }, 'Sabine Sach; 9030229'); + xmlMap.set({ type: 'DatumUhrzeit', position: 5 }, '2024-01-10T12:57:35.000Z'); + xmlMap.set({ type: 'Aktion', position: 5 }, 'CREATE_KOMMENTAR'); + compareXmlEntry(xdomeaFile, xmlMap); + }); + + it('should contain Bescheid info', () => { + const xmlMap: Map<XmlTypePosition, string> = new Map<XmlTypePosition, string>(); + xmlMap.set({ type: 'Typ', position: 2 }, 'Bescheid'); + xmlMap.set({ type: 'Akteur', position: 7 }, 'Sabine Sach; 9030229'); + xmlMap.set({ type: 'Aktion', position: 7 }, 'Bescheid an Antragsteller gesendet'); + compareXmlEntry(xdomeaFile, xmlMap); + }); + }); + + function openXdomeaFile(): void { + vorgangMoreMenu.openMenu(); + deleteDownloadFolder().then(() => { + menuItem.getButton().click({ force: true }); + waitForSpinnerToDisappear(); + cy.wait(1000); + getDownloadFiles().then((files) => { + unzipDownloadFile(files[0]); + }); + }); + } + + //TODO: Funktionen für NS3-Tag schreiben / anpassen + function getXdomeaNamespace(content: string, tagName: string, position: number): string { + return getXMLFromTagAtPosition(xdomeaNamespace, content, tagName, position); + } + + function getXMLFromTagAtPosition( + namespaceURI: string, + content: string, + tagName: string, + position: number, + ) { + const xmlDoc = parseXml(content); + return xmlDoc.getElementsByTagNameNS(namespaceURI, tagName)[position].textContent; + } + + function readXdomeaFile(): void { + findFirstDownloadFileWithString('Abgabe.0401.xml').then((xmlFile) => { + getDownloadFileAt(xmlFile).then((content) => { + xdomeaFile = content; + }); + }); + } + + function findFirstDownloadFileWithString(searchString: string): Cypress.Chainable<number> { + return getDownloadFiles().then((files) => { + const targetFiles = files.filter((file) => { + return file.toLowerCase().includes(searchString.toLowerCase()); + }); + + if (targetFiles.length === 0) { + throw new Error(`No files containing "${searchString}" found.`); + } + + const targetFileName = targetFiles[0]; + const position = files.indexOf(targetFileName); + return position; + }); + } + + function compareXmlEntry(xDomeaFile: string, xmlMap: Map<XmlTypePosition, string>) { + xmlMap.forEach((expectedValue, xmlTypePosition) => { + expect( + getXdomeaNamespace(xDomeaFile, xmlTypePosition.type, xmlTypePosition.position), + ).to.equal(expectedValue); + }); + } + + interface XmlTypePosition { + type: string; + position: number; + } +}); diff --git a/alfa-client/apps/alfa-e2e/src/model/command.ts b/alfa-client/apps/alfa-e2e/src/model/command.ts index acd160995e1bd16bc44116bd41f0e0977cb05e0c..b4ed055ac0fe2f4f2b54d302bff199a82813d437 100644 --- a/alfa-client/apps/alfa-e2e/src/model/command.ts +++ b/alfa-client/apps/alfa-e2e/src/model/command.ts @@ -34,7 +34,9 @@ export enum CommandOrderE2E { RESEND_POSTFACH_NACHRICHT = 'RESEND_POSTFACH_MAIL', SEND_POSTFACH_MAIL = 'SEND_POSTFACH_MAIL', SEND_POSTFACH_NACHRICHT = 'SEND_POSTFACH_NACHRICHT', + SET_AKTENZEICHEN = 'SET_AKTENZEICHEN', UPDATE_ATTACHED_ITEM = 'UPDATE_ATTACHED_ITEM', + VORGANG_WIEDEREROEFFNEN = 'VORGANG_WIEDEREROEFFNEN', } export class CommandE2E { vorgangId: string; diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts index 90c0c0b4058f983b0cb51861d8b632084cb2a8a3..aa30f90a3e2aba7dfd964af16093943324b68d14 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts @@ -192,7 +192,7 @@ export function reload(): void { } export function readFileFromDownloads(fileName: string): Cypress.Chainable<any> { - return cy.readFile(`${DOWNLOAD_FOLDER}/${fileName}`, { timeout: 5000 }); + return cy.readFile(`${DOWNLOAD_FOLDER}/${fileName}`); } export function pressTab(): void { @@ -216,3 +216,7 @@ export function addSmockerMock(mock: SmockerMocks): void { export function resetSmocker(): void { cy.resetSmocker(); } + +export function getDownloadFileAt(filePosition: number): Cypress.Chainable<string> { + return getDownloadFiles().then((files) => readFileFromDownloads(files[filePosition])); +} diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress.util.ts b/alfa-client/apps/alfa-e2e/src/support/cypress.util.ts index 4440874cbfcc512a5b23c9394c60f50f15e07d21..fb946e5df04adf16437a2d71ac9666ed7ce1932e 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress.util.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress.util.ts @@ -26,6 +26,10 @@ import { wait } from './cypress-helper'; //TODO Naming der Methoden geradeziehen +export function beEqual(element: any, text: string): void { + element.should('equal', text); +} + export function containClass(element: any, cssClass: string): void { element.should('have.class', cssClass); } diff --git a/alfa-client/apps/alfa-e2e/src/support/tech.util.ts b/alfa-client/apps/alfa-e2e/src/support/tech.util.ts index 564665623ac9f858891882a163cb1f435694f77e..675bc0457ffeeb7d90dfa98cad59c706dad31965 100644 --- a/alfa-client/apps/alfa-e2e/src/support/tech.util.ts +++ b/alfa-client/apps/alfa-e2e/src/support/tech.util.ts @@ -105,3 +105,9 @@ export function getAdjustedDateEnglish(daysOffset: number): string { const date = add(new Date(), { days: daysOffset }); return format(date, 'yyyy/MM/dd'); } + +const parser = new DOMParser(); + +export function parseXml(fileContent): Document { + return parser.parseFromString(fileContent, 'text/xml'); +} diff --git a/alfa-client/apps/alfa-e2e/src/support/user-util.ts b/alfa-client/apps/alfa-e2e/src/support/user-util.ts index 72b27edd2355cb32742d6c2ac3d7607500c226fa..34d06a712b3944f70b621d4507ca2dfc3b6ca004 100644 --- a/alfa-client/apps/alfa-e2e/src/support/user-util.ts +++ b/alfa-client/apps/alfa-e2e/src/support/user-util.ts @@ -92,6 +92,10 @@ export function getUserSabineId(): string { return getUserManagerUserSabine()._id.$oid; } +export function getUserDorotheaId(): string { + return getUserManagerUserDorothea()._id.$oid; +} + enum DatabaseUser { EMIL = 'user-ea/user_emil.json', ADELHEIT = 'user-main/user_adelheit.json', diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html index 38c6cab182bd292ea1d60227a3d03eef8a7d621e..c177ace12d14e3cd467b795ef256a70f1831d229 100644 --- a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html @@ -7,6 +7,7 @@ href="#" (click)="(false)" class="flex flex-col items-start justify-between gap-6 border-primary-600/50 px-6 py-4 hover:bg-background-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus lg:flex-row" + [attr.data-test-id]="'user-entry-' + user.username" > <div class="flex-1 basis-1/2"> <div class="mb-2 flex flex-wrap items-center gap-3"> diff --git a/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts b/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts index 071f1a03138fae246311d53e97be4819b029127b..bb96f8a56a4024daefb506cf927e2df9fdb9ab9d 100644 --- a/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts +++ b/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts @@ -280,7 +280,7 @@ describe('BinaryFileRepository', () => { }); function buildExpectedRequestOptions(): HttpHeaders { - return new HttpHeaders().set(HttpHeader.ACCEPT, ContentType.APPLICATION_OCTET_STREAM); + return new HttpHeaders().set(HttpHeader.ACCEPT, ContentType.APPLICATION_ZIP); } }); }); diff --git a/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.ts b/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.ts index ef0c1b6762f8ac2177282f36b07d64879f8aac7c..945b8662db1b3076489002a6bdfac68bdcff320e 100644 --- a/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.ts +++ b/alfa-client/libs/binary-file-shared/src/lib/binary-file.repository.ts @@ -104,7 +104,7 @@ export class BinaryFileRepository { buildRequestOptionsForArchive(): GetRequestOptions { let headers = new HttpHeaders(); - headers = headers.set(HttpHeader.ACCEPT, ContentType.APPLICATION_OCTET_STREAM); + headers = headers.set(HttpHeader.ACCEPT, ContentType.APPLICATION_ZIP); return <GetRequestOptions>{ headers, responseType: 'blob' as 'json', observe: 'response' }; } } diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.html index 620fc9b81ed43ea83b7d35f921e67c08ead4450d..f97b38f009433d90a0f84a07482faf148b615b29 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.html +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.html @@ -11,9 +11,9 @@ ></alfa-collaboration-request-form> </ng-container> <ng-template #anfrageErstellenButton> - <div class="flex w-fit gap-3 bg-background-100 p-4 shadow-md"> + <div class="flex w-111 justify-between bg-background-100 p-4 shadow-md"> <ods-external-unit-icon /> - <div class="flex flex-col text-base"> + <div class="flex w-44 flex-col text-base"> <p class="text-primary">Externe Fachstelle</p> <p class="text-text">Private Organisation,</p> <p class="text-text">Verein, Schule</p> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.spec.ts index 2730a808d4a1c6ea1739327acc98995116bdc004..2770d0fb9d618c8e139b9cf4131ec33c9667869c 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.spec.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.spec.ts @@ -103,11 +103,17 @@ describe('ExterneFachstelleContainerComponent', () => { }); describe('hideForm', () => { - it('should call service', () => { + it('should call service to hide form', () => { component.hideForm(); expect(service.hideExterneFachstelleForm).toHaveBeenCalled(); }); + + it.skip('FIXME should call formService to reset values', () => { + component.hideForm(); + + expect(formService.reset).toHaveBeenCalled(); + }); }); describe('showForm', () => { diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.ts index dc1356bc91ebc3e87e22bde2e61e41f7383c53e5..025455d739cbe39f5ac2fa96aa751eb73042c31a 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/externe-fachstelle-container/externe-fachstelle-container.component.ts @@ -33,6 +33,7 @@ export class ExterneFachstelleContainerComponent { public hideForm(): void { this.service.hideExterneFachstelleForm(); + this.formService.reset(); } public showForm(): void { diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.html b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.html index 665224a844d665c2a601f5377df3ebcf1878522b..85b5867ac43b95ec7909eefc849be1aa28f9a0cf 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.html +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.html @@ -11,9 +11,9 @@ ></alfa-collaboration-request-form> </ng-container> <ng-template #anfrageErstellenButton> - <div class="flex w-fit gap-3 bg-background-100 p-4 shadow-md"> + <div class="flex w-111 justify-between bg-background-100 p-4 shadow-md"> <ods-public-administration-icon /> - <div class="flex flex-col text-base"> + <div class="flex w-44 flex-col text-base"> <p class="text-primary">Öffentliche Verwaltung</p> <p class="text-text">Kommune, Amt,</p> <p class="text-text">Ministerium</p> diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.spec.ts index 3e0f934969b5ce2adf719c08b13da4856ae68f7b..db074ea7b2b912cf078df24749c72831b6935ba7 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.spec.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.spec.ts @@ -103,11 +103,17 @@ describe('OrganisationsEinheitContainerComponent', () => { }); describe('hideForm', () => { - it('should call service', () => { + it('should call service to hide form', () => { component.hideForm(); expect(service.hideOrganisationseinheitForm).toHaveBeenCalled(); }); + + it.skip('FIXME should call formService to reset values', () => { + component.hideForm(); + + expect(formService.reset).toHaveBeenCalled(); + }); }); describe('showForm', () => { diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.ts index b35a26b00bc213668e93042d4b7b8a31a3b7dead..4a76dd254321135bd414b66efc13e5c80f276574 100644 --- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.ts +++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-in-vorgang/organisations-einheit-container/organisations-einheit-container.component.ts @@ -33,6 +33,7 @@ export class OrganisationsEinheitContainerComponent implements OnInit, OnDestroy public hideForm(): void { this.service.hideOrganisationseinheitForm(); + this.formService.reset(); } public showForm(): void { diff --git a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts index 72cc13e7708a00114b96193a07e83a855f0c628c..b83a6e167dbaabae7a8a6e4b6595086ff48bde93 100644 --- a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts @@ -1,12 +1,6 @@ import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { EventEmitter } from '@angular/core'; -import { - ComponentFixture, - TestBed, - discardPeriodicTasks, - fakeAsync, - tick, -} from '@angular/core/testing'; +import { ComponentFixture, TestBed, discardPeriodicTasks, fakeAsync, tick } from '@angular/core/testing'; import { Resource } from '@ngxp/rest'; import { Subscription } from 'rxjs'; import { InstantSearchComponent } from './instant-search.component'; @@ -184,16 +178,13 @@ describe('InstantSearchComponent', () => { }); describe('on null or undefined', () => { - it.each([null, undefined])( - 'should not call setSearchResults for %s', - (searchResults: InstantSearchResult<Resource>[]) => { - component.setSearchResults = jest.fn(); + it.each([null, undefined])('should not call setSearchResults for %s', (searchResults: InstantSearchResult<Resource>[]) => { + component.setSearchResults = jest.fn(); - component.searchResults = searchResults; + component.searchResults = searchResults; - expect(component.setSearchResults).not.toHaveBeenCalled(); - }, - ); + expect(component.setSearchResults).not.toHaveBeenCalled(); + }); }); }); @@ -274,11 +265,11 @@ describe('InstantSearchComponent', () => { }); it('should call hideResults', () => { - component.hideResults = jest.fn(); + component.searchClosed.emit = jest.fn(); component.handleEscape(event); - expect(component.hideResults).toHaveBeenCalled(); + expect(component.searchClosed.emit).toHaveBeenCalled(); }); }); @@ -362,17 +353,13 @@ describe('InstantSearchComponent', () => { it('should return text for one result', () => { const result: string = component.buildAriaLiveText(1); - expect(result).toBe( - 'Ein Suchergebnis für Eingabe test. Nutze Pfeiltaste nach unten, um das zu erreichen.', - ); + expect(result).toBe('Ein Suchergebnis für Eingabe test. Nutze Pfeiltaste nach unten, um das zu erreichen.'); }); it('should return text for many results', () => { const result: string = component.buildAriaLiveText(4); - expect(result).toBe( - '4 Suchergebnisse für Eingabe test. Nutze Pfeiltaste nach unten, um diese zu erreichen.', - ); + expect(result).toBe('4 Suchergebnisse für Eingabe test. Nutze Pfeiltaste nach unten, um diese zu erreichen.'); }); it('should return text for no results', () => { @@ -396,14 +383,6 @@ describe('InstantSearchComponent', () => { expect(component.areResultsVisible).toBe(false); }); - - it('should emit searchResultClosed event', () => { - component.searchResultClosed.emit = jest.fn(); - - component.hideResults(); - - expect(component.searchResultClosed.emit).toHaveBeenCalled(); - }); }); describe('onKeydownHandler', () => { diff --git a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts index 1db3186f29f20d234199679ff3cc0c1688729cc8..8b23822f25beea96c9bdf42a52c4eba075c50b9d 100644 --- a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts +++ b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts @@ -15,7 +15,7 @@ import { import { FormControl } from '@angular/forms'; import { Resource } from '@ngxp/rest'; import { isEqual, isUndefined } from 'lodash-es'; -import { Subscription, debounceTime, distinctUntilChanged, filter } from 'rxjs'; +import { Subscription, debounceTime, filter } from 'rxjs'; import { AriaLiveRegionComponent } from '../../aria-live-region/aria-live-region.component'; import { SearchFieldComponent } from '../search-field/search-field.component'; import { SearchResultHeaderComponent } from '../search-result-header/search-result-header.component'; @@ -74,8 +74,8 @@ export class InstantSearchComponent implements OnInit, OnDestroy { } } + @Output() searchClosed: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); @Output() searchResultSelected: EventEmitter<InstantSearchResult<Resource>> = new EventEmitter<InstantSearchResult<Resource>>(); - @Output() searchResultClosed: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); @Output() searchQueryChanged: EventEmitter<InstantSearchQuery> = new EventEmitter<InstantSearchQuery>(); @Output() searchQueryCleared: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); @@ -99,8 +99,8 @@ export class InstantSearchComponent implements OnInit, OnDestroy { this.formControlSubscription = this.control.valueChanges .pipe( debounceTime(InstantSearchComponent.DEBOUNCE_TIME_IN_MILLIS), + filter((value) => Boolean(value)), filter((value: string) => value.length >= this.PREVIEW_SEARCH_STRING_MIN_LENGTH), - distinctUntilChanged(), ) .subscribe((searchBy: string) => { this.searchQueryChanged.emit({ searchBy }); @@ -138,6 +138,7 @@ export class InstantSearchComponent implements OnInit, OnDestroy { handleEscape(e: KeyboardEvent): void { e.preventDefault(); this.hideResults(); + this.searchClosed.emit(); } setFocusOnResultItem(index: number): void { @@ -193,7 +194,6 @@ export class InstantSearchComponent implements OnInit, OnDestroy { hideResults(): void { this.areResultsVisible = false; this.focusedResult = undefined; - this.searchResultClosed.emit(); } isLastItemOrOutOfArray(index: number, arrayLength: number): boolean { diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts index 71b3e7c98f8e23d30f056ef4ad65544794294196..88cde90f95160002d9f799f93bbd318cc6b87195 100644 --- a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts @@ -2,6 +2,7 @@ import { getElementFromFixture, Mock, mock } from '@alfa-client/test-utils'; import { importProvidersFrom } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router, RouterModule } from '@angular/router'; +import { ConvertForDataTestPipe } from 'libs/tech-shared/src/lib/pipe/convert-for-data-test.pipe'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { NavItemComponent } from './nav-item.component'; @@ -13,7 +14,7 @@ describe('NavItemComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [NavItemComponent], + imports: [ConvertForDataTestPipe, NavItemComponent], providers: [ { provide: Router, @@ -38,10 +39,7 @@ describe('NavItemComponent', () => { component.caption = 'Test caption'; fixture.detectChanges(); - const captionElement: HTMLParagraphElement = getElementFromFixture( - fixture, - getDataTestIdOf('link-caption'), - ); + const captionElement: HTMLParagraphElement = getElementFromFixture(fixture, getDataTestIdOf('link-caption')); expect(captionElement.innerHTML).toBe('Test caption'); }); @@ -52,10 +50,7 @@ describe('NavItemComponent', () => { component.to = '/'; fixture.detectChanges(); - const linkElement: HTMLAnchorElement = getElementFromFixture( - fixture, - getDataTestIdOf('link-to-/'), - ); + const linkElement: HTMLAnchorElement = getElementFromFixture(fixture, getDataTestIdOf('link-to-/')); expect(linkElement).toHaveProperty('href'); }); diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts index df3cc837b44933211f471f15420d87d88a95985b..67ecdbddabe3133079b97dc26c2249b62b3f5ce7 100644 --- a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts +++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts @@ -1,3 +1,4 @@ +import { TechSharedModule } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; import { Component, HostBinding, Input } from '@angular/core'; import { RouterLink, RouterLinkActive } from '@angular/router'; @@ -5,17 +6,17 @@ import { RouterLink, RouterLinkActive } from '@angular/router'; @Component({ selector: 'ods-nav-item', standalone: true, - imports: [CommonModule, RouterLink, RouterLinkActive], + imports: [CommonModule, RouterLink, RouterLinkActive, TechSharedModule], template: `<a [routerLink]="to" routerLinkActive="bg-selected-light border-selected" class="flex min-h-8 items-center gap-2 rounded-2xl border border-transparent px-4 py-2 outline-2 outline-offset-2 outline-focus hover:border-primary focus-visible:border-background-200 focus-visible:outline" - [attr.data-test-id]="'link-to-' + to" + [attr.data-test-id]="'link-to-' + to | convertForDataTest" > <ng-content select="[icon]" /> - <p class="text-left text-sm text-text" data-test-id="link-caption">{{ caption }}</p> + <p class="text-left text-sm text-text" [attr.data-test-id]="'nav-item-' + caption | convertForDataTest">{{ caption }}</p> </a>`, }) export class NavItemComponent { diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js index 3d33483b952c991b6d66bbf1170437c787cb80f4..c95f46b8f1d743ae68a353fa87d645f7f36edc6e 100644 --- a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js +++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js @@ -6,10 +6,7 @@ const { join } = require('path'); /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), - ...createGlobPatternsForDependencies(__dirname), - ], + content: [join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), ...createGlobPatternsForDependencies(__dirname)], darkMode: 'class', theme: { extend: { @@ -48,6 +45,9 @@ module.exports = { maxHeight: { 120: '480px', }, + width: { + 111: '444px', + }, colors: { ozgblue: { 50: 'hsl(200, 100%, 96%)', diff --git a/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.spec.ts b/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.spec.ts index 35fd33e57c839f74868240d50a5af8d47773fe79..bff5f0c17ffa7ad22f1de49bd51e1a3bf2729939 100644 --- a/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.spec.ts @@ -27,17 +27,16 @@ import { Resource } from '@ngxp/rest'; import { cold } from 'jest-marbles'; import { createInvalidParam, createProblemDetail } from 'libs/tech-shared/test/error'; import { Observable, of } from 'rxjs'; -import { AbstractFormService } from './formservice.abstract'; - +import { createCommandResource } from '../../../../command-shared/test/command'; import { + StateResource, createEmptyStateResource, createErrorStateResource, createStateResource, - StateResource, } from '../resource/resource.util'; import { InvalidParam, ProblemDetail } from '../tech.model'; +import { AbstractFormService } from './formservice.abstract'; -import { createCommandResource } from '../../../../command-shared/test/command'; import * as ValidationUtil from '../validation/tech.validation.util'; describe('AbstractFormService', () => { @@ -53,8 +52,7 @@ describe('AbstractFormService', () => { describe('submit', () => { describe('with ProblemDetail', () => { - const stateResourceWithError: StateResource<ProblemDetail> = - createErrorStateResource(createProblemDetail()); + const stateResourceWithError: StateResource<ProblemDetail> = createErrorStateResource(createProblemDetail()); beforeEach(() => { TestFormService.SUBMIT_OBSERVABLE = () => of(stateResourceWithError); @@ -76,8 +74,7 @@ describe('AbstractFormService', () => { }); it('should call after submit operator function', (done) => { - const commandStateResource: StateResource<CommandResource> = - createStateResource(createCommandResource()); + const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); const afterSubmit = () => of(commandStateResource); formService.handleResponse = jest.fn(); @@ -88,8 +85,7 @@ describe('AbstractFormService', () => { }); it('should pass through as default after submit', (done) => { - const commandStateResource: StateResource<CommandResource> = - createStateResource(createCommandResource()); + const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); TestFormService.SUBMIT_OBSERVABLE = () => of(commandStateResource); formService.handleResponse = jest.fn(); @@ -145,11 +141,7 @@ describe('AbstractFormService', () => { formService.setErrorByProblemDetail(problemDetail); - expect(setInvalidParamValidationErrorSpy).toHaveBeenCalledWith( - formService.form, - invalidParam, - TestFormService.PATH_PREFIX, - ); + expect(setInvalidParamValidationErrorSpy).toHaveBeenCalledWith(formService.form, invalidParam, TestFormService.PATH_PREFIX); }); }); @@ -162,6 +154,16 @@ describe('AbstractFormService', () => { expect(formService.form.value).toEqual(formValue); }); }); + + describe('reset', () => { + it('should reset form', () => { + formService.form.reset = jest.fn(); + + formService.reset(); + + expect(formService.form.reset).toHaveBeenCalled(); + }); + }); }); class TestFormService extends AbstractFormService { diff --git a/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts b/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts index 4f225d54b0b1d97d031eb854263bee095aeed03f..ddbdfbd28daffd74b6637bd446373730f7111bec 100644 --- a/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts +++ b/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts @@ -45,9 +45,7 @@ export abstract class AbstractFormService<T extends Resource = Resource> { protected abstract initForm(): UntypedFormGroup; - public submit( - afterSubmit: OperatorFunction<StateResource<T>, StateResource<T>> = identity, - ): Observable<StateResource<T>> { + public submit(afterSubmit: OperatorFunction<StateResource<T>, StateResource<T>> = identity): Observable<StateResource<T>> { return this.doSubmit().pipe( afterSubmit, map((result) => this.handleResponse(result)), @@ -100,4 +98,8 @@ export abstract class AbstractFormService<T extends Resource = Resource> { public isPatch(): boolean { return !isNil(this.source); } + + public reset(): void { + this.form.reset(); + } } diff --git a/alfa-client/libs/tech-shared/src/lib/tech.model.ts b/alfa-client/libs/tech-shared/src/lib/tech.model.ts index 869313d09ddd0b5c7703f80ea79f23bf72403e07..da754a64f4682e35b5770d23a7c06840db56551a 100644 --- a/alfa-client/libs/tech-shared/src/lib/tech.model.ts +++ b/alfa-client/libs/tech-shared/src/lib/tech.model.ts @@ -89,6 +89,7 @@ export enum ContentType { IMAGES_ALL = 'images/*', APPLICATION_ALL = 'application/*', APPLICATION_OCTET_STREAM = 'application/octet-stream', + APPLICATION_ZIP = 'application/zip', } export interface GetRequestOptions { diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html index 7252665d682c7686f3ae4b63e4cce1567edf4f9d..6c888f1981e40ff86e638086a34a92d0b6c8c1d1 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html @@ -7,6 +7,6 @@ (searchResultSelected)="selectSearchResult.emit($event.data)" (searchQueryChanged)="search.emit($event.searchBy)" (searchQueryCleared)="clearSearchResult.emit()" - (searchResultClosed)="clearSearchResult.emit()" + (searchClosed)="clearSearchResult.emit()" ></ods-instant-search> </form> diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/attachment/AttachmentByVorgangController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/attachment/AttachmentByVorgangController.java new file mode 100644 index 0000000000000000000000000000000000000000..10b1131c4cf583be35f5e2dd6f3f104763bc84ec --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/attachment/AttachmentByVorgangController.java @@ -0,0 +1,56 @@ +package de.ozgcloud.alfa.attachment; + +import java.io.OutputStream; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.EntityModel; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileModelAssembler; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileService; +import de.ozgcloud.alfa.common.zipdownload.ZipDownloadService; +import de.ozgcloud.alfa.vorgang.VorgangController; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping(AttachmentByVorgangController.PATH) +@RequiredArgsConstructor +public class AttachmentByVorgangController { + static final String PATH = "/api/vorgang/{vorgangId}/attachments"; // NOSONAR + static final String APPLICATION_ZIP_VALUE = "application/zip"; + + private final OzgFileService fileService; + private final ZipDownloadService zipDownloadService; + private final VorgangController vorgangController; + private final BinaryFileModelAssembler modelAssembler; + + @GetMapping + public CollectionModel<EntityModel<OzgFile>> getAllByVorgang(@PathVariable String vorgangId) { + return modelAssembler.toCollectionModel(fileService.getAttachments(vorgangId)); + } + + @GetMapping(produces = APPLICATION_ZIP_VALUE) + public ResponseEntity<StreamingResponseBody> download(@PathVariable String vorgangId) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s", buildZipName(vorgangId))) + .contentType(MediaType.valueOf(APPLICATION_ZIP_VALUE)) + .body(out -> createZipFile(out, vorgangId)); + } + + String buildZipName(String vorgangId) { + return vorgangController.getVorgang(vorgangId).getNummer() + "_Anhaenge.zip"; + } + + void createZipFile(OutputStream out, String vorgangId) { + var ozgFiles = fileService.getAttachments(vorgangId); + zipDownloadService.write(ozgFiles.toList(), out); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/attachment/AttachmentController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/attachment/AttachmentController.java deleted file mode 100644 index 1211543468abb21bc9b39b98408cd8075adc1710..0000000000000000000000000000000000000000 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/attachment/AttachmentController.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - */ -package de.ozgcloud.alfa.attachment; - -import java.io.OutputStream; - -import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.EntityModel; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; - -import de.ozgcloud.alfa.common.binaryfile.BinaryFileModelAssembler; -import de.ozgcloud.alfa.common.file.OzgFile; -import de.ozgcloud.alfa.common.file.OzgFileService; -import de.ozgcloud.alfa.common.zipdownload.ZipDownloadService; -import de.ozgcloud.alfa.vorgang.VorgangController; -import lombok.RequiredArgsConstructor; - -@RestController -@RequestMapping(AttachmentController.PATH) -@RequiredArgsConstructor -public class AttachmentController { - - static final String PATH = "/api/attachments"; // NOSONAR - - static final String PARAM_EINGANG_ID = "eingangId"; - - private final OzgFileService fileService; - private final BinaryFileModelAssembler modelAssembler; - - @GetMapping(params = PARAM_EINGANG_ID) - public CollectionModel<EntityModel<OzgFile>> getAllByEingang(@RequestParam String eingangId) { - return modelAssembler.toCollectionModel(fileService.getAttachmentsByEingang(eingangId)); - } - - @RestController - @RequestMapping(AttachmentsByVorgangController.PATH) - @RequiredArgsConstructor - public static class AttachmentsByVorgangController { - static final String PATH = "/api/vorgang/{vorgangId}/attachments"; // NOSONAR - - private final OzgFileService fileService; - private final ZipDownloadService zipDownloadService; - private final VorgangController vorgangController; - - @GetMapping(params = PARAM_EINGANG_ID, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) - public ResponseEntity<StreamingResponseBody> download(@PathVariable String vorgangId, @RequestParam String eingangId) { - return ResponseEntity.ok() - .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s", buildZipName(vorgangId))) - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(out -> createZipFile(out, eingangId)); - } - - String buildZipName(String vorgangId) { - return vorgangController.getVorgang(vorgangId).getNummer() + "_Anhaenge.zip"; - } - - void createZipFile(OutputStream out, String eingangId) { - var ozgFiles = fileService.getAttachmentsByEingang(eingangId); - zipDownloadService.write(ozgFiles.toList(), out); - } - } - -} \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileRemoteService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileRemoteService.java index 6b1577082e0c2bdc7d53344547265a77ad5e452e..d8c4a4e1d04bd53c9a2b0125a33e5c04da59e3e1 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileRemoteService.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileRemoteService.java @@ -29,7 +29,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import de.ozgcloud.alfa.common.GrpcUtil; -import de.ozgcloud.alfa.common.callcontext.ContextService; import de.ozgcloud.vorgang.grpc.file.FileServiceGrpc.FileServiceBlockingStub; import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest; import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsRequest; @@ -41,33 +40,29 @@ public class OzgFileRemoteService { @GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT) private FileServiceBlockingStub fileServiceStub; @Autowired - private ContextService contextService; - @Autowired private OzgFileMapper fileMapper; - public Stream<OzgFile> getAttachmentsByEingang(String eingangId) { - var response = fileServiceStub.getAttachments(buildGrpcGetAttachmentsRequest(eingangId)); + public Stream<OzgFile> getAttachments(String vorgangId) { + var response = fileServiceStub.getAttachments(buildGrpcGetAttachmentsRequest(vorgangId)); return response.getFileList().stream().map(fileMapper::toFile); } - private GrpcGetAttachmentsRequest buildGrpcGetAttachmentsRequest(String eingangId) { + private GrpcGetAttachmentsRequest buildGrpcGetAttachmentsRequest(String vorgangId) { return GrpcGetAttachmentsRequest.newBuilder() - .setContext(contextService.createCallContext()) - .setEingangId(eingangId) + .setVorgangId(vorgangId) .build(); } - public Stream<OzgFile> getRepresentationsByEingang(String eingangId) { - var response = fileServiceStub.getRepresentations(buildGrpcGetRepresentationsRequest(eingangId)); + public Stream<OzgFile> getRepresentations(String vorgangId) { + var response = fileServiceStub.getRepresentations(buildGrpcGetRepresentationsRequest(vorgangId)); return response.getFileList().stream().map(fileMapper::toFile); } - private GrpcGetRepresentationsRequest buildGrpcGetRepresentationsRequest(String eingangId) { + private GrpcGetRepresentationsRequest buildGrpcGetRepresentationsRequest(String vorgangId) { return GrpcGetRepresentationsRequest.newBuilder() - .setContext(contextService.createCallContext()) - .setEingangId(eingangId) + .setVorgangId(vorgangId) .build(); } } \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileService.java index 63e9bdb12be7eb045d6eb0d3876fd1694ac4ee08..9041fa12dcfd1d8e7cecc99af58a94fa4cbeb6dc 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileService.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/file/OzgFileService.java @@ -34,11 +34,11 @@ public class OzgFileService { @Autowired private OzgFileRemoteService remoteService; - public Stream<OzgFile> getAttachmentsByEingang(String eingangId) { - return remoteService.getAttachmentsByEingang(eingangId); + public Stream<OzgFile> getAttachments(String vorgangId) { + return remoteService.getAttachments(vorgangId); } - public Stream<OzgFile> getRepresentationsByEingang(String eingangId) { - return remoteService.getRepresentationsByEingang(eingangId); + public Stream<OzgFile> getRepresentations(String vorgangId) { + return remoteService.getRepresentations(vorgangId); } } \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/OrganisationsEinheitSettings.java b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/OrganisationsEinheitSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..f5d1f19f53554a619d68368c49e5445c978d8c73 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/OrganisationsEinheitSettings.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024. + * 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. + */ + +package de.ozgcloud.alfa.postfach; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class OrganisationsEinheitSettings { + private String signatur; +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachProperties.java b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachProperties.java index e6d7b0dea5e3fd6e4951c8df5447ab43a45d2a97..a7298837a5211b77bcb970bb82e2912b96466343 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachProperties.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachProperties.java @@ -1,5 +1,27 @@ +/* + * Copyright (c) 2024. + * 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. + */ + package de.ozgcloud.alfa.postfach; +import java.util.Map; + import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Configuration; @@ -21,4 +43,9 @@ public class PostfachProperties { */ private String signatur = ""; + /** + * Settings that are linked to an Organisationseinheit. Configured by administration config server. + */ + private Map<String, OrganisationsEinheitSettings> organisationsEinheitSettings = Map.of(); + } diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachSettingsService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachSettingsService.java index e42fc707246eba12df26de9cb20c31a6f6598262..84ffbf35e89c86ebd5f5f82939f1a6d9fe798256 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachSettingsService.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachSettingsService.java @@ -35,14 +35,15 @@ class PostfachSettingsService { .reply(isReplyToMessageAllowed(vorgang)) .build()) .settings(Settings.builder() - .signatur(getSignatur()) + .signatur(getSignatur(vorgang.getOrganisationseinheitenID())) .build()) .build(); } - String getSignatur() { + String getSignatur(String organisationseinheitenID) { refreshPostfachProperties(); - return postfachProperties.getSignatur(); + var settings = getOrganisationsEinheitSettings(organisationseinheitenID); + return settings.map(OrganisationsEinheitSettings::getSignatur).orElseGet(postfachProperties::getSignatur); } void refreshPostfachProperties() { @@ -71,4 +72,8 @@ class PostfachSettingsService { .findFirst() .orElse(false); } + + Optional<OrganisationsEinheitSettings> getOrganisationsEinheitSettings(final String organisationId) { + return Optional.ofNullable(postfachProperties.getOrganisationsEinheitSettings().get(organisationId)); + } } diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/representation/RepresentationController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/representation/RepresentationByVorgangController.java similarity index 79% rename from alfa-service/src/main/java/de/ozgcloud/alfa/representation/RepresentationController.java rename to alfa-service/src/main/java/de/ozgcloud/alfa/representation/RepresentationByVorgangController.java index 28913930a067740c12c8bf214423b59426f22c54..d7731c004ba71684e7d6a752ec78433b367f8aa6 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/representation/RepresentationController.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/representation/RepresentationByVorgangController.java @@ -26,8 +26,8 @@ package de.ozgcloud.alfa.representation; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import de.ozgcloud.alfa.common.binaryfile.BinaryFileModelAssembler; @@ -36,20 +36,17 @@ import de.ozgcloud.alfa.common.file.OzgFileService; import lombok.RequiredArgsConstructor; @RestController -@RequestMapping(RepresentationController.PATH) +@RequestMapping(RepresentationByVorgangController.PATH) @RequiredArgsConstructor -public class RepresentationController { - - static final String PATH = "/api/representations"; // NOSONAR - - static final String PARAM_EINGANG_ID = "eingangId"; +public class RepresentationByVorgangController { + static final String PATH = "/api/vorgang/{vorgangId}/representations"; // NOSONAR private final OzgFileService fileService; private final BinaryFileModelAssembler modelAssembler; - @GetMapping(params = PARAM_EINGANG_ID) - public CollectionModel<EntityModel<OzgFile>> getAllByEingang(@RequestParam String eingangId) { - return modelAssembler.toCollectionModel(fileService.getRepresentationsByEingang(eingangId)); + @GetMapping + public CollectionModel<EntityModel<OzgFile>> getAll(@PathVariable String vorgangId) { + return modelAssembler.toCollectionModel(fileService.getRepresentations(vorgangId)); } } 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 6b111ac3c55ed436df4b141e6115ba419d599905..68ab090f6a599fa547808abbf62e6ffc43075cf3 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 @@ -36,8 +36,7 @@ import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.server.RepresentationModelProcessor; import org.springframework.stereotype.Component; -import de.ozgcloud.alfa.attachment.AttachmentController; -import de.ozgcloud.alfa.attachment.AttachmentController.AttachmentsByVorgangController; +import de.ozgcloud.alfa.attachment.AttachmentByVorgangController; import de.ozgcloud.alfa.common.ModelBuilder; import de.ozgcloud.alfa.common.command.CommandController.CommandByRelationController; import de.ozgcloud.alfa.common.user.CurrentUserService; @@ -46,7 +45,7 @@ import de.ozgcloud.alfa.common.user.UserRole; import de.ozgcloud.alfa.historie.HistorieController; import de.ozgcloud.alfa.kommentar.KommentarController.KommentarByVorgangController; import de.ozgcloud.alfa.postfach.PostfachMailController; -import de.ozgcloud.alfa.representation.RepresentationController; +import de.ozgcloud.alfa.representation.RepresentationByVorgangController; import de.ozgcloud.alfa.vorgang.VorgangProperties.VorgangProperty; import de.ozgcloud.alfa.vorgang.forwarding.ForwardingController; import lombok.RequiredArgsConstructor; @@ -91,14 +90,13 @@ class VorgangWithEingangProcessor implements RepresentationModelProcessor<Entity return ModelBuilder.fromModel(model) .addLink(linkTo(KommentarByVorgangController.class).slash(vorgang.getId()).slash("kommentars").withRel(REL_KOMMENTARE)) .ifMatch(HAS_ATTACHMENTS) - .addLinks(linkTo(methodOn(AttachmentController.class).getAllByEingang(vorgang.getEingang().getId())) + .addLinks(linkTo(methodOn(AttachmentByVorgangController.class).getAllByVorgang(vorgang.getId())) .withRel(REL_ATTACHMENTS), - linkTo(methodOn(AttachmentsByVorgangController.class).download(vorgang.getId(), vorgang.getEingang().getId())) + linkTo(methodOn(AttachmentByVorgangController.class).download(vorgang.getId())) .withRel(REL_DOWNLOAD_ATTACHMENTS)) .ifMatch(HAS_REPRESENTATIONS) - .addLink(vorgangWithEingang -> linkTo( - methodOn(RepresentationController.class).getAllByEingang(vorgangWithEingang.getEingang().getId())) - .withRel(REL_REPRESENTATIONS)) + .addLink(linkTo(methodOn(RepresentationByVorgangController.class).getAll(vorgang.getId())) + .withRel(REL_REPRESENTATIONS)) .ifMatch(this::isPostfachConfigured) .addLink(linkTo(methodOn(PostfachMailController.class).getAll(vorgang.getId())).withRel(REL_POSTFACH_MAILS)) .ifMatch(this::isEinheitlicherAnsprechpartner) diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentsByVorgangControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentByVorgangControllerTest.java similarity index 72% rename from alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentsByVorgangControllerTest.java rename to alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentByVorgangControllerTest.java index 54638cb8a8390236ab8fc1c155d8ff3e33759779..0f3a90126e5da1db42e63875315efdb160947cb6 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentsByVorgangControllerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentByVorgangControllerTest.java @@ -15,6 +15,7 @@ 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.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; @@ -26,23 +27,22 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import com.thedeanda.lorem.LoremIpsum; -import de.ozgcloud.alfa.attachment.AttachmentController.AttachmentsByVorgangController; import de.ozgcloud.alfa.common.binaryfile.BinaryFileModelAssembler; +import de.ozgcloud.alfa.common.file.OzgFile; import de.ozgcloud.alfa.common.file.OzgFileService; import de.ozgcloud.alfa.common.file.OzgFileTestFactory; import de.ozgcloud.alfa.common.zipdownload.ZipDownloadService; -import de.ozgcloud.alfa.vorgang.EingangTestFactory; import de.ozgcloud.alfa.vorgang.VorgangController; import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; import de.ozgcloud.alfa.vorgang.VorgangWithEingang; import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; import lombok.SneakyThrows; -class AttachmentsByVorgangControllerTest { +class AttachmentByVorgangControllerTest { @Spy @InjectMocks - private AttachmentsByVorgangController controller; + private AttachmentByVorgangController controller; @Mock private BinaryFileModelAssembler modelAssembler; @Mock @@ -59,6 +59,38 @@ class AttachmentsByVorgangControllerTest { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } + @Nested + class TestGetAttachmentsByVorgang { + + @BeforeEach + void mockFileService() { + when(fileService.getAttachments(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(OzgFileTestFactory.create())); + } + + @SneakyThrows + @Test + void shouldResponseWithStatusOk() { + var result = callEndpoint(); + + result.andExpect(status().isOk()); + } + + @SneakyThrows + @Test + void shouldCallModelAssembler() { + callEndpoint(); + + verify(modelAssembler).toCollectionModel(ArgumentMatchers.<Stream<OzgFile>>any()); + } + + @SneakyThrows + private ResultActions callEndpoint() { + return mockMvc.perform( + get(AttachmentByVorgangController.PATH.replace("{vorgangId}", VorgangHeaderTestFactory.ID)) + .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)); + } + } + @DisplayName("Download") @Nested class TestDownload { @@ -98,7 +130,7 @@ class AttachmentsByVorgangControllerTest { void shouldHaveContentType() { var response = doRequest(); - response.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)); + response.andExpect(header().string(HttpHeaders.CONTENT_TYPE, AttachmentByVorgangController.APPLICATION_ZIP_VALUE)); } @SneakyThrows @@ -106,16 +138,15 @@ class AttachmentsByVorgangControllerTest { void shouldWriteZipFile() { doRequest(); - verify(controller).createZipFile(any(), eq(EingangTestFactory.ID)); + verify(controller).createZipFile(any(), eq(VorgangHeaderTestFactory.ID)); } @SneakyThrows private ResultActions doRequest() { return mockMvc.perform(asyncDispatch( - mockMvc.perform(get(AttachmentsByVorgangController.PATH.replace("{vorgangId}", VorgangHeaderTestFactory.ID) + "?eingangId=" - + EingangTestFactory.ID) - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE)) - .andReturn())) + mockMvc.perform(get(AttachmentByVorgangController.PATH.replace("{vorgangId}", VorgangHeaderTestFactory.ID)) + .header(HttpHeaders.ACCEPT, AttachmentByVorgangController.APPLICATION_ZIP_VALUE)) + .andReturn())) .andExpect(status().isOk()); } } @@ -159,13 +190,13 @@ class AttachmentsByVorgangControllerTest { void shouldGetAttachments() { callController(); - verify(fileService).getAttachmentsByEingang(EingangTestFactory.ID); + verify(fileService).getAttachments(VorgangHeaderTestFactory.ID); } @Test void shouldCallZipDownloadService() { var ozgFile = OzgFileTestFactory.create(); - when(fileService.getAttachmentsByEingang(EingangTestFactory.ID)).thenReturn(Stream.of(ozgFile)); + when(fileService.getAttachments(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(ozgFile)); callController(); @@ -173,7 +204,7 @@ class AttachmentsByVorgangControllerTest { } private void callController() { - controller.createZipFile(outputStream, EingangTestFactory.ID); + controller.createZipFile(outputStream, VorgangHeaderTestFactory.ID); } } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileRemoteServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileRemoteServiceTest.java index 72bbe175b6bf69fe5d31d0ada39c9c0be50eada9..5f6571512cd3660298c0d89cef73903d48addbf8 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileRemoteServiceTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileRemoteServiceTest.java @@ -26,7 +26,6 @@ package de.ozgcloud.alfa.common.file; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; @@ -36,11 +35,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import de.ozgcloud.alfa.attachment.GrpcGetAttachmentsResponseTestFactory; -import de.ozgcloud.alfa.common.GrpcCallContextTestFactory; import de.ozgcloud.alfa.common.callcontext.ContextService; import de.ozgcloud.alfa.representation.GrpcGetRepresentationsResponseTestFactory; -import de.ozgcloud.alfa.vorgang.EingangTestFactory; -import de.ozgcloud.vorgang.grpc.command.GrpcCallContext; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; import de.ozgcloud.vorgang.grpc.file.FileServiceGrpc.FileServiceBlockingStub; import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest; import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsResponse; @@ -58,15 +55,8 @@ class OzgFileRemoteServiceTest { @Mock private ContextService contextService; - private GrpcCallContext callContext = GrpcCallContextTestFactory.create(); - - @BeforeEach - void mockContextService() { - when(contextService.createCallContext()).thenReturn(callContext); - } - @Nested - class TestGetAttachmentsByEingang { + class TestGetAttachments { private final GrpcGetAttachmentsResponse response = GrpcGetAttachmentsResponseTestFactory.create(); @@ -75,13 +65,6 @@ class OzgFileRemoteServiceTest { when(serviceStub.getAttachments(any())).thenReturn(response); } - @Test - void shouldCallContextService() { - doServiceCall(); - - verify(contextService).createCallContext(); - } - @Test void shouldCallFileStub() { doServiceCall(); @@ -98,16 +81,16 @@ class OzgFileRemoteServiceTest { } private Stream<OzgFile> forceActionsDone(Stream<OzgFile> stream) { - return stream.collect(Collectors.toList()).stream(); + return stream.toList().stream(); } private Stream<OzgFile> doServiceCall() { - return remoteService.getAttachmentsByEingang(EingangTestFactory.ID); + return remoteService.getAttachments(VorgangHeaderTestFactory.ID); } } @Nested - class TestGetRepresentationsByEingang { + class TestGetRepresentations { private final GrpcGetRepresentationsResponse response = GrpcGetRepresentationsResponseTestFactory.create(); @@ -116,13 +99,6 @@ class OzgFileRemoteServiceTest { when(serviceStub.getRepresentations(any())).thenReturn(response); } - @Test - void shouldCallContextService() { - doServiceCall(); - - verify(contextService).createCallContext(); - } - @Test void shouldCallFileStub() { doServiceCall(); @@ -139,11 +115,11 @@ class OzgFileRemoteServiceTest { } private Stream<OzgFile> forceActionsDone(Stream<OzgFile> stream) { - return stream.collect(Collectors.toList()).stream(); + return stream.toList().stream(); } private Stream<OzgFile> doServiceCall() { - return remoteService.getRepresentationsByEingang(EingangTestFactory.ID); + return remoteService.getRepresentations(VorgangHeaderTestFactory.ID); } } -} \ No newline at end of file +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileServiceTest.java index 0cde31348cb7ee6eb9dcb1e36a01b3dd0c522356..320e1fede704fb20116eddc40ba3fe2ec15f4e40 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileServiceTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/common/file/OzgFileServiceTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.ozgcloud.alfa.vorgang.EingangTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; class OzgFileServiceTest { @@ -40,24 +40,24 @@ class OzgFileServiceTest { private OzgFileRemoteService remoteService; @Nested - class TestGetAttachmentsByEingang { + class TestGetAttachments { @Test void shouldCallRemoteService() { - service.getAttachmentsByEingang(EingangTestFactory.ID); + service.getAttachments(VorgangHeaderTestFactory.ID); - verify(remoteService).getAttachmentsByEingang(EingangTestFactory.ID); + verify(remoteService).getAttachments(VorgangHeaderTestFactory.ID); } } @Nested - class TestGetRepresentationsByEingang { + class TestGetRepresentations { @Test void shouldCallRemoteService() { - service.getRepresentationsByEingang(EingangTestFactory.ID); + service.getRepresentations(VorgangHeaderTestFactory.ID); - verify(remoteService).getRepresentationsByEingang(EingangTestFactory.ID); + verify(remoteService).getRepresentations(VorgangHeaderTestFactory.ID); } } -} \ No newline at end of file +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/OrganisationsEinheitSettingsTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/OrganisationsEinheitSettingsTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..3704afd3e6e53302b1fdff0f7883260cd332ff88 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/OrganisationsEinheitSettingsTestFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024. + * 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. + */ + +package de.ozgcloud.alfa.postfach; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +class OrganisationsEinheitSettingsTestFactory { + public static final String TEST_SIGNATUR = "Test organisationseinheit signatur"; + + static OrganisationsEinheitSettings create() { + return createBuilder().build(); + } + + static OrganisationsEinheitSettings.OrganisationsEinheitSettingsBuilder createBuilder() { + return new OrganisationsEinheitSettings.OrganisationsEinheitSettingsBuilder() + .signatur(TEST_SIGNATUR); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachPropertiesTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachPropertiesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4a880a875df7f52489823ab29804ad3f0ba96c6c --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachPropertiesTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024. + * 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. + */ + +package de.ozgcloud.alfa.postfach; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +@SpringBootTest(classes = { PostfachPropertiesTestConfiguration.class }) +class PostfachPropertiesTest { + private static final String ORGANISATIONSEINHEITEN_ID = "oe1"; + private static final String TEST_SIG = "test1"; + private static final String TEST_ORGANISATIONS_SIG = OrganisationsEinheitSettingsTestFactory.TEST_SIGNATUR; + + @DisplayName("Test loading postfach configuration") + @Nested + @TestPropertySource(properties = { + PostfachProperties.PREFIX + ".signatur=" + TEST_SIG, + PostfachProperties.PREFIX + ".organisations-einheit-settings." + ORGANISATIONSEINHEITEN_ID + ".signatur=" + TEST_ORGANISATIONS_SIG, + }) + class TestLoadingPostfachProperties { + + @Autowired + private PostfachProperties postfachProperties; + + @Nested + class TestInitialization { + + @Test + void shouldHaveProperties() { + assertThat(postfachProperties).isNotNull(); + } + + @Test + void shouldHaveOrganisationsEinheitSettings() { + assertThat(postfachProperties.getOrganisationsEinheitSettings()).isNotNull(); + } + } + } + + @DisplayName("Test mapping organisations einheit settings") + @Nested + @TestPropertySource(properties = { + PostfachProperties.PREFIX + ".signatur=" + TEST_SIG, + PostfachProperties.PREFIX + ".organisations-einheit-settings.oe1.signatur=" + TEST_ORGANISATIONS_SIG, + }) + class TestMapOrganisationsEinheitSettings { + + @Autowired + private PostfachProperties postfachProperties; + + @Test + void shouldHaveOrganisationsEinheit() { + var props = postfachProperties.getOrganisationsEinheitSettings(); + + assertThat(props).containsKey(ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldHaveOrganisationsEinheitSetting() { + assertThat(postfachProperties.getOrganisationsEinheitSettings().get(ORGANISATIONSEINHEITEN_ID)).hasFieldOrPropertyWithValue("signatur", + TEST_ORGANISATIONS_SIG); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachPropertiesTestConfiguration.java b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachPropertiesTestConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..0ad3591f8955244f52afbebae68225d0a43e0d62 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachPropertiesTestConfiguration.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024. + * 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. + */ + +package de.ozgcloud.alfa.postfach; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(PostfachProperties.class) +class PostfachPropertiesTestConfiguration { + + @Autowired + private PostfachProperties postfachProperties; + +} \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachSettingsServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachSettingsServiceTest.java index 2898c5ecf7fde5ead5dab2eb396bbeeae8f3861d..a772c4fdc09c6887a636697f16135f8af95373a7 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachSettingsServiceTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachSettingsServiceTest.java @@ -4,6 +4,9 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -19,6 +22,7 @@ import org.springframework.test.util.ReflectionTestUtils; import com.thedeanda.lorem.LoremIpsum; +import de.ozgcloud.alfa.collaboration.OrganisationsEinheitTestFactory; import de.ozgcloud.alfa.common.FeatureToggleProperties; import de.ozgcloud.alfa.vorgang.ServiceKontoTestFactory; import de.ozgcloud.alfa.vorgang.VorgangHeadTestFactory; @@ -62,7 +66,7 @@ class PostfachSettingsServiceTest { } @Test - void shoulCallRemoteServiceOnlyOnce() { + void shouldCallRemoteServiceOnlyOnce() { when(remoteService.getPostfachConfig()).thenReturn(PostfachConfigGroupTestFactory.create()); callService(); @@ -128,12 +132,12 @@ class PostfachSettingsServiceTest { void shouldGetSignatur() { callService(); - verify(service).getSignatur(); + verify(service).getSignatur(vorgang.getOrganisationseinheitenID()); } @Test void shouldSetSignatur() { - doReturn(SettingsTestFactory.SIGNATUR).when(service).getSignatur(); + doReturn(SettingsTestFactory.SIGNATUR).when(service).getSignatur(vorgang.getOrganisationseinheitenID()); var postfach = callService(); @@ -156,24 +160,60 @@ class PostfachSettingsServiceTest { } @Test - void shouldGetSignatur() { + void shouldGetOrganisationEinheitSettings() { callService(); - verify(postfachProperties).getSignatur(); + verify(service).getOrganisationsEinheitSettings(OrganisationsEinheitTestFactory.ID); + } + + @Nested + class OnExistingOrganisationsEinheitSignatur { + + @BeforeEach + void setUp() { + doReturn(Optional.of(OrganisationsEinheitSettingsTestFactory.create())).when(service) + .getOrganisationsEinheitSettings(OrganisationsEinheitTestFactory.ID); + } + + @Test + void shouldReturnOrganisationsEinheitSignatur() { + var signatur = callService(); + + assertThat(signatur).isEqualTo(OrganisationsEinheitSettingsTestFactory.TEST_SIGNATUR); + } } - @Test - void shouldReturnSignatur() { - when(postfachProperties.getSignatur()).thenReturn(SettingsTestFactory.SIGNATUR); + @Nested + class OnNoOrganisationsEinheitSignatur { + + @BeforeEach + void setUp() { + doReturn(Optional.empty()).when(service) + .getOrganisationsEinheitSettings(OrganisationsEinheitTestFactory.ID); + } - var signatur = callService(); + @Test + void shouldGetSignatur() { + callService(); + + verify(postfachProperties).getSignatur(); + + } + + @Test + void shouldReturnSignatur() { + when(postfachProperties.getSignatur()).thenReturn(SettingsTestFactory.SIGNATUR); + + var signatur = callService(); + + assertThat(signatur).isEqualTo(SettingsTestFactory.SIGNATUR); + } - assertThat(signatur).isEqualTo(SettingsTestFactory.SIGNATUR); } private String callService() { - return service.getSignatur(); + return service.getSignatur(OrganisationsEinheitTestFactory.ID); } } @@ -317,4 +357,36 @@ class PostfachSettingsServiceTest { ReflectionTestUtils.setField(service, "postfachConfigGroup", postfachConfigGroup); } + @Nested + class TestGetOrganisationsEinheitSettings { + + private final OrganisationsEinheitSettings organisationsEinheitSettings = OrganisationsEinheitSettingsTestFactory.create(); + + @BeforeEach + void setUp() { + when(postfachProperties.getOrganisationsEinheitSettings()).thenReturn( + Map.of(OrganisationsEinheitTestFactory.ID, organisationsEinheitSettings)); + } + + @Test + void shouldGetOrganisationsEinheitSettings() { + service.getOrganisationsEinheitSettings(OrganisationsEinheitTestFactory.ID); + + verify(postfachProperties).getOrganisationsEinheitSettings(); + } + + @Test + void shouldReturnSettings() { + var settings = service.getOrganisationsEinheitSettings(OrganisationsEinheitTestFactory.ID); + + assertThat(settings).hasValue(organisationsEinheitSettings); + } + + @Test + void shouldReturnEmpty() { + var settings = service.getOrganisationsEinheitSettings(UUID.randomUUID().toString()); + + assertThat(settings).isEmpty(); + } + } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/representation/RepresentationByVorgangControllerTest.java similarity index 67% rename from alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentControllerTest.java rename to alfa-service/src/test/java/de/ozgcloud/alfa/representation/RepresentationByVorgangControllerTest.java index 7e7b3a6e20a4aa2ca117acb79ece432c7d5cf57c..bacd8d37cd39d528a54d0eb3b778ecef9da5dc46 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/attachment/AttachmentControllerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/representation/RepresentationByVorgangControllerTest.java @@ -21,9 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.alfa.attachment; +package de.ozgcloud.alfa.representation; -import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -31,12 +30,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.util.stream.Stream; 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.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import org.springframework.hateoas.CollectionModel; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -45,50 +45,52 @@ import de.ozgcloud.alfa.common.binaryfile.BinaryFileModelAssembler; import de.ozgcloud.alfa.common.file.OzgFile; import de.ozgcloud.alfa.common.file.OzgFileService; import de.ozgcloud.alfa.common.file.OzgFileTestFactory; -import de.ozgcloud.alfa.common.zipdownload.ZipDownloadService; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; import lombok.SneakyThrows; -class AttachmentControllerTest { +class RepresentationByVorgangControllerTest { @Spy @InjectMocks - private AttachmentController controller; + private RepresentationByVorgangController controller; @Mock private BinaryFileModelAssembler modelAssembler; @Mock private OzgFileService fileService; - @Mock - private ZipDownloadService zipDownloadService; private MockMvc mockMvc; @BeforeEach - void initTest() { + void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } @Nested - class TestGetAttachmentsByEingang { + class TestGetRepresentations { + + Stream<OzgFile> representations = Stream.of(OzgFileTestFactory.create()); @BeforeEach void mockFileService() { - when(fileService.getAttachmentsByEingang(anyString())).thenReturn(Stream.of(OzgFileTestFactory.create())); + when(fileService.getRepresentations(VorgangHeaderTestFactory.ID)).thenReturn(representations); + when(modelAssembler.toCollectionModel(representations)).thenReturn(CollectionModel.empty()); } @SneakyThrows + @DisplayName("should return ok") @Test - void shouldResponseWithStatusOk() { + void shouldReturnOk() { var result = callEndpoint(); result.andExpect(status().isOk()); } - @SneakyThrows + @DisplayName("should call file service") @Test - void shoudlCallFileService() { + void shouldCallFileService() { callEndpoint(); - verify(fileService).getAttachmentsByEingang(any()); + verify(fileService).getRepresentations(VorgangHeaderTestFactory.ID); } @SneakyThrows @@ -96,12 +98,21 @@ class AttachmentControllerTest { void shouldCallModelAssembler() { callEndpoint(); - verify(modelAssembler).toCollectionModel(ArgumentMatchers.<Stream<OzgFile>>any()); + verify(modelAssembler).toCollectionModel(representations); + } + + @SneakyThrows + @DisplayName("should return entity") + @Test + void shouldReturnEntity() { + var result = callEndpoint(); + + result.andExpect(jsonPath("$.content").isEmpty()); } @SneakyThrows private ResultActions callEndpoint() { - return mockMvc.perform(get(AttachmentController.PATH).param(AttachmentController.PARAM_EINGANG_ID, "1")); + return mockMvc.perform(get(RepresentationByVorgangController.PATH, VorgangHeaderTestFactory.ID)); } } } \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/representation/RepresentationControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/representation/RepresentationControllerTest.java deleted file mode 100644 index baa2ecbbff4cb2b1ddf4e43ac192d10109088069..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/representation/RepresentationControllerTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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. - */ -package de.ozgcloud.alfa.representation; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import java.util.stream.Stream; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatchers; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import de.ozgcloud.alfa.common.binaryfile.BinaryFileModelAssembler; -import de.ozgcloud.alfa.common.file.OzgFile; -import de.ozgcloud.alfa.common.file.OzgFileService; -import de.ozgcloud.alfa.common.file.OzgFileTestFactory; -import lombok.SneakyThrows; - -class RepresentationControllerTest { - - @Spy - @InjectMocks - private RepresentationController controller; - @Mock - private BinaryFileModelAssembler modelAssembler; - @Mock - private OzgFileService fileService; - - private MockMvc mockMvc; - - @BeforeEach - void init() { - mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - } - - @Nested - class TestGetRepresentationsByEingang { - - @BeforeEach - void mockFileService() { - when(fileService.getRepresentationsByEingang(anyString())).thenReturn(Stream.of(OzgFileTestFactory.create())); - } - - @SneakyThrows - @Test - void shouldCallEndpoint() { - callEndpoint(); - } - - @SneakyThrows - @Test - void shouldCallFileService() { - callEndpoint(); - - verify(fileService).getRepresentationsByEingang(any()); - } - - @SneakyThrows - @Test - void shouldCallModelAssembler() { - callEndpoint(); - - verify(modelAssembler).toCollectionModel(ArgumentMatchers.<Stream<OzgFile>>any()); - } - - @SneakyThrows - private void callEndpoint() { - mockMvc.perform(get(RepresentationController.PATH).param(RepresentationController.PARAM_EINGANG_ID, "1")).andExpect(status().isOk()); - } - } - -} \ No newline at end of file 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 988b8cd04b8df6ae58cb6923785235828ebd5447..a145ca8b23e05f8d925e015a8e5cc9cb6f739357 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 @@ -67,7 +67,7 @@ class VorgangWithEingangProcessorTest { @Mock private VorgangProcessorProperties vorgangProcessorProperties; - private UserProfileUrlProvider urlProvider = new UserProfileUrlProvider(); + private final UserProfileUrlProvider urlProvider = new UserProfileUrlProvider(); @DisplayName("Attachments") @Nested @@ -82,7 +82,7 @@ class VorgangWithEingangProcessorTest { @Nested class TestLink { - private static final String PATH = "/api/attachments?eingangId=" + EingangTestFactory.ID; + private static final String PATH = "/api/vorgang/" + VorgangHeaderTestFactory.ID + "/attachments"; private final LinkRelation linkRel = VorgangWithEingangProcessor.REL_ATTACHMENTS; @DisplayName("should be present if attachments exists") @@ -105,7 +105,7 @@ class VorgangWithEingangProcessorTest { @Nested class TestDownloadLink { - private static final String PATH = "/api/vorgang/" + VorgangHeaderTestFactory.ID + "/attachments?eingangId=" + EingangTestFactory.ID; + private static final String PATH = "/api/vorgang/" + VorgangHeaderTestFactory.ID + "/attachments"; private final LinkRelation linkRel = VorgangWithEingangProcessor.REL_DOWNLOAD_ATTACHMENTS; @DisplayName("should be present if attachments exists") @@ -144,7 +144,7 @@ class VorgangWithEingangProcessorTest { initUserProfileUrlProvider(urlProvider); } - private static final String PATH = "/api/representations?eingangId=" + EingangTestFactory.ID; + private static final String PATH = "/api/vorgang/" + VorgangHeaderTestFactory.ID + "/representations"; private final LinkRelation linkRel = VorgangWithEingangProcessor.REL_REPRESENTATIONS; diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java index ab9ead3554f9ff95650c64d2e171882613b49e49..fd7442319cbf13109c91a94e72a04cc5d5af764d 100644 --- a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java @@ -2,7 +2,6 @@ package de.ozgcloud.alfa.file; import java.io.OutputStream; import java.util.List; -import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; @@ -12,7 +11,6 @@ import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; import de.ozgcloud.alfa.common.binaryfile.FileId; import de.ozgcloud.alfa.common.file.OzgFile; import de.ozgcloud.alfa.common.file.OzgFileService; -import de.ozgcloud.alfa.vorgang.Eingang; import de.ozgcloud.alfa.vorgang.VorgangWithEingang; import de.xoev.xdomea.DokumentType; import lombok.RequiredArgsConstructor; @@ -25,15 +23,11 @@ public class ExportFileService { private final BinaryFileService binaryFileService; public Stream<OzgFile> getRepresentations(VorgangWithEingang vorgang) { - return Optional.ofNullable(vorgang.getEingang()) - .map(Eingang::getId).stream() - .flatMap(ozgFileService::getRepresentationsByEingang); + return ozgFileService.getRepresentations(vorgang.getId()); } public Stream<OzgFile> getAttachments(VorgangWithEingang vorgang) { - return Optional.ofNullable(vorgang.getEingang()) - .map(Eingang::getId).stream() - .flatMap(ozgFileService::getAttachmentsByEingang); + return ozgFileService.getAttachments(vorgang.getId()); } public Stream<DokumentType> createDokumentTypes(List<OzgFile> ozgFiles, String formEngineName) { diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java index 502ab6599a36de2b53c4da6e2b0e3600b03b928f..73d519947c0903948271c05fd95c06ebcc29f3cf 100644 --- a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java @@ -9,12 +9,12 @@ import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; 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.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; -import org.springframework.http.MediaType; import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; import de.ozgcloud.alfa.common.binaryfile.FileId; @@ -23,7 +23,8 @@ import de.ozgcloud.alfa.common.file.OzgFileService; import de.ozgcloud.alfa.common.file.OzgFileTestFactory; import de.ozgcloud.alfa.export.DokumentTypeTestFactory; import de.ozgcloud.alfa.vorgang.EingangHeaderTestFactory; -import de.ozgcloud.alfa.vorgang.EingangTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; import de.xoev.xdomea.DokumentType; @@ -38,109 +39,66 @@ class ExportFileServiceTest { @Mock private BinaryFileService binaryFileService; - @Nested - class TestGetRepresentations { - - private final OzgFile representationPdfFile = OzgFileTestFactory.createBuilder().contentType(MediaType.APPLICATION_PDF_VALUE).build(); - private final OzgFile representationXmlFile = OzgFileTestFactory.createBuilder().contentType(MediaType.TEXT_XML_VALUE).build(); - - @Nested - class OnAvailableVorgangData { + private final OzgFile ozgFile = OzgFileTestFactory.create(); - @BeforeEach - void init() { - when(ozgFileService.getRepresentationsByEingang(EingangTestFactory.ID)).thenReturn( - Stream.of(representationPdfFile, representationXmlFile)); - } + private final VorgangWithEingang vorgangWithEingang = VorgangWithEingangTestFactory.create(); - @Test - void shouldLoadRepresentations() { - service.getRepresentations(VorgangWithEingangTestFactory.create()).toList(); - - verify(ozgFileService).getRepresentationsByEingang(EingangTestFactory.ID); - } - - @Test - void shouldReturnAllFiles() { - var representations = service.getRepresentations(VorgangWithEingangTestFactory.create()); + @DisplayName("get representations") + @Nested + class TestGetRepresentations { - assertThat(representations).hasSize(2).containsExactlyInAnyOrder(representationPdfFile, representationXmlFile); - } + @BeforeEach + void mock() { + when(ozgFileService.getRepresentations(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(ozgFile)); } - @Nested - class OnMissingVorgangData { - - @Test - void shouldReturnEmptyOnMissingEingang() { - var vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(null).build(); - - var representations = service.getRepresentations(vorgang); - - assertThat(representations).isEmpty(); - } - - @Test - void shouldReturnEmptyOnMissingEingangId() { - var vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().id(null).build()).build(); + @DisplayName("should call get representations") + @Test + void shouldShouldCallGetRepresentations() { + getRepresentations(); - var representations = service.getRepresentations(vorgang); + verify(ozgFileService).getRepresentations(VorgangHeaderTestFactory.ID); + } - assertThat(representations).isEmpty(); - } + @DisplayName("should return representations") + @Test + void shouldReturnRepresentations() { + var representations = getRepresentations(); + assertThat(representations).containsExactly(ozgFile); } + private List<OzgFile> getRepresentations() { + return service.getRepresentations(vorgangWithEingang).toList(); + } } + @DisplayName("get attachments") @Nested class TestGetAttachments { - - private final OzgFile attachmentPdfFile = OzgFileTestFactory.createBuilder().contentType(MediaType.APPLICATION_PDF_VALUE).build(); - private final OzgFile attachmentXmlFile = OzgFileTestFactory.createBuilder().contentType(MediaType.TEXT_XML_VALUE).build(); - - @Nested - class OnAvailableVorgangData { - - @BeforeEach - void init() { - when(ozgFileService.getAttachmentsByEingang(EingangTestFactory.ID)).thenReturn(Stream.of(attachmentXmlFile, attachmentPdfFile)); - } - - @Test - void shouldLoadAttachments() { - service.getAttachments(VorgangWithEingangTestFactory.create()).toList(); - - verify(ozgFileService).getAttachmentsByEingang(EingangTestFactory.ID); - } - - @Test - void shouldReturnAllFiles() { - var ozgFiles = service.getAttachments(VorgangWithEingangTestFactory.create()); - - assertThat(ozgFiles).hasSize(2).containsExactlyInAnyOrder(attachmentPdfFile, attachmentXmlFile); - } + @BeforeEach + void mock() { + when(ozgFileService.getAttachments(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(ozgFile)); } - @Nested - class OnMissingVorgangData { - @Test - void shouldReturnEmptyOnMissingEingang() { - var vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(null).build(); - - var attachments = service.getAttachments(vorgang); + @DisplayName("should call get attachments") + @Test + void shouldShouldCallGetRepresentations() { + getAttachments(); - assertThat(attachments).isEmpty(); - } + verify(ozgFileService).getAttachments(VorgangHeaderTestFactory.ID); + } - @Test - void shouldReturnEmptyOnMissingEingangId() { - var vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().id(null).build()).build(); + @DisplayName("should return") + @Test + void shouldReturn() { + var representations = getAttachments(); - var attachments = service.getAttachments(vorgang); + assertThat(representations).containsExactly(ozgFile); + } - assertThat(attachments).isEmpty(); - } + private List<OzgFile> getAttachments() { + return service.getAttachments(vorgangWithEingang).toList(); } }