diff --git a/alfa-client/Jenkinsfile.e2e b/alfa-client/Jenkinsfile.e2e index 84f66d922dc356516bac3e52bdab656e2776e452..da6f80f30f5cb7e07babc7fd53e3195f86d3afc4 100644 --- a/alfa-client/Jenkinsfile.e2e +++ b/alfa-client/Jenkinsfile.e2e @@ -456,12 +456,6 @@ String getHelmRepoUrl() { return "https://nexus.ozg-sh.de/repository/ozg-base-apps-snapshot" } -String getRootPomVersion() { - def rootPom = readMavenPom file: 'pom.xml' - - return rootPom.version -} - Void initEnvAdminDefaultVersions() { def values = getApplicationValues('administration') env.ADMINISTRATION_IMAGE_TAG = getImageTag(values) 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 12140f8351c958ba5388638076727ef41bee5053..673ea2c47571873cc69795547f6dc5359609e99a 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 @@ -100,11 +100,11 @@ export class BenutzerE2EComponent { private readonly userBenutzername: string = 'Benutzername-text-input'; private readonly userMail: string = 'E-Mail-text-input'; - private readonly adminCheckbox: string = 'Admin-checkbox-editor'; - private readonly loeschenCheckbox: string = 'Loschen-checkbox-editor'; - private readonly userCheckbox: string = 'User-checkbox-editor'; - private readonly postCheckbox: string = 'Poststelle-checkbox-editor'; - private readonly datenbeauftragungCheckbox: string = 'Datenbeauftragung-checkbox-editor'; + private readonly adminCheckboxLabel: string = 'Admin'; + private readonly loeschenCheckboxLabel: string = 'Löschen'; + private readonly userCheckboxLabel: string = 'User'; + private readonly postCheckboxLabel: string = 'Poststelle'; + private readonly datenbeauftragungLabel: string = 'Datenbeauftragung'; private readonly organisationsEinheitCheckboxSuffix: string = '-checkbox-editor'; @@ -115,6 +115,10 @@ export class BenutzerE2EComponent { return cy.getTestElement(this.headline); } + public getHeadline(): Cypress.Chainable<Element> { + return cy.getTestElement(this.headline); + } + public getVornameInput(): Cypress.Chainable<Element> { return cy.getTestElement(this.userVorname); } @@ -131,24 +135,24 @@ export class BenutzerE2EComponent { return cy.getTestElement(this.userMail); } - public getAdminCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.adminCheckbox); + public getAdminCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.adminCheckboxLabel); } - public getLoeschenCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.loeschenCheckbox); + public getLoeschenCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.loeschenCheckboxLabel); } - public getUserCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.userCheckbox); + public getUserCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.userCheckboxLabel); } - public getPostCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.postCheckbox); + public getPostCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.postCheckboxLabel); } - public getDatenbeauftragungCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.datenbeauftragungCheckbox); + public getDatenbeauftragungCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.datenbeauftragungLabel); } public getOrganisationsEinheitCheckbox(einheit: string): Cypress.Chainable<Element> { @@ -176,3 +180,29 @@ export class BenutzerDeleteDialogE2EComponent { return cy.getTestElement(this.deleteButton); } } + +export class BenutzerCheckboxE2EComponent { + private rootPrefix: string; + private prefix: string; + + private readonly adminCheckbox: string = '-checkbox-editor'; + private readonly adminInfoButtonSuffix: string = '-role-info-button'; + private readonly adminInfoButtonTooltipSuffix: string = '-role-info-button-tooltip'; + + constructor(label: string) { + this.rootPrefix = convertToDataTestId(label); + this.prefix = convertToDataTestId(label.toLocaleLowerCase()); + } + + public getRoot(): Cypress.Chainable<Element> { + return cy.getTestElement(`${this.rootPrefix}${this.adminCheckbox}`); + } + + public getInfoButton(): Cypress.Chainable<Element> { + return cy.getTestElement(`${this.prefix}${this.adminInfoButtonSuffix}`); + } + + public getInfoButtonTooltip(): Cypress.Chainable<Element> { + return cy.getTestElement(`${this.prefix}${this.adminInfoButtonTooltipSuffix}`); + } +} 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 62527711781b022092af5336db78779b0df2c914..f177cf791efec0113ceaebf9d6098e2008bc21f9 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 @@ -21,19 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { haveValue, typeText } from '../../support/cypress.util'; +import { haveValue } from '../../support/cypress.util'; export class PostfachE2EComponent { + private readonly headline: string = 'headline'; private readonly signaturText: string = 'signature-textarea'; private readonly saveSignaturButton: string = 'save-button'; + public getHeadline(): any { + return cy.getTestElement(this.headline); + } + public getSignaturText(): any { return cy.getTestElement(this.signaturText); } public setSignatur(signatur: string): void { this.clearSignatur(); - typeText(this.getSignaturText(), signatur); + this.getSignaturText().type(signatur); } public clearSignatur(): void { diff --git a/alfa-client/apps/admin-e2e/src/components/zustaendige-stelle/zustaendige-stelle-dialog.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/zustaendige-stelle/zustaendige-stelle-dialog.e2e.component.ts index 337cad0fe51c3ba1e7bf0b1123e8f324c57dbc73..6bd293d6fc2c39febbea6bfef0fb4e66de7e22b6 100644 --- a/alfa-client/apps/admin-e2e/src/components/zustaendige-stelle/zustaendige-stelle-dialog.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/zustaendige-stelle/zustaendige-stelle-dialog.e2e.component.ts @@ -1,5 +1,3 @@ -import { typeText } from '../../support/cypress.util'; - export class ZustaendigeStelleDialogE2EComponent { private readonly locatorZustaendigeStelleForm: string = 'search-organisations-einheit'; private readonly locatorSearchInput: string = 'instant_search-text-input'; @@ -15,7 +13,7 @@ export class ZustaendigeStelleDialogE2EComponent { } public enterSearchTerm(searchTerm: string): void { - typeText(this.getSearchInput(), searchTerm); + this.getSearchInput().type(searchTerm); } public countSearchEntries(): Cypress.Chainable<number> { diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts index 0d4a3c538f90b3621783a7f8ccc750429823434f..6869eafd381b1d9df0dde4b213466d4c8db8b4db 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts @@ -1,10 +1,11 @@ +import { faker } from '@faker-js/faker'; import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; import { E2EBenutzerVerifier } from 'apps/admin-e2e/src/helper/benutzer/benutzer.verifier'; import { getCypressEnv, interceptWithResponse, waitOfInterceptor } from 'apps/admin-e2e/src/support/cypress-helper'; import { SnackBarE2EComponent } from '../../../components/ui/snackbar.e2e.component'; import { AdminUserE2E, HttpMethodE2E, SnackbarMessagesE2E } from '../../../model/util'; import { contains, notExist } from '../../../support/cypress.util'; -import { loginAsAriane } from '../../../support/user-util'; +import { loginAsAriane, loginByUsernameAndPassword } from '../../../support/user-util'; describe('Benutzer anlegen', () => { const benutzerHelper: E2EBenutzerHelper = new E2EBenutzerHelper(); @@ -12,7 +13,8 @@ describe('Benutzer anlegen', () => { const snackBar: SnackBarE2EComponent = new SnackBarE2EComponent(); - const newUser: AdminUserE2E = { + const newUserPassword: string = 'TestTestTest'; + const newAdminUser: AdminUserE2E = { vorname: 'Theo', nachname: 'Testuser', username: 'testtheo', @@ -22,6 +24,15 @@ describe('Benutzer anlegen', () => { organisationseinheiten: [], }; + const newRegularUser: AdminUserE2E = { + vorname: 'Max', + nachname: 'Mustermann', + username: 'maxmust', + email: 'max.mustermann@ozg-sh.de', + isUser: true, + organisationseinheiten: [], + }; + before(() => { loginAsAriane(); }); @@ -34,7 +45,7 @@ describe('Benutzer anlegen', () => { interceptWithResponse(HttpMethodE2E.POST, url, { errorCode, errorBody }).as(interceptor); benutzerHelper.openNewBenutzerPage(); - benutzerHelper.addBenutzer(newUser); + benutzerHelper.addBenutzer(newAdminUser); benutzerHelper.saveBenutzer(); waitOfInterceptor(interceptor).then(() => { @@ -47,7 +58,7 @@ describe('Benutzer anlegen', () => { it('should show snackbar after save', () => { benutzerHelper.openNewBenutzerPage(); - benutzerHelper.addBenutzer(newUser); + benutzerHelper.addBenutzer(newAdminUser); benutzerHelper.saveBenutzer(); contains(snackBar.getMessage(), SnackbarMessagesE2E.NUTZER_ANGELEGT); @@ -55,6 +66,60 @@ describe('Benutzer anlegen', () => { }); it('should show created user in list', () => { - benutzerVerifier.verifyUserInList(newUser); + benutzerVerifier.verifyUserInList(newAdminUser); + }); + + it('should remove benutzer', () => { + benutzerHelper.deleteBenutzer(newAdminUser.username); + benutzerVerifier.verifyUserNotInList(newAdminUser.username); + }); + + describe('newly created admin user', () => { + it('should create new admin user', () => { + benutzerHelper.openNewBenutzerPage(); + + benutzerHelper.addBenutzer(newAdminUser); + benutzerHelper.saveBenutzer(); + + benutzerVerifier.verifyUserInList(newAdminUser); + }); + + it('should create new regular user', () => { + benutzerHelper.openNewBenutzerPage(); + + benutzerHelper.addBenutzer(newRegularUser); + benutzerHelper.saveBenutzer(); + + benutzerVerifier.verifyUserInList(newRegularUser); + }); + + it('should modify user', () => { + const userWithChangedFirstName = { ...newRegularUser, vorname: faker.person.firstName() }; + + benutzerHelper.activateUser(newAdminUser.username, newUserPassword).then(() => { + loginByUsernameAndPassword(newAdminUser.username, newUserPassword); + benutzerHelper.openBenutzerPage(newRegularUser.username); + + benutzerHelper.editBenutzer(userWithChangedFirstName); + benutzerHelper.saveBenutzer(); + + benutzerVerifier.verifyUserInList(userWithChangedFirstName); + }); + }); + + it('should have rights to delete user', () => { + loginByUsernameAndPassword(newAdminUser.username, newUserPassword); + benutzerHelper.openBenutzerListPage(); + + benutzerHelper.deleteBenutzer(newRegularUser.username); + + benutzerVerifier.verifyUserNotInList(newRegularUser.username); + }); + + it('should delete user', () => { + loginAsAriane(); + + benutzerHelper.deleteBenutzer(newAdminUser.username); + }); }); }); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-bearbeiten.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-bearbeiten.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..16d99dd00ad9ae05df7bc35fb531e981f712ceeb --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-bearbeiten.cy.ts @@ -0,0 +1,58 @@ +import { faker } from '@faker-js/faker'; +import { BenutzerE2EComponent } from 'apps/admin-e2e/src/components/benutzer/benutzer.e2e.component'; +import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; +import { E2EBenutzerVerifier } from 'apps/admin-e2e/src/helper/benutzer/benutzer.verifier'; +import { AdminUserE2E } from 'apps/admin-e2e/src/model/util'; +import { loginAsAriane } from 'apps/admin-e2e/src/support/user-util'; + +describe('Benutzer Bearbeiten', () => { + const benutzerVerifier: E2EBenutzerVerifier = new E2EBenutzerVerifier(); + const benutzerHelper: E2EBenutzerHelper = new E2EBenutzerHelper(); + const benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); + + const userName: string = 'testtheo' + faker.string.uuid(); + const user: AdminUserE2E = { + vorname: 'Theo', + nachname: 'Testuser', + username: userName, + email: 'theo' + faker.string.uuid() + '@ozg-sh.de', + isUser: true, + organisationseinheiten: [], + }; + + before(() => { + loginAsAriane(); + }); + + it('should add new user', () => { + benutzerHelper.openNewBenutzerPage(); + benutzerHelper.addBenutzerAndSave(user); + }); + + it('should not be able to edit username', () => { + benutzerHelper.openBenutzerPage(userName); + + benutzerPage.getBenutzernameInput().should('not.exist'); + }); + + it('should deactivate other alfa roles if "user" role is selected', () => { + benutzerVerifier.verifyAlfaRolesCorrectlyChecked(user); + }); + + it('should edit user', () => { + const editedUser: AdminUserE2E = { ...user, vorname: 'Theodor' }; + + benutzerHelper.editBenutzerAndSave(editedUser); + }); + + it('should check for new user name', () => { + benutzerHelper.openBenutzerPage(userName); + + benutzerVerifier.verifyUserVorname('Theodor'); + }); + + it('should delete user', () => { + benutzerHelper.deleteBenutzer(userName); + benutzerVerifier.verifyUserNotInList(userName); + }); +}); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts index 6f2aeed20740461f3dc978afdc2b974fec471f00..d978a0cea6580068a22a4c15571d078ab56a16dc 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts @@ -21,15 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; -import { OrganisationsEinheitE2E } from 'apps/admin-e2e/src/model/organisations-einheit'; import { BenutzerE2EComponent, BenutzerListE2EComponent, BenutzerListItemE2EComponent, -} from '../../../components/benutzer/benutzer.e2e.component'; -import { beChecked, beEnabled, contains, exist, notBeChecked, notBeEnabled } from '../../../support/cypress.util'; -import { AlfaRollen, AlfaUsers, loginAsAriane } from '../../../support/user-util'; +} from 'apps/admin-e2e/src/components/benutzer/benutzer.e2e.component'; +import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; +import { OrganisationsEinheitE2E } from 'apps/admin-e2e/src/model/organisations-einheit'; +import { + beChecked, + beEnabled, + contains, + exist, + mouseEnter, + notBeChecked, + notBeEnabled, + visible, +} from 'apps/admin-e2e/src/support/cypress.util'; +import { AlfaRollen, AlfaUsers, loginAsAriane } from 'apps/admin-e2e/src/support/user-util'; describe('Benutzer und Rollen', () => { const benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); @@ -47,7 +56,7 @@ describe('Benutzer und Rollen', () => { it('should show users and attributes in list', () => { helper.openBenutzerListPage(); - const ariane: BenutzerListItemE2EComponent = benutzerListPage.getItem(AlfaUsers.ARAINE); + const ariane: BenutzerListItemE2EComponent = benutzerListPage.getItem(AlfaUsers.ARIANE); exist(ariane.getRoot()); contains(ariane.getRoles(), AlfaRollen.USER); @@ -76,64 +85,93 @@ describe('Benutzer und Rollen', () => { exist(richard.getNoOrganisationsEinheitText()); }); - it('should show single user screen on click', () => { + it('should show checkbox for each role', () => { helper.openNewBenutzerPage(); - exist(benutzerPage.getVornameInput()); - exist(benutzerPage.getNachnameInput()); - exist(benutzerPage.getBenutzernameInput()); - exist(benutzerPage.getMailInput()); + notBeChecked(benutzerPage.getAdminCheckbox().getRoot()); + notBeChecked(benutzerPage.getDatenbeauftragungCheckbox().getRoot()); + notBeChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeChecked(benutzerPage.getUserCheckbox().getRoot()); + notBeChecked(benutzerPage.getPostCheckbox().getRoot()); + }); + + it('should deactivate other alfa roles if "loeschen" role is selected', () => { + benutzerPage.getLoeschenCheckbox().getRoot().click(); + beChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(benutzerPage.getPostCheckbox().getRoot()); - notBeChecked(benutzerPage.getAdminCheckbox()); - notBeChecked(benutzerPage.getLoeschenCheckbox()); - notBeChecked(benutzerPage.getUserCheckbox()); - notBeChecked(benutzerPage.getPostCheckbox()); + benutzerPage.getLoeschenCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getUserCheckbox().getRoot()); + beEnabled(benutzerPage.getPostCheckbox().getRoot()); }); - it('should activate loeschen checkbox and deactivate the other two checkboxes', () => { - benutzerPage.getLoeschenCheckbox().click(); - beChecked(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getUserCheckbox()); - notBeEnabled(benutzerPage.getPostCheckbox()); + it('should deactivate other alfa roles if "user" role is selected', () => { + benutzerPage.getUserCheckbox().getRoot().click(); + beChecked(benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getPostCheckbox().getRoot()); - benutzerPage.getLoeschenCheckbox().click(); - notBeChecked(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getUserCheckbox()); - beEnabled(benutzerPage.getPostCheckbox()); + benutzerPage.getUserCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getUserCheckbox().getRoot()); + beEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getPostCheckbox().getRoot()); }); - it('should additionally activate and deactivate admin checkbox', () => { - benutzerPage.getLoeschenCheckbox().click(); - benutzerPage.getAdminCheckbox().click(); - beChecked(benutzerPage.getLoeschenCheckbox()); - beChecked(benutzerPage.getAdminCheckbox()); + it('should deactivate other alfa roles if "poststelle" role is selected', () => { + benutzerPage.getPostCheckbox().getRoot().click(); + beChecked(benutzerPage.getPostCheckbox().getRoot()); + notBeEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getUserCheckbox().getRoot()); - benutzerPage.getAdminCheckbox().click(); - notBeChecked(benutzerPage.getAdminCheckbox()); + benutzerPage.getPostCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getPostCheckbox().getRoot()); + beEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getUserCheckbox().getRoot()); }); - it('should activate user checkbox and deactivate the other two checkboxes', () => { - benutzerPage.getLoeschenCheckbox().click(); - benutzerPage.getUserCheckbox().click(); - beChecked(benutzerPage.getUserCheckbox()); - notBeEnabled(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getPostCheckbox()); - - benutzerPage.getUserCheckbox().click(); - notBeChecked(benutzerPage.getUserCheckbox()); - beEnabled(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getPostCheckbox()); + it('should activate and deactivate admin roles', () => { + benutzerPage.getAdminCheckbox().getRoot().click(); + benutzerPage.getDatenbeauftragungCheckbox().getRoot().click(); + beChecked(benutzerPage.getAdminCheckbox().getRoot()); + beChecked(benutzerPage.getDatenbeauftragungCheckbox().getRoot()); + + benutzerPage.getAdminCheckbox().getRoot().click(); + benutzerPage.getDatenbeauftragungCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getAdminCheckbox().getRoot()); + notBeChecked(benutzerPage.getDatenbeauftragungCheckbox().getRoot()); }); - it('should activate post checkbox and deactivate the other two checkboxes', () => { - benutzerPage.getPostCheckbox().click(); - beChecked(benutzerPage.getPostCheckbox()); - notBeEnabled(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getUserCheckbox()); + describe('hint text', () => { + it('should be visible on admin role mouse hover', () => { + mouseEnter(benutzerPage.getAdminCheckbox().getInfoButton()); + + visible(benutzerPage.getAdminCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on loeschen role mouse hover', () => { + mouseEnter(benutzerPage.getLoeschenCheckbox().getInfoButton()); + + visible(benutzerPage.getLoeschenCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on user role mouse hover', () => { + mouseEnter(benutzerPage.getUserCheckbox().getInfoButton()); + + visible(benutzerPage.getUserCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on poststellt role mouse hover', () => { + mouseEnter(benutzerPage.getPostCheckbox().getInfoButton()); + + visible(benutzerPage.getPostCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on datenbeauftragung role mouse hover', () => { + mouseEnter(benutzerPage.getDatenbeauftragungCheckbox().getInfoButton()); - benutzerPage.getPostCheckbox().click(); - notBeChecked(benutzerPage.getPostCheckbox()); - beEnabled(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getUserCheckbox()); + visible(benutzerPage.getDatenbeauftragungCheckbox().getInfoButtonTooltip()); + }); }); }); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/ariane.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/ariane.cy.ts index 80987765996348c4f24f3105abc2328713ef4371..64218bf8c50d791ca4f221c518a454cc54df37fe 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/ariane.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/ariane.cy.ts @@ -1,29 +1,33 @@ -import { MainPage, waitForSpinnerToDisappear } from 'apps/admin-e2e/src/page-objects/main.po'; -import { exist, notExist } from 'apps/admin-e2e/src/support/cypress.util'; +import { MainPage } from 'apps/admin-e2e/src/page-objects/main.po'; +import { containClass, exist, notExist } from 'apps/admin-e2e/src/support/cypress.util'; import { loginAsAriane } from 'apps/admin-e2e/src/support/user-util'; -describe('Navigation', () => { +describe('Ariane Navigation', () => { const mainPage: MainPage = new MainPage(); describe('with user ariane', () => { before(() => { loginAsAriane(); - - waitForSpinnerToDisappear(); }); it('should show benutzer navigation item', () => { exist(mainPage.getBenutzerNavigationItem()); }); - it('should show postfach navigation item', () => { - exist(mainPage.getPostfachNavigationItem()); - }); - it('should show organisationseinheiten navigation item', () => { exist(mainPage.getOrganisationEinheitNavigationItem()); }); + describe('postfach navigation item', () => { + it('should be visible', () => { + exist(mainPage.getPostfachNavigationItem()); + }); + + it('should be selected initial', () => { + containClass(mainPage.getPostfachNavigationItem(), 'border-selected'); + }); + }); + it('should hide statistik navigation item', () => { notExist(mainPage.getStatistikNavigationItem()); }); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/daria.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/daria.cy.ts index 33a06a73b83c3a839b0490f96aa17ddb42106994..4fda0a2dee6bfb74ad354a08e46f27ced5e15bc6 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/daria.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/daria.cy.ts @@ -1,43 +1,34 @@ -import { MainPage, waitForSpinnerToDisappear } from 'apps/admin-e2e/src/page-objects/main.po'; -import { exist, notExist, visible } from 'apps/admin-e2e/src/support/cypress.util'; +import { MainPage } from 'apps/admin-e2e/src/page-objects/main.po'; +import { containClass, exist, notExist } from 'apps/admin-e2e/src/support/cypress.util'; import { loginAsDaria } from 'apps/admin-e2e/src/support/user-util'; -import { StatistikE2EComponent } from '../../../components/statistik/statistik.e2e.component'; -describe('Navigation', () => { +describe('Daria Navigation', () => { const mainPage: MainPage = new MainPage(); - const statistikPage: StatistikE2EComponent = new StatistikE2EComponent(); - describe('with user daria', () => { before(() => { loginAsDaria(); - - waitForSpinnerToDisappear(); }); - it('should hide other navigation item', () => { + it('should hide benutzer navigation item', () => { notExist(mainPage.getBenutzerNavigationItem()); }); - it('should hide postfach navigation item', () => { - notExist(mainPage.getPostfachNavigationItem()); - }); - it('should hide organisationseinheiten navigation item', () => { notExist(mainPage.getOrganisationEinheitNavigationItem()); }); - describe('statistik', () => { + it('should hide postfach navigation item', () => { + notExist(mainPage.getPostfachNavigationItem()); + }); + + describe('statistik navigation item', () => { it('should be visible', () => { exist(mainPage.getStatistikNavigationItem()); }); it('should be initial selected', () => { - mainPage.isStatistikNavigationItemSelected(); - }); - - it('should show header text', () => { - visible(statistikPage.getHeaderText()); + containClass(mainPage.getStatistikNavigationItem(), 'border-selected'); }); }); }); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/safira.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/safira.cy.ts index 005da2e5a576948787fdeb1f26165bd250b22138..ae328f579e493b6c493a687da703269120bebbd5 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/safira.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/navigation/safira.cy.ts @@ -1,50 +1,35 @@ -import { MainPage, waitForSpinnerToDisappear } from 'apps/admin-e2e/src/page-objects/main.po'; -import { exist, visible } from 'apps/admin-e2e/src/support/cypress.util'; +import { MainPage } from 'apps/admin-e2e/src/page-objects/main.po'; +import { containClass, exist } from 'apps/admin-e2e/src/support/cypress.util'; import { loginAsSafira } from 'apps/admin-e2e/src/support/user-util'; -import { StatistikE2EComponent } from '../../../components/statistik/statistik.e2e.component'; -describe('Navigation', () => { +describe('Safira Navigation', () => { const mainPage: MainPage = new MainPage(); - const statistikPage: StatistikE2EComponent = new StatistikE2EComponent(); - describe('with user safira', () => { before(() => { loginAsSafira(); - - waitForSpinnerToDisappear(); }); it('should show benutzer navigation item', () => { exist(mainPage.getBenutzerNavigationItem()); }); - it('should show postfach navigation item', () => { - exist(mainPage.getPostfachNavigationItem()); - }); - it('should show organisationseinheiten navigation item', () => { exist(mainPage.getOrganisationEinheitNavigationItem()); }); - describe('statistik', () => { + describe('postfach navigation item', () => { it('should be visible', () => { - exist(mainPage.getStatistikNavigationItem()); + exist(mainPage.getPostfachNavigationItem()); }); - describe('on selection', () => { - before(() => { - mainPage.clickStatistikNavigationItem(); - }); - - it('should show page on selection', () => { - visible(statistikPage.getHeaderText()); - }); - - it('should mark navigation item as selected', () => { - mainPage.isStatistikNavigationItemSelected(); - }); + it('should be selected initial', () => { + containClass(mainPage.getPostfachNavigationItem(), 'border-selected'); }); }); + + it('should show statistik navigation item', () => { + exist(mainPage.getStatistikNavigationItem()); + }); }); }); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/postfach-signatur.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/postfach-signatur.cy.ts index 1a8b4a69f8b1f19d1c2daf27b65274f46fea62e0..779a88f3c46a4724f9d188768e7344e9b992cf1d 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/postfach-signatur.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/postfach-signatur.cy.ts @@ -21,12 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { E2EPostfachHelper } from 'apps/admin-e2e/src/helper/postfach/postfach.helper'; import { PostfachE2EComponent } from '../../../components/postfach/postfach.e2e.component'; -import { waitForSpinnerToDisappear } from '../../../page-objects/main.po'; -import { exist } from '../../../support/cypress.util'; import { loginAsAriane } from '../../../support/user-util'; -describe('Signatur', () => { +describe('(TODO: Ist noch wackelig in Bezug auf die Eingabe in das Feld) Postfach Signatur', () => { + const postfachHelper: E2EPostfachHelper = new E2EPostfachHelper(); const postfach: PostfachE2EComponent = new PostfachE2EComponent(); const signaturText: string = 'Signatur\nmit\n\n\n\nZeilenumbruch\n\n'; @@ -35,12 +35,9 @@ describe('Signatur', () => { loginAsAriane(); }); - it('should show Postfach page', () => { - waitForSpinnerToDisappear(); - exist(postfach.getSignaturText()); - }); - it('should show signature input with scrollbar', () => { + postfachHelper.openPostfachPage(); + postfach.setSignatur(signaturText); postfach.saveSignatur(); diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts index 320db78e13e0fee0cae8dad0cd94969ad7b0e2de..ec1bbb05e560d3c45de062711da3da9ed8cf39c1 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts @@ -1,3 +1,4 @@ +import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; import { BenutzerDeleteDialogE2EComponent, BenutzerE2EComponent, @@ -7,6 +8,7 @@ import { SnackBarE2EComponent } from '../../components/ui/snackbar.e2e.component import { OrganisationsEinheitE2E } from '../../model/organisations-einheit'; import { AdminUserE2E } from '../../model/util'; import { exist, notExist } from '../../support/cypress.util'; +import Chainable = Cypress.Chainable; export class E2EBenutzerExecutor { private benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); @@ -14,24 +16,20 @@ export class E2EBenutzerExecutor { private benutzerDeleteDialog: BenutzerDeleteDialogE2EComponent = new BenutzerDeleteDialogE2EComponent(); private benutzerListPage: BenutzerListE2EComponent = new BenutzerListE2EComponent(); - public modifyBenutzer(user: AdminUserE2E): void { - this.benutzerPage.getVornameInput().type(user.vorname); - this.benutzerPage.getNachnameInput().type(user.nachname); + public createBenutzer(user: AdminUserE2E): void { this.benutzerPage.getBenutzernameInput().type(user.username); - this.benutzerPage.getMailInput().type(user.email); - - if (user.isAdmin) { - this.benutzerPage.getAdminCheckbox().click(); - } - if (user.isUser) { - this.benutzerPage.getUserCheckbox().click(); - } - if (user.isLoeschen) { - this.benutzerPage.getLoeschenCheckbox().click(); - } - if (user.isPoststelle) { - this.benutzerPage.getPostCheckbox().click(); - } + this.modifyBenutzer(user); + } + + public modifyBenutzer(user: AdminUserE2E): void { + this.benutzerPage.getVornameInput().clear().type(user.vorname); + this.benutzerPage.getNachnameInput().clear().type(user.nachname); + this.benutzerPage.getMailInput().clear().type(user.email); + + this.benutzerPage.getAdminCheckbox().getRoot()[user.isAdmin ? 'check' : 'uncheck'](); + this.benutzerPage.getUserCheckbox().getRoot()[user.isUser ? 'check' : 'uncheck'](); + this.benutzerPage.getLoeschenCheckbox().getRoot()[user.isLoeschen ? 'check' : 'uncheck'](); + this.benutzerPage.getPostCheckbox().getRoot()[user.isPoststelle ? 'check' : 'uncheck'](); this.modifyOrganisationsEinheiten(user.organisationseinheiten); } @@ -58,4 +56,16 @@ export class E2EBenutzerExecutor { this.benutzerDeleteDialog.getDeleteButton().click(); exist(this.benutzerListPage.getList()); } + + public verifyEmail(userId: string): Chainable<Cypress.Response<void>> { + return cy.verifyEmail(userId); + } + + public resetPassword(userId: string, newPassword: string): Chainable<Cypress.Response<void>> { + return cy.resetPassword(userId, newPassword); + } + + public findUser(username: string): Chainable<UserRepresentation> { + return cy.findUser(username); + } } diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts index 2b06766322f460cdb12f6ec065e19b9e79e756f0..0c0ad0c26492851788cb31352522ac0244f4217f 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.helper.ts @@ -1,3 +1,4 @@ +import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; import { OrganisationsEinheitE2E } from '../../model/organisations-einheit'; import { AdminUserE2E } from '../../model/util'; import { E2EBenutzerExecutor } from './benutzer.executor'; @@ -5,7 +6,7 @@ import { E2EBenutzerNavigator } from './benutzer.navigator'; export class E2EBenutzerHelper { private navigator: E2EBenutzerNavigator = new E2EBenutzerNavigator(); - private executer: E2EBenutzerExecutor = new E2EBenutzerExecutor(); + private executor: E2EBenutzerExecutor = new E2EBenutzerExecutor(); public openBenutzerListPage(): void { this.navigator.openBenutzerListPage(); @@ -21,7 +22,7 @@ export class E2EBenutzerHelper { } public addBenutzer(user: AdminUserE2E): void { - this.modifyBenutzer(user); + this.createBenutzer(user); } public editBenutzerAndSave(user: AdminUserE2E): void { @@ -34,28 +35,41 @@ export class E2EBenutzerHelper { } private modifyBenutzer(user: AdminUserE2E): void { - this.executer.modifyBenutzer(user); + this.executor.modifyBenutzer(user); + } + + private createBenutzer(user: AdminUserE2E): void { + this.executor.createBenutzer(user); } public editOrganisationsEinheitenAndSave(organisationsEinheiten: OrganisationsEinheitE2E[]): void { - this.executer.modifyOrganisationsEinheiten(organisationsEinheiten); + this.executor.modifyOrganisationsEinheiten(organisationsEinheiten); this.saveAndCloseSnackbar(); } private saveAndCloseSnackbar(): void { - this.executer.saveAndCloseSnackbar(); + this.executor.saveAndCloseSnackbar(); } public saveBenutzer(): void { - this.executer.saveBenutzer(); + this.executor.saveBenutzer(); } public deleteBenutzer(userName: string): void { this.openBenutzerPage(userName); - this.executer.deleteBenutzer(); + this.executor.deleteBenutzer(); } public openBenutzerPage(userName: string): void { this.navigator.openBenutzerPage(userName); } + + public activateUser(username: string, newPassword: string): Cypress.Chainable<UserRepresentation> { + return cy + .findUser(username) + .then((userRepresentation: UserRepresentation) => cy.verifyEmail(userRepresentation.id!).then(() => userRepresentation)) + .then((userRepresentation: UserRepresentation) => + cy.resetPassword(userRepresentation.id!, newPassword).then(() => userRepresentation), + ); + } } diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts index be750e3dfbfe90c3821451932ecb475bd31cbbe5..277f735a6038200c0c21c6efaa8b06d71d6d9e9c 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.verifier.ts @@ -4,7 +4,7 @@ import { BenutzerListItemE2EComponent, } from '../../components/benutzer/benutzer.e2e.component'; import { AdminUserE2E } from '../../model/util'; -import { contains, exist, notExist } from '../../support/cypress.util'; +import { contains, exist, notBeEnabled, notExist } from '../../support/cypress.util'; import { AlfaRollen } from '../../support/user-util'; export class E2EBenutzerVerifier { @@ -29,6 +29,25 @@ export class E2EBenutzerVerifier { }); } + public verifyUserVorname(name: string): void { + this.benutzerPage.getVornameInput().should('have.value', name); + } + + public verifyAlfaRolesCorrectlyChecked(user: AdminUserE2E): void { + if (user.isUser) { + notBeEnabled(this.benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(this.benutzerPage.getPostCheckbox().getRoot()); + } + if (user.isLoeschen) { + notBeEnabled(this.benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(this.benutzerPage.getPostCheckbox().getRoot()); + } + if (user.isPoststelle) { + notBeEnabled(this.benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(this.benutzerPage.getLoeschenCheckbox().getRoot()); + } + } + public verifyUserInList(user: AdminUserE2E): void { const benutzer: BenutzerListItemE2EComponent = this.getBenutzerItem(user.username); contains(benutzer.getUserName(), user.username); diff --git a/alfa-client/apps/admin-e2e/src/helper/postfach/postfach.helper.ts b/alfa-client/apps/admin-e2e/src/helper/postfach/postfach.helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..90624b0151bdae26e5e1859734132d6b2e24cf62 --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/helper/postfach/postfach.helper.ts @@ -0,0 +1,9 @@ +import { E2EPostfachNavigator } from './postfach.navigator'; + +export class E2EPostfachHelper { + private readonly navigator: E2EPostfachNavigator = new E2EPostfachNavigator(); + + public openPostfachPage(): void { + this.navigator.openPostfachPage(); + } +} diff --git a/alfa-client/apps/admin-e2e/src/helper/postfach/postfach.navigator.ts b/alfa-client/apps/admin-e2e/src/helper/postfach/postfach.navigator.ts new file mode 100644 index 0000000000000000000000000000000000000000..074438baaaf22cc22669f085412ddd5d2f22046d --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/helper/postfach/postfach.navigator.ts @@ -0,0 +1,18 @@ +import { PostfachE2EComponent } from '../../components/postfach/postfach.e2e.component'; +import { MainPage } from '../../page-objects/main.po'; +import { exist } from '../../support/cypress.util'; + +export class E2EPostfachNavigator { + private mainPage: MainPage = new MainPage(); + private postfach: PostfachE2EComponent = new PostfachE2EComponent(); + + public openPostfachPage(): void { + this.navigateToDomain(); + this.mainPage.getPostfachNavigationItem().click(); + exist(this.postfach.getHeadline()); + } + + private navigateToDomain(): void { + this.mainPage.getHeader().getLogo().click(); + } +} diff --git a/alfa-client/apps/admin-e2e/src/model/util.ts b/alfa-client/apps/admin-e2e/src/model/util.ts index 03041ea28be5dae394e7df97d6bf38ae72d2a182..7ad5cd61ab1741c43e02532c38b711c92eb9c8dc 100644 --- a/alfa-client/apps/admin-e2e/src/model/util.ts +++ b/alfa-client/apps/admin-e2e/src/model/util.ts @@ -46,6 +46,7 @@ export interface AdminUserE2E { username: string; email: string; isAdmin?: boolean; + isDatenbeauftragung?: boolean; isUser?: boolean; isLoeschen?: boolean; isPoststelle?: boolean; 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 338c98286a6f1fc02e97d52381b99de0dbfc3db6..75ecbdaefa5d692ca637af325afb58ec05f80abe 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 @@ -22,17 +22,16 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { BuildInfoE2EComponent } from '../components/buildinfo/buildinfo.e2e.component'; -import { containClass, exist } from '../support/cypress.util'; import { HeaderE2EComponent } from './header.po'; export class MainPage { private readonly buildInfo: BuildInfoE2EComponent = new BuildInfoE2EComponent(); private readonly header: HeaderE2EComponent = new HeaderE2EComponent(); - private readonly benutzerNavigationItem: string = 'caption-Benutzer__Rollen'; - private readonly postfachNavigationItem: string = 'postfach-navigation'; - private readonly organisationEinheitNavigationItem: string = 'organisations-einheiten-navigation'; - private readonly statistikNavigationItem: string = 'statistik-navigation'; + private readonly benutzerNavigationItem: string = 'link-path-benutzer'; + private readonly organisationEinheitNavigationItem: string = 'link-path-organisationseinheiten'; + private readonly postfachNavigationItem: string = 'link-path-postfach'; + private readonly statistikNavigationItem: string = 'link-path-statistik'; public getBuildInfo(): BuildInfoE2EComponent { return this.buildInfo; @@ -46,41 +45,17 @@ export class MainPage { return cy.getTestElement(this.benutzerNavigationItem); } - public clickBenutzerNavigationItem(): void { - this.getBenutzerNavigationItem().click(); - } - - public benutzerNavigationItemIsVisible(): void { - exist(this.getBenutzerNavigationItem()); - } - public getPostfachNavigationItem(): Cypress.Chainable<Element> { return cy.getTestElement(this.postfachNavigationItem); } - public clickPostfachNavigationItem(): void { - this.getPostfachNavigationItem().click(); - } - public getOrganisationEinheitNavigationItem(): Cypress.Chainable<Element> { return cy.getTestElement(this.organisationEinheitNavigationItem); } - public clickOrganisationsEinheitenNavigationItem(): void { - this.getOrganisationEinheitNavigationItem().click(); - } - public getStatistikNavigationItem(): Cypress.Chainable<Element> { return cy.getTestElement(this.statistikNavigationItem); } - - public clickStatistikNavigationItem(): void { - this.getStatistikNavigationItem().click(); - } - - public isStatistikNavigationItemSelected(): void { - containClass(this.getStatistikNavigationItem().get('a'), 'border-selected'); - } } export function waitForSpinnerToDisappear(): boolean { diff --git a/alfa-client/apps/admin-e2e/src/support/commands.ts b/alfa-client/apps/admin-e2e/src/support/commands.ts index 15e9839f02fc0b236bc23a554de9caa710947cf1..5442317e9972045e9b6be4644c4bbd5621377682 100644 --- a/alfa-client/apps/admin-e2e/src/support/commands.ts +++ b/alfa-client/apps/admin-e2e/src/support/commands.ts @@ -24,8 +24,12 @@ /// <reference types="cypress" /> +import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; +import { getCypressEnv } from './cypress-helper'; + enum HttpMethod { POST = 'POST', + PUT = 'PUT', GET = 'GET', } @@ -81,12 +85,57 @@ Cypress.Commands.add('getUserInfo', () => { return cy.request({ method: HttpMethod.GET, url: `${getKeycloakBaseRealmUrl()}/userinfo`, - headers: { - [Header.AUTHORIZATION]: `bearer ${window.sessionStorage.getItem(ACCES_TOKEN)}`, - }, + headers: { ...buildBearerTokenAuthorizationHeader() }, }); }); +Cypress.Commands.add('findUser', (username: string) => + cy + .request<UserRepresentation[]>({ + method: HttpMethod.GET, + url: getUsersApiUrl(), + headers: { ...buildBearerTokenAuthorizationHeader() }, + }) + .then<UserRepresentation>((response: Cypress.Response<UserRepresentation[]>) => { + const users: UserRepresentation[] = response.body; + const found: UserRepresentation | undefined = users.find((u: UserRepresentation) => u.username === username); + if (found) return found; + return Promise.reject(`User with username ${username} not found`); + }), +); + +Cypress.Commands.add('verifyEmail', (userId: string) => + cy.request<void>({ + method: HttpMethod.PUT, + url: getUsersApiUrl() + '/' + userId, + headers: { ...buildBearerTokenAuthorizationHeader() }, + body: { emailVerified: true }, + }), +); + +Cypress.Commands.add('resetPassword', (userId: string, newPassword: string) => + cy.request<void>({ + method: HttpMethod.PUT, + url: getUsersApiUrl() + '/' + userId + '/reset-password', + headers: { ...buildBearerTokenAuthorizationHeader() }, + body: { type: 'password', temporary: false, value: newPassword }, + }), +); + +function buildBearerTokenAuthorizationHeader(): object { + return { + [Header.AUTHORIZATION]: `Bearer ${getAccessToken()}`, + }; +} + +function getAccessToken(): string | null { + return window.sessionStorage.getItem(ACCES_TOKEN); +} + +function getUsersApiUrl(): string { + return getCypressEnv('keycloakUrl') + '/admin/realms/' + getCypressEnv('keycloakRealm') + '/users'; +} + function getKeycloakBaseRealmUrl(): string { return `${Cypress.env(CypressEnv.KEYCLOAK_URL)}realms/${Cypress.env(CypressEnv.KEYCLOAK_REALM)}/protocol/openid-connect`; } @@ -115,6 +164,12 @@ declare global { findElement(selector: string): Chainable<Element>; getUserInfo(): Chainable<void>; + + findUser(username: string): Chainable<UserRepresentation>; + + verifyEmail(userId: string): Chainable<Response<void>>; + + resetPassword(userId: string, password: string): Chainable<Response<void>>; } } } diff --git a/alfa-client/apps/admin-e2e/src/support/cypress.util.ts b/alfa-client/apps/admin-e2e/src/support/cypress.util.ts index 637963609081aa8cddbd24bbf5f56369b80cf0ef..63f3c24872ebea08644aa85eead331dac07f1b40 100644 --- a/alfa-client/apps/admin-e2e/src/support/cypress.util.ts +++ b/alfa-client/apps/admin-e2e/src/support/cypress.util.ts @@ -60,10 +60,6 @@ export function mouseEnter(element: Cypress.Chainable<Element>): void { element.trigger('mouseenter'); } -export function mouseOver(element: Cypress.Chainable<Element>): void { - element.trigger('mouseover'); -} - export function contains(element: Cypress.Chainable<Element>, containing: string): void { element.should('exist').contains(containing); } @@ -128,10 +124,6 @@ export function enterWith(element: Cypress.Chainable<Element>, value: string, de element.type(CypressKeyboardActions.ENTER); } -export function typeText(element: Cypress.Chainable<Element>, value: string): void { - element.type(value); -} - export function backspaceOn(element: Cypress.Chainable<Element>): void { element.type(CypressKeyboardActions.BACKSPACE); } diff --git a/alfa-client/apps/admin-e2e/src/support/tech-util.ts b/alfa-client/apps/admin-e2e/src/support/tech-util.ts index a1bbcb74ae2b53c9fc3fc05bbcab81896c4e183e..6e6c57d156a011e83fe53bee52ad26a56a384ad2 100644 --- a/alfa-client/apps/admin-e2e/src/support/tech-util.ts +++ b/alfa-client/apps/admin-e2e/src/support/tech-util.ts @@ -10,6 +10,6 @@ export function replaceAllWhitespaces(value: string, replaceWith: string): strin return value.replace(/ /g, replaceWith); } -export function simpleTransliteration(value: string) { +export function simpleTransliteration(value: string): string { return value.normalize('NFKD').replace(/[^-A-Za-z0-9_]/g, ''); } diff --git a/alfa-client/apps/admin-e2e/src/support/user-util.ts b/alfa-client/apps/admin-e2e/src/support/user-util.ts index d5e7462638087a82b1e4d365e0a59e11932962e5..0b8f311d0e9cbb0e5f453ee3e7c1e72a80548529 100644 --- a/alfa-client/apps/admin-e2e/src/support/user-util.ts +++ b/alfa-client/apps/admin-e2e/src/support/user-util.ts @@ -50,15 +50,19 @@ function login(userJson: string): void { // Hinweis: cacheAcrossSpecs: true lässt Tests umfallen export function loginByUi(user: UserE2E): void { + loginByUsernameAndPassword(user.name, user.password); +} + +export function loginByUsernameAndPassword(username: string, password: string): void { cy.session( - user.name, + username, () => { cy.visit('/') .get('#kc-login') .should('exist') .then(() => { - cy.get('#username').type(user.name); - cy.get('#password').type(user.password); + cy.get('#username').type(username); + cy.get('#password').type(password); cy.get('#kc-login').click(); }); }, @@ -89,10 +93,12 @@ export enum AlfaRollen { LOESCHEN = 'VERWALTUNG_LOESCHEN', POSTSTELLE = 'VERWALTUNG_POSTSTELLE', ADMIN = 'ADMIN_ADMIN', + DATEN = 'DATENBEAUFTRAGUNG', } export enum AlfaUsers { - ARAINE = 'ariane', + ARIANE = 'ariane', + DARIA = 'daria', DOROTHEA = 'dorothea', LUDWIG = 'ludwig', PETER = 'peter', diff --git a/alfa-client/apps/admin/package.json b/alfa-client/apps/admin/package.json index 924f232583709ebf8224d6a8301cd00d84cb1307..d124f972122f91564b8d04044ab8541beb8b4ae6 100644 --- a/alfa-client/apps/admin/package.json +++ b/alfa-client/apps/admin/package.json @@ -1,4 +1,4 @@ { "name": "admin", - "version": "1.6.0-SNAPSHOT" + "version": "1.7.0-SNAPSHOT" } diff --git a/alfa-client/apps/admin/src/app/app.component.spec.ts b/alfa-client/apps/admin/src/app/app.component.spec.ts index b0a354caa1b666ad9ad15a4527e77f8a632496c6..baa8c7fcc532a0e859fe596782a94bf7b2257803 100644 --- a/alfa-client/apps/admin/src/app/app.component.spec.ts +++ b/alfa-client/apps/admin/src/app/app.component.spec.ts @@ -55,29 +55,31 @@ describe('AppComponent', () => { const routerOutletSelector: string = getDataTestIdOf('router-outlet'); const menuContainer: string = getDataTestIdOf('menu-container'); - const authenticationService: Mock<AuthenticationService> = { - ...mock(AuthenticationService), - login: jest.fn().mockResolvedValue(Promise.resolve()), - }; - - const router: Mock<Router> = mock(Router); - const route: Mock<ActivatedRoute> = { - ...mock(ActivatedRoute), - snapshot: { - queryParams: { - iss: 'some-iss', - state: 'some-state', - session_state: 'some-session-state', - code: 'some-code', - }, - } as any, - }; - - const apiRootService: Mock<ApiRootService> = mock(ApiRootService); + let authenticationService: Mock<AuthenticationService>; + let router: Mock<Router>; + let route: Mock<ActivatedRoute>; + let apiRootService: Mock<ApiRootService>; let configurationService: Mock<ConfigurationService>; let keycloakTokenService: Mock<KeycloakTokenService>; beforeEach(async () => { + authenticationService = { + ...mock(AuthenticationService), + login: jest.fn().mockResolvedValue(Promise.resolve()), + }; + router = mock(Router); + route = { + ...mock(ActivatedRoute), + snapshot: { + queryParams: { + iss: 'some-iss', + state: 'some-state', + session_state: 'some-session-state', + code: 'some-code', + }, + } as any, + }; + apiRootService = mock(ApiRootService); configurationService = mock(ConfigurationService); keycloakTokenService = mock(KeycloakTokenService); @@ -145,81 +147,110 @@ describe('AppComponent', () => { expect(authenticationService.login).toHaveBeenCalled(); }); - it('should call doAfterLoggedIn', async () => { - component.doAfterLoggedIn = jest.fn(); + it('should call doAfterLoggedIn only once', async () => { + component._doAfterLoggedIn = jest.fn(); component.ngOnInit(); await fixture.whenStable(); - expect(component.doAfterLoggedIn).toHaveBeenCalled(); + expect(component._doAfterLoggedIn).toHaveBeenCalledTimes(1); }); }); describe('do after logged in', () => { beforeEach(() => { - component.evaluateInitialNavigation = jest.fn(); + component._evaluateInitialNavigation = jest.fn(); }); it('should call apiRootService to getApiRoot', () => { - component.doAfterLoggedIn(); + component._doAfterLoggedIn(); expect(apiRootService.getApiRoot).toHaveBeenCalled(); }); it('should call keycloak token service to register token provider', () => { - component.doAfterLoggedIn(); + component._doAfterLoggedIn(); expect(keycloakTokenService.registerAccessTokenProvider).toHaveBeenCalled(); }); it('should call evaluateInitialNavigation', () => { - component.doAfterLoggedIn(); + component._doAfterLoggedIn(); - expect(component.evaluateInitialNavigation).toHaveBeenCalled(); + expect(component._evaluateInitialNavigation).toHaveBeenCalled(); }); }); describe('evaluate initial navigation', () => { beforeEach(() => { - component.evaluateNavigationByApiRoot = jest.fn(); + component._evaluateNavigationByApiRoot = jest.fn(); + component._subscribeApiRootForEvaluation = jest.fn(); }); - it('should call evaluate navigation by apiRoot', () => { - const apiRootResource: ApiRootResource = createApiRootResource(); + it('should call router navigate', () => { + window.location.pathname = '/path'; + (router as any).url = '/path'; + + component._evaluateInitialNavigation(); + + expect(router.navigate).toHaveBeenCalledWith([window.location.pathname]); + }); + + it('should call subscribe api root evaluation if url starts with /?state', () => { + (router as any).url = '/?state=some-state'; + + component._evaluateInitialNavigation(); + + expect(component._subscribeApiRootForEvaluation).toHaveBeenCalled(); + }); + }); + + describe('subscribeApiRootForEvaluation', () => { + const apiRootResource: ApiRootResource = createApiRootResource(); + + beforeEach(() => { component.apiRootStateResource$ = of(createStateResource(apiRootResource)); + component._evaluateNavigationByApiRoot = jest.fn(); + }); - component.evaluateInitialNavigation(); + it('should set apiRootSubscription', () => { + component._subscribeApiRootForEvaluation(); + + expect(component.apiRootSubscription).toBeDefined(); + }); + + it('should call evaluate navigation by apiRoot', () => { + component._subscribeApiRootForEvaluation(); - expect(component.evaluateNavigationByApiRoot).toHaveBeenCalledWith(apiRootResource); + expect(component._evaluateNavigationByApiRoot).toHaveBeenCalledWith(apiRootResource); }); it('should NOT call evaluate navigation by apiRoot if resource is loading', () => { - component.apiRootStateResource$ = of(createEmptyStateResource<ApiRootResource>(true)); - component.evaluateNavigationByApiRoot = jest.fn(); + component.apiRootStateResource$ = of(createStateResource(apiRootResource, true)); - component.evaluateInitialNavigation(); + component._subscribeApiRootForEvaluation(); - expect(component.evaluateNavigationByApiRoot).not.toHaveBeenCalled(); + expect(component._evaluateNavigationByApiRoot).not.toHaveBeenCalled(); }); }); describe('evaluate navigation api root', () => { it('should evaluate navigation by configuration if link exists', () => { - component.evaluateNavigationByConfiguration = jest.fn(); + component._evaluateNavigationByConfiguration = jest.fn(); const apiRootResource: ApiRootResource = createApiRootResource([ApiRootLinkRel.CONFIGURATION]); - component.evaluateNavigationByApiRoot(apiRootResource); + component._evaluateNavigationByApiRoot(apiRootResource); - expect(component.evaluateNavigationByConfiguration).toHaveBeenCalled(); + expect(component._evaluateNavigationByConfiguration).toHaveBeenCalled(); }); it('should navigate by api root if link is missing', () => { - component.navigateByApiRoot = jest.fn(); + component._navigateByApiRoot = jest.fn(); const apiRootResource: ApiRootResource = createApiRootResource(); - component.evaluateNavigationByApiRoot(apiRootResource); + component._evaluateNavigationByApiRoot(apiRootResource); - expect(component.navigateByApiRoot).toHaveBeenCalledWith(apiRootResource); + expect(component._navigateByApiRoot).toHaveBeenCalledWith(apiRootResource); }); }); @@ -228,83 +259,83 @@ describe('AppComponent', () => { beforeEach(() => { configurationService.get.mockReturnValue(of(createStateResource(configurationResource))); - component.navigateByConfiguration = jest.fn(); + component._navigateByConfiguration = jest.fn(); }); it('should call configuration service to get resource', () => { - component.evaluateNavigationByConfiguration(); + component._evaluateNavigationByConfiguration(); expect(configurationService.get).toHaveBeenCalled(); }); it('should call navigate by configuration', () => { - component.evaluateNavigationByConfiguration(); + component._evaluateNavigationByConfiguration(); - expect(component.navigateByConfiguration).toHaveBeenCalledWith(configurationResource); + expect(component._navigateByConfiguration).toHaveBeenCalledWith(configurationResource); }); it('should NOT call navigate by configuration if resource is loading', () => { configurationService.get.mockReturnValue(of(createEmptyStateResource<ConfigurationResource>(true))); - component.evaluateNavigationByConfiguration(); + component._evaluateNavigationByConfiguration(); - expect(component.navigateByConfiguration).not.toHaveBeenCalled(); + expect(component._navigateByConfiguration).not.toHaveBeenCalled(); }); }); describe('navigate by configuration', () => { beforeEach(() => { - component.unsubscribe = jest.fn(); + component._unsubscribe = jest.fn(); }); it('should navigate to postfach if settings link exists', () => { - component.navigateByConfiguration(createConfigurationResource([ConfigurationLinkRel.SETTING])); + component._navigateByConfiguration(createConfigurationResource([ConfigurationLinkRel.SETTING])); expect(router.navigate).toHaveBeenCalledWith(['/postfach']); }); it('should navigate to statistik if aggregation mapping link exists', () => { - component.navigateByConfiguration(createConfigurationResource([ConfigurationLinkRel.AGGREGATION_MAPPINGS])); + component._navigateByConfiguration(createConfigurationResource([ConfigurationLinkRel.AGGREGATION_MAPPINGS])); expect(router.navigate).toHaveBeenCalledWith(['/statistik']); }); it('should navigate to unavailable page if no link exists', () => { - component.navigateByConfiguration(createConfigurationResource()); + component._navigateByConfiguration(createConfigurationResource()); expect(router.navigate).toHaveBeenCalledWith(['/unavailable']); }); it('should call unsubscribe', () => { - component.navigateByConfiguration(createConfigurationResource()); + component._navigateByConfiguration(createConfigurationResource()); - expect(component.unsubscribe).toHaveBeenCalled(); + expect(component._unsubscribe).toHaveBeenCalled(); }); }); describe('navigate by api root', () => { beforeEach(() => { - component.unsubscribe = jest.fn(); + component._unsubscribe = jest.fn(); }); it('should navigate to benutzer und rollen if users link exists', () => { const apiRootResource: ApiRootResource = createApiRootResource([ApiRootLinkRel.USERS]); - component.navigateByApiRoot(apiRootResource); + component._navigateByApiRoot(apiRootResource); expect(router.navigate).toHaveBeenCalledWith([`/${ROUTES.BENUTZER}`]); }); it('should navigate to unavailable page if no link exists', () => { - component.navigateByApiRoot(createApiRootResource()); + component._navigateByApiRoot(createApiRootResource()); expect(router.navigate).toHaveBeenCalledWith([`/${ROUTES.UNAVAILABLE}`]); }); it('should call unsubscribe', () => { - component.navigateByApiRoot(createApiRootResource()); + component._navigateByApiRoot(createApiRootResource()); - expect(component.unsubscribe).toHaveBeenCalled(); + expect(component._unsubscribe).toHaveBeenCalled(); }); }); @@ -314,7 +345,7 @@ describe('AppComponent', () => { component.apiRootSubscription = <any>mock(Subscription); component.apiRootSubscription.unsubscribe = jest.fn(); - component.unsubscribe(); + component._unsubscribe(); expect(component.apiRootSubscription.unsubscribe).toHaveBeenCalled(); }); @@ -323,7 +354,7 @@ describe('AppComponent', () => { component.apiRootSubscription = undefined; const unsubscribeSpy: jest.SpyInstance = jest.spyOn(Subscription.prototype, 'unsubscribe'); - component.unsubscribe(); + component._unsubscribe(); expect(unsubscribeSpy).not.toHaveBeenCalled(); unsubscribeSpy.mockRestore(); @@ -335,7 +366,7 @@ describe('AppComponent', () => { component.configurationSubscription = <any>mock(Subscription); component.configurationSubscription.unsubscribe = jest.fn(); - component.unsubscribe(); + component._unsubscribe(); expect(component.configurationSubscription.unsubscribe).toHaveBeenCalled(); }); @@ -344,7 +375,7 @@ describe('AppComponent', () => { component.apiRootSubscription = undefined; const unsubscribeSpy: jest.SpyInstance = jest.spyOn(Subscription.prototype, 'unsubscribe'); - component.unsubscribe(); + component._unsubscribe(); expect(unsubscribeSpy).not.toHaveBeenCalled(); unsubscribeSpy.mockRestore(); diff --git a/alfa-client/apps/admin/src/app/app.component.ts b/alfa-client/apps/admin/src/app/app.component.ts index bb5f2013fde365c95ae01525f1b8cb170decddd6..909b6cd198bd3ccb91dd61e922abb6a1ed79210c 100644 --- a/alfa-client/apps/admin/src/app/app.component.ts +++ b/alfa-client/apps/admin/src/app/app.component.ts @@ -33,13 +33,7 @@ import { Component, inject, OnInit } from '@angular/core'; import { Router, RouterLink, RouterOutlet } from '@angular/router'; import { AuthenticationService } from '@authentication'; import { hasLink } from '@ngxp/rest'; -import { - AdminLogoIconComponent, - NavbarComponent, - NavItemComponent, - OrgaUnitIconComponent, - UsersIconComponent, -} from '@ods/system'; +import { AdminLogoIconComponent, NavbarComponent, NavItemComponent, OrgaUnitIconComponent, UsersIconComponent, } from '@ods/system'; import { filter, Observable, Subscription } from 'rxjs'; import { UserProfileButtonContainerComponent } from '../../../../libs/admin/user-profile/src/lib/user-menu/user-profile.button-container.component'; import { UnavailablePageComponent } from '../pages/unavailable/unavailable-page/unavailable-page.component'; @@ -83,37 +77,49 @@ export class AppComponent implements OnInit { public readonly routes = ROUTES; ngOnInit(): void { - this.authenticationService.login().then(() => this.doAfterLoggedIn()); + this.authenticationService.login().then(() => this._doAfterLoggedIn()); } - doAfterLoggedIn(): void { + _doAfterLoggedIn(): void { this.apiRootStateResource$ = this.apiRootService.getApiRoot(); this.keycloakTokenService.registerAccessTokenProvider(); - this.evaluateInitialNavigation(); + this._evaluateInitialNavigation(); } - evaluateInitialNavigation(): void { + _evaluateInitialNavigation(): void { + if (this.router.url.startsWith('/?state')) { + this._subscribeApiRootForEvaluation(); + } else { + this.refreshForGuardEvaluation(); + } + } + + _subscribeApiRootForEvaluation(): void { this.apiRootSubscription = this.apiRootStateResource$ .pipe(filter(isLoaded), mapToResource<ApiRootResource>()) - .subscribe((apiRootResource: ApiRootResource) => this.evaluateNavigationByApiRoot(apiRootResource)); + .subscribe((apiRootResource: ApiRootResource) => this._evaluateNavigationByApiRoot(apiRootResource)); + } + + private refreshForGuardEvaluation(): void { + this.router.navigate([window.location.pathname]); } - evaluateNavigationByApiRoot(apiRootResource: ApiRootResource): void { + _evaluateNavigationByApiRoot(apiRootResource: ApiRootResource): void { if (hasLink(apiRootResource, ApiRootLinkRel.CONFIGURATION)) { - this.evaluateNavigationByConfiguration(); + this._evaluateNavigationByConfiguration(); } else { - this.navigateByApiRoot(apiRootResource); + this._navigateByApiRoot(apiRootResource); } } - evaluateNavigationByConfiguration(): void { + _evaluateNavigationByConfiguration(): void { this.configurationSubscription = this.configurationService .get() .pipe(filter(isLoaded), mapToResource<ApiRootResource>()) - .subscribe((configurationResource: ConfigurationResource) => this.navigateByConfiguration(configurationResource)); + .subscribe((configurationResource: ConfigurationResource) => this._navigateByConfiguration(configurationResource)); } - navigateByConfiguration(configurationResource: ConfigurationResource): void { + _navigateByConfiguration(configurationResource: ConfigurationResource): void { if (hasLink(configurationResource, ConfigurationLinkRel.SETTING)) { this.navigate(ROUTES.POSTFACH); } else if (hasLink(configurationResource, ConfigurationLinkRel.AGGREGATION_MAPPINGS)) { @@ -121,23 +127,23 @@ export class AppComponent implements OnInit { } else { this.navigate(ROUTES.UNAVAILABLE); } - this.unsubscribe(); + this._unsubscribe(); } - navigateByApiRoot(apiRootResource: ApiRootResource): void { + _navigateByApiRoot(apiRootResource: ApiRootResource): void { if (hasLink(apiRootResource, ApiRootLinkRel.USERS)) { this.navigate(ROUTES.BENUTZER); } else { this.navigate(ROUTES.UNAVAILABLE); } - this.unsubscribe(); + this._unsubscribe(); } private navigate(routePath: string): void { this.router.navigate(['/' + routePath]); } - unsubscribe(): void { + _unsubscribe(): void { if (isNotUndefined(this.apiRootSubscription)) this.apiRootSubscription.unsubscribe(); if (isNotUndefined(this.configurationSubscription)) this.configurationSubscription.unsubscribe(); } diff --git a/alfa-client/apps/admin/src/app/app.guard.spec.ts b/alfa-client/apps/admin/src/app/app.guard.spec.ts index 24e0a21eca4fb630c66112e19ba4b0024bf983a9..41cfe7506366e35bdd3d16d4f24d054c16eef40c 100644 --- a/alfa-client/apps/admin/src/app/app.guard.spec.ts +++ b/alfa-client/apps/admin/src/app/app.guard.spec.ts @@ -27,6 +27,7 @@ import { createStateResource, LinkRelationName, StateResource } from '@alfa-clie import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { TestBed } from '@angular/core/testing'; import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; +import { AuthenticationService } from '@authentication'; import { Resource } from '@ngxp/rest'; import { createConfigurationResource } from 'libs/admin/configuration-shared/test/configuration'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; @@ -139,10 +140,49 @@ describe('Guard', () => { const resource: Resource = createDummyResource([DummyLinkRel.DUMMY]); const stateResource$: Observable<StateResource<Resource>> = of(createStateResource(resource)); + let authService: Mock<AuthenticationService>; + let router: Mock<Router>; + + beforeEach(() => { + authService = { + ...mock(AuthenticationService), + isLoggedIn: jest.fn().mockReturnValue(true), + }; + router = mock(Router); + + TestBed.configureTestingModule({ + providers: [ + { + provide: Router, + useValue: router, + }, + { + provide: AuthenticationService, + useValue: authService, + }, + ], + }); + }); + afterEach(() => { jest.restoreAllMocks(); }); + it('should call authenticationService isLoggedIn', () => { + evaluate().subscribe(); + + expect(authService.isLoggedIn).toHaveBeenCalled(); + }); + + it('should return observable true if not logged in', (done) => { + authService.isLoggedIn.mockReturnValue(false); + + evaluate().subscribe((resolvedValue) => { + expect(resolvedValue).toEqual(true); + done(); + }); + }); + it('should evaluate resource', () => { const urlTreeMock: Mock<UrlTree> = mock(UrlTree); const evaluateResourceSpy: jest.SpyInstance = jest @@ -151,7 +191,7 @@ describe('Guard', () => { evaluate().subscribe(); - expect(evaluateResourceSpy).toHaveBeenCalledWith(resource, DummyLinkRel.DUMMY); + expect(evaluateResourceSpy).toHaveBeenCalledWith(resource, DummyLinkRel.DUMMY, router); }); it('should return evaluated boolean', (done) => { @@ -181,34 +221,23 @@ describe('Guard', () => { }); describe('evaluate resource', () => { - let router: Mock<Router>; - - beforeEach(() => { - router = mock(Router); - - TestBed.configureTestingModule({ - providers: [ - { - provide: Router, - useValue: router, - }, - ], - }); - }); + const router: Mock<Router> = mock(Router); afterEach(() => { jest.restoreAllMocks(); }); it('should return true if link exists', () => { - const result: boolean = <boolean>evaluateResource(createDummyResource([DummyLinkRel.DUMMY])); + const result: boolean = <boolean>( + Guard.evaluateResource(createDummyResource([DummyLinkRel.DUMMY]), DummyLinkRel.DUMMY, useFromMock(router)) + ); expect(result).toBeTruthy(); }); describe('if link not exists', () => { it('should call router', () => { - evaluateResource(createDummyResource()); + Guard.evaluateResource(createDummyResource(), DummyLinkRel.DUMMY, useFromMock(router)); expect(router.createUrlTree).toHaveBeenCalledWith(['/unavailable']); }); @@ -217,14 +246,10 @@ describe('Guard', () => { const urlTree: Mock<UrlTree> = mock(UrlTree); router.createUrlTree.mockReturnValue(urlTree); - const result: UrlTree = <UrlTree>evaluateResource(createDummyResource()); + const result: UrlTree = <UrlTree>Guard.evaluateResource(createDummyResource(), DummyLinkRel.DUMMY, useFromMock(router)); expect(result).toEqual(urlTree); }); }); - - function evaluateResource(dummyResource: Resource): boolean | UrlTree { - return <boolean | UrlTree>TestBed.runInInjectionContext(() => Guard.evaluateResource(dummyResource, DummyLinkRel.DUMMY)); - } }); }); diff --git a/alfa-client/apps/admin/src/app/app.guard.ts b/alfa-client/apps/admin/src/app/app.guard.ts index 85625be095c256aa593faa2d0d415352258aa1e0..c61df188c0c4ea38de5c66cfe69a55e39fc780ce 100644 --- a/alfa-client/apps/admin/src/app/app.guard.ts +++ b/alfa-client/apps/admin/src/app/app.guard.ts @@ -21,24 +21,25 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { ConfigurationService } from '@admin-client/configuration-shared'; import { ROUTES } from '@admin-client/shared'; import { ApiRootService } from '@alfa-client/api-root-shared'; import { LinkRelationName, mapToResource, StateResource } from '@alfa-client/tech-shared'; import { inject } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivateFn, Router, UrlTree } from '@angular/router'; +import { AuthenticationService } from '@authentication'; import { hasLink, Resource } from '@ngxp/rest'; -import { filter, map, Observable } from 'rxjs'; +import { filter, map, Observable, of } from 'rxjs'; import { GuardData } from './app.routes'; -import { ConfigurationService } from '@admin-client/configuration-shared'; import * as Guard from './app.guard'; -export const apiRootGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => { +export const apiRootGuard: CanActivateFn = (route: ActivatedRouteSnapshot): Observable<true | UrlTree> => { const apiRootService: ApiRootService = inject(ApiRootService); return Guard.evaluate(apiRootService.getApiRoot(), getLinkRelationName(route)); }; -export const configurationGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => { +export const configurationGuard: CanActivateFn = (route: ActivatedRouteSnapshot): Observable<true | UrlTree> => { const configurationService: ConfigurationService = inject(ConfigurationService); return Guard.evaluate(configurationService.get(), getLinkRelationName(route)); }; @@ -46,11 +47,16 @@ export const configurationGuard: CanActivateFn = (route: ActivatedRouteSnapshot) export function evaluate( stateResource$: Observable<StateResource<Resource>>, linkRelationName: LinkRelationName, -): Observable<boolean | UrlTree> { +): Observable<true | UrlTree> { + const authService = inject(AuthenticationService); + const router = inject(Router); + + if (!authService.isLoggedIn()) return of(true); + return stateResource$.pipe( - filter((stateResource: StateResource<Resource>) => stateResource.loaded), + filter((stateResource: StateResource<Resource>): boolean => stateResource.loaded), mapToResource<Resource>(), - map((resource: Resource) => Guard.evaluateResource(resource, linkRelationName)), + map((resource: Resource): true | UrlTree => Guard.evaluateResource(resource, linkRelationName, router)), ); } @@ -58,10 +64,10 @@ function getLinkRelationName(route: ActivatedRouteSnapshot): string { return (<GuardData>route.data).linkRelName; } -export function evaluateResource(resource: Resource, linkRelationName: LinkRelationName): boolean | UrlTree { - return hasLink(resource, linkRelationName) ? true : redirectToUnavailable(); +export function evaluateResource(resource: Resource, linkRelationName: LinkRelationName, router: Router): true | UrlTree { + return hasLink(resource, linkRelationName) ? true : redirectToUnavailable(router); } -function redirectToUnavailable(): UrlTree { - return inject(Router).createUrlTree(['/' + ROUTES.UNAVAILABLE]); +function redirectToUnavailable(router: Router): UrlTree { + return router.createUrlTree(['/' + ROUTES.UNAVAILABLE]); } diff --git a/alfa-client/apps/admin/src/app/app.routes.ts b/alfa-client/apps/admin/src/app/app.routes.ts index 279141277b1bbd700ca663d7009e886b89453429..c5974993c237ec15254220a64157b63ae0f46136 100644 --- a/alfa-client/apps/admin/src/app/app.routes.ts +++ b/alfa-client/apps/admin/src/app/app.routes.ts @@ -44,6 +44,7 @@ export const appRoutes: Route[] = [ path: ROUTES.POSTFACH, component: PostfachPageComponent, title: 'Admin | Postfach', + runGuardsAndResolvers: 'always', canActivate: [configurationGuard], data: <GuardData>{ linkRelName: ConfigurationLinkRel.SETTING }, }, @@ -51,6 +52,7 @@ export const appRoutes: Route[] = [ path: ROUTES.BENUTZER, component: UserListPageComponent, title: 'Admin | Benutzer', + runGuardsAndResolvers: 'always', canActivate: [apiRootGuard], data: <GuardData>{ linkRelName: ApiRootLinkRel.USERS }, }, @@ -58,6 +60,7 @@ export const appRoutes: Route[] = [ path: ROUTES.BENUTZER_NEU, component: UserFormPageComponent, title: 'Admin | Benutzer anlegen', + runGuardsAndResolvers: 'always', canActivate: [apiRootGuard], data: <GuardData>{ linkRelName: ApiRootLinkRel.USERS }, }, @@ -65,6 +68,7 @@ export const appRoutes: Route[] = [ path: ROUTES.BENUTZER_ID, component: UserFormComponent, title: 'Admin | Benutzer bearbeiten', + runGuardsAndResolvers: 'always', canActivate: [apiRootGuard], data: <GuardData>{ linkRelName: ApiRootLinkRel.USERS }, }, @@ -82,6 +86,7 @@ export const appRoutes: Route[] = [ path: ROUTES.STATISTIK, component: StatistikPageComponent, title: 'Admin | Statistik', + runGuardsAndResolvers: 'always', canActivate: [configurationGuard], data: <GuardData>{ linkRelName: ConfigurationLinkRel.AGGREGATION_MAPPINGS }, }, @@ -89,7 +94,13 @@ export const appRoutes: Route[] = [ path: ROUTES.STATISTIK_NEU, component: StatistikFieldsFormPageComponent, title: 'Admin | Statistik weitere Felder auswerten', + runGuardsAndResolvers: 'always', canActivate: [configurationGuard], data: <GuardData>{ linkRelName: ConfigurationLinkRel.AGGREGATION_MAPPINGS }, }, + { + path: '**', + component: UnavailablePageComponent, + title: 'Unavailable', + }, ]; diff --git a/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts index 7e7207e39038dfd923b4b1560bdda6864496a0f2..dbcb98b4dc2a1a77eb110910dd711bf5b9e40dff 100644 --- a/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts @@ -24,46 +24,45 @@ import { convertToDataTestId } from '../../support/tech.util'; export class AttachmentContainerE2EComponent { - private readonly locatorFileUploadInput: string = '-file-upload-input'; + private readonly multiUploadInput: string = 'multi-file-upload-button'; + private readonly attachmentList: AttachmentListE2EComponent = new AttachmentListE2EComponent(); public getList(): AttachmentListE2EComponent { return this.attachmentList; } - public getUploadInput() { - return cy.getTestElementContaining(this.locatorFileUploadInput); + //TODO Rename getMultiUploadButton + public getUploadInput(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.multiUploadInput); } } export class AttachmentListE2EComponent { private readonly locatorRoot: string = 'file-list'; - private readonly downloadAttachmentsButton: string = 'download-archive-file-button'; - public getRoot() { - return cy.getTestElement(this.locatorRoot); - } + private readonly downloadArchiveButton: string = 'download-archive-file-button'; - public getItem(fileName: string): AttachmentE2EItem { - return new AttachmentE2EItem(fileName); + public getRoot(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.locatorRoot); } - public getLoadingOrErrorItem(fileName: string): LoadingErrorAttachmentE2EItem { - return new LoadingErrorAttachmentE2EItem(fileName); + public getItem(fileName: string): AttachmentListItemE2EComponent { + return new AttachmentListItemE2EComponent(fileName); } - public getDownloadAttachmentsButton(): Cypress.Chainable<JQuery<HTMLElement>> { - return this.getRoot().findTestElementWithClass(this.downloadAttachmentsButton); + public getLoadingOrErrorItem(fileName: string): LoadingErrorAttachmentListeItemE2EComponent { + return new LoadingErrorAttachmentListeItemE2EComponent(fileName); } - public downloadAttachments(): Cypress.Chainable<any> { - return this.getDownloadAttachmentsButton().click(); + public getDownloadArchiveButton(): Cypress.Chainable<HTMLElement> { + return this.getRoot().getTestElement(this.downloadArchiveButton); } } -class AttachmentE2EItem { - private readonly locatorDeleteButton: string = 'delete-file-button'; - private readonly locatorDownloadButton: string = 'download-file-button'; +export class AttachmentListItemE2EComponent { + private readonly deleteButton: string = 'delete-file-button'; + private readonly downloadButton: string = 'download-file-button'; private locatorRoot: string; @@ -71,20 +70,20 @@ class AttachmentE2EItem { this.locatorRoot = convertToDataTestId(this.fileName) + '-file-item'; } - public getRoot() { + public getRoot(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.locatorRoot); } - public getDeleteButton() { - return this.getRoot().findTestElementWithClass(this.locatorDeleteButton); + public getDeleteButton(): Cypress.Chainable<HTMLElement> { + return this.getRoot().findTestElementWithClass(this.deleteButton); } - public getDownloadButton() { - return this.getRoot().findTestElementWithClass(this.locatorDownloadButton); + public getDownloadButton(): Cypress.Chainable<HTMLElement> { + return this.getRoot().findTestElementWithClass(this.downloadButton); } } -class LoadingErrorAttachmentE2EItem { +export class LoadingErrorAttachmentListeItemE2EComponent { private readonly root: string; private readonly attachmentSuffix: string = '-file-upload-list-item-attachment-upload'; @@ -92,7 +91,7 @@ class LoadingErrorAttachmentE2EItem { this.root = convertToDataTestId(this.fileName) + this.attachmentSuffix; } - public getRoot() { + public getRoot(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.root); } } diff --git a/alfa-client/apps/alfa-e2e/src/components/kommentar/kommentar-list.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/kommentar/kommentar-list.e2e.component.ts index 42e791b9899b0348637184324cfcf91f0ef5d60b..09cebe8b80f722d1869036d55767e47104031728 100644 --- a/alfa-client/apps/alfa-e2e/src/components/kommentar/kommentar-list.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/kommentar/kommentar-list.e2e.component.ts @@ -25,54 +25,60 @@ import { convertToDataTestId } from '../../support/tech.util'; import { AttachmentContainerE2EComponent } from '../attachment/attachment.e2e.component'; import { UserProfileE2EComponent } from '../user-profile/user-profile.component.e2e'; -export class KommentareInVorgangE2EComponent { - readonly locatorHinzufuegenButton: string = 'create-kommentar'; - readonly locatorFormular: string = 'kommentar-formular'; - readonly locatorFormularSpeichernButton: string = 'add-button'; - readonly locatorFormularAbbrechenButton: string = 'cancel-button'; - readonly locatorKommentarList: string = 'kommentar-list-in-vorgang'; - readonly locatorTextInput: string = 'Kommentar-textarea-input'; - readonly locatorTextError: string = 'Kommentar-textarea-error'; - - private readonly attachmentContainer: AttachmentContainerE2EComponent = - new AttachmentContainerE2EComponent(); - - readonly locatorRoot: string = 'kommentar-container-in-vorgang'; - - public getRoot() { - return cy.getTestElement(this.locatorRoot); +export class KommentarListInVorgangE2EComponent { + readonly hinzufuegenButton: string = 'create-kommentar'; + + readonly root: string = 'kommentar-container-in-vorgang'; + + readonly kommentarList: string = 'kommentar-list-in-vorgang'; + + readonly formular: string = 'kommentar-formular'; + readonly formularItem: string = 'kommentar-list-item-form'; + readonly formularSpeichernButton: string = 'add-button'; + readonly formularAbbrechenButton: string = 'cancel-button'; + readonly textInput: string = 'Kommentar-textarea-input'; + readonly textError: string = 'Kommentar-textarea-error'; + + private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); + + public getRoot(): Cypress.Chainable<Element> { + return cy.getTestElement(this.root); + } + + public getFormular(): Cypress.Chainable<Element> { + return cy.getTestElement(this.formular); } - public getFormular() { - return cy.getTestElement(this.locatorFormular); + public getFormulare(): Cypress.Chainable<Element[]> { + return cy.getTestElement(this.formularItem); } - public getHinzufuegenButton() { - return cy.getTestElement(this.locatorHinzufuegenButton); + public getHinzufuegenButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.hinzufuegenButton); } - public getFormularSpeichernButton() { - return cy.getTestElement(this.locatorFormularSpeichernButton); + public getFormularSpeichernButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.formularSpeichernButton); } - public getFormularAbbrechenButton() { - return cy.getTestElement(this.locatorFormularAbbrechenButton); + public getFormularAbbrechenButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.formularAbbrechenButton); } - public getKommentarList() { - return cy.getTestElement(this.locatorKommentarList); + public getKommentarList(): Cypress.Chainable<Element> { + return cy.getTestElement(this.kommentarList); } - public getTextInput() { - return cy.getTestElement(this.locatorTextInput); + public getTextInput(): Cypress.Chainable<Element> { + return cy.getTestElement(this.textInput); } - public getTextError() { - return cy.getTestElement(this.locatorTextError); + public getTextError(): Cypress.Chainable<Element> { + return cy.getTestElement(this.textError); } - public getKommentar(text: string): KommentarInVorgangE2E { - return new KommentarInVorgangE2E(text); + public getKommentar(text: string): KommentarInVorgangE2EComponent { + return new KommentarInVorgangE2EComponent(text); } public getAttachmentContainer(): AttachmentContainerE2EComponent { @@ -80,26 +86,24 @@ export class KommentareInVorgangE2EComponent { } } -export class KommentarInVorgangE2E { - //TODO: Rename to KommentarInVorgangE2EComponent - - private readonly locatorCreatedAt: string = 'kommentar-created-at'; +export class KommentarInVorgangE2EComponent { + private readonly root: string; - private readonly locatorRoot: string; + private readonly createdAtInput: string = 'kommentar-created-at'; constructor(private text: string) { - this.locatorRoot = 'kommentar-item-' + convertToDataTestId(this.text); + this.root = 'kommentar-item-' + convertToDataTestId(this.text); } - public getRoot() { - return cy.getTestElement(this.locatorRoot); + public getRoot(): Cypress.Chainable<Element> { + return cy.getTestElement(this.root); } public getUserProfile(): UserProfileE2EComponent { - return new UserProfileE2EComponent(this.locatorRoot); + return new UserProfileE2EComponent(this.root); } - public getCreatedAt() { - return cy.getTestElement(this.locatorCreatedAt); + public getCreatedAt(): Cypress.Chainable<Element> { + return this.getRoot().findTestElementWithClass(this.createdAtInput); } } diff --git a/alfa-client/apps/alfa-e2e/src/components/navigation/navigation.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/navigation/navigation.e2e.component.ts index 7e1a233687f36196443be78c7d3d56c2601cc51e..5f4b16d3b7c03aaf22996fa476bcc6cde954c363 100644 --- a/alfa-client/apps/alfa-e2e/src/components/navigation/navigation.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/navigation/navigation.e2e.component.ts @@ -28,19 +28,19 @@ export class NavigationE2EComponent { private readonly locatorRoot: string = 'navigation'; - public getRoot() { + public getRoot(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorRoot); } - public getAlleFilter() { + public getAlleFilter(): Cypress.Chainable<Element> { return cy.getTestElement(this.alleFilterToggleButton); } - public getMeineVorgaengeFilter() { + public getMeineVorgaengeFilter(): Cypress.Chainable<Element> { return cy.getTestElement(this.meineVorgaengeToggleButton); } - public getUnassignedFilter() { + public getUnassignedFilter(): Cypress.Chainable<Element> { return cy.getTestElement(this.unassignedToggleButton); } } diff --git a/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail-formular.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail-formular.e2e.component.ts index fc4edd22fe768eb8be089b6142314fc6d0227e1c..c1348e724905b5cb8bc0daa0b8a02521cd9b23d9 100644 --- a/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail-formular.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail-formular.e2e.component.ts @@ -25,43 +25,42 @@ import { getTestElement } from '../../support/cypress-helper'; import { AttachmentContainerE2EComponent } from '../attachment/attachment.e2e.component'; export class PostfachMailFormularE2EComponent { - private readonly locatorEmpfaenger: string = 'postfach-empfaenger'; - private readonly locatorBetreff: string = 'Betreff-text-input'; - private readonly locatorBetreffError: string = 'Betreff-text-error'; - private readonly locatorText: string = 'Text-textarea-input'; - private readonly locatorTextError: string = 'Text-textarea-error'; - private readonly locatorSendButton: string = 'postfach-send-button'; + private readonly empfaenger: string = 'postfach-empfaenger'; + private readonly betreffInput: string = 'Betreff-text-input'; + private readonly betreffError: string = 'Betreff-text-error'; + private readonly textInput: string = 'Text-textarea-input'; + private readonly textError: string = 'Text-textarea-error'; + private readonly replyOptionCheckbox: string = 'postfach-reply-option'; + private readonly sendButton: string = 'postfach-send-button'; - private readonly replyOption: string = 'postfach-reply-option'; - private readonly attachmentContainer: AttachmentContainerE2EComponent = - new AttachmentContainerE2EComponent(); + private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); - public getEmpfaenger() { - return cy.getTestElement(this.locatorEmpfaenger); + public getEmpfaenger(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.empfaenger); } - public getBetreff() { - return cy.getTestElement(this.locatorBetreff); + public getBetreff(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.betreffInput); } - public getBetreffError() { - return cy.getTestElement(this.locatorBetreffError); + public getBetreffError(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.betreffError); } - public getText() { - return cy.getTestElement(this.locatorText); + public getText(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.textInput); } - public getTextError() { - return cy.getTestElement(this.locatorTextError); + public getTextError(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.textError); } - public getSendButton() { - return cy.getTestElement(this.locatorSendButton); + public getSendButton(): Cypress.Chainable<HTMLElement> { + return cy.getTestElement(this.sendButton); } - public getReplyOption() { - return getTestElement(this.replyOption).find('.mdc-checkbox__native-control'); + public getReplyOption(): Cypress.Chainable<HTMLElement> { + return getTestElement(this.replyOptionCheckbox).find('.mdc-checkbox__native-control'); } public getAttachmentContainer(): AttachmentContainerE2EComponent { diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-bescheid-wizard.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-bescheid-wizard.e2e.component.ts index 057b39b29c7de8819c69e745af44cda24e300859..4b1e36d8940baf9c31b74c0db1496400ff3f3a16 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-bescheid-wizard.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-bescheid-wizard.e2e.component.ts @@ -49,7 +49,6 @@ export class VorgangBescheidWizardE2EComponent { private readonly uploadBescheidFileButton: string = '-single-file-upload-button'; private readonly uploadAttachmentButton: string = 'Anhang_hochladen-file-upload-button'; private readonly uploadAutomaticBescheid: string = 'create-bescheid-document-button'; - private readonly mailTextArea: string = 'Text-textarea-editor'; private readonly saveBescheid: string = 'save-button'; private readonly sendBescheid: string = 'send-button'; private readonly confirmAndSaveButton: string = 'confirm-and-save-button'; @@ -63,10 +62,6 @@ export class VorgangBescheidWizardE2EComponent { private readonly bescheidDocument: string = 'bescheid-document'; private readonly attachmentDocument: string = 'bescheid-attachments'; - private readonly bescheidUploadSpinner: string = '[data-test-id="bescheid-document"] ods-spinner-icon'; - private readonly attachmentUploadSpinner: string = '[data-test-id="bescheid-attachments"] ods-spinner-icon'; - private readonly bescheidSaveSpinner: string = '[data-test-id="confirm-and-save-button"] ods-spinner-icon'; - private readonly sendenSpinner: string = '[data-test-id="send-button"] ods-spinner-icon'; private readonly missingBescheidDocumentMessage: string = 'missing-bescheid-document-error-message'; private locatorRoot: string = 'bescheid-wizard'; @@ -142,35 +137,35 @@ export class VorgangBescheidWizardE2EComponent { return cy.getTestElement(this.closeDialog); } - public getCloseVerwerfenButton(): Cypress.Chainable<JQuery<HTMLElement>> { + public getCloseVerwerfenButton(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.bescheidVerwerfenButton); } - public getCloseSpeichernButton(): Cypress.Chainable<JQuery<HTMLElement>> { + public getCloseSpeichernButton(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.bescheidSpeichernButton); } - public getUploadBescheidButton(): Cypress.Chainable<JQuery<HTMLElement>> { + public getUploadBescheidButton(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.uploadBescheidFileButton); } - public getUploadAttachmentButton(): Cypress.Chainable<JQuery<HTMLElement>> { + public getUploadAttachmentButton(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.uploadAttachmentButton); } - public getFileBescheidValidInWizard(): Cypress.Chainable<JQuery<HTMLElement>> { + public getFileBescheidValidInWizard(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.locatorRoot).find(`[data-test-id=${this.fileBescheidValid}]`); } - public getFileAnhangValidInWizard(): Cypress.Chainable<JQuery<HTMLElement>> { + public getFileAnhangValidInWizard(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.locatorRoot).find(`[data-test-id=${this.fileAnhangValid}]`); } - public getAutomaticBescheidFileInWizard() { + public getAutomaticBescheidFileInWizard(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.locatorRoot).find(`[data-test-id=${this.fileAutomaticBescheid}]`); } - public getDeleteButtonOfElement(element: string): Cypress.Chainable<JQuery<HTMLElement>> { + public getDeleteButtonOfElement(element: string): Cypress.Chainable<HTMLElement> { return cy.getTestElement(element).find('[title="Anhang löschen"]'); } @@ -178,30 +173,14 @@ export class VorgangBescheidWizardE2EComponent { return filename.replace(/\./g, '') + '-file-item'; } - public getBescheidDocument(): Cypress.Chainable<JQuery<HTMLElement>> { + public getBescheidDocument(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.bescheidDocument); } - public getAttachmentDocument(): Cypress.Chainable<JQuery<HTMLElement>> { + public getAttachmentDocument(): Cypress.Chainable<HTMLElement> { return cy.getTestElement(this.attachmentDocument); } - public getBescheidUploadSpinner(): Cypress.Chainable<JQuery<HTMLElement>> { - return cy.get(this.bescheidUploadSpinner); - } - - public getAttachmentUploadSpinner(): Cypress.Chainable<JQuery<HTMLElement>> { - return cy.get(this.attachmentUploadSpinner); - } - - public getBescheidSaveSpinner(): Cypress.Chainable<JQuery<HTMLElement>> { - return cy.get(this.bescheidSaveSpinner); - } - - public getSendenSpinner(): Cypress.Chainable<JQuery<HTMLElement>> { - return cy.get(this.sendenSpinner); - } - public getMailText(): Cypress.Chainable<JQuery<HTMLElement>> { return cy.getTestElement(this.nachrichtText); } @@ -274,14 +253,6 @@ export class VorgangBescheidWizardE2EComponent { uploadFile(this.getUploadAttachmentButton(), fileName); } - public bescheidUploadSpinnerIsClosed(): void { - this.getBescheidUploadSpinner().should('not.exist'); - } - - public attachmentSpinnerIsClosed(): void { - this.getAttachmentUploadSpinner().should('not.exist'); - } - public enterDate(difference: number): void { this.getDateInput().should('exist'); enterWith(this.getDateInput(), getAdjustedDateGerman(difference)); diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components.ts index b91293c81d9c0bc662f2ba91cbc1a14a03b9b548..eb3c618504707e0ab04322b655320bc57cdb9709 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components.ts @@ -25,7 +25,7 @@ export class VorgangFormularButtonsE2EComponent { private readonly abschliessenButton: string = 'abschliessen-button'; private readonly annehmenButton: string = 'annehmen-button'; private readonly bearbeitenButton: string = 'bearbeiten-button'; - private readonly forwardButton: string = 'forward-by-ozgcloud-button'; + private readonly forwardButton: string = 'forwarding-button'; private readonly bescheidenButton: string = 'bescheiden-button'; private readonly endgueltigLoeschenButton: string = 'endgueltig-loeschen-button'; private readonly loeschAnforderungZuruecknehmenButton: string = 'loesch-anforderung-zuruecknehmen-button'; diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward-formular.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward-formular.e2e.component.ts index a4c4310c17db187a33065e33cb60e21cbff21b47..a550f4adf9a9e0a864640917ce66fcd10a42ed20 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward-formular.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward-formular.e2e.component.ts @@ -50,13 +50,7 @@ export class ForwardFormularE2EComponent { return cy.getTestElement(this.locatorZustaendigeStelleError); } - //TODO Getter draus machen und im Test den click durchführen - public forward() { - return this.getForwardButton().click(); - } - // - - private getForwardButton() { + public getForwardButton() { return cy.getTestElement(this.locatorForwardButton); } } diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward.e2e.component.ts index b6e8c7ca678c84bc16b90780b606e8858406b042..ee138ef9c37dc0daffcefd25286206011b778f2f 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forward.e2e.component.ts @@ -23,7 +23,7 @@ */ import { ForwardFormularE2EComponent } from './vorgang-forward-formular.e2e.component'; -export class VorgangForwardingE2EComponent { +export class ForwardingByEmailE2EComponent { private readonly locatorForwardingSpinner: string = 'forwarding-spinner'; private readonly locatorForwardingSuccessMessage: string = 'forwarding-success-message'; private readonly locatorForwardingErrorMessage: string = 'forwarding-error-message'; @@ -32,8 +32,7 @@ export class VorgangForwardingE2EComponent { private readonly locatorForwardingMarkAsFailButton: string = 'mark-as-fail-button'; private readonly locatorFailedMessage: string = 'failed-message'; - private readonly forwardingFormular: ForwardFormularE2EComponent = - new ForwardFormularE2EComponent(); + private readonly forwardingFormular: ForwardFormularE2EComponent = new ForwardFormularE2EComponent(); private readonly locatorRoot: string = 'forwarding'; diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forwarding-dialog.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forwarding-dialog.e2e.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..7f5d897628057b0c929c61fd9596ad7de3dad49a --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-forwarding-dialog.e2e.component.ts @@ -0,0 +1,51 @@ +export class ForwardingDialogE2EComponent { + private readonly root: string = 'forwarding-dialog'; + private readonly cancelButton: string = 'cancel-dialog-button'; + private readonly cancelIconButton: string = 'cancel-dialog-icon-button'; + private readonly forwardingButton: string = 'forwarding-dialog-forwarding-button'; + private readonly searchText: string = 'instant_search-text-input'; + private readonly searchEntry: string = 'item-button'; + private readonly forwardingItem: string = 'forwarding-item'; + private readonly changeButton: string = 'forwarding-item-change-button'; + private readonly zufiSearch: string = 'zufi-search'; + + public getRoot() { + return cy.getTestElement(this.root); + } + + public getCancelButton() { + return cy.getTestElement(this.cancelButton); + } + + public getCancelIconButton() { + return cy.getTestElement(this.cancelIconButton); + } + + public getForwardingButton() { + return cy.getTestElement(this.forwardingButton); + } + + public getSearchText() { + return cy.getTestElement(this.searchText); + } + + public search(text: string) { + this.getSearchText().type(text); + } + + public clickSearchEntry(index: number): void { + cy.getTestElement(this.searchEntry).eq(index).click(); + } + + public getForwardingItem() { + return cy.getTestElement(this.forwardingItem); + } + + public getChangeButton() { + return cy.getTestElement(this.changeButton); + } + + public getZufiSearch() { + return cy.getTestElement(this.zufiSearch); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-views.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-views.e2e.component.ts index 9ada0f2e5a1a3f6a6b52e516037e1040e5948fd0..09585caa4a0cf07a4e271b9c0f071afa5b8052da 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-views.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-views.e2e.component.ts @@ -23,33 +23,16 @@ */ export class VorgangViewsE2EComponent { private readonly neuViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Neu'); - private readonly angenommenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Angenommen', - ); - private readonly inBearbeitungViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'In_Bearbeitung', - ); - private readonly beschiedenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Beschieden', - ); - private readonly abgeschlossenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Abgeschlossen', - ); - private readonly verworfenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Verworfen', - ); - private readonly zuLoeschenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Zu_Loschen', - ); - private readonly ungelesenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Ungelesen', - ); - private readonly wiedervorlagenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Wiedervorlagen', - ); - private readonly vorgangListViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent( - 'Vorgangsliste', - ); + private readonly angenommenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Angenommen'); + private readonly inBearbeitungViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('In_Bearbeitung'); + private readonly beschiedenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Beschieden'); + private readonly abgeschlossenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Abgeschlossen'); + private readonly weitergeleitetViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Weitergeleitet'); + private readonly verworfenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Verworfen'); + private readonly zuLoeschenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Zu_Loschen'); + private readonly ungelesenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Ungelesen'); + private readonly wiedervorlagenViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Wiedervorlagen'); + private readonly vorgangListViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Vorgangsliste'); private readonly searchViewItem: VorgangViewE2EComponent = new VorgangViewE2EComponent('Suche'); public getNeu(): VorgangViewE2EComponent { @@ -72,6 +55,10 @@ export class VorgangViewsE2EComponent { return this.abgeschlossenViewItem; } + public getWeitergeleitet(): VorgangViewE2EComponent { + return this.weitergeleitetViewItem; + } + public getVerworfen(): VorgangViewE2EComponent { return this.verworfenViewItem; } @@ -108,15 +95,15 @@ export class VorgangViewE2EComponent { this.rootId = rootId; } - public getRoot() { + public getRoot(): Cypress.Chainable<Element> { return cy.getTestElement(`${this.root}${this.rootId}`); } - public getCount() { + public getCount(): Cypress.Chainable<Element> { return this.getRoot().getTestElement(`${this.count}${this.rootId}`); } - public getButton() { + public getButton(): Cypress.Chainable<Element> { return this.getRoot().findTestElementWithClass(this.button); } } diff --git a/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-in-vorgang.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-in-vorgang.e2e.component.ts index 36b36d076f83254d26bdaa6babef3975300ebedd..753fe1f790e2f4cdcfc140f93ae23681764b3736 100644 --- a/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-in-vorgang.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-in-vorgang.e2e.component.ts @@ -26,38 +26,37 @@ import { AttachmentContainerE2EComponent } from '../attachment/attachment.e2e.co import { StatusE2EComponent } from './wiedervorlage-status.e2e.component'; export class WiedervorlageInVorgangE2EComponent { - private readonly locatorFrist: string = 'frist'; - private readonly locatorBetreff: string = 'betreff'; - private readonly locatorLink: string = 'link'; - private readonly locatorExpandButon: string = 'expand-button'; - private readonly locatorExpandable: string = 'expandable'; - private readonly attachmentContainer: AttachmentContainerE2EComponent = - new AttachmentContainerE2EComponent(); + private readonly frist: string = 'frist'; + private readonly betreff: string = 'betreff'; + private readonly link: string = 'link'; + private readonly expandButton: string = 'expand-button'; + private readonly expandable: string = 'expandable'; + private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); private locatorRoot: string; - constructor(private betreff: string) { - this.locatorRoot = replaceAllWhitespaces(this.betreff, '_'); + constructor(private betreffIdentificator: string) { + this.locatorRoot = replaceAllWhitespaces(this.betreffIdentificator, '_'); } - public getRoot() { + public getRoot(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorRoot); } - public getLink() { - return this.getRoot().findTestElementWithClass(this.locatorLink); + public getLink(): Cypress.Chainable<Element> { + return this.getRoot().findTestElementWithClass(this.link); } - public getFrist() { - return this.getRoot().findTestElementWithClass(this.locatorFrist); + public getFrist(): Cypress.Chainable<Element> { + return this.getRoot().findTestElementWithClass(this.frist); } - public getBetreff() { - return this.getRoot().findTestElementWithClass(this.locatorBetreff); + public getBetreff(): Cypress.Chainable<Element> { + return this.getRoot().findTestElementWithClass(this.betreff); } - public getExpandButton() { - return this.getRoot().findTestElementWithClass(this.locatorExpandButon); + public getExpandButton(): Cypress.Chainable<Element> { + return this.getRoot().findTestElementWithClass(this.expandButton); } public getStatus(): StatusE2EComponent { @@ -68,8 +67,8 @@ export class WiedervorlageInVorgangE2EComponent { this.getExpandButton().click(); } - public getExpandable() { - return this.getRoot().findTestElementWithClass(this.locatorExpandable); + public getExpandable(): Cypress.Chainable<Element> { + return this.getRoot().findTestElementWithClass(this.expandable); } public getAttachmentContainer(): AttachmentContainerE2EComponent { diff --git a/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-page.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-page.e2e.component.ts index e17043afdfaa7c7de564ec7b244ff85b1761985a..a647445a85ed68f65dccd37e8f1416dd0c03c396 100644 --- a/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-page.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-page.e2e.component.ts @@ -34,31 +34,31 @@ export class WiedervorlageE2EComponent { private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); - public getBetreff() { + public getBetreff(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorBetreffInput); } - public getBetreffError() { + public getBetreffError(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorBetreffError); } - public getBeschreibung() { + public getBeschreibung(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorBeschreibungInput); } - public getFrist() { + public getFrist(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorFristInput); } - public getDatumError() { + public getDatumError(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorDatumError); } - public getStatusDot() { + public getStatusDot(): Cypress.Chainable<Element> { return cy.getTestElementWithClass(this.locatorStatusDot); } - public getSpeichernButton() { + public getSpeichernButton(): Cypress.Chainable<Element> { return cy.getTestElement(this.locatorSpeichernButton); } diff --git a/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component.ts index 91718623842de6e64bb8c0a863ba2146606d68c4..0f5d46f7ab8f257fc75e3f6a1bcd9d3cfd80da56 100644 --- a/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component.ts @@ -24,18 +24,18 @@ import { WiedervorlageInVorgangE2EComponent } from './wiedervorlage-in-vorgang.e2e.component'; export class WiedervorlagenInVorgangE2EComponent { - private readonly locatorCreateWiedervorlageButton: string = 'create-wiedervorlage'; - private readonly locatorRoot: string = 'wiedervorlagen-in-vorgang'; + private readonly createWiedervorlageButton: string = 'create-wiedervorlage'; + private readonly root: string = 'wiedervorlagen-in-vorgang'; - public getRoot() { - return cy.getTestElement(this.locatorRoot); + public getRoot(): Cypress.Chainable<Element> { + return cy.getTestElement(this.root); } public getWiedervorlage(betreff: string): WiedervorlageInVorgangE2EComponent { return new WiedervorlageInVorgangE2EComponent(betreff); } - public getCreateWiedervorlageButton() { - return cy.getTestElement(this.locatorCreateWiedervorlageButton); + public getCreateWiedervorlageButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.createWiedervorlageButton); } } diff --git a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward-by-ozgcloud.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward-by-ozgcloud.cy.ts deleted file mode 100644 index 8b346e0d75ba810435adc064d63adf36e2ef0991..0000000000000000000000000000000000000000 --- a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward-by-ozgcloud.cy.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { registerLocaleData } from '@angular/common'; -import localeDe from '@angular/common/locales/de'; -import localeDeExtra from '@angular/common/locales/extra/de'; -import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; -import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; -import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; -import { VorgangPage } from '../../../page-objects/vorgang.po'; -import { dropCollections } from '../../../support/cypress-helper'; -import { exist, notExist } from '../../../support/cypress.util'; -import { loginAsEmil } from '../../../support/user-util'; -import { createVorgang, initVorgaenge } from '../../../support/vorgang-util'; - -registerLocaleData(localeDe, 'de', localeDeExtra); - -describe('Vorgang weiterleiten innerhalb der OzgCloud', () => { - const mainPage: MainPage = new MainPage(); - const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); - - const vorgangPage: VorgangPage = new VorgangPage(); - const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); - - const vorgangWeiterleiten: VorgangE2E = { ...createVorgang(), name: 'Weiterleitung' }; - - before(() => { - initVorgaenge([vorgangWeiterleiten]); - - loginAsEmil(); - - waitForSpinnerToDisappear(); - exist(vorgangList.getRoot()); - }); - - after(() => { - dropCollections(); - }); - - describe('Weiterleiten', () => { - it('should display Weiterleiten button in Status Neu', () => { - vorgangList.getListItem(vorgangWeiterleiten.name).getRoot().click(); - waitForSpinnerToDisappear(); - - notExist(vorgangFormularButtons.getForwardButton()); - }); - }); -}); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward-fail.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email-fail.cy.ts similarity index 76% rename from alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward-fail.cy.ts rename to alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email-fail.cy.ts index 717b730610c3be2da7d0f12e9c1f2783c553ae97..e90a6964108c52d02bd0503f615268fc50b0da5b 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward-fail.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email-fail.cy.ts @@ -21,7 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { VorgangForwardingE2EComponent } from '../../../components/vorgang/vorgang-forward.e2e.component'; +import { ForwardFormularE2EComponent } from '../../../components/vorgang/vorgang-forward-formular.e2e.component'; +import { ForwardingByEmailE2EComponent } from '../../../components/vorgang/vorgang-forward.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E, VorgangStatusE2E, vorgangStatusLabelE2E } from '../../../model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; @@ -32,12 +33,12 @@ import { FORWARDING_INVALID_EMAIL } from '../../../support/data.util'; import { loginAsEmil } from '../../../support/user-util'; import { createVorgang, initVorgang } from '../../../support/vorgang-util'; -describe.skip('{TODO: need to fix with a mock} Vorgang forwarding fail', () => { +describe.skip('{TODO: need to fix with a mock} Vorgang forwarding by email fail', () => { const mainPage: MainPage = new MainPage(); const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); const vorgangPage: VorgangPage = new VorgangPage(); - const forwardingContainer: VorgangForwardingE2EComponent = vorgangPage.getForwardingContainer(); + const forwardingByEmailContainer: ForwardingByEmailE2EComponent = vorgangPage.getForwardingByEmailContainer(); const vorgang: VorgangE2E = createVorgang(); @@ -60,20 +61,20 @@ describe.skip('{TODO: need to fix with a mock} Vorgang forwarding fail', () => { exist(vorgangPage.getVorgangDetailHeader().getRoot()); }); - it('should show forwarding', () => { - exist(forwardingContainer.getRoot()); + it('should show forwarding by email', () => { + exist(forwardingByEmailContainer.getRoot()); }); }); describe('fill forward formular', () => { it('should show spinner with text on valid formular', () => { - const forwardForumlar = forwardingContainer.getFormular(); + const forwardForumlar: ForwardFormularE2EComponent = forwardingByEmailContainer.getFormular(); forwardForumlar.getZustaendigeStelle().clear().type(FORWARDING_INVALID_EMAIL); forwardForumlar.getPasswort().clear().type('validespasswort'); - forwardForumlar.forward(); + forwardForumlar.getForwardButton().click(); - exist(forwardingContainer.getSpinner()); + exist(forwardingByEmailContainer.getSpinner()); }); }); @@ -81,22 +82,19 @@ describe.skip('{TODO: need to fix with a mock} Vorgang forwarding fail', () => { it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG], () => { waitForSpinnerToDisappear(); - haveText( - vorgangPage.getVorgangDetailHeader().getStatus(), - vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG], - ); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }); it('should show forward fail text', () => { - exist(forwardingContainer.getForwardingErrorMessage()); + exist(forwardingByEmailContainer.getForwardingErrorMessage()); }); it('should NOT show "mark as success" button', () => { - notExist(forwardingContainer.getMarkAsSuccessButton()); + notExist(forwardingByEmailContainer.getMarkAsSuccessButton()); }); it('should show formular', () => { - exist(forwardingContainer.getFormular().getRoot()); + exist(forwardingByEmailContainer.getFormular().getRoot()); }); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email-failed.cy.ts similarity index 80% rename from alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-cy.ts rename to alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email-failed.cy.ts index f9b5af08c1bffc8e87594aa775c383a222255876..8a9bc49f7aa34bf2e1f47da5d31419bf891ea3b9 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email-failed.cy.ts @@ -21,7 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { VorgangForwardingE2EComponent } from '../../../components/vorgang/vorgang-forward.e2e.component'; +import { ForwardFormularE2EComponent } from '../../../components/vorgang/vorgang-forward-formular.e2e.component'; +import { ForwardingByEmailE2EComponent } from '../../../components/vorgang/vorgang-forward.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E, VorgangStatusE2E, vorgangStatusLabelE2E } from '../../../model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; @@ -32,12 +33,12 @@ import { FORWARDING_TEST_EMAIL } from '../../../support/data.util'; import { loginAsEmil } from '../../../support/user-util'; import { createVorgang, initVorgang } from '../../../support/vorgang-util'; -describe('Vorgang forwarding failed', () => { +describe.skip('{TODO: needs fixing} Vorgang forwarding by email failed', () => { const mainPage: MainPage = new MainPage(); const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); const vorgangPage: VorgangPage = new VorgangPage(); - const forwardingContainer: VorgangForwardingE2EComponent = vorgangPage.getForwardingContainer(); + const forwardingContainer: ForwardingByEmailE2EComponent = vorgangPage.getForwardingByEmailContainer(); const vorgang: VorgangE2E = createVorgang(); @@ -69,11 +70,11 @@ describe('Vorgang forwarding failed', () => { describe('fill forward formular', () => { it('should show spinner with text on valid formular', { defaultCommandTimeout: 30000 }, () => { - const formular = forwardingContainer.getFormular(); + const formular: ForwardFormularE2EComponent = forwardingContainer.getFormular(); formular.getZustaendigeStelle().clear().type(FORWARDING_TEST_EMAIL); formular.getPasswort().clear().type('validespasswort'); - formular.forward(); + formular.getForwardButton().click(); exist(forwardingContainer.getSpinner()); }); @@ -83,10 +84,7 @@ describe('Vorgang forwarding failed', () => { it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], () => { waitForSpinnerToDisappear(); - haveText( - vorgangPage.getVorgangDetailHeader().getStatus(), - vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], - ); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET]); }); it('should show forward success text', () => { @@ -121,17 +119,11 @@ describe('Vorgang forwarding failed', () => { }); describe('switch to list view', () => { - it( - 'should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG] + ' in list', - () => { - vorgangPage.getSubnavigation().getBackButton().click(); - waitForSpinnerToDisappear(); - - haveText( - vorgangList.getListItem(vorgang.name).getStatus(), - vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG], - ); - }, - ); + it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG] + ' in list', () => { + vorgangPage.getSubnavigation().getBackButton().click(); + waitForSpinnerToDisappear(); + + haveText(vorgangList.getListItem(vorgang.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); + }); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email.cy.ts similarity index 77% rename from alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.cy.ts rename to alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email.cy.ts index f090dd3185bf81dffdb06b6f8f3dc48fc7f378a2..279337199a74e46b323388ba33ca09b47d7a80d6 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-by-email.cy.ts @@ -21,32 +21,23 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { VorgangForwardingE2EComponent } from '../../../components/vorgang/vorgang-forward.e2e.component'; +import { ForwardingByEmailE2EComponent } from '../../../components/vorgang/vorgang-forward.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E, VorgangStatusE2E, vorgangStatusLabelE2E } from '../../../model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections } from '../../../support/cypress-helper'; import { exist, haveText, haveValue, notExist } from '../../../support/cypress.util'; -import { - FORWARDING_INVALID_EMAIL, - FORWARDING_TEST_EMAIL, - VORGANG_ZUSTAENDIGE_STELLE_EMAIL, -} from '../../../support/data.util'; +import { FORWARDING_INVALID_EMAIL, FORWARDING_TEST_EMAIL, VORGANG_ZUSTAENDIGE_STELLE_EMAIL } from '../../../support/data.util'; import { loginAsEmil } from '../../../support/user-util'; -import { - buildVorgang, - createVorgang, - initVorgaenge, - objectIds, -} from '../../../support/vorgang-util'; - -describe.skip('Vorgang forward', () => { +import { buildVorgang, createVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util'; + +describe.skip('Vorgang forwarding by email', () => { const mainPage: MainPage = new MainPage(); const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); const vorgangPage: VorgangPage = new VorgangPage(); - const forwardingContainer: VorgangForwardingE2EComponent = vorgangPage.getForwardingContainer(); + const forwardingContainer: ForwardingByEmailE2EComponent = vorgangPage.getForwardingByEmailContainer(); const vorgang: VorgangE2E = { ...createVorgang(), name: 'TestVorgangRedirectSpinner' }; const vorgangEmpty: VorgangE2E = buildVorgang(objectIds[0], 'TestVorgangRedirectEmpty'); @@ -77,10 +68,7 @@ describe.skip('Vorgang forward', () => { }); it('should be prefilled', () => { - haveValue( - forwardingContainer.getFormular().getZustaendigeStelle(), - VORGANG_ZUSTAENDIGE_STELLE_EMAIL, - ); + haveValue(forwardingContainer.getFormular().getZustaendigeStelle(), VORGANG_ZUSTAENDIGE_STELLE_EMAIL); }); }); @@ -91,7 +79,7 @@ describe.skip('Vorgang forward', () => { forwardFormular.getZustaendigeStelle().clear().type(FORWARDING_INVALID_EMAIL); //TODO create valid email-address without adding it to landesnetzlist forwardFormular.getPasswort().clear().type('zukurz'); - forwardFormular.forward(); + forwardFormular.getForwardButton().click(); waitForSpinnerToDisappear(); exist(forwardFormular.getPasswortError()); @@ -101,7 +89,7 @@ describe.skip('Vorgang forward', () => { const forwardFormular = forwardingContainer.getFormular(); forwardFormular.getZustaendigeStelle().clear().type(FORWARDING_INVALID_EMAIL); - forwardFormular.forward(); + forwardFormular.getForwardButton().click(); waitForSpinnerToDisappear(); exist(forwardFormular.getZustaendigeStelleError()); @@ -114,7 +102,7 @@ describe.skip('Vorgang forward', () => { forwardFormular.getZustaendigeStelle().clear().type(FORWARDING_TEST_EMAIL); forwardFormular.getPasswort().clear(); - forwardFormular.forward(); + forwardFormular.getForwardButton().click(); exist(forwardingContainer.getSpinner()); }); @@ -122,18 +110,11 @@ describe.skip('Vorgang forward', () => { }); describe('success forwarding', () => { - it( - 'should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], - { defaultCommandTimeout: 30000 }, - () => { - waitForSpinnerToDisappear(); + it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], { defaultCommandTimeout: 30000 }, () => { + waitForSpinnerToDisappear(); - haveText( - vorgangPage.getVorgangDetailHeader().getStatus(), - vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], - ); - }, - ); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET]); + }); it('should show forward success text', () => { exist(forwardingContainer.getForwardingSuccessMessage()); @@ -156,18 +137,12 @@ describe.skip('Vorgang forward', () => { }); describe('switch to list view', () => { - it( - 'should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET] + ' in list', - () => { - vorgangPage.getSubnavigation().getBackButton().click(); - waitForSpinnerToDisappear(); + it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET] + ' in list', () => { + vorgangPage.getSubnavigation().getBackButton().click(); + waitForSpinnerToDisappear(); - haveText( - vorgangList.getListItem(vorgang.name).getStatus(), - vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], - ); - }, - ); + haveText(vorgangList.getListItem(vorgang.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET]); + }); }); describe('change to non forwarding vorgang', () => { diff --git a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..82dd57a8ae88f5879ed473712a489e31520d0c0e --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts @@ -0,0 +1,42 @@ +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; +import localeDeExtra from '@angular/common/locales/extra/de'; +import { E2EVorgangNavigator } from '../../../helper/vorgang/vorgang.navigator'; +import { E2EVorgangVerifier } from '../../../helper/vorgang/vorgang.verifier'; +import { VorgangE2E } from '../../../model/vorgang'; +import { dropCollections } from '../../../support/cypress-helper'; +import { loginAsEmil } from '../../../support/user-util'; +import { createVorgang, initVorgaenge } from '../../../support/vorgang-util'; + +registerLocaleData(localeDe, 'de', localeDeExtra); + +describe('Vorgang weiterleiten innerhalb der OzgCloud', () => { + const vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator(); + const vorgangVerifier: E2EVorgangVerifier = new E2EVorgangVerifier(); + + const vorgangWeiterleiten: VorgangE2E = { ...createVorgang(), name: 'Weiterleitung' }; + + before(() => { + initVorgaenge([vorgangWeiterleiten]); + }); + + after(() => { + dropCollections(); + }); + + describe('Weiterleiten', () => { + describe('Emil', () => { + it('should login as Emil', () => { + loginAsEmil(); + }); + + it('should open vorgang', () => { + vorgangNavigator.openVorgangDetailByName(vorgangWeiterleiten.name); + }); + + it('should display Weiterleiten button in Status Neu', () => { + vorgangVerifier.verifyForwardingButtonExists(); + }); + }); + }); +}); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/accessibility/vorgang-list.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/accessibility/vorgang-list.cy.ts index a254ba3a092baa3b88fa2579ecf0399e5a83029c..c92fb955a61b78ce58d2222f12b3ff8785c04670 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/accessibility/vorgang-list.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/accessibility/vorgang-list.cy.ts @@ -161,6 +161,12 @@ describe('VorgangList Page', () => { isKeyboardFocused(views.getAbgeschlossen().getButton()); }); + it('should focus Weitergeleitet view', () => { + pressTab(); + + isKeyboardFocused(views.getWeitergeleitet().getButton()); + }); + it('should focus Verworfen view', () => { pressTab(); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/forwarding/forwarding.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/forwarding/forwarding.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..38dc17bb68d5b4e430c6ae5c3c3cd5bbc4cb8f4c --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/forwarding/forwarding.cy.ts @@ -0,0 +1,40 @@ +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; +import localeDeExtra from '@angular/common/locales/extra/de'; +import { E2EAppHelper } from 'apps/alfa-e2e/src/helper/app.helper'; +import { E2EForwardingHelper } from 'apps/alfa-e2e/src/helper/forwarding/forwarding.helper'; +import { E2EOrganisationsEinheit } from 'apps/alfa-e2e/src/model/organisationseinheit'; +import { E2EVorgangVerifier } from '../../../helper/vorgang/vorgang.verifier'; +import { VorgangE2E } from '../../../model/vorgang'; +import { dropCollections } from '../../../support/cypress-helper'; +import { createVorgang, initVorgang } from '../../../support/vorgang-util'; + +registerLocaleData(localeDe, 'de', localeDeExtra); + +describe('Vorgang weiterleiten', () => { + const appHelper: E2EAppHelper = new E2EAppHelper(); + + const vorgangVerifier: E2EVorgangVerifier = new E2EVorgangVerifier(); + + const forwardingHelper: E2EForwardingHelper = new E2EForwardingHelper(); + + const vorgang: VorgangE2E = { ...createVorgang(), name: 'Weiterleitung' }; + + before(() => { + initVorgang(vorgang); + + appHelper.loginAsSabine(); + }); + + after(() => { + dropCollections(); + }); + + it('should disable all functions after successfully forwarding', () => { + forwardingHelper.openForwarding(vorgang.name); + + forwardingHelper.forwardTo(E2EOrganisationsEinheit.HAMBURG_STADTENTWAESSERUNG); + + vorgangVerifier.verifyVorgangIsLocked(); + }); +}); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar-attachment/kommentar-attachment.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar-attachment/kommentar-attachment.cy.ts index e3d96d18276ee39862dd14f25d9a0ed02169b812..8cddad300e40d3cb4c4cca590d69f30845a5314f 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar-attachment/kommentar-attachment.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar-attachment/kommentar-attachment.cy.ts @@ -22,18 +22,20 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { sleep } from '@alfa-client/tech-shared'; -import { AttachmentContainerE2EComponent, AttachmentListE2EComponent, } from '../../../components/attachment/attachment.e2e.component'; -import { KommentareInVorgangE2EComponent } from '../../../components/kommentar/kommentar-list.e2e.component'; +import { + AttachmentContainerE2EComponent, + AttachmentListE2EComponent, +} from '../../../components/attachment/attachment.e2e.component'; +import { KommentarListInVorgangE2EComponent } from '../../../components/kommentar/kommentar-list.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; -import { UserE2E } from '../../../model/user'; import { VorgangE2E } from '../../../model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections, readFileFromDownloads } from '../../../support/cypress-helper'; import { exist, notExist } from '../../../support/cypress.util'; import { TEST_FILE_WITH_CONTENT, TEST_FILE_WITHOUT_CONTENT } from '../../../support/data.util'; -import { uploadFile } from '../../../support/file-upload'; -import { getUserSabine, loginAsSabine } from '../../../support/user-util'; +import { uploadFile, uploadFiles } from '../../../support/file-upload'; +import { loginAsSabine } from '../../../support/user-util'; import { createVorgang, initVorgang } from '../../../support/vorgang-util'; describe('Kommentar attachments', () => { @@ -41,7 +43,7 @@ describe('Kommentar attachments', () => { const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); const vorgangPage: VorgangPage = new VorgangPage(); - const kommentarContainer: KommentareInVorgangE2EComponent = vorgangPage.getKommentarContainer(); + const kommentarContainer: KommentarListInVorgangE2EComponent = vorgangPage.getKommentarContainer(); const attachmentContainer: AttachmentContainerE2EComponent = kommentarContainer.getAttachmentContainer(); const attachmentList: AttachmentListE2EComponent = attachmentContainer.getList(); @@ -49,7 +51,6 @@ describe('Kommentar attachments', () => { const kommentarText: string = 'Test text to test the test text test'; const vorgang: VorgangE2E = createVorgang(); - const userSabine: UserE2E = getUserSabine(); before(() => { initVorgang(vorgang); @@ -124,20 +125,22 @@ describe('Kommentar attachments', () => { }); }); - describe('Download Kommentar attachments', () => { - it('should upload attachment', () => { + describe('upload multiple attachments', () => { + it('should show files after upload is done', () => { kommentarContainer.getKommentar(kommentarText).getRoot().click(); waitForSpinnerToDisappear(); - uploadFile(attachmentContainer.getUploadInput(), TEST_FILE_WITH_CONTENT); + uploadFiles(attachmentContainer.getUploadInput(), [TEST_FILE_WITH_CONTENT, TEST_FILE_WITHOUT_CONTENT]); waitForSpinnerToDisappear(); - kommentarContainer.getFormularSpeichernButton().click(); waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); + exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); }); + }); + describe('Download Kommentar attachments', () => { it('should download uploaded attachment', () => { sleep(1000); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar/kommentar.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar/kommentar.cy.ts index 23754b15795ba5f5ed020b7dd450dad2a2d14fe3..002476fc9fbca92bc87ef43cf52f794266c3c45c 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar/kommentar.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/kommentar/kommentar.cy.ts @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { KommentareInVorgangE2EComponent } from '../../../components/kommentar/kommentar-list.e2e.component'; +import { KommentarListInVorgangE2EComponent } from '../../../components/kommentar/kommentar-list.e2e.component'; import { UserE2E } from '../../../model/user'; import { VorgangE2E } from '../../../model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections } from '../../../support/cypress-helper'; -import { contains, exist, haveText, notExist } from '../../../support/cypress.util'; +import { contains, exist, haveLength, haveText, notExist } from '../../../support/cypress.util'; import { getUserSabine, initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; import { createVorgang, initVorgang } from '../../../support/vorgang-util'; @@ -35,7 +35,7 @@ describe('Kommentar', () => { const mainPage: MainPage = new MainPage(); const vorgangPage: VorgangPage = new VorgangPage(); - const kommentarContainer: KommentareInVorgangE2EComponent = vorgangPage.getKommentarContainer(); + const kommentarContainer: KommentarListInVorgangE2EComponent = vorgangPage.getKommentarContainer(); const kommentarText: string = 'Test text to test the test text test'; @@ -90,7 +90,7 @@ describe('Kommentar', () => { }); describe('click on hinzufuegen button in formular', () => { - it('should show error on invalid input', () => { + it('should show error on empty text', () => { kommentarContainer.getFormularSpeichernButton().click(); waitForSpinnerToDisappear(); @@ -101,53 +101,22 @@ describe('Kommentar', () => { kommentarContainer.getTextInput().clear().type(kommentarText); kommentarContainer.getFormularSpeichernButton().click(); - exist(vorgangPage.getSpinner()); - notExist( - kommentarContainer - .getKommentar(kommentarText) - .getUserProfile() - .getIconContainer() - .getAssignedIcon(), - ); - exist(vorgangPage.getSpinner()); waitForSpinnerToDisappear(); - exist( - kommentarContainer - .getKommentar(kommentarText) - .getUserProfile() - .getIconContainer() - .getAssignedIcon(), - ); + exist(kommentarContainer.getKommentar(kommentarText).getUserProfile().getIconContainer().getAssignedIcon()); notExist(kommentarContainer.getTextError()); notExist(kommentarContainer.getFormular()); exist(kommentarContainer.getHinzufuegenButton()); - }); - - it('should show entry in list', () => { exist(kommentarContainer.getKommentar(kommentarText).getRoot()); }); it('should show user profile at kommentar', () => { - exist( - kommentarContainer - .getKommentar(kommentarText) - .getUserProfile() - .getIconContainer() - .getAssignedIcon(), - ); + exist(kommentarContainer.getKommentar(kommentarText).getUserProfile().getIconContainer().getAssignedIcon()); haveText( - kommentarContainer - .getKommentar(kommentarText) - .getUserProfile() - .getIconContainer() - .getAssignedIcon(), + kommentarContainer.getKommentar(kommentarText).getUserProfile().getIconContainer().getAssignedIcon(), userSabine.initials, ); - contains( - kommentarContainer.getKommentar(kommentarText).getUserProfile().getName(), - userSabine.fullName, - ); + contains(kommentarContainer.getKommentar(kommentarText).getUserProfile().getName(), userSabine.fullName); exist(kommentarContainer.getKommentar(kommentarText).getCreatedAt()); }); }); @@ -212,5 +181,27 @@ describe('Kommentar', () => { exist(kommentarContainer.getHinzufuegenButton()); }); }); + + describe('other kommentar', () => { + const otherKommentar: string = 'otherKommentar'; + + it('should be created', () => { + kommentarContainer.getHinzufuegenButton().click(); + kommentarContainer.getTextInput().clear().type(otherKommentar); + kommentarContainer.getFormularSpeichernButton().click(); + waitForSpinnerToDisappear(); + + haveLength(kommentarContainer.getFormulare(), 0); + exist(kommentarContainer.getKommentar(otherKommentar).getRoot()); + }); + + it('should hide previous opened kommentar on edit other kommentar', () => { + kommentarContainer.getKommentar(kommentarText).getRoot().click(); + haveLength(kommentarContainer.getFormulare(), 1); + + kommentarContainer.getKommentar(otherKommentar).getRoot().click(); + haveLength(kommentarContainer.getFormulare(), 1); + }); + }); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts index 044306b1063a79e993a306928e4a1bf7d9cbf827..70ef41af32be8a87839358860fa5eb7c7243be28 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts @@ -22,7 +22,12 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { faker } from '@faker-js/faker'; -import { AttachmentContainerE2EComponent, AttachmentListE2EComponent, } from 'apps/alfa-e2e/src/components/attachment/attachment.e2e.component'; +import { + AttachmentContainerE2EComponent, + AttachmentListE2EComponent, +} from 'apps/alfa-e2e/src/components/attachment/attachment.e2e.component'; +import { E2EAttachmentHelper } from 'apps/alfa-e2e/src/helper/attachment/attachment.helper'; +import { E2EAttachmentVerifier } from 'apps/alfa-e2e/src/helper/attachment/attachment.verifier'; import { BinaryFileSnackbarMessageE2E } from 'apps/alfa-e2e/src/model/binary-file'; import { PostfachMailFormularE2EComponent } from '../../../components/postfach/postfach-mail-formular.e2e.component'; import { PostfachMailE2EComponent, PostfachMailListItem } from '../../../components/postfach/postfach-mail.e2e.component'; @@ -31,7 +36,12 @@ import { SnackBarE2EComponent } from '../../../components/ui/snackbar.e2e.compon import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangSubnavigationE2EComponent } from '../../../components/vorgang/vorgang-subnavigation'; import { ClientAttributeNameE2E, ClientAttributesE2E, VorgangE2E } from '../../../model/vorgang'; -import { PostfachMailItemE2E, PostfachNachrichtSnackbarMessageE2E, VorgangAttachedItemClientE2E, VorgangAttachedItemE2E, } from '../../../model/vorgang-attached-item'; +import { + PostfachMailItemE2E, + PostfachNachrichtSnackbarMessageE2E, + VorgangAttachedItemClientE2E, + VorgangAttachedItemE2E, +} from '../../../model/vorgang-attached-item'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { PostfachMailPage } from '../../../page-objects/postfach-mail.component.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; @@ -39,10 +49,20 @@ import { expectIconWithBadge, expectIconWithoutBadge } from '../../../support/an import { dropCollections, readFileFromDownloads } from '../../../support/cypress-helper'; import { beChecked, contains, exist, notBeChecked, notBeVisible, notExist, visible } from '../../../support/cypress.util'; import { TEST_FILE_WITH_CONTENT, TEST_FILE_WITH_CONTENT_4_MB, TEST_FILE_WITHOUT_CONTENT } from '../../../support/data.util'; -import { uploadEmptyFile, uploadFile } from '../../../support/file-upload'; import { initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; -import { createPostfachNachrichtAttachedItem, createPostfachNachrichtReplyItem, initVorgangAttachedItem, } from '../../../support/vorgang-attached-item-util'; -import { buildVorgang, createHasNewPostfachNachrichtClientAttribute, createHasPostfachNachrichtClientAttribute, createVorgang, initVorgaenge, objectIds, } from '../../../support/vorgang-util'; +import { + createPostfachNachrichtAttachedItem, + createPostfachNachrichtReplyItem, + initVorgangAttachedItem, +} from '../../../support/vorgang-attached-item-util'; +import { + buildVorgang, + createHasNewPostfachNachrichtClientAttribute, + createHasPostfachNachrichtClientAttribute, + createVorgang, + initVorgaenge, + objectIds, +} from '../../../support/vorgang-util'; describe('PostfachMail', () => { const mainPage: MainPage = new MainPage(); @@ -57,6 +77,9 @@ describe('PostfachMail', () => { const attachmentContainer: AttachmentContainerE2EComponent = postfachMailFormular.getAttachmentContainer(); const attachmentList: AttachmentListE2EComponent = attachmentContainer.getList(); + const attachmentHelper: E2EAttachmentHelper = new E2EAttachmentHelper(); + const attachmentVerifier: E2EAttachmentVerifier = new E2EAttachmentVerifier(); + const postfachMailPage: PostfachMailPage = new PostfachMailPage(); const clientAttributes: ClientAttributesE2E = { @@ -226,45 +249,47 @@ describe('PostfachMail', () => { describe('attach files', () => { it('should show empty attachment after uploading it', () => { - uploadEmptyFile(attachmentContainer.getUploadInput(), TEST_FILE_WITHOUT_CONTENT); - waitForSpinnerToDisappear(); + attachmentHelper.uploadEmptyAttachment(); - exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); + attachmentVerifier.verifyAttachmentInList(TEST_FILE_WITHOUT_CONTENT); }); it('should show attachment with content after uploading it', () => { - uploadFile(postfachMailFormular.getAttachmentContainer().getUploadInput(), TEST_FILE_WITH_CONTENT); - waitForSpinnerToDisappear(); + attachmentHelper.uploadAttachment(); - exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); + attachmentVerifier.verifyAttachmentInList(TEST_FILE_WITH_CONTENT); }); it('should download empty attachment on click', () => { - attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.downloadAttachment(TEST_FILE_WITHOUT_CONTENT); - exist(readFileFromDownloads(TEST_FILE_WITHOUT_CONTENT)); + attachmentVerifier.verifyAttachmentDownload(TEST_FILE_WITHOUT_CONTENT); }); it('should download attachment with content on click', () => { - attachmentList.getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.downloadAttachment(TEST_FILE_WITH_CONTENT); - exist(readFileFromDownloads(TEST_FILE_WITH_CONTENT)); + attachmentVerifier.verifyAttachmentDownload(TEST_FILE_WITH_CONTENT); }); it('should not show empty attachment after deleting it', () => { - attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDeleteButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.deleteAttachment(TEST_FILE_WITHOUT_CONTENT); + + attachmentVerifier.verifyAttachmentNotInList(TEST_FILE_WITHOUT_CONTENT); + }); - notExist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); + it('should delete and multi upload all', () => { + attachmentHelper.deleteAttachments([TEST_FILE_WITH_CONTENT]); + + attachmentHelper.uploadAttachments([TEST_FILE_WITH_CONTENT, TEST_FILE_WITHOUT_CONTENT]); + + attachmentVerifier.verifyAttachmentsInList([TEST_FILE_WITH_CONTENT, TEST_FILE_WITHOUT_CONTENT]); }); }); describe('attach file > 3 MB', () => { - it('should show failed upload', () => { - uploadFile(postfachMailFormular.getAttachmentContainer().getUploadInput(), TEST_FILE_WITH_CONTENT_4_MB); - waitForSpinnerToDisappear(); + it('should show failed upload', { defaultCommandTimeout: 90000 }, () => { + attachmentHelper.uploadAttachment(TEST_FILE_WITH_CONTENT_4_MB); exist(attachmentList.getLoadingOrErrorItem(TEST_FILE_WITH_CONTENT_4_MB).getRoot()); contains( diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts index 66ed9474b72739851ea9c6f0eb4845b761d91377..122141ad34b4cb0fbf1b594b071ffaa932e9166f 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts @@ -132,7 +132,7 @@ describe('Vorgang Anhänge', () => { }); it('should download attachment zip file', () => { - attachmentList.downloadAttachments(); + attachmentList.getDownloadArchiveButton().click(); waitForSpinnerToDisappear(); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-abbrechen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-abbrechen.cy.ts index 7292aa333e4233b18c846485f02d316a080b6dc4..d7f9e7a5a73f9fa0eb942be9e5b64b25e4f53169 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-abbrechen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-abbrechen.cy.ts @@ -88,9 +88,9 @@ describe('Vorgang - Bescheid abbrechen', () => { it('should upload files and continue to step 3', () => { bescheidWizard.uploadBescheid(TEST_FILE_BESCHEID_VALID); - bescheidWizard.bescheidUploadSpinnerIsClosed(); + waitForSpinnerToDisappear(); bescheidWizard.uploadAttachment(TEST_FILE_BESCHEID_ANHANG_VALID); - bescheidWizard.attachmentSpinnerIsClosed(); + waitForSpinnerToDisappear(); bescheidWizard.weiter(); bescheidWizard.isBescheidVersendenStep(); @@ -140,9 +140,10 @@ describe('Vorgang - Bescheid abbrechen', () => { it('should upload Bescheid and attachment', () => { uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); + uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - notExist(bescheidWizard.getAttachmentUploadSpinner()); + waitForSpinnerToDisappear(); }); it('should open dialog after click on X', () => { bescheidWizard.close(); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts index 7cd0331269d087f962a1602f91a87b27ddf14128..1a8e2f654385e9d00a147f3d87277d3d4c175686 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts @@ -28,12 +28,7 @@ import { VorgangBescheidWizardE2EComponent } from 'apps/alfa-e2e/src/components/ import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; import { VorgangSubnavigationE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-subnavigation'; import { SmockerMocks } from 'apps/alfa-e2e/src/model/smocker'; -import { - EingangE2E, - EingangHeaderE2E, - VorgangE2E, - VorgangStatusE2E, -} from 'apps/alfa-e2e/src/model/vorgang'; +import { EingangE2E, EingangHeaderE2E, VorgangE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang'; import 'cypress-real-events/support'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; @@ -41,12 +36,7 @@ import { VorgangPage } from '../../../page-objects/vorgang.po'; import { addSmockerMock, dropCollections } from '../../../support/cypress-helper'; import { exist, haveText, notExist } from '../../../support/cypress.util'; import { initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; -import { - buildVorgang, - createVorgang, - initVorgaenge, - objectIds, -} from '../../../support/vorgang-util'; +import { buildVorgang, createVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util'; registerLocaleData(localeDe, 'de', localeDeExtra); @@ -79,8 +69,7 @@ describe('Upload automatic Bescheid', () => { status: VorgangStatusE2E.IN_BEARBEITUNG, }; - const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = - vorgangPage.getFormularButtons(); + const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); const vorgangSubnavigation: VorgangSubnavigationE2EComponent = vorgangPage.getSubnavigation(); @@ -114,8 +103,7 @@ describe('Upload automatic Bescheid', () => { waitForSpinnerToDisappear(); bescheidWizard.getUploadAutomaticBescheidButton().click(); - exist(bescheidWizard.getBescheidUploadSpinner()); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); exist(bescheidWizard.getAutomaticBescheidFileInWizard()); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-dokumente-hochladen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-dokumente-hochladen.cy.ts index 2f0235885f20f005854b6a72df819534cbd15c6c..71531d122d7f3fdc14570feb7d498dd7f449b467 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-dokumente-hochladen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-dokumente-hochladen.cy.ts @@ -26,15 +26,25 @@ 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 { E2EAttachmentHelper } from 'apps/alfa-e2e/src/helper/attachment/attachment.helper'; +import { E2EAttachmentVerifier } from 'apps/alfa-e2e/src/helper/attachment/attachment.verifier'; import { VorgangE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang'; import { uploadFile } from 'apps/alfa-e2e/src/support/file-upload'; import 'cypress-real-events/support'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; -import { dropCollections, getTestElement } from '../../../support/cypress-helper'; +import { dropCollections } from '../../../support/cypress-helper'; import { contains, exist, haveText, haveValue, notContains, notExist } from '../../../support/cypress.util'; -import { TEST_FILE_BESCHEID_ANHANG_BIG, TEST_FILE_BESCHEID_ANHANG_VALID, TEST_FILE_BESCHEID_VALID, TEST_FILE_JPEG, TEST_FILE_JPG, TEST_FILE_PNG, TEST_FILE_WITH_CONTENT, } from '../../../support/data.util'; +import { + TEST_FILE_BESCHEID_ANHANG_BIG, + TEST_FILE_BESCHEID_ANHANG_VALID, + TEST_FILE_BESCHEID_VALID, + TEST_FILE_JPEG, + TEST_FILE_JPG, + TEST_FILE_PNG, + TEST_FILE_WITH_CONTENT, +} from '../../../support/data.util'; import { initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; import { buildVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util'; @@ -54,6 +64,9 @@ describe('Bescheid Dokumente hochladen', () => { const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); + const attachmentHelper: E2EAttachmentHelper = new E2EAttachmentHelper(); + const attachmentVerifier: E2EAttachmentVerifier = new E2EAttachmentVerifier(); + const documentError: string = 'Erlaubte Dateiendungen'; const sizeError: string = 'Anhänge größer'; const missingBescheidError: string = 'Bitte fügen Sie ein Bescheiddokument hinzu.'; @@ -90,13 +103,15 @@ describe('Bescheid Dokumente hochladen', () => { it('should upload manual Bescheid file', () => { uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); + exist(bescheidWizard.getFileBescheidValidInWizard()); }); it('should upload attachment file', () => { - uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - exist(bescheidWizard.getFileAnhangValidInWizard()); + attachmentHelper.uploadAttachment(TEST_FILE_BESCHEID_ANHANG_VALID); + + attachmentVerifier.verifyAttachmentInList(TEST_FILE_BESCHEID_ANHANG_VALID); }); it('should still show files after clicking Weiter and step 2', () => { @@ -127,15 +142,9 @@ describe('Bescheid Dokumente hochladen', () => { }); it('should be able to attach all valid types of files', () => { - uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_JPG); - notExist(bescheidWizard.getAttachmentUploadSpinner()); - uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_JPEG); - notExist(bescheidWizard.getAttachmentUploadSpinner()); - uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_PNG); - notExist(bescheidWizard.getAttachmentUploadSpinner()); - exist(getTestElement(bescheidWizard.getElementFromFileName(TEST_FILE_JPG))); - exist(getTestElement(bescheidWizard.getElementFromFileName(TEST_FILE_JPEG))); - exist(getTestElement(bescheidWizard.getElementFromFileName(TEST_FILE_PNG))); + attachmentHelper.uploadAttachments([TEST_FILE_JPG, TEST_FILE_JPEG, TEST_FILE_PNG]); + + attachmentVerifier.verifyAttachmentsInList([TEST_FILE_JPG, TEST_FILE_JPEG, TEST_FILE_PNG]); }); }); @@ -145,8 +154,9 @@ describe('Bescheid Dokumente hochladen', () => { contains(bescheidWizard.getBescheidDocument(), documentError); }); - it('should show error if file is too big', () => { + it('should show error if file is too big', { defaultCommandTimeout: 90000 }, () => { uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_BIG); + contains(bescheidWizard.getAttachmentDocument(), sizeError); }); }); @@ -162,7 +172,7 @@ describe('Bescheid Dokumente hochladen', () => { describe('check contents of step 3', () => { it('should show Max Testermann as Antragsteller, the default message text', () => { uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-historie.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-historie.cy.ts index 36320a61d712fa2189a6e23b43971de8fe1ffbf6..55c6b8b418ee3224b35210e6b963dbf78e03d268 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-historie.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-historie.cy.ts @@ -29,7 +29,10 @@ import { VorgangBescheideE2EComponent } from 'apps/alfa-e2e/src/components/vorga import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; import { VorgangFormularDatenE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component'; import { VorgangSubnavigationE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-subnavigation'; -import { BescheidHistorieItemE2EComponent, VorgangFormularDatenHistorieItemE2EComponent, } from 'apps/alfa-e2e/src/components/vorgang/vorgang.formular-daten.historie.e2e.component'; +import { + BescheidHistorieItemE2EComponent, + VorgangFormularDatenHistorieItemE2EComponent, +} from 'apps/alfa-e2e/src/components/vorgang/vorgang.formular-daten.historie.e2e.component'; import { HistorieHeadlineE2E } from 'apps/alfa-e2e/src/model/historie'; import { VorgangE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang'; import { TEST_FILE_BESCHEID_ANHANG_VALID, TEST_FILE_BESCHEID_VALID } from 'apps/alfa-e2e/src/support/data.util'; @@ -110,9 +113,9 @@ describe('Bescheid History', () => { waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - notExist(bescheidWizard.getAttachmentUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); waitForSpinnerToDisappear(); wait(waitForFormPatchMillis, 'Wait for patch form values to be completed.'); @@ -151,7 +154,7 @@ describe('Bescheid History', () => { waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); waitForSpinnerToDisappear(); wait(waitForFormPatchMillis, 'Wait for patch form values to be completed.'); @@ -186,17 +189,16 @@ describe('Bescheid History', () => { waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - notExist(bescheidWizard.getAttachmentUploadSpinner()); + waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - notExist(bescheidWizard.getAttachmentUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); waitForSpinnerToDisappear(); bescheidWizard.getSendButton().click(); - exist(bescheidWizard.getSendenSpinner()); - notExist(bescheidWizard.getSendenSpinner()); + waitForSpinnerToDisappear(); vorgangDatenFormular.getHistorieTab().click(); const historieItemExpand: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(0); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-info-anzeigen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-info-anzeigen.cy.ts index a6d7e8cc4795a1794745211f20c99a6f4a7e213e..d0e5d9939d952ad91aad4b1539b7989decf1f00b 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-info-anzeigen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-info-anzeigen.cy.ts @@ -132,9 +132,9 @@ describe('Bescheid Info anzeigen', () => { it('should upload files and continue to step 3', () => { bescheidWizard.uploadBescheid(TEST_FILE_BESCHEID_VALID); - bescheidWizard.bescheidUploadSpinnerIsClosed(); + waitForSpinnerToDisappear(); bescheidWizard.uploadAttachment(TEST_FILE_BESCHEID_ANHANG_VALID); - bescheidWizard.attachmentSpinnerIsClosed(); + waitForSpinnerToDisappear(); bescheidWizard.weiter(); bescheidWizard.isBescheidVersendenStep(); @@ -193,7 +193,7 @@ describe('Bescheid Info anzeigen', () => { it('should upload Bescheid and continue to step 3', () => { bescheidWizard.uploadBescheid(TEST_FILE_BESCHEID_VALID); - bescheidWizard.bescheidUploadSpinnerIsClosed(); + waitForSpinnerToDisappear(); bescheidWizard.weiter(); bescheidWizard.isBescheidVersendenStep(); }); @@ -201,9 +201,7 @@ describe('Bescheid Info anzeigen', () => { it('should show 2 Bescheid containers after saving', () => { bescheidWizard.getSaveButton().click(); bescheidWizard.getConfirmAndSaveButton().click(); - exist(bescheidWizard.getBescheidSaveSpinner()); - notExist(bescheidWizard.getBescheidSaveSpinner()); - + waitForSpinnerToDisappear(); haveLength(bescheide.getBescheidContainer(), 2); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-nur-speichern.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-nur-speichern.cy.ts index f7c01770b981f35ce9753d9898b89648dfcfb685..54c4965b9fb8e41f6cced9749f375e472bc5a262 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-nur-speichern.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-nur-speichern.cy.ts @@ -83,9 +83,9 @@ describe('Bescheid speichern', () => { enterWith(bescheidWizard.getDateInput(), getAdjustedDateGerman(-1)); bescheidWizard.getWeiterButton().click(); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - notExist(bescheidWizard.getAttachmentUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); waitForSpinnerToDisappear(); wait(waitForFormPatchMillis, 'Wait for patch form values to be completed.'); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-senden.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-senden.cy.ts index 7d5ccdabee70ce2b9e5307e61cf20b79d18919f5..43e23febb7f15a82dd1431890c52590438388cfd 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-senden.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-senden.cy.ts @@ -32,10 +32,7 @@ import { VorgangBescheidWizardE2EComponent } from 'apps/alfa-e2e/src/components/ import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; import { VorgangE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang'; import { PostfachMailPage } from 'apps/alfa-e2e/src/page-objects/postfach-mail.component.po'; -import { - TEST_FILE_BESCHEID_ANHANG_VALID, - TEST_FILE_BESCHEID_VALID, -} from 'apps/alfa-e2e/src/support/data.util'; +import { TEST_FILE_BESCHEID_ANHANG_VALID, TEST_FILE_BESCHEID_VALID } from 'apps/alfa-e2e/src/support/data.util'; import { uploadFile } from 'apps/alfa-e2e/src/support/file-upload'; import { getAdjustedDateGerman } from 'apps/alfa-e2e/src/support/tech.util'; import 'cypress-real-events/support'; @@ -43,7 +40,7 @@ import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-lis import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections } from '../../../support/cypress-helper'; -import { contains, enterWith, exist, notExist } from '../../../support/cypress.util'; +import { contains, enterWith, exist } from '../../../support/cypress.util'; import { initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; import { buildVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util'; @@ -66,8 +63,7 @@ describe('Bescheid senden', () => { status: VorgangStatusE2E.IN_BEARBEITUNG, }; - const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = - vorgangPage.getFormularButtons(); + const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); before(() => { initVorgaenge([bescheidSendenVorgang]); @@ -93,9 +89,9 @@ describe('Bescheid senden', () => { enterWith(bescheidWizard.getDateInput(), getAdjustedDateGerman(1)); bescheidWizard.getWeiterButton().click(); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); uploadFile(bescheidWizard.getUploadAttachmentButton(), TEST_FILE_BESCHEID_ANHANG_VALID); - notExist(bescheidWizard.getAttachmentUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); bescheidWizard.getSendButton().click(); @@ -114,21 +110,9 @@ describe('Bescheid senden', () => { const postfachListItem: PostfachMailListItem = postfachMailPage.getListItem(mailText); contains(postfachMailPage.getMailText(), anredeText); - exist( - postfachListItem - .getAttachmentContainer() - .getList() - .getItem(TEST_FILE_BESCHEID_VALID) - .getRoot(), - ); - - exist( - postfachListItem - .getAttachmentContainer() - .getList() - .getItem(TEST_FILE_BESCHEID_ANHANG_VALID) - .getRoot(), - ); + exist(postfachListItem.getAttachmentContainer().getList().getItem(TEST_FILE_BESCHEID_VALID).getRoot()); + + exist(postfachListItem.getAttachmentContainer().getList().getItem(TEST_FILE_BESCHEID_ANHANG_VALID).getRoot()); }); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-wizard.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-wizard.cy.ts index d02307f1af90ab1e2a3fdaa354534dd8861cba7c..06378019b3ceaf1a1d74e8143846923091b7c2a0 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-wizard.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-wizard.cy.ts @@ -118,7 +118,7 @@ describe('Bescheid Wizard', () => { bescheidWizard.getRoot().should('not.contain', stepCaption3); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.getWeiterButton().click(); waitForSpinnerToDisappear(); bescheidWizard.getRoot().contains(stepCaption1); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts index c93d89d9e08a0433aa15dc52a59e02b8a848f3c1..c1b5866cb7d4483cae346c7a3b036ae99654975c 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts @@ -140,7 +140,7 @@ describe('Dateien Tab', () => { it('should show attachments and download button', () => { exist(vorgangDatenFormular.getFileElementByName(jpgFileName)); exist(vorgangDatenFormular.getFileElementByName(pdfFileName)); - exist(attachmentList.getDownloadAttachmentsButton(vorgangDatenFormular.getRoot())); + exist(attachmentList.getDownloadArchiveButton()); }); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forward-by-ozgcloud.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forward-by-ozgcloud.cy.ts deleted file mode 100644 index d4661c6d5f536cda3e4286f4064b157cd5e56cf0..0000000000000000000000000000000000000000 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forward-by-ozgcloud.cy.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { registerLocaleData } from '@angular/common'; -import localeDe from '@angular/common/locales/de'; -import localeDeExtra from '@angular/common/locales/extra/de'; -import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; -import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; -import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; -import { VorgangPage } from '../../../page-objects/vorgang.po'; -import { dropCollections } from '../../../support/cypress-helper'; -import { exist, notExist } from '../../../support/cypress.util'; -import { loginAsPeter, loginAsSabine } from '../../../support/user-util'; -import { createVorgang, initVorgaenge } from '../../../support/vorgang-util'; - -registerLocaleData(localeDe, 'de', localeDeExtra); - -describe('Vorgang weiterleiten innerhalb der OzgCloud', () => { - const mainPage: MainPage = new MainPage(); - const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); - - const vorgangPage: VorgangPage = new VorgangPage(); - const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); - - const vorgangWeiterleiten: VorgangE2E = { ...createVorgang(), name: 'Weiterleitung' }; - - after(() => { - dropCollections(); - }); - - describe('For Sabine', () => { - before(() => { - initVorgaenge([vorgangWeiterleiten]); - - loginAsSabine(); - - waitForSpinnerToDisappear(); - exist(vorgangList.getRoot()); - }); - - it('should display Weiterleiten button in Status Neu', () => { - vorgangList.getListItem(vorgangWeiterleiten.name).getRoot().click(); - waitForSpinnerToDisappear(); - - exist(vorgangFormularButtons.getForwardButton()); - }); - - it('should not display Weiterleiten button in Status Angenommen', () => { - vorgangFormularButtons.getAnnehmenButton().click(); - waitForSpinnerToDisappear(); - - notExist(vorgangFormularButtons.getForwardButton()); - }); - - it('should not display Weiterleiten button in Status In Bearbeitung', () => { - vorgangFormularButtons.getBearbeitenButton().click(); - waitForSpinnerToDisappear(); - - notExist(vorgangFormularButtons.getForwardButton()); - }); - }); - - describe('For Peter', () => { - before(() => { - initVorgaenge([vorgangWeiterleiten]); - - loginAsPeter(); - - waitForSpinnerToDisappear(); - exist(vorgangList.getRoot()); - }); - - it('should not display Weiterleiten button in Status In Neu', () => { - vorgangList.getListItem(vorgangWeiterleiten.name).getRoot().click(); - waitForSpinnerToDisappear(); - - notExist(vorgangFormularButtons.getForwardButton()); - }); - }); -}); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..d91019905c1bc53a44fb0a28e0fb882a416933f3 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts @@ -0,0 +1,148 @@ +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; +import localeDeExtra from '@angular/common/locales/extra/de'; +import { VorgangFormularButtonsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular-buttons.e2e.components'; +import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; +import { E2EVorgangNavigator } from '../../../helper/vorgang/vorgang.navigator'; +import { E2EVorgangVerifier } from '../../../helper/vorgang/vorgang.verifier'; +import { VorgangE2E } from '../../../model/vorgang'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; +import { VorgangPage } from '../../../page-objects/vorgang.po'; +import { dropCollections } from '../../../support/cypress-helper'; +import { beDisabled, contains, exist, notBeDisabled, notExist } from '../../../support/cypress.util'; +import { loginAsPeter, loginAsSabine } from '../../../support/user-util'; +import { createVorgang, initVorgaenge } from '../../../support/vorgang-util'; +import { ForwardingDialogE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-forwarding-dialog.e2e.component'; + +registerLocaleData(localeDe, 'de', localeDeExtra); + +describe('Vorgang weiterleiten', () => { + const vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator(); + const vorgangVerifier: E2EVorgangVerifier = new E2EVorgangVerifier(); + + const mainPage: MainPage = new MainPage(); + const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); + + const organisationsEinheitName = 'Landeshauptstadt Kiel - Pries-Friedrichsort Stadtteilamt'; + const organisationsEinheitAddress = 'An der Schanze 45, 24159 Kiel'; + + const vorgangPage: VorgangPage = new VorgangPage(); + const forwardingDialog: ForwardingDialogE2EComponent = vorgangPage.getForwardingDialogContainer(); + const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); + + const vorgangWeiterleiten: VorgangE2E = { ...createVorgang(), name: 'Weiterleitung' }; + + after(() => { + dropCollections(); + }); + + describe('For Sabine', () => { + before(() => { + initVorgaenge([vorgangWeiterleiten]); + + loginAsSabine(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }); + + it('should display Weiterleiten button in Status Neu', () => { + vorgangList.getListItem(vorgangWeiterleiten.name).getRoot().click(); + waitForSpinnerToDisappear(); + + vorgangVerifier.verifyForwardingButtonExists(); + }); + + it('should open forwarding dialog on forward button click', () => { + vorgangFormularButtons.getForwardButton().click(); + + exist(forwardingDialog.getRoot()); + }); + + it('should have zufi search', () => { + exist(forwardingDialog.getZufiSearch()); + }); + + it('should have disabled forwarding button', () => { + beDisabled(forwardingDialog.getForwardingButton()); + }); + + it('should close dialog on escape', () => { + forwardingDialog.getRoot().type('{esc}'); + + notExist(forwardingDialog.getRoot()); + }); + + it('should close dialog on abbrechen button', () => { + vorgangFormularButtons.getForwardButton().click(); + forwardingDialog.getCancelButton().click(); + + notExist(forwardingDialog.getRoot()); + }); + + it('should close dialog on x icon', () => { + vorgangFormularButtons.getForwardButton().click(); + forwardingDialog.getCancelIconButton().click(); + + notExist(forwardingDialog.getRoot()); + }); + + it('should show forwarding item on search select', () => { + vorgangFormularButtons.getForwardButton().click(); + forwardingDialog.search(organisationsEinheitName); + forwardingDialog.clickSearchEntry(0); + + exist(forwardingDialog.getForwardingItem()); + contains(forwardingDialog.getForwardingItem(), organisationsEinheitName); + contains(forwardingDialog.getForwardingItem(), organisationsEinheitAddress); + }); + + it('should not show zufi search on search select', () => { + notExist(forwardingDialog.getZufiSearch()); + }); + + it('should not disable forwarding button on search select', () => { + notBeDisabled(forwardingDialog.getForwardingButton()); + }); + + it('should clear forwarding item on change button click', () => { + forwardingDialog.getChangeButton().click(); + + notExist(forwardingDialog.getForwardingItem()); + exist(forwardingDialog.getZufiSearch()); + beDisabled(forwardingDialog.getForwardingButton()); + }); + + it('should not display Weiterleiten button in status Angenommen', () => { + forwardingDialog.getCancelButton().click(); + vorgangFormularButtons.getAnnehmenButton().click(); + waitForSpinnerToDisappear(); + + vorgangVerifier.verifyNoForwardingButtonExists(); + }); + + it('should not display Weiterleiten button in status In Bearbeitung', () => { + vorgangFormularButtons.getBearbeitenButton().click(); + waitForSpinnerToDisappear(); + + vorgangVerifier.verifyNoForwardingButtonExists(); + }); + }); + + describe('For Peter', () => { + before(() => { + initVorgaenge([vorgangWeiterleiten]); + + loginAsPeter(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }); + + it('should display Weiterleiten button in Status In Neu', () => { + vorgangNavigator.openVorgangDetailByName(vorgangWeiterleiten.name); + + vorgangVerifier.verifyForwardingButtonExists(); + }); + }); +}); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts index 1018a1081b39f524092d92c8d3449c9bdeb2d363..45a24946fded8a238f1d92fa39d4c057b28a5573 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-pages.cy.ts @@ -30,6 +30,7 @@ import { dropCollections, intercept, scrollToWindowBottom, + scrollToWindowTop, waitOfInterceptor, } from '../../../support/cypress-helper'; import { generateIds } from '../../../support/tech.util'; @@ -72,13 +73,8 @@ describe('VorgangList Pages', () => { it('should show 1 page with 100 vorgaenge NEU', () => { waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEU_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangNEU_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEU_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangNEU_' + PAGE_SIZE); }); }); }); @@ -95,14 +91,8 @@ describe('VorgangList Pages', () => { waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangNEUAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangNEUAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEUAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangNEUAssigned_' + PAGE_SIZE); }); waitForSpinnerToDisappear(); }); @@ -120,14 +110,8 @@ describe('VorgangList Pages', () => { waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangANGENOMMEN_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangANGENOMMEN_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangANGENOMMEN_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangANGENOMMEN_' + PAGE_SIZE); }); waitForSpinnerToDisappear(); }); @@ -140,20 +124,18 @@ describe('VorgangList Pages', () => { intercept(HttpMethodE2E.GET, buildVorgangPageLink(4)).as(loadNextPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 3 page with 100 vorgaenge ANGENOMMEN ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { scrollToWindowBottom(); assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangANGENOMMENAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangANGENOMMENAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangANGENOMMENAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangANGENOMMENAssigned_' + PAGE_SIZE); }); }); }); @@ -176,14 +158,8 @@ describe('VorgangList Pages', () => { waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangNEUAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangNEUAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangNEUAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangNEUAssigned_' + PAGE_SIZE); }); }); }); @@ -195,19 +171,17 @@ describe('VorgangList Pages', () => { intercept(HttpMethodE2E.GET, buildVorgangPageLink(2)).as(loadNextPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 2 page with 100 vorgaenge ANGENOMMEN ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); waitOfInterceptor(loadNextPageInterceptor).then((interception: Interception) => { assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert( - interception.response.body._embedded.vorgangHeaderList[0].name === - 'VorgangANGENOMMENAssigned_1', - ); - assert( - interception.response.body._embedded.vorgangHeaderList[99].name === - 'VorgangANGENOMMENAssigned_' + PAGE_SIZE, - ); + assert(interception.response.body._embedded.vorgangHeaderList[0].name === 'VorgangANGENOMMENAssigned_1'); + assert(interception.response.body._embedded.vorgangHeaderList[99].name === 'VorgangANGENOMMENAssigned_' + PAGE_SIZE); }); waitForSpinnerToDisappear(); }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-views-pages.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-views-pages.cy.ts index 2a2316dfc645ba0cbb99af05b34b041ce5d7646e..d8374f8aa947247e627e8d5d437f4aca9f61c9a7 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-views-pages.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-views-pages.cy.ts @@ -23,13 +23,22 @@ */ import { NavigationE2EComponent } from 'apps/alfa-e2e/src/components/navigation/navigation.e2e.component'; import { VorgangListE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-list.e2e.component'; -import { VorgangViewsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-views.e2e.component'; +import { + VorgangViewE2EComponent, + VorgangViewsE2EComponent, +} from 'apps/alfa-e2e/src/components/vorgang/vorgang-views.e2e.component'; import { MainPage, waitForSpinnerToDisappear } from 'apps/alfa-e2e/src/page-objects/main.po'; import { exist } from 'apps/alfa-e2e/src/support/cypress.util'; import { Interception } from 'cypress/types/net-stubbing'; import { HttpMethodE2E } from '../../../model/util'; import { VorgangE2E, VorgangStatusE2E } from '../../../model/vorgang'; -import { dropCollections, intercept, scrollToWindowBottom, waitOfInterceptor } from '../../../support/cypress-helper'; +import { + dropCollections, + intercept, + scrollToWindowBottom, + scrollToWindowTop, + waitOfInterceptor, +} from '../../../support/cypress-helper'; import { generateIds } from '../../../support/tech.util'; import { getUserSabineId, initUsermanagerUsers, loginAsSabine } from '../../../support/user-util'; import { buildVorgang, initVorgaenge } from '../../../support/vorgang-util'; @@ -43,6 +52,7 @@ describe('VorgangList View Pages', () => { const views: VorgangViewsE2EComponent = mainPage.getViews(); + const VORGANG_NAME_PREFIX: string = 'Vorgang'; const PAGE_SIZE: number = 100; const assignedTo: string = getUserSabineId(); @@ -57,6 +67,8 @@ describe('VorgangList View Pages', () => { createAssignedVorgaengeWithStatus(VorgangStatusE2E.BESCHIEDEN), createVorgaengeWithStatus(VorgangStatusE2E.ABGESCHLOSSEN), createAssignedVorgaengeWithStatus(VorgangStatusE2E.ABGESCHLOSSEN), + createVorgaengeWithStatus(VorgangStatusE2E.WEITERGELEITET), + createAssignedVorgaengeWithStatus(VorgangStatusE2E.WEITERGELEITET), createVorgaengeWithStatus(VorgangStatusE2E.VERWORFEN), createAssignedVorgaengeWithStatus(VorgangStatusE2E.VERWORFEN), ); @@ -73,914 +85,259 @@ describe('VorgangList View Pages', () => { }); describe('Neu', () => { - const ALLE_NAME_PREFIX: string = 'VorgangNEU_'; - const MEINE_VORGAENGE_NAME_PREFIX: string = 'VorgangNEUAssigned_'; + const STATUS: string = VorgangStatusE2E.NEU; - describe('Alle filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangNeuPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge NEU', () => { - views.getNeu().getRoot().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangNeuPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge NEU and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 3', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangNeuPageLink(3)).as(loadPageInterceptor); - }); - - it('should show page 3 with 10 vorgaenge NEU ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 20); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 80); - assert(interception.response.body._embedded.vorgangHeaderList[19].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - function buildVorgangNeuPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&status=NEU`; - } - }); - - describe('Meine Vorgänge filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangNeuAssignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge NEU', () => { - navigation.getMeineVorgaengeFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangNeuAssignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge NEU and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); - }); - }); - - function buildVorgangNeuAssignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=NEU`; - } - }); - - describe('Nicht zugewiesen filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangUnassignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge NEU', () => { - navigation.getUnassignedFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangUnassignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, ALLE_NAME_PREFIX + 110); - }); - }); - }); - - function buildVorgangUnassignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=&status=NEU`; - } - }); + testAlleFilter(STATUS, views.getNeu()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); }); describe('Angenommen', () => { - const ALLE_NAME_PREFIX: string = 'VorgangANGENOMMEN_'; - const MEINE_VORGAENGE_NAME_PREFIX: string = 'VorgangANGENOMMENAssigned_'; - - describe('Alle filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - navigation.getAlleFilter().click(); - waitForSpinnerToDisappear(); - intercept(HttpMethodE2E.GET, buildVorgangAngenommenPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge ANGENOMMEN', () => { - views.getAngenommen().getRoot().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAngenommenPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge ANGENOMMEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 3', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAngenommenPageLink(3)).as(loadPageInterceptor); - }); - - it('should show page 3 with 10 vorgaenge ANGENOMMEN ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); + const STATUS: string = VorgangStatusE2E.ANGENOMMEN; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 20); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 80); - assert(interception.response.body._embedded.vorgangHeaderList[19].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - function buildVorgangAngenommenPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&status=ANGENOMMEN`; - } - }); - - describe('Meine Vorgänge filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAngenommenAssignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge ANGENOMMEN', () => { - navigation.getMeineVorgaengeFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAngenommenAssignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge ANGENOMMEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); - }); - }); - - function buildVorgangAngenommenAssignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=ANGENOMMEN`; - } - }); - - describe('Nicht zugewiesen filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAngenommenUnassignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge ANGENOMMEN', () => { - navigation.getUnassignedFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAngenommenUnassignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, ALLE_NAME_PREFIX + 110); - }); - }); - }); - - function buildVorgangAngenommenUnassignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=&status=ANGENOMMEN`; - } - }); + testAlleFilter(STATUS, views.getAngenommen()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); }); describe('In Bearbeitung', () => { - const ALLE_NAME_PREFIX: string = 'VorgangIN_BEARBEITUNG_'; - const MEINE_VORGAENGE_NAME_PREFIX: string = 'VorgangIN_BEARBEITUNGAssigned_'; + const STATUS: string = VorgangStatusE2E.IN_BEARBEITUNG; - describe('Alle filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - navigation.getAlleFilter().click(); - waitForSpinnerToDisappear(); - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge IN_BEARBEITUNG', () => { - views.getInBearbeitung().getRoot().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); + testAlleFilter(STATUS, views.getInBearbeitung()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); + }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; + describe('Bescheiden', () => { + const STATUS: string = VorgangStatusE2E.BESCHIEDEN; - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungPageLink(2)).as(loadPageInterceptor); - }); + testAlleFilter(STATUS, views.getBeschieden()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); + }); - it('should show page 2 with 10 vorgaenge IN_BEARBEITUNG and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); + describe('Abgeschlossen', () => { + const STATUS: string = VorgangStatusE2E.ABGESCHLOSSEN; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); + testAlleFilter(STATUS, views.getAbgeschlossen()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); + }); - describe('page 3', () => { - const loadPageInterceptor: string = 'loadPage'; + describe('Weitergeleitet', () => { + const STATUS: string = VorgangStatusE2E.WEITERGELEITET; - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungPageLink(3)).as(loadPageInterceptor); - }); + testAlleFilter(STATUS, views.getWeitergeleitet()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); + }); - it('should show page 3 with 10 vorgaenge IN_BEARBEITUNG ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); + describe('Verworfen', () => { + const STATUS: string = VorgangStatusE2E.VERWORFEN; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 20); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 80); - assert(interception.response.body._embedded.vorgangHeaderList[19].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); + testAlleFilter(STATUS, views.getVerworfen()); + testMeineVorgaengeFilter(STATUS); + testNichtZugewiesenFilter(STATUS); + }); - function buildVorgangInBearbeitungPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&status=IN_BEARBEITUNG`; - } + function testAlleFilter(status: string, view: VorgangViewE2EComponent) { + describe('Alle filter', () => { + testAlleFilterPage1(status, view); + testAlleFilterPage2(status); + testAlleFilterPage3(status); }); + } - describe('Meine Vorgänge filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungAssignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge IN_BEARBEITUNG', () => { - navigation.getMeineVorgaengeFilter().click(); + function testAlleFilterPage1(status: string, view: VorgangViewE2EComponent): void { + describe('page 1', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + navigation.getAlleFilter().click(); + waitForSpinnerToDisappear(); + intercept(HttpMethodE2E.GET, buildVorgangStatusPageLink(1, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; + it(`should show page 1 with 100 vorgaenge ${status}`, () => { + view.getRoot().click(); - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungAssignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge IN_BEARBEITUNG and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === PAGE_SIZE); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + status + 1); + assert(getVorgangList(interception)[99].name, VORGANG_NAME_PREFIX + status + PAGE_SIZE); }); }); - - function buildVorgangInBearbeitungAssignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=IN_BEARBEITUNG`; - } }); + } - describe('Nicht zugewiesen filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungUnassignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge IN_BEARBEITUNG', () => { - navigation.getUnassignedFilter().click(); + function testAlleFilterPage2(status: string): void { + describe('page 2', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + intercept(HttpMethodE2E.GET, buildVorgangStatusPageLink(2, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; + it(`should show page 2 with 10 vorgaenge ${status} and 90 vorgaenge ASSIGNED on scrolling to bottom`, () => { + scrollToWindowBottom(); - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBearbeitungUnassignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, ALLE_NAME_PREFIX + 110); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === PAGE_SIZE); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + 1); + assert(getVorgangList(interception)[99].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + PAGE_SIZE); }); }); - - function buildVorgangInBearbeitungUnassignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=&status=IN_BEARBEITUNG`; - } }); - }); - - describe('Beschieden', () => { - const ALLE_NAME_PREFIX: string = 'VorgangBESCHIEDEN_'; - const MEINE_VORGAENGE_NAME_PREFIX: string = 'VorgangBESCHIEDENAssigned_'; - - describe('Alle filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - navigation.getAlleFilter().click(); - waitForSpinnerToDisappear(); - intercept(HttpMethodE2E.GET, buildVorgangBeschiedenPageLink(1)).as(loadPageInterceptor); - }); + } - it('should show page 1 with 100 vorgaenge BESCHIEDEN', () => { - views.getBeschieden().getRoot().click(); + function testAlleFilterPage3(status: string): void { + describe('page 3', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + intercept(HttpMethodE2E.GET, buildVorgangStatusPageLink(3, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangBeschiedenPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge BESCHIEDEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); + after(() => { + scrollToWindowTop(); }); - describe('page 3', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangBeschiedenPageLink(3)).as(loadPageInterceptor); - }); - - it('should show page 3 with 10 vorgaenge BESCHIEDEN ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); + it(`should show page 3 with 10 vorgaenge ${status} ASSIGNED on scrolling to bottom`, () => { + scrollToWindowBottom(); - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 20); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 80); - assert(interception.response.body._embedded.vorgangHeaderList[19].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === 20); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + 80); + assert(getVorgangList(interception)[19].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + PAGE_SIZE); }); }); - - function buildVorgangBeschiedenPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&status=BESCHIEDEN`; - } }); + } - describe('Meine Vorgänge filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBescheidenAssignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge BESCHIEDEN', () => { - navigation.getMeineVorgaengeFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBescheidenAssignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge BESCHIEDEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); - }); - }); + function buildVorgangStatusPageLink(page: number, status: string): string { + return `${buildVorgangPageLink(page)}&status=${status}`; + } - function buildVorgangInBescheidenAssignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=BESCHIEDEN`; - } + function testMeineVorgaengeFilter(status: string): void { + describe('Meine Vorgänge filter', () => { + testMeineVorgaengePage1(status); + testMeineVorgaengePage2(status); }); + } - describe('Nicht zugewiesen filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBescheidenUnassignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge BESCHIEDEN', () => { - navigation.getUnassignedFilter().click(); + function testMeineVorgaengePage1(status: string): void { + describe('page 1', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + intercept(HttpMethodE2E.GET, buildVorgangInStatusAssignedPageLink(1, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; + it(`should show page 1 with 100 vorgaenge ${status}`, () => { + navigation.getMeineVorgaengeFilter().click(); - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInBescheidenUnassignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, ALLE_NAME_PREFIX + 110); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === PAGE_SIZE); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + 'Assigned_' + 1); + assert(getVorgangList(interception)[99].name, VORGANG_NAME_PREFIX + 'Assigned_' + PAGE_SIZE); }); }); - - function buildVorgangInBescheidenUnassignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=&status=BESCHIEDEN`; - } }); - }); - - describe('Abgeschlossen', () => { - const ALLE_NAME_PREFIX: string = 'VorgangABGESCHLOSSEN_'; - const MEINE_VORGAENGE_NAME_PREFIX: string = 'VorgangABGESCHLOSSENAssigned_'; - - describe('Alle filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - navigation.getAlleFilter().click(); - waitForSpinnerToDisappear(); - intercept(HttpMethodE2E.GET, buildVorgangAbgeschlossenPageLink(1)).as(loadPageInterceptor); - }); + } - it('should show page 1 with 100 vorgaenge ABGESCHLOSSEN', () => { - views.getAbgeschlossen().getRoot().click(); + function testMeineVorgaengePage2(status: string): void { + describe('page 2', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + intercept(HttpMethodE2E.GET, buildVorgangInStatusAssignedPageLink(2, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAbgeschlossenPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge ABGESCHLOSSEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); + after(() => { + scrollToWindowTop(); }); - describe('page 3', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangAbgeschlossenPageLink(3)).as(loadPageInterceptor); - }); - - it('should show page 3 with 10 vorgaenge ABGESCHLOSSEN ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); + it(`should show page 2 with 10 vorgaenge ${status} and 90 vorgaenge ASSIGNED on scrolling to bottom`, () => { + scrollToWindowBottom(); - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 20); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 80); - assert(interception.response.body._embedded.vorgangHeaderList[19].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === 10); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + 'Assigned_' + 101); + assert(getVorgangList(interception)[9].name, VORGANG_NAME_PREFIX + 'Assigned_' + 110); }); }); - - function buildVorgangAbgeschlossenPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&status=ABGESCHLOSSEN`; - } }); + } - describe('Meine Vorgänge filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInAbgeschlossenAssignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge ABGESCHLOSSEN', () => { - navigation.getMeineVorgaengeFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInAbgeschlossenAssignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge ABGESCHLOSSEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); - }); - }); - - function buildVorgangInAbgeschlossenAssignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=ABGESCHLOSSEN`; - } - }); + function buildVorgangInStatusAssignedPageLink(page: number, status: string): string { + return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=${status}`; + } + function testNichtZugewiesenFilter(status: string): void { describe('Nicht zugewiesen filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInAbgeschlossenUnassignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge ABGESCHLOSSEN', () => { - navigation.getUnassignedFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInAbgeschlossenUnassignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); - }); - }); - - function buildVorgangInAbgeschlossenUnassignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=&status=ABGESCHLOSSEN`; - } + testNichtZugewiesenPage1(status); + testNichtZugewiesenPage2(status); }); - }); - - describe('Verworfen', () => { - const ALLE_NAME_PREFIX: string = 'VorgangVERWORFEN_'; - const MEINE_VORGAENGE_NAME_PREFIX: string = 'VorgangVERWORFENAssigned_'; - - describe('Alle filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - navigation.getAlleFilter().click(); - waitForSpinnerToDisappear(); - intercept(HttpMethodE2E.GET, buildVorgangVerworfenPageLink(1)).as(loadPageInterceptor); - }); + } - it('should show page 1 with 100 vorgaenge VERWORFEN', () => { - views.getVerworfen().getRoot().click(); + function testNichtZugewiesenPage1(status: string): void { + describe('page 1', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + intercept(HttpMethodE2E.GET, buildVorgangInStatusUnassignedPageLink(1, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; + it(`should show page 1 with 100 vorgaeng ${status}`, () => { + navigation.getUnassignedFilter().click(); - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangVerworfenPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge VERWORFEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === PAGE_SIZE); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + 1); + assert(getVorgangList(interception)[99].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + PAGE_SIZE); }); }); - - describe('page 3', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangVerworfenPageLink(3)).as(loadPageInterceptor); - }); - - it('should show page 3 with 10 vorgaenge VERWORFEN ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 20); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 80); - assert(interception.response.body._embedded.vorgangHeaderList[19].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - function buildVorgangVerworfenPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&status=VERWORFEN`; - } }); + } - describe('Meine Vorgänge filter', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInVerworfenAssignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge VERWORFEN', () => { - navigation.getMeineVorgaengeFilter().click(); + function testNichtZugewiesenPage2(status: string): void { + describe('page 2', () => { + const loadPageInterceptor: string = 'loadPage'; - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, MEINE_VORGAENGE_NAME_PREFIX + PAGE_SIZE); - }); - }); + beforeEach(() => { + intercept(HttpMethodE2E.GET, buildVorgangInStatusUnassignedPageLink(2, status)).as(loadPageInterceptor); }); - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; + it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { + scrollToWindowBottom(); - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInVerworfenAssignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge VERWORFEN and 90 vorgaenge ASSIGNED on scrolling to bottom', () => { - scrollToWindowBottom(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, MEINE_VORGAENGE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, MEINE_VORGAENGE_NAME_PREFIX + 110); - }); + waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { + assert(getVorgangList(interception).length === 10); + assert(getVorgangList(interception)[0].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + 101); + assert(getVorgangList(interception)[9].name, VORGANG_NAME_PREFIX + status + 'Assigned_' + 110); }); + scrollToWindowTop(); }); - - function buildVorgangInVerworfenAssignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=${assignedTo}&status=VERWORFEN`; - } }); + } - describe('Nicht zugewiesen', () => { - describe('page 1', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInVerworfenUnassignedPageLink(1)).as(loadPageInterceptor); - }); - - it('should show page 1 with 100 vorgaenge VERWORFEN', () => { - navigation.getUnassignedFilter().click(); - - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === PAGE_SIZE); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 1); - assert(interception.response.body._embedded.vorgangHeaderList[99].name, ALLE_NAME_PREFIX + PAGE_SIZE); - }); - }); - }); - - describe('page 2', () => { - const loadPageInterceptor: string = 'loadPage'; - - beforeEach(() => { - intercept(HttpMethodE2E.GET, buildVorgangInVerworfenUnassignedPageLink(2)).as(loadPageInterceptor); - }); - - it('should show page 2 with 10 vorgaenge on scrolling to bottom', () => { - scrollToWindowBottom(); + function buildVorgangInStatusUnassignedPageLink(page: number, status: string): string { + return `${buildVorgangPageLink(page)}&assignedTo=&status=${status}`; + } - waitOfInterceptor(loadPageInterceptor).then((interception: Interception) => { - assert(interception.response.body._embedded.vorgangHeaderList.length === 10); - assert(interception.response.body._embedded.vorgangHeaderList[0].name, ALLE_NAME_PREFIX + 101); - assert(interception.response.body._embedded.vorgangHeaderList[9].name, ALLE_NAME_PREFIX + 110); - }); - }); - }); + function buildVorgangPageLink(page: number): string { + return `vorgangs?page=${page - 1}&limit=100`; + } - function buildVorgangInVerworfenUnassignedPageLink(page: number): string { - return `${buildVorgangPageLink(page)}&assignedTo=&status=VERWORFEN`; - } - }); - }); + function getVorgangList(interception: Interception): VorgangE2E[] { + return interception.response.body._embedded.vorgangHeaderList; + } function createVorgaengeWithStatus(status: VorgangStatusE2E): VorgangE2E[] { let count = 1; return generateIds(110).map((randomId) => { const vorgang: VorgangE2E = { - ...buildVorgang(randomId, 'Vorgang' + status + '_' + count), + ...buildVorgang(randomId, VORGANG_NAME_PREFIX + status + '_' + count), status, }; count++; @@ -992,7 +349,7 @@ describe('VorgangList View Pages', () => { let count = 1; return generateIds(110).map((randomId) => { const vorgang: VorgangE2E = { - ...buildVorgang(randomId, 'Vorgang' + status + 'Assigned_' + count), + ...buildVorgang(randomId, VORGANG_NAME_PREFIX + status + 'Assigned_' + count), status, assignedTo, }; @@ -1000,8 +357,4 @@ describe('VorgangList View Pages', () => { return vorgang; }); } - - function buildVorgangPageLink(page: number): string { - return `vorgangs?page=${page - 1}&limit=100`; - } }); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts index c1ffd8afacb43b5f408688fc2da1c2a0bbe849c3..db83669a5bb144828aa67a60d4f89a8271fc8972 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-view-wiedervorlagen.pages.cy.ts @@ -31,7 +31,13 @@ import { VorgangViewsE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/v import { HttpMethodE2E } from 'apps/alfa-e2e/src/model/util'; import { ClientAttributeNameE2E, VorgangE2E } from 'apps/alfa-e2e/src/model/vorgang'; import { MainPage, waitForSpinnerToDisappear } from 'apps/alfa-e2e/src/page-objects/main.po'; -import { dropCollections, intercept, scrollToWindowBottom, waitOfInterceptor } from 'apps/alfa-e2e/src/support/cypress-helper'; +import { + dropCollections, + intercept, + scrollToWindowBottom, + scrollToWindowTop, + waitOfInterceptor, +} from 'apps/alfa-e2e/src/support/cypress-helper'; import { exist } from 'apps/alfa-e2e/src/support/cypress.util'; import { createDateToday, generateIds } from 'apps/alfa-e2e/src/support/tech.util'; import { getUserSabineId, initUsermanagerUsers, loginAsSabine } from 'apps/alfa-e2e/src/support/user-util'; @@ -161,6 +167,10 @@ describe('VorgangList View Wiedervorlagen', () => { intercept(HttpMethodE2E.GET, buildVorgangWithOpenWiedervorlagenPageLink(3)).as(loadPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 3 page with 10 vorgaenge with open wiedervorlagen ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); @@ -203,6 +213,10 @@ describe('VorgangList View Wiedervorlagen', () => { intercept(HttpMethodE2E.GET, buildVorgangWithOpenWiedervorlagenAssignedPageLink(2)).as(loadPageInterceptor); }); + after(() => { + scrollToWindowTop(); + }); + it('should show 2 page with 10 vorgaenge with open wiedervorlagen and 90 vorgaenge with open wiedervorlagen ASSIGNED on scrolling to bottom', () => { scrollToWindowBottom(); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-views-filter.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-views-filter.cy.ts index 2547f4523c44b68ebd98dacc223c38f8db94abf0..d2b2f5c137420c986239141c7b60c4dff57868f0 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-views-filter.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-views-filter.cy.ts @@ -66,12 +66,29 @@ describe('Vorgang views and filter', () => { const inBearbeitungView: VorgangViewE2EComponent = views.getInBearbeitung(); const beschiedenView: VorgangViewE2EComponent = views.getBeschieden(); const abgeschlossenView: VorgangViewE2EComponent = views.getAbgeschlossen(); + const weitergeleitetView: VorgangViewE2EComponent = views.getWeitergeleitet(); const verworfenView: VorgangViewE2EComponent = views.getVerworfen(); const zuLoeschenView: VorgangViewE2EComponent = views.getZuLoeschen(); + const ungelesenView: VorgangViewE2EComponent = views.getUngelesen(); const wiedervorlagenView: VorgangViewE2EComponent = views.getWiedervorlagen(); const vorgangListView: VorgangViewE2EComponent = views.getVorgangList(); const sucheView: VorgangViewE2EComponent = views.getSuche(); + const ALL_VIEW_COMPONENTS: VorgangViewE2EComponent[] = [ + neuView, + angenommenView, + inBearbeitungView, + beschiedenView, + abgeschlossenView, + weitergeleitetView, + verworfenView, + zuLoeschenView, + ungelesenView, + wiedervorlagenView, + vorgangListView, + sucheView, + ]; + const navigation: NavigationE2EComponent = mainPage.getNavigation(); const vorgangNeuAssigned: VorgangE2E = { @@ -134,6 +151,16 @@ describe('Vorgang views and filter', () => { status: VorgangStatusE2E.ABGESCHLOSSEN, }; + const vorgangWeitergeleitetAssigned: VorgangE2E = { + ...buildVorgang(objectIds[13], 'VorgangWeitergeleitetAssigned'), + status: VorgangStatusE2E.WEITERGELEITET, + assignedTo: getUserSabineId(), + }; + const vorgangWeitergeleitetUnassigned: VorgangE2E = { + ...buildVorgang(objectIds[14], 'VorgangWeitergeleitetUnassigned'), + status: VorgangStatusE2E.WEITERGELEITET, + }; + const vorgangVerworfenAssigned: VorgangE2E = { ...buildVorgang(objectIds[9], 'VorgangVerworfenAssigned'), status: VorgangStatusE2E.VERWORFEN, @@ -181,6 +208,13 @@ describe('Vorgang views and filter', () => { vorgangAbgeschlossenUnassigned.name, ); + const vorgangWeitergeleitetAssignedInList: VorgangListItemE2EComponent = vorgangList.getListItem( + vorgangWeitergeleitetAssigned.name, + ); + const vorgangWeitergeleitetUnassignedInList: VorgangListItemE2EComponent = vorgangList.getListItem( + vorgangWeitergeleitetUnassigned.name, + ); + const vorgangVerworfenAssignedInList: VorgangListItemE2EComponent = vorgangList.getListItem(vorgangVerworfenAssigned.name); const vorgangVerworfenUnassignedInList: VorgangListItemE2EComponent = vorgangList.getListItem(vorgangVerworfenUnassigned.name); @@ -189,7 +223,7 @@ describe('Vorgang views and filter', () => { vorgangZuLoeschenUnassigned.name, ); - const LIST_SIZE: number = 14; + const LIST_SIZE: number = 16; before(() => { const vorgaenge: VorgangE2E[] = [ @@ -203,6 +237,8 @@ describe('Vorgang views and filter', () => { vorgangBeschiedenUnassigned, vorgangAbgeschlossenAssigned, vorgangAbgeschlossenUnassigned, + vorgangWeitergeleitetAssigned, + vorgangWeitergeleitetUnassigned, vorgangVerworfenAssigned, vorgangVerworfenUnassigned, vorgangZuLoeschenAssigned, @@ -214,8 +250,6 @@ describe('Vorgang views and filter', () => { initUsermanagerUsers(); loginAsSabine(); - - waitForSpinnerToDisappear(); }); after(() => { @@ -257,6 +291,7 @@ describe('Vorgang views and filter', () => { isNotSelected(inBearbeitungView.getRoot()); isNotSelected(beschiedenView.getRoot()); isNotSelected(abgeschlossenView.getRoot()); + isNotSelected(weitergeleitetView.getRoot()); isNotSelected(verworfenView.getRoot()); isNotSelected(zuLoeschenView.getRoot()); isNotSelected(sucheView.getRoot()); @@ -283,6 +318,10 @@ describe('Vorgang views and filter', () => { contains(abgeschlossenView.getCount(), '2'); }); + it('weitergeleitet', () => { + contains(abgeschlossenView.getCount(), '2'); + }); + it('verworfen', () => { contains(verworfenView.getCount(), '2'); }); @@ -300,262 +339,82 @@ describe('Vorgang views and filter', () => { describe('Select view', () => { describe('Neu', () => { - it('should set selected after click', () => { - neuView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(neuView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); - - it('should filter List', () => { - haveLength(vorgangList.getItems(), 2); - exist(vorgangNeuAssignedInList.getRoot()); - exist(vorgangNeuUnassignedInList.getRoot()); - }); + testAlleFilterViewSelection(neuView, [vorgangNeuAssignedInList, vorgangNeuUnassignedInList]); }); describe('Angenommen', () => { - it('should set selected after click', () => { - angenommenView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(angenommenView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); - - it('should filter List', () => { - haveLength(vorgangList.getItems(), 2); - exist(vorgangAngenommenAssignedInList.getRoot()); - exist(vorgangAngenommenUnassignedInList.getRoot()); - }); + testAlleFilterViewSelection(angenommenView, [vorgangAngenommenAssignedInList, vorgangAngenommenUnassignedInList]); }); describe('In Bearbeitung', () => { - it('should set selected after click', () => { - inBearbeitungView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(inBearbeitungView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); - - it('should filter List', () => { - haveLength(vorgangList.getItems(), LIST_SIZE - 12); - exist(vorgangInBearbeitungAssignedInList.getRoot()); - exist(vorgangInBearbeitungUnassignedInList.getRoot()); - }); + testAlleFilterViewSelection(inBearbeitungView, [vorgangInBearbeitungAssignedInList, vorgangInBearbeitungUnassignedInList]); }); describe('Beschieden', () => { - it('should set selected after click', () => { - beschiedenView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(beschiedenView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); - - it('should filter List', () => { - haveLength(vorgangList.getItems(), LIST_SIZE - 12); - exist(vorgangBeschiedenAssignedInList.getRoot()); - exist(vorgangBeschiedenUnassignedInList.getRoot()); - }); + testAlleFilterViewSelection(beschiedenView, [vorgangBeschiedenAssignedInList, vorgangBeschiedenUnassignedInList]); }); describe('Abgeschlossen', () => { - it('should set selected after click', () => { - abgeschlossenView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(abgeschlossenView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); + testAlleFilterViewSelection(abgeschlossenView, [vorgangAbgeschlossenAssignedInList, vorgangAbgeschlossenUnassignedInList]); + }); - it('should filter List', () => { - haveLength(vorgangList.getItems(), LIST_SIZE - 12); - exist(vorgangAbgeschlossenAssignedInList.getRoot()); - exist(vorgangAbgeschlossenUnassignedInList.getRoot()); - }); + describe('Weitergeleitet', () => { + testAlleFilterViewSelection(weitergeleitetView, [ + vorgangWeitergeleitetAssignedInList, + vorgangWeitergeleitetUnassignedInList, + ]); }); describe('Verworfen', () => { - it('should set selected after click', () => { - verworfenView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(verworfenView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); - - it('should filter List', () => { - haveLength(vorgangList.getItems(), LIST_SIZE - 12); - exist(vorgangVerworfenAssignedInList.getRoot()); - exist(vorgangVerworfenUnassignedInList.getRoot()); - }); + testAlleFilterViewSelection(verworfenView, [vorgangVerworfenAssignedInList, vorgangVerworfenUnassignedInList]); }); describe('Zu Löschen', () => { - it('should set selected after click', () => { - zuLoeschenView.getRoot().click(); - waitForSpinnerToDisappear(); - - isSelected(zuLoeschenView.getRoot()); - }); - - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); - - it('should filter List', () => { - haveLength(vorgangList.getItems(), LIST_SIZE - 12); - exist(vorgangZuLoeschenAssignedInList.getRoot()); - exist(vorgangZuLoeschenUnassignedInList.getRoot()); - }); + testAlleFilterViewSelection(zuLoeschenView, [vorgangZuLoeschenAssignedInList, vorgangZuLoeschenUnassignedInList]); }); describe('Wiedervorlagen', () => { + testAlleFilterViewSelection(wiedervorlagenView, [vorgangAngenommenUnassignedInList, vorgangAbgeschlossenAssignedInList]); + }); + + function testAlleFilterViewSelection(view: VorgangViewE2EComponent, listItems: VorgangListItemE2EComponent[]): void { + testViewSelection(view); + testOtherViewsAreUnselected(view); + testAlleFilterIsSelected(); + testVorgangListItem(listItems); + } + + function testViewSelection(view: VorgangViewE2EComponent): void { it('should set selected after click', () => { - wiedervorlagenView.getRoot().click(); + view.getRoot().click(); waitForSpinnerToDisappear(); - isSelected(wiedervorlagenView.getRoot()); + isSelected(view.getRoot()); }); + } + function testOtherViewsAreUnselected(selectedView: VorgangViewE2EComponent): void { it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - isNotSelected(sucheView.getRoot()); + ALL_VIEW_COMPONENTS.filter((view: VorgangViewE2EComponent) => view != selectedView).forEach( + (view: VorgangViewE2EComponent) => isNotSelected(view.getRoot()), + ); }); + } + function testAlleFilterIsSelected(): void { it('should keep filter selection', () => { isOdsButtonToggleChecked(navigation.getAlleFilter()); isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); }); + } + function testVorgangListItem(listItems: VorgangListItemE2EComponent[]): void { it('should filter List', () => { - haveLength(vorgangList.getItems(), 2); - - exist(vorgangAngenommenUnassignedInList.getRoot()); - exist(vorgangAbgeschlossenAssignedInList.getRoot()); + haveLength(vorgangList.getItems(), LIST_SIZE - 14); + listItems.forEach((item: VorgangListItemE2EComponent) => exist(item.getRoot())); }); - }); + } describe('VorgangList', () => { it('should set selected after click', () => { @@ -571,6 +430,7 @@ describe('Vorgang views and filter', () => { isNotSelected(inBearbeitungView.getRoot()); isNotSelected(beschiedenView.getRoot()); isNotSelected(abgeschlossenView.getRoot()); + isNotSelected(weitergeleitetView.getRoot()); isNotSelected(zuLoeschenView.getRoot()); isNotSelected(verworfenView.getRoot()); isNotSelected(sucheView.getRoot()); @@ -595,22 +455,8 @@ describe('Vorgang views and filter', () => { isSelected(sucheView.getRoot()); }); - it('should unselect other views', () => { - isNotSelected(neuView.getRoot()); - isNotSelected(angenommenView.getRoot()); - isNotSelected(inBearbeitungView.getRoot()); - isNotSelected(beschiedenView.getRoot()); - isNotSelected(abgeschlossenView.getRoot()); - isNotSelected(zuLoeschenView.getRoot()); - isNotSelected(verworfenView.getRoot()); - isNotSelected(vorgangListView.getRoot()); - }); - - it('should keep filter selection', () => { - isOdsButtonToggleChecked(navigation.getAlleFilter()); - isOdsButtonToggleNotChecked(navigation.getMeineVorgaengeFilter()); - isOdsButtonToggleNotChecked(navigation.getUnassignedFilter()); - }); + testOtherViewsAreUnselected(sucheView); + testAlleFilterIsSelected(); it('should show message', () => { haveText(vorgangList.getEmptySucheMessage(), 'Bitte geben Sie einen Suchbegriff ein.'); @@ -643,6 +489,7 @@ describe('Vorgang views and filter', () => { isNotSelected(inBearbeitungView.getRoot()); isNotSelected(beschiedenView.getRoot()); isNotSelected(abgeschlossenView.getRoot()); + isNotSelected(weitergeleitetView.getRoot()); isNotSelected(verworfenView.getRoot()); isNotSelected(zuLoeschenView.getRoot()); isNotSelected(vorgangListView.getRoot()); @@ -892,11 +739,11 @@ describe('Vorgang views and filter', () => { vorgangSearch.doSearch(searchString); } - function isNotSelected(element) { + function isNotSelected(element: Cypress.Chainable<Element>): void { notContainClass(element, 'selected'); } - function isSelected(element) { + function isSelected(element: Cypress.Chainable<Element>): void { containClass(element, 'selected'); } }); 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 index 1ed205ce1acecae3028a6682411de030b49c17cb..ff177ddcffc8fae0d04a2294b6c3176c07062abd 100644 --- 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 @@ -36,10 +36,7 @@ import { VorgangAttachedItemE2E } from 'apps/alfa-e2e/src/model/vorgang-attached 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 { 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'; @@ -53,7 +50,7 @@ import { getDownloadFiles, unzipDownloadFile, } from '../../../support/cypress-helper'; -import { exist, notExist } from '../../../support/cypress.util'; +import { exist } 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'; @@ -81,11 +78,7 @@ describe('check xDomea contents', () => { }; const assignUserCommand: CommandE2E = { - ...buildCommand( - CommandOrderE2E.ASSIGN_USER, - vorgangExportieren._id.$oid, - vorgangExportieren._id.$oid, - ), + ...buildCommand(CommandOrderE2E.ASSIGN_USER, vorgangExportieren._id.$oid, vorgangExportieren._id.$oid), bodyObject: { assignedTo: getUserDorotheaId() }, finishedAt: { $date: '2024-06-20T07:25:30.000Z' }, }; @@ -102,11 +95,7 @@ describe('check xDomea contents', () => { }; const setAktenzeichenCommand: CommandE2E = { - ...buildCommand( - CommandOrderE2E.SET_AKTENZEICHEN, - vorgangExportieren._id.$oid, - vorgangExportieren._id.$oid, - ), + ...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' }, @@ -121,8 +110,7 @@ describe('check xDomea contents', () => { item: kommentar, }; - const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = - vorgangPage.getFormularButtons(); + const vorgangFormularButtons: VorgangFormularButtonsE2EComponent = vorgangPage.getFormularButtons(); const bescheidWizard: VorgangBescheidWizardE2EComponent = vorgangPage.getBescheidWizard(); @@ -148,7 +136,7 @@ describe('check xDomea contents', () => { vorgangFormularButtons.getBescheidenButton().click(); bescheidWizard.weiter(); uploadFile(bescheidWizard.getUploadBescheidButton(), TEST_FILE_BESCHEID_VALID); - notExist(bescheidWizard.getBescheidUploadSpinner()); + waitForSpinnerToDisappear(); bescheidWizard.weiter(); bescheidWizard.getSendButton().click(); waitForSpinnerToDisappear(); @@ -237,12 +225,7 @@ describe('check xDomea contents', () => { return getXMLFromTagAtPosition(xdomeaNamespace, content, tagName, position); } - function getXMLFromTagAtPosition( - namespaceURI: string, - content: string, - tagName: string, - position: number, - ) { + function getXMLFromTagAtPosition(namespaceURI: string, content: string, tagName: string, position: number) { const xmlDoc = parseXml(content); return xmlDoc.getElementsByTagNameNS(namespaceURI, tagName)[position].textContent; } @@ -273,9 +256,7 @@ describe('check xDomea contents', () => { function compareXmlEntry(xDomeaFile: string, xmlMap: Map<XmlTypePosition, string>) { xmlMap.forEach((expectedValue, xmlTypePosition) => { - expect( - getXdomeaNamespace(xDomeaFile, xmlTypePosition.type, xmlTypePosition.position), - ).to.equal(expectedValue); + expect(getXdomeaNamespace(xDomeaFile, xmlTypePosition.type, xmlTypePosition.position)).to.equal(expectedValue); }); } diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.cy.ts index a32737f51ba4be5eb46a092f211db36236f239cf..fa176831377d0b9775f4991bdaa1ccd2454df68a 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.cy.ts @@ -21,10 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { AttachmentContainerE2EComponent, AttachmentListE2EComponent, } from 'apps/alfa-e2e/src/components/attachment/attachment.e2e.component'; +import { + AttachmentContainerE2EComponent, + AttachmentListE2EComponent, +} from 'apps/alfa-e2e/src/components/attachment/attachment.e2e.component'; import { WiedervorlageSubnavigationE2EComponent } from 'apps/alfa-e2e/src/components/wiedervorlage/wiedervorlage-subnavigation'; +import { E2EAttachmentHelper } from 'apps/alfa-e2e/src/helper/attachment/attachment.helper'; +import { E2EWiedervorlageHelper } from 'apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.helper'; import { WiedervorlageE2E } from 'apps/alfa-e2e/src/model/wiedervorlage'; -import { dropCollections, readFileFromDownloads, wait } from 'apps/alfa-e2e/src/support/cypress-helper'; +import { dropCollections, readFileFromDownloads } from 'apps/alfa-e2e/src/support/cypress-helper'; import { initVorgangAttachedItem } from 'apps/alfa-e2e/src/support/vorgang-attached-item-util'; import { SnackBarE2EComponent } from '../../../components/ui/snackbar.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; @@ -37,7 +42,6 @@ import { VorgangPage } from '../../../page-objects/vorgang.po'; import { WiedervorlagePage } from '../../../page-objects/wiedervorlage.po'; import { containClass, contains, exist, haveLength, notContainClass, notExist } from '../../../support/cypress.util'; import { TEST_FILE_WITH_CONTENT, TEST_FILE_WITH_CONTENT_46MB, TEST_FILE_WITHOUT_CONTENT } from '../../../support/data.util'; -import { uploadEmptyFile, uploadFile } from '../../../support/file-upload'; import { loginAsSabine } from '../../../support/user-util'; import { createVorgang, initVorgang, objectIds } from '../../../support/vorgang-util'; import { createWiedervorlageAttachedItem, createWiedervorlageItem } from '../../../support/wiedervorlage-util'; @@ -60,6 +64,9 @@ describe('Wiedervorlage attachments', () => { const snackbar: SnackBarE2EComponent = mainPage.getSnackBar(); + const wiedervorlageHelper: E2EWiedervorlageHelper = new E2EWiedervorlageHelper(); + const attachmentHelper: E2EAttachmentHelper = new E2EAttachmentHelper(); + const WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF: string = 'WiedervorlageWithAttachments'; const vorgang: VorgangE2E = createVorgang(); @@ -89,36 +96,31 @@ describe('Wiedervorlage attachments', () => { }); it('should show wiedervorlage page on click on create wiedervorlage button', () => { - wiedervorlageContainerInVorgang.getCreateWiedervorlageButton().click(); - waitForSpinnerToDisappear(); + wiedervorlageHelper.openNewWiedervorlage(); exist(wiedervorlagePage.getRoot()); }); it('should show empty attachment after upload', () => { - uploadEmptyFile(attachmentContainer.getUploadInput(), TEST_FILE_WITHOUT_CONTENT); - waitForSpinnerToDisappear(); + attachmentHelper.uploadEmptyAttachment(); exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); }); it('should download empty attachment on click', () => { - attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.downloadAttachment(TEST_FILE_WITHOUT_CONTENT); exist(readFileFromDownloads(TEST_FILE_WITHOUT_CONTENT)); }); it('should show attachment with content after download', () => { - uploadFile(attachmentContainer.getUploadInput(), TEST_FILE_WITH_CONTENT); - waitForSpinnerToDisappear(); + attachmentHelper.uploadAttachment(TEST_FILE_WITH_CONTENT); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); }); - it('should show failed upload', { defaultCommandTimeout: 30000 }, () => { - uploadFile(attachmentContainer.getUploadInput(), TEST_FILE_WITH_CONTENT_46MB); - waitForSpinnerToDisappear(); + it('should show failed upload on bigger size than allowed', { defaultCommandTimeout: 300000 }, () => { + attachmentHelper.uploadAttachment(TEST_FILE_WITH_CONTENT_46MB); exist(attachmentList.getLoadingOrErrorItem(TEST_FILE_WITH_CONTENT_46MB).getRoot()); contains( @@ -128,8 +130,7 @@ describe('Wiedervorlage attachments', () => { }); it('should download attachment on click', () => { - attachmentList.getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.downloadAttachment(TEST_FILE_WITH_CONTENT); exist(readFileFromDownloads(TEST_FILE_WITH_CONTENT)); }); @@ -205,22 +206,63 @@ describe('Wiedervorlage attachments', () => { }); }); - describe('Delete attachment', () => { + describe('Upload multiple attachments', () => { const wiedervorlageComp: WiedervorlageInVorgangE2EComponent = wiedervorlageContainerInVorgang.getWiedervorlage( WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF, ); it('should open wiedervorlage page', () => { - wiedervorlageComp.getLink().click(); + wiedervorlageHelper.openWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF); + + exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); + exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); + }); + + it('should delete all', () => { + attachmentHelper.deleteAttachment(TEST_FILE_WITH_CONTENT); + attachmentHelper.deleteAttachment(TEST_FILE_WITHOUT_CONTENT); + + notExist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); + notExist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); + }); + + it('should do upload', () => { + attachmentHelper.uploadAttachments([TEST_FILE_WITHOUT_CONTENT, TEST_FILE_WITH_CONTENT]); + + exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); + exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); + + wiedervorlageContainer.getSpeichernButton().click(); + exist(snackbar.getMessage()); + contains(snackbar.getMessage(), `Die Wiedervorlage "${WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF}" wurde gespeichert`); + snackbar.getCloseButton().click(); + }); + + it('check attachments in wiedervorlage list', () => { waitForSpinnerToDisappear(); + wiedervorlageComp.getExpandButton(); + wiedervorlageComp.expandItem(); + + exist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); + exist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getRoot()); + }); + }); + + describe('Delete attachment', () => { + const wiedervorlageComp: WiedervorlageInVorgangE2EComponent = wiedervorlageContainerInVorgang.getWiedervorlage( + WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF, + ); + + it('should open wiedervorlage page', () => { + wiedervorlageHelper.openWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF); + exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); }); it('delete', () => { - attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDeleteButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.deleteAttachment(TEST_FILE_WITHOUT_CONTENT); notExist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); @@ -239,6 +281,7 @@ describe('Wiedervorlage attachments', () => { wiedervorlageComp.getExpandButton(); wiedervorlageComp.expandItem(); + waitForSpinnerToDisappear(); notExist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); exist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getRoot()); @@ -251,28 +294,22 @@ describe('Wiedervorlage attachments', () => { ); it('should not show any attachments', () => { - wiedervorlageComp.getLink().click(); - waitForSpinnerToDisappear(); + wiedervorlageHelper.openWiedervorlage(wiedervorlage.betreff); notExist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); notExist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getRoot()); wiedervorlagePage.getSubnavigation().navigateBack(); + waitForSpinnerToDisappear(); }); }); describe('Same number of attachments after status change', () => { - const wiedervorlageComp: WiedervorlageInVorgangE2EComponent = wiedervorlageContainerInVorgang.getWiedervorlage( - WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF, - ); - it('should open wiedervorlage page', () => { - wait(500); - wiedervorlageComp.getLink().click(); - - waitForSpinnerToDisappear(); + wiedervorlageHelper.openWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); + notExist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); }); it('should mark as erledigt', () => { @@ -317,8 +354,7 @@ describe('Wiedervorlage attachments', () => { describe('delete last attachment', () => { it('should remove on delete', () => { - attachmentList.getItem(TEST_FILE_WITH_CONTENT).getDeleteButton().click(); - waitForSpinnerToDisappear(); + attachmentHelper.deleteAttachment(TEST_FILE_WITH_CONTENT); notExist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); }); @@ -337,7 +373,7 @@ describe('Wiedervorlage attachments', () => { notExist(snackBar.getMessage()); }); - it('(Skip reason in OZG-4658) should have no attachments after save', () => { + it('should have no attachments after save', () => { const wiedervorlageComp: WiedervorlageInVorgangE2EComponent = wiedervorlageContainerInVorgang.getWiedervorlage( WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF, ); diff --git a/alfa-client/apps/alfa-e2e/src/helper/app.helper.ts b/alfa-client/apps/alfa-e2e/src/helper/app.helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..e264eb98df16537f69c250fa09252c35346c43b8 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/app.helper.ts @@ -0,0 +1,23 @@ +import { VorgangListE2EComponent } from '../components/vorgang/vorgang-list.e2e.component'; +import { MainPage, waitForSpinnerToDisappear } from '../page-objects/main.po'; +import { exist } from '../support/cypress.util'; +import { loginAsSabine } from '../support/user-util'; + +export class E2EAppHelper { + private readonly mainPage: MainPage = new MainPage(); + private readonly vorgangList: VorgangListE2EComponent = new VorgangListE2EComponent(); + + public loginAsSabine(): void { + loginAsSabine(); + this.waitAfterLogin(); + } + + private waitAfterLogin(): void { + waitForSpinnerToDisappear(); + exist(this.vorgangList.getRoot()); + } + + public navigateToDomain(): void { + this.mainPage.getHeader().getLogo().click(); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.executor.ts b/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.executor.ts new file mode 100644 index 0000000000000000000000000000000000000000..25b0dce789373955a60b97632848ac2c8c218dde --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.executor.ts @@ -0,0 +1,44 @@ +import { AttachmentContainerE2EComponent, AttachmentE2EItem } from '../../components/attachment/attachment.e2e.component'; +import { waitForSpinnerToDisappear } from '../../page-objects/main.po'; +import { exist, notExist } from '../../support/cypress.util'; +import { uploadEmptyFile, uploadFiles } from '../../support/file-upload'; + +export class E2EAttachmentExecutor { + private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); + + public uploadAttachment(fileNames: string[]): void { + uploadFiles(this.getUploadInput(), fileNames); + waitForSpinnerToDisappear(); + } + + public uploadEmptyAttachment(fileName: string): void { + uploadEmptyFile(this.getUploadInput(), fileName); + waitForSpinnerToDisappear(); + } + + private getUploadInput(): Cypress.Chainable<HTMLElement> { + return this.attachmentContainer.getUploadInput(); + } + + public deleteAttachments(fileNames: string[]): void { + fileNames.forEach((fileName: string) => this.deleteAttachment(fileName)); + } + + private deleteAttachment(fileName: string): void { + const attachment: AttachmentE2EItem = this.getAttachment(fileName); + exist(attachment.getRoot()); + attachment.getDeleteButton().click(); + notExist(attachment.getRoot()); + } + + public downloadAttachment(fileName: string): void { + const attachment: AttachmentE2EItem = this.getAttachment(fileName); + exist(attachment.getRoot()); + attachment.getDownloadButton().click(); + waitForSpinnerToDisappear(); + } + + private getAttachment(fileName: string): AttachmentE2EItem { + return this.attachmentContainer.getList().getItem(fileName); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.helper.ts b/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..dd9743081a8eae3596b692daf53ff5b2479ce74b --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.helper.ts @@ -0,0 +1,30 @@ +import { TEST_FILE_WITH_CONTENT, TEST_FILE_WITHOUT_CONTENT } from '../../support/data.util'; +import { E2EAttachmentExecutor } from './attachment.executor'; + +export class E2EAttachmentHelper { + private readonly executor: E2EAttachmentExecutor = new E2EAttachmentExecutor(); + + public deleteAttachment(fileName: string): void { + this.deleteAttachments([fileName]); + } + + public deleteAttachments(fileNames: string[]): void { + this.executor.deleteAttachments(fileNames); + } + + public uploadAttachment(fileName: string = TEST_FILE_WITH_CONTENT): void { + this.uploadAttachments([fileName]); + } + + public uploadAttachments(fileNames: string[]): void { + this.executor.uploadAttachment(fileNames); + } + + public uploadEmptyAttachment(fileName: string = TEST_FILE_WITHOUT_CONTENT): void { + this.executor.uploadEmptyAttachment(fileName); + } + + public downloadAttachment(fileName: string): void { + this.executor.downloadAttachment(fileName); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.verifier.ts b/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.verifier.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c68292a0e10bdfac3e20d83377120a258d08b25 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/attachment/attachment.verifier.ts @@ -0,0 +1,23 @@ +import { AttachmentContainerE2EComponent } from '../../components/attachment/attachment.e2e.component'; +import { readFileFromDownloads } from '../../support/cypress-helper'; +import { exist, notExist } from '../../support/cypress.util'; + +export class E2EAttachmentVerifier { + private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); + + public verifyAttachmentsInList(filesNames: string[]): void { + filesNames.forEach((filesName: string) => this.verifyAttachmentInList(filesName)); + } + + public verifyAttachmentInList(filesName: string): void { + exist(this.attachmentContainer.getList().getItem(filesName).getRoot()); + } + + public verifyAttachmentNotInList(filesName: string): void { + notExist(this.attachmentContainer.getList().getItem(filesName).getRoot()); + } + + public verifyAttachmentDownload(fileName: string): void { + exist(readFileFromDownloads(fileName)); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.executor.ts b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.executor.ts new file mode 100644 index 0000000000000000000000000000000000000000..22295bb180d00c9d23b787fde72a001bea29cab2 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.executor.ts @@ -0,0 +1,16 @@ +import { ForwardingDialogE2EComponent } from '../../components/vorgang/vorgang-forwarding-dialog.e2e.component'; +import { waitForSpinnerToDisappear } from '../../page-objects/main.po'; +import { exist } from '../../support/cypress.util'; + +export class E2EForwardingExecutor { + private readonly forwardingDialog = new ForwardingDialogE2EComponent(); + + public fillForwardingDialog(organisationsEinheit: string): void { + this.forwardingDialog.getSearchText().type(organisationsEinheit); + waitForSpinnerToDisappear(); + this.forwardingDialog.clickSearchEntry(0); + exist(this.forwardingDialog.getForwardingItem()); + this.forwardingDialog.getForwardingButton().click(); + waitForSpinnerToDisappear(); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.helper.ts b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..408faf920fba169b3a69908575d7d422e2cf743d --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.helper.ts @@ -0,0 +1,15 @@ +import { E2EForwardingExecutor } from './forwarding.executor'; +import { E2EForwardingNavigator } from './forwarding.navigator'; + +export class E2EForwardingHelper { + private readonly executor: E2EForwardingExecutor = new E2EForwardingExecutor(); + private readonly navigator: E2EForwardingNavigator = new E2EForwardingNavigator(); + + public openForwarding(vorgangName: string): void { + this.navigator.openForwardDialog(vorgangName); + } + + public forwardTo(organisationsEinheit: string): void { + this.executor.fillForwardingDialog(organisationsEinheit); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts new file mode 100644 index 0000000000000000000000000000000000000000..3400d79516d98512531d28f43b8575f583a5d0f4 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts @@ -0,0 +1,17 @@ +import { VorgangFormularButtonsE2EComponent } from '../../components/vorgang/vorgang-formular-buttons.e2e.components'; +import { ForwardingDialogE2EComponent } from '../../components/vorgang/vorgang-forwarding-dialog.e2e.component'; +import { exist } from '../../support/cypress.util'; +import { E2EVorgangNavigator } from '../vorgang/vorgang.navigator'; + +export class E2EForwardingNavigator { + private readonly vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator(); + + private readonly formularButtons: VorgangFormularButtonsE2EComponent = new VorgangFormularButtonsE2EComponent(); + private readonly forwardingDialog: ForwardingDialogE2EComponent = new ForwardingDialogE2EComponent(); + + public openForwardDialog(vorgangName: string): void { + this.vorgangNavigator.openVorgangDetailByName(vorgangName); + this.formularButtons.getForwardButton().click(); + exist(this.forwardingDialog.getRoot()); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/kommentar/kommentar.executor.ts b/alfa-client/apps/alfa-e2e/src/helper/kommentar/kommentar.executor.ts new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.helper.ts b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..14855ec9447435b69b037074d1e17fb695c54ab4 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.helper.ts @@ -0,0 +1,7 @@ +import { E2EVorgangNavigator } from './vorgang.navigator'; +import { E2EVorgangVerifier } from './vorgang.verifier'; + +export class E2EVorgangHelper { + private readonly verifier: E2EVorgangVerifier = new E2EVorgangVerifier(); + private readonly navigator: E2EVorgangNavigator = new E2EVorgangNavigator(); +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts new file mode 100644 index 0000000000000000000000000000000000000000..3225f82b8ac3c2dd7158bbc00e1499f30c0f4c14 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts @@ -0,0 +1,26 @@ +import { VorgangListE2EComponent } from '../../components/vorgang/vorgang-list.e2e.component'; +import { waitForSpinnerToDisappear } from '../../page-objects/main.po'; +import { exist } from '../../support/cypress.util'; +import { E2EAppHelper } from '../app.helper'; +import { E2EVorgangVerifier } from './vorgang.verifier'; + +export class E2EVorgangNavigator { + private readonly appHelper: E2EAppHelper = new E2EAppHelper(); + + private readonly verifier: E2EVorgangVerifier = new E2EVorgangVerifier(); + + private readonly vorgangListPage = new VorgangListE2EComponent(); + + public openVorgangDetailByName(vorgangName: string): void { + this.vorgangListPage.getListItem(vorgangName).getRoot().click(); + waitForSpinnerToDisappear(); + this.verifier.verifyVorgangDetailOpen(vorgangName); + } + + public openVorgang(vorgangName: string): void { + this.appHelper.navigateToDomain(); + waitForSpinnerToDisappear(); + exist(this.vorgangListPage.getRoot()); + this.openVorgangDetailByName(vorgangName); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.verifier.ts b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.verifier.ts new file mode 100644 index 0000000000000000000000000000000000000000..d8e8e39394686a7a4414a6d38564e69c5969f6f0 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.verifier.ts @@ -0,0 +1,42 @@ +import { VorgangFormularButtonsE2EComponent } from '../../components/vorgang/vorgang-formular-buttons.e2e.components'; +import { VorgangPage } from '../../page-objects/vorgang.po'; +import { contains, exist, notExist } from '../../support/cypress.util'; + +export class E2EVorgangVerifier { + private readonly vorgangPage: VorgangPage = new VorgangPage(); + private readonly formularButtons: VorgangFormularButtonsE2EComponent = new VorgangFormularButtonsE2EComponent(); + + public verifyVorgangDetailOpen(vorgangName: string): void { + exist(this.vorgangPage.getVorgangDetailHeader().getRoot()); + contains(this.vorgangPage.getVorgangDetailHeader().getName(), vorgangName); + } + + public verifyForwardingButtonExists(): void { + exist(this.vorgangPage.getFormularButtons().getForwardButton()); + } + + public verifyNoForwardingButtonExists(): void { + notExist(this.vorgangPage.getFormularButtons().getForwardButton()); + } + + public verifyVorgangIsLocked(): void { + this.verifyFormularButtonsNotVisible(); + notExist(this.vorgangPage.getWiedervorlagenContainer().getCreateWiedervorlageButton()); + notExist(this.vorgangPage.getKommentarContainer().getHinzufuegenButton()); + notExist(this.vorgangPage.getPostfachMailcontainer().getCreateButtonWithText()); + notExist(this.vorgangPage.getPostfachMailcontainer().getCreateButtonWithoutText()); + } + + private verifyFormularButtonsNotVisible(): void { + notExist(this.formularButtons.getAbschliessenButton()); + notExist(this.formularButtons.getBearbeitenButton()); + notExist(this.formularButtons.getBescheidenButton()); + notExist(this.formularButtons.getEndgueltigLoeschenButton()); + notExist(this.formularButtons.getForwardButton()); + notExist(this.formularButtons.getLoeschAnforderungZuruecknehmenButton()); + notExist(this.formularButtons.getVerwerfenButton()); + notExist(this.formularButtons.getWiedereroeffnenButton()); + notExist(this.formularButtons.getZurueckholenButton()); + notExist(this.formularButtons.getZurueckstellenButton()); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.helper.ts b/alfa-client/apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c6c96e50c79a44ee3d6a771d16e5a74fb3bd1a5 --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.helper.ts @@ -0,0 +1,13 @@ +import { E2EWiedervorlageNavigator } from './wiedervorlage.navigator'; + +export class E2EWiedervorlageHelper { + private navigator: E2EWiedervorlageNavigator = new E2EWiedervorlageNavigator(); + + public openWiedervorlage(betreff: string): void { + this.navigator.openWiedervorlage(betreff); + } + + public openNewWiedervorlage(): void { + this.navigator.openNewWiedervorlage(); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.navigator.ts b/alfa-client/apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.navigator.ts new file mode 100644 index 0000000000000000000000000000000000000000..42fe2c26a02ce0b3518c7bcd0f39aabaf9a25edd --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/helper/wiedervorlage/wiedervorlage.navigator.ts @@ -0,0 +1,26 @@ +import { WiedervorlageInVorgangE2EComponent } from '../../components/wiedervorlage/wiedervorlage-in-vorgang.e2e.component'; +import { WiedervorlagenInVorgangE2EComponent } from '../../components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component'; +import { VorgangPage } from '../../page-objects/vorgang.po'; +import { WiedervorlagePage } from '../../page-objects/wiedervorlage.po'; +import { exist } from '../../support/cypress.util'; + +export class E2EWiedervorlageNavigator { + private vorgangPage: VorgangPage = new VorgangPage(); + private wiedervorlagenInVorgang: WiedervorlagenInVorgangE2EComponent = this.vorgangPage.getWiedervorlagenContainer(); + + private wiedervorlagePage: WiedervorlagePage = new WiedervorlagePage(); + + public openWiedervorlage(betreff: string): void { + const wiedervorlageInVorgang: WiedervorlageInVorgangE2EComponent = this.wiedervorlagenInVorgang.getWiedervorlage(betreff); + exist(wiedervorlageInVorgang.getRoot()); + exist(wiedervorlageInVorgang.getLink()); + wiedervorlageInVorgang.getLink().click(); + exist(this.wiedervorlagePage.getHeadline()); + } + + public openNewWiedervorlage(): void { + exist(this.wiedervorlagenInVorgang.getCreateWiedervorlageButton()); + this.wiedervorlagenInVorgang.getCreateWiedervorlageButton().click(); + exist(this.wiedervorlagePage.getHeadline()); + } +} diff --git a/alfa-client/apps/alfa-e2e/src/model/organisationseinheit.ts b/alfa-client/apps/alfa-e2e/src/model/organisationseinheit.ts new file mode 100644 index 0000000000000000000000000000000000000000..302f3c401870a6951537a8fceeea96760e239abf --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/model/organisationseinheit.ts @@ -0,0 +1,3 @@ +export enum E2EOrganisationsEinheit { + HAMBURG_STADTENTWAESSERUNG = 'Wasserwerk - Hamburg Wasser - Hamburger Stadtentwässerung', +} diff --git a/alfa-client/apps/alfa-e2e/src/page-objects/vorgang.po.ts b/alfa-client/apps/alfa-e2e/src/page-objects/vorgang.po.ts index caa0e2872c6ffb9820602075dd194c072b8b6008..8a2647fd1d0a8b47aaf41cd8e007177991b1fe1f 100644 --- a/alfa-client/apps/alfa-e2e/src/page-objects/vorgang.po.ts +++ b/alfa-client/apps/alfa-e2e/src/page-objects/vorgang.po.ts @@ -22,7 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { AttachmentContainerE2EComponent } from '../components/attachment/attachment.e2e.component'; -import { KommentareInVorgangE2EComponent } from '../components/kommentar/kommentar-list.e2e.component'; +import { KommentarListInVorgangE2EComponent } from '../components/kommentar/kommentar-list.e2e.component'; import { PostfachMailFormularE2EComponent } from '../components/postfach/postfach-mail-formular.e2e.component'; import { PostfachMailE2EComponent } from '../components/postfach/postfach-mail.e2e.component'; import { FixedDialogE2EComponent } from '../components/ui/fixed-dialog.e2e.component'; @@ -33,54 +33,47 @@ import { VorgangBescheideE2EComponent } from '../components/vorgang/vorgang-besc import { VorgangDetailHeaderE2EComponent } from '../components/vorgang/vorgang-detail-header.e2e.component'; import { VorgangFormularButtonsE2EComponent } from '../components/vorgang/vorgang-formular-buttons.e2e.components'; import { VorgangFormularDatenE2EComponent } from '../components/vorgang/vorgang-formular.e2e.component'; -import { VorgangForwardingE2EComponent } from '../components/vorgang/vorgang-forward.e2e.component'; +import { ForwardingByEmailE2EComponent } from '../components/vorgang/vorgang-forward.e2e.component'; +import { ForwardingDialogE2EComponent } from '../components/vorgang/vorgang-forwarding-dialog.e2e.component'; import { VorgangMoreMenuE2EComponent } from '../components/vorgang/vorgang-more-menu.e2e.components'; import { VorgangSubnavigationE2EComponent } from '../components/vorgang/vorgang-subnavigation'; import { VorgangZusammenarbeitE2EComponent } from '../components/vorgang/vorgang-zusammenarbeit.e2e.component'; import { WiedervorlagenInVorgangE2EComponent } from '../components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component'; export class VorgangPage { - private readonly subnavigation: VorgangSubnavigationE2EComponent = - new VorgangSubnavigationE2EComponent(); - private readonly vorgangDetailHeader: VorgangDetailHeaderE2EComponent = - new VorgangDetailHeaderE2EComponent(); - private readonly formularDatenContainer: VorgangFormularDatenE2EComponent = - new VorgangFormularDatenE2EComponent(); - private readonly formularButtons: VorgangFormularButtonsE2EComponent = - new VorgangFormularButtonsE2EComponent(); + private readonly subnavigation: VorgangSubnavigationE2EComponent = new VorgangSubnavigationE2EComponent(); + private readonly vorgangDetailHeader: VorgangDetailHeaderE2EComponent = new VorgangDetailHeaderE2EComponent(); + private readonly formularDatenContainer: VorgangFormularDatenE2EComponent = new VorgangFormularDatenE2EComponent(); + private readonly formularButtons: VorgangFormularButtonsE2EComponent = new VorgangFormularButtonsE2EComponent(); private readonly moreMenu: VorgangMoreMenuE2EComponent = new VorgangMoreMenuE2EComponent(); - private readonly aktenzeichenEditor: VorgangAktenzeichenEditE2EComponent = - new VorgangAktenzeichenEditE2EComponent(); - private readonly bescheidWizard: VorgangBescheidWizardE2EComponent = - new VorgangBescheidWizardE2EComponent(); + private readonly aktenzeichenEditor: VorgangAktenzeichenEditE2EComponent = new VorgangAktenzeichenEditE2EComponent(); + private readonly bescheidWizard: VorgangBescheidWizardE2EComponent = new VorgangBescheidWizardE2EComponent(); private readonly bescheide: VorgangBescheideE2EComponent = new VorgangBescheideE2EComponent(); - private readonly wiedervorlagen: WiedervorlagenInVorgangE2EComponent = - new WiedervorlagenInVorgangE2EComponent(); - private readonly forwardingContainer: VorgangForwardingE2EComponent = - new VorgangForwardingE2EComponent(); - private readonly attachmentContainer: AttachmentContainerE2EComponent = - new AttachmentContainerE2EComponent(); - private readonly kommentarContainer: KommentareInVorgangE2EComponent = - new KommentareInVorgangE2EComponent(); + private readonly wiedervorlagen: WiedervorlagenInVorgangE2EComponent = new WiedervorlagenInVorgangE2EComponent(); + private readonly forwardingDialogContainer: ForwardingDialogE2EComponent = new ForwardingDialogE2EComponent(); + private readonly forwardingByEmailContainer: ForwardingByEmailE2EComponent = new ForwardingByEmailE2EComponent(); + private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent(); + private readonly kommentarContainer: KommentarListInVorgangE2EComponent = new KommentarListInVorgangE2EComponent(); private readonly postfachMailContainer: PostfachMailE2EComponent = new PostfachMailE2EComponent(); - private readonly antragstellerContainer: AntragstellerE2EComponent = - new AntragstellerE2EComponent(); - private readonly zusammenArbeitContainer: VorgangZusammenarbeitE2EComponent = - new VorgangZusammenarbeitE2EComponent(); + private readonly antragstellerContainer: AntragstellerE2EComponent = new AntragstellerE2EComponent(); + private readonly zusammenArbeitContainer: VorgangZusammenarbeitE2EComponent = new VorgangZusammenarbeitE2EComponent(); private readonly fixedDialog: FixedDialogE2EComponent = new FixedDialogE2EComponent(); - private readonly postfachMailFormular: PostfachMailFormularE2EComponent = - new PostfachMailFormularE2EComponent(); + private readonly postfachMailFormular: PostfachMailFormularE2EComponent = new PostfachMailFormularE2EComponent(); private readonly locatorSpinner: string = 'spinner'; private readonly locatorProgressBar: string = 'progress-bar'; - public getKommentarContainer(): KommentareInVorgangE2EComponent { + public getKommentarContainer(): KommentarListInVorgangE2EComponent { return this.kommentarContainer; } - public getForwardingContainer(): VorgangForwardingE2EComponent { - return this.forwardingContainer; + public getForwardingDialogContainer(): ForwardingDialogE2EComponent { + return this.forwardingDialogContainer; + } + + public getForwardingByEmailContainer(): ForwardingByEmailE2EComponent { + return this.forwardingByEmailContainer; } public getSubnavigation(): VorgangSubnavigationE2EComponent { diff --git a/alfa-client/apps/alfa-e2e/src/page-objects/wiedervorlage.po.ts b/alfa-client/apps/alfa-e2e/src/page-objects/wiedervorlage.po.ts index ce5c00e85ce61eb22109881bf26ab4bf3f121b02..cf253b1d3e54ade65ed5711a9b689e88b2640baf 100644 --- a/alfa-client/apps/alfa-e2e/src/page-objects/wiedervorlage.po.ts +++ b/alfa-client/apps/alfa-e2e/src/page-objects/wiedervorlage.po.ts @@ -25,20 +25,24 @@ import { WiedervorlageE2EComponent } from '../components/wiedervorlage/wiedervor import { WiedervorlageSubnavigationE2EComponent } from '../components/wiedervorlage/wiedervorlage-subnavigation'; export class WiedervorlagePage { - private readonly subnavigation: WiedervorlageSubnavigationE2EComponent = - new WiedervorlageSubnavigationE2EComponent(); - private readonly wiedervorlageContainer: WiedervorlageE2EComponent = - new WiedervorlageE2EComponent(); - private readonly locatorWiedervorlagePage: string = 'wiedervorlage-page'; + private readonly root: string = 'wiedervorlage-page'; - public getRoot() { - return cy.getTestElement(this.locatorWiedervorlagePage); + private readonly subnavigation: WiedervorlageSubnavigationE2EComponent = new WiedervorlageSubnavigationE2EComponent(); + private readonly headline: string = 'wiedervorlage-headline'; + private readonly wiedervorlageContainer: WiedervorlageE2EComponent = new WiedervorlageE2EComponent(); + + public getRoot(): Cypress.Chainable<Element> { + return cy.getTestElement(this.root); } public getSubnavigation(): WiedervorlageSubnavigationE2EComponent { return this.subnavigation; } + public getHeadline(): Cypress.Chainable<Element> { + return cy.getTestElement(this.headline); + } + public getWiedervorlageContainer(): WiedervorlageE2EComponent { return this.wiedervorlageContainer; } 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 9c2bd2f7944d04ee78e668cf89f1cbe9c396689f..9e520f34e3c7641fc9dd0c0b2d6d4ff25ac39ab0 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts @@ -28,6 +28,7 @@ import { SmockerMocks } from '../model/smocker'; import { UsermanagerUserE2E } from '../model/usermanager'; import { VorgangE2E } from '../model/vorgang'; import { VorgangAttachedItemE2E } from '../model/vorgang-attached-item'; +import { waitForSpinnerToDisappear } from '../page-objects/main.po'; enum CypressTasks { DROP_COLLECTIONS = 'dropCollections', @@ -62,6 +63,7 @@ export function login(userJsonPath: string): void { cy.fixture(userJsonPath).then((user) => { cy.login(user.name, user.password); }); + waitForSpinnerToDisappear(); } export function visitUrl(url: string): void { @@ -134,11 +136,12 @@ export function initUsermanagerData(data: UsermanagerUserE2E[]): void { cy.task(CypressTasks.INIT_USERMANAGER_DATA, { collection: MongoCollections.USER, data }); } -export function dropCollections() { +export function dropCollections(): void { cy.task(CypressTasks.DROP_COLLECTIONS, [ MongoCollections.COMMAND, MongoCollections.VORGANG, MongoCollections.VORGANG_ATTACHED_ITEM, + MongoCollections.OZG_CLOUD_FILE, MongoCollections.FS_FILES, MongoCollections.FS_CHUNKS, ]); @@ -169,6 +172,10 @@ export function scrollToWindowBottom(): void { cy.window().scrollTo('bottom'); } +export function scrollToWindowTop(): void { + cy.window().scrollTo('top'); +} + export function intercept(method: string, url: string): Cypress.Chainable<null> { return cy.intercept(method, url); } 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 3dbd6155939b778a411f9b2fd18822286feaf958..f62a66e73e504ddd9952afd438ecdd7cf242866a 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress.util.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress.util.ts @@ -97,6 +97,14 @@ export function notBeChecked(element: any): void { element.should('not.be.checked'); } +export function beDisabled(element: any): void { + element.should('be.disabled'); +} + +export function notBeDisabled(element: any): void { + element.should('not.be.disabled'); +} + //TODO: "first()" rausnehmen -> im html eine entprechende data-test-id ansprechen?! | trennen in "get" und "verify" export function shouldFirstContains(element: any, containing: string) { element.first().should('exist').contains(containing); diff --git a/alfa-client/apps/alfa-e2e/src/support/data.util.ts b/alfa-client/apps/alfa-e2e/src/support/data.util.ts index 47f84cd7927ba964684b1de514a846d866d188af..46c335ab573be9cd33c24970ebd37cce56f1da15 100644 --- a/alfa-client/apps/alfa-e2e/src/support/data.util.ts +++ b/alfa-client/apps/alfa-e2e/src/support/data.util.ts @@ -36,10 +36,13 @@ export const ORGANISATIONSEINHEITEN_ID_FOR_ADELHEIT = '10363455'; export const ORGANISATIONSEINHEITEN_ID_FOR_SABINE = '9030229'; export const ORGANISATIONSEINHEITEN_ID_FOR_BEATE = '12345678'; +//TODO Rename = nicht fachlich bezogen bspw. TEST_FILE_WITH_CONTENT_5_MB anstelle von "invalid" oder "big" export const TEST_FILE_BESCHEID_VALID: string = 'Bescheid_valid.pdf'; export const TEST_FILE_BESCHEID_BIG: string = 'Bescheid_5mb.pdf'; export const TEST_FILE_BESCHEID_ANHANG_VALID: string = 'Anhang_valid.pdf'; export const TEST_FILE_BESCHEID_ANHANG_BIG: string = 'Anhang_5mb.pdf'; +// + export const TEST_FILE_JPG: string = 'small_jpg.jpg'; export const TEST_FILE_JPEG: string = 'small_jpeg.jpeg'; export const TEST_FILE_PNG: string = 'small_png.png'; diff --git a/alfa-client/apps/alfa-e2e/src/support/file-upload.ts b/alfa-client/apps/alfa-e2e/src/support/file-upload.ts index eb8b69908acb11159d4c8b35d1ee8471bc4b9637..d01cc9a98299f7766f316a5b84bda890e4c7e3ba 100644 --- a/alfa-client/apps/alfa-e2e/src/support/file-upload.ts +++ b/alfa-client/apps/alfa-e2e/src/support/file-upload.ts @@ -23,10 +23,14 @@ */ import 'cypress-file-upload'; -export function uploadFile(inputElement: any, fileName: string): void { - inputElement.attachFile(fileName); +export function uploadFile(inputElement: Cypress.Chainable<HTMLElement>, fileName: string): void { + uploadFiles(inputElement, [fileName]); } -export function uploadEmptyFile(inputElement: any, fileName: string): void { +export function uploadFiles(inputElement: Cypress.Chainable<HTMLElement>, fileNames: string[]): void { + inputElement.attachFile(fileNames); +} + +export function uploadEmptyFile(inputElement: Cypress.Chainable<HTMLElement>, fileName: string): void { inputElement.attachFile(fileName, { allowEmpty: true }); } diff --git a/alfa-client/apps/alfa/package.json b/alfa-client/apps/alfa/package.json index c5322d141c5350c1a5a192513595e4a25eb170f9..db8d098a8244e0cfde3ebcd7f8e148c07ffd9316 100644 --- a/alfa-client/apps/alfa/package.json +++ b/alfa-client/apps/alfa/package.json @@ -1,4 +1,4 @@ { "name": "alfa", - "version": "2.21.0-SNAPSHOT" + "version": "2.22.0-SNAPSHOT" } diff --git a/alfa-client/apps/demo/src/app/app.component.html b/alfa-client/apps/demo/src/app/app.component.html index 226972864701eedbc6a7b16461f51f85130a88aa..22a2f09c8bd01b957ed678fd264ac675685cf402 100644 --- a/alfa-client/apps/demo/src/app/app.component.html +++ b/alfa-client/apps/demo/src/app/app.component.html @@ -56,6 +56,70 @@ <ods-button destructive="true" variant="ghost" text="Organisationseinheit hinzufügen" /> </div> + <div class="my-12"> + <h1 class="mb-6 text-2xl font-semibold text-text">Auswertungen</h1> + <ods-button text="Auswertung hinzufügen" /> + <ul class="mt-6 divide-y divide-gray-300 rounded-md bg-background-50 text-text shadow-sm ring-1 ring-gray-300"> + <li> + <a + href="#" + class="flex flex-col items-start justify-between gap-2 rounded-t-md 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 lg:gap-6" + > + <div class="flex-1"> + <div class="flex flex-wrap items-center gap-x-3"> + <h3 class="text-md font-semibold">Titel der Auswertung</h3> + </div> + </div> + + <dl class="flex-1"> + <dt class="sr-only">Formengine:</dt> + <dd>Formsolutions</dd> + <dt class="sr-only">FormID:</dt> + <dd>waffen/kleinerWaffenscheinKOPutopia</dd> + </dl> + </a> + </li> + <li> + <a + href="#" + class="flex flex-col items-start justify-between gap-2 rounded-t-md 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 lg:gap-6" + > + <div class="flex-1"> + <div class="flex flex-wrap items-center gap-x-3"> + <h3 class="text-md font-semibold">Auswertungstitel 2</h3> + </div> + </div> + + <dl class="flex-1"> + <dt class="sr-only">Formengine:</dt> + <dd>AFM / cit/Intelliform</dd> + <dt class="sr-only">FormID:</dt> + <dd>eGewerbe/eGewerbeAnmeldung</dd> + </dl> + </a> + </li> + <li> + <a + href="#" + class="flex flex-col items-start justify-between gap-2 rounded-t-md 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 lg:gap-6" + > + <div class="flex-1"> + <div class="flex flex-wrap items-center gap-x-3"> + <h3 class="text-md font-semibold">Titel 3</h3> + </div> + </div> + + <dl class="flex-1"> + <dt class="sr-only">Formengine:</dt> + <dd>dFördermittelantrag</dd> + <dt class="sr-only">FormID:</dt> + <dd>waffen/kleinerWaffenschein</dd> + </dl> + </a> + </li> + </ul> + </div> + <div class="my-12"> <h1 class="mb-6 text-2xl font-semibold text-text">Organisationseinheiten</h1> <ods-button text="Organisationseinheit hinzufügen" /> diff --git a/alfa-client/apps/info/package.json b/alfa-client/apps/info/package.json index 5861518686029b9621a5e39e361c49ce6f462690..f7b9ea61038da3ea7801ac1121b57c21816c49a6 100644 --- a/alfa-client/apps/info/package.json +++ b/alfa-client/apps/info/package.json @@ -1,4 +1,4 @@ { "name": "info", - "version": "1.6.0-SNAPSHOT" + "version": "1.7.0-SNAPSHOT" } diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.spec.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.spec.ts index be3f115f38c800b3b1cf87b3aaec5044e9b3c121..348a6c4b49125dca4d13765528be6b83f8b6e1de 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.spec.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.spec.ts @@ -1,18 +1,18 @@ +import { mockWindowError } from '@alfa-client/test-utils'; import { FormControl, FormGroup } from '@angular/forms'; import { patchForm } from './form.util'; describe('FormUtil', () => { describe('patch form', () => { it('should not throw any errors', () => { - const errorHandler = jest.fn(); - window.onerror = errorHandler; + const errorSpy: jest.SpyInstance = mockWindowError(); const formGroup: FormGroup = new FormGroup({ existingKey: new FormControl(null), }); patchForm({ missingKey: 'dummyValue' }, formGroup); - expect(errorHandler).not.toHaveBeenCalled(); + expect(errorSpy).not.toHaveBeenCalled(); }); describe('on strings', () => { @@ -57,6 +57,15 @@ describe('FormUtil', () => { expect(arrayFormGroup.controls['arrayValue1'].value).toBeTruthy(); expect(arrayFormGroup.controls['arrayValue2'].value).toBeFalsy(); }); + + it('should not throw any error if control is missing', () => { + const errorSpy: jest.SpyInstance = mockWindowError(); + const formGroup: FormGroup = new FormGroup({ array: new FormGroup({}) }); + + patchForm({ array: ['arrayValue1'] }, formGroup); + + expect(errorSpy).not.toHaveBeenCalled(); + }); }); describe('on object value', () => { diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.ts index 877cf9e458b14b0d2f7732086f5e033ba3b40bf5..d57cf619353a41d05d4e9d866ca098331d4345b1 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/form.util.ts @@ -15,7 +15,9 @@ function patchNonStringValues(valueToPatch: any, formGroup: FormGroup): void { function patchNonStringValue(value: any, formGroup: FormGroup): void { if (Array.isArray(value)) { - value.forEach((oneValue: any) => formGroup.controls[oneValue].patchValue(true)); + value.forEach((oneValue: any) => { + if (formGroup.contains(oneValue)) formGroup.controls[oneValue].patchValue(true); + }); } else if (!isString(value) && !isBoolean(value)) { patchNonStringValues(value, formGroup); } diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.model.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..4a2a5d7eabcfd524c1846a53c47f4d31d54f75a1 --- /dev/null +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.model.ts @@ -0,0 +1,12 @@ +export const KeycloakDefaults = { + clients: { + realmManagement: { + clientName: 'realm-management', + roles: { + managerUsers: { roleName: 'manage-users' }, + queryGroups: { roleName: 'query-groups' }, + viewClients: { roleName: 'view-clients' }, + }, + }, + }, +}; diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts index 5a91a0813ffbe8dec5a89c9f526382168481bdcd..3928e72cc9b20e768c905eedb69dc48c4ecfba3b 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.spec.ts @@ -40,6 +40,9 @@ describe('KeycloakResourceService', () => { const dummyObject: Dummy = createDummy(); const dummyAction: Observable<Dummy> = of(dummyObject); + const dummyError: Error = new Error('Test error'); + const dummyErrorAction: Observable<Error> = new Observable((observer) => observer.error(dummyError)); + beforeEach(() => { TestBed.configureTestingModule({ providers: [TestResourceService], @@ -52,7 +55,7 @@ describe('KeycloakResourceService', () => { const stateResource: StateResource<unknown> = createStateResource([]); beforeEach(() => { - service.handleChanges = jest.fn().mockReturnValue(singleCold(stateResource)); + service._handleChanges = jest.fn().mockReturnValue(singleCold(stateResource)); }); it('should return stateResource', () => { @@ -64,7 +67,7 @@ describe('KeycloakResourceService', () => { it('should call handleChanges ', fakeAsync(() => { service.getAll().subscribe(); - expect(service.handleChanges).toHaveBeenCalled(); + expect(service._handleChanges).toHaveBeenCalled(); })); }); @@ -76,7 +79,7 @@ describe('KeycloakResourceService', () => { }); it('should call doIfLoadingRequired', () => { - service.handleChanges(emptyStateResource); + service._handleChanges(emptyStateResource); expect(doIfLoadingRequiredSpy).toHaveBeenCalled(); }); @@ -84,7 +87,7 @@ describe('KeycloakResourceService', () => { it('should return stateResource', (done) => { service.stateResource.next(createStateResource([])); - service.handleChanges(emptyStateResource).subscribe((stateResource: StateResource<[]>) => { + service._handleChanges(emptyStateResource).subscribe((stateResource: StateResource<[]>) => { expect(stateResource).toEqual(createStateResource([])); done(); }); @@ -93,18 +96,18 @@ describe('KeycloakResourceService', () => { describe('loadResource', () => { it('should call set loading', () => { - service.setLoading = jest.fn(); + service._setLoading = jest.fn(); - service.loadResource(); + service._loadResource(); - expect(service.setLoading).toHaveBeenCalled(); + expect(service._setLoading).toHaveBeenCalled(); }); it('should update Resource', fakeAsync(() => { const dummyItems = [createDummy(), createDummy()]; jest.spyOn(service, '_getItemsFromKeycloak' as any).mockReturnValue(of(dummyItems)); - service.loadResource(); + service._loadResource(); tick(); expect(service.stateResource.value.resource).toEqual(dummyItems); @@ -115,11 +118,11 @@ describe('KeycloakResourceService', () => { const saveObject: Dummy = createDummy(); it('should call handleLoading', () => { - service.handleLoading = jest.fn(); + service._handleLoading = jest.fn(); service.create(saveObject); - expect(service.handleLoading).toHaveBeenCalled(); + expect(service._handleLoading).toHaveBeenCalled(); }); it('should call createInKeycloak', () => { @@ -133,11 +136,11 @@ describe('KeycloakResourceService', () => { describe('save', () => { it('should call handleLoading', () => { - service.handleLoading = jest.fn(); + service._handleLoading = jest.fn(); service.save(dummyObject); - expect(service.handleLoading).toHaveBeenCalled(); + expect(service._handleLoading).toHaveBeenCalled(); }); it('should call createInKeycloak', () => { @@ -151,11 +154,11 @@ describe('KeycloakResourceService', () => { describe('delete', () => { it('should call handleLoading', () => { - service.handleLoading = jest.fn(); + service._handleLoading = jest.fn(); service.delete(id); - expect(service.handleLoading).toHaveBeenCalled(); + expect(service._handleLoading).toHaveBeenCalled(); }); it('should call createInKeycloak', () => { @@ -169,42 +172,57 @@ describe('KeycloakResourceService', () => { describe('handleLoading', () => { it('should set loading', () => { - service.handleLoading(dummyAction); + service._handleLoading(dummyAction); expect(service.stateResource.value.loading).toBe(true); }); it('should call refreshAfterFirstEmit', () => { - service.refreshAfterFirstEmit = jest.fn().mockReturnValue(dummyAction); + service._refreshAfterEmit = jest.fn().mockReturnValue(dummyAction); - service.handleLoading(dummyAction); + service._handleLoading(dummyAction); - expect(service.refreshAfterFirstEmit).toHaveBeenCalled(); + expect(service._refreshAfterEmit).toHaveBeenCalled(); }); it('should call progress', () => { - service.setLoadingInStateResource = jest.fn().mockReturnValue(dummyAction); + service._setLoadingInStateResource = jest.fn().mockReturnValue(dummyAction); - service.handleLoading(dummyAction); + service._handleLoading(dummyAction); - expect(service.setLoadingInStateResource).toHaveBeenCalled(); + expect(service._setLoadingInStateResource).toHaveBeenCalled(); }); }); - describe('refreshAfterFirstEmit', () => { - it('should call refresh after first emit', fakeAsync(() => { + describe('refreshAfterEmit', () => { + it('should call refresh after first emit', () => { service.refresh = jest.fn(); - service.refreshAfterFirstEmit(dummyAction).subscribe(); - tick(); + service._refreshAfterEmit(dummyAction).subscribe(); expect(service.refresh).toHaveBeenCalled(); - })); + }); + + it('should call refresh on error', () => { + service.refresh = jest.fn(); + + service._refreshAfterEmit(dummyErrorAction).subscribe(); + + expect(service.refresh).toHaveBeenCalled(); + }); + + it('should throw error refresh on error', () => { + service.refresh = jest.fn(); + + const result: Observable<unknown> = service._refreshAfterEmit(dummyErrorAction); + + expect(result).toBeObservable(cold('#', null, dummyError)); + }); }); describe('setLoadingInStateResource', () => { it('should emit emptyState first with loading and then state without loading', () => { - const result: Observable<StateResource<Dummy>> = service.setLoadingInStateResource<Dummy>(cold('--x', { x: dummyObject })); + const result: Observable<StateResource<Dummy>> = service._setLoadingInStateResource<Dummy>(cold('--x', { x: dummyObject })); expect(result).toBeObservable(cold('a-b', { a: createEmptyStateResource(true), b: createStateResource(dummyObject) })); }); @@ -214,7 +232,7 @@ describe('KeycloakResourceService', () => { it('should set loading in state to true without parameter', () => { service.stateResource.value.loading = false; - service.setLoading(); + service._setLoading(); expect(service.stateResource.value.loading).toEqual(true); }); diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts index ae74c73ee2c59c989a0db77dbaa1b881c4061448..2b6255aa9bba1e4ac1424de5a9b56282cb683349 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/keycloak.resource.service.ts @@ -22,7 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { createEmptyStateResource, createStateResource, doIfLoadingRequired, StateResource } from '@alfa-client/tech-shared'; -import { BehaviorSubject, first, map, Observable, startWith, switchMap, tap } from 'rxjs'; +import { BehaviorSubject, catchError, first, map, Observable, startWith, switchMap, tap, throwError } from 'rxjs'; export abstract class KeycloakResourceService<T> { readonly stateResource: BehaviorSubject<StateResource<T[]>> = new BehaviorSubject(createEmptyStateResource()); @@ -30,16 +30,16 @@ export abstract class KeycloakResourceService<T> { public getAll(): Observable<StateResource<T[]>> { return this.stateResource .asObservable() - .pipe(switchMap((stateResource: StateResource<T[]>) => this.handleChanges(stateResource))); + .pipe(switchMap((stateResource: StateResource<T[]>) => this._handleChanges(stateResource))); } - handleChanges(stateResource: StateResource<T[]>): Observable<StateResource<T[]>> { - doIfLoadingRequired(stateResource, (): void => this.loadResource()); + _handleChanges(stateResource: StateResource<T[]>): Observable<StateResource<T[]>> { + doIfLoadingRequired(stateResource, (): void => this._loadResource()); return this.stateResource.asObservable(); } - loadResource(): void { - this.setLoading(); + _loadResource(): void { + this._setLoading(); this._getItemsFromKeycloak() .pipe(first()) .subscribe((items: T[]): void => this.updateResource(items)); @@ -52,43 +52,49 @@ export abstract class KeycloakResourceService<T> { } public create(item: Partial<T>): Observable<StateResource<T>> { - return this.handleLoading<T>(this._createInKeycloak(item)); + return this._handleLoading<T>(this._createInKeycloak(item)); } protected abstract _createInKeycloak(item: Partial<T>): Observable<T>; public save(item: T): Observable<StateResource<T>> { - return this.handleLoading<T>(this._saveInKeycloak(item)); + return this._handleLoading<T>(this._saveInKeycloak(item)); } protected abstract _saveInKeycloak(item: T): Observable<T>; public delete(id: string): Observable<StateResource<void>> { - return this.handleLoading(this._deleteInKeycloak(id)); + return this._handleLoading(this._deleteInKeycloak(id)); } protected abstract _deleteInKeycloak(id: string): Observable<void>; - handleLoading<D>(action: Observable<D>): Observable<StateResource<D>> { - this.setLoading(); - return this.setLoadingInStateResource<D>(this.refreshAfterFirstEmit<D>(action)); + _handleLoading<D>(action: Observable<D>): Observable<StateResource<D>> { + this._setLoading(); + return this._setLoadingInStateResource<D>(this._refreshAfterEmit<D>(action)); } - refreshAfterFirstEmit<D>(action: Observable<D>): Observable<D> { + _refreshAfterEmit<D>(action: Observable<D>): Observable<D> { return action.pipe( first(), tap((): void => this.refresh()), + catchError((err: Error) => this.handleError(err)), ); } - setLoadingInStateResource<D>(action: Observable<D>): Observable<StateResource<D>> { + handleError(err: Error): Observable<never> { + this.refresh(); + return throwError(() => err); + } + + _setLoadingInStateResource<D>(action: Observable<D>): Observable<StateResource<D>> { return action.pipe( map((value: D): StateResource<D> => createStateResource<D>(value)), startWith(createEmptyStateResource<D>(true)), ); } - setLoading(): void { + _setLoading(): void { this.stateResource.next({ ...this.stateResource.value, loading: true }); } diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.spec.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.spec.ts index d0806e198efa5090d375832bbd313ca99482149b..c0ef6b387b57946efc4336573809b55582b7912e 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.spec.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.spec.ts @@ -21,22 +21,25 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { User } from '@admin-client/user-shared'; +import { AdminRoles, RoleMappings, User } from '@admin-client/user-shared'; import { UserRepository } from '@admin/keycloak-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { Mock, mock } from '@alfa-client/test-utils'; -import { TestBed, fakeAsync, tick } from '@angular/core/testing'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; +import { expect } from '@jest/globals'; import KcAdminClient from '@keycloak/keycloak-admin-client'; import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation'; import MappingsRepresentation from '@keycloak/keycloak-admin-client/lib/defs/mappingsRepresentation'; -import RoleRepresentation, { RoleMappingPayload } from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; +import { RequiredActionAlias } from '@keycloak/keycloak-admin-client/lib/defs/requiredActionProviderRepresentation'; +import { RoleMappingPayload } from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; import { Users } from '@keycloak/keycloak-admin-client/lib/resources/users'; import { cold } from 'jest-marbles'; -import { omit } from 'lodash-es'; +import { omit, times } from 'lodash-es'; import { throwError } from 'rxjs'; import { createUser } from '../../../user-shared/test/user'; import { UserFormService } from '../../../user/src/lib/user-form/user.formservice'; +import { KeycloakDefaults } from './keycloak.model'; describe('UserRepository', () => { let repository: UserRepository; @@ -71,18 +74,18 @@ describe('UserRepository', () => { expect(kcAdminClient.users['create']).toHaveBeenCalledWith(omit(user, 'groupIds')); }); - it('should call addUserRoles', fakeAsync(() => { - repository._addUserRoles = jest.fn(); + it('should call updateUserRoles', fakeAsync(() => { + repository._updateUserRoles = jest.fn(); repository.createInKeycloak(user).subscribe(); tick(); - expect(repository._addUserRoles).toHaveBeenCalledWith(user.id, user.clientRoles); + expect(repository._updateUserRoles).toHaveBeenCalledWith(user.id, user.clientRoles); })); it('should call sendActivationMail', (done) => { repository._sendActivationMail = jest.fn(); - repository._addUserRoles = jest.fn().mockReturnValue(Promise.resolve()); + repository._updateUserRoles = jest.fn().mockReturnValue(Promise.resolve()); repository.createInKeycloak(user).subscribe(() => { expect(repository._sendActivationMail).toHaveBeenCalledWith(user.id); @@ -107,7 +110,7 @@ describe('UserRepository', () => { update: jest.fn().mockReturnValue(Promise.resolve()), }; - repository._addUserRoles = jest.fn().mockReturnValue(Promise.resolve()); + repository._updateUserRoles = jest.fn().mockReturnValue(Promise.resolve()); repository._updateUserGroups = jest.fn().mockReturnValue(Promise.resolve()); }); @@ -117,11 +120,11 @@ describe('UserRepository', () => { expect(kcAdminClient.users['update']).toHaveBeenCalledWith({ id: user.id }, omit(user, 'groupIds')); }); - it('should call addUserRoles', fakeAsync(() => { + it('should call updateUserRoles', fakeAsync(() => { repository.saveInKeycloak(user).subscribe(); tick(); - expect(repository._addUserRoles).toHaveBeenCalledWith(user.id, user.clientRoles); + expect(repository._updateUserRoles).toHaveBeenCalledWith(user.id, user.clientRoles); })); it('should call updateUserGroups', (done) => { @@ -241,70 +244,197 @@ describe('UserRepository', () => { }); }); - describe('addUserRoles', () => { - it('should call addUserRolesForClient for admin', async () => { - repository._addUserRolesForClient = jest.fn(); + describe('UpdateUserRoles', () => { + const clientId: string = faker.string.uuid(); + + beforeEach(() => { + repository._updateUserRolesForClient = jest.fn(); + repository._getClientId = jest.fn().mockReturnValue(clientId); + }); - await repository._addUserRoles(user.id, { admin: [UserFormService.ADMIN], alfa: [] }); + it('should call getClientId for admin', async () => { + await repository._updateUserRoles(user.id, { admin: [UserFormService.ADMIN], alfa: [] }); - expect(repository._addUserRolesForClient).toHaveBeenCalledWith( - user.id, - [UserFormService.ADMIN], - UserRepository.ADMIN_CLIENT_NAME, - ); + expect(repository._getClientId).toHaveBeenCalledWith(UserRepository.ADMIN_CLIENT_NAME); }); - it('should call addUserRolesForClient for admin', async () => { - repository._addUserRolesForClient = jest.fn(); + it('should call UpdateUserRolesForClient for admin', async () => { + await repository._updateUserRoles(user.id, { admin: [UserFormService.ADMIN], alfa: [] }); - await repository._addUserRoles(user.id, { alfa: [UserFormService.POSTSTELLE], admin: [] }); + expect(repository._updateUserRolesForClient).toHaveBeenCalledWith(user.id, [UserFormService.ADMIN], clientId); + }); - expect(repository._addUserRolesForClient).toHaveBeenCalledWith( - user.id, - [UserFormService.POSTSTELLE], - UserRepository.ALFA_CLIENT_NAME, - ); + it('should call getClientId for admin', async () => { + await repository._updateUserRoles(user.id, { alfa: [UserFormService.POSTSTELLE], admin: [] }); + + expect(repository._getClientId).toHaveBeenCalledWith(UserRepository.ALFA_CLIENT_NAME); }); - it('should not call addUserRolesForClient if clientRoles alfa and admin are empty', async () => { - repository._addUserRolesForClient = jest.fn(); + it('should call UpdateUserRolesForClient for admin', async () => { + await repository._updateUserRoles(user.id, { alfa: [UserFormService.POSTSTELLE], admin: [] }); - await repository._addUserRoles(user.id, { admin: [], alfa: [] }); + expect(repository._updateUserRolesForClient).toHaveBeenCalledWith(user.id, [UserFormService.POSTSTELLE], clientId); + }); + }); - expect(repository._addUserRolesForClient).not.toHaveBeenCalled(); + describe('updateUserRolesForClient', () => { + const clientId: string = faker.string.uuid(); + const clientRoles: string[] = times(3, () => faker.word.sample()); + const newClientRoleMappings: RoleMappingPayload[] = clientRoles.map((role: string) => ({ + id: faker.string.uuid(), + name: role, + })); + const oldClientRoleMappings: RoleMappingPayload[] = newClientRoleMappings.slice(1); + const clientRoleMappings: RoleMappings = { newClientRoleMappings, oldClientRoleMappings }; + + beforeEach(() => { + repository._getClientRoleMappings = jest.fn().mockReturnValue(Promise.resolve(clientRoleMappings)); + repository._deleteUserRoles = jest.fn(); + repository._addUserRoles = jest.fn(); + }); + + it('should call getClientRoleMappings', async () => { + await repository._updateUserRolesForClient(user.id, clientRoles, clientId); + + expect(repository._getClientRoleMappings).toHaveBeenCalledWith(user.id, clientId, clientRoles); + }); + + it('should call deleteUserRoles', async () => { + await repository._updateUserRolesForClient(user.id, clientRoles, clientId); + + expect(repository._deleteUserRoles).toHaveBeenCalledWith(user.id, clientRoleMappings, clientId); + }); + + it('should call addUserRoles', async () => { + await repository._updateUserRolesForClient(user.id, clientRoles, clientId); + + expect(repository._addUserRoles).toHaveBeenCalledWith(user.id, clientRoleMappings, clientId); }); }); - describe('addUserRolesForClient', () => { + describe('getClientRoleMappings', () => { const clientId: string = faker.string.uuid(); - const roleMapping: RoleMappingPayload[] = [{ id: faker.string.uuid(), name: faker.word.sample() }]; + const newClientRoles: string[] = times(3, () => faker.word.sample()); + const newClientRoleMappings: RoleMappingPayload[] = newClientRoles.map((role: string) => ({ + id: faker.string.uuid(), + name: role, + })); + const oldClientRoleMappings: RoleMappingPayload[] = newClientRoleMappings.slice(1); + const clientRoleMappings: RoleMappings = { newClientRoleMappings, oldClientRoleMappings }; beforeEach(() => { + repository._getOldUserRoleMappings = jest.fn().mockReturnValue(Promise.resolve(oldClientRoleMappings)); repository._getClientId = jest.fn().mockReturnValue(Promise.resolve(clientId)); - repository._mapUserRoles = jest.fn().mockReturnValue(Promise.resolve(roleMapping)); - repository._addUserRolesInKeycloak = jest.fn(); + repository._mapUserRoles = jest.fn().mockReturnValue(Promise.resolve(newClientRoleMappings)); + repository._deleteUserRoles = jest.fn(); + repository._addUserRoles = jest.fn(); + }); + + it('should call mapUserRoles', () => { + repository._getClientRoleMappings(user.id, clientId, newClientRoles); + + expect(repository._mapUserRoles).toHaveBeenCalledWith(clientId, newClientRoles); + }); + + it('should call get old user role mappings', async () => { + await repository._getClientRoleMappings(user.id, clientId, newClientRoles); + + expect(repository._getOldUserRoleMappings).toHaveBeenCalledWith(user.id, clientId); + }); + + it('should return clientRoleMappings', async () => { + const result: RoleMappings = await repository._getClientRoleMappings(user.id, clientId, newClientRoles); + + expect(result).toEqual(clientRoleMappings); + }); + }); + + describe('getOldUserRoleMappings', () => { + const clientId: string = faker.string.uuid(); + const roleMapping: RoleMappingPayload[] = [{ id: faker.string.uuid(), name: faker.word.sample() }]; + + beforeEach(() => { + kcAdminClient.users = <any>{ + listClientRoleMappings: jest.fn().mockReturnValue(Promise.resolve(roleMapping)), + }; + }); + + it('should call users listClientRoleMappings', () => { + repository._getOldUserRoleMappings(user.id, clientId); + + expect(kcAdminClient.users['listClientRoleMappings']).toHaveBeenCalledWith({ id: user.id, clientUniqueId: clientId }); + }); + + it('should return roleMapping', async () => { + const result: RoleMappingPayload[] = await repository._getOldUserRoleMappings(user.id, clientId); + + expect(result).toEqual(roleMapping); + }); + }); + + describe('deleteUserRoles', () => { + const clientId: string = faker.string.uuid(); + const clientRoles: string[] = times(3, () => faker.word.sample()); + const oldClientRoleMappings: RoleMappingPayload[] = clientRoles.map((role: string) => ({ + id: faker.string.uuid(), + name: role, + })); + const newClientRoleMappings: RoleMappingPayload[] = oldClientRoleMappings.slice(1); + const clientRoleMappings: RoleMappings = { newClientRoleMappings, oldClientRoleMappings }; + + beforeEach(() => { + repository._deleteUserRolesInKeycloak = jest.fn(); kcAdminClient.users = <any>{ addClientRoleMappings: jest.fn().mockReturnValue(Promise.resolve()), }; }); - it('should call getClientId', async () => { - await repository._addUserRolesForClient(user.id, [UserFormService.ADMIN], UserRepository.ADMIN_CLIENT_NAME); + it('should call deleteUserRolesInKeycloak', async () => { + await repository._deleteUserRoles(user.id, clientRoleMappings, clientId); - expect(repository._getClientId).toHaveBeenCalled(); + expect(repository._deleteUserRolesInKeycloak).toHaveBeenCalledWith(user.id, clientId, [oldClientRoleMappings[0]]); }); - it('should call getAlfaClientId', async () => { - await repository._addUserRolesForClient(user.id, [UserFormService.ADMIN], UserRepository.ADMIN_CLIENT_NAME); + it('should call not call deleteUserRolesInKeycloak if no roles to delete', async () => { + await repository._deleteUserRoles( + user.id, + { oldClientRoleMappings, newClientRoleMappings: oldClientRoleMappings }, + clientId, + ); + + expect(repository._deleteUserRolesInKeycloak).not.toHaveBeenCalled(); + }); + }); + + describe('addUserRoles', () => { + const clientId: string = faker.string.uuid(); + const clientRoles: string[] = times(3, () => faker.word.sample()); + const newClientRoleMappings: RoleMappingPayload[] = clientRoles.map((role: string) => ({ + id: faker.string.uuid(), + name: role, + })); + const oldClientRoleMappings: RoleMappingPayload[] = newClientRoleMappings.slice(1); + const clientRoleMappings: RoleMappings = { newClientRoleMappings, oldClientRoleMappings }; + + beforeEach(() => { + repository._addUserRolesInKeycloak = jest.fn(); - expect(repository._mapUserRoles).toHaveBeenCalledWith(clientId, [UserFormService.ADMIN]); + kcAdminClient.users = <any>{ + addClientRoleMappings: jest.fn().mockReturnValue(Promise.resolve()), + }; }); it('should call addUserRolesInKeycloak', async () => { - await repository._addUserRolesForClient(user.id, [UserFormService.ADMIN], UserRepository.ADMIN_CLIENT_NAME); + await repository._addUserRoles(user.id, clientRoleMappings, clientId); - expect(repository._addUserRolesInKeycloak).toHaveBeenCalledWith(user.id, clientId, roleMapping); + expect(repository._addUserRolesInKeycloak).toHaveBeenCalledWith(user.id, clientId, [newClientRoleMappings[0]]); + }); + + it('should not call addUserRolesInKeycloak if no roles to add', async () => { + await repository._addUserRoles(user.id, { newClientRoleMappings, oldClientRoleMappings: newClientRoleMappings }, clientId); + + expect(repository._addUserRolesInKeycloak).not.toHaveBeenCalled(); }); }); @@ -332,11 +462,11 @@ describe('UserRepository', () => { describe('mapUserRoles', () => { const clientId: string = faker.string.uuid(); - const clientRoles: RoleRepresentation[] = Array.from({ length: 3 }, () => ({ + const clientRoles: RoleMappingPayload[] = Array.from({ length: 3 }, () => ({ id: faker.string.uuid(), name: faker.word.sample(), })); - const userRoles: string[] = clientRoles.map((role) => role.name).slice(1); + const userRoles: string[] = clientRoles.map((role: RoleMappingPayload): string => role.name).slice(1); beforeEach(() => { kcAdminClient.clients = <any>{ @@ -353,7 +483,7 @@ describe('UserRepository', () => { it('should return roleMapping', async () => { const result: RoleMappingPayload[] = await repository._mapUserRoles(clientId, userRoles); - expect(result).toEqual(clientRoles.slice(1).map((role) => ({ id: role.id, name: role.name }))); + expect(result).toEqual(clientRoles.slice(1)); }); it('should filter roles if they are not in clientRoles', async () => { @@ -383,6 +513,70 @@ describe('UserRepository', () => { }); }); + describe('deleteUserRolesInKeycloak', () => { + beforeEach(() => { + kcAdminClient.users = <any>{ + delClientRoleMappings: jest.fn().mockReturnValue(Promise.resolve()), + }; + }); + + it('should call kcAdminClient users delClientRoleMappings', async () => { + const clientId: string = faker.string.uuid(); + const roles: RoleMappingPayload[] = Array.from({ length: 3 }, () => ({ + id: faker.string.uuid(), + name: faker.word.sample(), + })); + + await repository._deleteUserRolesInKeycloak(user.id, clientId, roles); + + expect(kcAdminClient.users['delClientRoleMappings']).toHaveBeenCalledWith({ id: user.id, clientUniqueId: clientId, roles }); + }); + }); + + describe('update user roles for admin', () => { + const clientId: string = faker.string.uuid(); + + beforeEach(() => { + repository._updateUserRolesForClient = jest.fn(); + repository._getClientId = jest.fn().mockReturnValue(new Promise((resolve) => resolve(clientId))); + }); + + it('should get client id', async () => { + await repository._updateUserRolesForAdmin(user.id, { + admin: [AdminRoles.ADMIN], + alfa: [], + }); + + expect(repository._getClientId).toHaveBeenCalledWith(KeycloakDefaults.clients.realmManagement.clientName); + }); + + it('should update user roles', async () => { + await repository._updateUserRolesForAdmin(user.id, { + admin: [AdminRoles.ADMIN], + alfa: [], + }); + + expect(repository._updateUserRolesForClient).toHaveBeenCalledWith( + user.id, + [ + KeycloakDefaults.clients.realmManagement.roles.managerUsers.roleName, + KeycloakDefaults.clients.realmManagement.roles.queryGroups.roleName, + KeycloakDefaults.clients.realmManagement.roles.viewClients.roleName, + ], + clientId, + ); + }); + + it('should NOT update user roles for no ADMIN_ADMIN role', async () => { + await repository._updateUserRolesForAdmin(user.id, { + admin: [faker.word.noun()], + alfa: [], + }); + + expect(repository._updateUserRolesForClient).not.toHaveBeenCalled(); + }); + }); + describe('sendActivationMail', () => { it('should call kcAdminClient users executeActionsEmail', () => { const userId: string = faker.string.uuid(); @@ -391,7 +585,7 @@ describe('UserRepository', () => { expect(kcAdminClientUsers.executeActionsEmail).toHaveBeenCalledWith({ id: userId, - actions: ['VERIFY_EMAIL'], + actions: [RequiredActionAlias.VERIFY_EMAIL, RequiredActionAlias.UPDATE_PASSWORD], lifespan: 3600 * 24 * 7, }); }); diff --git a/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.ts b/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.ts index a5df128a7de4ceb8bd71c4d2edc337078b57bcca..c510b595f5b6157f20093328d23fa31bcc11e242 100644 --- a/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.ts +++ b/alfa-client/libs/admin/keycloak-shared/src/lib/user.repository.ts @@ -21,17 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ClientMapping, ClientRoles, User } from '@admin-client/user-shared'; +import { AdminRoles, ClientMapping, ClientRoles, RoleMappings, User } from '@admin-client/user-shared'; import { createStateResource, StateResource } from '@alfa-client/tech-shared'; import { inject, Injectable } from '@angular/core'; import KcAdminClient from '@keycloak/keycloak-admin-client'; import ClientRepresentation from '@keycloak/keycloak-admin-client/lib/defs/clientRepresentation'; import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation'; import MappingsRepresentation from '@keycloak/keycloak-admin-client/lib/defs/mappingsRepresentation'; -import RoleRepresentation, { RoleMappingPayload } from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; +import { RequiredActionAlias } from '@keycloak/keycloak-admin-client/lib/defs/requiredActionProviderRepresentation'; +import { RoleMappingPayload } from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; +import * as _ from 'lodash-es'; import { isNil, omit } from 'lodash-es'; import { catchError, concatMap, forkJoin, from, map, mergeMap, Observable, tap, throwError } from 'rxjs'; +import { KeycloakDefaults } from './keycloak.model'; @Injectable({ providedIn: 'root', @@ -45,7 +48,7 @@ export class UserRepository { public createInKeycloak(user: User): Observable<User> { return from(this.kcAdminClient.users.create(omit(user, 'groupIds'))).pipe( concatMap(async (response: { id: string }): Promise<{ id: string }> => { - await this._addUserRoles(response.id, user.clientRoles); + await this._updateUserRoles(response.id, user.clientRoles); return response; }), tap((response: { id: string }): void => this._sendActivationMail(response.id)), @@ -58,7 +61,7 @@ export class UserRepository { const { groupIds, ...userToSave } = user; return from(this.kcAdminClient.users.update({ id: user.id }, userToSave)).pipe( concatMap(async (): Promise<void> => { - await this._addUserRoles(user.id, user.clientRoles); + await this._updateUserRoles(user.id, user.clientRoles); await this._updateUserGroups(user.id, user.groupIds); }), map((): User => user), @@ -73,8 +76,10 @@ export class UserRepository { } async _getOldUserGroupIds(userId: string): Promise<string[]> { - const oldUserGroupsReps: GroupRepresentation[] = await this.kcAdminClient.users.listGroups({ id: userId }); - return oldUserGroupsReps.map((group: GroupRepresentation): string => group.id); + const oldUserGroupsReps: RoleMappingPayload[] = <RoleMappingPayload[]>( + await this.kcAdminClient.users.listGroups({ id: userId }) + ); + return _.map(oldUserGroupsReps, 'id'); } async _deleteUserGroups(userId: string, newGroupIds: string[], oldGroupIds: string[]): Promise<void> { @@ -87,7 +92,7 @@ export class UserRepository { ); } - async _addUserGroups(userId: string, newGroupIds: string[], oldGroupIds): Promise<void> { + async _addUserGroups(userId: string, newGroupIds: string[], oldGroupIds: string[]): Promise<void> { await Promise.all( newGroupIds .filter((group) => !oldGroupIds.includes(group)) @@ -97,20 +102,55 @@ export class UserRepository { ); } - async _addUserRoles(userId: string, clientRoles: ClientRoles): Promise<void> { - if (clientRoles.admin.length > 0) { - await this._addUserRolesForClient(userId, clientRoles.admin, UserRepository.ADMIN_CLIENT_NAME); + async _updateUserRoles(userId: string, clientRoles: ClientRoles): Promise<void> { + await this._updateUserRolesForClient(userId, clientRoles.admin, await this._getClientId(UserRepository.ADMIN_CLIENT_NAME)); + await this._updateUserRolesForClient(userId, clientRoles.alfa, await this._getClientId(UserRepository.ALFA_CLIENT_NAME)); + await this._updateUserRolesForAdmin(userId, clientRoles); + } + + async _updateUserRolesForClient(userId: string, clientRoles: string[], clientId: string): Promise<void> { + const roleMappings: RoleMappings = await this._getClientRoleMappings(userId, clientId, clientRoles); + await this._deleteUserRoles(userId, roleMappings, clientId); + await this._addUserRoles(userId, roleMappings, clientId); + } + + async _getClientRoleMappings(userId: string, clientId: string, clientRoles: string[]): Promise<RoleMappings> { + const newClientRoleMappings: RoleMappingPayload[] = await this._mapUserRoles(clientId, clientRoles); + const oldClientRoleMappings: RoleMappingPayload[] = await this._getOldUserRoleMappings(userId, clientId); + return { newClientRoleMappings, oldClientRoleMappings }; + } + + async _getOldUserRoleMappings(userId: string, clientId: string): Promise<RoleMappingPayload[]> { + return <RoleMappingPayload[]>await this.kcAdminClient.users.listClientRoleMappings({ + id: userId, + clientUniqueId: clientId, + }); + } + + async _deleteUserRoles(userId: string, roleMappings: RoleMappings, clientId: string): Promise<void> { + const rolesToDelete: RoleMappingPayload[] = this.getRolesToDelete(roleMappings); + if (rolesToDelete.length > 0) { + await this._deleteUserRolesInKeycloak(userId, clientId, rolesToDelete); } + } - if (clientRoles.alfa.length > 0) { - await this._addUserRolesForClient(userId, clientRoles.alfa, UserRepository.ALFA_CLIENT_NAME); + private getRolesToDelete(roleMappings: RoleMappings): RoleMappingPayload[] { + return roleMappings.oldClientRoleMappings.filter( + (role: RoleMappingPayload) => !_.map(roleMappings.newClientRoleMappings, 'name').includes(role.name), + ); + } + + async _addUserRoles(userId: string, roleMappings: RoleMappings, clientId: string): Promise<void> { + const rolesToAdd: RoleMappingPayload[] = this.getRolesToAdd(roleMappings); + if (rolesToAdd.length > 0) { + await this._addUserRolesInKeycloak(userId, clientId, rolesToAdd); } } - async _addUserRolesForClient(userId: string, userRoles: string[], client: string): Promise<void> { - const clientId: string = await this._getClientId(client); - const roles: RoleMappingPayload[] = await this._mapUserRoles(clientId, userRoles); - await this._addUserRolesInKeycloak(userId, clientId, roles); + private getRolesToAdd(roleMappings: RoleMappings): RoleMappingPayload[] { + return roleMappings.newClientRoleMappings.filter( + (role: RoleMappingPayload) => !_.map(roleMappings.oldClientRoleMappings, 'name').includes(role.name), + ); } async _getClientId(client: string): Promise<string | undefined> { @@ -119,10 +159,8 @@ export class UserRepository { } async _mapUserRoles(clientId: string, userRoles: string[]): Promise<RoleMappingPayload[]> { - const roles: RoleRepresentation[] = await this.kcAdminClient.clients.listRoles({ id: clientId }); - return roles - .filter((role: RoleRepresentation): boolean => userRoles.includes(role.name)) - .map((role: RoleRepresentation): RoleMappingPayload => ({ id: role.id, name: role.name })); + const roles: RoleMappingPayload[] = <RoleMappingPayload[]>await this.kcAdminClient.clients.listRoles({ id: clientId }); + return roles.filter((role: RoleMappingPayload): boolean => userRoles.includes(role.name)); } async _addUserRolesInKeycloak(userId: string, clientId: string, roles: RoleMappingPayload[]): Promise<void> { @@ -133,10 +171,32 @@ export class UserRepository { }); } + async _deleteUserRolesInKeycloak(userId: string, clientId: string, roles: RoleMappingPayload[]): Promise<void> { + await this.kcAdminClient.users.delClientRoleMappings({ + id: userId, + clientUniqueId: clientId, + roles, + }); + } + + async _updateUserRolesForAdmin(userId: string, clientRoles: ClientRoles): Promise<void> { + if (clientRoles.admin.includes(AdminRoles.ADMIN)) { + await this._updateUserRolesForClient( + userId, + [ + KeycloakDefaults.clients.realmManagement.roles.managerUsers.roleName, + KeycloakDefaults.clients.realmManagement.roles.queryGroups.roleName, + KeycloakDefaults.clients.realmManagement.roles.viewClients.roleName, + ], + await this._getClientId(KeycloakDefaults.clients.realmManagement.clientName), + ); + } + } + _sendActivationMail(userId: string): void { this.kcAdminClient.users.executeActionsEmail({ id: userId, - actions: ['VERIFY_EMAIL'], + actions: [RequiredActionAlias.VERIFY_EMAIL, RequiredActionAlias.UPDATE_PASSWORD], lifespan: 3600 * 24 * 7, }); } @@ -208,7 +268,7 @@ export class UserRepository { private getUserGroups(user: User): Observable<string[]> { return from(this.kcAdminClient.users.listGroups({ id: user.id })).pipe( - map((groups: GroupRepresentation[]): string[] => groups.map((group: GroupRepresentation): string => group.name)), + map((groups: GroupRepresentation[]): string[] => _.map(groups, 'name')), ); } @@ -230,6 +290,6 @@ export class UserRepository { return []; } - return clientMappingsAlfa.mappings.map((role: RoleRepresentation): string => role.name); + return _.map(clientMappingsAlfa.mappings, 'name'); } } diff --git a/alfa-client/libs/admin/organisations-einheit/src/lib/organisations-einheit-container/organisations-einheit-container.component.spec.ts b/alfa-client/libs/admin/organisations-einheit/src/lib/organisations-einheit-container/organisations-einheit-container.component.spec.ts index 2f207e5573f8398234d5d01e201430a4c4e34303..18827db0127eebb847a3082817bc397fdc6394e0 100644 --- a/alfa-client/libs/admin/organisations-einheit/src/lib/organisations-einheit-container/organisations-einheit-container.component.spec.ts +++ b/alfa-client/libs/admin/organisations-einheit/src/lib/organisations-einheit-container/organisations-einheit-container.component.spec.ts @@ -23,16 +23,18 @@ */ import { OrganisationsEinheitContainerComponent } from '@admin-client/organisations-einheit'; import { AdminOrganisationsEinheit, AdminOrganisationsEinheitService } from '@admin-client/organisations-einheit-shared'; -import { createStateResource, StateResource, ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared'; +import { createStateResource, StateResource } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, getMockComponent, Mock, mock } from '@alfa-client/test-utils'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; +import { OzgcloudDialogService, SpinnerComponent } from '@alfa-client/ui'; +import { ZustaendigeStelleModule } from '@alfa-client/zustaendige-stelle'; +import { OrganisationsEinheitResource, ZustaendigeStelleSharedModule } from '@alfa-client/zustaendige-stelle-shared'; import { CommonModule } from '@angular/common'; import { ViewContainerRef } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ButtonComponent } from '@ods/system'; import { createAdminOrganisationsEinheit } from 'libs/admin/organisations-einheit-shared/src/test/organisations-einheit'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; +import { MockComponent, MockModule } from 'ng-mocks'; import { of } from 'rxjs'; import { createOrganisationsEinheitResource } from '../../../../../zustaendige-stelle-shared/test/organisations-einheit'; import { OrganisationsEinheitListComponent } from './organisations-einheit-list/organisations-einheit-list.component'; @@ -43,7 +45,8 @@ describe('OrganisationsEinheitContainerComponent', () => { let organisationsEinheitService: Mock<AdminOrganisationsEinheitService>; let dialogService: Mock<OzgcloudDialogService>; - let vieContainerRef: Mock<ViewContainerRef>; + + const viewContainerRef = <any>{}; const organisationsEinheit: AdminOrganisationsEinheit = createAdminOrganisationsEinheit(); const organisationsEinheitListStateResource: StateResource<AdminOrganisationsEinheit[]> = createStateResource([ @@ -60,17 +63,24 @@ describe('OrganisationsEinheitContainerComponent', () => { refresh: jest.fn(), }; dialogService = mock(OzgcloudDialogService); - vieContainerRef = mock(ViewContainerRef as any); }); beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ToEmbeddedResourcesPipe], - imports: [CommonModule, OrganisationsEinheitContainerComponent, MockComponent(OrganisationsEinheitListComponent)], + declarations: [], + imports: [ + OrganisationsEinheitContainerComponent, + MockModule(CommonModule), + MockModule(ZustaendigeStelleModule), + MockModule(ZustaendigeStelleSharedModule), + MockComponent(OrganisationsEinheitListComponent), + MockComponent(ButtonComponent), + MockComponent(SpinnerComponent), + ], providers: [ { provide: AdminOrganisationsEinheitService, useValue: organisationsEinheitService }, { provide: OzgcloudDialogService, useValue: dialogService }, - { provide: ViewContainerRef, useValue: vieContainerRef }, + { provide: ViewContainerRef, useValue: viewContainerRef }, ], }).compileComponents(); diff --git a/alfa-client/libs/admin/postfach/src/lib/postfach-container/postfach-container.component.html b/alfa-client/libs/admin/postfach/src/lib/postfach-container/postfach-container.component.html index 3e8e4b49ae09ba083768eb4a1ffa4155ab1bb49c..4cc1c39f9ceae871719596a641734e16f8f966c4 100644 --- a/alfa-client/libs/admin/postfach/src/lib/postfach-container/postfach-container.component.html +++ b/alfa-client/libs/admin/postfach/src/lib/postfach-container/postfach-container.component.html @@ -1,2 +1,2 @@ -<h1 class="heading-1">Postfach</h1> +<h1 class="heading-1" data-test-id="headline">Postfach</h1> <admin-postfach-form [postfachStateResource]="postfachStateResource$ | async" /> diff --git a/alfa-client/libs/admin/user-shared/src/lib/user.model.ts b/alfa-client/libs/admin/user-shared/src/lib/user.model.ts index db185a0209450a60d50e2ffc89a263d62f480d12..45d8e171c2c2b1cde1e96e25d76cac23bcf6e5e2 100644 --- a/alfa-client/libs/admin/user-shared/src/lib/user.model.ts +++ b/alfa-client/libs/admin/user-shared/src/lib/user.model.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import RoleRepresentation from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; +import RoleRepresentation, { RoleMappingPayload } from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; export interface User { id?: string; @@ -43,3 +43,12 @@ export interface ClientRoles { export interface ClientMapping { mappings: RoleRepresentation[]; } + +export interface RoleMappings { + newClientRoleMappings: RoleMappingPayload[]; + oldClientRoleMappings: RoleMappingPayload[]; +} + +export enum AdminRoles { + ADMIN = 'ADMIN_ADMIN', +} diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.html new file mode 100644 index 0000000000000000000000000000000000000000..ef80c0f57a92cc1f284caa5b6b0afe83e6973f1d --- /dev/null +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.html @@ -0,0 +1,4 @@ +<p class="flex flex-col gap-0.5 text-text"> + <span class="font-medium">Benutzername</span> + <span>{{ userName }}</span> +</p> diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..f515c9412747b65e91386a3a5db676f2a6888271 --- /dev/null +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { UserFormDataNameComponent } from './user-form-data-name.component'; + +describe('UserFormDataNameComponent', () => { + let component: UserFormDataNameComponent; + let fixture: ComponentFixture<UserFormDataNameComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [UserFormDataNameComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(UserFormDataNameComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..931174e68ce1fc96a8e8301d79c93e8dbb8a80a6 --- /dev/null +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data-name/user-form-data-name.component.ts @@ -0,0 +1,10 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'admin-user-form-data-name', + standalone: true, + templateUrl: './user-form-data-name.component.html', +}) +export class UserFormDataNameComponent { + @Input() userName: string; +} diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.html index 430a3fde777062e005bab85507e57ef17883b311..830c7960ac97bb94267cdb6737d3a83001e44951 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.html @@ -2,7 +2,16 @@ <div class="mb-4 grid gap-4 xl:grid-cols-2"> <ods-text-editor [formControlName]="UserFormService.FIRST_NAME" [isRequired]="true" label="Vorname" /> <ods-text-editor [formControlName]="UserFormService.LAST_NAME" [isRequired]="true" label="Nachname" /> - <ods-text-editor [formControlName]="UserFormService.USERNAME" [isRequired]="true" label="Benutzername" /> + @if (isPatch) { + <admin-user-form-data-name [userName]="userName" data-test-id="user-name-info" /> + } @else { + <ods-text-editor + [formControlName]="UserFormService.USERNAME" + [isRequired]="true" + label="Benutzername" + data-test-id="user-name-editor" + /> + } <ods-text-editor [formControlName]="UserFormService.EMAIL" [isRequired]="true" label="E-Mail" /> </div> </div> diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.spec.ts index 40a8f3782988d250b27e9b7867c52eda96072b58..e8c6ef7d13ae82ecc182da1b50a0dac60d96c00f 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.spec.ts @@ -1,5 +1,7 @@ +import { existsAsHtmlElement } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { createUserFormGroup } from '../../../../test/form'; import { UserFormDataComponent } from './user-form-data.component'; @@ -7,6 +9,9 @@ describe('UserFormDataComponent', () => { let component: UserFormDataComponent; let fixture: ComponentFixture<UserFormDataComponent>; + const userNameInfoSelector: string = getDataTestIdOf('user-name-info'); + const userNameEditorSelector: string = getDataTestIdOf('user-name-editor'); + beforeEach(async () => { await TestBed.configureTestingModule({ imports: [UserFormDataComponent, ReactiveFormsModule], @@ -21,4 +26,25 @@ describe('UserFormDataComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('template', () => { + describe('user name', () => { + it('should show info', () => { + component.isPatch = true; + component.userName = 'ariane'; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, userNameInfoSelector); + }); + + it('should show editor', () => { + component.isPatch = false; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, userNameEditorSelector); + }); + }); + }); }); diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.ts index d40bee2ba526b9e7bb52d4f638bcb3f95f28095c..9bf2f6b95124810d75ee7676dadb60826cc55fc5 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-data/user-form-data.component.ts @@ -1,16 +1,19 @@ import { Component, Input } from '@angular/core'; import { ReactiveFormsModule, UntypedFormGroup } from '@angular/forms'; -import { CheckboxEditorComponent, TextEditorComponent } from '@ods/component'; +import { TextEditorComponent } from '@ods/component'; import { UserFormService } from '../user.formservice'; +import { UserFormDataNameComponent } from './user-form-data-name/user-form-data-name.component'; @Component({ selector: 'admin-user-form-data', standalone: true, - imports: [CheckboxEditorComponent, ReactiveFormsModule, TextEditorComponent], + imports: [ReactiveFormsModule, TextEditorComponent, UserFormDataNameComponent], templateUrl: './user-form-data.component.html', }) export class UserFormDataComponent { @Input() formGroupParent: UntypedFormGroup; + @Input() userName: string; + @Input() isPatch: boolean; public readonly UserFormService = UserFormService; } diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.html deleted file mode 100644 index b49a93cae8a97f0cf12a2e10c50abacc140ab8b6..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.html +++ /dev/null @@ -1 +0,0 @@ -<admin-delete-open-dialog-button /> \ No newline at end of file diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.spec.ts deleted file mode 100644 index ec691fc665e848da93f5c649141ec8d34c180e61..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { UserFormDeleteButtonContainerComponent } from './user-form-delete-button-container.component'; - -describe('UserFormDeleteButtonComponent', () => { - let component: UserFormDeleteButtonContainerComponent; - let fixture: ComponentFixture<UserFormDeleteButtonContainerComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [UserFormDeleteButtonContainerComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(UserFormDeleteButtonContainerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.ts deleted file mode 100644 index 2c66a5500b2e177a0f0a39aedad3f1ccd5e7e3e9..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-delete-button/user-form-delete-button-container.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { AdminDeleteOpenDialogButtonComponent } from '@admin-client/shared'; -import { DIALOG_COMPONENT } from '@alfa-client/ui'; -import { Component } from '@angular/core'; -import { UserDeleteDialogContainerComponent } from '../user-form-delete-dialog-container/user-delete-dialog-container.component'; - -@Component({ - selector: 'admin-user-form-delete-container-button', - standalone: true, - imports: [AdminDeleteOpenDialogButtonComponent], - providers: [{ provide: DIALOG_COMPONENT, useValue: UserDeleteDialogContainerComponent }], - templateUrl: './user-form-delete-button-container.component.html', -}) -export class UserFormDeleteButtonContainerComponent {} diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html index 129d8476634e65400913eb770ac3f6b9c9ff017a..1dda4319a297a47b72c1d1c8bc6e1401a796a7ee 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html @@ -1,23 +1,38 @@ <h2 class="heading-2 mt-4">Rollen für OZG-Cloud</h2> <div [formGroup]="formGroupParent"> - <div [formGroupName]="UserFormService.CLIENT_ROLES" class="mb-8 flex gap-56"> - <div [formGroupName]="UserFormService.ADMINISTRATION_GROUP" class="flex flex-col gap-2"> + <div [formGroupName]="UserFormService.CLIENT_ROLES" class="mb-8 flex flex-col gap-4 md:flex-row"> + <div [formGroupName]="UserFormService.ADMINISTRATION_GROUP" class="flex flex-1 flex-col gap-2"> <h3 class="text-md block font-medium text-text">Administration</h3> <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.ADMIN" label="Admin" inputId="admin" /> <button - tooltip='Wird nur in Kombination mit "User" verwendet. Diese Rolle kann Funktionen in Keycloak und der Administration konfigurieren, z.B. Benutzer anlegen, Gruppen erstellen bzw. Organisationseinheiten hinzufügen und Rollen zuweisen.' + data-test-id="admin-role-info-button" + tooltip="Diese Rolle kann Funktionen der OZG-Cloud konfigurieren, z.B. Benutzer anlegen, Organisationseinheiten hinzufügen und Rollen zuweisen." + > + <ods-info-icon /> + </button> + </div> + <div class="flex items-center gap-2"> + <ods-checkbox-editor + [formControlName]="UserFormService.DATENBEAUFTRAGUNG" + label="Datenbeauftragung" + inputId="datenbeauftragung" + /> + <button + data-test-id="datenbeauftragung-role-info-button" + tooltip='Diese Rolle kann in der Administration unter dem Menüpunkt "Statistik" Felder zur Auswertung konfigurieren. Sie ist mit allen anderen Rollen kompatibel.' > <ods-info-icon /> </button> </div> </div> - <div [formGroupName]="UserFormService.ALFA_GROUP" class="flex flex-col gap-2"> + <div [formGroupName]="UserFormService.ALFA_GROUP" class="flex flex-1 flex-col gap-2"> <h3 class="text-md block font-medium text-text">Alfa</h3> <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.LOESCHEN" label="Löschen" inputId="delete" /> <button - tooltip='Diese Rolle hat dieselben Rechte wie die Rolle "User". Zusätzlich kann "Löschen" ausgewählte Vorgänge aus Alfa löschen. Diese Rolle sollten zwei Benutzer haben, da das Löschen einem Vieraugen-Prinzip folgt.' + data-test-id="loschen-role-info-button" + tooltip='Diese Rolle hat dieselben Rechte wie die Rolle "User". Zusätzlich kann "Löschen" Löschanträge aus Alfa bestätigen. ' > <ods-info-icon /> </button> @@ -25,16 +40,15 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.USER" label="User" inputId="user" /> <button - tooltip='Diese Rolle kann alle Vorgänge sehen und bearbeiten, wenn diese seiner Organisationseinheit zugewiesen sind. Ist kompatibel mit "Löschen" und "Admin".' + data-test-id="user-role-info-button" + tooltip="Diese Rolle kann alle Vorgänge sehen und bearbeiten, wenn diese seiner Organisationseinheit zugewiesen sind." > <ods-info-icon /> </button> </div> <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.POSTSTELLE" label="Poststelle" inputId="post_office" /> - <button - tooltip='Diese Rolle kann ausschließlich alle neu eingegangenen Vorgänge sehen und anderen Benutzern zuweisen. Sie sollte nur einem Benutzer zugewiesen sein. Dieser sollte keine weiteren Rollen besitzen. (Sie ist aber kompatibel mit der "Admin")' - > + <button data-test-id="poststelle-role-info-button" tooltip="Diese Rolle kann alle neu eingegangenen Vorgänge sehen."> <ods-info-icon /> </button> </div> diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.html index 5ce59646fde16f7fd3299848b2615f318685e536..132dc6ba2c8eb40cfc12c0f163ba94092afca6a2 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.html @@ -25,17 +25,17 @@ --> <ods-spinner [stateResource]="userStateResource$ | async"> <div class="max-w-[960px]" data-test-id="user-content"> - <admin-user-form-headline [isPatch]="formService.isPatch()" /> - <admin-user-form-data [formGroupParent]="formService.form" /> + <admin-user-form-headline [isPatch]="isPatch" /> + <admin-user-form-data [formGroupParent]="formService.form" [isPatch]="isPatch" [userName]="userName" /> <admin-user-form-roles [formGroupParent]="formService.form" /> <admin-user-form-organisations-einheit-list [formGroupParent]="formService.form" [formGroupOrganisationsEinheiten]="formService.getOrganisationsEinheitenGroup()" /> - <div class="flex justify-between"> + <div class="mb-6 flex justify-between"> <admin-user-form-save-button /> - @if (formService.isPatch()) { - <admin-user-form-delete-container-button data-test-id="delete-button-container"/> + @if (isPatch) { + <admin-delete-open-dialog-button data-test-id="delete-button-container" /> } </div> </div> diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.spec.ts index 160ab43ceea91f4c2fd18bc37ca506e99edfa033..bbaa75605aa2bc1071ceba8302892ee5088be620 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.spec.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { AdminDeleteOpenDialogButtonComponent } from '@admin-client/shared'; import { User } from '@admin-client/user-shared'; import { createEmptyStateResource, createStateResource, StateResource } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, getMockComponent, mock, Mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; @@ -50,10 +51,12 @@ describe('UserFormComponent', () => { const userContent: string = getDataTestIdOf('user-content'); const deleteButtonContainer: string = getDataTestIdOf('delete-button-container'); + const userStateResource: StateResource<User> = createStateResource(createUser()); + beforeEach(async () => { formService = <any>{ ...mock(UserFormService), - get: jest.fn(), + get: jest.fn().mockReturnValue(of(userStateResource)), isInvalid: jest.fn(), form: new FormGroup({}), isPatch: jest.fn(), @@ -68,6 +71,7 @@ describe('UserFormComponent', () => { MockComponent(UserFormOrganisationsEinheitListComponent), MockComponent(UserFormRolesComponent), MockComponent(UserFormHeadlineComponent), + MockComponent(AdminDeleteOpenDialogButtonComponent), ], providers: [{ provide: DIALOG_COMPONENT, useValue: {} }], }) @@ -94,10 +98,11 @@ describe('UserFormComponent', () => { describe('component', () => { describe('on init', () => { - const userStateResource: StateResource<User> = createStateResource(createUser()); + const userName: string = 'ariane'; beforeEach(() => { - formService.get.mockReturnValue(of(userStateResource)); + formService.isPatch.mockReturnValue(true); + formService.getUserName.mockReturnValue(userName); }); it('should call formservice to get user', () => { @@ -113,13 +118,39 @@ describe('UserFormComponent', () => { expect(component.userStateResource$).toBeObservable(cold('(a|)', { a: userStateResource })); }); + + it('should call formservice to get is patch', () => { + component.ngOnInit(); + + expect(formService.isPatch).toHaveBeenCalled(); + }); + + it('should set is patch', () => { + component.ngOnInit(); + fixture.detectChanges(); + + expect(component.isPatch).toBe(true); + }); + + it('should call formservice to get user name', () => { + component.ngOnInit(); + + expect(formService.getUserName).toHaveBeenCalled(); + }); + + it('should set user name', () => { + component.ngOnInit(); + fixture.detectChanges(); + + expect(component.userName).toBe(userName); + }); }); }); describe('template', () => { describe('admin headline', () => { it('should exist with input', () => { - formService.isPatch.mockReturnValue(true); + component.isPatch = true; fixture.detectChanges(); @@ -131,8 +162,15 @@ describe('UserFormComponent', () => { describe('admin data', () => { it('should exist with input', () => { const formDataComponent: UserFormDataComponent = getMockComponent(fixture, UserFormDataComponent); + const userName: string = 'testUser'; + component.isPatch = true; + component.userName = userName; + + fixture.detectChanges(); expect(formDataComponent.formGroupParent).toBe(component.formService.form); + expect(formDataComponent.isPatch).toBeTruthy(); + expect(formDataComponent.userName).toBe(userName); }); }); @@ -170,7 +208,7 @@ describe('UserFormComponent', () => { describe('admin delete button container', () => { it('should exist', () => { - formService.isPatch.mockReturnValue(true); + component.isPatch = true; fixture.detectChanges(); @@ -178,7 +216,7 @@ describe('UserFormComponent', () => { }); it('should not exist', () => { - formService.isPatch.mockReturnValue(false); + component.isPatch = false; fixture.detectChanges(); diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.ts b/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.ts index a533ff55e37698883943902df16183dc776b22c2..f60e03692eed409a960bdeb3b27caa64b12d1ef9 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form.component.ts @@ -21,15 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { AdminDeleteOpenDialogButtonComponent } from '@admin-client/shared'; import { User } from '@admin-client/user-shared'; import { StateResource } from '@alfa-client/tech-shared'; +import { DIALOG_COMPONENT } from '@alfa-client/ui'; import { AsyncPipe } from '@angular/common'; import { Component, inject, OnInit } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { SpinnerComponent } from '@ods/component'; -import { Observable } from 'rxjs'; +import { Observable, tap } from 'rxjs'; import { UserFormDataComponent } from './user-form-data/user-form-data.component'; -import { UserFormDeleteButtonContainerComponent } from './user-form-delete-button/user-form-delete-button-container.component'; +import { UserDeleteDialogContainerComponent } from './user-form-delete-dialog-container/user-delete-dialog-container.component'; import { UserFormHeadlineComponent } from './user-form-headline/user-form-headline.component'; import { UserFormOrganisationsEinheitListComponent } from './user-form-organisations-einheit-list/user-form-organisations-einheit-list.component'; import { UserFormRolesComponent } from './user-form-roles/user-form-roles.component'; @@ -38,7 +40,7 @@ import { UserFormService } from './user.formservice'; @Component({ selector: 'admin-user-form', - providers: [UserFormService], + providers: [UserFormService, { provide: DIALOG_COMPONENT, useValue: UserDeleteDialogContainerComponent }], templateUrl: './user-form.component.html', standalone: true, imports: [ @@ -51,15 +53,22 @@ import { UserFormService } from './user.formservice'; UserFormOrganisationsEinheitListComponent, UserFormHeadlineComponent, UserFormSaveButtonComponent, - UserFormDeleteButtonContainerComponent, + AdminDeleteOpenDialogButtonComponent, ], }) export class UserFormComponent implements OnInit { public readonly formService = inject(UserFormService); public userStateResource$: Observable<StateResource<User>>; + public isPatch: boolean; + public userName: string; ngOnInit(): void { - this.userStateResource$ = this.formService.get(); + this.userStateResource$ = this.formService.get().pipe( + tap(() => { + this.isPatch = this.formService.isPatch(); + this.userName = this.formService.getUserName(); + }), + ); } } diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts index 724564f208c9f26cb6265da1bbad81b52ad92b13..99e28aabc946516a2076a89eb850c1df7b5594cd 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.spec.ts @@ -26,18 +26,14 @@ import { ROUTES } from '@admin-client/shared'; import { User, UserService } from '@admin-client/user-shared'; import { PatchConfig } from '@admin/keycloak-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { - createEmptyStateResource, - createLoadingStateResource, - createStateResource, - StateResource, -} from '@alfa-client/tech-shared'; +import { createEmptyStateResource, createLoadingStateResource, createStateResource, StateResource, } from '@alfa-client/tech-shared'; import { Mock, mock, mockWindowError } from '@alfa-client/test-utils'; import { SnackBarService } from '@alfa-client/ui'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { AbstractControl, FormControl, FormGroup, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { ActivatedRoute, UrlSegment } from '@angular/router'; import { faker } from '@faker-js/faker/locale/de'; +import { expect } from '@jest/globals'; import { cold } from 'jest-marbles'; import { createUser } from 'libs/admin/user-shared/test/user'; import { Observable, of, throwError } from 'rxjs'; @@ -45,7 +41,6 @@ import { createUrlSegment } from '../../../../../navigation-shared/test/navigati import { singleCold, singleColdCompleted, singleHot } from '../../../../../tech-shared/test/marbles'; import { createAdminOrganisationsEinheit } from '../../../../organisations-einheit-shared/src/test/organisations-einheit'; import { UserFormService } from './user.formservice'; - import SpyInstance = jest.SpyInstance; describe('UserFormService', () => { @@ -152,6 +147,14 @@ describe('UserFormService', () => { }); describe('listenToAlfaGroupChanges', () => { + it('should call handleAlfaGroupChange on initial change', () => { + formService._handleAlfaGroupChange = jest.fn(); + + formService.listenToAlfaGroupChanges(); + + expect(formService._handleAlfaGroupChange).toHaveBeenCalled(); + }); + it('should call handleAlfaGroupChange when value of form element changes', fakeAsync(() => { formService._handleAlfaGroupChange = jest.fn(); @@ -481,6 +484,14 @@ describe('UserFormService', () => { expect(formService._initOrganisationsEinheiten$.unsubscribe).toHaveBeenCalled(); }); + + it('should unsubscribe from initOrganisationsEinheiten$', () => { + formService._alfaGroupChanges.unsubscribe = jest.fn(); + + formService.ngOnDestroy(); + + expect(formService._alfaGroupChanges.unsubscribe).toHaveBeenCalled(); + }); }); describe('get userName', () => { diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts index 3d0960b1d363fe87688c1c9fd07f7b61ddefc67c..666d4d192605be0c6e14cca6008225b86570e1d5 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts +++ b/alfa-client/libs/admin/user/src/lib/user-form/user.formservice.ts @@ -23,21 +23,13 @@ */ import { AdminOrganisationsEinheit, AdminOrganisationsEinheitService } from '@admin-client/organisations-einheit-shared'; import { ROUTES } from '@admin-client/shared'; -import { User, UserService } from '@admin-client/user-shared'; +import { AdminRoles, User, UserService } from '@admin-client/user-shared'; import { KeycloakFormService, PatchConfig } from '@admin/keycloak-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { createEmptyStateResource, EMPTY_STRING, isLoaded, mapToResource, StateResource } from '@alfa-client/tech-shared'; import { SnackBarService } from '@alfa-client/ui'; import { Injectable, OnDestroy } from '@angular/core'; -import { - AbstractControl, - FormControl, - UntypedFormBuilder, - UntypedFormGroup, - ValidationErrors, - ValidatorFn, - Validators, -} from '@angular/forms'; +import { AbstractControl, FormControl, UntypedFormBuilder, UntypedFormGroup, ValidationErrors, ValidatorFn, Validators, } from '@angular/forms'; import { UrlSegment } from '@angular/router'; import { catchError, filter, Observable, of, Subscription, tap } from 'rxjs'; @@ -51,13 +43,15 @@ export class UserFormService extends KeycloakFormService<User> implements OnDest public static readonly CLIENT_ROLES: string = 'clientRoles'; public static readonly GROUPS: string = 'groups'; public static readonly ADMINISTRATION_GROUP: string = 'admin'; - public static readonly ADMIN: string = 'ADMIN_ADMIN'; + public static readonly ADMIN: string = AdminRoles.ADMIN; + public static readonly DATENBEAUFTRAGUNG: string = 'DATENBEAUFTRAGUNG'; public static readonly ALFA_GROUP: string = 'alfa'; public static readonly LOESCHEN: string = 'VERWALTUNG_LOESCHEN'; public static readonly USER: string = 'VERWALTUNG_USER'; public static readonly POSTSTELLE: string = 'VERWALTUNG_POSTSTELLE'; _initOrganisationsEinheiten$: Subscription; + _alfaGroupChanges: Subscription; _organisationsEinheitToGroupIdMap: Map<string, string> = new Map<string, string>(); @@ -100,6 +94,7 @@ export class UserFormService extends KeycloakFormService<User> implements OnDest { [UserFormService.ADMINISTRATION_GROUP]: this.formBuilder.group({ [UserFormService.ADMIN]: new FormControl(false), + [UserFormService.DATENBEAUFTRAGUNG]: new FormControl(false), }), [UserFormService.ALFA_GROUP]: this.formBuilder.group({ [UserFormService.LOESCHEN]: new FormControl(false), @@ -161,9 +156,10 @@ export class UserFormService extends KeycloakFormService<User> implements OnDest }); } - protected listenToAlfaGroupChanges(): void { + listenToAlfaGroupChanges(): void { const alfaGroup: UntypedFormGroup = this.getRoleGroup(UserFormService.ALFA_GROUP); - alfaGroup.valueChanges.subscribe(() => { + this._handleAlfaGroupChange(alfaGroup); + this._alfaGroupChanges = alfaGroup.valueChanges.subscribe(() => { this._handleAlfaGroupChange(alfaGroup); }); } @@ -183,7 +179,7 @@ export class UserFormService extends KeycloakFormService<User> implements OnDest _disableUncheckedCheckboxes(alfaGroup: UntypedFormGroup): void { for (const control of Object.values<AbstractControl>(alfaGroup.controls)) { - if (control.value === false) control.disable({ emitEvent: false }); + if (!control.value) control.disable({ emitEvent: false }); } } @@ -263,6 +259,7 @@ export class UserFormService extends KeycloakFormService<User> implements OnDest ngOnDestroy(): void { this._initOrganisationsEinheiten$.unsubscribe(); + this._alfaGroupChanges.unsubscribe(); } public getUserName(): string { diff --git a/alfa-client/libs/admin/user/test/form.ts b/alfa-client/libs/admin/user/test/form.ts index 7b3f06850de1ff16504596b38056fb3752b3d5e5..d8ac4bb73c5b96a51e5559e85d8876a1695506aa 100644 --- a/alfa-client/libs/admin/user/test/form.ts +++ b/alfa-client/libs/admin/user/test/form.ts @@ -12,6 +12,7 @@ export function createUserFormGroup(): UntypedFormGroup { [UserFormService.CLIENT_ROLES]: new UntypedFormGroup({ [UserFormService.ADMINISTRATION_GROUP]: new UntypedFormGroup({ [UserFormService.ADMIN]: new FormControl(false), + [UserFormService.DATENBEAUFTRAGUNG]: new FormControl(false), }), [UserFormService.ALFA_GROUP]: new UntypedFormGroup({ [UserFormService.LOESCHEN]: new FormControl(false), diff --git a/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts b/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts index 1ea618d47d18ed73a95030929bf0d581d41d3c6c..9d89989e6f5eb294ee5d7215b881a2584f3490db 100644 --- a/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts +++ b/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts @@ -46,6 +46,9 @@ export enum ApiRootLinkRel { ALLE_VORGAENGE_ABGESCHLOSSEN = 'vorgaenge_abgeschlossen_all', MEINE_VORGAENGE_ABGESCHLOSSEN = 'vorgaenge_abgeschlossen_my', UNASSIGNED_ABGESCHLOSSEN = 'vorgaenge_abgeschlossen_unassigned', + ALLE_VORGAENGE_WEITERGELEITET = 'vorgaenge_weitergeleitet_all', + MEINE_VORGAENGE_WEITERGELEITET = 'vorgaenge_weitergeleitet_my', + UNASSIGNED_WEITERGELEITET = 'vorgaenge_weitergeleitet_unassigned', ALLE_VORGAENGE_VERWORFEN = 'vorgaenge_verworfen_all', MEINE_VORGAENGE_VERWORFEN = 'vorgaenge_verworfen_my', UNASSIGNED_VERWORFEN = 'vorgaenge_verworfen_unassigned', diff --git a/alfa-client/libs/authentication/src/lib/authentication.service.spec.ts b/alfa-client/libs/authentication/src/lib/authentication.service.spec.ts index 486415f425de82475e9733ec3f5800cb47128c92..0e2ba5d44dd5054b2fa2b0e651b8205cf0327258 100644 --- a/alfa-client/libs/authentication/src/lib/authentication.service.spec.ts +++ b/alfa-client/libs/authentication/src/lib/authentication.service.spec.ts @@ -23,10 +23,11 @@ */ import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { UserProfileResource } from '@alfa-client/user-profile-shared'; +import { NavigationEnd, Router } from '@angular/router'; import { AuthConfig, OAuthEvent, OAuthService } from 'angular-oauth2-oidc'; import { Environment } from 'libs/environment-shared/src/lib/environment.model'; import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile'; -import { Subject } from 'rxjs'; +import { of, Subject } from 'rxjs'; import { createEnvironment } from '../../../environment-shared/test/environment'; import { createAuthConfig, createOAuthEvent } from '../../test/authentication'; import { AuthenticationService } from './authentication.service'; @@ -34,6 +35,7 @@ import { AuthenticationService } from './authentication.service'; describe('AuthenticationService', () => { let service: AuthenticationService; let oAuthService: Mock<OAuthService>; + let router: Mock<Router>; let environmentConfig: Environment; let eventsSubject: Subject<OAuthEvent>; @@ -41,6 +43,7 @@ describe('AuthenticationService', () => { beforeEach(() => { eventsSubject = new Subject<OAuthEvent>(); + router = mock(Router); oAuthService = <any>{ ...mock(OAuthService), loadDiscoveryDocumentAndLogin: jest.fn().mockResolvedValue(() => Promise.resolve()), @@ -50,12 +53,19 @@ describe('AuthenticationService', () => { Object.defineProperty(oAuthService, 'events', { get: () => eventsSubject }); environmentConfig = createEnvironment(); - service = new AuthenticationService(useFromMock(oAuthService), environmentConfig); + service = new AuthenticationService(useFromMock(oAuthService), useFromMock(router), environmentConfig); }); describe('login', () => { beforeEach(() => { service.buildAuthEventPromise = jest.fn(); + service._initialNavigationIsDone = jest.fn().mockResolvedValue(() => Promise.resolve()); + }); + + it('should wait for initial navigation', async () => { + await service.login(); + + expect(service._initialNavigationIsDone).toHaveBeenCalled(); }); it('should configure service with authConfig', async () => { @@ -89,8 +99,8 @@ describe('AuthenticationService', () => { expect(service.buildAuthEventPromise).toHaveBeenCalled(); }); - it('should load discovery document and login', () => { - service.login(); + it('should load discovery document and login', async () => { + await service.login(); expect(oAuthService.loadDiscoveryDocumentAndLogin).toHaveBeenCalled(); }); @@ -105,6 +115,16 @@ describe('AuthenticationService', () => { }); }); + describe('_initialNavigationIsDone', () => { + it('should wait for navigation end event', async () => { + (router.events as any) = of(new NavigationEnd(0, 'url1', 'url1')); + + const promise: Promise<void> = service._initialNavigationIsDone(); + + await expect(promise).resolves.toBeUndefined(); + }); + }); + describe('build auth event promise', () => { const event: OAuthEvent = createOAuthEvent(); @@ -350,4 +370,20 @@ describe('AuthenticationService', () => { expect(oAuthService.revokeTokenAndLogout).toHaveBeenCalled(); }); }); + + describe('isLoggedIn', () => { + it('should call oAuthService hasValidAccessToken', () => { + service.isLoggedIn(); + + expect(oAuthService.hasValidAccessToken).toHaveBeenCalled(); + }); + + it('should return result', () => { + oAuthService.hasValidAccessToken.mockReturnValue(true); + + const isLoggedIn: boolean = service.isLoggedIn(); + + expect(isLoggedIn).toBe(true); + }); + }); }); diff --git a/alfa-client/libs/authentication/src/lib/authentication.service.ts b/alfa-client/libs/authentication/src/lib/authentication.service.ts index e350dcafe7cb9312799db97db5eb50c0d25c8319..4918b8f8d7e95c9ff71b2c53a7aa487266e91155 100644 --- a/alfa-client/libs/authentication/src/lib/authentication.service.ts +++ b/alfa-client/libs/authentication/src/lib/authentication.service.ts @@ -23,11 +23,12 @@ */ import { Environment, ENVIRONMENT_CONFIG } from '@alfa-client/environment-shared'; import { Inject, Injectable } from '@angular/core'; +import { NavigationEnd, Router } from '@angular/router'; import { AuthConfig, OAuthEvent, OAuthService } from 'angular-oauth2-oidc'; import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks'; import { UserProfileResource } from 'libs/user-profile-shared/src/lib/user-profile.model'; import { getUserNameInitials } from 'libs/user-profile-shared/src/lib/user-profile.util'; -import { filter, Subscription } from 'rxjs'; +import { filter, firstValueFrom, Subscription } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class AuthenticationService { @@ -37,10 +38,13 @@ export class AuthenticationService { constructor( private oAuthService: OAuthService, + private router: Router, @Inject(ENVIRONMENT_CONFIG) private envConfig: Environment, ) {} public async login(): Promise<void> { + await this._initialNavigationIsDone(); + this.oAuthService.configure(this.buildConfiguration()); this.oAuthService.setupAutomaticSilentRefresh(); this.oAuthService.tokenValidationHandler = new JwksValidationHandler(); @@ -50,6 +54,10 @@ export class AuthenticationService { return eventPromise; } + async _initialNavigationIsDone(): Promise<void> { + await firstValueFrom(this.router.events.pipe(filter((event) => event instanceof NavigationEnd))); + } + buildAuthEventPromise(): Promise<void> { return new Promise<void>((resolve, reject) => this.handleAuthEventsForPromise(resolve, reject)); } @@ -90,7 +98,7 @@ export class AuthenticationService { return { issuer: this.envConfig.authServer + '/realms/' + this.envConfig.realm, tokenEndpoint: this.envConfig.authServer + '/realms/' + this.envConfig.realm + '/protocol/openid-connect/token', - redirectUri: window.location.origin + '/', + redirectUri: window.location.origin + window.location.pathname, clientId: this.envConfig.clientId, scope: 'openid profile', requireHttps: false, @@ -119,4 +127,8 @@ export class AuthenticationService { public logout(): void { this.oAuthService.revokeTokenAndLogout(); } + + public isLoggedIn(): boolean { + return this.oAuthService.hasValidAccessToken(); + } } diff --git a/alfa-client/libs/bescheid-shared/src/index.ts b/alfa-client/libs/bescheid-shared/src/index.ts index 51f69102aff5c73708f9145fed53b74a98f91ce2..e847b8792390c501ad6da3f257442992ff9e5806 100644 --- a/alfa-client/libs/bescheid-shared/src/index.ts +++ b/alfa-client/libs/bescheid-shared/src/index.ts @@ -21,6 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +export * from './lib/bescheid-list-resource-service'; +export * from './lib/bescheid-resource-service'; export * from './lib/bescheid-shared.module'; export * from './lib/bescheid.linkrel'; export * from './lib/bescheid.model'; diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid-list-resource-service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid-list-resource-service.ts new file mode 100644 index 0000000000000000000000000000000000000000..43b427dd4e8975e8ac0d3d6211a2957c14b99671 --- /dev/null +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid-list-resource-service.ts @@ -0,0 +1,25 @@ +import { ListResourceServiceConfig, ResourceListService, ResourceRepository } from '@alfa-client/tech-shared'; +import { VorgangService, VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { BescheidListLinkRel } from './bescheid.linkrel'; +import { BescheidListResource, BescheidResource } from './bescheid.model'; + +export class BescheidListResourceService extends ResourceListService< + VorgangWithEingangResource, + BescheidListResource, + BescheidResource +> {} + +export function createBescheidListResourceService( + repository: ResourceRepository<BescheidResource>, + vorgangService: VorgangService, +): ResourceListService<VorgangWithEingangResource, BescheidListResource, BescheidResource> { + return new BescheidListResourceService(buildBescheidListServiceConfig(vorgangService), repository); +} + +function buildBescheidListServiceConfig(vorgangService: VorgangService): ListResourceServiceConfig<VorgangWithEingangResource> { + return { + baseResource: vorgangService.getVorgangWithEingang(), + listLinkRel: VorgangWithEingangLinkRel.BESCHEIDE, + listResourceListLinkRel: BescheidListLinkRel.BESCHEID_LIST, + }; +} diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts index e3722e0383e87b6f44e022873498f51631e2246b..ae974499af8180747f7915423b75c4e91a4a48a5 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts @@ -21,671 +21,572 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BinaryFileListResource, BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared'; -import { CommandOrder, CommandResource, CommandService, CreateCommandProps } from '@alfa-client/command-shared'; +import { + BinaryFileListLinkRel, + BinaryFileListResource, + BinaryFileResource, + BinaryFileService, +} from '@alfa-client/binary-file-shared'; +import { + CommandOrder, + CommandResource, + CommandResourceService, + CommandService, + CreateCommandProps, + getEffectedResourceUrl, +} from '@alfa-client/command-shared'; import { PostfachService } from '@alfa-client/postfach-shared'; import { - ApiError, - EMPTY_STRING, - HttpError, - ResourceRepository, - StateResource, - StateService, createEmptyStateResource, createErrorStateResource, createStateResource, + EMPTY_STRING, + getEmbeddedResources, + ResourceListService, + ResourceRepository, + StateResource, } from '@alfa-client/tech-shared'; -import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; -import { - VorgangCommandService, - VorgangService, - VorgangWithEingangLinkRel, - VorgangWithEingangResource, -} from '@alfa-client/vorgang-shared'; -import { fakeAsync, tick } from '@angular/core/testing'; +import { Mock, mock } from '@alfa-client/test-utils'; +import { VorgangCommandService, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; -import { ResourceUri, getUrl } from '@ngxp/rest'; -import { cold } from 'jest-marbles'; +import { getUrl, LinkRel, ResourceUri } from '@ngxp/rest'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { createApiError } from 'libs/tech-shared/test/error'; +import { createProblemDetail } from 'libs/tech-shared/test/error'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; -import { Observable, first, of } from 'rxjs'; +import { EMPTY, Observable, of } from 'rxjs'; +import { createBinaryFileListResource, createBinaryFileResource } from '../../../binary-file-shared/test/binary-file'; import { - createBinaryFileListResource, - createBinaryFileResource, -} from '../../../binary-file-shared/test/binary-file'; -import { - createCommandErrorResource, + createCommandErrorStateResource, createCommandResource, createCommandStateResource, createCreateCommandProps, + createSuccessfullyDoneCommandStateResource, } from '../../../command-shared/test/command'; import { createFile } from '../../../tech-shared/test/file'; import { singleCold, singleColdCompleted } from '../../../tech-shared/test/marbles'; -import { - createBescheid, - createBescheidListResource, - createBescheidResource, - createBescheidStateResource, - createUploadFileInProgress, -} from '../test/bescheid'; +import { createBescheid, createBescheidDocument, createBescheidListResource, createBescheidResource } from '../test/bescheid'; import { createDocumentResource } from '../test/document'; import { BescheidFacade } from './+state/bescheid.facade'; import { BescheidLinkRel } from './bescheid.linkrel'; import { Bescheid, + BESCHEID_UPLOADED_ATTACHMENTS, + BescheidDocument, BescheidListResource, BescheidResource, BescheidStatus, BescheidWizardStep, - UploadFileInProgress, + createEmptyBescheidDocument, + createEmptyUploadInProgress, + createInitialWizard, } from './bescheid.model'; import { BescheidService } from './bescheid.service'; import { DocumentLinkRel } from './document.linkrel'; import { DocumentResource } from './document.model'; +import { + BescheidListResourceService, + BescheidResourceService, + buildCreateBescheidDocumentFromFileProps, + buildUpdateBescheidCommandProps, + createBescheidListResourceService, + createBescheidResourceService, +} from '@alfa-client/bescheid-shared'; +import { expect } from '@jest/globals'; +import { cold } from 'jest-marbles'; import * as DateUtil from '../../../tech-shared/src/lib/date.util'; -import * as BescheidUtil from './bescheid.util'; + +jest.mock('@alfa-client/bescheid-shared', () => { + const originalModule = jest.requireActual('@alfa-client/bescheid-shared'); + + return { + __esModule: true, + ...originalModule, + createBescheidResourceService: jest.fn(), + createBescheidListResourceService: jest.fn(), + buildUpdateBescheidCommandProps: jest.fn(), + buildCreateBescheidDocumentFromFileProps: jest.fn(), + }; +}); describe('BescheidService', () => { let service: BescheidService; - let facade: Mock<BescheidFacade>; let vorgangService: Mock<VorgangService>; - let resourceRepository: Mock<ResourceRepository<BescheidResource>>; + let resourceRepository: Mock<ResourceRepository>; let commandService: Mock<CommandService>; let vorgangCommandService: Mock<VorgangCommandService>; let binaryFileService: Mock<BinaryFileService>; - let stateService: Mock<StateService>; let postfachService: Mock<PostfachService>; + let bescheidResourceService: Mock<BescheidResourceService>; + let bescheidListResourceService: Mock<BescheidListResourceService>; - const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = createStateResource( - createVorgangWithEingangResource(), - ); + const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); + const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = + createStateResource(vorgangWithEingangResource); + const bescheidResource: BescheidResource = createBescheidResource(); + const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); beforeEach(() => { facade = mock(BescheidFacade); resourceRepository = mock(ResourceRepository); commandService = mock(CommandService); vorgangCommandService = mock(VorgangCommandService); - stateService = mock(StateService); - vorgangService = mock(VorgangService); vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangWithEingangStateResource)); binaryFileService = mock(BinaryFileService); postfachService = mock(PostfachService); - - service = new BescheidService( - useFromMock(facade), - useFromMock(vorgangService), - useFromMock(commandService), - useFromMock(vorgangCommandService), - useFromMock(binaryFileService), - useFromMock(resourceRepository), - useFromMock(postfachService), - useFromMock(stateService), - ); + bescheidResourceService = mock(CommandResourceService); + bescheidListResourceService = mock(ResourceListService); + (createBescheidResourceService as jest.Mock).mockReturnValue(bescheidResourceService); + (createBescheidListResourceService as jest.Mock).mockReturnValue(bescheidListResourceService); + + TestBed.configureTestingModule({ + providers: [ + { provide: BescheidFacade, useValue: facade }, + { provide: VorgangService, useValue: vorgangService }, + { provide: ResourceRepository, useValue: resourceRepository }, + { provide: CommandService, useValue: commandService }, + { provide: VorgangCommandService, useValue: vorgangCommandService }, + { provide: BinaryFileService, useValue: binaryFileService }, + { + provide: PostfachService, + useValue: postfachService, + }, + BescheidService, + ], + }); + + service = TestBed.inject(BescheidService); }); it('should be created', () => { expect(service).toBeTruthy(); }); - describe('getActiveStep', () => { - it('should emit initial value', () => { - const activeStep$: Observable<number> = service.getActiveStep(); - - expect(activeStep$).toBeObservable(singleCold(BescheidWizardStep.AntragBescheiden)); - }); - }); + describe('init', () => { + it('should init state', () => { + service.setActiveStep(2); - describe('setActiveStep', () => { - it('should emit changed active step', () => { - service.setActiveStep(BescheidWizardStep.DokumenteHochladen); + service.init(); - expect(service.activeStep$).toBeObservable(singleCold(BescheidWizardStep.DokumenteHochladen)); + expect(service.getWizard()).toBeObservable(singleCold(createInitialWizard())); + expect(service.getActiveStep()).toBeObservable(singleCold(BescheidWizardStep.AntragBescheiden)); + expect(service.getBescheidCreated()).toBeObservable(singleCold(false)); + expect(service.getBescheidDocument()).toBeObservable(singleCold(createEmptyBescheidDocument())); }); }); - describe('get bescheid draft', () => { - const bescheidDraft: BescheidResource = createBescheidResource(); - const bescheidDraftStateResource: StateResource<BescheidResource> = createStateResource(bescheidDraft); - - it('should call resource service', () => { - service.bescheidResourceService.get = jest.fn(); + describe('exit', () => { + beforeEach(() => { + service._clearUploadedFiles = jest.fn(); + }); - service.getBescheidDraft(); + it('should reload bescheid list', () => { + service.exit(); - expect(service.bescheidResourceService.get).toHaveBeenCalled(); + expect(bescheidListResourceService.refresh).toHaveBeenCalled(); }); - it('should return value', () => { - service.bescheidResourceService.get = jest.fn().mockReturnValue(singleCold(bescheidDraftStateResource)); - - const bescheidStateResource$: Observable<StateResource<BescheidResource>> = service.getBescheidDraft(); + it('should reload postfach list', () => { + service.exit(); - expect(bescheidStateResource$).toBeObservable(singleCold(bescheidDraftStateResource)); + expect(postfachService._setPostfachMailOnReload).toHaveBeenCalled(); }); - }); - describe('getBescheidCommand', () => { - it('should call facade', () => { - service.getBescheidCommand(); + it('should clear uploaded files', () => { + service.exit(); - expect(facade.getBescheidCommand).toHaveBeenCalled(); + expect(service._clearUploadedFiles).toHaveBeenCalled(); }); }); - describe('createBescheid', () => { - const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource(); - const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - const commandStateResource: StateResource<CommandResource> = createStateResource(command); - + describe('skipBescheidCreation', () => { beforeEach(() => { - facade.getBescheidCommand.mockReturnValue(of(commandStateResource)); - service.bescheidResourceService.loadByResourceUri = jest.fn(); + service.deleteBescheidAndCompleteVorgang = jest.fn().mockReturnValue(of(commandStateResource)); }); - it('should call facade', () => { - service.createBescheid(vorgangWithEingang).subscribe(); + it('should complete vorgang', () => { + service.skipBescheidCreation(vorgangWithEingangResource, null); - expect(facade.createBescheidDraft).toHaveBeenCalledWith(vorgangWithEingang, { - order: CommandOrder.CREATE_BESCHEID, - body: null, - }); + expect(vorgangCommandService.abschliessen).toHaveBeenCalledWith(vorgangWithEingangResource); }); - it('should set resource by uri', () => { - service.createBescheid(vorgangWithEingang).subscribe(); + it('should NOT complete vorgang', () => { + service.skipBescheidCreation(vorgangWithEingangResource, bescheidResource); - expect(service.bescheidResourceService.loadByResourceUri).toHaveBeenCalledWith( - getUrl(command, CommandLinkRel.EFFECTED_RESOURCE), - ); + expect(vorgangCommandService.abschliessen).not.toHaveBeenCalled(); }); - }); - - describe('bescheidErstellungUeberspringen', () => { - describe('Bescheid Draft exists', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); - - const bescheidResource: BescheidResource = createBescheidResource(); - const bescheidStateResource: StateResource<BescheidResource> = createStateResource(bescheidResource); - - const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); - - beforeEach(() => { - service.existsBescheidDraft = jest.fn().mockReturnValue(true); - service.getBescheidDraft = jest.fn().mockReturnValue(of(bescheidStateResource)); - service.bescheidLoeschenUndErstellungUeberspringen = jest.fn().mockReturnValue(of(commandStateResource)); - }); - - it('should get bescheid draft', (done) => { - const command$: Observable<StateResource<CommandResource>> = - service.bescheidErstellungUeberspringen(vorgangWithEingangResource); - - command$.subscribe(() => { - expect(service.getBescheidDraft).toHaveBeenCalled(); - done(); - }); - }); - - it('should Bescheid löschen und Erstellung überspringen', (done) => { - const command$: Observable<StateResource<CommandResource>> = - service.bescheidErstellungUeberspringen(vorgangWithEingangResource); - - command$.subscribe(() => { - expect(service.bescheidLoeschenUndErstellungUeberspringen).toHaveBeenCalledWith( - vorgangWithEingangResource, - ); - done(); - }); - }); - it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = - service.bescheidErstellungUeberspringen(vorgangWithEingangResource); + it('should delete bescheid and complete vorgang', () => { + service.skipBescheidCreation(vorgangWithEingangResource, bescheidResource).subscribe(); - expect(command$).toBeObservable(singleColdCompleted(commandStateResource)); - }); + expect(service.deleteBescheidAndCompleteVorgang).toHaveBeenCalledWith(vorgangWithEingangResource); }); - describe('Bescheid Draft not exists', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); - const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); - - beforeEach(() => { - service.existsBescheidDraft = jest.fn().mockReturnValue(false); - service.vorgangAbschliesen = jest.fn().mockReturnValue(of(commandStateResource)); - }); - - it('should call vorgang abschliessen', (done) => { - const command$: Observable<StateResource<CommandResource>> = - service.bescheidErstellungUeberspringen(vorgangWithEingangResource); - - command$.subscribe(() => { - expect(service.vorgangAbschliesen).toHaveBeenCalledWith(vorgangWithEingangResource); - done(); - }); - }); - - it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = - service.bescheidErstellungUeberspringen(vorgangWithEingangResource); + it('should return command', () => { + const command$: Observable<StateResource<CommandResource>> = service.skipBescheidCreation( + vorgangWithEingangResource, + bescheidResource, + ); - expect(command$).toBeObservable(singleColdCompleted(commandStateResource)); - }); + expect(command$).toBeObservable(singleColdCompleted(commandStateResource)); }); }); - describe('getBescheidDraftIfExists', () => { - let vorgangStateResource: StateResource<VorgangWithEingangResource>; - let bescheidStateResource: StateResource<BescheidResource>; - + describe('deleteBescheidAndCompleteVorgang', () => { beforeEach(() => { - vorgangStateResource = createStateResource(createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT])); - bescheidStateResource = createBescheidStateResource(); - vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangStateResource)); - service.getBescheidDraft = jest.fn().mockReturnValue(of(bescheidStateResource)); - }); - - it('should get vorgang with eingang', () => { - service.getBescheidDraftIfExists(); - - expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled(); + service.deleteBescheid = jest.fn().mockReturnValue(of(createCommandStateResource)); + vorgangCommandService.abschliessen.mockReturnValue(EMPTY); }); - it('should emit state resources', () => { - const bescheid$: Observable<StateResource<BescheidResource>> = service.getBescheidDraftIfExists(); + it('should complete vorgang', () => { + service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - expect(bescheid$).toBeObservable(cold('(ab|)', { a: createEmptyStateResource(), b: bescheidStateResource })); + expect(vorgangCommandService.abschliessen).toHaveBeenCalledWith(vorgangWithEingangResource); }); - }); - describe('bescheidLoeschenUndErstellungUeberspringen', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); - const bescheidResource: BescheidResource = createBescheidResource(); - const vorgangAbschliessenCommandStateResource: StateResource<CommandResource> = createCommandStateResource(); + it('should delete bescheid', () => { + vorgangCommandService.abschliessen.mockReturnValue(of(createSuccessfullyDoneCommandStateResource())); - beforeEach(() => { - service.vorgangAbschliesen = jest.fn().mockReturnValue(of(vorgangAbschliessenCommandStateResource)); - service.deleteBescheid = jest.fn().mockReturnValue(of(createCommandStateResource)); - }); + service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - it('should Bescheiderstellung überspringen', (done) => { - const command$: Observable<StateResource<CommandResource>> = - service.bescheidLoeschenUndErstellungUeberspringen(vorgangWithEingangResource); - - command$.subscribe(() => { - expect(service.vorgangAbschliesen).toHaveBeenCalledWith(vorgangWithEingangResource); - done(); - }); + expect(service.deleteBescheid).toHaveBeenCalled(); }); - it('should Bescheid löschen', (done) => { - service.vorgangAbschliesen = jest.fn().mockReturnValue(of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE]))); + it('should NOT delete bescheid on loading', () => { + vorgangCommandService.abschliessen.mockReturnValue(of(createEmptyStateResource(true))); - const command$: Observable<StateResource<CommandResource>> = - service.bescheidLoeschenUndErstellungUeberspringen(vorgangWithEingangResource); + service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - command$.subscribe(() => { - expect(service.deleteBescheid).toHaveBeenCalledWith(); - done(); - }); + expect(service.deleteBescheid).not.toHaveBeenCalled(); }); - it('should not Bescheid löschen', (done) => { - service.vorgangAbschliesen = jest.fn().mockReturnValue(of(createCommandStateResource())); + it('should NOT delete bescheid on error', () => { + vorgangCommandService.abschliessen.mockReturnValue(of(createErrorStateResource(createProblemDetail()))); - const command$: Observable<StateResource<CommandResource>> = - service.bescheidLoeschenUndErstellungUeberspringen(vorgangWithEingangResource); + service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - command$.subscribe(() => { - expect(service.deleteBescheid).not.toHaveBeenCalledWith(bescheidResource); - done(); - }); + expect(service.deleteBescheid).not.toHaveBeenCalled(); }); - it('should emit vorgang abschliessen command', () => { + it('should return vorgang abschliessen command', () => { + const command: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); + vorgangCommandService.abschliessen.mockReturnValue(of(command)); + const command$: Observable<StateResource<CommandResource>> = - service.bescheidLoeschenUndErstellungUeberspringen(vorgangWithEingangResource); + service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource); - expect(command$).toBeObservable(singleColdCompleted(vorgangAbschliessenCommandStateResource)); + expect(command$).toBeObservable(singleColdCompleted(command)); }); }); - describe('vorgang abschliessen', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); - const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); - - beforeEach(() => { - vorgangCommandService.abschliessen.mockReturnValue(of(commandStateResource)); - }); - - it('should call vorgang command service', (done) => { - const command$: Observable<StateResource<CommandResource>> = service.vorgangAbschliesen(vorgangWithEingangResource); + describe('delete bescheid', () => { + it('should create command', () => { + service.deleteBescheid(); - command$.subscribe(() => { - expect(vorgangCommandService.abschliessen).toHaveBeenCalledWith(vorgangWithEingangResource); - done(); - }); + expect(bescheidResourceService.delete).toHaveBeenCalled(); }); it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = service.vorgangAbschliesen(vorgangWithEingangResource); + const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); + bescheidResourceService.delete.mockReturnValue(of(commandStateResource)); - expect(command$).toBeObservable(singleColdCompleted(commandStateResource)); + const createdCommand$: Observable<StateResource<CommandResource>> = service.deleteBescheid(); + + expect(createdCommand$).toBeObservable(singleColdCompleted(commandStateResource)); }); }); - describe('delete bescheid', () => { - const commandStateResource: StateResource<CommandResource> = createEmptyStateResource(); - + describe('loadFiles', () => { beforeEach(() => { - service.bescheidResourceService.delete = jest.fn().mockReturnValue(of(commandStateResource)); + service.loadBescheidDocument = jest.fn(); + service.loadAttachments = jest.fn(); }); - it('should call bescheid draft service', () => { - service.deleteBescheid(); + it('should bescheid document', () => { + service.loadFiles(bescheidResource); - expect(service.bescheidResourceService.delete).toHaveBeenCalled(); + expect(service.loadBescheidDocument).toHaveBeenCalledWith(bescheidResource); }); - it('should return command', () => { - const deleteCommand$: Observable<StateResource<CommandResource>> = service.deleteBescheid(); + it('should load attachments', () => { + service.loadFiles(bescheidResource); - expect(deleteCommand$).toBeObservable(singleColdCompleted(commandStateResource)); + expect(service.loadAttachments).toHaveBeenCalledWith(bescheidResource); }); }); - describe('update bescheid', () => { - const bescheid: Bescheid = createBescheid(); - const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); - const createCommandProps: CreateCommandProps = createCreateCommandProps(); - let buildUpdateBescheidCommandPropsSpy: jest.SpyInstance; - + describe('create bescheid document', () => { beforeEach(() => { - service.bescheidResourceService.save = jest.fn().mockReturnValue(of(commandStateResource)); + service.doCreateBescheidDocument = jest.fn().mockReturnValue(EMPTY); + service.handleCreateBescheidDocumentResponse = jest.fn(); }); - it('should save bescheid', () => { - service.updateBescheid(bescheid).pipe(first()).subscribe(); + it('should emit bescheid document', () => { + service.createBescheidDocument(bescheidResource); - expect(service.bescheidResourceService.save).toHaveBeenCalledWith(bescheid); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ ...createEmptyBescheidDocument(), create: createEmptyStateResource(true) }), + ); }); - it('should return command', () => { - const updateBescheid$: Observable<StateResource<CommandResource>> = service.updateBescheid(bescheid); + it('should do create bescheid document', () => { + service.createBescheidDocument(bescheidResource); - expect(updateBescheid$).toBeObservable(singleColdCompleted(commandStateResource)); + expect(service.doCreateBescheidDocument).toHaveBeenCalledWith(bescheidResource); }); - it('should clear create bescheid document in progress', (done) => { - service.createBescheidDocumentInProgress$.next(createCommandStateResource()); + it('should handle create response on loaded', () => { + service.doCreateBescheidDocument = jest.fn().mockReturnValue(of(commandStateResource)); - service.updateBescheid(bescheid).subscribe(() => { - expect(service.createBescheidDocumentInProgress$.value).toEqual(createEmptyStateResource()); - done(); - }); + service.createBescheidDocument(bescheidResource); + + expect(service.handleCreateBescheidDocumentResponse).toHaveBeenCalledWith(commandStateResource); }); - it('should clear upload bescheid document in progress', (done) => { - service.uploadBescheidDocumentInProgress$.next(createUploadFileInProgress()); + it('should handle create response on error', () => { + const commandError: StateResource<CommandResource> = createCommandErrorStateResource(); + service.doCreateBescheidDocument = jest.fn().mockReturnValue(of(commandError)); - service.updateBescheid(bescheid).subscribe(() => { - expect(service.uploadBescheidDocumentInProgress$.value).toEqual({ loading: false }); - done(); - }); - }); + service.createBescheidDocument(bescheidResource); - it('should clear attachment upload', (done) => { - service.uploadedAttachment$.next(createStateResource(createBinaryFileResource())); + expect(service.handleCreateBescheidDocumentResponse).toHaveBeenCalledWith(commandError); + }); + }); - service.updateBescheid(bescheid).subscribe(() => { - expect(service.uploadedAttachment$.value).toEqual(createEmptyStateResource()); - done(); + describe('doCreateBescheidDocument', () => { + it('should create command by props', () => { + service.doCreateBescheidDocument(bescheidResource); + + expect(commandService.createCommandByProps).toHaveBeenCalledWith({ + resource: bescheidResource, + linkRel: BescheidLinkRel.CREATE_DOCUMENT, + command: { + order: CommandOrder.CREATE_BESCHEID_DOCUMENT, + body: null, + }, + snackBarMessage: EMPTY_STRING, }); }); }); - describe('send bescheid', () => { - const bescheidResource: BescheidResource = createBescheidResource(); - const createCommandProps: CreateCommandProps = createCreateCommandProps(); - const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); - const linkRel: string = 'link_rel'; - - let buildSendBescheidCommandPropsSpy: jest.SpyInstance; + describe('handleCreateBescheidDocumentResponse', () => { + const commandStateResource: StateResource<CommandResource> = createStateResource( + createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), + ); beforeEach(() => { - service.bescheidResourceService.get = jest.fn().mockReturnValue(of(createStateResource(bescheidResource))); - buildSendBescheidCommandPropsSpy = jest - .spyOn(BescheidUtil, 'buildSendBescheidCommandProps') - .mockReturnValue(createCommandProps); - commandService.createCommandByProps.mockReturnValue(of(commandStateResource)); + service.loadBescheidDocumentByUri = jest.fn(); + service.emitBescheidDocumentError = jest.fn(); }); - it('should get resource', () => { - service.sendBescheid(bescheidResource, linkRel); - - expect(service.bescheidResourceService.get).toHaveBeenCalled(); - }); + it('should emit error', () => { + const commandErrorStateResource: StateResource<CommandResource> = createCommandErrorStateResource(); - it('should call command service', (done) => { - service.sendBescheid(bescheidResource, linkRel).subscribe(() => { - expect(commandService.createCommandByProps).toHaveBeenCalledWith(createCommandProps); - done(); - }); - }); + service.handleCreateBescheidDocumentResponse(commandErrorStateResource); - it('should build send bescheid command props', (done) => { - service.sendBescheid(bescheidResource, linkRel).subscribe(() => { - expect(buildSendBescheidCommandPropsSpy).toHaveBeenCalledWith(bescheidResource, linkRel); - done(); - }); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ ...createEmptyBescheidDocument(), create: commandErrorStateResource } as BescheidDocument), + ); }); - it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = service.sendBescheid(bescheidResource, linkRel); + it('should emit bescheid document state', () => { + service.handleCreateBescheidDocumentResponse(commandStateResource); - expect(command$).toBeObservable(singleColdCompleted(commandStateResource)); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ + ...createEmptyBescheidDocument(), + documentUri: getEffectedResourceUrl(commandStateResource.resource), + }), + ); }); - }); - describe('sendBescheidManually', () => { - const bescheidResource: BescheidResource = createBescheidResource(); - const sendBescheidCommand: StateResource<CommandResource> = createCommandStateResource(); + it('should load document by uri', () => { + service.handleCreateBescheidDocumentResponse(commandStateResource); - beforeEach(() => { - service.sendBescheid = jest.fn().mockReturnValue(of(sendBescheidCommand)); + expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(getEffectedResourceUrl(commandStateResource.resource)); }); + }); - it('should call sendBescheid', () => { - service.sendBescheidManually(bescheidResource); + describe('emitBescheidDocumentError', () => { + it('should emit', () => { + const commandError: StateResource<CommandResource> = createCommandErrorStateResource(); - expect(service.sendBescheid).toHaveBeenCalledWith(bescheidResource, BescheidLinkRel.BESCHEIDEN); - }); + service.emitBescheidDocumentError(commandError); - it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = service.sendBescheidManually(bescheidResource); - - expect(command$).toBeObservable(singleColdCompleted(sendBescheidCommand)); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ + ...createEmptyBescheidDocument(), + upload: { ...createEmptyUploadInProgress(), loading: false, error: commandError.error }, + }), + ); }); }); - describe('sendBescheidToAntragsteller', () => { - const bescheidResource: BescheidResource = createBescheidResource(); - const sendBescheidCommand: StateResource<CommandResource> = createCommandStateResource(); - + describe('loadBescheidDocument', () => { beforeEach(() => { - service.sendBescheid = jest.fn().mockReturnValue(of(sendBescheidCommand)); + service.loadBescheidDocumentByUri = jest.fn(); }); - it('should call sendBescheid', () => { - service.sendBescheidToAntragsteller(bescheidResource); + it('should load by uri', () => { + const bescheidResource: BescheidResource = createBescheidResource([BescheidLinkRel.BESCHEID_DOCUMENT]); - expect(service.sendBescheid).toHaveBeenCalledWith(bescheidResource, BescheidLinkRel.BESCHEIDEN_UND_SENDEN); + service.loadBescheidDocument(bescheidResource); + + expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(getUrl(bescheidResource, BescheidLinkRel.BESCHEID_DOCUMENT)); }); - it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = service.sendBescheidToAntragsteller(bescheidResource); + it('should NOT load by uri', () => { + service.loadBescheidDocument(bescheidResource); - expect(command$).toBeObservable(singleColdCompleted(sendBescheidCommand)); + expect(service.loadBescheidDocumentByUri).not.toHaveBeenCalled(); }); }); - describe('getAttachments', () => { - let bescheidResource: BescheidResource; - let binaryFileListResource: BinaryFileListResource; - let binaryFileResource: BinaryFileResource; + describe('loadBescheidDocumentByUri', () => { + const resourceUri: ResourceUri = faker.internet.url(); beforeEach(() => { - bescheidResource = createBescheidResource([BescheidLinkRel.ATTACHMENTS]); - service.getBescheidDraft = jest.fn().mockReturnValue(of(createStateResource(bescheidResource))); + resourceRepository.getResource.mockReturnValue(EMPTY); + service.loadBescheidDocumentFile = jest.fn(); + }); - binaryFileResource = createBinaryFileResource(); + it('should get resource', () => { + service.loadBescheidDocumentByUri(resourceUri); - binaryFileListResource = createBinaryFileListResource([binaryFileResource]); - binaryFileService.getFiles.mockReturnValue(of(createStateResource(binaryFileListResource))); + expect(resourceRepository.getResource).toHaveBeenCalledWith(resourceUri); }); - it('should get files', (done) => { - service.getAttachments().subscribe(() => { - expect(binaryFileService.getFiles).toHaveBeenCalledWith(bescheidResource, BescheidLinkRel.ATTACHMENTS); - done(); - }); - }); + it('should load bescheid document file', () => { + const documentResource: DocumentResource = createDocumentResource(); + resourceRepository.getResource.mockReturnValue(of(documentResource)); - it('should return embedded resources', () => { - const attachments$: Observable<BinaryFileResource[]> = service.getAttachments(); + service.loadBescheidDocumentByUri(resourceUri); - expect(attachments$).toBeObservable(singleColdCompleted([binaryFileResource])); + expect(service.loadBescheidDocumentFile).toHaveBeenCalledWith(documentResource); }); }); - describe('get document uri', () => { - const documentUri: ResourceUri = faker.internet.url(); + describe('load bescheid document file', () => { + const document: DocumentResource = createDocumentResource([DocumentLinkRel.FILE]); + const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); beforeEach(() => { - service.bescheidDocumentUri$.next(documentUri); + binaryFileService.getFile.mockReturnValue(of(binaryFileStateResource)); }); - it('should return value', (done) => { - service.getDocumentUri().subscribe((uri) => { - expect(uri).toBe(documentUri); - done(); - }); + it('should call binary file service', () => { + service.loadBescheidDocumentFile(document); + + expect(binaryFileService.getFile).toHaveBeenCalledWith(getUrl(document, DocumentLinkRel.FILE)); }); - }); - describe('get bescheid document file', () => { - it('should return value', (done) => { - const binaryFile: BinaryFileResource = createBinaryFileResource(); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(binaryFile); - service.bescheidDocumentFile$.next(binaryFileStateResource); + it('should emit bescheid document state', () => { + service.loadBescheidDocumentFile(document); - service.getBescheidDocumentFile().subscribe((result: StateResource<BinaryFileResource>) => { - expect(result).toBe(binaryFileStateResource); - done(); - }); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ + upload: createEmptyUploadInProgress(), + create: createEmptyStateResource(), + resource: binaryFileStateResource.resource, + documentUri: getUrl(document, LinkRel.Self), + }), + ); }); }); - describe('upload bescheid document', () => { - const bescheid: BescheidResource = createBescheidResource(); - const file: File = createFile(); + describe('loadAttachments', () => { + const bescheidResourceWithAttachments: BescheidResource = createBescheidResource([BescheidLinkRel.ATTACHMENTS]); beforeEach(() => { - service.doUploadBescheidDocument = jest.fn(); + binaryFileService.getFiles.mockReturnValue(EMPTY); }); - it('should call init upload bescheid document in progress', () => { - service.uploadBescheidDocument(bescheid, file); + it('should call binary file service', () => { + service.loadAttachments(bescheidResourceWithAttachments); - expect(service.uploadBescheidDocumentInProgress$.value).toEqual({ - loading: true, - fileName: file.name, - }); + expect(binaryFileService.getFiles).toHaveBeenCalledWith(bescheidResourceWithAttachments, BescheidLinkRel.ATTACHMENTS); }); - it('should clear create bescheid document', () => { - service.createBescheidDocumentInProgress$.next(createCommandStateResource()); - service.uploadBescheidDocument(bescheid, file); + it('should NOT call binary file service', () => { + service.loadAttachments(bescheidResource); - expect(service.createBescheidDocumentInProgress$.value).toEqual(createEmptyStateResource()); + expect(binaryFileService.getFiles).not.toHaveBeenCalled(); }); - it('should call do upload bescheid document', () => { - service.uploadBescheidDocument(bescheid, file); + it('should add files', () => { + const binaryFileListStateResource: StateResource<BinaryFileListResource> = + createStateResource(createBinaryFileListResource()); + binaryFileService.getFiles.mockReturnValue(of(binaryFileListStateResource)); - expect(service.doUploadBescheidDocument).toHaveBeenCalledWith(bescheid, file); - }); + service.loadAttachments(bescheidResourceWithAttachments); - it('should return bescheid document file', (done) => { - service.uploadBescheidDocument(bescheid, file).subscribe((uploadFileInProgress: UploadFileInProgress) => { - expect(uploadFileInProgress.fileName).toBe(file.name); - expect(uploadFileInProgress.loading).toBeTruthy(); - done(); - }); + expect(binaryFileService.addFiles).toHaveBeenCalledWith( + BESCHEID_UPLOADED_ATTACHMENTS, + getEmbeddedResources(binaryFileListStateResource, BinaryFileListLinkRel.FILE_LIST), + ); }); }); - describe('do upload bescheid document', () => { - const bescheid: BescheidResource = createBescheidResource(); - const file: File = createFile(); - - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); + describe('upload bescheid document', () => { + const documentFile: File = createFile(); beforeEach(() => { - binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource)); + binaryFileService.uploadFile.mockReturnValue(EMPTY); + service.handleUploadBescheidDocumentResponse = jest.fn(); + }); + + it('should emit bescheid document state', () => { + service.uploadBescheidDocument(documentFile, bescheidResource); + + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ ...createEmptyBescheidDocument(), upload: { fileName: documentFile.name, loading: true } }), + ); }); it('should call binary file service', () => { - service.doUploadBescheidDocument(bescheid, file); + service.uploadBescheidDocument(documentFile, bescheidResource); - expect(binaryFileService.uploadFile).toHaveBeenCalledWith(bescheid, BescheidLinkRel.UPLOAD_BESCHEID_FILE, file, false); + expect(binaryFileService.uploadFile).toHaveBeenCalledWith( + bescheidResource, + BescheidLinkRel.UPLOAD_BESCHEID_FILE, + documentFile, + false, + ); }); - it('should call handle upload becheid document response', () => { - service.handleUploadBescheidDocumentResponse = jest.fn(); + it('should handle upload response', () => { + const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); + binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource)); - service.doUploadBescheidDocument(bescheid, file); + service.uploadBescheidDocument(documentFile, bescheidResource); - expect(service.handleUploadBescheidDocumentResponse).toHaveBeenCalledWith(bescheid, binaryFileStateResource); + expect(service.handleUploadBescheidDocumentResponse).toHaveBeenCalledWith(bescheidResource, binaryFileStateResource); }); }); - describe('handle upload bescheid document response', () => { - const bescheid: BescheidResource = createBescheidResource(); - - const binaryFile: BinaryFileResource = createBinaryFileResource(); - const apiError: ApiError = createApiError(); - const binaryFileErrorStateResource: StateResource<BinaryFileResource> = createErrorStateResource(apiError); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(binaryFile); - - it('should call create bescheid document from file on success', () => { + describe('handleUploadBescheidDocumentResponse', () => { + beforeEach(() => { + service.emitBescheidDocumentError = jest.fn(); service.createBescheidDocumentFromFile = jest.fn(); - - service.handleUploadBescheidDocumentResponse(bescheid, binaryFileStateResource); - - expect(service.createBescheidDocumentFromFile).toHaveBeenCalledWith(bescheid, binaryFile); }); - describe('on no error', () => { - it('should set error', () => { - service.uploadBescheidDocumentInProgress$.next({ loading: false }); + it('should emit error', () => { + const errorStateResource: StateResource<BinaryFileResource> = createErrorStateResource(createProblemDetail()); - service.handleUploadBescheidDocumentResponse(bescheid, binaryFileErrorStateResource); + service.handleUploadBescheidDocumentResponse(bescheidResource, errorStateResource); - expect(service.uploadBescheidDocumentInProgress$.value.error).toBe(apiError); - }); + expect(service.emitBescheidDocumentError).toHaveBeenCalledWith(errorStateResource); + }); - it('should set loading to false', () => { - service.uploadBescheidDocumentInProgress$.next({ loading: true }); + it('should create bescheid document from file', () => { + const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); - service.handleUploadBescheidDocumentResponse(bescheid, binaryFileErrorStateResource); + service.handleUploadBescheidDocumentResponse(bescheidResource, binaryFileStateResource); - expect(service.uploadBescheidDocumentInProgress$.value.loading).toBeFalsy(); - }); + expect(service.createBescheidDocumentFromFile).toHaveBeenCalledWith(bescheidResource, binaryFileStateResource.resource); }); }); @@ -694,14 +595,12 @@ describe('BescheidService', () => { const binaryFile: BinaryFileResource = createBinaryFileResource(); const createCommandProps: CreateCommandProps = createCreateCommandProps(); - let buildCreateBescheidDocumentFromFilePropsSpy; + let buildCreateBescheidDocumentFromFilePropsMock = buildCreateBescheidDocumentFromFileProps as jest.Mock; const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); beforeEach(() => { - buildCreateBescheidDocumentFromFilePropsSpy = jest - .spyOn(BescheidUtil, 'buildCreateBescheidDocumentFromFileProps') - .mockReturnValue(createCommandProps); + buildCreateBescheidDocumentFromFilePropsMock.mockReturnValue(createCommandProps); commandService.createCommandByProps.mockReturnValue(of(commandStateResource)); }); @@ -714,7 +613,7 @@ describe('BescheidService', () => { it('should build create command document from file props', () => { service.createBescheidDocumentFromFile(bescheid, binaryFile); - expect(buildCreateBescheidDocumentFromFilePropsSpy).toHaveBeenCalledWith(bescheid, binaryFile); + expect(buildCreateBescheidDocumentFromFilePropsMock).toHaveBeenCalledWith(bescheid, binaryFile); }); it('should call handle create bescheid document from file response', () => { @@ -726,368 +625,340 @@ describe('BescheidService', () => { }); }); - describe('handle create bescheid document response from file', () => { - const binaryFile: BinaryFileResource = createBinaryFileResource(); - const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - const commandStateResource: StateResource<CommandResource> = createStateResource(command); + describe('handleCreateBescheidDocumentFromFileResponse', () => { + const commandStateResource: StateResource<CommandResource> = createStateResource( + createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), + ); beforeEach(() => { - service.bescheidDocumentFile$.next(createEmptyStateResource()); + service.emitBescheidDocumentError = jest.fn(); }); - it('should set upload bescheid document in progress done', () => { - service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFile); + it('should emit error', () => { + const errorStateResource: StateResource<CommandResource> = createErrorStateResource(createProblemDetail()); - expect(service.bescheidDocumentFile$.value).toEqual(createStateResource(binaryFile)); + service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, createBinaryFileResource()); + + expect(service.emitBescheidDocumentError).toHaveBeenCalledWith(errorStateResource); }); - describe('on error', () => { - it('should set upload bescheid in progress error', () => { - const httpError: HttpError = createApiError(); - const errorStateResource: StateResource<CommandResource> = createErrorStateResource(httpError); + it('should NOT emit error', () => { + const binaryFileResource: BinaryFileResource = createBinaryFileResource(); - service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, binaryFile); + service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFileResource); - expect(service.uploadBescheidDocumentInProgress$.value.error).toBe(httpError); - }); + expect(service.emitBescheidDocumentError).not.toHaveBeenCalled(); + }); - it('should set upload bescheid in progress loading false', () => { - const httpError: HttpError = createApiError(); - const errorStateResource: StateResource<CommandResource> = createErrorStateResource(httpError); + it('should emit bescheid document state', () => { + const binaryFileResource: BinaryFileResource = createBinaryFileResource(); - service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, binaryFile); + service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFileResource); - expect(service.uploadBescheidDocumentInProgress$.value.loading).toBeFalsy(); - }); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ + ...createEmptyBescheidDocument(), + documentUri: getEffectedResourceUrl(commandStateResource.resource), + upload: createEmptyUploadInProgress(), + resource: binaryFileResource, + }), + ); }); - describe('on success', () => { - it('should set documentFile', () => { - service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFile); - - expect(service.bescheidDocumentFile$.value).toEqual(createStateResource(binaryFile)); - }); + it('should NOT emit bescheid document state', () => { + const errorStateResource: StateResource<CommandResource> = createErrorStateResource(createProblemDetail()); - it('should set document uri', () => { - service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFile); + service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, createBinaryFileResource()); - expect(service.bescheidDocumentUri$.value).toEqual(getUrl(command, CommandLinkRel.EFFECTED_RESOURCE)); - }); + expect(service.getBescheidDocument()).toBeObservable(singleCold(createEmptyBescheidDocument())); }); }); - describe('delete bescheid document', () => { - it('should clear document uri', () => { - service.bescheidDocumentUri$.next(faker.internet.url()); - - service.deleteBescheidDocument(); + describe('createBescheid', () => { + const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource(); + const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); + const commandStateResource: StateResource<CommandResource> = createStateResource(command); - expect(service.bescheidDocumentUri$.value).toBeNull(); + beforeEach(() => { + service.updateBescheidDraft = jest.fn(); }); - it('should clear document file', () => { - service.bescheidDocumentFile$.next(createStateResource(createBinaryFileResource())); + beforeEach(() => { + facade.getBescheidCommand.mockReturnValue(of(commandStateResource)); + (service as any).bescheidResourceService.loadByResourceUri = jest.fn(); + }); - service.deleteBescheidDocument(); + it('should call facade', () => { + service.createBescheid(vorgangWithEingang).subscribe(); - expect(service.bescheidDocumentFile$.value).toEqual(createEmptyStateResource()); + expect(facade.createBescheidDraft).toHaveBeenCalledWith(vorgangWithEingang, { + order: CommandOrder.CREATE_BESCHEID, + body: null, + }); }); - it('should clear document', () => { - service.bescheidDocument$.next(createStateResource(createDocumentResource())); - - service.deleteBescheidDocument(); + it('should update bescheid draft', () => { + service.createBescheid(vorgangWithEingang).subscribe(); - expect(service.bescheidDocument$.value).toEqual(createEmptyStateResource()); + expect(service.updateBescheidDraft).toHaveBeenCalledWith(commandStateResource.resource); }); }); - describe('init', () => { - it('should emit null bescheid document uri', () => { - service.init(); + describe('updateBescheidDraft', () => { + const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - expect(service.getDocumentUri()).toBeObservable(singleCold(null)); + beforeEach(() => { + (service as any).bescheidResourceService.loadByResourceUri = jest.fn(); }); - it('should emit empty state resource document file', () => { - service.init(); + it('should load resource by uri', () => { + service.updateBescheidDraft(command); - expect(service.getBescheidDocumentFile()).toBeObservable(singleCold(createEmptyStateResource())); + expect((service as any).bescheidResourceService.loadByResourceUri).toHaveBeenCalledWith( + getUrl(command, CommandLinkRel.EFFECTED_RESOURCE), + ); }); - it('should emit empty state resource uploaded attachment', () => { - service.init(); + it('should emit bescheid created', () => { + service.updateBescheidDraft({ ...command, order: CommandOrder.CREATE_BESCHEID }); - expect(service.getUploadedAttachment()).toBeObservable(singleCold(createEmptyStateResource())); + expect(service.getBescheidCreated()).toBeObservable(singleCold(true)); }); + }); - it('should emit empty upload in progress for upload bescheid document in progress', () => { - service.init(); + describe('updateBescheid', () => { + const bescheid: Bescheid = createBescheid(); + const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); - expect(service.getUploadBescheidDocumentInProgress()).toBeObservable(singleCold({ loading: false })); + beforeEach(() => { + service.doUpdateBescheid = jest.fn().mockReturnValue(EMPTY); + service.updateBescheidDraft = jest.fn().mockReturnValue(EMPTY); }); - it('should emit empty upload in progress for upload attachmentdocument in progress', () => { - service.init(); + it('should do update bescheid', () => { + service.updateBescheid(bescheidResource, bescheid); - expect(service.getUploadAttachmentInProgress()).toBeObservable(singleCold({ loading: false })); + expect(service.doUpdateBescheid).toHaveBeenCalledWith(bescheidResource, bescheid); }); - it('should init active step', () => { - service.setActiveStep(2); + it('should update bescheid draft', () => { + service.doUpdateBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - service.init(); + service.updateBescheid(bescheidResource, bescheid).subscribe(); - expect(service.activeStep$).toBeObservable(singleCold(1)); + expect(service.updateBescheidDraft).toHaveBeenCalledWith(commandResource); }); }); - describe('create bescheid document', () => { - const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); - + describe('do update bescheid', () => { + const bescheid: Bescheid = createBescheid(); const bescheidResource: BescheidResource = createBescheidResource(); - const createCommandProps: CreateCommandProps = createCreateCommandProps(); - let buildCreateBescheidDocumentCommandPropsSpy: jest.SpyInstance; + const createCommandProps: CreateCommandProps = createCreateCommandProps(); + let buildUpdateBescheidCommandPropsMock: jest.Mock = buildUpdateBescheidCommandProps as jest.Mock; beforeEach(() => { - commandService.createCommandByProps.mockReturnValue(of(commandStateResource)); - service.getResource = jest.fn().mockReturnValue(bescheidResource); - buildCreateBescheidDocumentCommandPropsSpy = jest - .spyOn(BescheidUtil, 'buildCreateBescheidDocumentCommandProps') - .mockReturnValue(createCommandProps); + buildUpdateBescheidCommandPropsMock.mockReturnValue(createCommandProps); + commandService.createCommandByProps.mockClear(); + commandService.createCommandByProps.mockReturnValue(of(createCommandStateResource())); }); - it('should call command service', () => { - service.createBescheidDocument(); + it('should build update bescheid command props', () => { + service.doUpdateBescheid(bescheidResource, bescheid); - expect(commandService.createCommandByProps).toHaveBeenCalledWith(createCommandProps); + expect(buildUpdateBescheidCommandPropsMock).toHaveBeenCalledWith(bescheidResource, bescheid); }); - it('should build create command props', () => { - service.createBescheidDocument(); + it('should call command service', () => { + service.doUpdateBescheid(bescheidResource, bescheid).subscribe(); - expect(buildCreateBescheidDocumentCommandPropsSpy).toHaveBeenCalledWith(bescheidResource); + expect(commandService.createCommandByProps).toHaveBeenCalledWith(createCommandProps); }); + }); - it('should set create beschied document in progress', () => { - service.createBescheidDocument(); - - expect(service.createBescheidDocumentInProgress$.value).toEqual(commandStateResource); + describe('sendBescheidManually', () => { + beforeEach(() => { + service.sendBescheid = jest.fn().mockReturnValue(EMPTY); }); - it('should set upload beschied document in progress loading false', () => { - service.uploadBescheidDocumentInProgress$.next({ - loading: true, - error: createApiError(), - fileName: 'Dummy', - }); - - service.createBescheidDocument(); + it('should send bescheid', () => { + service.sendBescheidManually().subscribe(); - expect(service.uploadBescheidDocumentInProgress$.value).toEqual({ loading: false }); + expect(service.sendBescheid).toHaveBeenCalledWith(BescheidLinkRel.BESCHEIDEN); }); - describe('on successfully done command', () => { - it('should load bescheid document', fakeAsync(() => { - service.loadBescheidDocumentByUri = jest.fn(); - - service.createBescheidDocument(); - tick(); + it('should return send bescheid command', () => { + const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); + service.sendBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(getUrl(commandResource, CommandLinkRel.EFFECTED_RESOURCE)); - })); + const sendCommandStateResource$: Observable<StateResource<CommandResource>> = service.sendBescheidManually(); - it('should update bescheid document Url', fakeAsync(() => { - service.loadBescheidDocumentByUri = jest.fn(); - - service.createBescheidDocument(); - tick(); + expect(sendCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + }); - expect(service.bescheidDocumentUri$.value).toBe(getUrl(commandResource, CommandLinkRel.EFFECTED_RESOURCE)); - })); + describe('sendBescheid', () => { + beforeEach(() => { + service.getBescheidDraft = jest.fn().mockReturnValue(of(createStateResource(bescheidResource))); + commandService.createCommandByProps.mockReturnValue(EMPTY); }); - describe('on error', () => { - const commandErrorStateResource: StateResource<CommandResource> = createStateResource(createCommandErrorResource()); + it('should get bescheid draft', () => { + service.sendBescheidManually().subscribe(); - it('should emit command state resource', () => { - commandService.createCommandByProps.mockReturnValue(of(commandErrorStateResource)); + expect(service.getBescheidDraft).toHaveBeenCalled(); + }); - service.createBescheidDocument(); + it('should create command', () => { + service.sendBescheid(BescheidLinkRel.BESCHEIDEN).subscribe(); - expect(service.createBescheidDocumentInProgress$.value).toBe(commandErrorStateResource); - }); + expect(commandService.createCommandByProps).toHaveBeenCalledWith({ + resource: bescheidResource, + linkRel: BescheidLinkRel.BESCHEIDEN, + command: { + order: CommandOrder.SEND_BESCHEID, + body: null, + }, + snackBarMessage: EMPTY_STRING, + } as CreateCommandProps); + }); - it('should set create bescheid document in progress loading false', () => { - service.createBescheidDocumentInProgress$.next(createEmptyStateResource(true)); - commandService.createCommandByProps.mockReturnValue(of(commandErrorStateResource)); + it('should return send bescheid command', () => { + const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); + commandService.createCommandByProps = jest.fn().mockReturnValue(of(commandStateResource)); - service.createBescheidDocument(); + const sendCommandStateResource$: Observable<StateResource<CommandResource>> = service.sendBescheid( + BescheidLinkRel.BESCHEIDEN, + ); - expect(service.createBescheidDocumentInProgress$.value.loading).toBeFalsy(); - }); + expect(sendCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); }); }); - describe('exists bescheid document file', () => { - it('should return true if resource exists', (done) => { - service.bescheidDocumentFile$.next(createStateResource(createBinaryFileResource())); - - service.existBescheidDocumentFile().subscribe((result) => { - expect(result).toBeTruthy(); - done(); - }); + describe('sendBescheidMessage', () => { + beforeEach(() => { + service.getBescheidDraft = jest.fn().mockReturnValue(createStateResource(bescheidResource)); + service.sendBescheid = jest.fn().mockReturnValue(EMPTY); }); - it('should return false if resource is null', (done) => { - service.bescheidDocumentFile$.next(createEmptyStateResource()); + it('should send bescheid', () => { + service.sendBescheidMessage().subscribe(); - service.existBescheidDocumentFile().subscribe((result) => { - expect(result).toBeFalsy(); - done(); - }); + expect(service.sendBescheid).toHaveBeenCalledWith(BescheidLinkRel.BESCHEIDEN_UND_SENDEN); }); - }); - - describe('get bescheid document command', () => { - const commandResource: CommandResource = createCommandResource(); - const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); - beforeEach(() => { - commandService.getCommandByOrder.mockReturnValue(of(commandStateResource)); - }); + it('should return send bescheid command', () => { + const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); + service.sendBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - it('should call command service', (done) => { - service.getBescheidDocumentCommand().subscribe(() => { - expect(commandService.getCommandByOrder).toHaveBeenCalledWith(CommandOrder.CREATE_BESCHEID_DOCUMENT); - done(); - }); - }); + const sendCommandStateResource$: Observable<StateResource<CommandResource>> = service.sendBescheidMessage(); - it('should return command stateResource', (done) => { - service.getBescheidDocumentCommand().subscribe((result) => { - expect(result).toBe(commandStateResource); - done(); - }); + expect(sendCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); }); }); - describe('exists bescheid draft', () => { + describe('setActiveStep', () => { beforeEach(() => { - service.bescheidResourceService.existResource = jest.fn().mockReturnValue(of(true)); - }); - - it('should call bescheid resource service', () => { - service.existsBescheidDraft(); - - expect(service.bescheidResourceService.existResource).toHaveBeenCalled(); + service._clearUploadedFiles = jest.fn(); }); - it('should return false on missing resource', () => { - service.bescheidResourceService.existResource = jest.fn().mockReturnValue(of(false)); - - const exists: boolean = service.existsBescheidDraft(); + it('should emit changed active step', () => { + service.setActiveStep(BescheidWizardStep.DokumenteHochladen); - expect(exists).toBeFalsy(); + expect(service.getActiveStep()).toBeObservable(singleCold(BescheidWizardStep.DokumenteHochladen)); }); - it('should return true on existing resource', () => { - const exists: boolean = service.existsBescheidDraft(); + it('should clear uploaded files', () => { + service.setActiveStep(BescheidWizardStep.DokumenteHochladen); - expect(exists).toBeTruthy(); + expect(service._clearUploadedFiles).toHaveBeenCalled(); }); }); - describe('bescheidVerwerfen', () => { - const command: CommandResource = createCommandResource(); - const commandStateResource: StateResource<CommandResource> = createStateResource(command); + describe('getBescheidDraft', () => { + const bescheidDraft: BescheidResource = createBescheidResource(); + const bescheidDraftStateResource: StateResource<BescheidResource> = createStateResource(bescheidDraft); - beforeEach(() => { - service.deleteBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - service.deleteBescheidDocument = jest.fn(); + it('should call resource service', () => { + bescheidResourceService.get = jest.fn(); - service.getResource = jest.fn().mockReturnValue(createBescheidResource()); - }); + service.getBescheidDraft(); - it('should delete bescheid', (done) => { - service.bescheidVerwerfen().subscribe(() => { - expect(service.deleteBescheid).toHaveBeenCalled(); - done(); - }); + expect(bescheidResourceService.get).toHaveBeenCalled(); }); - it('should return command', () => { - const command: StateResource<CommandResource> = createCommandStateResource(); - service.deleteBescheid = jest.fn().mockReturnValue(singleCold(command)); + it('should return value', () => { + bescheidResourceService.get = jest.fn().mockReturnValue(singleCold(bescheidDraftStateResource)); - const command$: Observable<StateResource<CommandResource>> = service.bescheidVerwerfen(); + const bescheidStateResource$: Observable<StateResource<BescheidResource>> = service.getBescheidDraft(); - expect(command$).toBeObservable(singleCold(command)); + expect(bescheidStateResource$).toBeObservable(singleCold(bescheidDraftStateResource)); }); + }); - it('should delete bescheid document', (done) => { - service.deleteBescheid = jest.fn().mockReturnValue(of(createCommandStateResource())); - - service.bescheidVerwerfen().subscribe(() => { - done(); - expect(service.deleteBescheidDocument).toHaveBeenCalled(); - }); - }); + describe('setNachrichtEmpfaenger', () => { + it('should change wizard state', () => { + const empfaenger: string = faker.person.fullName(); - it('should reload vorgang', (done) => { - service.deleteBescheid = jest.fn().mockReturnValue(of(createCommandStateResource())); + service.setNachrichtEmpfaenger(empfaenger); - service.bescheidVerwerfen().subscribe(() => { - done(); - expect(vorgangService.reloadCurrentVorgang).toHaveBeenCalled(); - }); + expect(service.getWizard()).toBeObservable(singleCold({ ...createInitialWizard(), empfaenger })); }); }); - describe('load bescheid document file', () => { - const document: DocumentResource = createDocumentResource([DocumentLinkRel.FILE]); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); + describe('lockBescheidSending', () => { + it('should change wizard state', () => { + service.lockBescheidSending(); - beforeEach(() => { - binaryFileService.getFile.mockReturnValue(of(binaryFileStateResource)); + expect(service.getWizard()).toBeObservable(singleCold({ ...createInitialWizard(), canBeSend: false })); }); + }); - it('should call bianry file service', () => { - service.loadBescheidDocumentFile(document); + describe('unlockBescheidSending', () => { + it('should change wizard state', () => { + service.unlockBescheidSending(); - expect(binaryFileService.getFile).toHaveBeenCalledWith(getUrl(document, DocumentLinkRel.FILE)); + expect(service.getWizard()).toBeObservable(singleCold({ ...createInitialWizard(), canBeSend: true })); }); + }); - it('should set bescheidDocument file', () => { - service.loadBescheidDocumentFile(document); + describe('finishAddingBescheidDocument', () => { + it('should update state', () => { + const bescheidDocument: BescheidDocument = createBescheidDocument(); + service._bescheidDocument$.next(bescheidDocument); - expect(service.bescheidDocumentFile$.value).toBe(binaryFileStateResource); - }); + service.finishAddingBescheidDocument(); - it('should set create bescheid document in progress loading false', () => { - service.createBescheidDocumentInProgress$.next(createEmptyStateResource(true)); + expect(service.getBescheidDocument()).toBeObservable( + singleCold({ + ...bescheidDocument, + create: createEmptyStateResource(), + upload: createEmptyUploadInProgress(), + } as BescheidDocument), + ); + }); + }); - service.loadBescheidDocumentFile(document); + describe('clear uploaded files', () => { + it('should call binary files service', () => { + service._clearUploadedFiles(); - expect(service.createBescheidDocumentInProgress$.value.loading).toBeFalsy(); + expect(binaryFileService.clearUploadedFiles).toHaveBeenCalledWith(BESCHEID_UPLOADED_ATTACHMENTS); }); }); describe('get bescheid list', () => { it('should call bescheid list resource service', () => { - service.bescheidListResourceService.getList = jest.fn(); - service.getBescheidList(); - expect(service.bescheidListResourceService.getList).toHaveBeenCalled(); + expect(bescheidListResourceService.getList).toHaveBeenCalled(); }); it('should return value', () => { const bescheidList: BescheidListResource = createBescheidListResource(); const bescheidListStateResource: StateResource<BescheidListResource> = createStateResource(bescheidList); - service.bescheidListResourceService.getList = jest.fn().mockReturnValue(singleCold(bescheidListStateResource)); + bescheidListResourceService.getList = jest.fn().mockReturnValue(singleCold(bescheidListStateResource)); const command$: Observable<StateResource<BescheidListResource>> = service.getBescheidList(); @@ -1095,7 +966,7 @@ describe('BescheidService', () => { }); }); - describe('load bescheid document', () => { + describe('get bescheid document by uri', () => { const resourceUri: ResourceUri = faker.internet.url(); const document: DocumentResource = createDocumentResource(); @@ -1104,13 +975,13 @@ describe('BescheidService', () => { }); it('should call repository', () => { - service.loadBescheidDocument(resourceUri); + service.getBescheidDocumentByUri(resourceUri); expect(resourceRepository.getResource).toHaveBeenCalledWith(resourceUri); }); it('should return value', () => { - const documentStateResource$: Observable<StateResource<DocumentResource>> = service.loadBescheidDocument(resourceUri); + const documentStateResource$: Observable<StateResource<DocumentResource>> = service.getBescheidDocumentByUri(resourceUri); expect(documentStateResource$).toBeObservable( cold('(ab|)', { a: createEmptyStateResource(true), b: createStateResource(document) }), @@ -1118,44 +989,6 @@ describe('BescheidService', () => { }); }); - describe('get resource', () => { - const bescheidResource: BescheidResource = createBescheidResource(); - const bescheidStateResource: StateResource<BescheidResource> = createStateResource(bescheidResource); - - it('should call bescheid resource service select resource', () => { - service.bescheidResourceService.selectResource = jest.fn().mockReturnValue(of(bescheidStateResource)); - - service.getResource(); - - expect(service.bescheidResourceService.selectResource).toHaveBeenCalled(); - }); - - it('should return value', () => { - service.bescheidResourceService.selectResource = jest.fn().mockReturnValue(of(bescheidStateResource)); - - const bescheidDraft: BescheidResource = service.getResource(); - - expect(bescheidDraft).toBe(bescheidResource); - }); - }); - - describe('getEmpfaenger', () => { - it('should return Empfänger', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); - const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = - createStateResource(vorgangWithEingangResource); - vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangWithEingangStateResource)); - - const empfaenger$: Observable<string> = service.getEmpfaenger(); - - expect(empfaenger$).toBeObservable( - singleColdCompleted( - `${vorgangWithEingangResource.eingang.antragsteller.vorname} ${vorgangWithEingangResource.eingang.antragsteller.nachname}`, - ), - ); - }); - }); - describe('get last bescheid', () => { const bescheid: BescheidResource = createBescheidResource(); const bescheide: BescheidResource[] = [bescheid]; @@ -1166,7 +999,7 @@ describe('BescheidService', () => { beforeEach(() => { service.filterBySentStatus = jest.fn().mockReturnValue(bescheide); sortByGermanDateStrSpy = jest.spyOn(DateUtil, 'sortByGermanDateStr').mockReturnValue(bescheide); - getItemsSpy = service.bescheidListResourceService.getItems = jest.fn().mockReturnValue(of(bescheide)); + getItemsSpy = bescheidListResourceService.getItems = jest.fn().mockReturnValue(of(bescheide)); }); it('should get items', () => { @@ -1194,47 +1027,6 @@ describe('BescheidService', () => { }); }); - describe('exist bescheid', () => { - const bescheid: BescheidResource = createBescheidResource(); - const bescheide: BescheidResource[] = [bescheid]; - const bescheidListStateResource: StateResource<BescheidListResource> = createStateResource( - createBescheidListResource(bescheide), - ); - let getItemsSpy: jest.SpyInstance; - - beforeEach(() => { - service.getBescheidList = jest.fn().mockReturnValue(of(bescheidListStateResource)); - service.filterBySentStatus = jest.fn().mockReturnValue(bescheide); - getItemsSpy = service.bescheidListResourceService.getItems = jest.fn().mockReturnValue(of(bescheide)); - }); - - it('should get items', () => { - service.existBescheid().subscribe(); - - expect(getItemsSpy).toHaveBeenCalled(); - }); - - it('should filter by sent status', () => { - service.existBescheid().subscribe(); - - expect(service.filterBySentStatus).toHaveBeenCalledWith(bescheide); - }); - - it('should return true if at least one bescheid exists', () => { - const existBescheid$: Observable<boolean> = service.existBescheid(); - - expect(existBescheid$).toBeObservable(singleColdCompleted(true)); - }); - - it('should return false if no bescheide exists', () => { - service.filterBySentStatus = jest.fn().mockReturnValue([]); - - const existBescheid$: Observable<boolean> = service.existBescheid(); - - expect(existBescheid$).toBeObservable(singleColdCompleted(false)); - }); - }); - describe('filter by sent status', () => { it('should keep entry with sent status', () => { const bescheidWithSentStatus: BescheidResource = { @@ -1265,130 +1057,44 @@ describe('BescheidService', () => { }); }); - describe('refresh list', () => { - it('should call refresh on list resource service', () => { - service.bescheidListResourceService.refresh = jest.fn(); - - service.refreshList(); - - expect(service.bescheidListResourceService.refresh).toHaveBeenCalled(); - }); - }); - - describe('uploadAttachment', () => { - const bescheidResource: BescheidResource = createBescheidResource([BescheidLinkRel.UPLOAD_ATTACHMENT]); - const file: File = createFile(); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); + describe('exist bescheid', () => { + const bescheid: BescheidResource = createBescheidResource(); + const bescheide: BescheidResource[] = [bescheid]; + const bescheidListStateResource: StateResource<BescheidListResource> = createStateResource( + createBescheidListResource(bescheide), + ); + let getItemsSpy: jest.SpyInstance; beforeEach(() => { - binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource)); - service.handleAttachmentUpload = jest.fn(); - }); - - it('should emit upload in progress', () => { - service.uploadAttachment(bescheidResource, file).subscribe(); - - expect(service.getUploadAttachmentInProgress()).toBeObservable( - singleCold({ fileName: file.name, loading: true } as UploadFileInProgress), - ); - }); - - it('should upload file', (done) => { - service.uploadAttachment(bescheidResource, file).subscribe(() => { - expect(binaryFileService.uploadFile).toHaveBeenCalledWith( - bescheidResource, - BescheidLinkRel.UPLOAD_ATTACHMENT, - file, - false, - ); - done(); - }); - }); - - it('should handle attachment upload', (done) => { - service.uploadAttachment(bescheidResource, file).subscribe(() => { - expect(service.handleAttachmentUpload).toHaveBeenCalledWith(binaryFileStateResource); - done(); - }); - }); - - it('should emit uploaded binary file', () => { - expect(service.uploadAttachment(bescheidResource, file)).toBeObservable(singleColdCompleted(binaryFileStateResource)); - }); - }); - - describe('handleAttachmentUpload', () => { - describe('on error', () => { - const binaryFileStateResource: StateResource<BinaryFileResource> = createErrorStateResource(createApiError()); - - it('should emit upload in progress', () => { - service.handleAttachmentUpload(binaryFileStateResource); - - expect(service.getUploadAttachmentInProgress()).toBeObservable( - singleCold({ - loading: false, - error: binaryFileStateResource.error, - } as UploadFileInProgress), - ); - }); - - it('should emit binary file', () => { - service.handleAttachmentUpload(binaryFileStateResource); - - expect(service.getUploadedAttachment()).toBeObservable(singleCold(binaryFileStateResource)); - }); + service.getBescheidList = jest.fn().mockReturnValue(of(bescheidListStateResource)); + service.filterBySentStatus = jest.fn().mockReturnValue(bescheide); + getItemsSpy = bescheidListResourceService.getItems = jest.fn().mockReturnValue(of(bescheide)); }); - describe('on success', () => { - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); - - it('should emit upload in progress', () => { - service.handleAttachmentUpload(binaryFileStateResource); - - expect(service.getUploadAttachmentInProgress()).toBeObservable( - singleCold({ - loading: false, - } as UploadFileInProgress), - ); - }); - - it('should emit binary file', () => { - service.handleAttachmentUpload(binaryFileStateResource); + it('should get items', () => { + service.existBescheid().subscribe(); - expect(service.getUploadedAttachment()).toBeObservable(singleCold(binaryFileStateResource)); - }); + expect(getItemsSpy).toHaveBeenCalled(); }); - }); - - describe('clear attachment upload', () => { - it('should clear stateresource', () => { - service.uploadAttachmentInProgress$.next(createStateResource(createUploadFileInProgress())); - service.clearAttachmentUpload(); + it('should filter by sent status', () => { + service.existBescheid().subscribe(); - expect(service.uploadAttachmentInProgress$.value).toEqual(createEmptyStateResource()); + expect(service.filterBySentStatus).toHaveBeenCalledWith(bescheide); }); - }); - describe('exit', () => { - it('should refresh bescheid list', () => { - service.bescheidListResourceService.refresh = jest.fn(); - - service.exit(); + it('should return true if at least one bescheid exists', () => { + const existBescheid$: Observable<boolean> = service.existBescheid(); - expect(service.bescheidListResourceService.refresh).toHaveBeenCalled(); + expect(existBescheid$).toBeObservable(singleColdCompleted(true)); }); - it('should reload current vorgang', () => { - service.exit(); - - expect(vorgangService.reloadCurrentVorgang).toHaveBeenCalled(); - }); + it('should return false if no bescheide exists', () => { + service.filterBySentStatus = jest.fn().mockReturnValue([]); - it('should reload postfach list', () => { - service.exit(); + const existBescheid$: Observable<boolean> = service.existBescheid(); - expect(postfachService.setPostfachMailOnReload).toHaveBeenCalled(); + expect(existBescheid$).toBeObservable(singleColdCompleted(false)); }); }); }); diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts index b2f3df0020b5498bfc5784d12f5a93c40af0ed9c..22107e92d9b6ff28981edc35f13ab3da9b8880b8 100644 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts +++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den + * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den * Ministerpräsidenten des Landes Schleswig-Holstein * Staatskanzlei * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung @@ -21,13 +21,38 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BinaryFileListLinkRel, BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared'; import { - CommandListResourceService, - CommandListResourceServiceConfig, + Bescheid, + BESCHEID_UPLOADED_ATTACHMENTS, + BescheidDocument, + BescheidLinkRel, + BescheidListResource, + BescheidResource, + BescheidSendBy, + BescheidStatus, + BescheidWizardStep, + buildCreateBescheidCommand, + buildCreateBescheidDocumentCommandProps, + buildCreateBescheidDocumentFromFileProps, + buildSendBescheidCommandProps, + buildUpdateBescheidCommandProps, + createBescheidListResourceService, + createBescheidResourceService, + createEmptyBescheidDocument, + createEmptyUploadInProgress, + createInitialWizard, + DocumentResource, + Wizard, +} from '@alfa-client/bescheid-shared'; +import { + BinaryFileListLinkRel, + BinaryFileListResource, + BinaryFileResource, + BinaryFileService, +} from '@alfa-client/binary-file-shared'; +import { CommandOrder, CommandResource, - CommandResourceService, CommandService, getEffectedResourceUrl, notHasCommandError, @@ -35,12 +60,6 @@ import { } from '@alfa-client/command-shared'; import { PostfachService } from '@alfa-client/postfach-shared'; import { - HttpError, - ResourceListService, - ResourceRepository, - ResourceServiceConfig, - StateResource, - StateService, createEmptyStateResource, createStateResource, filterIsLoadedOrHasError, @@ -49,294 +68,155 @@ import { isLoaded, isNotEmpty, isNotNil, + ResourceRepository, sortByGermanDateStr, + StateResource, } from '@alfa-client/tech-shared'; -import { - VorgangCommandService, - VorgangService, - VorgangWithEingangLinkRel, - VorgangWithEingangResource, -} from '@alfa-client/vorgang-shared'; -import { getEmpfaenger } from '@alfa-client/vorgang-shared-ui'; -import { Injectable } from '@angular/core'; -import { ResourceUri, getUrl, hasLink } from '@ngxp/rest'; -import { BehaviorSubject, Observable, Subscription, filter, first, map, startWith, switchMap, take, tap } from 'rxjs'; +import { VorgangCommandService, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { inject, Injectable } from '@angular/core'; +import { getUrl, hasLink, LinkRel, Resource, ResourceUri } from '@ngxp/rest'; +import { isNil } from 'lodash-es'; +import { BehaviorSubject, filter, first, map, Observable, startWith, switchMap } from 'rxjs'; import { BescheidFacade } from './+state/bescheid.facade'; -import { BESCHEID_DRAFT_PATH, BESCHEID_FEATURE_KEY } from './+state/bescheid.reducer'; -import { BescheidLinkRel, BescheidListLinkRel } from './bescheid.linkrel'; -import { - Bescheid, - BescheidListResource, - BescheidResource, - BescheidStatus, - BescheidWizardStep, - UploadFileInProgress, -} from './bescheid.model'; -import { - buildCreateBescheidCommand, - buildCreateBescheidDocumentCommandProps, - buildCreateBescheidDocumentFromFileProps, - buildSendBescheidCommandProps, -} from './bescheid.util'; import { DocumentLinkRel } from './document.linkrel'; -import { DocumentResource } from './document.model'; @Injectable({ providedIn: 'root' }) export class BescheidService { - readonly activeStep$: BehaviorSubject<BescheidWizardStep> = new BehaviorSubject(BescheidWizardStep.AntragBescheiden); - - bescheidResourceService: CommandResourceService<VorgangWithEingangResource, BescheidResource>; - bescheidListResourceService: ResourceListService<VorgangWithEingangResource, BescheidListResource, BescheidResource>; - - readonly bescheidDocumentFile$: BehaviorSubject<StateResource<BinaryFileResource>> = new BehaviorSubject< - StateResource<BinaryFileResource> - >(createEmptyStateResource()); - - readonly bescheidDocumentUri$: BehaviorSubject<ResourceUri> = new BehaviorSubject<ResourceUri>(null); - - readonly bescheidDocument$: BehaviorSubject<StateResource<DocumentResource>> = new BehaviorSubject< - StateResource<DocumentResource> - >(createEmptyStateResource()); - - readonly bescheidList$: BehaviorSubject<StateResource<BescheidListResource>> = new BehaviorSubject( - createEmptyStateResource<BescheidListResource>(), - ); - - readonly createBescheidDocumentInProgress$: BehaviorSubject<StateResource<CommandResource>> = new BehaviorSubject< - StateResource<CommandResource> - >(createEmptyStateResource()); - - readonly uploadBescheidDocumentInProgress$: BehaviorSubject<UploadFileInProgress> = new BehaviorSubject<UploadFileInProgress>({ - loading: false, - }); - - readonly uploadAttachmentInProgress$: BehaviorSubject<UploadFileInProgress> = new BehaviorSubject({ loading: false }); - - readonly uploadedAttachment$: BehaviorSubject<StateResource<BinaryFileResource>> = new BehaviorSubject( - createEmptyStateResource(), + private readonly bescheidFacade = inject(BescheidFacade); + private readonly commandService = inject(CommandService); + private readonly vorgangCommandService = inject(VorgangCommandService); + private readonly binaryFileService = inject(BinaryFileService); + private readonly resourceRepository = inject(ResourceRepository); + private readonly postfachService = inject(PostfachService); + private readonly vorgangService = inject(VorgangService); + // The injection of this services is problematic. + // It must be analysed how to inject BescheidService via providers in BescheidSharedModule. + private readonly bescheidResourceService = createBescheidResourceService( + this.resourceRepository, + this.commandService, + this.vorgangService, ); - - loadBescheidDocumentSubscription: Subscription; - - constructor( - private readonly facade: BescheidFacade, - private readonly vorgangService: VorgangService, - private readonly commandService: CommandService, - private readonly vorgangCommandService: VorgangCommandService, - private readonly binaryFileService: BinaryFileService, - private readonly repository: ResourceRepository<BescheidResource>, - private readonly postfachService: PostfachService, - private readonly stateService: StateService, - ) { - this.bescheidResourceService = new CommandResourceService( - this.buildBescheidDraftServiceConfig(), - this.stateService, - this.commandService, - ); - this.bescheidListResourceService = new CommandListResourceService< - VorgangWithEingangResource, - BescheidListResource, - BescheidResource - >( - this.buildBescheidListServiceConfig(), - repository, - commandService, - ); - } - - public getActiveStep(): Observable<BescheidWizardStep> { - return this.activeStep$.asObservable(); - } - - public setActiveStep(step: BescheidWizardStep): void { - this.activeStep$.next(step); - } - - buildBescheidDraftServiceConfig(): ResourceServiceConfig<VorgangWithEingangResource> { - return { - stateInfo: { name: BESCHEID_FEATURE_KEY, path: BESCHEID_DRAFT_PATH }, - baseResource: this.vorgangService.getVorgangWithEingang(), - getLinkRel: VorgangWithEingangLinkRel.BESCHEID_DRAFT, - delete: { linkRel: BescheidLinkRel.DELETE, order: CommandOrder.DELETE_BESCHEID }, - edit: { linkRel: BescheidLinkRel.UPDATE, order: CommandOrder.UPDATE_BESCHEID }, - }; - } - - buildBescheidListServiceConfig(): CommandListResourceServiceConfig<VorgangWithEingangResource> { - return { - baseResource: this.vorgangService.getVorgangWithEingang(), - getLinkRel: VorgangWithEingangLinkRel.BESCHEIDE, - listResourceListLinkRel: BescheidListLinkRel.BESCHEID_LIST, - }; - } + private readonly bescheidListResourceService = createBescheidListResourceService(this.resourceRepository, this.vorgangService); + // + readonly _bescheidDocument$: BehaviorSubject<BescheidDocument> = new BehaviorSubject(createEmptyBescheidDocument()); + readonly _wizard$: BehaviorSubject<Wizard> = new BehaviorSubject(createInitialWizard()); public init(): void { - this.bescheidDocumentFile$.next(createEmptyStateResource()); - this.bescheidDocumentUri$.next(null); - this.uploadBescheidDocumentInProgress$.next({ loading: false }); - this.clearUploadAttachment(); - this.uploadAttachmentInProgress$.next({ loading: false }); - this.activeStep$.next(BescheidWizardStep.AntragBescheiden); - } - - public getBescheidDraft(): Observable<StateResource<BescheidResource>> { - return this.bescheidResourceService.get(); - } - - public getBescheidCommand(): Observable<StateResource<CommandResource>> { - return this.facade.getBescheidCommand(); + this._wizard$.next(createInitialWizard()); + this._bescheidDocument$.next(createEmptyBescheidDocument()); } - public createBescheid( - vorgangWithEingang: VorgangWithEingangResource, - bescheid?: Bescheid, - ): Observable<StateResource<CommandResource>> { - this.facade.createBescheidDraft(vorgangWithEingang, buildCreateBescheidCommand(bescheid)); - return this.getBescheidCommand().pipe( - tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => - this.updateBescheidDraft(commandStateResource.resource), - ), - ); + public exit(): void { + this.bescheidListResourceService.refresh(); + this.postfachService._setPostfachMailOnReload(); + this._clearUploadedFiles(); } - public bescheidErstellungUeberspringen( + public skipBescheidCreation( vorgangWithEingangResource: VorgangWithEingangResource, + bescheidResource: BescheidResource, ): Observable<StateResource<CommandResource>> { - if (!this.existsBescheidDraft()) { - return this.vorgangAbschliesen(vorgangWithEingangResource); + if (isNil(bescheidResource)) { + return this.vorgangCommandService.abschliessen(vorgangWithEingangResource); } - return this.getBescheidDraft().pipe( - filter(isLoaded), - first(), - switchMap(() => this.bescheidLoeschenUndErstellungUeberspringen(vorgangWithEingangResource)), - ); + return this.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource); } - public getBescheidDraftIfExists(): Observable<StateResource<BescheidResource>> { - return this.vorgangService.getVorgangWithEingang().pipe( - filter( - (stateResource: StateResource<VorgangWithEingangResource>) => - isLoaded(stateResource) && hasLink(stateResource.resource, VorgangWithEingangLinkRel.BESCHEID_DRAFT), - ), - switchMap(() => this.getBescheidDraft()), - startWith(createEmptyStateResource<BescheidResource>()), - ); - } - - bescheidLoeschenUndErstellungUeberspringen( + deleteBescheidAndCompleteVorgang( vorgangWithEingangResource: VorgangWithEingangResource, ): Observable<StateResource<CommandResource>> { - return this.vorgangAbschliesen(vorgangWithEingangResource).pipe(tapOnCommandSuccessfullyDone(() => this.deleteBescheid())); - } - - vorgangAbschliesen(vorgangWithEingangResource: VorgangWithEingangResource): Observable<StateResource<CommandResource>> { - return this.vorgangCommandService.abschliessen(vorgangWithEingangResource); - } - - public updateBescheid(bescheid: Bescheid): Observable<StateResource<CommandResource>> { - return this.bescheidResourceService.save(bescheid).pipe( - tapOnCommandSuccessfullyDone(() => { - this.clearCreateBescheidDocumentInProgress(); - this.clearUploadBescheidDocumentInProgress(); - this.clearUploadAttachment(); - }), - ); - } - - private clearUploadAttachment() { - this.uploadedAttachment$.next(createEmptyStateResource()); - } - - public sendBescheidToAntragsteller(bescheidResource: BescheidResource): Observable<StateResource<CommandResource>> { - return this.sendBescheid(bescheidResource, BescheidLinkRel.BESCHEIDEN_UND_SENDEN); - } - - public sendBescheidManually(bescheidResource: BescheidResource): Observable<StateResource<CommandResource>> { - return this.sendBescheid(bescheidResource, BescheidLinkRel.BESCHEIDEN); - } - - sendBescheid(bescheidResource: BescheidResource, linkRel: string): Observable<StateResource<CommandResource>> { - return this.bescheidResourceService.get().pipe( - filterIsLoadedOrHasError(), - switchMap((stateResource: StateResource<BescheidResource>) => - this.commandService.createCommandByProps(buildSendBescheidCommandProps(stateResource.resource, linkRel)), - ), - ); + return this.vorgangCommandService + .abschliessen(vorgangWithEingangResource) + .pipe(tapOnCommandSuccessfullyDone(() => this.deleteBescheid())); } - private updateBescheidDraft(command: CommandResource): void { - this.bescheidResourceService.loadByResourceUri(getEffectedResourceUrl(command)); + public deleteBescheid(): Observable<StateResource<CommandResource>> { + return this.bescheidResourceService.delete(); } - public getAttachments(): Observable<BinaryFileResource[]> { - return this.getBescheidDraft().pipe( - filter(isLoaded), - map((stateResource: StateResource<BescheidResource>) => stateResource.resource), - filter((resource: BescheidResource) => hasLink(resource, BescheidLinkRel.ATTACHMENTS)), - switchMap((resource: BescheidResource) => this.binaryFileService.getFiles(resource, BescheidLinkRel.ATTACHMENTS)), - filter(isLoaded), - map((stateResource) => getEmbeddedResources<BinaryFileResource>(stateResource, BinaryFileListLinkRel.FILE_LIST)), - ); + public loadFiles(bescheidResource: BescheidResource): void { + this.loadBescheidDocument(bescheidResource); + this.loadAttachments(bescheidResource); } - public getDocumentUri(): Observable<ResourceUri> { - return this.bescheidDocumentUri$.asObservable(); + public createBescheidDocument(bescheidResource: BescheidResource): void { + this._bescheidDocument$.next({ ...createEmptyBescheidDocument(), create: createEmptyStateResource(true) }); + this.doCreateBescheidDocument(bescheidResource) + .pipe(filterIsLoadedOrHasError(), first()) + .subscribe((commandStateResource: StateResource<CommandResource>) => + this.handleCreateBescheidDocumentResponse(commandStateResource), + ); } - public setDocumentUri(uri: ResourceUri): void { - this.bescheidDocumentUri$.next(uri); + doCreateBescheidDocument(bescheidResource: BescheidResource): Observable<StateResource<CommandResource>> { + return this.commandService.createCommandByProps(buildCreateBescheidDocumentCommandProps(bescheidResource)); } - public existBescheidDocumentFile(): Observable<boolean> { - return this.bescheidDocumentFile$.asObservable().pipe(map(isLoaded)); + handleCreateBescheidDocumentResponse(commandStateResource: StateResource<CommandResource>): void { + if (notHasCommandError(commandStateResource.resource)) { + const documentUri: ResourceUri = getEffectedResourceUrl(commandStateResource.resource); + this._bescheidDocument$.next({ ...this._bescheidDocument$.value, documentUri }); + this.loadBescheidDocumentByUri(documentUri); + } else { + this._bescheidDocument$.next({ ...this._bescheidDocument$.value, create: commandStateResource }); + } } - public getBescheidDocumentFile(): Observable<StateResource<BinaryFileResource>> { - return this.bescheidDocumentFile$.asObservable(); + emitBescheidDocumentError(stateResource: StateResource<Resource>): void { + const value: BescheidDocument = this._bescheidDocument$.value; + this._bescheidDocument$.next({ + ...value, + upload: { ...value.upload, loading: false, error: stateResource.error }, + }); } - public getBescheidDocument(): Observable<StateResource<DocumentResource>> { - return this.bescheidDocument$.asObservable(); + loadBescheidDocument(bescheidResource: BescheidResource): void { + if (hasLink(bescheidResource, BescheidLinkRel.BESCHEID_DOCUMENT)) { + this.loadBescheidDocumentByUri(getUrl(bescheidResource, BescheidLinkRel.BESCHEID_DOCUMENT)); + } } public loadBescheidDocumentByUri(resourceUri: ResourceUri): void { - this.setBescheidDocumentFileLoading(); - this.loadBescheidDocumentSubscription = this.repository + this.resourceRepository .getResource(resourceUri) - .pipe() - .subscribe((document: DocumentResource) => { - this.bescheidDocument$.next(createStateResource(document)); - this.loadBescheidDocumentFile(document); - this.loadBescheidDocumentSubscription.unsubscribe(); - }); - } - - setBescheidDocumentFileLoading(): void { - this.bescheidDocumentFile$.next({ ...this.bescheidDocumentFile$.value, loading: true }); + .pipe(first()) + .subscribe((document: DocumentResource) => this.loadBescheidDocumentFile(document)); } - public uploadBescheidDocument(bescheid: BescheidResource, file: File): Observable<UploadFileInProgress> { - this.clearCreateBescheidDocumentInProgress(); - this.initUploadBescheidDocumentInProgress(file.name); - this.doUploadBescheidDocument(bescheid, file); - return this.getUploadBescheidDocumentInProgress(); - } - - private clearCreateBescheidDocumentInProgress(): void { - this.createBescheidDocumentInProgress$.next(createEmptyStateResource()); - } - - private initUploadBescheidDocumentInProgress(fileName: string): void { - this.uploadBescheidDocumentInProgress$.next({ fileName, loading: true }); + loadBescheidDocumentFile(document: DocumentResource): void { + this.binaryFileService + .getFile(getUrl(document, DocumentLinkRel.FILE)) + .pipe(filterIsLoadedOrHasError(), first()) + .subscribe((binaryFile: StateResource<BinaryFileResource>) => { + this._bescheidDocument$.next({ + ...this._bescheidDocument$.value, + upload: createEmptyUploadInProgress(), + create: createEmptyStateResource(), + resource: binaryFile.resource, + documentUri: getUrl(document, LinkRel.Self), + }); + }); } - public getUploadBescheidDocumentInProgress(): Observable<UploadFileInProgress> { - return this.uploadBescheidDocumentInProgress$.asObservable(); + loadAttachments(bescheidResource: BescheidResource): void { + if (hasLink(bescheidResource, BescheidLinkRel.ATTACHMENTS)) { + this.binaryFileService + .getFiles(bescheidResource, BescheidLinkRel.ATTACHMENTS) + .pipe( + filterIsLoadedOrHasError(), + first(), + map((stateResource: StateResource<BinaryFileListResource>) => + getEmbeddedResources<BinaryFileResource>(stateResource, BinaryFileListLinkRel.FILE_LIST), + ), + ) + .subscribe((files: BinaryFileResource[]) => this.binaryFileService.addFiles(BESCHEID_UPLOADED_ATTACHMENTS, files)); + } } - doUploadBescheidDocument(bescheid: BescheidResource, file: File): void { + public uploadBescheidDocument(document: File, bescheid: BescheidResource): void { + this._bescheidDocument$.next({ ...this._bescheidDocument$.value, upload: { fileName: document.name, loading: true } }); this.binaryFileService - .uploadFile(bescheid, BescheidLinkRel.UPLOAD_BESCHEID_FILE, file, false) + .uploadFile(bescheid, BescheidLinkRel.UPLOAD_BESCHEID_FILE, document, false) .pipe(filterIsLoadedOrHasError(), first()) .subscribe((binaryFileStateResource: StateResource<BinaryFileResource>) => this.handleUploadBescheidDocumentResponse(bescheid, binaryFileStateResource), @@ -348,7 +228,7 @@ export class BescheidService { binaryFileStateResource: StateResource<BinaryFileResource>, ): void { if (hasStateResourceError(binaryFileStateResource)) { - this.setUploadBescheidDocumentInProgressError(binaryFileStateResource.error); + this.emitBescheidDocumentError(binaryFileStateResource); } else { this.createBescheidDocumentFromFile(bescheid, binaryFileStateResource.resource); } @@ -368,203 +248,167 @@ export class BescheidService { binaryFile: BinaryFileResource, ): void { if (hasStateResourceError(commandStateResource)) { - this.setUploadBescheidDocumentInProgressError(commandStateResource.error); + this.emitBescheidDocumentError(commandStateResource); } else { - this.bescheidDocument$.next(createEmptyStateResource()); - this.bescheidDocumentFile$.next(createStateResource(binaryFile)); - this.bescheidDocumentUri$.next(getEffectedResourceUrl(commandStateResource.resource)); - this.clearUploadBescheidDocumentInProgress(); + this._bescheidDocument$.next({ + ...this._bescheidDocument$.value, + documentUri: getEffectedResourceUrl(commandStateResource.resource), + upload: createEmptyUploadInProgress(), + resource: binaryFile, + }); } } - private setUploadBescheidDocumentInProgressError(error: HttpError): void { - this.uploadBescheidDocumentInProgress$.next({ loading: false, error }); - } - - public deleteBescheidDocument(): void { - this.bescheidDocumentUri$.next(null); - this.bescheidDocumentFile$.next(createEmptyStateResource()); - this.bescheidDocument$.next(createEmptyStateResource()); - } - - public createBescheidDocument(): Observable<StateResource<CommandResource>> { - this.clearUploadBescheidDocumentInProgress(); - this.setCreateBescheidDocumentInProgress(); - this.doCreateBescheidDocument() - .pipe(filterIsLoadedOrHasError(), first()) - .subscribe((commandStateResource: StateResource<CommandResource>) => - this.handleCreateBescheidDocumentResponse(commandStateResource), + public createBescheid( + vorgangWithEingang: VorgangWithEingangResource, + bescheid?: Bescheid, + ): Observable<StateResource<CommandResource>> { + this.bescheidFacade.createBescheidDraft(vorgangWithEingang, buildCreateBescheidCommand(bescheid)); + return this.bescheidFacade + .getBescheidCommand() + .pipe( + tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => + this.updateBescheidDraft(commandStateResource.resource), + ), ); - return this.getCreateBescheidDocumentInProgress(); } - private clearUploadBescheidDocumentInProgress(): void { - this.uploadBescheidDocumentInProgress$.next({ loading: false }); + updateBescheidDraft(command: CommandResource): void { + this.bescheidResourceService.loadByResourceUri(getEffectedResourceUrl(command)); + if (command.order === CommandOrder.CREATE_BESCHEID) { + this._wizard$.next({ ...this._wizard$.value, bescheidCreated: true }); + } } - public getCreateBescheidDocumentInProgress(): Observable<StateResource<CommandResource>> { - return this.createBescheidDocumentInProgress$.asObservable(); + public updateBescheid( + bescheidResource: BescheidResource, + updatedBescheid: Bescheid, + ): Observable<StateResource<CommandResource>> { + return this.doUpdateBescheid(bescheidResource, updatedBescheid).pipe( + tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => { + this.updateBescheidDraft(commandStateResource.resource); + }), + ); } - private setCreateBescheidDocumentInProgress(): void { - this.createBescheidDocumentInProgress$.next(createEmptyStateResource(true)); + doUpdateBescheid(bescheidResource: BescheidResource, bescheid: Bescheid): Observable<StateResource<CommandResource>> { + return this.commandService.createCommandByProps(buildUpdateBescheidCommandProps(bescheidResource, bescheid)); } - doCreateBescheidDocument(): Observable<StateResource<CommandResource>> { - return this.commandService.createCommandByProps(buildCreateBescheidDocumentCommandProps(this.getResource())); + public sendBescheidManually(): Observable<StateResource<CommandResource>> { + return this.sendBescheid(BescheidLinkRel.BESCHEIDEN); } - private handleCreateBescheidDocumentResponse(commandStateResource: StateResource<CommandResource>): void { - this.createBescheidDocumentInProgress$.next(commandStateResource); - if (notHasCommandError(commandStateResource.resource)) { - const documentUri: ResourceUri = getEffectedResourceUrl(commandStateResource.resource); - this.bescheidDocumentUri$.next(documentUri); - this.loadBescheidDocumentByUri(documentUri); - } + public sendBescheidMessage(): Observable<StateResource<CommandResource>> { + return this.sendBescheid(BescheidLinkRel.BESCHEIDEN_UND_SENDEN); } - loadBescheidDocumentFile(document: DocumentResource): void { - this.binaryFileService - .getFile(getUrl(document, DocumentLinkRel.FILE)) - .pipe(filterIsLoadedOrHasError(), first()) - .subscribe((binaryFile) => { - this.bescheidDocumentFile$.next(binaryFile); - this.createBescheidDocumentInProgress$.next(createEmptyStateResource()); - }); + sendBescheid(linkRel: BescheidLinkRel): Observable<StateResource<CommandResource>> { + return this.getBescheidDraft().pipe( + filter(isLoaded), + map((stateResource: StateResource<BescheidResource>) => stateResource.resource), + switchMap((bescheidResource: BescheidResource) => + this.commandService.createCommandByProps(buildSendBescheidCommandProps(bescheidResource, linkRel)), + ), + ); } - public getBescheidDocumentCommand(): Observable<StateResource<CommandResource>> { - return this.commandService.getCommandByOrder(CommandOrder.CREATE_BESCHEID_DOCUMENT); + public getBescheidDraft(): Observable<StateResource<BescheidResource>> { + return this.bescheidResourceService.get(); } - public existsBescheidDraft(): boolean { - let exists: boolean; - this.bescheidResourceService - .existResource() - .pipe(take(1)) - .subscribe((existsDraft: boolean) => (exists = existsDraft)); - return exists; + public getBescheidDocument(): Observable<BescheidDocument> { + return this._bescheidDocument$.asObservable(); } - public bescheidVerwerfen(): Observable<StateResource<CommandResource>> { - return this.deleteBescheid().pipe( - tapOnCommandSuccessfullyDone(() => { - this.deleteBescheidDocument(); - this.vorgangService.reloadCurrentVorgang(); - }), - ); + public deleteBescheidDocument(): void { + this._bescheidDocument$.next(createEmptyBescheidDocument()); } - deleteBescheid(): Observable<StateResource<CommandResource>> { - return this.bescheidResourceService.delete(); + public getActiveStep(): Observable<BescheidWizardStep> { + return this._wizard$.asObservable().pipe(map((wizard: Wizard) => wizard.activeStep)); } - /** - * @returns @deprecated Don't use this function, instead pass data to function if necessarry. - */ - getResource(): BescheidResource { - let resource: StateResource<BescheidResource> = undefined; - this.bescheidResourceService - .selectResource() - .pipe(take(1)) - .subscribe((stateResource: StateResource<BescheidResource>) => (resource = stateResource)); - - return resource.resource; + public setActiveStep(step: BescheidWizardStep): void { + this._clearUploadedFiles(); + this._wizard$.next({ ...this._wizard$.value, activeStep: step }); } - public reloadCurrentVorgang(): void { - this.vorgangService.reloadCurrentVorgang(); + public getBescheidCreated(): Observable<boolean> { + return this._wizard$.asObservable().pipe(map((wizard: Wizard) => wizard.bescheidCreated)); } - public loadBescheidDocument(resourceUri: ResourceUri): Observable<StateResource<DocumentResource>> { - return this.repository.getResource<DocumentResource>(resourceUri).pipe( - map((documentResource: DocumentResource) => createStateResource(documentResource)), - startWith(createEmptyStateResource<DocumentResource>(true)), - ); + public selectBescheidResource(): Observable<StateResource<BescheidResource>> { + return this.bescheidResourceService.selectResource(); } - public getEmpfaenger(): Observable<string> { - return this.vorgangService.getVorgangWithEingang().pipe( - filter(isLoaded), - map((stateResource) => stateResource.resource), - map(getEmpfaenger), - ); + public getWizard(): Observable<Wizard> { + return this._wizard$.asObservable(); } - public getLastBescheid(): Observable<BescheidResource> { - return this.bescheidListResourceService.getItems().pipe( - map((bescheide: BescheidResource[]) => this.filterBySentStatus(bescheide)), - map((bescheide: BescheidResource[]) => this.sortByBeschiedenAm(bescheide)), - map((bescheide: BescheidResource[]) => bescheide[0]), - ); + public setSendBy(sendBy: BescheidSendBy): void { + this._wizard$.next({ ...this._wizard$.value, sendBy: sendBy }); } - private sortByBeschiedenAm(bescheide: BescheidResource[]): BescheidResource[] { - return sortByGermanDateStr<BescheidResource>(bescheide, (bescheid: BescheidResource) => bescheid.beschiedenAm); + public setNachrichtEmpfaenger(empfaenger: string): void { + this._wizard$.next({ ...this._wizard$.value, empfaenger: empfaenger }); } - public existBescheid(): Observable<boolean> { - return this.bescheidListResourceService.getItems().pipe( - map((bescheide: BescheidResource[]) => this.filterBySentStatus(bescheide)), - map((bescheide: BescheidResource[]) => isNotEmpty(bescheide)), - ); + public lockBescheidSending(): void { + this._wizard$.next({ ...this._wizard$.value, canBeSend: false }); } - public getBescheidList(): Observable<StateResource<BescheidListResource>> { - return this.bescheidListResourceService.getList(); + public unlockBescheidSending(): void { + this._wizard$.next({ ...this._wizard$.value, canBeSend: true }); } - filterBySentStatus(bescheide: BescheidResource[]): BescheidResource[] { - return isNotNil(bescheide) ? bescheide.filter(this.hasSentStatus) : []; + public finishAddingBescheidDocument(): void { + this._bescheidDocument$.next({ + ...this._bescheidDocument$.value, + upload: createEmptyUploadInProgress(), + create: createEmptyStateResource(), + }); } - private hasSentStatus(bescheid: BescheidResource): boolean { - return bescheid.status === BescheidStatus.SENT; + _clearUploadedFiles(): void { + this.binaryFileService.clearUploadedFiles(BESCHEID_UPLOADED_ATTACHMENTS); } - public refreshList(): void { - this.bescheidListResourceService.refresh(); + public getBescheidList(): Observable<StateResource<BescheidListResource>> { + return this.bescheidListResourceService.getList(); } - public uploadAttachment(bescheidResource: BescheidResource, file: File): Observable<StateResource<BinaryFileResource>> { - this.uploadAttachmentInProgress$.next({ fileName: file.name, loading: true }); - return this.binaryFileService - .uploadFile(bescheidResource, BescheidLinkRel.UPLOAD_ATTACHMENT, file, false) - .pipe( - tap((binaryFileStateResource: StateResource<BinaryFileResource>) => this.handleAttachmentUpload(binaryFileStateResource)), - ); + public getBescheidDocumentByUri(resourceUri: ResourceUri): Observable<StateResource<DocumentResource>> { + return this.resourceRepository.getResource<DocumentResource>(resourceUri).pipe( + map((documentResource: DocumentResource) => createStateResource(documentResource)), + startWith(createEmptyStateResource<DocumentResource>(true)), + ); } - handleAttachmentUpload(binaryFileStateResource: StateResource<BinaryFileResource>) { - if (hasStateResourceError(binaryFileStateResource)) { - this.uploadAttachmentInProgress$.next({ - loading: false, - error: binaryFileStateResource.error, - }); - } else { - this.uploadAttachmentInProgress$.next({ - ...this.uploadAttachmentInProgress$.value, - loading: binaryFileStateResource.loading, - }); - } - this.uploadedAttachment$.next(binaryFileStateResource); + public getLastBescheid(): Observable<BescheidResource> { + return this.bescheidListResourceService.getItems().pipe( + map((bescheide: BescheidResource[]) => this.filterBySentStatus(bescheide)), + map((bescheide: BescheidResource[]) => this.sortByBeschiedenAm(bescheide)), + map((bescheide: BescheidResource[]) => bescheide[0]), + ); } - public getUploadAttachmentInProgress(): Observable<UploadFileInProgress> { - return this.uploadAttachmentInProgress$.asObservable(); + filterBySentStatus(bescheide: BescheidResource[]): BescheidResource[] { + return isNotNil(bescheide) ? bescheide.filter(this.hasSentStatus) : []; } - public getUploadedAttachment(): Observable<StateResource<BinaryFileResource>> { - return this.uploadedAttachment$.asObservable(); + private hasSentStatus(bescheid: BescheidResource): boolean { + return bescheid.status === BescheidStatus.SENT; } - public clearAttachmentUpload(): void { - this.uploadAttachmentInProgress$.next(createEmptyStateResource()); + private sortByBeschiedenAm(bescheide: BescheidResource[]): BescheidResource[] { + return sortByGermanDateStr<BescheidResource>(bescheide, (bescheid: BescheidResource) => bescheid.beschiedenAm); } - public exit(): void { - this.bescheidListResourceService.refresh(); - this.vorgangService.reloadCurrentVorgang(); - this.postfachService.setPostfachMailOnReload(); + public existBescheid(): Observable<boolean> { + return this.bescheidListResourceService.getItems().pipe( + map((bescheide: BescheidResource[]) => this.filterBySentStatus(bescheide)), + map((bescheide: BescheidResource[]) => isNotEmpty(bescheide)), + ); } } diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid2.service.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid2.service.spec.ts deleted file mode 100644 index 9fbf45a5ca814d6ed15691e08259f1a664f836e0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid2.service.spec.ts +++ /dev/null @@ -1,888 +0,0 @@ -/* - * Copyright (C) 2023 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 { BinaryFileListLinkRel, BinaryFileListResource, BinaryFileResource, BinaryFileService, } from '@alfa-client/binary-file-shared'; -import { CommandOrder, CommandResource, CommandResourceService, CommandService, CreateCommandProps, getEffectedResourceUrl, } from '@alfa-client/command-shared'; -import { PostfachService } from '@alfa-client/postfach-shared'; -import { createEmptyStateResource, createErrorStateResource, createStateResource, EMPTY_STRING, getEmbeddedResources, StateResource, } from '@alfa-client/tech-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; -import { VorgangCommandService, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { TestBed } from '@angular/core/testing'; -import { faker } from '@faker-js/faker'; -import { getUrl, LinkRel, ResourceUri } from '@ngxp/rest'; -import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { createProblemDetail } from 'libs/tech-shared/test/error'; -import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; -import { EMPTY, Observable, of } from 'rxjs'; -import { createBinaryFileListResource, createBinaryFileResource } from '../../../binary-file-shared/test/binary-file'; -import { createCommandErrorStateResource, createCommandResource, createCommandStateResource, createCreateCommandProps, createSuccessfullyDoneCommandStateResource, } from '../../../command-shared/test/command'; -import { ResourceRepository } from '../../../tech-shared/src/lib/resource/resource.repository'; -import { createFile } from '../../../tech-shared/test/file'; -import { singleCold, singleColdCompleted } from '../../../tech-shared/test/marbles'; -import { createBescheid, createBescheidDocument, createBescheidResource } from '../test/bescheid'; -import { createDocumentResource } from '../test/document'; -import { BescheidFacade } from './+state/bescheid.facade'; -import { BescheidResourceService } from './bescheid-resource-service'; -import { BescheidLinkRel } from './bescheid.linkrel'; -import { Bescheid, BESCHEID_UPLOADED_ATTACHMENTS, BescheidDocument, BescheidResource, BescheidWizardStep, createEmptyBescheidDocument, createEmptyUploadInProgress, createInitialWizard, } from './bescheid.model'; -import { BescheidService2 } from './bescheid2.service'; -import { DocumentLinkRel } from './document.linkrel'; -import { DocumentResource } from './document.model'; - -import { expect } from '@jest/globals'; -import * as BescheidUtil from './bescheid.util'; - -describe('BescheidService', () => { - let service: BescheidService2; - - let facade: Mock<BescheidFacade>; - let vorgangService: Mock<VorgangService>; - let resourceRepository: Mock<ResourceRepository>; - let commandService: Mock<CommandService>; - let vorgangCommandService: Mock<VorgangCommandService>; - let binaryFileService: Mock<BinaryFileService>; - let postfachService: Mock<PostfachService>; - let bescheidResourceService: Mock<BescheidResourceService>; - - const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); - const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = - createStateResource(vorgangWithEingangResource); - const bescheidResource: BescheidResource = createBescheidResource(); - const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); - - beforeEach(() => { - facade = mock(BescheidFacade); - resourceRepository = mock(ResourceRepository); - commandService = mock(CommandService); - vorgangCommandService = mock(VorgangCommandService); - vorgangService = mock(VorgangService); - vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangWithEingangStateResource)); - binaryFileService = mock(BinaryFileService); - postfachService = mock(PostfachService); - bescheidResourceService = mock(CommandResourceService); - - TestBed.configureTestingModule({ - providers: [ - { provide: BescheidFacade, useValue: facade }, - { provide: VorgangService, useValue: vorgangService }, - { provide: ResourceRepository, useValue: resourceRepository }, - { provide: CommandService, useValue: commandService }, - { provide: VorgangCommandService, useValue: vorgangCommandService }, - { provide: BinaryFileService, useValue: binaryFileService }, - { - provide: PostfachService, - useValue: postfachService, - }, - { provide: BescheidResourceService, useValue: bescheidResourceService }, - BescheidService2, - ], - }); - - service = TestBed.inject(BescheidService2); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); - - describe('init', () => { - it('should init state', () => { - service.setActiveStep(2); - - service.init(); - - expect(service.getWizard()).toBeObservable(singleCold(createInitialWizard())); - expect(service.getActiveStep()).toBeObservable(singleCold(BescheidWizardStep.AntragBescheiden)); - expect(service.getBescheidCreated()).toBeObservable(singleCold(false)); - expect(service.getBescheidDocument()).toBeObservable(singleCold(createEmptyBescheidDocument())); - }); - }); - - describe('exit', () => { - beforeEach(() => { - service._clearUploadedFiles = jest.fn(); - }); - - it('should reload postfach list', () => { - service.exit(); - - expect(postfachService.setPostfachMailOnReload).toHaveBeenCalled(); - }); - - it('should clear uploaded files', () => { - service.exit(); - - expect(service._clearUploadedFiles).toHaveBeenCalled(); - }); - }); - - describe('skipBescheidCreation', () => { - beforeEach(() => { - service.deleteBescheidAndCompleteVorgang = jest.fn().mockReturnValue(of(commandStateResource)); - }); - - it('should complete vorgang', () => { - service.skipBescheidCreation(vorgangWithEingangResource, null); - - expect(vorgangCommandService.abschliessen).toHaveBeenCalledWith(vorgangWithEingangResource); - }); - - it('should NOT complete vorgang', () => { - service.skipBescheidCreation(vorgangWithEingangResource, bescheidResource); - - expect(vorgangCommandService.abschliessen).not.toHaveBeenCalled(); - }); - - it('should delete bescheid and complete vorgang', () => { - service.skipBescheidCreation(vorgangWithEingangResource, bescheidResource).subscribe(); - - expect(service.deleteBescheidAndCompleteVorgang).toHaveBeenCalledWith(vorgangWithEingangResource); - }); - - it('should return command', () => { - const command$: Observable<StateResource<CommandResource>> = service.skipBescheidCreation( - vorgangWithEingangResource, - bescheidResource, - ); - - expect(command$).toBeObservable(singleColdCompleted(commandStateResource)); - }); - }); - - describe('deleteBescheidAndCompleteVorgang', () => { - beforeEach(() => { - service.deleteBescheid = jest.fn().mockReturnValue(of(createCommandStateResource)); - vorgangCommandService.abschliessen.mockReturnValue(EMPTY); - }); - - it('should complete vorgang', () => { - service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - - expect(vorgangCommandService.abschliessen).toHaveBeenCalledWith(vorgangWithEingangResource); - }); - - it('should delete bescheid', () => { - vorgangCommandService.abschliessen.mockReturnValue(of(createSuccessfullyDoneCommandStateResource())); - - service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - - expect(service.deleteBescheid).toHaveBeenCalled(); - }); - - it('should NOT delete bescheid on loading', () => { - vorgangCommandService.abschliessen.mockReturnValue(of(createEmptyStateResource(true))); - - service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - - expect(service.deleteBescheid).not.toHaveBeenCalled(); - }); - - it('should NOT delete bescheid on error', () => { - vorgangCommandService.abschliessen.mockReturnValue(of(createErrorStateResource(createProblemDetail()))); - - service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource).subscribe(); - - expect(service.deleteBescheid).not.toHaveBeenCalled(); - }); - - it('should return vorgang abschliessen command', () => { - const command: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); - vorgangCommandService.abschliessen.mockReturnValue(of(command)); - - const command$: Observable<StateResource<CommandResource>> = - service.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource); - - expect(command$).toBeObservable(singleColdCompleted(command)); - }); - }); - - describe('delete bescheid', () => { - it('should create command', () => { - service.deleteBescheid(); - - expect(bescheidResourceService.delete).toHaveBeenCalled(); - }); - - it('should return command', () => { - const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); - bescheidResourceService.delete.mockReturnValue(of(commandStateResource)); - - const createdCommand$: Observable<StateResource<CommandResource>> = service.deleteBescheid(); - - expect(createdCommand$).toBeObservable(singleColdCompleted(commandStateResource)); - }); - }); - - describe('loadFiles', () => { - beforeEach(() => { - service.loadBescheidDocument = jest.fn(); - service.loadAttachments = jest.fn(); - }); - - it('should bescheid document', () => { - service.loadFiles(bescheidResource); - - expect(service.loadBescheidDocument).toHaveBeenCalledWith(bescheidResource); - }); - - it('should load attachments', () => { - service.loadFiles(bescheidResource); - - expect(service.loadAttachments).toHaveBeenCalledWith(bescheidResource); - }); - }); - - describe('create bescheid document', () => { - beforeEach(() => { - service.doCreateBescheidDocument = jest.fn().mockReturnValue(EMPTY); - service.handleCreateBescheidDocumentResponse = jest.fn(); - }); - - it('should emit bescheid document', () => { - service.createBescheidDocument(bescheidResource); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ ...createEmptyBescheidDocument(), create: createEmptyStateResource(true) }), - ); - }); - - it('should do create bescheid document', () => { - service.createBescheidDocument(bescheidResource); - - expect(service.doCreateBescheidDocument).toHaveBeenCalledWith(bescheidResource); - }); - - it('should handle create response on loaded', () => { - service.doCreateBescheidDocument = jest.fn().mockReturnValue(of(commandStateResource)); - - service.createBescheidDocument(bescheidResource); - - expect(service.handleCreateBescheidDocumentResponse).toHaveBeenCalledWith(commandStateResource); - }); - - it('should handle create response on error', () => { - const commandError: StateResource<CommandResource> = createCommandErrorStateResource(); - service.doCreateBescheidDocument = jest.fn().mockReturnValue(of(commandError)); - - service.createBescheidDocument(bescheidResource); - - expect(service.handleCreateBescheidDocumentResponse).toHaveBeenCalledWith(commandError); - }); - }); - - describe('doCreateBescheidDocument', () => { - it('should create command by props', () => { - service.doCreateBescheidDocument(bescheidResource); - - expect(commandService.createCommandByProps).toHaveBeenCalledWith({ - resource: bescheidResource, - linkRel: BescheidLinkRel.CREATE_DOCUMENT, - command: { - order: CommandOrder.CREATE_BESCHEID_DOCUMENT, - body: null, - }, - snackBarMessage: EMPTY_STRING, - }); - }); - }); - - describe('handleCreateBescheidDocumentResponse', () => { - const commandStateResource: StateResource<CommandResource> = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); - - beforeEach(() => { - service.loadBescheidDocumentByUri = jest.fn(); - service.emitBescheidDocumentError = jest.fn(); - }); - - it('should emit error', () => { - const commandErrorStateResource: StateResource<CommandResource> = createCommandErrorStateResource(); - - service.handleCreateBescheidDocumentResponse(commandErrorStateResource); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ ...createEmptyBescheidDocument(), create: commandErrorStateResource } as BescheidDocument), - ); - }); - - it('should emit bescheid document state', () => { - service.handleCreateBescheidDocumentResponse(commandStateResource); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ - ...createEmptyBescheidDocument(), - documentUri: getEffectedResourceUrl(commandStateResource.resource), - }), - ); - }); - - it('should load document by uri', () => { - service.handleCreateBescheidDocumentResponse(commandStateResource); - - expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(getEffectedResourceUrl(commandStateResource.resource)); - }); - }); - - describe('emitBescheidDocumentError', () => { - it('should emit', () => { - const commandError: StateResource<CommandResource> = createCommandErrorStateResource(); - - service.emitBescheidDocumentError(commandError); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ - ...createEmptyBescheidDocument(), - upload: { ...createEmptyUploadInProgress(), loading: false, error: commandError.error }, - }), - ); - }); - }); - - describe('loadBescheidDocument', () => { - beforeEach(() => { - service.loadBescheidDocumentByUri = jest.fn(); - }); - - it('should load by uri', () => { - const bescheidResource: BescheidResource = createBescheidResource([BescheidLinkRel.BESCHEID_DOCUMENT]); - - service.loadBescheidDocument(bescheidResource); - - expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(getUrl(bescheidResource, BescheidLinkRel.BESCHEID_DOCUMENT)); - }); - - it('should NOT load by uri', () => { - service.loadBescheidDocument(bescheidResource); - - expect(service.loadBescheidDocumentByUri).not.toHaveBeenCalled(); - }); - }); - - describe('loadBescheidDocumentByUri', () => { - const resourceUri: ResourceUri = faker.internet.url(); - - beforeEach(() => { - resourceRepository.getResource.mockReturnValue(EMPTY); - service.loadBescheidDocumentFile = jest.fn(); - }); - - it('should get resource', () => { - service.loadBescheidDocumentByUri(resourceUri); - - expect(resourceRepository.getResource).toHaveBeenCalledWith(resourceUri); - }); - - it('should load bescheid document file', () => { - const documentResource: DocumentResource = createDocumentResource(); - resourceRepository.getResource.mockReturnValue(of(documentResource)); - - service.loadBescheidDocumentByUri(resourceUri); - - expect(service.loadBescheidDocumentFile).toHaveBeenCalledWith(documentResource); - }); - }); - - describe('load bescheid document file', () => { - const document: DocumentResource = createDocumentResource([DocumentLinkRel.FILE]); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); - - beforeEach(() => { - binaryFileService.getFile.mockReturnValue(of(binaryFileStateResource)); - }); - - it('should call binary file service', () => { - service.loadBescheidDocumentFile(document); - - expect(binaryFileService.getFile).toHaveBeenCalledWith(getUrl(document, DocumentLinkRel.FILE)); - }); - - it('should emit bescheid document state', () => { - service.loadBescheidDocumentFile(document); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ - upload: createEmptyUploadInProgress(), - create: createEmptyStateResource(), - resource: binaryFileStateResource.resource, - documentUri: getUrl(document, LinkRel.Self), - }), - ); - }); - }); - - describe('loadAttachments', () => { - const bescheidResourceWithAttachments: BescheidResource = createBescheidResource([BescheidLinkRel.ATTACHMENTS]); - - beforeEach(() => { - binaryFileService.getFiles.mockReturnValue(EMPTY); - }); - - it('should call binary file service', () => { - service.loadAttachments(bescheidResourceWithAttachments); - - expect(binaryFileService.getFiles).toHaveBeenCalledWith(bescheidResourceWithAttachments, BescheidLinkRel.ATTACHMENTS); - }); - - it('should NOT call binary file service', () => { - service.loadAttachments(bescheidResource); - - expect(binaryFileService.getFiles).not.toHaveBeenCalled(); - }); - - it('should add files', () => { - const binaryFileListStateResource: StateResource<BinaryFileListResource> = - createStateResource(createBinaryFileListResource()); - binaryFileService.getFiles.mockReturnValue(of(binaryFileListStateResource)); - - service.loadAttachments(bescheidResourceWithAttachments); - - expect(binaryFileService.addFiles).toHaveBeenCalledWith( - BESCHEID_UPLOADED_ATTACHMENTS, - getEmbeddedResources(binaryFileListStateResource, BinaryFileListLinkRel.FILE_LIST), - ); - }); - }); - - describe('upload bescheid document', () => { - const documentFile: File = createFile(); - - beforeEach(() => { - binaryFileService.uploadFile.mockReturnValue(EMPTY); - service.handleUploadBescheidDocumentResponse = jest.fn(); - }); - - it('should emit bescheid document state', () => { - service.uploadBescheidDocument(documentFile, bescheidResource); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ ...createEmptyBescheidDocument(), upload: { fileName: documentFile.name, loading: true } }), - ); - }); - - it('should call binary file service', () => { - service.uploadBescheidDocument(documentFile, bescheidResource); - - expect(binaryFileService.uploadFile).toHaveBeenCalledWith( - bescheidResource, - BescheidLinkRel.UPLOAD_BESCHEID_FILE, - documentFile, - false, - ); - }); - - it('should handle upload response', () => { - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); - binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource)); - - service.uploadBescheidDocument(documentFile, bescheidResource); - - expect(service.handleUploadBescheidDocumentResponse).toHaveBeenCalledWith(bescheidResource, binaryFileStateResource); - }); - }); - - describe('handleUploadBescheidDocumentResponse', () => { - beforeEach(() => { - service.emitBescheidDocumentError = jest.fn(); - service.createBescheidDocumentFromFile = jest.fn(); - }); - - it('should emit error', () => { - const errorStateResource: StateResource<BinaryFileResource> = createErrorStateResource(createProblemDetail()); - - service.handleUploadBescheidDocumentResponse(bescheidResource, errorStateResource); - - expect(service.emitBescheidDocumentError).toHaveBeenCalledWith(errorStateResource); - }); - - it('should create bescheid document from file', () => { - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); - - service.handleUploadBescheidDocumentResponse(bescheidResource, binaryFileStateResource); - - expect(service.createBescheidDocumentFromFile).toHaveBeenCalledWith(bescheidResource, binaryFileStateResource.resource); - }); - }); - - describe('create bescheid document from file', () => { - const bescheid: BescheidResource = createBescheidResource(); - const binaryFile: BinaryFileResource = createBinaryFileResource(); - - const createCommandProps: CreateCommandProps = createCreateCommandProps(); - let buildCreateBescheidDocumentFromFilePropsSpy; - - const commandStateResource: StateResource<CommandResource> = createCommandStateResource(); - - beforeEach(() => { - buildCreateBescheidDocumentFromFilePropsSpy = jest - .spyOn(BescheidUtil, 'buildCreateBescheidDocumentFromFileProps') - .mockReturnValue(createCommandProps); - commandService.createCommandByProps.mockReturnValue(of(commandStateResource)); - }); - - it('should call command sevice', () => { - service.createBescheidDocumentFromFile(bescheid, binaryFile); - - expect(commandService.createCommandByProps).toHaveBeenCalledWith(createCommandProps); - }); - - it('should build create command document from file props', () => { - service.createBescheidDocumentFromFile(bescheid, binaryFile); - - expect(buildCreateBescheidDocumentFromFilePropsSpy).toHaveBeenCalledWith(bescheid, binaryFile); - }); - - it('should call handle create bescheid document from file response', () => { - service.handleCreateBescheidDocumentFromFileResponse = jest.fn(); - - service.createBescheidDocumentFromFile(bescheid, binaryFile); - - expect(service.handleCreateBescheidDocumentFromFileResponse).toHaveBeenCalledWith(commandStateResource, binaryFile); - }); - }); - - describe('handleCreateBescheidDocumentFromFileResponse', () => { - const commandStateResource: StateResource<CommandResource> = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); - - beforeEach(() => { - service.emitBescheidDocumentError = jest.fn(); - }); - - it('should emit error', () => { - const errorStateResource: StateResource<CommandResource> = createErrorStateResource(createProblemDetail()); - - service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, createBinaryFileResource()); - - expect(service.emitBescheidDocumentError).toHaveBeenCalledWith(errorStateResource); - }); - - it('should NOT emit error', () => { - const binaryFileResource: BinaryFileResource = createBinaryFileResource(); - - service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFileResource); - - expect(service.emitBescheidDocumentError).not.toHaveBeenCalled(); - }); - - it('should emit bescheid document state', () => { - const binaryFileResource: BinaryFileResource = createBinaryFileResource(); - - service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFileResource); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ - ...createEmptyBescheidDocument(), - documentUri: getEffectedResourceUrl(commandStateResource.resource), - upload: createEmptyUploadInProgress(), - resource: binaryFileResource, - }), - ); - }); - - it('should NOT emit bescheid document state', () => { - const errorStateResource: StateResource<CommandResource> = createErrorStateResource(createProblemDetail()); - - service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, createBinaryFileResource()); - - expect(service.getBescheidDocument()).toBeObservable(singleCold(createEmptyBescheidDocument())); - }); - }); - - describe('createBescheid', () => { - const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource(); - const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - const commandStateResource: StateResource<CommandResource> = createStateResource(command); - - beforeEach(() => { - service.updateBescheidDraft = jest.fn(); - }); - - beforeEach(() => { - facade.getBescheidCommand.mockReturnValue(of(commandStateResource)); - (service as any).bescheidResourceService.loadByResourceUri = jest.fn(); - }); - - it('should call facade', () => { - service.createBescheid(vorgangWithEingang).subscribe(); - - expect(facade.createBescheidDraft).toHaveBeenCalledWith(vorgangWithEingang, { - order: CommandOrder.CREATE_BESCHEID, - body: null, - }); - }); - - it('should update bescheid draft', () => { - service.createBescheid(vorgangWithEingang).subscribe(); - - expect(service.updateBescheidDraft).toHaveBeenCalledWith(commandStateResource.resource); - }); - }); - - describe('updateBescheidDraft', () => { - const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - - beforeEach(() => { - (service as any).bescheidResourceService.loadByResourceUri = jest.fn(); - }); - - it('should load resource by uri', () => { - service.updateBescheidDraft(command); - - expect((service as any).bescheidResourceService.loadByResourceUri).toHaveBeenCalledWith( - getUrl(command, CommandLinkRel.EFFECTED_RESOURCE), - ); - }); - - it('should emit bescheid created', () => { - service.updateBescheidDraft({ ...command, order: CommandOrder.CREATE_BESCHEID }); - - expect(service.getBescheidCreated()).toBeObservable(singleCold(true)); - }); - }); - - describe('updateBescheid', () => { - const bescheid: Bescheid = createBescheid(); - const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); - - beforeEach(() => { - service.doUpdateBescheid = jest.fn().mockReturnValue(EMPTY); - service.updateBescheidDraft = jest.fn().mockReturnValue(EMPTY); - }); - - it('should do update bescheid', () => { - service.updateBescheid(bescheidResource, bescheid); - - expect(service.doUpdateBescheid).toHaveBeenCalledWith(bescheidResource, bescheid); - }); - - it('should update bescheid draft', () => { - service.doUpdateBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - - service.updateBescheid(bescheidResource, bescheid).subscribe(); - - expect(service.updateBescheidDraft).toHaveBeenCalledWith(commandResource); - }); - }); - - describe('do update bescheid', () => { - const bescheid: Bescheid = createBescheid(); - const bescheidResource: BescheidResource = createBescheidResource(); - - const createCommandProps: CreateCommandProps = createCreateCommandProps(); - let buildUpdateBescheidCommandPropsSpy: jest.SpyInstance; - - beforeEach(() => { - buildUpdateBescheidCommandPropsSpy = jest - .spyOn(BescheidUtil, 'buildUpdateBescheidCommandProps') - .mockReturnValue(createCommandProps); - commandService.createCommandByProps.mockClear(); - commandService.createCommandByProps.mockReturnValue(of(createCommandStateResource())); - }); - - it('should build update bescheid command props', () => { - service.doUpdateBescheid(bescheidResource, bescheid); - - expect(buildUpdateBescheidCommandPropsSpy).toHaveBeenCalledWith(bescheidResource, bescheid); - }); - - it('should call command service', () => { - service.doUpdateBescheid(bescheidResource, bescheid).subscribe(); - - expect(commandService.createCommandByProps).toHaveBeenCalledWith(createCommandProps); - }); - }); - - describe('sendBescheidManually', () => { - beforeEach(() => { - service.sendBescheid = jest.fn().mockReturnValue(EMPTY); - }); - - it('should send bescheid', () => { - service.sendBescheidManually().subscribe(); - - expect(service.sendBescheid).toHaveBeenCalledWith(BescheidLinkRel.BESCHEIDEN); - }); - - it('should return send bescheid command', () => { - const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); - service.sendBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - - const sendCommandStateResource$: Observable<StateResource<CommandResource>> = service.sendBescheidManually(); - - expect(sendCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); - }); - }); - - describe('sendBescheid', () => { - beforeEach(() => { - service.getBescheidDraft = jest.fn().mockReturnValue(of(createStateResource(bescheidResource))); - commandService.createCommandByProps.mockReturnValue(EMPTY); - }); - - it('should get bescheid draft', () => { - service.sendBescheidManually().subscribe(); - - expect(service.getBescheidDraft).toHaveBeenCalled(); - }); - - it('should create command', () => { - service.sendBescheid(BescheidLinkRel.BESCHEIDEN).subscribe(); - - expect(commandService.createCommandByProps).toHaveBeenCalledWith({ - resource: bescheidResource, - linkRel: BescheidLinkRel.BESCHEIDEN, - command: { - order: CommandOrder.SEND_BESCHEID, - body: null, - }, - snackBarMessage: EMPTY_STRING, - } as CreateCommandProps); - }); - - it('should return send bescheid command', () => { - const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); - commandService.createCommandByProps = jest.fn().mockReturnValue(of(commandStateResource)); - - const sendCommandStateResource$: Observable<StateResource<CommandResource>> = service.sendBescheid( - BescheidLinkRel.BESCHEIDEN, - ); - - expect(sendCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); - }); - }); - - describe('sendBescheidMessage', () => { - beforeEach(() => { - service.getBescheidDraft = jest.fn().mockReturnValue(createStateResource(bescheidResource)); - service.sendBescheid = jest.fn().mockReturnValue(EMPTY); - }); - - it('should send bescheid', () => { - service.sendBescheidMessage().subscribe(); - - expect(service.sendBescheid).toHaveBeenCalledWith(BescheidLinkRel.BESCHEIDEN_UND_SENDEN); - }); - - it('should return send bescheid command', () => { - const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource(); - service.sendBescheid = jest.fn().mockReturnValue(of(commandStateResource)); - - const sendCommandStateResource$: Observable<StateResource<CommandResource>> = service.sendBescheidMessage(); - - expect(sendCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); - }); - }); - - describe('setActiveStep', () => { - beforeEach(() => { - service._clearUploadedFiles = jest.fn(); - }); - - it('should emit changed active step', () => { - service.setActiveStep(BescheidWizardStep.DokumenteHochladen); - - expect(service.getActiveStep()).toBeObservable(singleCold(BescheidWizardStep.DokumenteHochladen)); - }); - - it('should clear uploaded files', () => { - service.setActiveStep(BescheidWizardStep.DokumenteHochladen); - - expect(service._clearUploadedFiles).toHaveBeenCalled(); - }); - }); - - describe('getBescheidDraft', () => { - const bescheidDraft: BescheidResource = createBescheidResource(); - const bescheidDraftStateResource: StateResource<BescheidResource> = createStateResource(bescheidDraft); - - it('should call resource service', () => { - bescheidResourceService.get = jest.fn(); - - service.getBescheidDraft(); - - expect(bescheidResourceService.get).toHaveBeenCalled(); - }); - - it('should return value', () => { - bescheidResourceService.get = jest.fn().mockReturnValue(singleCold(bescheidDraftStateResource)); - - const bescheidStateResource$: Observable<StateResource<BescheidResource>> = service.getBescheidDraft(); - - expect(bescheidStateResource$).toBeObservable(singleCold(bescheidDraftStateResource)); - }); - }); - - describe('setNachrichtEmpfaenger', () => { - it('should change wizard state', () => { - const empfaenger: string = faker.person.fullName(); - - service.setNachrichtEmpfaenger(empfaenger); - - expect(service.getWizard()).toBeObservable(singleCold({ ...createInitialWizard(), empfaenger })); - }); - }); - - describe('lockBescheidSending', () => { - it('should change wizard state', () => { - service.lockBescheidSending(); - - expect(service.getWizard()).toBeObservable(singleCold({ ...createInitialWizard(), canBeSend: false })); - }); - }); - - describe('unlockBescheidSending', () => { - it('should change wizard state', () => { - service.unlockBescheidSending(); - - expect(service.getWizard()).toBeObservable(singleCold({ ...createInitialWizard(), canBeSend: true })); - }); - }); - - describe('finishAddingBescheidDocument', () => { - it('should update state', () => { - const bescheidDocument: BescheidDocument = createBescheidDocument(); - service._bescheidDocument$.next(bescheidDocument); - - service.finishAddingBescheidDocument(); - - expect(service.getBescheidDocument()).toBeObservable( - singleCold({ - ...bescheidDocument, - create: createEmptyStateResource(), - upload: createEmptyUploadInProgress(), - } as BescheidDocument), - ); - }); - }); - - describe('clear uploaded files', () => { - it('should call binary files service', () => { - service._clearUploadedFiles(); - - expect(binaryFileService.clearUploadedFiles).toHaveBeenCalledWith(BESCHEID_UPLOADED_ATTACHMENTS); - }); - }); -}); diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid2.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid2.service.ts deleted file mode 100644 index 8a48a4dbdf043a0994ac12c2a298a6ae2be2fb3e..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid-shared/src/lib/bescheid2.service.ts +++ /dev/null @@ -1,337 +0,0 @@ -import { - Bescheid, - BESCHEID_UPLOADED_ATTACHMENTS, - BescheidDocument, - BescheidLinkRel, - BescheidResource, - BescheidSendBy, - BescheidWizardStep, - buildCreateBescheidCommand, - buildCreateBescheidDocumentCommandProps, - buildCreateBescheidDocumentFromFileProps, - buildSendBescheidCommandProps, - buildUpdateBescheidCommandProps, - createEmptyBescheidDocument, - createEmptyUploadInProgress, - createInitialWizard, - DocumentResource, - Wizard, -} from '@alfa-client/bescheid-shared'; -import { - BinaryFileListLinkRel, - BinaryFileListResource, - BinaryFileResource, - BinaryFileService, -} from '@alfa-client/binary-file-shared'; -import { - CommandOrder, - CommandResource, - CommandService, - getEffectedResourceUrl, - notHasCommandError, - tapOnCommandSuccessfullyDone, -} from '@alfa-client/command-shared'; -import { PostfachService } from '@alfa-client/postfach-shared'; -import { - createEmptyStateResource, - filterIsLoadedOrHasError, - getEmbeddedResources, - hasStateResourceError, - isLoaded, - ResourceRepository, - StateResource, -} from '@alfa-client/tech-shared'; -import { VorgangCommandService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { inject, Injectable } from '@angular/core'; -import { getUrl, hasLink, LinkRel, Resource, ResourceUri } from '@ngxp/rest'; -import { isNil } from 'lodash-es'; -import { BehaviorSubject, filter, first, map, Observable, switchMap } from 'rxjs'; -import { BescheidFacade } from './+state/bescheid.facade'; -import { BescheidResourceService } from './bescheid-resource-service'; -import { DocumentLinkRel } from './document.linkrel'; - -@Injectable() -export class BescheidService2 { - private readonly bescheidFacade = inject(BescheidFacade); - private readonly commandService = inject(CommandService); - private readonly vorgangCommandService = inject(VorgangCommandService); - private readonly binaryFileService = inject(BinaryFileService); - private readonly resourceRepository = inject(ResourceRepository); - private readonly postfachService = inject(PostfachService); - private readonly bescheidResourceService = inject(BescheidResourceService); - - readonly _bescheidDocument$: BehaviorSubject<BescheidDocument> = new BehaviorSubject(createEmptyBescheidDocument()); - readonly _wizard$: BehaviorSubject<Wizard> = new BehaviorSubject(createInitialWizard()); - - public init(): void { - this._wizard$.next(createInitialWizard()); - this._bescheidDocument$.next(createEmptyBescheidDocument()); - } - - public exit(): void { - this.postfachService.setPostfachMailOnReload(); - this._clearUploadedFiles(); - } - - public skipBescheidCreation( - vorgangWithEingangResource: VorgangWithEingangResource, - bescheidResource: BescheidResource, - ): Observable<StateResource<CommandResource>> { - if (isNil(bescheidResource)) { - return this.vorgangCommandService.abschliessen(vorgangWithEingangResource); - } - return this.deleteBescheidAndCompleteVorgang(vorgangWithEingangResource); - } - - deleteBescheidAndCompleteVorgang( - vorgangWithEingangResource: VorgangWithEingangResource, - ): Observable<StateResource<CommandResource>> { - return this.vorgangCommandService - .abschliessen(vorgangWithEingangResource) - .pipe(tapOnCommandSuccessfullyDone(() => this.deleteBescheid())); - } - - public deleteBescheid(): Observable<StateResource<CommandResource>> { - return this.bescheidResourceService.delete(); - } - - public loadFiles(bescheidResource: BescheidResource): void { - this.loadBescheidDocument(bescheidResource); - this.loadAttachments(bescheidResource); - } - - public createBescheidDocument(bescheidResource: BescheidResource): void { - this._bescheidDocument$.next({ ...createEmptyBescheidDocument(), create: createEmptyStateResource(true) }); - this.doCreateBescheidDocument(bescheidResource) - .pipe(filterIsLoadedOrHasError(), first()) - .subscribe((commandStateResource: StateResource<CommandResource>) => - this.handleCreateBescheidDocumentResponse(commandStateResource), - ); - } - - doCreateBescheidDocument(bescheidResource: BescheidResource): Observable<StateResource<CommandResource>> { - return this.commandService.createCommandByProps(buildCreateBescheidDocumentCommandProps(bescheidResource)); - } - - handleCreateBescheidDocumentResponse(commandStateResource: StateResource<CommandResource>): void { - if (notHasCommandError(commandStateResource.resource)) { - const documentUri: ResourceUri = getEffectedResourceUrl(commandStateResource.resource); - this._bescheidDocument$.next({ ...this._bescheidDocument$.value, documentUri }); - this.loadBescheidDocumentByUri(documentUri); - } else { - this._bescheidDocument$.next({ ...this._bescheidDocument$.value, create: commandStateResource }); - } - } - - emitBescheidDocumentError(stateResource: StateResource<Resource>): void { - const value: BescheidDocument = this._bescheidDocument$.value; - this._bescheidDocument$.next({ - ...value, - upload: { ...value.upload, loading: false, error: stateResource.error }, - }); - } - - loadBescheidDocument(bescheidResource: BescheidResource): void { - if (hasLink(bescheidResource, BescheidLinkRel.BESCHEID_DOCUMENT)) { - this.loadBescheidDocumentByUri(getUrl(bescheidResource, BescheidLinkRel.BESCHEID_DOCUMENT)); - } - } - - public loadBescheidDocumentByUri(resourceUri: ResourceUri): void { - this.resourceRepository - .getResource(resourceUri) - .pipe(first()) - .subscribe((document: DocumentResource) => this.loadBescheidDocumentFile(document)); - } - - loadBescheidDocumentFile(document: DocumentResource): void { - this.binaryFileService - .getFile(getUrl(document, DocumentLinkRel.FILE)) - .pipe(filterIsLoadedOrHasError(), first()) - .subscribe((binaryFile: StateResource<BinaryFileResource>) => { - this._bescheidDocument$.next({ - ...this._bescheidDocument$.value, - upload: createEmptyUploadInProgress(), - create: createEmptyStateResource(), - resource: binaryFile.resource, - documentUri: getUrl(document, LinkRel.Self), - }); - }); - } - - loadAttachments(bescheidResource: BescheidResource): void { - if (hasLink(bescheidResource, BescheidLinkRel.ATTACHMENTS)) { - this.binaryFileService - .getFiles(bescheidResource, BescheidLinkRel.ATTACHMENTS) - .pipe( - filterIsLoadedOrHasError(), - first(), - map((stateResource: StateResource<BinaryFileListResource>) => - getEmbeddedResources<BinaryFileResource>(stateResource, BinaryFileListLinkRel.FILE_LIST), - ), - ) - .subscribe((files: BinaryFileResource[]) => this.binaryFileService.addFiles(BESCHEID_UPLOADED_ATTACHMENTS, files)); - } - } - - public uploadBescheidDocument(document: File, bescheid: BescheidResource): void { - this._bescheidDocument$.next({ ...this._bescheidDocument$.value, upload: { fileName: document.name, loading: true } }); - this.binaryFileService - .uploadFile(bescheid, BescheidLinkRel.UPLOAD_BESCHEID_FILE, document, false) - .pipe(filterIsLoadedOrHasError(), first()) - .subscribe((binaryFileStateResource: StateResource<BinaryFileResource>) => - this.handleUploadBescheidDocumentResponse(bescheid, binaryFileStateResource), - ); - } - - handleUploadBescheidDocumentResponse( - bescheid: BescheidResource, - binaryFileStateResource: StateResource<BinaryFileResource>, - ): void { - if (hasStateResourceError(binaryFileStateResource)) { - this.emitBescheidDocumentError(binaryFileStateResource); - } else { - this.createBescheidDocumentFromFile(bescheid, binaryFileStateResource.resource); - } - } - - createBescheidDocumentFromFile(bescheid: BescheidResource, binaryFile: BinaryFileResource): void { - this.commandService - .createCommandByProps(buildCreateBescheidDocumentFromFileProps(bescheid, binaryFile)) - .pipe(filterIsLoadedOrHasError(), first()) - .subscribe((commandStateResource: StateResource<CommandResource>) => - this.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFile), - ); - } - - handleCreateBescheidDocumentFromFileResponse( - commandStateResource: StateResource<CommandResource>, - binaryFile: BinaryFileResource, - ): void { - if (hasStateResourceError(commandStateResource)) { - this.emitBescheidDocumentError(commandStateResource); - } else { - this._bescheidDocument$.next({ - ...this._bescheidDocument$.value, - documentUri: getEffectedResourceUrl(commandStateResource.resource), - upload: createEmptyUploadInProgress(), - resource: binaryFile, - }); - } - } - - public createBescheid( - vorgangWithEingang: VorgangWithEingangResource, - bescheid?: Bescheid, - ): Observable<StateResource<CommandResource>> { - this.bescheidFacade.createBescheidDraft(vorgangWithEingang, buildCreateBescheidCommand(bescheid)); - return this.bescheidFacade - .getBescheidCommand() - .pipe( - tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => - this.updateBescheidDraft(commandStateResource.resource), - ), - ); - } - - updateBescheidDraft(command: CommandResource): void { - this.bescheidResourceService.loadByResourceUri(getEffectedResourceUrl(command)); - if (command.order === CommandOrder.CREATE_BESCHEID) { - this._wizard$.next({ ...this._wizard$.value, bescheidCreated: true }); - } - } - - public updateBescheid( - bescheidResource: BescheidResource, - updatedBescheid: Bescheid, - ): Observable<StateResource<CommandResource>> { - return this.doUpdateBescheid(bescheidResource, updatedBescheid).pipe( - tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => { - this.updateBescheidDraft(commandStateResource.resource); - }), - ); - } - - doUpdateBescheid(bescheidResource: BescheidResource, bescheid: Bescheid): Observable<StateResource<CommandResource>> { - return this.commandService.createCommandByProps(buildUpdateBescheidCommandProps(bescheidResource, bescheid)); - } - - public sendBescheidManually(): Observable<StateResource<CommandResource>> { - return this.sendBescheid(BescheidLinkRel.BESCHEIDEN); - } - - public sendBescheidMessage(): Observable<StateResource<CommandResource>> { - return this.sendBescheid(BescheidLinkRel.BESCHEIDEN_UND_SENDEN); - } - - sendBescheid(linkRel: BescheidLinkRel): Observable<StateResource<CommandResource>> { - return this.getBescheidDraft().pipe( - filter(isLoaded), - map((stateResource: StateResource<BescheidResource>) => stateResource.resource), - switchMap((bescheidResource: BescheidResource) => - this.commandService.createCommandByProps(buildSendBescheidCommandProps(bescheidResource, linkRel)), - ), - ); - } - - public getBescheidDraft(): Observable<StateResource<BescheidResource>> { - return this.bescheidResourceService.get(); - } - - public getBescheidDocument(): Observable<BescheidDocument> { - return this._bescheidDocument$.asObservable(); - } - - public deleteBescheidDocument(): void { - this._bescheidDocument$.next(createEmptyBescheidDocument()); - } - - public getActiveStep(): Observable<BescheidWizardStep> { - return this._wizard$.asObservable().pipe(map((wizard: Wizard) => wizard.activeStep)); - } - - public setActiveStep(step: BescheidWizardStep): void { - this._clearUploadedFiles(); - this._wizard$.next({ ...this._wizard$.value, activeStep: step }); - } - - public getBescheidCreated(): Observable<boolean> { - return this._wizard$.asObservable().pipe(map((wizard: Wizard) => wizard.bescheidCreated)); - } - - public selectBescheidResource(): Observable<StateResource<BescheidResource>> { - return this.bescheidResourceService.selectResource(); - } - - public getWizard(): Observable<Wizard> { - return this._wizard$.asObservable(); - } - - public setSendBy(sendBy: BescheidSendBy): void { - this._wizard$.next({ ...this._wizard$.value, sendBy: sendBy }); - } - - public setNachrichtEmpfaenger(empfaenger: string): void { - this._wizard$.next({ ...this._wizard$.value, empfaenger: empfaenger }); - } - - public lockBescheidSending(): void { - this._wizard$.next({ ...this._wizard$.value, canBeSend: false }); - } - - public unlockBescheidSending(): void { - this._wizard$.next({ ...this._wizard$.value, canBeSend: true }); - } - - public finishAddingBescheidDocument(): void { - this._bescheidDocument$.next({ - ...this._bescheidDocument$.value, - upload: createEmptyUploadInProgress(), - create: createEmptyStateResource(), - }); - } - - _clearUploadedFiles(): void { - this.binaryFileService.clearUploadedFiles(BESCHEID_UPLOADED_ATTACHMENTS); - } -} diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.html deleted file mode 100644 index 0526dcd28fe6df116fd5b5265bf6c032ea25746a..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.html +++ /dev/null @@ -1,33 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<alfa-bescheid-in-vorgang - *ngIf="bescheidStateResource$ | async as bescheidStateResource" - data-test-id="bescheid-in-vorgang" - [bescheidStateResource]="bescheidStateResource" - [bescheidDocumentFile]="bescheidDocumentFile$ | async" - [hasBescheidDraft]="hasBescheidDraft" -> -</alfa-bescheid-in-vorgang> diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.spec.ts deleted file mode 100644 index 9e0e0870df4acfdef28672db7215f9eeb5839f8e..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.spec.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { StateResource, createStateResource } from '@alfa-client/tech-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; -import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { SimpleChanges } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { createBescheidResource } from 'libs/bescheid-shared/src/test/bescheid'; -import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; -import { MockComponent } from 'ng-mocks'; -import { of } from 'rxjs'; -import { BescheidInVorgangContainerComponent } from './bescheid-in-vorgang-container.component'; -import { BescheidInVorgangComponent } from './bescheid-in-vorgang/bescheid-in-vorgang.component'; - -describe('BescheidInVorgangContainerComponent', () => { - let component: BescheidInVorgangContainerComponent; - let fixture: ComponentFixture<BescheidInVorgangContainerComponent>; - - let bescheidService: Mock<BescheidService>; - const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource(); - - const noChanges: SimpleChanges = {}; - const changes: SimpleChanges = <any>{ vorgang: vorgang }; - - const bescheidResource: BescheidResource = createBescheidResource(); - const bescheidStateResource: StateResource<BescheidResource> = - createStateResource(bescheidResource); - - beforeEach(async () => { - bescheidService = mock(BescheidService); - bescheidService.getBescheidDocumentFile = jest.fn(); - bescheidService.loadBescheidDocument = jest.fn(); - bescheidService.getBescheidDraft.mockReturnValue(of(bescheidStateResource)); - - await TestBed.configureTestingModule({ - declarations: [ - BescheidInVorgangContainerComponent, - MockComponent(BescheidInVorgangComponent), - ], - providers: [{ provide: BescheidService, useValue: bescheidService }], - }).compileComponents(); - - fixture = TestBed.createComponent(BescheidInVorgangContainerComponent); - component = fixture.componentInstance; - component.vorgang = vorgang; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('hasBescheidDraft', () => { - it('should return false', () => { - component.vorgang = vorgang; - - expect(component.hasBescheidDraft).toBeFalsy(); - }); - - it('should return true', () => { - component.vorgang = createVorgangWithEingangResource([ - VorgangWithEingangLinkRel.BESCHEID_DRAFT, - ]); - - expect(component.hasBescheidDraft).toBeTruthy(); - }); - }); - - describe('onChanges', () => { - it('should not call getBescheid', () => { - component.getBescheid = jest.fn(); - - component.ngOnChanges(noChanges); - - expect(component.getBescheid).not.toHaveBeenCalled(); - }); - - it('should call getBescheid', () => { - component.getBescheid = jest.fn(); - - component.ngOnChanges(changes); - - expect(component.getBescheid).toHaveBeenCalled(); - }); - - it('should not call bescheidService.getBescheidDocumentFile', () => { - component.ngOnChanges(noChanges); - - expect(bescheidService.getBescheidDocumentFile).not.toHaveBeenCalled(); - }); - - it('should call bescheidService.getBescheidDocumentFile', () => { - component.ngOnChanges(changes); - - expect(bescheidService.getBescheidDocumentFile).toHaveBeenCalled(); - }); - }); - - describe('getBescheid', () => { - it('should not call bescheidService.loadBescheidDocumentByUri', (done) => { - component.ngOnChanges(changes); - - component.bescheidStateResource$.subscribe(() => { - expect(bescheidService.loadBescheidDocumentByUri).not.toHaveBeenCalled(); - done(); - }); - }); - - it('should call bescheidService.loadBescheidDocumentByUri', (done) => { - const bescheidResource: BescheidResource = createBescheidResource([ - BescheidLinkRel.BESCHEID_DOCUMENT, - ]); - const bescheidStateResource: StateResource<BescheidResource> = - createStateResource(bescheidResource); - bescheidService.getBescheidDraft.mockReturnValue(of(bescheidStateResource)); - - component.ngOnChanges(changes); - - component.bescheidStateResource$.subscribe(() => { - expect(bescheidService.loadBescheidDocumentByUri).toHaveBeenCalled(); - done(); - }); - }); - }); -}); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.ts deleted file mode 100644 index 97dc8bd587a6a4ece1d5d88c44a283681dc288dd..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang-container.component.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { StateResource } from '@alfa-client/tech-shared'; -import { VorgangResource, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; -import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { getUrl, hasLink } from '@ngxp/rest'; -import { has } from 'lodash-es'; -import { Observable, tap } from 'rxjs'; - -@Component({ - selector: 'alfa-bescheid-in-vorgang-container', - templateUrl: './bescheid-in-vorgang-container.component.html', - styles: [], -}) -export class BescheidInVorgangContainerComponent implements OnChanges { - @Input() vorgang: VorgangResource; - - public bescheidStateResource$: Observable<StateResource<BescheidResource>>; - public bescheidDocumentFile$: Observable<StateResource<BinaryFileResource>>; - - get hasBescheidDraft(): boolean { - return hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT); - } - - constructor(private bescheidService: BescheidService) {} - - // TODO Prüfen, warum nicht als Setter möglich. Hatte im ersten Versuch zu Laufzeitfehlern geführt. - ngOnChanges(changes: SimpleChanges): void { - if (!has(changes, 'vorgang')) { - return; - } - - this.bescheidStateResource$ = this.getBescheid(); - this.bescheidDocumentFile$ = this.bescheidService.getBescheidDocumentFile(); - } - - getBescheid(): Observable<StateResource<BescheidResource>> { - return this.bescheidService.getBescheidDraft().pipe( - tap((bescheidResource) => { - if (hasLink(bescheidResource.resource, BescheidLinkRel.BESCHEID_DOCUMENT)) { - this.bescheidService.loadBescheidDocumentByUri( - getUrl(bescheidResource.resource, BescheidLinkRel.BESCHEID_DOCUMENT), - ); - } - }), - ); - } -} diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.html deleted file mode 100644 index 8273187344645af3ac5814af70eb389e268283ba..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.html +++ /dev/null @@ -1,41 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<ozgcloud-spinner [stateResource]="bescheidStateResource"> - <ng-container *ngIf="bescheidStateResource.resource as bescheid"> - <ozgcloud-expansion-panel headline="Bescheid"> - <div class="flex max-w-xl flex-col gap-4"> - <ods-bescheid-status-text [dateText]="bescheid.beschiedenAm | formatFullDatePipe" /> - - <alfa-binary-file2-container - *ngIf="bescheidDocumentFile.resource && bescheidDocumentFile.loaded" - [file]="bescheidDocumentFile.resource" - data-test-id="bescheid-document-in-vorgang-binary-file" - > - </alfa-binary-file2-container> - </div> - </ozgcloud-expansion-panel> - </ng-container> -</ozgcloud-spinner> diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts deleted file mode 100644 index c68eaca257bb2cc3feaad12ab0cb232a199c0ecc..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource } from '@alfa-client/bescheid-shared'; -import { BinaryFile2ContainerComponent, BinaryFileContainerComponent } from '@alfa-client/binary-file'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { StateResource, createStateResource } from '@alfa-client/tech-shared'; -import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils'; -import { ExpansionPanelComponent, SpinnerComponent } from '@alfa-client/ui'; -import { registerLocaleData } from '@angular/common'; -import localeDe from '@angular/common/locales/de'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormatFullDatePipe } from 'libs/tech-shared/src/lib/pipe/format-full-date.pipe'; -import { MockComponent } from 'ng-mocks'; -import { createBescheidResource } from '../../../../../bescheid-shared/src/test/bescheid'; -import { createBinaryFileResource } from '../../../../../binary-file-shared/test/binary-file'; -import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; -import { BescheidInVorgangComponent } from './bescheid-in-vorgang.component'; - -import { BescheidStatusTextComponent } from '@ods/system'; - -registerLocaleData(localeDe); - -describe('BescheidInVorgangComponent', () => { - let component: BescheidInVorgangComponent; - let fixture: ComponentFixture<BescheidInVorgangComponent>; - - const bescheidResource: BescheidResource = createBescheidResource(); - const bescheidStateResource: StateResource<BescheidResource> = createStateResource(bescheidResource); - - const binaryFile: BinaryFileResource = createBinaryFileResource(); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(binaryFile); - - const bescheidDocumentBinaryFileContainer: string = getDataTestIdOf('bescheid-document-in-vorgang-binary-file'); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - BescheidInVorgangComponent, - FormatFullDatePipe, - MockComponent(SpinnerComponent), - MockComponent(ExpansionPanelComponent), - MockComponent(BinaryFileContainerComponent), - MockComponent(BescheidStatusTextComponent), - MockComponent(BinaryFile2ContainerComponent), - ], - }).compileComponents(); - - fixture = TestBed.createComponent(BescheidInVorgangComponent); - component = fixture.componentInstance; - component.bescheidStateResource = bescheidStateResource; - component.bescheidDocumentFile = binaryFileStateResource; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render', () => { - it('should show bescheid document file', () => { - component.bescheidDocumentFile = createStateResource(createBinaryFileResource()); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, bescheidDocumentBinaryFileContainer); - }); - - it('should NOT show bescheid document file if resource null', () => { - component.bescheidDocumentFile = { ...createStateResource(null), loaded: true }; - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidDocumentBinaryFileContainer); - }); - - it('should NOT show bescheid document file if resource loading', () => { - component.bescheidDocumentFile = { - ...createStateResource(createBinaryFileResource()), - loaded: false, - }; - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidDocumentBinaryFileContainer); - }); - }); - - describe('bescheidBewilligt', () => { - it('should return true', () => { - component.bescheidStateResource.resource.bewilligt = true; - - expect(component.bescheidBewilligt).toBeTruthy(); - }); - - it('should return false', () => { - component.bescheidStateResource.resource.bewilligt = false; - - expect(component.bescheidBewilligt).toBeFalsy(); - }); - }); - - describe('bescheidAbgelehnt', () => { - it('should return false', () => { - component.bescheidStateResource.resource.bewilligt = true; - - expect(component.bescheidAbgelehnt).toBeFalsy(); - }); - - it('should return true', () => { - component.bescheidStateResource.resource.bewilligt = false; - - expect(component.bescheidAbgelehnt).toBeTruthy(); - }); - }); -}); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.ts deleted file mode 100644 index cb92b3bebba90cb4bc62d3685519dbc9c29683d5..0000000000000000000000000000000000000000 --- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource } from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { StateResource } from '@alfa-client/tech-shared'; -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'alfa-bescheid-in-vorgang', - templateUrl: './bescheid-in-vorgang.component.html', -}) -export class BescheidInVorgangComponent { - @Input() bescheidStateResource: StateResource<BescheidResource>; - @Input() bescheidDocumentFile: StateResource<BinaryFileResource>; - @Input() hasBescheidDraft: boolean = false; - - get bescheidBewilligt(): boolean { - return <boolean>this.bescheidStateResource.resource.bewilligt; - } - - get bescheidAbgelehnt(): boolean { - return !this.bescheidBewilligt; - } -} diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.spec.ts index 9d003e6fff71a5306124381c873fc1eef9d2b496..d1c390fc0df7df8a30b9463b1d22eeef9b5dcb82 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.spec.ts @@ -23,22 +23,11 @@ */ import { BescheidService } from '@alfa-client/bescheid-shared'; import { BinaryFileUriContainerComponent } from '@alfa-client/binary-file'; -import { - GetUrlPipe, - HasLinkPipe, - StateResource, - createStateResource, -} from '@alfa-client/tech-shared'; -import { - Mock, - existsAsHtmlElement, - getMockComponent, - mock, - notExistsAsHtmlElement, -} from '@alfa-client/test-utils'; +import { createStateResource, GetUrlPipe, HasLinkPipe, StateResource } from '@alfa-client/tech-shared'; +import { existsAsHtmlElement, getMockComponent, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; -import { ResourceUri, getUrl } from '@ngxp/rest'; +import { getUrl, ResourceUri } from '@ngxp/rest'; import { AttachmentWrapperComponent } from '@ods/system'; import { DocumentLinkRel } from 'libs/bescheid-shared/src/lib/document.linkrel'; import { DocumentResource } from 'libs/bescheid-shared/src/lib/document.model'; @@ -81,7 +70,7 @@ describe('DocumentInBescheidContainerComponent', () => { fixture = TestBed.createComponent(DocumentInBescheidContainerComponent); component = fixture.componentInstance; component.documentUri = documentUri; - bescheidService.loadBescheidDocument.mockReturnValue(of(documentStateResource)); + bescheidService.getBescheidDocumentByUri.mockReturnValue(of(documentStateResource)); fixture.detectChanges(); }); @@ -93,15 +82,13 @@ describe('DocumentInBescheidContainerComponent', () => { it('should call service to load bescheid document', () => { component.ngOnInit(); - expect(bescheidService.loadBescheidDocument).toHaveBeenCalledWith(documentUri); + expect(bescheidService.getBescheidDocumentByUri).toHaveBeenCalledWith(documentUri); }); }); describe('binary file uri container', () => { it('should be visible if link exists on resource', () => { - component.documentStateResource$ = of( - createStateResource(createDocumentResource([DocumentLinkRel.FILE])), - ); + component.documentStateResource$ = of(createStateResource(createDocumentResource([DocumentLinkRel.FILE]))); fixture.detectChanges(); @@ -117,8 +104,10 @@ describe('DocumentInBescheidContainerComponent', () => { }); it('should be called with binaryFileUri', () => { - const binaryFileUriContainer: BinaryFileUriContainerComponent = - getMockComponent<BinaryFileUriContainerComponent>(fixture, BinaryFileUriContainerComponent); + const binaryFileUriContainer: BinaryFileUriContainerComponent = getMockComponent<BinaryFileUriContainerComponent>( + fixture, + BinaryFileUriContainerComponent, + ); expect(binaryFileUriContainer.binaryFileUri).toBe(getUrl(document, DocumentLinkRel.FILE)); }); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.ts index d4ff2b232c9cbd6e4a0602dfb8de775b2f6b8634..a99457f2b2edf4a0aeca4060a5e2fbe6588c99bc 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component.ts @@ -43,6 +43,6 @@ export class DocumentInBescheidContainerComponent implements OnInit { constructor(private bescheidService: BescheidService) {} ngOnInit(): void { - this.documentStateResource$ = this.bescheidService.loadBescheidDocument(this.documentUri); + this.documentStateResource$ = this.bescheidService.getBescheidDocumentByUri(this.documentUri); } } diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts index 1fe204ade444f7609bea459484de54ed0ab5a829..ed66740aa800ca2b5243d64b3f60d0b04552e43b 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts @@ -21,19 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource, BescheidWizardDialogResult, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { BescheidWizardContainerComponent } from '@alfa-client/bescheid'; +import { BescheidResource, BescheidService, BescheidWizardDialogResult, BescheidWizardStep } from '@alfa-client/bescheid-shared'; import { CommandOrder, CommandResource } from '@alfa-client/command-shared'; import { createEmptyStateResource, createStateResource, ESCAPE_KEY, StateResource } from '@alfa-client/tech-shared'; -import { - createDialogRefMock, - DialogRefMock, - existsAsHtmlElement, - getElementFromFixtureByType, - Mock, - mock, - triggerEvent, - useFromMock, -} from '@alfa-client/test-utils'; +import { createDialogRefMock, DialogRefMock, existsAsHtmlElement, getElementFromFixtureByType, Mock, mock, triggerEvent, useFromMock, } from '@alfa-client/test-utils'; import { OzgcloudDialogService } from '@alfa-client/ui'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; @@ -41,20 +33,14 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ButtonComponent, CloseIconComponent } from '@ods/system'; import { MockComponent } from 'ng-mocks'; import { EMPTY, of } from 'rxjs'; -import { BescheidService2 } from '../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource, createBescheidStateResource } from '../../../../bescheid-shared/src/test/bescheid'; import { createCommandErrorResource, createSuccessfullyDoneCommandResource } from '../../../../command-shared/test/command'; import { getDataTestIdAttributeOf, getDataTestIdOf } from '../../../../tech-shared/test/data-test'; import { singleColdCompleted } from '../../../../tech-shared/test/marbles'; import { createKeydownKeyboardEvent } from '../../../../test-utils/src/lib/keyboard'; import { createVorgangWithEingangResource } from '../../../../vorgang-shared/test/vorgang'; -import { BescheidWizardContainerComponent } from './bescheid-wizard-container.component'; import { BescheidWizardComponent } from './bescheid-wizard/bescheid-wizard.component'; -import { - BescheidWizardCancelDialogContainerComponent, - CancelWizardDialogData, - CancelWizardDialogResult, -} from './bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component'; +import { BescheidWizardCancelDialogContainerComponent, CancelWizardDialogData, CancelWizardDialogResult, } from './bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component'; import { BescheidFormService } from './bescheid.formservice'; describe('BescheidWizardContainerComponent', () => { @@ -64,7 +50,7 @@ describe('BescheidWizardContainerComponent', () => { const bescheidWizard: string = getDataTestIdOf('bescheid-wizard'); const closeButton: string = getDataTestIdAttributeOf('close-bescheid'); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; let ozgcloudDialogService: Mock<OzgcloudDialogService>; let formService: Mock<BescheidFormService>; let wizardDialogRef: DialogRefMock<BescheidWizardDialogResult>; @@ -72,7 +58,7 @@ describe('BescheidWizardContainerComponent', () => { const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); bescheidService.getBescheidCreated.mockReturnValue(EMPTY); ozgcloudDialogService = mock(OzgcloudDialogService); formService = mock(BescheidFormService); @@ -105,7 +91,7 @@ describe('BescheidWizardContainerComponent', () => { useValue: { vorgangWithEingangResource }, }, { - provide: BescheidService2, + provide: BescheidService, useValue: bescheidService, }, { diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts index cba4185d1a3d6805f5291ad6972c11965ed40fc5..75bf0b0c07f51e508304f2b353af195b6bc97254 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts @@ -21,18 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource, BescheidWizardDialogResult, BescheidWizardStep } from '@alfa-client/bescheid-shared'; -import { CommandOrder, CommandResource, CommandService, isSuccessfulDone } from '@alfa-client/command-shared'; -import { createEmptyStateResource, isEscapeKey, isNotLoading, isNotNil, ResourceRepository, StateResource, } from '@alfa-client/tech-shared'; +import { BescheidResource, BescheidService, BescheidWizardDialogResult, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { CommandOrder, CommandResource, isSuccessfulDone } from '@alfa-client/command-shared'; +import { createEmptyStateResource, isEscapeKey, isNotLoading, isNotNil, StateResource } from '@alfa-client/tech-shared'; import { OzgcloudDialogService } from '@alfa-client/ui'; -import { VorgangService, VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { getEmpfaenger } from '@alfa-client/vorgang-shared-ui'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; import { Component, inject, OnDestroy, OnInit, ViewContainerRef } from '@angular/core'; import { hasLink } from '@ngxp/rest'; -import { BescheidResourceService, createBescheidResourceService } from 'libs/bescheid-shared/src/lib/bescheid-resource-service'; import { filter, first, Observable, of, Subscription, switchMap } from 'rxjs'; -import { BescheidService2 } from '../../../../bescheid-shared/src/lib/bescheid2.service'; import { BescheidWizardCancelDialogContainerComponent, CancelWizardDialogData, CancelWizardDialogResult, } from './bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component'; import { BescheidFormService } from './bescheid.formservice'; @@ -43,18 +41,10 @@ export interface BescheidWizardDialogData { @Component({ selector: 'alfa-bescheid-wizard-container', templateUrl: './bescheid-wizard-container.component.html', - providers: [ - BescheidFormService, - BescheidService2, - { - provide: BescheidResourceService, - useFactory: createBescheidResourceService, - deps: [ResourceRepository, CommandService, VorgangService], - }, - ], + providers: [BescheidFormService], }) export class BescheidWizardContainerComponent implements OnInit, OnDestroy { - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); private readonly ozgcloudDialogService = inject(OzgcloudDialogService); private readonly dialogData: BescheidWizardDialogData = inject(DIALOG_DATA); private readonly dialogRef = inject(DialogRef<BescheidWizardDialogResult>); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts index df6b0e09d088b27f5601ba9b12abf43363b8a0a7..176d402990d293f01afab28575a5d1d0dce49a32 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { createDialogRefMock, DialogRefMock, getElementComponentFromFixtureByCss, mock, Mock, triggerEvent, } from '@alfa-client/test-utils'; @@ -32,7 +32,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatIcon } from '@angular/material/icon'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource } from '../../../../../../../bescheid-shared/src/test/bescheid'; import { createSuccessfullyDoneCommandStateResource } from '../../../../../../../command-shared/test/command'; import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test'; @@ -52,10 +51,10 @@ describe('BescheidWizardAbschliessenDialogContainerComponent', () => { const dialogData: AbschliessenDialogData = { vorgangWithEingangResource, bescheidResource }; let dialogRef: DialogRefMock; - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); dialogRef = createDialogRefMock(); }); @@ -76,7 +75,7 @@ describe('BescheidWizardAbschliessenDialogContainerComponent', () => { useValue: dialogRef, }, { - provide: BescheidService2, + provide: BescheidService, useValue: bescheidService, }, ], diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts index 5a8ace4040ce03c2e7cff5f2efc3f24877d0f201..b420406bed82120b5f314a766ded532bdc413b9e 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { createDialogResult } from '@alfa-client/ui'; @@ -29,7 +29,6 @@ import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; import { Component, inject } from '@angular/core'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../../bescheid-shared/src/lib/bescheid2.service'; export interface AbschliessenDialogData { vorgangWithEingangResource: VorgangWithEingangResource; @@ -43,7 +42,7 @@ export interface AbschliessenDialogData { export class BescheidWizardAbschliessenDialogContainerComponent { private readonly dialogData: AbschliessenDialogData = inject(DIALOG_DATA); private readonly dialogRef = inject(DialogRef); - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); public abschliessen$: Observable<StateResource<CommandResource>>; diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.spec.ts index d3452acaabaa91d8cced04afc925138dd1d2d546..44b1340298c7853918997126eb57c715dbd6ecf7 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.spec.ts @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { BescheidService } from '@alfa-client/bescheid-shared'; import { existsAsHtmlElement, getElementFromFixtureByType, Mock, mock, triggerEvent, useFromMock } from '@alfa-client/test-utils'; import { EventEmitter } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource } from '../../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test'; import { createVorgangWithEingangResource } from '../../../../../../vorgang-shared/test/vorgang'; @@ -47,10 +47,10 @@ describe('BescheidWizardAntragBescheidenComponent', () => { const abschliessenButton: string = getDataTestIdOf('wizard-abschliessen-button'); const antragBescheidenSummary: string = getDataTestIdOf('antrag-bescheiden-summary'); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); }); beforeEach(async () => { @@ -67,7 +67,7 @@ describe('BescheidWizardAntragBescheidenComponent', () => { ], providers: [ { - provide: BescheidService2, + provide: BescheidService, useValue: bescheidService, }, ], diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.ts index 9837cbe2bca5ed1e8ff4f9674d10895c476d7faf..c7a230663a49cf616a2d6429527f2c28a23a0af6 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden-container.component.ts @@ -21,10 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { BescheidResource, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared'; import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; @Component({ selector: 'alfa-bescheid-wizard-antrag-bescheiden-container', @@ -36,7 +35,7 @@ export class BescheidWizardAntragBescheidenContainerComponent { @Output() vorgangAbgeschlossen: EventEmitter<void> = new EventEmitter<void>(); - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); public readonly BescheidWizardStep = BescheidWizardStep; diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts index fc15a7f9282febbd25179f0b255a5781234bfb86..17cafdfc31404bd5b48a694aac2cb4886ffa039b 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidLinkRel } from '@alfa-client/bescheid-shared'; +import { BescheidLinkRel, BescheidService } from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; import { createEmptyStateResource, HasLinkPipe, StateResource } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, getElementFromFixtureByType, mock, notExistsAsHtmlElement, triggerEvent, useFromMock, } from '@alfa-client/test-utils'; @@ -33,7 +33,6 @@ import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; import { CloseIconComponent, RadioButtonCardComponent, StampIconComponent } from '@ods/system'; import { MockComponent } from 'ng-mocks'; import { EMPTY, of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource } from '../../../../../../../bescheid-shared/src/test/bescheid'; import { createSuccessfullyDoneCommandStateResource } from '../../../../../../../command-shared/test/command'; import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test'; @@ -52,7 +51,7 @@ describe('BescheidWizardAntragBescheidenFormComponent', () => { let formService: BescheidFormService; beforeEach(async () => { - formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(mock(BescheidService2))); + formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(mock(BescheidService))); formService.submit = jest.fn().mockReturnValue(EMPTY); await TestBed.configureTestingModule({ diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.spec.ts index abdb3be7cef699e775c5bbc324911d1ef71b7127..2c380d39800c54ee08bb2df2ccf0cbf8772454de 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.spec.ts @@ -1,9 +1,8 @@ -import { BescheidResource, BescheidSendBy, BescheidWizardStep, Wizard } from '@alfa-client/bescheid-shared'; +import { BescheidResource, BescheidSendBy, BescheidService, BescheidWizardStep, Wizard } from '@alfa-client/bescheid-shared'; import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource, createWizard } from '../../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test'; import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles'; @@ -26,10 +25,10 @@ describe('BescheidWizardBescheidVersendenComponent', () => { const bescheidResource: BescheidResource = createBescheidResource(); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); }); beforeEach(async () => { @@ -42,7 +41,7 @@ describe('BescheidWizardBescheidVersendenComponent', () => { MockComponent(BescheidWizardSummaryComponent), MockComponent(BescheidWizardBescheidVersendenSummaryComponent), ], - providers: [{ provide: BescheidService2, useValue: bescheidService }], + providers: [{ provide: BescheidService, useValue: bescheidService }], }).compileComponents(); createComponent(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.ts index 70408d0b23afb74630248f0a140e07f8f0ccf60a..d1bbf807849412342cc64563b8a77f8b84be271f 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/bescheid-wizard-bescheid-versenden-container.component.ts @@ -1,7 +1,6 @@ -import { BescheidResource, BescheidSendBy, BescheidWizardStep, Wizard } from '@alfa-client/bescheid-shared'; +import { BescheidResource, BescheidSendBy, BescheidService, BescheidWizardStep, Wizard } from '@alfa-client/bescheid-shared'; import { Component, inject, Input } from '@angular/core'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; @Component({ selector: 'alfa-bescheid-wizard-bescheid-versenden-container', @@ -17,7 +16,7 @@ export class BescheidWizardBescheidVersendenContainerComponent { return this._bescheidResource; } - private readonly bescheidService: BescheidService2 = inject(BescheidService2); + private readonly bescheidService: BescheidService = inject(BescheidService); public readonly wizard$: Observable<Wizard> = this.bescheidService.getWizard(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/summary/senden/bescheid-wizard-bescheid-versenden-senden.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/summary/senden/bescheid-wizard-bescheid-versenden-senden.component.spec.ts index 3f2dd5b69457b1b28b56291e838c633fc17b120f..f26bf0b030c3f4e2ce0e4eab50433c485302069c 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/summary/senden/bescheid-wizard-bescheid-versenden-senden.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-versenden/summary/senden/bescheid-wizard-bescheid-versenden-senden.component.spec.ts @@ -1,4 +1,4 @@ -import { BescheidLinkRel, BescheidWizardDialogResult } from '@alfa-client/bescheid-shared'; +import { BescheidLinkRel, BescheidService, BescheidWizardDialogResult } from '@alfa-client/bescheid-shared'; import { BinaryFileListContainerComponent } from '@alfa-client/binary-file'; import { createEmptyStateResource, @@ -14,7 +14,6 @@ import { expect } from '@jest/globals'; import { ButtonWithSpinnerComponent, TextareaEditorComponent, TextEditorComponent } from '@ods/component'; import { MockComponent } from 'ng-mocks'; import { EMPTY, of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource, createWizard } from '../../../../../../../../bescheid-shared/src/test/bescheid'; import { createSuccessfullyDoneCommandStateResource } from '../../../../../../../../command-shared/test/command'; import { getDataTestIdOf } from '../../../../../../../../tech-shared/test/data-test'; @@ -31,12 +30,12 @@ describe('BescheidWizardBescheidVersendenSendenComponent', () => { const attachmentsTestId: string = getDataTestIdOf('bescheid-attachments'); const empfaengerTestId: string = getDataTestIdOf('bescheid-nachricht-empfaenger'); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; let formService: BescheidFormService; let dialogRef: Mock<DialogRef<BescheidWizardDialogResult>>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); formService = new BescheidFormService(new FormBuilder(), useFromMock(bescheidService)); formService.submit = jest.fn(); dialogRef = mock(DialogRef<BescheidWizardDialogResult>); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts index c818a3613876e7b6533d508d5714fbbfa5881330..93aeea17c15dd88b2a0cd57455c972025c297de7 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts @@ -21,23 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource, BescheidWizardStep } from '@alfa-client/bescheid-shared'; -import { - createEmptyStateResource, - createErrorStateResource, - createLoadingStateResource, - HasLinkPipe, - StateResource, -} from '@alfa-client/tech-shared'; -import { - existsAsHtmlElement, - getElementComponentFromFixtureByCss, - Mock, - mock, - notExistsAsHtmlElement, - triggerEvent, - useFromMock, -} from '@alfa-client/test-utils'; +import { BescheidResource, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { createEmptyStateResource, createErrorStateResource, createLoadingStateResource, HasLinkPipe, StateResource, } from '@alfa-client/tech-shared'; +import { existsAsHtmlElement, getElementComponentFromFixtureByCss, Mock, mock, notExistsAsHtmlElement, triggerEvent, useFromMock, } from '@alfa-client/test-utils'; import { SpinnerComponent } from '@alfa-client/ui'; import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; import { EventEmitter } from '@angular/core'; @@ -45,7 +31,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; import { expect } from '@jest/globals'; import { MockComponent } from 'ng-mocks'; -import { BescheidService2 } from '../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource, createBescheidStateResource } from '../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; import { createProblemDetail } from '../../../../../tech-shared/test/error'; @@ -66,11 +51,11 @@ describe('BescheidWizardComponent', () => { const dokumenteHochladenStep: string = getDataTestIdOf('dokumente-hochladen-step'); const bescheidVersendenStepTestId: string = getDataTestIdOf('bescheid-versenden-step'); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; let formService: BescheidFormService; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); }); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts index 47aa453fd30472816900af6f9f3c15c74063a05d..54f6e363e26b5372102bc8be397585cae8b839f5 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts @@ -21,23 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { BescheidService } from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; import { createErrorStateResource, StateResource } from '@alfa-client/tech-shared'; -import { - createDialogRefMock, - DialogRefMock, - existsAsHtmlElement, - getElementComponentFromFixtureByCss, - Mock, - mock, - triggerEvent, -} from '@alfa-client/test-utils'; +import { createDialogRefMock, DialogRefMock, existsAsHtmlElement, getElementComponentFromFixtureByCss, Mock, mock, triggerEvent, } from '@alfa-client/test-utils'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { expect } from '@jest/globals'; import { ButtonWithSpinnerComponent } from '@ods/component'; import { CheckIconComponent, CloseIconComponent } from '@ods/system'; -import { BescheidService2 } from 'libs/bescheid-shared/src/lib/bescheid2.service'; import { createBescheidResource } from 'libs/bescheid-shared/src/test/bescheid'; import { createCommandStateResource, createSuccessfullyDoneCommandStateResource } from 'libs/command-shared/test/command'; import { getDataTestIdAttributeOf } from 'libs/tech-shared/test/data-test'; @@ -46,10 +38,7 @@ import { singleColdCompleted } from 'libs/tech-shared/test/marbles'; import { MockComponent } from 'ng-mocks'; import { EMPTY, of } from 'rxjs'; import { BescheidFormService } from '../../bescheid.formservice'; -import { - BescheidWizardCancelDialogContainerComponent, - CancelWizardDialogData, -} from './bescheid-wizard-cancel-dialog-container.component'; +import { BescheidWizardCancelDialogContainerComponent, CancelWizardDialogData, } from './bescheid-wizard-cancel-dialog-container.component'; describe('BescheidWizardCancelDialogContainerComponent', () => { let component: BescheidWizardCancelDialogContainerComponent; @@ -63,13 +52,13 @@ describe('BescheidWizardCancelDialogContainerComponent', () => { }; let formService: Mock<BescheidFormService>; - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; let dialogRef: DialogRefMock; beforeEach(() => { formService = mock(BescheidFormService); formService.submit = jest.fn().mockReturnValue(EMPTY); - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); bescheidService.deleteBescheid.mockReturnValue(EMPTY); dialogRef = createDialogRefMock(); }); @@ -84,7 +73,7 @@ describe('BescheidWizardCancelDialogContainerComponent', () => { ], providers: [ { - provide: BescheidService2, + provide: BescheidService, useValue: bescheidService, }, { diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts index 2b2ee2327c607f41cc889b00a62c84ff3b9560b2..e230e5d3b832b550dd2e99035e02bf44f9e4f5cf 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts @@ -21,14 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; import { isNotNil, StateResource } from '@alfa-client/tech-shared'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; import { Component, inject, OnDestroy, OnInit } from '@angular/core'; import { Resource } from '@ngxp/rest'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { BescheidFormService } from '../../bescheid.formservice'; export interface CancelWizardDialogData { @@ -45,7 +44,7 @@ export interface CancelWizardDialogResult { export class BescheidWizardCancelDialogContainerComponent implements OnInit, OnDestroy { private readonly dialogData: CancelWizardDialogData = inject(DIALOG_DATA); private readonly dialogRef = inject(DialogRef); - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); private readonly formService = inject(BescheidFormService); public saveStateResource$: Observable<StateResource<Resource>>; diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.spec.ts index 578b614b16d24e6b9d40ed36e1a0608b04781e24..3bc3dff8884f2550f4cdd597a520aedbfde10ef2 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.spec.ts @@ -1,9 +1,8 @@ -import { BescheidDocument, BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidDocument, createBescheidResource } from '../../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test'; import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles'; @@ -19,10 +18,10 @@ describe('BescheidWizardCreateDocumentButtonContainerComponent', () => { const bescheidDocument: BescheidDocument = createBescheidDocument(); const bescheidResource: BescheidResource = createBescheidResource(); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); }); beforeEach(async () => { @@ -31,7 +30,7 @@ describe('BescheidWizardCreateDocumentButtonContainerComponent', () => { BescheidWizardCreateDocumentButtonContainerComponent, MockComponent(BescheidWizardCreateDocumentButtonComponent), ], - providers: [{ provide: BescheidService2, useValue: bescheidService }], + providers: [{ provide: BescheidService, useValue: bescheidService }], }).compileComponents(); createComponent(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.ts index 63c525d76932091bdf971c5789c843568afd8112..4d9e68343b9ab3dc71d0afe637df79b13af83687 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/create-document-button-container/bescheid-wizard-create-document-button-container.component.ts @@ -1,7 +1,6 @@ -import { BescheidDocument, BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { Component, inject, Input } from '@angular/core'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; @Component({ selector: 'alfa-bescheid-wizard-create-document-button-container', @@ -10,7 +9,7 @@ import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/besc export class BescheidWizardCreateDocumentButtonContainerComponent { @Input() bescheidResource: BescheidResource; - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); public readonly bescheidDocument$: Observable<BescheidDocument> = this.bescheidService.getBescheidDocument(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.spec.ts index 9171b0143e8af45416b48d4a779d6e277ad0a5ef..0a88e197e4883b8c2186568328d0c104e0c10fcd 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.spec.ts @@ -1,9 +1,8 @@ -import { BescheidDocument, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared'; import { existsAsHtmlElement, getElementComponentFromFixtureByCss, Mock, mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidDocument } from '../../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test'; import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles'; @@ -19,11 +18,11 @@ describe('BescheidWizardDocumentFileContainerComponent', () => { const bescheidDocument: BescheidDocument = createBescheidDocument(); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; let formService: Mock<BescheidFormService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); formService = mock(BescheidFormService); }); @@ -31,7 +30,7 @@ describe('BescheidWizardDocumentFileContainerComponent', () => { await TestBed.configureTestingModule({ declarations: [BescheidWizardDocumentFileContainerComponent, MockComponent(BescheidWizardDocumentFileComponent)], providers: [ - { provide: BescheidService2, useValue: bescheidService }, + { provide: BescheidService, useValue: bescheidService }, { provide: BescheidFormService, useValue: formService }, ], }).compileComponents(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.ts index f50758a6f2914eacb0f1f0a3711e6d0eec3f5d13..cfaf1a4a8de33e7cf16ea21c8fc79a922987fda5 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/document-file-container/bescheid-wizard-document-file-container.component.ts @@ -1,7 +1,6 @@ -import { BescheidDocument, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared'; import { Component, inject } from '@angular/core'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { BescheidFormService } from '../../bescheid.formservice'; @Component({ @@ -9,7 +8,7 @@ import { BescheidFormService } from '../../bescheid.formservice'; templateUrl: './bescheid-wizard-document-file-container.component.html', }) export class BescheidWizardDocumentFileContainerComponent { - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); private readonly formService = inject(BescheidFormService); public readonly bescheidDocument$: Observable<BescheidDocument> = this.bescheidService.getBescheidDocument(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.spec.ts index 26fb71e977b88813e501e3adcebe112e4077c3fb..258427f6c2c4d46ec153dde019e6f51f0cb777b6 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.spec.ts @@ -21,13 +21,12 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidDocument, BescheidResource, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidResource, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared'; import { getElementComponentFromFixtureByCss, Mock, mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { expect } from '@jest/globals'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidDocument, createBescheidResource } from '../../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test'; import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles'; @@ -52,10 +51,10 @@ describe('BescheidWizardDokumenteHochladenComponent', () => { const bescheidResource: BescheidResource = createBescheidResource(); const bescheidDocument: BescheidDocument = createBescheidDocument(); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); }); beforeEach(async () => { @@ -70,7 +69,7 @@ describe('BescheidWizardDokumenteHochladenComponent', () => { MockComponent(BescheidWizardDokumenteHochladenFormComponent), MockComponent(BescheidWizardStepperComponent), ], - providers: [{ provide: BescheidService2, useValue: bescheidService }], + providers: [{ provide: BescheidService, useValue: bescheidService }], }).compileComponents(); createComponent(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.ts index c15d92820a7e08b122ed18f729dc344adc8f8a58..6f6f5711ad1c0996f6382f316255a2b248e8a671 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/bescheid-wizard-dokumente-hochladen-container.component.ts @@ -21,10 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidDocument, BescheidResource, BescheidWizardStep } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidResource, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared'; import { Component, inject, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; @Component({ selector: 'alfa-bescheid-wizard-dokumente-hochladen-container', @@ -33,7 +32,7 @@ import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/besc export class BescheidWizardDokumenteHochladenContainerComponent implements OnInit { @Input() bescheidResource: BescheidResource; - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); public readonly bescheidDocument$: Observable<BescheidDocument> = this.bescheidService.getBescheidDocument(); public isBescheidDocumentMissing: boolean = false; diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html index edd8aff832236fb11a9b372a47c40f4bbb8d06d3..007a02ec854d9001c4eaef88f688760d6db3fa8d 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html @@ -23,7 +23,7 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<div class="mt-4 flex flex-col gap-4"> +<div class="mt-4 flex max-w-72 flex-col gap-4"> @if (bescheidResource | hasLink: BescheidLinkRel.CREATE_DOCUMENT) { <alfa-bescheid-wizard-create-document-button-container [bescheidResource]="bescheidResource" diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.spec.ts index aad7d40ccedf3a798acadb6be1b76e9560b43912..c2c9cd000ce52b6755a0dc94e667cfa89975b87d 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.spec.ts @@ -1,9 +1,8 @@ -import { BescheidDocument, BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { getElementComponentFromFixtureByCss, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidDocument, createBescheidResource } from '../../../../../../bescheid-shared/src/test/bescheid'; import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test'; import { createFile } from '../../../../../../tech-shared/test/file'; @@ -19,10 +18,10 @@ describe('BescheidWizardDokumentHochladenContainerButtonComponent', () => { const bescheidDocument: BescheidDocument = createBescheidDocument(); - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); }); beforeEach(async () => { @@ -31,7 +30,7 @@ describe('BescheidWizardDokumentHochladenContainerButtonComponent', () => { BescheidWizardUploadDocumentButtonContainerComponent, MockComponent(BescheidWizardUploadDocumentButtonComponent), ], - providers: [{ provide: BescheidService2, useValue: bescheidService }], + providers: [{ provide: BescheidService, useValue: bescheidService }], }).compileComponents(); createComponent(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.ts index a874617f496f42ccb8492a8fd116ae29d2384d36..a20952de3f529cca7bfe2dcc1bbb5328b773c793 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/bescheid-wizard-upload-document-button-container.component.ts @@ -1,7 +1,6 @@ -import { BescheidDocument, BescheidResource } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; import { Component, inject, Input } from '@angular/core'; import { Observable } from 'rxjs'; -import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/bescheid2.service'; @Component({ selector: 'alfa-bescheid-wizard-upload-document-button-container', @@ -10,7 +9,7 @@ import { BescheidService2 } from '../../../../../../bescheid-shared/src/lib/besc export class BescheidWizardUploadDocumentButtonContainerComponent { @Input() bescheidResource: BescheidResource; - private readonly bescheidService = inject(BescheidService2); + private readonly bescheidService = inject(BescheidService); public readonly bescheidDocument$: Observable<BescheidDocument> = this.bescheidService.getBescheidDocument(); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/upload-document-button/bescheid-wizard-upload-document-button.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/upload-document-button/bescheid-wizard-upload-document-button.component.spec.ts index 66689e97b55fe62c4176df10614f23737020c5ba..083c98f7eed6d4c044c5069d477adce953fd8722 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/upload-document-button/bescheid-wizard-upload-document-button.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/upload-document-button-container/upload-document-button/bescheid-wizard-upload-document-button.component.spec.ts @@ -1,4 +1,4 @@ -import { BescheidDocument, BescheidLinkRel, createEmptyUploadInProgress } from '@alfa-client/bescheid-shared'; +import { BescheidDocument, BescheidLinkRel, BescheidService, createEmptyUploadInProgress } from '@alfa-client/bescheid-shared'; import { HasLinkPipe } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, @@ -12,7 +12,6 @@ import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; import { SingleFileUploadEditorComponent } from '@ods/component'; import { BescheidUploadIconComponent, SpinnerIconComponent } from '@ods/system'; import { MockComponent } from 'ng-mocks'; -import { BescheidService2 } from '../../../../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheidDocument, createBescheidResource, @@ -34,7 +33,7 @@ describe('BescheidWizardDokumentHochladenButtonComponent', () => { let formService: BescheidFormService; beforeEach(() => { - formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(mock(BescheidService2))); + formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(mock(BescheidService))); }); beforeEach(async () => { diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts index 86c5f0caee0f27416b51343699e465ec2eb4ef47..2197d0fc501a39c9c0569732ba606df100d60f9d 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts @@ -21,7 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Bescheid, BescheidLinkRel, BescheidResource, BescheidSendBy, BescheidWizardStep, Wizard, } from '@alfa-client/bescheid-shared'; +import { + Bescheid, + BescheidLinkRel, + BescheidResource, + BescheidSendBy, + BescheidService, + BescheidWizardStep, + Wizard, +} from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; import { createErrorStateResource, createLoadingStateResource, formatForDatabase, StateResource } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; @@ -33,7 +41,6 @@ import { faker } from '@faker-js/faker'; import { expect } from '@jest/globals'; import { ResourceUri } from '@ngxp/rest'; import { EMPTY, Observable, of } from 'rxjs'; -import { BescheidService2 } from '../../../../bescheid-shared/src/lib/bescheid2.service'; import { createBescheid, createBescheidResource, createWizard } from '../../../../bescheid-shared/src/test/bescheid'; import { createSuccessfullyDoneCommandStateResource } from '../../../../command-shared/test/command'; import { createProblemDetail } from '../../../../tech-shared/test/error'; @@ -45,13 +52,13 @@ registerLocaleData(localeDe); describe('BescheidFormService', () => { let service: BescheidFormService; - let bescheidService: Mock<BescheidService2>; + let bescheidService: Mock<BescheidService>; const now: Date = new Date(); Date.now = jest.fn().mockReturnValue(now); const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); beforeEach(() => { - bescheidService = mock(BescheidService2); + bescheidService = mock(BescheidService); service = new BescheidFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); service.setVorgangWithEingangResource(vorgangWithEingangResource); }); diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts index eb96bb9d90af5f6729a3f251ea01bc2e91c58eb7..bdcd436ea2fe58713c255e8a953101205e6b9b90 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Bescheid, BescheidLinkRel, BescheidResource, BescheidSendBy, BescheidWizardStep, Wizard, } from '@alfa-client/bescheid-shared'; +import { Bescheid, BescheidLinkRel, BescheidResource, BescheidSendBy, BescheidService, BescheidWizardStep, Wizard, } from '@alfa-client/bescheid-shared'; import { CommandResource, switchMapCommandSuccessfullyDone } from '@alfa-client/command-shared'; import { AbstractFormService, convertToBoolean, formatForDatabase, isNotNil, StateResource } from '@alfa-client/tech-shared'; import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; @@ -30,7 +30,6 @@ import { FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, import { getUrl, hasLink, ResourceUri } from '@ngxp/rest'; import { isNil } from 'lodash-es'; import { first, Observable, startWith, switchMap } from 'rxjs'; -import { BescheidService2 } from '../../../../bescheid-shared/src/lib/bescheid2.service'; @Injectable() export class BescheidFormService extends AbstractFormService<CommandResource> { @@ -49,7 +48,7 @@ export class BescheidFormService extends AbstractFormService<CommandResource> { constructor( formBuilder: UntypedFormBuilder, - private readonly bescheidService: BescheidService2, + private readonly bescheidService: BescheidService, ) { super(formBuilder); } diff --git a/alfa-client/libs/bescheid/src/lib/bescheid.module.ts b/alfa-client/libs/bescheid/src/lib/bescheid.module.ts index f098c06d4ec7b163b55a8bad5f60c7682521866c..bff2453ae3266fe805b85177073edc854782757c 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid.module.ts +++ b/alfa-client/libs/bescheid/src/lib/bescheid.module.ts @@ -28,8 +28,6 @@ import { ConvertForDataTestPipe, ConvertProblemDetailToErrorMessagesPipe, GetUrl import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { ButtonWithSpinnerComponent, FileUploadEditorComponent, SingleFileUploadEditorComponent, TextareaEditorComponent, TextEditorComponent, } from '@ods/component'; -import { BescheidInVorgangContainerComponent } from './bescheid-in-vorgang-container/bescheid-in-vorgang-container.component'; -import { BescheidInVorgangComponent } from './bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component'; import { BescheidListInVorgangContainerComponent } from './bescheid-list-in-vorgang-container/bescheid-list-in-vorgang-container.component'; import { BescheidListInVorgangComponent } from './bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/bescheid-list-in-vorgang.component'; import { DocumentInBescheidContainerComponent } from './bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/document-in-bescheid-container/document-in-bescheid-container.component'; @@ -114,8 +112,6 @@ import { BescheidWizardWeiterButtonComponent } from './bescheid-wizard-container MultiFileUploadEditorComponent, ], declarations: [ - BescheidInVorgangContainerComponent, - BescheidInVorgangComponent, BescheidListInVorgangContainerComponent, BescheidListInVorgangComponent, DocumentInBescheidContainerComponent, @@ -152,10 +148,6 @@ import { BescheidWizardWeiterButtonComponent } from './bescheid-wizard-container BescheidWizardBescheidVersendenSpeichernComponent, StepContentLayoutComponent, ], - exports: [ - BescheidInVorgangContainerComponent, - BescheidListInVorgangContainerComponent, - BeschiedenDateInVorgangContainerComponent, - ], + exports: [BescheidListInVorgangContainerComponent, BeschiedenDateInVorgangContainerComponent], }) export class BescheidModule {} diff --git a/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-container/beschieden-date-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-container/beschieden-date-container.component.spec.ts index 94e4e5de89a58a43eaacae49d8473f9e979afb7b..e70aa9d868a76481094ebd59714e262e0356a98d 100644 --- a/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-container/beschieden-date-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-container/beschieden-date-container.component.spec.ts @@ -21,13 +21,13 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidService } from '@alfa-client/bescheid-shared'; -import { Mock, existsAsHtmlElement, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; +import { existsAsHtmlElement, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { registerLocaleData } from '@angular/common'; import localeDe from '@angular/common/locales/de'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MockComponent } from 'ng-mocks'; +import { BescheidService } from '@alfa-client/bescheid-shared'; import { CloseIconComponent, StampIconComponent } from '@ods/system'; import { createBescheidResource } from 'libs/bescheid-shared/src/test/bescheid'; import { FormatFullDatePipe } from 'libs/tech-shared/src/lib/pipe/format-full-date.pipe'; diff --git a/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-in-vorgang-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-in-vorgang-container.component.spec.ts index c2ace7dc8dfdb9b91b374315dcd557b38962c0e9..d7b59d493cc09da7afa7a84f1decfc6fa5ba1a86 100644 --- a/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-in-vorgang-container.component.spec.ts +++ b/alfa-client/libs/bescheid/src/lib/beschieden-date-in-vorgang-container/beschieden-date-in-vorgang-container.component.spec.ts @@ -22,7 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { BescheidService } from '@alfa-client/bescheid-shared'; -import { Mock, existsAsHtmlElement, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; +import { existsAsHtmlElement, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; @@ -40,10 +40,7 @@ describe('BeschiedenDateInVorgangContainerComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ - BeschiedenDateInVorgangContainerComponent, - MockComponent(BeschiedenDateContainerComponent), - ], + declarations: [BeschiedenDateInVorgangContainerComponent, MockComponent(BeschiedenDateContainerComponent)], providers: [ { provide: BescheidService, diff --git a/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.spec.ts b/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.spec.ts index 9d26d35e6e9f7a882e0bad43d87f69fcb7562cc3..f32b65dd32e10f8754cb8e138122312211bdac26 100644 --- a/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.spec.ts +++ b/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.spec.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BlobWithFileName, createEmptyStateResource, createStateResource, StateResource } from '@alfa-client/tech-shared'; +import { BlobWithFileName, createEmptyStateResource, createErrorStateResource, createStateResource, StateResource, } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { SnackBarService } from '@alfa-client/ui'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; @@ -36,6 +36,7 @@ import { DummyLinkRel } from 'libs/tech-shared/test/dummy'; import { createDummyResource } from 'libs/tech-shared/test/resource'; import { uniqueId } from 'lodash-es'; import { Observable, of, throwError } from 'rxjs'; +import { createApiError } from '../../../tech-shared/test/error'; import { createHttpErrorResponse } from '../../../tech-shared/test/http'; import { multipleCold, singleCold, singleHot } from '../../../tech-shared/test/marbles'; import { BinaryFileResource, FileUploadType, ToUploadFile, UploadFile, UploadFileByIdentifier } from './binary-file.model'; @@ -98,11 +99,18 @@ describe('BinaryFileService', () => { const toUploadFile: ToUploadFile = { type, file, uploadUrl: faker.internet.url() }; beforeEach(() => { + service._clearFailedUploads = jest.fn(); service._generateUniqueId = jest.fn().mockReturnValue(uniqId); service._addUploadFileLoading = jest.fn(); service._doUploadFile = jest.fn(); }); + it('should clear failed uploads', () => { + service.uploadFileNew(toUploadFile); + + expect(service._clearFailedUploads).toHaveBeenCalled(); + }); + it('should create an empty map if type key not exists', () => { service._uploadFiles$.next({}); @@ -124,6 +132,39 @@ describe('BinaryFileService', () => { }); }); + describe('clear failed uploads', () => { + const fileUploadType: string = faker.word.noun(); + const failedFileKey: string = faker.word.noun(); + const successFileKey: string = faker.word.noun(); + const successUploadFile: UploadFile = createUploadFile(); + const secondSuccessFileKey: string = faker.word.noun(); + const secondFileUploadType: string = faker.word.noun(); + const secondSuccessUploadFile: UploadFile = createUploadFile(); + + it('should remove failed uploads', () => { + service._uploadFiles$.next({ + [fileUploadType]: { + [failedFileKey]: { ...createUploadFile(), uploadedFile: createErrorStateResource(createApiError()) }, + [successFileKey]: successUploadFile, + }, + [secondFileUploadType]: { + [secondSuccessFileKey]: secondSuccessUploadFile, + }, + }); + + service._clearFailedUploads(fileUploadType); + + expect(service._uploadFiles$.value).toEqual({ + [fileUploadType]: { + [successFileKey]: successUploadFile, + }, + [secondFileUploadType]: { + [secondSuccessFileKey]: secondSuccessUploadFile, + }, + }); + }); + }); + describe('add upload file loading', () => { const uniqId: string = uniqueId(); const type: string = 'dummyType'; diff --git a/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.ts b/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.ts index 223db64a230da606052caaf48a90dc45cd60f6a8..b6a628e32f0ef01e8ab34a02fc44a486ce1e69e9 100644 --- a/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.ts +++ b/alfa-client/libs/binary-file-shared/src/lib/binary-file.service.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BlobWithFileName, createEmptyStateResource, createErrorStateResource, createStateResource, EMPTY_STRING, getMessageForInvalidParam, HttpHeader, isNotNil, isUnprocessableEntity, isValidationFieldFileSizeExceedError, sanitizeFileName, StateResource, } from '@alfa-client/tech-shared'; +import { BlobWithFileName, createEmptyStateResource, createErrorStateResource, createStateResource, EMPTY_STRING, getMessageForInvalidParam, hasStateResourceError, HttpHeader, isNotNil, isUnprocessableEntity, isValidationFieldFileSizeExceedError, sanitizeFileName, StateResource, } from '@alfa-client/tech-shared'; import { SnackBarService } from '@alfa-client/ui'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; @@ -50,12 +50,25 @@ export class BinaryFileService { } public uploadFileNew(toUploadFile: ToUploadFile): void { + this._clearFailedUploads(toUploadFile.type); this.createEmptyMapIfTypeNotExists(toUploadFile.type); const uniqId: string = this._generateUniqueId(); this._addUploadFileLoading(uniqId, toUploadFile); this._doUploadFile(uniqId, toUploadFile); } + _clearFailedUploads(fileUploadType: FileUploadType): void { + const uploads: UploadFileByIdentifier = this._uploadFiles$.value[fileUploadType]; + const keys: string[] = Object.keys(uploads); + const successfulUploads: UploadFileByIdentifier = {}; + for (const key of keys) { + if (!hasStateResourceError(uploads[key].uploadedFile)) { + successfulUploads[key] = uploads[key]; + } + } + this._uploadFiles$.next({ ...this._uploadFiles$.value, [fileUploadType]: successfulUploads }); + } + _generateUniqueId(): string { return uniqueId(); } diff --git a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.html b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.html index cfa93fbc6b3b9dbd01834a8d31c1bf74f4088299..de2d67af94b520ec15bb8292ef9278cb78d8e395 100644 --- a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.html +++ b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.html @@ -23,9 +23,7 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<ods-attachment-wrapper> - <alfa-binary-file-list - [binaryFileListStateResource]="binaryFileListStateResource$ | async" - [listOrientation]="listOrientation" - ></alfa-binary-file-list> -</ods-attachment-wrapper> +<alfa-binary-file-list + [binaryFileListStateResource]="binaryFileListStateResource$ | async" + [listOrientation]="listOrientation" +></alfa-binary-file-list> diff --git a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.spec.ts b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.spec.ts index e9473e9ee486bc437328ee6fe85227d12c6293e5..6cca0983e8268484b83772fa1f78dafda782e70e 100644 --- a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.spec.ts +++ b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list-container.component.spec.ts @@ -34,27 +34,19 @@ import { of } from 'rxjs'; import { BinaryFileListContainerComponent } from './binary-file-list-container.component'; import { BinaryFileListComponent } from './binary-file-list/binary-file-list.component'; -import { AttachmentWrapperComponent } from '@ods/system'; - describe('BinaryFileListContainerComponent', () => { let component: BinaryFileListContainerComponent; let fixture: ComponentFixture<BinaryFileListContainerComponent>; const binaryFileService: Mock<BinaryFileService> = mock(BinaryFileService); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource( - createBinaryFileResource(), - ); + const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource()); const resource: Resource = createDummyResource(); const linkRel: LinkRelationName = DummyLinkRel.DUMMY; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ - BinaryFileListContainerComponent, - MockComponent(BinaryFileListComponent), - MockComponent(AttachmentWrapperComponent), - ], + declarations: [BinaryFileListContainerComponent, MockComponent(BinaryFileListComponent)], providers: [ { provide: BinaryFileService, @@ -85,8 +77,10 @@ describe('BinaryFileListContainerComponent', () => { describe('binary file list', () => { it('should be called with binary file state resource', () => { - const binaryFileListComponent: BinaryFileListComponent = - getMockComponent<BinaryFileListComponent>(fixture, BinaryFileListComponent); + const binaryFileListComponent: BinaryFileListComponent = getMockComponent<BinaryFileListComponent>( + fixture, + BinaryFileListComponent, + ); expect(binaryFileListComponent.binaryFileListStateResource).toBe(binaryFileStateResource); }); diff --git a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.html b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.html index 70054de869940144f9b0e1d3fa0eb7c23ea72a33..a4ee6adc69c75525b8a32dd2e0ad5a9352701c2d 100644 --- a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.html +++ b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.html @@ -23,11 +23,13 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<div [binaryFileListOrientation]="listOrientation"> - <alfa-binary-file2-container - *ngFor="let binaryFile of binaryFileListStateResource.resource | toEmbeddedResources: binaryFileListLinkRel.FILE_LIST" - [file]="binaryFile" - [deletable]="false" - > - </alfa-binary-file2-container> -</div> +@if (binaryFileListStateResource.resource | toEmbeddedResources: binaryFileListLinkRel.FILE_LIST; as binaryFileList) { + @if (binaryFileList.length) { + <ods-attachment-wrapper data-test-id="binary-file-list-wrapper"> + <div [binaryFileListOrientation]="listOrientation"> + <alfa-binary-file2-container *ngFor="let binaryFile of binaryFileList" [file]="binaryFile" [deletable]="false"> + </alfa-binary-file2-container> + </div> + </ods-attachment-wrapper> + } +} diff --git a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.spec.ts b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.spec.ts index fbbc820600ee4d1b3a9235dafd3515f9c1f16404..354a9d2be51cb3f1bd9bdb20d1525ed75b653904 100644 --- a/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.spec.ts +++ b/alfa-client/libs/binary-file/src/lib/binary-file-list-container/binary-file-list/binary-file-list.component.spec.ts @@ -23,9 +23,11 @@ */ import { BinaryFileListResource, BinaryFileResource } from '@alfa-client/binary-file-shared'; import { createStateResource, StateResource, ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared'; -import { getMockComponent } from '@alfa-client/test-utils'; +import { existsAsHtmlElement, getMockComponent, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AttachmentWrapperComponent } from '@ods/system'; import { createBinaryFileListResource, createBinaryFileResource } from 'libs/binary-file-shared/test/binary-file'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent, MockDirective } from 'ng-mocks'; import { BinaryFile2ContainerComponent } from '../../binary-file2-container/binary-file2-container.component'; import { BinaryFileListOrientationDirective } from '../../directive/binary-file-list-orientation/binary-file-list-orientation.directive'; @@ -36,9 +38,11 @@ describe('BinaryFileListComponent', () => { let fixture: ComponentFixture<BinaryFileListComponent>; const binaryFile: BinaryFileResource = createBinaryFileResource(); - const binaryFileListStateResource: StateResource<BinaryFileListResource> = createStateResource( - createBinaryFileListResource([binaryFile]), - ); + function getBinaryFileListStateResource(binaryFiles: BinaryFileResource[]): StateResource<BinaryFileListResource> { + return createStateResource(createBinaryFileListResource(binaryFiles)); + } + + const wrapperSelector: string = getDataTestIdOf('binary-file-list-wrapper'); beforeEach(async () => { await TestBed.configureTestingModule({ @@ -46,13 +50,14 @@ describe('BinaryFileListComponent', () => { BinaryFileListComponent, ToEmbeddedResourcesPipe, MockComponent(BinaryFile2ContainerComponent), + MockComponent(AttachmentWrapperComponent), MockDirective(BinaryFileListOrientationDirective), ], }).compileComponents(); fixture = TestBed.createComponent(BinaryFileListComponent); component = fixture.componentInstance; - component.binaryFileListStateResource = binaryFileListStateResource; + component.binaryFileListStateResource = getBinaryFileListStateResource([binaryFile]); fixture.detectChanges(); }); @@ -60,6 +65,22 @@ describe('BinaryFileListComponent', () => { expect(component).toBeTruthy(); }); + describe('template', () => { + describe('attachment wrapper', () => { + it('should show', () => { + existsAsHtmlElement(fixture, wrapperSelector); + }); + + it('should hide', () => { + component.binaryFileListStateResource = getBinaryFileListStateResource([]); + + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, wrapperSelector); + }); + }); + }); + describe('binary file container', () => { it('should be called with file', () => { const binaryFileContainerComponent: BinaryFile2ContainerComponent = getMockComponent<BinaryFile2ContainerComponent>( diff --git a/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts b/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts index 3a1a42958aca047046c5aa29edaed15dc77a1705..956be5722cdcd4966e12c8a5216bfb0dde53d706 100644 --- a/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts +++ b/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts @@ -1,7 +1,7 @@ import { Directive, ElementRef, Input } from '@angular/core'; export const _verticalClasses: string[] = ['flex', 'flex-col']; -export const _horizontalClasses: string[] = ['flex', 'flex-row', 'flex-wrap']; +export const _horizontalClasses: string[] = ['flex', 'flex-wrap', 'gap-2']; export enum BinaryFileListOrientation { HORIZONTAL = 'horizontal', diff --git a/alfa-client/libs/binary-file/src/lib/download-archive-file-button-container/download-archive-file-button-container.component.html b/alfa-client/libs/binary-file/src/lib/download-archive-file-button-container/download-archive-file-button-container.component.html index b4f57dff63600c9090de98d2646272bad58e06f4..9434cdd4a3edbaa2d3adb37bc41b54d585dc1b81 100644 --- a/alfa-client/libs/binary-file/src/lib/download-archive-file-button-container/download-archive-file-button-container.component.html +++ b/alfa-client/libs/binary-file/src/lib/download-archive-file-button-container/download-archive-file-button-container.component.html @@ -24,6 +24,7 @@ --> <ods-download-button + dataTestId="download-archive-file-button" [stateResource]="downloadArchiveInProgress$ | async" data-test-class="download-archive" (click)="downloadArchive()" diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html index 1bfa1fb53740999476b2e6b342777abec551f000..538932cf346eea42688fc28259a330b1d18fb552 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html @@ -4,10 +4,13 @@ [attr.data-test-id]="(label | convertForDataTest) + '-file-upload-button'" [multi]="true" [isLoading]="isUploadInProgress$ | async" - class="relative w-72" + [variant]="uploadButtonVariant" data-test-id="binary-file-upload" + dataTestId="multi-file-upload-button" > <ods-spinner-icon spinner size="medium" /> <ods-attachment-icon icon size="medium" /> - <p text class="text-center">{{ label }}</p> + @if (label) { + <p text data-test-id="upload-button-label" class="text-center">{{ label }}</p> + } </ods-file-upload-button> diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts index dc42e69a0f52518ba01f5f3ddf2009ef04e344e9..38303a464c9f128eb05963f94df756663567e129 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts @@ -1,11 +1,17 @@ import { BinaryFileService, FileUploadType, ToUploadFile } from '@alfa-client/binary-file-shared'; import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; -import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock } from '@alfa-client/test-utils'; +import { + existsAsHtmlElement, + getElementComponentFromFixtureByCss, + mock, + Mock, + notExistsAsHtmlElement, +} from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker/.'; import { expect } from '@jest/globals'; import { getUrl, Resource } from '@ngxp/rest'; -import { FileUploadButtonComponent, SpinnerIconComponent } from '@ods/system'; +import { FileUploadButtonComponent, SpinnerIconComponent, UploadButtonVariants } from '@ods/system'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; @@ -23,6 +29,7 @@ describe('MultiFileUploadEditorComponent', () => { const uploadResource: Resource = createDummyResource([uploadLinkRel]); const buttonTestId: string = getDataTestIdOf('Ein_Label-file-upload-button'); + const buttonLabelTestId: string = getDataTestIdOf('upload-button-label'); let binaryFileService: Mock<BinaryFileService>; @@ -104,6 +111,24 @@ describe('MultiFileUploadEditorComponent', () => { } as ToUploadFile); }); }); + + describe('get uploadButtonVariant', () => { + it('should return "label"', () => { + component.label = 'test'; + + const result: UploadButtonVariants['variant'] = component.uploadButtonVariant; + + expect(result).toBe('label'); + }); + + it('should return "icon"', () => { + component.label = ''; + + const result: UploadButtonVariants['variant'] = component.uploadButtonVariant; + + expect(result).toBe('icon'); + }); + }); }); describe('template', () => { @@ -125,5 +150,22 @@ describe('MultiFileUploadEditorComponent', () => { expect(fileButtonComponent.isLoading).toEqual(true); }); }); + describe('upload button label', () => { + it('should show', () => { + component.label = 'test'; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, buttonLabelTestId); + }); + + it('should hide', () => { + component.label = ''; + + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, buttonLabelTestId); + }); + }); }); }); diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts index 4c057b3f3d7b52b25dc63164e62f06bb054b83c8..2a9623612015f5350b39822c605c8faed1903d59 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts @@ -5,7 +5,7 @@ import { AsyncPipe } from '@angular/common'; import { Component, HostListener, inject, Input, OnInit } from '@angular/core'; import { ControlContainer, FormGroupDirective, ReactiveFormsModule } from '@angular/forms'; import { getUrl, Resource } from '@ngxp/rest'; -import { AttachmentIconComponent, FileUploadButtonComponent, SpinnerIconComponent } from '@ods/system'; +import { AttachmentIconComponent, FileUploadButtonComponent, SpinnerIconComponent, UploadButtonVariants } from '@ods/system'; import { uniqueId } from 'lodash-es'; import { Observable } from 'rxjs'; @@ -55,4 +55,8 @@ export class MultiFileUploadEditorComponent implements OnInit { }); } } + + get uploadButtonVariant(): UploadButtonVariants['variant'] { + return this.label ? 'label' : 'icon'; + } } diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html b/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html index 184ac868f9f594da443f6f89b969ce1cc85b1dfc..8efd002c007d46dba8fc79c2526e59e132191c66 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html @@ -1,13 +1,15 @@ -<ods-file-upload-list-container - [parentFormArrayName]="filesFormFieldName" - [fileUploadType]="fileUploadType" - [filesResource]="filesResource" - [filesLinkRel]="filesLinkRelation" - data-test-id="file-list" -></ods-file-upload-list-container> -<ods-multi-file-upload-editor - [fileUploadType]="fileUploadType" - [uploadResource]="uploadResource" - [uploadLinkRelation]="uploadLinkRelation" - data-test-id="multi-file-upload-editor" -></ods-multi-file-upload-editor> \ No newline at end of file +<div class="flex flex-col gap-2"> + <ods-file-upload-list-container + [parentFormArrayName]="filesFormFieldName" + [fileUploadType]="fileUploadType" + [filesResource]="filesResource" + [filesLinkRel]="filesLinkRelation" + data-test-id="file-list" + /> + <ods-multi-file-upload-editor + [fileUploadType]="fileUploadType" + [uploadResource]="uploadResource" + [uploadLinkRelation]="uploadLinkRelation" + data-test-id="multi-file-upload-editor" + /> +</div> diff --git a/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.html b/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.html index b8b8d9e4c1d3addfff29d35af5e786923e194454..2649c1cdb731e0b5997df29d904241f569cf544d 100644 --- a/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.html +++ b/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.html @@ -23,28 +23,18 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<ozgcloud-spinner - *ngIf="binaryFileListStateResource.resource" - [stateResource]="binaryFileListStateResource" -> +<ozgcloud-spinner *ngIf="binaryFileListStateResource.resource" [stateResource]="binaryFileListStateResource"> <ods-attachment-wrapper data-test-id="file-list"> - <ods-attachment-header - [title]="title" - *ngIf="title || archiveDownloadUri" - data-test-id="file-list-header" - > + <ods-attachment-header [title]="title" *ngIf="title || archiveDownloadUri" data-test-id="file-list-header"> <alfa-download-archive-file-button-container *ngIf="archiveDownloadUri" - data-test-class="download-archive-file-button" + data-test-id="download-archive-file-button-container" [downloadUri]="archiveDownloadUri" action-buttons ></alfa-download-archive-file-button-container ></ods-attachment-header> <ng-container - *ngFor=" - let binaryFileResource of binaryFileListStateResource.resource - | toEmbeddedResources: fileListRel.FILE_LIST - " + *ngFor="let binaryFileResource of binaryFileListStateResource.resource | toEmbeddedResources: fileListRel.FILE_LIST" > <alfa-binary-file2-container [file]="binaryFileResource" diff --git a/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.spec.ts b/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.spec.ts index 93be7c71dab2c1f665423770e2c877a73e12c869..500c35cf858960e3a27674d2bf53ca9999555ca5 100644 --- a/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.spec.ts +++ b/alfa-client/libs/binary-file/src/lib/vertical-binary-file-list/vertical-binary-file-list.component.spec.ts @@ -23,21 +23,14 @@ */ import { BinaryFileResource } from '@alfa-client/binary-file-shared'; import { ToEmbeddedResourcesPipe, createStateResource } from '@alfa-client/tech-shared'; -import { - existsAsHtmlElement, - getMockComponent, - notExistsAsHtmlElement, -} from '@alfa-client/test-utils'; +import { existsAsHtmlElement, getMockComponent, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { SpinnerComponent } from '@alfa-client/ui'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; import { ResourceUri } from '@ngxp/rest'; import { AttachmentHeaderComponent, AttachmentWrapperComponent } from '@ods/system'; -import { - createBinaryFileListResource, - createBinaryFileResource, -} from 'libs/binary-file-shared/test/binary-file'; -import { getDataTestClassOf, getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { createBinaryFileListResource, createBinaryFileResource } from 'libs/binary-file-shared/test/binary-file'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; import { BinaryFile2ContainerComponent } from '../binary-file2-container/binary-file2-container.component'; import { DownloadArchiveFileButtonContainerComponent } from '../download-archive-file-button-container/download-archive-file-button-container.component'; @@ -47,7 +40,7 @@ describe('VerticalBinaryFileListComponent', () => { let component: VerticalBinaryFileListComponent; let fixture: ComponentFixture<VerticalBinaryFileListComponent>; - const downloadArchiveFileButton: string = getDataTestClassOf('download-archive-file-button'); + const downloadArchiveFileButton: string = getDataTestIdOf('download-archive-file-button-container'); const fileListHeader: string = getDataTestIdOf('file-list-header'); const binaryFile: BinaryFileResource = createBinaryFileResource(); @@ -69,9 +62,7 @@ describe('VerticalBinaryFileListComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(VerticalBinaryFileListComponent); component = fixture.componentInstance; - component.binaryFileListStateResource = createStateResource( - createBinaryFileListResource([binaryFile]), - ); + component.binaryFileListStateResource = createStateResource(createBinaryFileListResource([binaryFile])); fixture.detectChanges(); }); @@ -82,28 +73,19 @@ describe('VerticalBinaryFileListComponent', () => { describe('binary file component', () => { describe('should be called with', () => { it('file', () => { - const comp: BinaryFile2ContainerComponent = getMockComponent( - fixture, - BinaryFile2ContainerComponent, - ); + const comp: BinaryFile2ContainerComponent = getMockComponent(fixture, BinaryFile2ContainerComponent); expect(comp.file).toBe(binaryFile); }); it('deletable', () => { - const comp: BinaryFile2ContainerComponent = getMockComponent( - fixture, - BinaryFile2ContainerComponent, - ); + const comp: BinaryFile2ContainerComponent = getMockComponent(fixture, BinaryFile2ContainerComponent); expect(comp.deletable).toBe(component.deletable); }); it('downloadFileNamePrefix', () => { - const comp: BinaryFile2ContainerComponent = getMockComponent( - fixture, - BinaryFile2ContainerComponent, - ); + const comp: BinaryFile2ContainerComponent = getMockComponent(fixture, BinaryFile2ContainerComponent); expect(comp.downloadFileNamePrefix).toBe(component.downloadFileNamePrefix); }); diff --git a/alfa-client/libs/command-shared/src/lib/command.model.ts b/alfa-client/libs/command-shared/src/lib/command.model.ts index 7bc63c58fa69ac135c6cc8ed82104b6d5d25b419..ecbb001c6287b6f244cac55bbfcc8d59962ab703 100644 --- a/alfa-client/libs/command-shared/src/lib/command.model.ts +++ b/alfa-client/libs/command-shared/src/lib/command.model.ts @@ -33,6 +33,7 @@ export interface CreateCommand { body?: any | CommandBody; relationId?: string; } + export interface CommandBody { item: any; } @@ -76,6 +77,7 @@ export enum CommandOrder { VORGANG_ZURUECKHOLEN = 'VORGANG_ZURUECKHOLEN', VORGANG_BEARBEITEN = 'VORGANG_BEARBEITEN', VORGANG_BESCHEIDEN = 'VORGANG_BESCHEIDEN', + FORWARD_VORGANG = 'FORWARD_VORGANG', VORGANG_ZURUECKSTELLEN = 'VORGANG_ZURUECKSTELLEN', VORGANG_ABSCHLIESSEN = 'VORGANG_ABSCHLIESSEN', VORGANG_WIEDEREROEFFNEN = 'VORGANG_WIEDEREROEFFNEN', @@ -103,6 +105,8 @@ export interface CreateCommandProps { snackBarErrorMessage?: string; } +export type CreateCommandPropsWithoutResource = Omit<CreateCommandProps, 'resource'>; + export interface SaveCommandProps { snackBarMessage: string; } diff --git a/alfa-client/libs/command-shared/test/command.ts b/alfa-client/libs/command-shared/test/command.ts index afd83feddb19509b7484212c166781868810c011..10df5d5b0a12eec1292a32dbc27e513f58eb0927 100644 --- a/alfa-client/libs/command-shared/test/command.ts +++ b/alfa-client/libs/command-shared/test/command.ts @@ -35,6 +35,7 @@ import { CommandStatus, CreateCommand, CreateCommandProps, + CreateCommandPropsWithoutResource, } from '../src/lib/command.model'; export function createCommand(): Command { @@ -85,8 +86,11 @@ export function createCreateCommand(order: CommandOrder = CommandOrder.VORGANG_A } export function createCreateCommandProps(): CreateCommandProps { + return { ...createCreateCommandPropsWithoutResource(), resource: createCommandResource() }; +} + +export function createCreateCommandPropsWithoutResource(): CreateCommandPropsWithoutResource { return { - resource: createCommandResource(), linkRel: faker.internet.url(), command: createCreateCommand(), snackBarMessage: faker.word.sample(5), diff --git a/alfa-client/libs/design-component/src/lib/button-with-spinner/button-with-spinner.component.ts b/alfa-client/libs/design-component/src/lib/button-with-spinner/button-with-spinner.component.ts index 2882badd9ed4c127e29bfcc5a6d6414c35ce70bf..1a97d12351e15c734c2108bf255e4f6836b31d08 100644 --- a/alfa-client/libs/design-component/src/lib/button-with-spinner/button-with-spinner.component.ts +++ b/alfa-client/libs/design-component/src/lib/button-with-spinner/button-with-spinner.component.ts @@ -48,6 +48,7 @@ type ButtonVariants = VariantProps<typeof buttonVariants>; [size]="size" [dataTestId]="dataTestId" [isLoading]="isLoading" + [disabled]="disabled" (click)="clickEmitter.emit()" > <ng-content icon select="[icon]" /> @@ -61,6 +62,7 @@ export class ButtonWithSpinnerComponent { @Input() dataTestId: string = ''; @Input() variant: ButtonVariants['variant'] = 'primary'; @Input() size: ButtonVariants['size'] = 'medium'; + @Input() disabled: boolean = false; @Output() public clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); diff --git a/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.spec.ts b/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.spec.ts index 110c81e4d4072ef0417676ea9966a7fa3394f144..8a67d24b410454a80ae2d62f7bbbd6a86a08fd9e 100644 --- a/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.spec.ts +++ b/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.spec.ts @@ -1,4 +1,4 @@ -import { dispatchEventFromFixture, mock, Mock, MockEvent } from '@alfa-client/test-utils'; +import { dispatchEventFromFixture, existsAsHtmlElement, mock, Mock, MockEvent } from '@alfa-client/test-utils'; import { OzgcloudDialogService } from '@alfa-client/ui'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ButtonComponent } from '@ods/system'; @@ -12,7 +12,8 @@ describe('CancelDialogButtonComponent', () => { let dialogService: Mock<OzgcloudDialogService>; - const cancelDialog: string = getDataTestIdOf('cancel-dialog'); + const cancelDialogButton: string = getDataTestIdOf('cancel-dialog-button-container'); + const cancelDialogIconButton: string = getDataTestIdOf('cancel-dialog-icon-button-container'); beforeEach(async () => { dialogService = mock(OzgcloudDialogService); @@ -39,9 +40,51 @@ describe('CancelDialogButtonComponent', () => { describe('on button click', () => { it('should call dialog service to close all', () => { - dispatchEventFromFixture(fixture, cancelDialog, MockEvent.CLICK); + dispatchEventFromFixture(fixture, cancelDialogButton, MockEvent.CLICK); expect(dialogService.closeAll).toHaveBeenCalled(); }); }); + + describe('template', () => { + describe('button', () => { + beforeEach(() => { + component.showAsIconButton = false; + + fixture.detectChanges(); + }); + + it('should be visible when showAsIconButton is false', () => { + existsAsHtmlElement(fixture, cancelDialogButton); + }); + + it('should call dialog service to close all', () => { + dispatchEventFromFixture(fixture, cancelDialogButton, MockEvent.CLICK); + + expect(dialogService.closeAll).toHaveBeenCalled(); + }); + }); + + describe('icon button', () => { + beforeEach(() => { + component.showAsIconButton = true; + + fixture.detectChanges(); + }); + + it('should be visible when showAsIconButton is true', () => { + component.showAsIconButton = true; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, cancelDialogIconButton); + }); + + it('should call dialog service to close all', () => { + dispatchEventFromFixture(fixture, cancelDialogIconButton, MockEvent.CLICK); + + expect(dialogService.closeAll).toHaveBeenCalled(); + }); + }); + }); }); diff --git a/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.ts b/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.ts index 5d80db0f4e7755c1a2bd9ae9eb7b921c3cf58349..df1f5fa4b1732a9b60879f6353ec9f006832cb5f 100644 --- a/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.ts +++ b/alfa-client/libs/design-component/src/lib/cancel-dialog-button/cancel-dialog-button.component.ts @@ -1,22 +1,40 @@ import { OzgcloudDialogService } from '@alfa-client/ui'; -import { Component, inject } from '@angular/core'; -import { ButtonComponent } from '@ods/system'; +import { Component, inject, Input } from '@angular/core'; +import { ButtonComponent, CloseIconComponent, TooltipDirective } from '@ods/system'; @Component({ selector: 'ods-cancel-dialog-button', standalone: true, - imports: [ButtonComponent], - template: `<ods-button - (clickEmitter)="cancel()" - variant="outline" - text="Abbrechen" - dataTestId="cancel-dialog" - data-test-id="cancel-dialog" - />`, + imports: [ButtonComponent, CloseIconComponent, TooltipDirective], + template: ` @if (showAsIconButton) { + <ods-button + (clickEmitter)="cancel()" + [tooltip]="'Schließen'" + tooltipAriaType="aria-labelledby" + variant="ghost" + size="fit" + dataTestId="cancel-dialog-icon-button" + data-test-id="cancel-dialog-icon-button-container" + > + <ng-container icon> + <ods-close-icon class="fill-primary" /> + </ng-container> + </ods-button> + } @else { + <ods-button + (clickEmitter)="cancel()" + variant="outline" + text="Abbrechen" + dataTestId="cancel-dialog-button" + data-test-id="cancel-dialog-button-container" + /> + }`, }) export class CancelDialogButtonComponent { public readonly dialogService = inject(OzgcloudDialogService); + @Input() showAsIconButton: boolean = false; + public cancel(): void { this.dialogService.closeAll(); } diff --git a/alfa-client/libs/design-component/src/lib/download-button/download-button.component.ts b/alfa-client/libs/design-component/src/lib/download-button/download-button.component.ts index 7c479ec1713ce6efca5777e04880575c623ba23d..14473d08c588ba1a2ee9d63a240cb30ca451d48b 100644 --- a/alfa-client/libs/design-component/src/lib/download-button/download-button.component.ts +++ b/alfa-client/libs/design-component/src/lib/download-button/download-button.component.ts @@ -46,7 +46,7 @@ type IconVariants = VariantProps<typeof iconVariants>; </ods-button>`, }) export class DownloadButtonComponent { - @Input() dataTestId: string = ''; + @Input({ required: true }) dataTestId: string; @Input() size: IconVariants['size'] = 'small'; @Input() set stateResource(resource: StateResource<CommandResource>) { this.isLoading = resource.loading || resource.reload; diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts index e5dd90b745edd9549abd452e66b8b566ce118e01..cada7efb7a5dc25e643c2854438cd39f626f70a9 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts @@ -56,7 +56,7 @@ describe('CheckboxEditorComponent', () => { describe('hasError', () => { it('should return true', () => { component.fieldControl.setErrors({ 1: createInvalidParam() }); - + component._updateInvalidParams(); const result: boolean = component.hasError; expect(result).toBe(true); @@ -76,6 +76,7 @@ describe('CheckboxEditorComponent', () => { describe('error message', () => { it('should show', () => { component.fieldControl.setErrors({ 1: createInvalidParam() }); + component._updateInvalidParams(); fixture.detectChanges(); const element: HTMLElement = getElementFromFixture(fixture, errorMessageId); diff --git a/alfa-client/libs/design-component/src/lib/form/file-upload-editor/file-upload-editor.component.html b/alfa-client/libs/design-component/src/lib/form/file-upload-editor/file-upload-editor.component.html index ff08ce18e4ad8cc6037b84833bd941f375a6da0f..e3807c40af21c86b0026c201ed9cb12525aa263b 100644 --- a/alfa-client/libs/design-component/src/lib/form/file-upload-editor/file-upload-editor.component.html +++ b/alfa-client/libs/design-component/src/lib/form/file-upload-editor/file-upload-editor.component.html @@ -35,6 +35,7 @@ [attr.data-test-id]="(label | convertForDataTest) + '-file-upload-button'" [isLoading]="uploadInProgress.loading" class="relative w-full max-w-72" + dataTestId="file-upload-editor" > <ods-spinner-icon spinner size="medium" /> <ods-attachment-icon icon size="medium" /> diff --git a/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts b/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts index 1227c464e93ac1d30efb35880ef6dc872bf280e3..89c0cd5fb117bc5c11c2aa254dfd810ec7616b32 100644 --- a/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts +++ b/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts @@ -33,6 +33,7 @@ export abstract class FormControlEditorAbstractComponent implements ControlValue readonly fieldControl: UntypedFormControl = new UntypedFormControl(); public onChange = (text: string | Date) => undefined; public onTouched = () => undefined; + public invalidParams: InvalidParam[] = []; private changesSubscr: Subscription; private statusSubscr: Subscription; @@ -63,12 +64,15 @@ export abstract class FormControlEditorAbstractComponent implements ControlValue this.fieldControl.setValue(text); this.setErrors(); } + registerOnChange(fn: (text: string | Date) => {}): void { this.onChange = fn; } + registerOnTouched(fn: () => {}): void { this.onTouched = fn; } + setDisabledState?(isDisabled: boolean): void { this.disabled = isDisabled; } @@ -81,12 +85,16 @@ export abstract class FormControlEditorAbstractComponent implements ControlValue setErrors(): void { if (this.control) { this.fieldControl.setErrors(this.control.errors); - if (this.control.invalid) this.fieldControl.markAsTouched(); + if (this.control.invalid) { + this.fieldControl.markAsTouched(); + } + this._updateInvalidParams(); } } - get invalidParams(): InvalidParam[] { - return this.fieldControl.errors ? + _updateInvalidParams(): void { + this.invalidParams = + this.fieldControl.errors ? Object.keys(this.fieldControl.errors).map((key) => <InvalidParam>this.fieldControl.errors[key]) : []; } diff --git a/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.html b/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.html index 837b069ad149e2e7e2eb08305e54e8ab74df16f5..409101e9b6320310d915e0364f8da49bf82a7fda 100644 --- a/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.html +++ b/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.html @@ -29,6 +29,7 @@ [isLoading]="uploadInProgress" [accept]="accept" [attr.data-test-id]="(label | convertForDataTest) + '-single-file-upload-button'" + dataTestId="single-file-upload-button" > <ng-content icon select="[icon]"></ng-content> <ng-content text select="[text]"></ng-content> diff --git a/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts b/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts index a62e384fb3c9ff9c15b453cc9927438d1e1790c4..7de4a0bf3fc04340fa80daed1896235559f6dd18 100644 --- a/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts +++ b/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts @@ -24,7 +24,7 @@ import { ConvertForDataTestPipe, isNotNil } from '@alfa-client/tech-shared'; import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; -import { FileUploadButtonComponent, SpinnerIconComponent } from '@ods/system'; +import { FileUploadButtonComponent } from '@ods/system'; import { uniqueId } from 'lodash-es'; import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstract.component'; @@ -32,7 +32,8 @@ import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstra selector: 'ods-single-file-upload-editor', templateUrl: './single-file-upload-editor.component.html', standalone: true, - imports: [FileUploadButtonComponent, SpinnerIconComponent, ReactiveFormsModule, ConvertForDataTestPipe], + styles: [':host {@apply contents}'], + imports: [FileUploadButtonComponent, ReactiveFormsModule, ConvertForDataTestPipe], }) export class SingleFileUploadEditorComponent extends FormControlEditorAbstractComponent { @Input() label: string = ''; diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts index eda668409767d19830222cb490f11f1608efff9b..d05d44db8ce46777152a6f48145ac2000dd5d0a3 100644 --- a/alfa-client/libs/design-system/src/index.ts +++ b/alfa-client/libs/design-system/src/index.ts @@ -41,6 +41,7 @@ export * from './lib/form/file-upload-button/file-upload-button.component'; export * from './lib/form/radio-button-card/radio-button-card.component'; export * from './lib/form/text-input/text-input.component'; export * from './lib/form/textarea/textarea.component'; +export * from './lib/forwarding-item/forwarding-item.component'; export * from './lib/icons/accessibility-icon/accessibility-icon.component'; export * from './lib/icons/account-circle-icon/account-circle-icon.component'; export * from './lib/icons/admin-logo-icon/admin-logo-icon.component'; diff --git a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html index dc2b6cef68ea7358023c7791fea0eb6efbaf47bf..2e4573ac9c648f820f392f51dc8e96c237f74fb5 100644 --- a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html +++ b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html @@ -32,16 +32,15 @@ (click)="resetInput()" [disabled]="isLoading" [multiple]="multi" - [attr.data-test-id]="(id | convertForDataTest) + '-file-upload-input'" + [attr.data-test-id]="dataTestId" /> -<label - [for]="id" - class="z-10 inline-flex w-full flex-grow items-center justify-start gap-4 break-words rounded-md bg-background-50 py-3 pl-6 pr-6 text-text hover:bg-background-100 focus:outline-none focus:ring-2 focus:ring-primary peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ozgblue-800 peer-disabled:cursor-wait peer-disabled:hover:bg-background-50" - role="button" -> - <ng-content *ngIf="!isLoading" select="[icon]"></ng-content> - <ng-content *ngIf="isLoading" select="[spinner]"></ng-content> - <div class="flex-grow"> +<label [for]="id" [ngClass]="uploadButtonVariants({ variant })" role="button"> + @if (isLoading) { + <ng-content select="[spinner]"></ng-content> + } @else { + <ng-content select="[icon]"></ng-content> + } + <div class="flex-grow empty:hidden"> <ng-content select="[text]"></ng-content> </div> </label> diff --git a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.spec.ts b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.spec.ts index 54b7d3b7dde522ce018e0efae8b4210f6e2e2cff..bc63bfe1e214deec130fcd1f487045d14a68ad79 100644 --- a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.spec.ts @@ -21,7 +21,6 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; import { getElementFromFixture } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; @@ -34,16 +33,18 @@ describe('FileUploadButtonComponent', () => { let fixture: ComponentFixture<FileUploadButtonComponent>; const labelText: string = faker.word.noun(); - const inputTestClass: string = getDataTestIdOf(labelText + '-file-upload-input'); + const dataTestId: string = 'dummyDataTestId'; + const input: string = getDataTestIdOf(dataTestId); beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [FileUploadButtonComponent, ConvertForDataTestPipe], + imports: [FileUploadButtonComponent], }).compileComponents(); fixture = TestBed.createComponent(FileUploadButtonComponent); component = fixture.componentInstance; component.id = labelText; + component.dataTestId = dataTestId; fixture.detectChanges(); }); @@ -54,7 +55,7 @@ describe('FileUploadButtonComponent', () => { describe('click at file input', () => { it('should call resetInput()', () => { component.resetInput = jest.fn(); - const fileInput = getElementFromFixture(fixture, inputTestClass); + const fileInput = getElementFromFixture(fixture, input); fileInput.click(); fixture.detectChanges(); @@ -68,7 +69,7 @@ describe('FileUploadButtonComponent', () => { component.multi = true; fixture.detectChanges(); - const inputElement: HTMLInputElement = getElementFromFixture(fixture, inputTestClass); + const inputElement: HTMLInputElement = getElementFromFixture(fixture, input); expect(inputElement.multiple).toEqual(component.multi); }); diff --git a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts index 2371918f9cdba62e0ea0ee3a5e315ee9f1d9e378..9f06d3864e0c7767b368509d49449e68d18ac0a0 100644 --- a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts +++ b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts @@ -24,12 +24,33 @@ import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { cva, VariantProps } from 'class-variance-authority'; + +export const uploadButtonVariants = cva( + [ + 'z-10 inline-flex flex-grow items-center justify-start gap-4 break-words rounded-md text-primary', + 'border border-transparent hover:bg-ghost-hover peer-focus-visible:border-background-200', + 'peer-focus-visible:outline peer-focus-visible:outline-focus peer-focus-visible:bg-ghost-hover peer-focus-visible:outline-offset-1', + ], + { + variants: { + variant: { + label: 'py-3 px-6 bg-background-50 w-full', + icon: 'p-2 w-fit', + }, + }, + defaultVariants: { + variant: 'label', + }, + }, +); +export type UploadButtonVariants = VariantProps<typeof uploadButtonVariants>; @Component({ selector: 'ods-file-upload-button', standalone: true, imports: [CommonModule, ConvertForDataTestPipe], - styles: [':host {@apply inline-flex}'], + styles: [':host {@apply relative}'], templateUrl: './file-upload-button.component.html', }) export class FileUploadButtonComponent { @@ -37,9 +58,13 @@ export class FileUploadButtonComponent { @Input() isLoading: boolean = false; @Input() accept: string = '*/*'; @Input() multi: boolean = false; + @Input() variant: UploadButtonVariants['variant']; + @Input({ required: true }) dataTestId: string; @ViewChild('inputElement') inputElement: ElementRef = new ElementRef({}); + readonly uploadButtonVariants = uploadButtonVariants; + resetInput(): void { this.inputElement.nativeElement.value = ''; } diff --git a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.spec.ts b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.spec.ts index 974db9b7c5c5dc93f83768157da9d570cfb0a2d3..32ba66bd623c7a1c2609cba72f5e0f877f59207c 100644 --- a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.spec.ts @@ -88,12 +88,16 @@ describe('TextInputComponent', () => { it('should focus', () => { component.focus = true; + component.ngAfterViewInit(); + expect(component.inputElement.nativeElement.focus).toHaveBeenCalled(); }); it('should not focus', () => { component.focus = false; + component.ngAfterViewInit(); + expect(component.inputElement.nativeElement.focus).not.toHaveBeenCalled(); }); }); diff --git a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts index 1b8bf5fdf47948bbc9374b01086238c3e41c0ac3..cd01ba0190c68b4f9fec34f3e94496e6d86f73aa 100644 --- a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts +++ b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts @@ -21,9 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { convertForDataTest, ConvertForDataTestPipe, EMPTY_STRING, isNotUndefined } from '@alfa-client/tech-shared'; +import { convertForDataTest, EMPTY_STRING, isNotUndefined } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; -import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { cva, VariantProps } from 'class-variance-authority'; import { uniqueId } from 'lodash-es'; @@ -51,7 +51,7 @@ type TextInputVariants = VariantProps<typeof textInputVariants>; @Component({ selector: 'ods-text-input', standalone: true, - imports: [CommonModule, ReactiveFormsModule, ConvertForDataTestPipe], + imports: [CommonModule, ReactiveFormsModule], template: ` <div class="relative"> <label *ngIf="showLabel" [for]="id" class="text-md mb-2 block font-medium text-text"> @@ -82,7 +82,7 @@ type TextInputVariants = VariantProps<typeof textInputVariants>; </div> `, }) -export class TextInputComponent { +export class TextInputComponent implements AfterViewInit { @ViewChild('inputElement') inputElement: ElementRef; @Input({ required: true }) set label(label: string) { @@ -98,20 +98,19 @@ export class TextInputComponent { @Input() withPrefix: boolean = false; @Input() withSuffix: boolean = false; @Input() showLabel: boolean = true; + @Input() focus: boolean = false; @Input() set dataTestId(value: string) { if (isNotUndefined(value)) this._dataTestId = value; } - @Input() set focus(value: boolean) { - if (value && this.inputElement) { - this.inputElement.nativeElement.focus(); - } - } - @Output() clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); inputLabel: string; id: string; _dataTestId: string; textInputVariants = textInputVariants; + + ngAfterViewInit() { + if (this.focus) this.inputElement.nativeElement.focus(); + } } diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.spec.ts b/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.component.spec.ts similarity index 70% rename from alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.spec.ts rename to alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.component.spec.ts index 1f353186741ab865b0ce29209c74de7869b24794..5700f028372d57391a28997d4f8e7429d9f73a5c 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.component.spec.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den + * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den * Ministerpräsidenten des Landes Schleswig-Holstein * Staatskanzlei * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung @@ -22,18 +22,18 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { VorgangDetailBescheidenStepTitleComponent } from './vorgang-detail-bescheiden-step-title.component'; +import { ForwardingItemComponent } from './forwarding-item.component'; -describe('VorgangDetailBescheidenStepTitleComponent', () => { - let component: VorgangDetailBescheidenStepTitleComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenStepTitleComponent>; +describe('ForwardingItemComponent', () => { + let component: ForwardingItemComponent; + let fixture: ComponentFixture<ForwardingItemComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [VorgangDetailBescheidenStepTitleComponent], + imports: [ForwardingItemComponent], }).compileComponents(); - fixture = TestBed.createComponent(VorgangDetailBescheidenStepTitleComponent); + fixture = TestBed.createComponent(ForwardingItemComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.component.ts b/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..7f8ebfd800c662910c5ec0905935c3d12487b7f3 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.component.ts @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2025 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 { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { ForwardVorgangIconComponent } from '../icons/forward-vorgang-icon/forward-vorgang-icon.component'; + +export enum ForwardingDirection { + FROM = 'Weitergeleitet von', + TO = 'An', +} + +@Component({ + selector: 'ods-forwarding-item', + standalone: true, + imports: [CommonModule, ForwardVorgangIconComponent], + template: `<div + class="flex flex-col items-start justify-between gap-2 rounded-lg border border-grayborder p-3 md:flex-row md:items-center md:gap-0" + > + <div class="flex gap-3"> + <ods-forward-vorgang-icon class="fill-text" /> + <p class="text-gray-500">{{ direction }}:</p> + <div> + <p class="font-medium">{{ label }}</p> + <p>{{ address }}</p> + </div> + </div> + <div class="text-end empty:hidden"> + <ng-content /> + </div> + </div>`, +}) +export class ForwardingItemComponent { + @Input({ required: true }) label!: string; + @Input({ required: true }) address!: string; + @Input() direction: ForwardingDirection = ForwardingDirection.TO; +} diff --git a/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.stories.ts b/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..53d2116e9f314c9e2194cd8a9ff7c72e39dd1b12 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/forwarding-item/forwarding-item.stories.ts @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2025 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 { argsToTemplate, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular'; + +import { ButtonComponent } from '../button/button.component'; +import { ForwardingDirection, ForwardingItemComponent } from './forwarding-item.component'; + +const label: string = 'Bund für Umwelt und Naturschutz Kreisgruppe Kiel'; +const address: string = 'Kaiserstraße 25, 12443 Kiel'; + +const meta: Meta<ForwardingItemComponent> = { + title: 'Forwarding item', + component: ForwardingItemComponent, + parameters: { + docs: { + description: { + component: 'Information of forwarded item', + }, + }, + }, + decorators: [ + moduleMetadata({ + imports: [ForwardingItemComponent, ButtonComponent], + }), + ], + excludeStories: /.*Data$/, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj<ForwardingItemComponent>; + +export const Default: Story = { + args: { + label: label, + address: address, + direction: ForwardingDirection.TO, + }, + argTypes: { + direction: { control: 'select', options: [ForwardingDirection.TO, ForwardingDirection.FROM] }, + }, +}; + +export const WithButton: Story = { + args: { + label: label, + address: address, + }, + + render: (args: ForwardingItemComponent) => ({ + props: args, + template: `<ods-forwarding-item ${argsToTemplate(args)}> + <ods-button variant="outline" text="Stelle ändern" /> + </ods-forwarding-item>`, + }), +}; + +export const WithCreationInfo: Story = { + args: { + label: label, + address: address, + direction: ForwardingDirection.FROM, + }, + render: (args: ForwardingItemComponent) => ({ + props: args, + template: `<ods-forwarding-item ${argsToTemplate(args)}> + <p>20. Dez. 09:35</p> + <p class="text-sm">Karin Wanowski-Müller</p> + </ods-forwarding-item>`, + }), +}; 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 05bd9d0120ab93428f1786c24a77a4b7f6eadf33..48a8a502165e5795ba32bd93485def62486d4de9 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 @@ -62,6 +62,7 @@ import { InstantSearchQuery, InstantSearchResult } from './instant-search.model' [placeholder]="placeholder" [attr.aria-expanded]="results.length" [control]="control" + [focusOnInput]="focusOnSearchField" aria-controls="results" (inputClicked)="showResults()" (searchQueryCleared)="searchQueryCleared.emit()" @@ -90,6 +91,7 @@ export class InstantSearchComponent implements OnInit, OnDestroy { @Input() placeholder: string = EMPTY_STRING; @Input() headerText: string = EMPTY_STRING; @Input() control: FormControl<string> = new FormControl(EMPTY_STRING); + @Input() focusOnSearchField: boolean = false; @Input() set searchResults(searchResults: InstantSearchResult<Resource>[]) { if (!isEqual(searchResults, this.results) && isNotNil(searchResults)) { diff --git a/alfa-client/libs/design-system/src/lib/instant-search/search-field/search-field.component.ts b/alfa-client/libs/design-system/src/lib/instant-search/search-field/search-field.component.ts index 7d8141a461626c6dee05d91262423f2d1a011470..2f45e945d817ca874dc2bec1b927aac498240999 100644 --- a/alfa-client/libs/design-system/src/lib/instant-search/search-field/search-field.component.ts +++ b/alfa-client/libs/design-system/src/lib/instant-search/search-field/search-field.component.ts @@ -37,6 +37,7 @@ import { SearchIconComponent } from '../../icons/search-icon/search-icon.compone label="instant search" [fieldControl]="control" [placeholder]="placeholder" + [focus]="focusOnInput" [withPrefix]="true" [withSuffix]="true" [showLabel]="false" @@ -44,13 +45,7 @@ import { SearchIconComponent } from '../../icons/search-icon/search-icon.compone role="combobox" > <ods-search-icon prefix aria-hidden="true" aria-label="Suchfeld" /> - <button - suffix - *ngIf="control.value" - (click)="clearInput()" - aria-label="Eingabe löschen" - data-test-id="clear-instant-search" - > + <button suffix *ngIf="control.value" (click)="clearInput()" aria-label="Eingabe löschen" data-test-id="clear-instant-search"> <ods-close-icon class="fill-primary hover:fill-primary-hover" /> </button> </ods-text-input>`, @@ -58,6 +53,7 @@ import { SearchIconComponent } from '../../icons/search-icon/search-icon.compone export class SearchFieldComponent { @Input() placeholder: string = EMPTY_STRING; @Input() control: FormControl<string> = new FormControl(EMPTY_STRING); + @Input() focusOnInput: boolean = false; @Output() inputClicked: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); @Output() searchQueryCleared: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); diff --git a/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts index 7bfdff811e56e7986b589f06cad84a596b4ddf59..fff8eddf2051dbd1cbf53c80e1f5c733cae7e42a 100644 --- a/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts @@ -24,7 +24,7 @@ import { getElementFromFixture } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { provideRouter } from '@angular/router'; -import { faker } from '@faker-js/faker'; +import { faker } from '@faker-js/faker/.'; import { getDataTestClassOf } from 'libs/tech-shared/test/data-test'; import { ListItemComponent } from './list-item.component'; @@ -32,6 +32,8 @@ describe('ListItemComponent', () => { let component: ListItemComponent; let fixture: ComponentFixture<ListItemComponent>; + const link: string = getDataTestClassOf('list-item-link'); + beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ListItemComponent], @@ -50,13 +52,12 @@ describe('ListItemComponent', () => { describe('input', () => { describe('routerLink', () => { it('should set href attribute', () => { - component.path = encodeURI(faker.system.filePath()); - const resultingLink: string = 'http://localhost' + component.path; - const linkElement: HTMLLinkElement = getElementFromFixture(fixture, getDataTestClassOf('list-item-link')); + component.path = encodeURIComponent(faker.system.filePath()); fixture.detectChanges(); - expect(linkElement.href).toBe(resultingLink); + const linkElement: HTMLLinkElement = getElementFromFixture(fixture, link); + expect(decodeURIComponent(linkElement.href)).toBe(`http://localhost/${component.path}`); }); }); }); diff --git a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts index 671af957965555f680862dad37081cc00c537c9d..f62b0e92488cc33d05bbc61112556850a74766e9 100644 --- a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts +++ b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts @@ -29,6 +29,7 @@ import { TooltipPosition } from './tooltip.directive'; selector: 'ods-tooltip', imports: [NgClass], template: `<span + [attr.data-test-id]="dataTestId" class="tooltip fixed z-[100] animate-fadeIn cursor-default break-words rounded bg-ozggray-900 px-3 py-2 text-sm font-normal text-whitetext before:absolute before:border-l-[0.5rem] before:border-r-[0.5rem] before:border-l-transparent before:border-r-transparent dark:bg-white" [ngClass]="class" [class.visible]="show" @@ -58,6 +59,8 @@ export class TooltipComponent { class: string; leftOffset: number; + dataTestId: string; + set position(value: TooltipPosition) { if (value === TooltipPosition.ABOVE) { this.class = diff --git a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts index 76c569e4245841930a5387dc5c8a2e34e6328c1b..3b775dd56d43e4247a3de4cf06fe0a3e4d64bc76 100644 --- a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts +++ b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { assignValue, mock, useFromMock } from '@alfa-client/test-utils'; import { InteractivityChecker } from '@angular/cdk/a11y'; import { ComponentRef, ElementRef, Renderer2, ViewContainerRef } from '@angular/core'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; @@ -37,6 +38,18 @@ class MockElementRef extends ElementRef { describe('TooltipDirective', () => { let directive: TooltipDirective; + const mockComponentRefInstance: TooltipComponent = { + id: '', + left: 0, + top: 0, + text: '', + show: false, + position: TooltipPosition.BELOW, + class: '', + leftOffset: 0, + width: null, + dataTestId: undefined, + }; const mockComponentRef: ComponentRef<TooltipComponent> = { setInput: jest.fn(), destroy: jest.fn(), @@ -46,17 +59,7 @@ describe('TooltipDirective', () => { location: null, hostView: null, injector: null, - instance: { - id: '', - left: 0, - top: 0, - text: '', - show: false, - position: TooltipPosition.BELOW, - class: '', - leftOffset: 0, - width: null, - }, + instance: mockComponentRefInstance, }; const parentRect: DOMRect = { bottom: 0, top: 0, height: 0, left: 0, right: 0, toJSON: jest.fn(), width: 0, x: 0, y: 0 }; @@ -119,6 +122,7 @@ describe('TooltipDirective', () => { directive.setInitialTooltipProperties = jest.fn(); directive.getParentElement = jest.fn().mockReturnValue({ appendChild: jest.fn() }); directive.interactivityChecker.isFocusable = jest.fn(); + directive._addDataTestId = jest.fn(); }); it('should create tooltip component', () => { @@ -156,6 +160,43 @@ describe('TooltipDirective', () => { expect(directive.getParentElement).not.toHaveBeenCalled(); }); + + it('should call add data test id', () => { + directive.createTooltip(tooltipText); + + expect(directive._addDataTestId).toHaveBeenCalled(); + }); + }); + + describe('add data test id', () => { + const dataTestId: string = 'dummyDataTestId'; + + beforeEach(() => { + directive.componentRef = assignValue(mockComponentRef, 'instance', { ...mockComponentRef.instance, dataTestId: undefined }); + }); + + it('should set attribute to tooltip component if exists', () => { + directive.parentElement = mockParentAttribute(dataTestId); + + directive._addDataTestId(); + + expect(directive.componentRef.instance.dataTestId).toBe(dataTestId + directive.dataTestIdTooltipSuffix); + }); + + it('should NOT set attribute to tooltip component if undefined', () => { + directive.parentElement = mockParentAttribute(undefined); + + directive._addDataTestId(); + + expect(directive.componentRef.instance.dataTestId).toBeUndefined(); + }); + + function mockParentAttribute(value: any): HTMLElement { + return useFromMock<HTMLElement>({ + ...mock(HTMLElement), + getAttribute: jest.fn().mockReturnValue(value), + }); + } }); describe('showTooltip', () => { diff --git a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts index d8f42d4ab8dd4e8bdab6e49031a00fbbbddbb480..10cca117f0ab929c71c43dc0a33482a57a5c19de 100644 --- a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts +++ b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { isEscapeKey, isNotNull } from '@alfa-client/tech-shared'; +import { isEscapeKey, isNotNull, isNotUndefined } from '@alfa-client/tech-shared'; import { InteractivityChecker } from '@angular/cdk/a11y'; import { ComponentRef, @@ -80,6 +80,10 @@ export class TooltipDirective implements OnDestroy { public readonly renderer: Renderer2 = inject(Renderer2); public readonly interactivityChecker: InteractivityChecker = inject(InteractivityChecker); + dataTestIdParentAttribute: string = 'data-test-id'; + dataTestIdAttribute: string = 'dataTestId'; + dataTestIdTooltipSuffix: string = '-tooltip'; + ngOnDestroy(): void { this.destroy(); } @@ -120,12 +124,18 @@ export class TooltipDirective implements OnDestroy { const nativeElement: HTMLElement = this.elementRef.nativeElement; this.componentRef = this.viewContainerRef.createComponent(TooltipComponent); this.parentElement = this.getParentElement(nativeElement); + this._addDataTestId(); this.parentElement.appendChild(this.componentRef.location.nativeElement); this.tooltipId = uniqueId('tooltip'); this.setInitialTooltipProperties(tooltipText, this.tooltipId); this.setAriaAttribute(this.tooltipAriaType); } + _addDataTestId(): void { + const dataTestId: string = this.parentElement.getAttribute(this.dataTestIdParentAttribute); + if (isNotUndefined(dataTestId)) this.componentRef.instance.dataTestId = dataTestId + this.dataTestIdTooltipSuffix; + } + setInitialTooltipProperties(text: string, id: string) { this.componentRef.instance.text = text; this.componentRef.instance.id = id; diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts index 34a7bd065f0c85b3ddc80a39d2fbe195e9c33655..8c472b9da3215b624913bf869c367887ab97c27f 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.spec.ts @@ -21,8 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { LinkRelationName } from '@alfa-client/tech-shared'; import { mock, useFromMock } from '@alfa-client/test-utils'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { faker } from '@faker-js/faker/.'; import { ResourceFactory } from '@ngxp/rest'; import { cold, hot } from 'jest-marbles'; import { createForwardingListResource } from 'libs/forwarding-shared/test/forwarding'; @@ -45,25 +47,26 @@ describe('ForwardingRepository', () => { describe('getForwardings', () => { const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.FORWARD_BY_EMAIL]); const commandList: ForwardingListResource = createForwardingListResource(); + const linkRel: LinkRelationName = faker.string.alpha(5); beforeEach(() => { resourceWrapper.get.mockReturnValue(hot('a', { a: commandList })); }); it('should call resourceFactory', () => { - repository.getForwardings(vorgang); + repository.getForwardings(vorgang, linkRel); expect(resourceFactory.from).toHaveBeenCalledWith(vorgang); }); it('should call resourceWrapper', () => { - repository.getForwardings(vorgang); + repository.getForwardings(vorgang, linkRel); - expect(resourceWrapper.get).toHaveBeenCalledWith(VorgangWithEingangLinkRel.FORWARD_BY_EMAIL); + expect(resourceWrapper.get).toHaveBeenCalledWith(linkRel); }); it('should return result', () => { - let result = repository.getForwardings(vorgang); + let result = repository.getForwardings(vorgang, linkRel); expect(result).not.toBeNull(); expect(result).toBeObservable(cold('a', { a: commandList })); diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts index a83ca3536dabe921ff4dc10719dbbdd1f5c74943..acd33b4bc2523a2761e420640d1d422cbdbca088 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.repository.ts @@ -21,7 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { LinkRelationName } from '@alfa-client/tech-shared'; +import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Injectable } from '@angular/core'; import { ResourceFactory } from '@ngxp/rest'; import { Observable } from 'rxjs'; @@ -31,7 +32,7 @@ import { ForwardingListResource } from './forwarding.model'; export class ForwardingRepository { constructor(private resourceFactory: ResourceFactory) {} - public getForwardings(vorgang: VorgangWithEingangResource): Observable<ForwardingListResource> { - return this.resourceFactory.from(vorgang).get(VorgangWithEingangLinkRel.FORWARD_BY_EMAIL); + public getForwardings(vorgang: VorgangWithEingangResource, linkRel: LinkRelationName): Observable<ForwardingListResource> { + return this.resourceFactory.from(vorgang).get(linkRel); } } diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts index afb141693929a6b51c1d096d58510076816fdc0a..f3f631dfbcb316d354a18b2c2fab9299d347cd91 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.spec.ts @@ -21,9 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { CommandOrder, CommandResource, CommandService } from '@alfa-client/command-shared'; +import { CommandOrder, CommandResource, CommandService, CreateCommandPropsWithoutResource } from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { + EMPTY_STRING, StateResource, createEmptyStateResource, createErrorStateResource, @@ -38,16 +39,19 @@ import { VorgangWithEingangLinkRel, VorgangWithEingangResource, } from '@alfa-client/vorgang-shared'; -import { cold, hot } from 'jest-marbles'; +import { faker } from '@faker-js/faker/.'; +import { ResourceUri } from '@ngxp/rest'; +import { hot } from 'jest-marbles'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { createCommandResource } from 'libs/command-shared/test/command'; +import { createCommandResource, createCreateCommandPropsWithoutResource } from 'libs/command-shared/test/command'; import { createVorgangForwardRequest, createVorgangResource, createVorgangWithEingangResource, } from 'libs/vorgang-shared/test/vorgang'; -import { of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { createApiError } from '../../../tech-shared/test/error'; +import { multipleCold, singleColdCompleted } from '../../../tech-shared/test/marbles'; import { createForwardingListResource, createForwardingResource } from '../../test/forwarding'; import { ForwardingLinkRel } from './forwarding.linkrel'; import { ForwardingListResource, ForwardingResource } from './forwarding.model'; @@ -82,10 +86,9 @@ describe('ForwardingService', () => { expect(service).toBeTruthy(); }); - describe('forward', () => { + describe('forward by email', () => { const vorgang: VorgangResource = createVorgangResource(); - const commandStateResource: StateResource<CommandResource> = - createStateResource(createCommandResource()); + const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); beforeEach(() => { commandService.createCommand.mockReturnValue(of(commandStateResource)); @@ -99,31 +102,27 @@ describe('ForwardingService', () => { body: null, }; - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); - expect(commandService.createCommand).toHaveBeenCalledWith( - vorgang, - VorgangWithEingangLinkRel.FORWARD, - command, - ); + expect(commandService.createCommand).toHaveBeenCalledWith(vorgang, VorgangWithEingangLinkRel.FORWARD, command); }); it('should call reloadCurrentVorgang', () => { service.reloadCurrentVorgang = jest.fn(); - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); expect(service.reloadCurrentVorgang).toHaveBeenCalled(); }); it('should call setPendingForwardSingleCommandLoading', () => { - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); expect(vorgangService.setPendingForwardSingleCommandLoading).toHaveBeenCalled(); }); it('should call setPendingForwardSingleCommand', () => { - service.forward(vorgang, forwardRequest); + service.forwardByEmail(vorgang, forwardRequest); expect(vorgangService.setPendingForwardSingleCommand).toHaveBeenCalled(); }); @@ -169,16 +168,12 @@ describe('ForwardingService', () => { }); it('should call vorgangservice on command is done', () => { - const commandServiceReturnValue = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); + const commandServiceReturnValue = createStateResource(createCommandResource([CommandLinkRel.EFFECTED_RESOURCE])); commandService.pollCommand.mockReturnValue(of(commandServiceReturnValue)); service.pollPendingForwardCommand(createStateResource(commandResourceWithUpdateLink)); - expect(vorgangService.setPendingForwardSingleCommand).toHaveBeenCalledWith( - commandServiceReturnValue, - ); + expect(vorgangService.setPendingForwardSingleCommand).toHaveBeenCalledWith(commandServiceReturnValue); }); it('should call not vorgangservice on pending command', () => { @@ -237,7 +232,7 @@ describe('ForwardingService', () => { }); }); - describe('getForwardings', () => { + describe('get forwardings by email', () => { const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource(); const listResource: ForwardingListResource = createForwardingListResource(); @@ -246,17 +241,15 @@ describe('ForwardingService', () => { }); it('should return value', () => { - const result = service.getForwardings(vorgang); + const result: Observable<StateResource<ForwardingListResource>> = service.getForwardingsByEmail(vorgang); - expect(result).toBeObservable( - cold('ab', { a: createEmptyStateResource(true), b: createStateResource(listResource) }), - ); + expect(result).toBeObservable(multipleCold(createEmptyStateResource(true), createStateResource(listResource))); }); it('should call repository', () => { - service.getForwardings(vorgang); + service.getForwardingsByEmail(vorgang); - expect(forwardingRepository.getForwardings).toHaveBeenCalledWith(vorgang); + expect(forwardingRepository.getForwardings).toHaveBeenCalledWith(vorgang, VorgangWithEingangLinkRel.FORWARD_BY_EMAIL); }); }); @@ -273,10 +266,7 @@ describe('ForwardingService', () => { order: CommandOrder.FORWARD_SUCCESSFULL, body: null, }); - - expect(result).toBeObservable( - cold('ab', { a: createEmptyStateResource(true), b: stateResource }), - ); + expect(result).toBeObservable(multipleCold(createEmptyStateResource(true), stateResource)); }); }); @@ -284,11 +274,10 @@ describe('ForwardingService', () => { it('should call command service', () => { service.markAsSuccess(forwading); - expect(commandService.createCommand).toHaveBeenCalledWith( - forwading, - ForwardingLinkRel.MARK_AS_SUCCESS, - { order: CommandOrder.FORWARD_SUCCESSFULL, body: null }, - ); + expect(commandService.createCommand).toHaveBeenCalledWith(forwading, ForwardingLinkRel.MARK_AS_SUCCESS, { + order: CommandOrder.FORWARD_SUCCESSFULL, + body: null, + }); }); it('should update list on valid response', () => { @@ -306,11 +295,10 @@ describe('ForwardingService', () => { it('should call command service', () => { service.markAsFail(forwading); - expect(commandService.createCommand).toHaveBeenCalledWith( - forwading, - ForwardingLinkRel.MARK_AS_FAIL, - { order: CommandOrder.FORWARD_FAILED, body: null }, - ); + expect(commandService.createCommand).toHaveBeenCalledWith(forwading, ForwardingLinkRel.MARK_AS_FAIL, { + order: CommandOrder.FORWARD_FAILED, + body: null, + }); }); it('should update vorgang on valid response', () => { @@ -368,4 +356,60 @@ describe('ForwardingService', () => { expect(service.setList).toHaveBeenCalledWith(list); }); }); + + describe('forward', () => { + const forwardingToUri: ResourceUri = faker.internet.url(); + + const createCommandProps: CreateCommandPropsWithoutResource = createCreateCommandPropsWithoutResource(); + const commandResource: CommandResource = createCommandResource(); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); + + beforeEach(() => { + vorgangService.createCommand.mockReturnValue(of(commandStateResource)); + service._buildForwardCreateCommandProps = jest.fn().mockReturnValue(createCommandProps); + }); + + it('should call build forward create command', () => { + service.forward(forwardingToUri).subscribe(); + + expect(service._buildForwardCreateCommandProps).toHaveBeenCalledWith(forwardingToUri); + }); + + it('should call vorgang service to create command', () => { + service.forward(forwardingToUri).subscribe(); + + expect(vorgangService.createCommand).toHaveBeenCalledWith(createCommandProps, true); + }); + + it('should return response from command service', () => { + const forwardCommand$: Observable<StateResource<CommandResource>> = service.forward(forwardingToUri); + + expect(forwardCommand$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + }); + + describe('build forward command props', () => { + const forwardingToUri: ResourceUri = faker.internet.url(); + + it('should contains linkrel', () => { + const commandProps: CreateCommandPropsWithoutResource = service._buildForwardCreateCommandProps(forwardingToUri); + + expect(commandProps.linkRel).toBe(VorgangWithEingangLinkRel.FORWARD_BY_OZGCLOUD); + }); + + it('should contains command', () => { + const commandProps: CreateCommandPropsWithoutResource = service._buildForwardCreateCommandProps(forwardingToUri); + + expect(commandProps.command).toEqual({ + order: CommandOrder.FORWARD_VORGANG, + body: { organisationEinheitId: forwardingToUri }, + }); + }); + + it('should contains empty snackbar message', () => { + const commandProps: CreateCommandPropsWithoutResource = service._buildForwardCreateCommandProps(forwardingToUri); + + expect(commandProps.snackBarMessage).toBe(EMPTY_STRING); + }); + }); }); diff --git a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts index 73510b902a2a9408905b9af3124bba1ab81efe47..b84c9d5c0ee51ea7e6464997fd24106a8c91fbf4 100644 --- a/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts +++ b/alfa-client/libs/forwarding-shared/src/lib/forwarding.service.ts @@ -21,17 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Injectable, OnDestroy } from '@angular/core'; -import { Params } from '@angular/router'; import { + CommandOrder, CommandResource, CommandService, CreateCommand, + CreateCommandPropsWithoutResource, isDone, isPending, } from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { + EMPTY_STRING, StateResource, createEmptyStateResource, createStateResource, @@ -45,21 +46,22 @@ import { VorgangWithEingangResource, createForwardCommand, } from '@alfa-client/vorgang-shared'; +import { Injectable, OnDestroy } from '@angular/core'; +import { Params } from '@angular/router'; +import { ResourceUri } from '@ngxp/rest'; import { isNil } from 'lodash-es'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { first, map, startWith, tap } from 'rxjs/operators'; import { ForwardingLinkRel } from './forwarding.linkrel'; import { ForwardingListResource, ForwardingResource } from './forwarding.model'; import { ForwardingRepository } from './forwarding.repository'; -import { - createForwardingMarkAsFailCommand, - createForwardingMarkAsSuccessCommand, -} from './forwarding.util'; +import { createForwardingMarkAsFailCommand, createForwardingMarkAsSuccessCommand } from './forwarding.util'; @Injectable({ providedIn: 'root' }) export class ForwardingService implements OnDestroy { - private readonly forwardingList$: BehaviorSubject<StateResource<ForwardingListResource>> = - new BehaviorSubject(createEmptyStateResource<ForwardingListResource>()); + private readonly forwardingList$: BehaviorSubject<StateResource<ForwardingListResource>> = new BehaviorSubject( + createEmptyStateResource<ForwardingListResource>(), + ); private navigationSubscription: Subscription; private subscription: Subscription; @@ -71,15 +73,15 @@ export class ForwardingService implements OnDestroy { private forwardingRepository: ForwardingRepository, ) {} - getForwardings( - vorgang: VorgangWithEingangResource, - ): Observable<StateResource<ForwardingListResource>> { + getForwardingsByEmail(vorgang: VorgangWithEingangResource): Observable<StateResource<ForwardingListResource>> { this.forwardingList$.next(createEmptyStateResource(true)); - const subscription = this.forwardingRepository.getForwardings(vorgang).subscribe((list) => { - this.forwardingList$.next(createStateResource(list)); - subscription.unsubscribe(); - }); + const subscription = this.forwardingRepository + .getForwardings(vorgang, VorgangWithEingangLinkRel.FORWARD_BY_EMAIL) + .subscribe((listResource: ForwardingListResource) => { + this.forwardingList$.next(createStateResource(listResource)); + subscription.unsubscribe(); + }); return this.forwardingList$.asObservable(); } @@ -94,9 +96,7 @@ export class ForwardingService implements OnDestroy { listenToNavigation(): void { this.unsubscribe(); - this.navigationSubscription = this.navigationService - .urlChanged() - .subscribe((params) => this.onNavigation(params)); + this.navigationSubscription = this.navigationService.urlChanged().subscribe((params) => this.onNavigation(params)); } onNavigation(params: Params): void { @@ -105,19 +105,15 @@ export class ForwardingService implements OnDestroy { } } - pollPendingForwardCommand( - command: StateResource<CommandResource>, - ): StateResource<CommandResource> { + pollPendingForwardCommand(command: StateResource<CommandResource>): StateResource<CommandResource> { if (this.shouldPoll(command)) { - this.subscription = this.commandService - .pollCommand(command.resource) - .subscribe((updatedCommand) => { - if (isDone(updatedCommand.resource)) { - this.vorgangService.setPendingForwardSingleCommand(updatedCommand); - this.reloadCurrentVorgang(updatedCommand); - this.subscription.unsubscribe(); - } - }); + this.subscription = this.commandService.pollCommand(command.resource).subscribe((updatedCommand) => { + if (isDone(updatedCommand.resource)) { + this.vorgangService.setPendingForwardSingleCommand(updatedCommand); + this.reloadCurrentVorgang(updatedCommand); + this.subscription.unsubscribe(); + } + }); } return command; } @@ -126,10 +122,7 @@ export class ForwardingService implements OnDestroy { return command.loaded && isPending(command.resource); } - public forward( - vorgang: VorgangResource, - request: ForwardRequest, - ): Observable<StateResource<CommandResource>> { + public forwardByEmail(vorgang: VorgangResource, request: ForwardRequest): Observable<StateResource<CommandResource>> { this.vorgangService.setPendingForwardSingleCommandLoading(); const subscription: Subscription = this.commandService .createCommand(vorgang, VorgangWithEingangLinkRel.FORWARD, createForwardCommand(request)) @@ -142,19 +135,13 @@ export class ForwardingService implements OnDestroy { } markAsSuccess(forward: ForwardingResource): Observable<StateResource<CommandResource>> { - return this.createMarkAsCommand( - forward, - ForwardingLinkRel.MARK_AS_SUCCESS, - createForwardingMarkAsSuccessCommand(), - ).pipe(tap((command) => this.updateForwardingList(command))); + return this.createMarkAsCommand(forward, ForwardingLinkRel.MARK_AS_SUCCESS, createForwardingMarkAsSuccessCommand()).pipe( + tap((command) => this.updateForwardingList(command)), + ); } markAsFail(forward: ForwardingResource): Observable<StateResource<CommandResource>> { - return this.createMarkAsCommand( - forward, - ForwardingLinkRel.MARK_AS_FAIL, - createForwardingMarkAsFailCommand(), - ).pipe( + return this.createMarkAsCommand(forward, ForwardingLinkRel.MARK_AS_FAIL, createForwardingMarkAsFailCommand()).pipe( tap((command) => { if (isDone(command.resource)) this.reloadCurrentVorgang(command); }), @@ -192,6 +179,22 @@ export class ForwardingService implements OnDestroy { this.forwardingList$.next(createStateResource(list)); } + public forward(forwardingToUri: ResourceUri): Observable<StateResource<CommandResource>> { + return this.vorgangService.createCommand(this._buildForwardCreateCommandProps(forwardingToUri), true); + } + + _buildForwardCreateCommandProps(forwardingToUri: ResourceUri): CreateCommandPropsWithoutResource { + return { + linkRel: VorgangWithEingangLinkRel.FORWARD_BY_OZGCLOUD, + command: this.createBuildForwardCommand(forwardingToUri), + snackBarMessage: EMPTY_STRING, + }; + } + + private createBuildForwardCommand(forwardingToUri: ResourceUri): CreateCommand { + return { order: CommandOrder.FORWARD_VORGANG, body: { organisationEinheitId: forwardingToUri } }; + } + ngOnDestroy(): void { this.unsubscribe(); } diff --git a/alfa-client/libs/forwarding/src/index.ts b/alfa-client/libs/forwarding/src/index.ts index 24d937c3408da87eef49107297ff05faf4ffd709..49ebdccb493b46cfb0c7565d0635dfb7ee617d18 100644 --- a/alfa-client/libs/forwarding/src/index.ts +++ b/alfa-client/libs/forwarding/src/index.ts @@ -21,6 +21,6 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -export * from './lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component'; +export * from './lib/forwarding-button-container/forwarding-button-container.component'; +export * from './lib/forwarding-by-email-container/forwarding-by-email-container.component'; export * from './lib/forwarding.module'; -export * from './lib/vorgang-forwarding-container/vorgang-forwarding-container.component'; diff --git a/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.ts b/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.ts deleted file mode 100644 index f5fbad7ed1280171822f6746847c08887dbaff75..0000000000000000000000000000000000000000 --- a/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { HasLinkPipe } from '@alfa-client/tech-shared'; -import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { CommonModule } from '@angular/common'; -import { Component, Input } from '@angular/core'; -import { ButtonWithSpinnerComponent } from '@ods/component'; -import { ForwardVorgangIconComponent, TooltipDirective } from '@ods/system'; - -@Component({ - selector: 'alfa-forward-by-ozgcloud-button-container', - standalone: true, - imports: [CommonModule, ButtonWithSpinnerComponent, ForwardVorgangIconComponent, TooltipDirective, HasLinkPipe], - templateUrl: './forward-by-ozgcloud-button-container.component.html', - styles: [':host {@apply empty:hidden}'], -}) -export class ForwardByOzgcloudButtonContainerComponent { - @Input() vorgangWithEingang: VorgangWithEingangResource; - @Input() showAsIconButton: boolean = false; - - public readonly vorgangWithEingangLinkRel = VorgangWithEingangLinkRel; -} diff --git a/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.html similarity index 51% rename from alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.html index 6afe4a115c084140ff69e8b5351c1c2fd9804406..bdf8537e74921852fa7d6d5c614dacc7179b1cf4 100644 --- a/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.html @@ -1,17 +1,17 @@ @if (vorgangWithEingang | hasLink: vorgangWithEingangLinkRel.FORWARD_BY_OZGCLOUD) { @if (showAsIconButton) { - <ods-button-with-spinner + <ods-open-dialog-button [tooltip]="'Vorgang weiterleiten'" tooltipAriaType="aria-labelledby" variant="ghost" size="fit" - dataTestId="forward-by-ozgcloud-icon-button" + dataTestId="forwarding-icon-button" > <ods-forward-vorgang-icon icon class="fill-text" /> - </ods-button-with-spinner> + </ods-open-dialog-button> } @else { - <ods-button-with-spinner text="Weiterleiten" variant="outline" dataTestId="forward-by-ozgcloud-button"> - <ods-forward-vorgang-icon icon /> - </ods-button-with-spinner> + <ods-open-dialog-button label="Weiterleiten" variant="outline" dataTestId="forwarding-button"> + <ods-forward-vorgang-icon icon class="fill-primary" /> + </ods-open-dialog-button> } } diff --git a/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.spec.ts similarity index 75% rename from alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.spec.ts index 8aab319a28e6ed8a3cd49270fdd27a42e2ed09f3..64f911229dabdbf02698f7d1faddff016383be75 100644 --- a/alfa-client/libs/forwarding/src/lib/forward-by-ozgcloud-button-container/forward-by-ozgcloud-button-container.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.spec.ts @@ -2,31 +2,31 @@ import { HasLinkPipe } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ButtonWithSpinnerComponent } from '@ods/component'; +import { OpenDialogButtonComponent } from '@ods/component'; import { ForwardVorgangIconComponent, TooltipDirective } from '@ods/system'; import { getDataTestIdAttributeOf } from 'libs/tech-shared/test/data-test'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent, MockDirective } from 'ng-mocks'; -import { ForwardByOzgcloudButtonContainerComponent } from './forward-by-ozgcloud-button-container.component'; +import { ForwardingButtonContainerComponent } from './forwarding-button-container.component'; -describe('ForwardByOzgcloudButtonContainerComponent', () => { - let component: ForwardByOzgcloudButtonContainerComponent; - let fixture: ComponentFixture<ForwardByOzgcloudButtonContainerComponent>; +describe('ForwardingButtonContainerComponent', () => { + let component: ForwardingButtonContainerComponent; + let fixture: ComponentFixture<ForwardingButtonContainerComponent>; - const iconButton: string = getDataTestIdAttributeOf('forward-by-ozgcloud-icon-button'); - const button: string = getDataTestIdAttributeOf('forward-by-ozgcloud-button'); + const iconButton: string = getDataTestIdAttributeOf('forwarding-icon-button'); + const button: string = getDataTestIdAttributeOf('forwarding-button'); beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ForwardByOzgcloudButtonContainerComponent, HasLinkPipe], + imports: [ForwardingButtonContainerComponent, HasLinkPipe], declarations: [ - MockComponent(ButtonWithSpinnerComponent), + MockComponent(OpenDialogButtonComponent), MockComponent(ForwardVorgangIconComponent), MockDirective(TooltipDirective), ], }).compileComponents(); - fixture = TestBed.createComponent(ForwardByOzgcloudButtonContainerComponent); + fixture = TestBed.createComponent(ForwardingButtonContainerComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f6d13f6a511dfed30763f27404380391a873e00 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-button-container/forwarding-button-container.component.ts @@ -0,0 +1,23 @@ +import { HasLinkPipe } from '@alfa-client/tech-shared'; +import { DIALOG_COMPONENT } from '@alfa-client/ui'; +import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; +import { OpenDialogButtonComponent } from '@ods/component'; +import { ForwardVorgangIconComponent, TooltipDirective } from '@ods/system'; +import { ForwardingDialogContainerComponent } from '../forwarding-dialog-container/forwarding-dialog-container.component'; + +@Component({ + selector: 'alfa-forwarding-button-container', + standalone: true, + imports: [CommonModule, ForwardVorgangIconComponent, TooltipDirective, HasLinkPipe, OpenDialogButtonComponent], + templateUrl: './forwarding-button-container.component.html', + providers: [{ provide: DIALOG_COMPONENT, useValue: ForwardingDialogContainerComponent }], + styles: [':host {@apply empty:hidden}'], +}) +export class ForwardingButtonContainerComponent { + @Input() vorgangWithEingang: VorgangWithEingangResource; + @Input() showAsIconButton: boolean = false; + + public readonly vorgangWithEingangLinkRel = VorgangWithEingangLinkRel; +} diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.html similarity index 88% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.html index 2698ddc7e78cbb2a6b8c6d0a4a6bbd67806ecc85..6f6b5fecf630fc540d9be10a2ff9fa40897fef97 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.html @@ -30,15 +30,15 @@ *ngIf="forwardingStateResources$ | async as forwardingStateResources" > <ozgcloud-spinner [stateResource]="forwardingStateResources"> - <alfa-vorgang-forwarding-info-list [forwardingList]="forwardingStateResources"></alfa-vorgang-forwarding-info-list> + <alfa-forwarding-by-email-info-list [forwardingList]="forwardingStateResources"></alfa-forwarding-by-email-info-list> </ozgcloud-spinner> - <alfa-vorgang-forward-formular + <alfa-forward-by-email-formular data-test-id="forward-formular" [vorgang]="vorgang" [pendingForwardCommand]="pendingForwardStateResource$ | async" (doSubmit)="submit()" > - </alfa-vorgang-forward-formular> + </alfa-forward-by-email-formular> </ozgcloud-expansion-panel> </ng-container> diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.scss b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.scss similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.scss rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.scss diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts similarity index 82% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts index 25691e2e369a3024d426d9a1e7a4e8976b37d228..b7387f11528fc118117ad6ca0cb51e11850ec1e8 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.spec.ts @@ -32,16 +32,16 @@ import { createCommandResource } from 'libs/command-shared/test/command'; import { createVorgangForwardRequest, createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; -import { VorgangForwardFormService } from './vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice'; -import { VorgangForwardFormularComponent } from './vorgang-forward-formular/vorgang-forward-formular.component'; -import { VorgangForwardingContainerComponent } from './vorgang-forwarding-container.component'; -import { VorgangForwardingInfoListComponent } from './vorgang-forwarding-info-list/vorgang-forwarding-info-list.component'; +import { ForwardingByEmailContainerComponent } from './forwarding-by-email-container.component'; +import { ForwardingByEmailFormService } from './forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service'; +import { ForwardingByEmailFormularComponent } from './forwarding-by-email-formular/forwarding-by-email-formular.component'; +import { ForwardingByEmailInfoListComponent } from './forwarding-by-email-info-list/forwarding-by-email-info-list.component'; -describe('VorgangForwardingContainerComponent', () => { - let component: VorgangForwardingContainerComponent; - let fixture: ComponentFixture<VorgangForwardingContainerComponent>; +describe('ForwardingByEmailContainerComponent', () => { + let component: ForwardingByEmailContainerComponent; + let fixture: ComponentFixture<ForwardingByEmailContainerComponent>; - const formService = mock(VorgangForwardFormService); + const formService = mock(ForwardingByEmailFormService); const service = mock(ForwardingService); const forwarding: string = '[data-test-id="forwarding"]'; @@ -49,17 +49,17 @@ describe('VorgangForwardingContainerComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ - VorgangForwardingContainerComponent, + ForwardingByEmailContainerComponent, HasLinkPipe, MockComponent(SpinnerComponent), - MockComponent(VorgangForwardingInfoListComponent), - MockComponent(VorgangForwardFormularComponent), + MockComponent(ForwardingByEmailInfoListComponent), + MockComponent(ForwardingByEmailFormularComponent), MockComponent(ExpansionPanelComponent), ], providers: [ UntypedFormBuilder, { - provide: VorgangForwardFormService, + provide: ForwardingByEmailFormService, useValue: formService, }, { @@ -71,7 +71,7 @@ describe('VorgangForwardingContainerComponent', () => { }); beforeEach(() => { - fixture = TestBed.createComponent(VorgangForwardingContainerComponent); + fixture = TestBed.createComponent(ForwardingByEmailContainerComponent); component = fixture.componentInstance; component.pendingForwardStateResource$ = of( createStateResource({ @@ -120,7 +120,7 @@ describe('VorgangForwardingContainerComponent', () => { component.getForwardings(); - expect(service.getForwardings).not.toHaveBeenCalled(); + expect(service.getForwardingsByEmail).not.toHaveBeenCalled(); }); it('should call service get forward commands', () => { @@ -129,7 +129,7 @@ describe('VorgangForwardingContainerComponent', () => { component.getForwardings(); - expect(service.getForwardings).toHaveBeenCalled(); + expect(service.getForwardingsByEmail).toHaveBeenCalled(); }); }); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts similarity index 83% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts index 9613957552ae86a387c108ecfa05f71463c8218b..bfc76dd9bd7bcb57c775bf38f8b60ab924c8f31b 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-container.component.ts @@ -29,15 +29,15 @@ import { Component, Input, OnChanges } from '@angular/core'; import { hasLink } from '@ngxp/rest'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; import { Observable, of } from 'rxjs'; -import { VorgangForwardFormService } from './vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice'; +import { ForwardingByEmailFormService } from './forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service'; @Component({ - selector: 'alfa-vorgang-forwarding-container', - templateUrl: './vorgang-forwarding-container.component.html', - styleUrls: ['./vorgang-forwarding-container.component.scss'], - providers: [VorgangForwardFormService], + selector: 'alfa-forwarding-by-email-container', + templateUrl: './forwarding-by-email-container.component.html', + styleUrls: ['./forwarding-by-email-container.component.scss'], + providers: [ForwardingByEmailFormService], }) -export class VorgangForwardingContainerComponent implements OnChanges { +export class ForwardingByEmailContainerComponent implements OnChanges { @Input() public vorgang: VorgangWithEingangResource; forwardingStateResources$: Observable<StateResource<ForwardingListResource>> = @@ -48,7 +48,7 @@ export class VorgangForwardingContainerComponent implements OnChanges { readonly vorgangLinkRel = VorgangWithEingangLinkRel; constructor( - public formService: VorgangForwardFormService, + public formService: ForwardingByEmailFormService, private forwardingService: ForwardingService, ) {} @@ -65,7 +65,7 @@ export class VorgangForwardingContainerComponent implements OnChanges { getForwardings(): void { if (hasLink(this.vorgang, VorgangWithEingangLinkRel.FORWARD_BY_EMAIL)) { - this.forwardingStateResources$ = this.forwardingService.getForwardings(this.vorgang); + this.forwardingStateResources$ = this.forwardingService.getForwardingsByEmail(this.vorgang); } } diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.html similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.html diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.scss b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.scss similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.scss rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.scss diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.spec.ts similarity index 83% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.spec.ts index d4de767de8c460d74794b21ec61a5152ee38d2c6..a7f290dba1dbce319cd3822a64c97d63ba0c2adc 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.spec.ts @@ -32,26 +32,26 @@ import { MatInputModule } from '@angular/material/input'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; -import { VorgangForwardFormComponent } from './vorgang-forward-form.component'; -import { VorgangForwardFormService } from './vorgang-forward.formservice'; +import { ForwardingByEmailFormComponent } from './forwarding-by-email-form.component'; +import { ForwardingByEmailFormService } from './forwarding-by-email-form.service'; -describe('VorgangForwardFormComponent', () => { - let component: VorgangForwardFormComponent; - let fixture: ComponentFixture<VorgangForwardFormComponent>; +describe('ForwardingByEmailFormComponent', () => { + let component: ForwardingByEmailFormComponent; + let fixture: ComponentFixture<ForwardingByEmailFormComponent>; const form: UntypedFormGroup = new UntypedFormGroup({ - [VorgangForwardFormService.FIELD_PASSWORD]: new UntypedFormControl(null), - [VorgangForwardFormService.FIELD_EMAIL]: new UntypedFormControl(null), + [ForwardingByEmailFormService.FIELD_PASSWORD]: new UntypedFormControl(null), + [ForwardingByEmailFormService.FIELD_EMAIL]: new UntypedFormControl(null), }); - const formService = { ...mock(VorgangForwardFormService), form }; + const formService = { ...mock(ForwardingByEmailFormService), form }; const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource(); beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ - VorgangForwardFormComponent, + ForwardingByEmailFormComponent, MatIcon, MockComponent(OzgcloudStrokedButtonWithSpinnerComponent), MockComponent(OzgcloudTextEditorComponent), @@ -59,7 +59,7 @@ describe('VorgangForwardFormComponent', () => { imports: [MatFormFieldModule, MatInputModule, ReactiveFormsModule, BrowserAnimationsModule], providers: [ { - provide: VorgangForwardFormService, + provide: ForwardingByEmailFormService, useValue: formService, }, ], @@ -67,7 +67,7 @@ describe('VorgangForwardFormComponent', () => { }); beforeEach(() => { - fixture = TestBed.createComponent(VorgangForwardFormComponent); + fixture = TestBed.createComponent(ForwardingByEmailFormComponent); component = fixture.componentInstance; component.vorgang = vorgangWithEingang; fixture.detectChanges(); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.ts similarity index 78% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.ts index 202a4fe83e31c78ac708914a1ef041a3203dec2f..62056b753804b1ebc91d616df4205cd172f05485 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component.ts @@ -21,28 +21,28 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; -import { UntypedFormGroup } from '@angular/forms'; import { CommandResource } from '@alfa-client/command-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; import { isNil } from 'lodash-es'; -import { VorgangForwardFormService } from './vorgang-forward.formservice'; +import { ForwardingByEmailFormService } from './forwarding-by-email-form.service'; @Component({ - selector: 'alfa-vorgang-forward-form', - templateUrl: './vorgang-forward-form.component.html', - styleUrls: ['./vorgang-forward-form.component.scss'], + selector: 'alfa-forward-by-email-form', + templateUrl: './forwarding-by-email-form.component.html', + styleUrls: ['./forwarding-by-email-form.component.scss'], }) -export class VorgangForwardFormComponent implements OnChanges { +export class ForwardingByEmailFormComponent implements OnChanges { @Input() forwardStateResource: StateResource<CommandResource>; @Input() vorgang: VorgangWithEingangResource; @Output('doSubmit') submit: EventEmitter<void> = new EventEmitter(); - readonly formServiceClass = VorgangForwardFormService; + readonly formServiceClass = ForwardingByEmailFormService; - constructor(private formService: VorgangForwardFormService) {} + constructor(private formService: ForwardingByEmailFormService) {} ngOnChanges(changes: SimpleChanges) { if (changes.vorgang && this.zustaendigeStelleEmailExists()) { @@ -60,10 +60,7 @@ export class VorgangForwardFormComponent implements OnChanges { } patchEmail(): void { - this.formService.patchField( - VorgangForwardFormService.FIELD_EMAIL, - this.vorgang.eingang.zustaendigeStelle.email, - ); + this.formService.patchField(ForwardingByEmailFormService.FIELD_EMAIL, this.vorgang.eingang.zustaendigeStelle.email); } get form(): UntypedFormGroup { diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts similarity index 85% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts index 68fc4c4a960aa2635f161a4b4413da33b7da7a7e..364d7e506e6e6b54ec5a84ecfb01f98ffebb9d9c 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.service.ts @@ -30,7 +30,7 @@ import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angul import { Observable } from 'rxjs'; @Injectable() -export class VorgangForwardFormService extends AbstractFormService<CommandResource> { +export class ForwardingByEmailFormService extends AbstractFormService<CommandResource> { static readonly FIELD_PATH_PREFIX = 'command.redirectRequest'; static readonly FIELD_EMAIL = 'email'; @@ -47,13 +47,13 @@ export class VorgangForwardFormService extends AbstractFormService<CommandResour protected initForm(): UntypedFormGroup { return this.formBuilder.group({ - [VorgangForwardFormService.FIELD_EMAIL]: new UntypedFormControl(), - [VorgangForwardFormService.FIELD_PASSWORD]: new UntypedFormControl(), + [ForwardingByEmailFormService.FIELD_EMAIL]: new UntypedFormControl(), + [ForwardingByEmailFormService.FIELD_PASSWORD]: new UntypedFormControl(), }); } protected getPathPrefix(): string { - return VorgangForwardFormService.FIELD_PATH_PREFIX; + return ForwardingByEmailFormService.FIELD_PATH_PREFIX; } public setVorgang(vorgang: VorgangResource): void { @@ -61,7 +61,7 @@ export class VorgangForwardFormService extends AbstractFormService<CommandResour } protected doSubmit(): Observable<StateResource<CommandResource>> { - return this.forwardingService.forward(this.vorgang, this.getFormValue()); + return this.forwardingService.forwardByEmail(this.vorgang, this.getFormValue()); } patchField(fieldName: string, value: string) { diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts similarity index 79% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts index bdf61274a7de5bee95e7f4192ec724b109bf6735..26483f43dbf893769e87f2c6589ff88744c84461 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward.formservice.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email.formservice.spec.ts @@ -21,23 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { ForwardingService } from '@alfa-client/forwarding-shared'; -import { mock, useFromMock } from '@alfa-client/test-utils'; +import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; +import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang'; import { of } from 'rxjs'; -import { VorgangForwardFormService } from './vorgang-forward.formservice'; +import { ForwardingByEmailFormService } from './forwarding-by-email-form.service'; + +describe('ForwardingByEmailFormService', () => { + let formService: ForwardingByEmailFormService; -describe('VorgangForwardFormService', () => { - let formService: VorgangForwardFormService; - let service; + let service: Mock<ForwardingService>; const formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); beforeEach(() => { service = mock(ForwardingService); - formService = new VorgangForwardFormService(formBuilder, useFromMock(service)); + formService = new ForwardingByEmailFormService(formBuilder, useFromMock(service)); }); it('should create', () => { @@ -48,8 +49,7 @@ describe('VorgangForwardFormService', () => { const returnValue = {}; beforeEach(() => { - service.forward.mockReturnValue(of(returnValue)); - service.doSubmit = jest.fn(); + service.forwardByEmail.mockReturnValue(of(returnValue)); }); it('should call service', () => { @@ -57,7 +57,7 @@ describe('VorgangForwardFormService', () => { formService.submit(); - expect(service.forward).toHaveBeenCalledWith(formService.vorgang, formService.form.value); + expect(service.forwardByEmail).toHaveBeenCalledWith(formService.vorgang, formService.form.value); }); }); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.html similarity index 95% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.html index 62c2a5d4b5f9c70f8366791911cee5e02db1bf58..b3729e2b1a5da9a17c16b456c0d826c940816aeb 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.html @@ -32,11 +32,11 @@ > </ozgcloud-spinner> -<alfa-vorgang-forward-form +<alfa-forward-by-email-form *ngIf="vorgang | hasLink: vorgangLinkRel.FORWARD" data-test-id="forward-form" [vorgang]="vorgang" [forwardStateResource]="pendingForwardCommand" (doSubmit)="submit.emit()" > -</alfa-vorgang-forward-form> +</alfa-forward-by-email-form> diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.scss b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.scss similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-container.component.scss rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.scss diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.spec.ts similarity index 81% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.spec.ts index 1ae6e68ebdc117a55bab652ed62496bb3f00699d..cd26ff87ee2eb7cbec85b974db3aa23cc77f206c 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.spec.ts @@ -21,34 +21,34 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createEmptyStateResource, HasLinkPipe } from '@alfa-client/tech-shared'; import { SpinnerComponent } from '@alfa-client/ui'; import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; -import { VorgangForwardFormComponent } from './vorgang-forward-form/vorgang-forward-form.component'; -import { VorgangForwardFormularComponent } from './vorgang-forward-formular.component'; +import { ForwardingByEmailFormComponent } from './forwarding-by-email-form/forwarding-by-email-form.component'; +import { ForwardingByEmailFormularComponent } from './forwarding-by-email-formular.component'; -describe('VorgangForwardFormularComponent', () => { - let component: VorgangForwardFormularComponent; - let fixture: ComponentFixture<VorgangForwardFormularComponent>; +describe('ForwardingByEmailFormularComponent', () => { + let component: ForwardingByEmailFormularComponent; + let fixture: ComponentFixture<ForwardingByEmailFormularComponent>; const forwardFormular: string = '[data-test-id="forward-form"]'; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ - VorgangForwardFormularComponent, + ForwardingByEmailFormularComponent, HasLinkPipe, MockComponent(SpinnerComponent), - MockComponent(VorgangForwardFormComponent), + MockComponent(ForwardingByEmailFormComponent), ], }); }); beforeEach(() => { - fixture = TestBed.createComponent(VorgangForwardFormularComponent); + fixture = TestBed.createComponent(ForwardingByEmailFormularComponent); component = fixture.componentInstance; component.pendingForwardCommand = createEmptyStateResource(); fixture.detectChanges(); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.ts similarity index 88% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.ts index 087ef0833ec89bdfd4a94cf766afde315b3fb838..90359c37ba60ac4ed31c983af4203cf476341cfc 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component.ts @@ -21,18 +21,18 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CommandResource } from '@alfa-client/command-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; @Component({ - selector: 'alfa-vorgang-forward-formular', - templateUrl: './vorgang-forward-formular.component.html', - styleUrls: ['./vorgang-forward-formular.component.scss'], + selector: 'alfa-forward-by-email-formular', + templateUrl: './forwarding-by-email-formular.component.html', + styleUrls: ['./forwarding-by-email-formular.component.scss'], }) -export class VorgangForwardFormularComponent { +export class ForwardingByEmailFormularComponent { @Input() public vorgang: VorgangWithEingangResource; @Input() public pendingForwardCommand: StateResource<CommandResource>; diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.html similarity index 94% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.html index a358b03574297c36505a0f6456632bd50124a8ed..cdaf3279726e35aadd126f4565d36ca8a165026f 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.html @@ -23,10 +23,10 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<alfa-vorgang-forwarding-info +<alfa-forwarding-by-email-info *ngFor=" let forwarding of forwardingList.resource | toEmbeddedResources: listLinkRel.FORWARDING_LIST " [forwarding]="forwarding" > -</alfa-vorgang-forwarding-info> +</alfa-forwarding-by-email-info> diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.scss b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.scss similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.scss rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.scss diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.spec.ts similarity index 72% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.spec.ts index fcb17963b66bc13d7ca9204a20b46eb3c4dcdb0e..d4bd32a97b8b36df4c1bf911ce9a4e01a9d976a7 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.spec.ts @@ -21,29 +21,25 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createStateResource, ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createCommandListResource } from 'libs/command-shared/test/command'; import { MockComponent } from 'ng-mocks'; -import { VorgangForwardingInfoListComponent } from './vorgang-forwarding-info-list.component'; -import { VorgangForwardingInfoComponent } from './vorgang-forwarding-info/vorgang-forwarding-info.component'; +import { ForwardingByEmailInfoListComponent } from './forwarding-by-email-info-list.component'; +import { ForwardingByEmailInfoComponent } from './forwarding-by-email-info/forwarding-by-email-info.component'; -describe('VorgangForwardingInfoListComponent', () => { - let component: VorgangForwardingInfoListComponent; - let fixture: ComponentFixture<VorgangForwardingInfoListComponent>; +describe('ForwardingByEmailInfoListComponent', () => { + let component: ForwardingByEmailInfoListComponent; + let fixture: ComponentFixture<ForwardingByEmailInfoListComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ - VorgangForwardingInfoListComponent, - MockComponent(VorgangForwardingInfoComponent), - ToEmbeddedResourcesPipe, - ], + declarations: [ForwardingByEmailInfoListComponent, MockComponent(ForwardingByEmailInfoComponent), ToEmbeddedResourcesPipe], }).compileComponents(); }); beforeEach(() => { - fixture = TestBed.createComponent(VorgangForwardingInfoListComponent); + fixture = TestBed.createComponent(ForwardingByEmailInfoListComponent); component = fixture.componentInstance; component.forwardingList = createStateResource(createCommandListResource()); fixture.detectChanges(); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.ts similarity index 85% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.ts index 23c57cf9b93914849174a9550dbdc4ba5623f397..8cc5127425be7951f0105fe614745324f50344ce 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component.ts @@ -21,17 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, Input } from '@angular/core'; import { CommandListResource } from '@alfa-client/command-shared'; import { ForwardingListLinkRel } from '@alfa-client/forwarding-shared'; import { StateResource } from '@alfa-client/tech-shared'; +import { Component, Input } from '@angular/core'; @Component({ - selector: 'alfa-vorgang-forwarding-info-list', - templateUrl: './vorgang-forwarding-info-list.component.html', - styleUrls: ['./vorgang-forwarding-info-list.component.scss'], + selector: 'alfa-forwarding-by-email-info-list', + templateUrl: './forwarding-by-email-info-list.component.html', + styleUrls: ['./forwarding-by-email-info-list.component.scss'], }) -export class VorgangForwardingInfoListComponent { +export class ForwardingByEmailInfoListComponent { @Input() public forwardingList: StateResource<CommandListResource>; readonly listLinkRel = ForwardingListLinkRel; diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.html similarity index 95% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.html index e3fe65cb08140c7190e6c96f943895c744e00da0..add689836951a6d770d92fc47547d2eea730077e 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.html @@ -42,7 +42,7 @@ Versendet am {{ forwarding.sentAt | formatDateWithTimePipe }} </p> - <alfa-vorgang-forward-zustellen-container + <alfa-forward-by-email-zustellen-container [forwarding]="forwarding" - ></alfa-vorgang-forward-zustellen-container> + ></alfa-forward-by-email-zustellen-container> </ng-template> diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.scss b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.scss similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.scss rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.scss diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.spec.ts similarity index 86% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.spec.ts index 12b90483aed9a47eed13c6aa1cd7eff4d3828059..c42367bfa51ab3181cdfe38ea817f9d92ec1d8fb 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.spec.ts @@ -21,6 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { ForwardingLinkRel } from '@alfa-client/forwarding-shared'; +import { FormatDateWithTimePipe, HasLinkPipe } from '@alfa-client/tech-shared'; import { registerLocaleData } from '@angular/common'; import localeDe from '@angular/common/locales/de'; import localeDeExtra from '@angular/common/locales/extra/de'; @@ -28,18 +30,16 @@ import { LOCALE_ID } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DATE_LOCALE } from '@angular/material/core'; import { MatIcon } from '@angular/material/icon'; -import { ForwardingLinkRel } from '@alfa-client/forwarding-shared'; -import { FormatDateWithTimePipe, HasLinkPipe } from '@alfa-client/tech-shared'; import { createForwardingResource } from 'libs/forwarding-shared/test/forwarding'; import { MockComponent } from 'ng-mocks'; -import { VorgangForwardZustellenContainerComponent } from '../../../vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component'; -import { VorgangForwardingInfoComponent } from './vorgang-forwarding-info.component'; +import { ForwardingByEmailZustellenContainerComponent } from '../../../forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component'; +import { ForwardingByEmailInfoComponent } from './forwarding-by-email-info.component'; registerLocaleData(localeDe, 'de', localeDeExtra); -describe('VorgangForwardingInfoComponent', () => { - let component: VorgangForwardingInfoComponent; - let fixture: ComponentFixture<VorgangForwardingInfoComponent>; +describe('ForwardingByEmailInfoComponent', () => { + let component: ForwardingByEmailInfoComponent; + let fixture: ComponentFixture<ForwardingByEmailInfoComponent>; const errorMessage: string = '[data-test-id="forwarding-error-message"]'; const successMessage: string = '[data-test-id="forwarding-success-message"]'; @@ -47,11 +47,11 @@ describe('VorgangForwardingInfoComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ - VorgangForwardingInfoComponent, + ForwardingByEmailInfoComponent, FormatDateWithTimePipe, MatIcon, HasLinkPipe, - MockComponent(VorgangForwardZustellenContainerComponent), + MockComponent(ForwardingByEmailZustellenContainerComponent), ], providers: [ { provide: LOCALE_ID, useValue: 'de' }, @@ -61,7 +61,7 @@ describe('VorgangForwardingInfoComponent', () => { }); beforeEach(() => { - fixture = TestBed.createComponent(VorgangForwardingInfoComponent); + fixture = TestBed.createComponent(ForwardingByEmailInfoComponent); component = fixture.componentInstance; component.forwarding = createForwardingResource(); fixture.detectChanges(); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.ts similarity index 85% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.ts index 3f4948987d118ab454fb65a25988fe5d1327e3e8..7c5490bb38db212d873a50ca4ead6f4eb93e338f 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component.ts @@ -21,15 +21,15 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, Input } from '@angular/core'; import { ForwardingLinkRel, ForwardingResource } from '@alfa-client/forwarding-shared'; +import { Component, Input } from '@angular/core'; @Component({ - selector: 'alfa-vorgang-forwarding-info', - templateUrl: './vorgang-forwarding-info.component.html', - styleUrls: ['./vorgang-forwarding-info.component.scss'], + selector: 'alfa-forwarding-by-email-info', + templateUrl: './forwarding-by-email-info.component.html', + styleUrls: ['./forwarding-by-email-info.component.scss'], }) -export class VorgangForwardingInfoComponent { +export class ForwardingByEmailInfoComponent { @Input() public forwarding: ForwardingResource; readonly linkRel = ForwardingLinkRel; diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.html similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.html rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.html diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.scss b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.scss similarity index 100% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.scss rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.scss diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.spec.ts similarity index 89% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.spec.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.spec.ts index 46602865bee94117dd136e994133029c41001d07..e28f66a088a6dff1fb47b02c4423fcad0ef3b042 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.spec.ts @@ -21,23 +21,19 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatIcon } from '@angular/material/icon'; -import { - ForwardingLinkRel, - ForwardingResource, - ForwardingService, -} from '@alfa-client/forwarding-shared'; +import { ForwardingLinkRel, ForwardingResource, ForwardingService } from '@alfa-client/forwarding-shared'; import { HasLinkPipe } from '@alfa-client/tech-shared'; import { mock } from '@alfa-client/test-utils'; import { OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatIcon } from '@angular/material/icon'; import { createForwardingResource } from 'libs/forwarding-shared/test/forwarding'; import { MockComponent } from 'ng-mocks'; -import { VorgangForwardZustellenContainerComponent } from './vorgang-forward-zustellen-container.component'; +import { ForwardingByEmailZustellenContainerComponent } from './forwarding-by-email-zustellen-container.component'; -describe('VorgangForwardZustellenContainerComponent', () => { - let component: VorgangForwardZustellenContainerComponent; - let fixture: ComponentFixture<VorgangForwardZustellenContainerComponent>; +describe('ForwardingByEmailZustellenContainerComponent', () => { + let component: ForwardingByEmailZustellenContainerComponent; + let fixture: ComponentFixture<ForwardingByEmailZustellenContainerComponent>; const forwarding: ForwardingResource = createForwardingResource(); @@ -53,7 +49,7 @@ describe('VorgangForwardZustellenContainerComponent', () => { await TestBed.configureTestingModule({ declarations: [ HasLinkPipe, - VorgangForwardZustellenContainerComponent, + ForwardingByEmailZustellenContainerComponent, MatIcon, MockComponent(OzgcloudStrokedButtonWithSpinnerComponent), ], @@ -67,7 +63,7 @@ describe('VorgangForwardZustellenContainerComponent', () => { }); beforeEach(() => { - fixture = TestBed.createComponent(VorgangForwardZustellenContainerComponent); + fixture = TestBed.createComponent(ForwardingByEmailZustellenContainerComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.ts similarity index 76% rename from alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.ts rename to alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.ts index c7aebc99014825288f365709d57b693823d7fe3a..e4d6c197b9ec5eb09cbfd20a8cbcb9df7ca6d14a 100644 --- a/alfa-client/libs/forwarding/src/lib/vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component.ts @@ -21,30 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, Input } from '@angular/core'; import { CommandResource } from '@alfa-client/command-shared'; -import { - ForwardingLinkRel, - ForwardingResource, - ForwardingService, -} from '@alfa-client/forwarding-shared'; +import { ForwardingLinkRel, ForwardingResource, ForwardingService } from '@alfa-client/forwarding-shared'; import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared'; +import { Component, Input } from '@angular/core'; import { Observable, of } from 'rxjs'; @Component({ - selector: 'alfa-vorgang-forward-zustellen-container', - templateUrl: './vorgang-forward-zustellen-container.component.html', - styleUrls: ['./vorgang-forward-zustellen-container.component.scss'], + selector: 'alfa-forward-by-email-zustellen-container', + templateUrl: './forwarding-by-email-zustellen-container.component.html', + styleUrls: ['./forwarding-by-email-zustellen-container.component.scss'], }) -export class VorgangForwardZustellenContainerComponent { +export class ForwardingByEmailZustellenContainerComponent { @Input() forwarding: ForwardingResource; - public markAsSuccessCommandStateResource$: Observable<StateResource<CommandResource>> = of( - createEmptyStateResource<CommandResource>(), - ); - public markAsFailCommandStateResource$: Observable<StateResource<CommandResource>> = of( - createEmptyStateResource<CommandResource>(), - ); + public markAsSuccessCommandStateResource$: Observable<StateResource<CommandResource>> = + of(createEmptyStateResource<CommandResource>()); + public markAsFailCommandStateResource$: Observable<StateResource<CommandResource>> = + of(createEmptyStateResource<CommandResource>()); readonly linkRel = ForwardingLinkRel; diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..e6c65fbf4d123859056d2b834c6b45107a620683 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.html @@ -0,0 +1,6 @@ +<alfa-forwarding-dialog + [forwardCommandStateResource]="forwardCommandStateResource$ | async" + [selectedSearchResult]="selectedSearchResult$ | async" + (forward)="forward($event)" + data-test-id="forwarding-dialog" +/> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..2dbd1a86402ade740cfbef6bc23460542baec559 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.spec.ts @@ -0,0 +1,109 @@ +import { CommandLinkRel, CommandResource } from '@alfa-client/command-shared'; +import { ForwardingService } from '@alfa-client/forwarding-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { mock, Mock, triggerEvent } from '@alfa-client/test-utils'; +import { OzgcloudDialogService } from '@alfa-client/ui'; +import { OrganisationsEinheitService, ZUSTAENDIGE_STELLE_SERVICE } from '@alfa-client/zustaendige-stelle-shared'; +import { AsyncPipe } from '@angular/common'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { faker } from '@faker-js/faker/.'; +import { ResourceUri } from '@ngxp/rest'; +import { createCommandStateResource } from 'libs/command-shared/test/command'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { singleColdCompleted } from 'libs/tech-shared/test/marbles'; +import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; +import { ForwardingDialogContainerComponent } from './forwarding-dialog-container.component'; +import { ForwardingDialogComponent } from './forwarding-dialog/forwarding-dialog.component'; + +describe('ForwardingDialogContainerComponent', () => { + let component: ForwardingDialogContainerComponent; + let fixture: ComponentFixture<ForwardingDialogContainerComponent>; + + const forwardingDialog: string = getDataTestIdOf('forwarding-dialog'); + + let service: Mock<ForwardingService>; + let organisationsEinheitService: Mock<OrganisationsEinheitService>; + let dialogService: Mock<OzgcloudDialogService>; + + beforeEach(async () => { + service = mock(ForwardingService); + organisationsEinheitService = mock(OrganisationsEinheitService); + dialogService = mock(OzgcloudDialogService); + + await TestBed.configureTestingModule({ + imports: [ForwardingDialogContainerComponent, AsyncPipe], + declarations: [MockComponent(ForwardingDialogComponent)], + providers: [ + { + provide: ForwardingService, + useValue: service, + }, + { + provide: OzgcloudDialogService, + useValue: dialogService, + }, + ], + }) + .overrideComponent(ForwardingDialogContainerComponent, { + set: { + providers: [ + { + provide: ZUSTAENDIGE_STELLE_SERVICE, + useValue: organisationsEinheitService, + }, + ], + }, + }) + .compileComponents(); + + fixture = TestBed.createComponent(ForwardingDialogContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('forward button', () => { + const targetUri: ResourceUri = faker.internet.url(); + + it('should call forward on click', () => { + component.forward = jest.fn(); + + triggerEvent({ fixture, elementSelector: forwardingDialog, name: 'forward', data: targetUri }); + + expect(component.forward).toHaveBeenCalledWith(targetUri); + }); + }); + + describe('forward', () => { + const targetUri: ResourceUri = faker.internet.url(); + + const commandStateResource: StateResource<CommandResource> = createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE]); + + beforeEach(() => { + service.forward.mockReturnValue(of(commandStateResource)); + }); + + it('should call service with uri', () => { + component.forward(targetUri); + + expect(service.forward).toHaveBeenCalledWith(targetUri); + }); + + it('should set service response', () => { + component.forward(targetUri); + + expect(component.forwardCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + + it('should call dialog service to close all if command is done', () => { + component.forward(targetUri); + component.forwardCommandStateResource$.subscribe(); + + expect(dialogService.closeAll).toHaveBeenCalled(); + }); + }); +}); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..726320a3498c9e9b3ede988f28d84feee3cbcc24 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog-container.component.ts @@ -0,0 +1,51 @@ +import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; +import { ForwardingService } from '@alfa-client/forwarding-shared'; +import { createEmptyStateResource, ResourceRepository, StateResource } from '@alfa-client/tech-shared'; +import { OzgcloudDialogService } from '@alfa-client/ui'; +import { VorgangService } from '@alfa-client/vorgang-shared'; +import { createOrganisationEinheitService } from '@alfa-client/zustaendige-stelle'; +import { + OrganisationsEinheitResource, + OrganisationsEinheitService, + ZUSTAENDIGE_STELLE_SERVICE, +} from '@alfa-client/zustaendige-stelle-shared'; +import { AsyncPipe, CommonModule } from '@angular/common'; +import { Component, inject, OnInit } from '@angular/core'; +import { ResourceUri } from '@ngxp/rest'; +import { Observable, of } from 'rxjs'; +import { ForwardingDialogComponent } from './forwarding-dialog/forwarding-dialog.component'; + +@Component({ + selector: 'alfa-forwarding-dialog-container', + standalone: true, + imports: [ForwardingDialogComponent, AsyncPipe, CommonModule], + templateUrl: './forwarding-dialog-container.component.html', + providers: [ + { + provide: ZUSTAENDIGE_STELLE_SERVICE, + useFactory: createOrganisationEinheitService, + deps: [ResourceRepository, VorgangService], + }, + ], +}) +export class ForwardingDialogContainerComponent implements OnInit { + private readonly organisationsEinheitService = inject(ZUSTAENDIGE_STELLE_SERVICE) as OrganisationsEinheitService; + private readonly forwardingService = inject(ForwardingService); + private readonly dialogService = inject(OzgcloudDialogService); + + public selectedSearchResult$: Observable<OrganisationsEinheitResource>; + public forwardCommandStateResource$: Observable<StateResource<CommandResource>> = + of(createEmptyStateResource<CommandResource>()); + + ngOnInit(): void { + this.selectedSearchResult$ = this.organisationsEinheitService.getSelectedResult(); + } + + public forward(targetUri: ResourceUri): void { + this.forwardCommandStateResource$ = this.forwardingService.forward(targetUri).pipe( + tapOnCommandSuccessfullyDone(() => { + this.dialogService.closeAll(); + }), + ); + } +} diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html new file mode 100644 index 0000000000000000000000000000000000000000..5bf44a14c8978d8fea1e07d51b0ccc1279935ca4 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html @@ -0,0 +1,11 @@ +<ods-button-with-spinner + [stateResource]="stateResource" + [disabled]="disabled" + (clickEmitter)="clickEmitter.emit()" + text="Weiterleiten" + variant="outline" + dataTestId="forwarding-dialog-forwarding-button" + data-test-id="forwarding-button-container" +> + <ods-forward-vorgang-icon icon class="fill-primary" /> +</ods-button-with-spinner> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e9a9d2118e1a9758f7ba58715f822822ead4cbf --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts @@ -0,0 +1,39 @@ +import { dispatchEventFromFixture, MockEvent } from '@alfa-client/test-utils'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ButtonWithSpinnerComponent } from '@ods/component'; +import { ForwardVorgangIconComponent } from '@ods/system'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { MockComponent } from 'ng-mocks'; +import { ForwardingButtonComponent } from './forwarding-button.component'; + +describe('ForwardingButtonComponent', () => { + let component: ForwardingButtonComponent; + let fixture: ComponentFixture<ForwardingButtonComponent>; + + const button: string = getDataTestIdOf('forwarding-button-container'); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ForwardingButtonComponent], + declarations: [MockComponent(ForwardVorgangIconComponent), MockComponent(ButtonWithSpinnerComponent)], + }).compileComponents(); + + fixture = TestBed.createComponent(ForwardingButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('on button click', () => { + it('should emit', () => { + component.clickEmitter.emit = jest.fn(); + + dispatchEventFromFixture(fixture, button, MockEvent.CLICK); + + expect(component.clickEmitter.emit).toHaveBeenCalled(); + }); + }); +}); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..767fe5e4ce40e7589725973d37e9a84c12fd0564 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts @@ -0,0 +1,18 @@ +import { CommandResource } from '@alfa-client/command-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { ButtonWithSpinnerComponent } from '@ods/component'; +import { ForwardVorgangIconComponent } from '@ods/system'; + +@Component({ + selector: 'alfa-forwarding-button', + standalone: true, + imports: [ButtonWithSpinnerComponent, ForwardVorgangIconComponent], + templateUrl: './forwarding-button.component.html', +}) +export class ForwardingButtonComponent { + @Input() disabled: boolean; + @Input() stateResource: StateResource<CommandResource>; + + @Output() clickEmitter: EventEmitter<void> = new EventEmitter(); +} diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html new file mode 100644 index 0000000000000000000000000000000000000000..5aaf99a340455262073812254cf8c7d74adf578e --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html @@ -0,0 +1,22 @@ +<div class="flex w-[620px] max-w-full flex-col gap-4 bg-background-100 p-8"> + <div class="flex items-center justify-between"> + <h1 class="text-xl font-semibold text-primary">Vorgang weiterleiten</h1> + <ods-cancel-dialog-button showAsIconButton="true" /> + </div> + + @if (!selectedSearchResult) { + <alfa-search-zustaendige-stelle-form-container cdkFocusInitial focusOnSearchField="true" data-test-id="zufi-search" /> + } @else { + <alfa-forwarding-item-in-dialog [organisationsEinheitResource]="selectedSearchResult" data-test-id="forwarding-item" /> + } + + <div class="flex gap-4"> + <alfa-forwarding-button + [stateResource]="forwardCommandStateResource" + [disabled]="!selectedSearchResult" + (clickEmitter)="onForwarding()" + data-test-id="foward-dialog-forward-button" + /> + <ods-cancel-dialog-button /> + </div> +</div> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e6114236be2ad7d2dddfcdfd309853b32568cdd --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.spec.ts @@ -0,0 +1,123 @@ +import { + dispatchEventFromFixture, + existsAsHtmlElement, + getMockComponent, + MockEvent, + notExistsAsHtmlElement, +} from '@alfa-client/test-utils'; +import { ZustaendigeStelleModule } from '@alfa-client/zustaendige-stelle'; +import { OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { getUrl } from '@ngxp/rest'; +import { CancelDialogButtonComponent } from '@ods/component'; +import { MockComponent, MockModule } from 'ng-mocks'; +import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; +import { createOrganisationsEinheitResource } from '../../../../../zustaendige-stelle-shared/test/organisations-einheit'; +import { ForwardingButtonComponent } from './forwarding-button/forwarding-button.component'; +import { ForwardingDialogComponent } from './forwarding-dialog.component'; +import { ForwardingItemInDialogComponent } from './forwarding-item/forwarding-item.component'; + +describe('ForwardingDialogComponent', () => { + let component: ForwardingDialogComponent; + let fixture: ComponentFixture<ForwardingDialogComponent>; + + const zufiSearch: string = getDataTestIdOf('zufi-search'); + const forwardingItem: string = getDataTestIdOf('forwarding-item'); + const forwardButton: string = getDataTestIdOf('foward-dialog-forward-button'); + + const organisationsEinheitResource: OrganisationsEinheitResource = createOrganisationsEinheitResource(); + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ForwardingDialogComponent], + declarations: [ + MockComponent(CancelDialogButtonComponent), + MockComponent(ForwardingButtonComponent), + MockComponent(ForwardingItemInDialogComponent), + MockModule(ZustaendigeStelleModule), + ], + }).compileComponents(); + + fixture = TestBed.createComponent(ForwardingDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('template', () => { + describe('zufi search', () => { + it('should render if selectedSearchResult is null', () => { + component.selectedSearchResult = null; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, zufiSearch); + }); + + it('should NOT render if selectedSearchResult is NOT null', () => { + component.selectedSearchResult = organisationsEinheitResource; + + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, zufiSearch); + }); + }); + }); + + it('should render zufi search if selectedSearchResult is null', () => { + component.selectedSearchResult = null; + + fixture.detectChanges(); + }); + + describe('forwarding item', () => { + it('should render if selectedSearchResult is NOT null', () => { + component.selectedSearchResult = organisationsEinheitResource; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, forwardingItem); + }); + + it('should NOT render if selectedSearchResult is null', () => { + component.selectedSearchResult = null; + + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, forwardingItem); + }); + }); + + describe('forwarding button', () => { + it('should be disabled if selectedSearchResult is null', () => { + component.selectedSearchResult = null; + + fixture.detectChanges(); + + const forwardingButton: ForwardingButtonComponent = getMockComponent(fixture, ForwardingButtonComponent); + expect(forwardingButton.disabled).toBeTruthy(); + }); + + it('should NOT be disabled if selectedSearchResult is NOT null', () => { + component.selectedSearchResult = organisationsEinheitResource; + + fixture.detectChanges(); + + const forwardingButton: ForwardingButtonComponent = getMockComponent(fixture, ForwardingButtonComponent); + expect(forwardingButton.disabled).toBeFalsy(); + }); + }); + + describe('forward button', () => { + it('should emit on click', () => { + component.selectedSearchResult = organisationsEinheitResource; + component.forward.emit = jest.fn(); + + dispatchEventFromFixture(fixture, forwardButton, MockEvent.CLICK); + + expect(component.forward.emit).toHaveBeenCalledWith(getUrl(organisationsEinheitResource)); + }); + }); +}); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..178d84465273bc421ee5bd9a49dca84d213cb299 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.ts @@ -0,0 +1,35 @@ +import { CommandResource } from '@alfa-client/command-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { ZustaendigeStelleModule } from '@alfa-client/zustaendige-stelle'; +import { OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; +import { A11yModule } from '@angular/cdk/a11y'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { getUrl, ResourceUri } from '@ngxp/rest'; +import { CancelDialogButtonComponent } from '@ods/component'; +import { ForwardingButtonComponent } from './forwarding-button/forwarding-button.component'; +import { ForwardingItemInDialogComponent } from './forwarding-item/forwarding-item.component'; + +@Component({ + selector: 'alfa-forwarding-dialog', + standalone: true, + imports: [ + A11yModule, + CancelDialogButtonComponent, + ReactiveFormsModule, + ZustaendigeStelleModule, + ForwardingButtonComponent, + ForwardingItemInDialogComponent, + ], + templateUrl: './forwarding-dialog.component.html', +}) +export class ForwardingDialogComponent { + @Input() selectedSearchResult: OrganisationsEinheitResource; + @Input() forwardCommandStateResource: StateResource<CommandResource>; + + @Output() forward: EventEmitter<ResourceUri> = new EventEmitter(); + + public onForwarding(): void { + this.forward.emit(getUrl(this.selectedSearchResult)); + } +} diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..bd825b7ca43ad8dbb31580050274303e9bd26333 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.html @@ -0,0 +1,7 @@ +<ods-button + (clickEmitter)="onClick()" + text="Ändern" + variant="outline" + dataTestId="forwarding-item-change-button" + data-test-id="forwarding-item-change-button-container" +/> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..49e50eaa845262e74914cd7f4717c66e549ca924 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.spec.ts @@ -0,0 +1,53 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { dispatchEventFromFixture, mock, Mock, MockEvent } from '@alfa-client/test-utils'; +import { OrganisationsEinheitService, ZUSTAENDIGE_STELLE_SERVICE } from '@alfa-client/zustaendige-stelle-shared'; +import { ButtonComponent } from '@ods/system'; +import { MockComponent } from 'ng-mocks'; +import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test'; +import { ForwardingItemChangeButtonContainerComponent } from './forwarding-item-change-button-container.component'; + +describe('ForwardingItemChangeButtonContainerComponent', () => { + let component: ForwardingItemChangeButtonContainerComponent; + let fixture: ComponentFixture<ForwardingItemChangeButtonContainerComponent>; + + const buttonContainer: string = getDataTestIdOf('forwarding-item-change-button-container'); + + let service: Mock<OrganisationsEinheitService>; + + beforeEach(() => { + service = mock(OrganisationsEinheitService); + + TestBed.configureTestingModule({ + imports: [ForwardingItemChangeButtonContainerComponent], + declarations: [MockComponent(ButtonComponent)], + providers: [{ provide: ZUSTAENDIGE_STELLE_SERVICE, useValue: service }], + }).compileComponents(); + + fixture = TestBed.createComponent(ForwardingItemChangeButtonContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('button', () => { + it('should call onClick on button click', () => { + component.onClick = jest.fn(); + + dispatchEventFromFixture(fixture, buttonContainer, MockEvent.CLICK); + + expect(component.onClick).toHaveBeenCalled(); + }); + }); + + describe('onClick', () => { + it('should clear selected result', () => { + component.onClick(); + + expect(service.clearSelectedResult).toHaveBeenCalled(); + }); + }); +}); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a0ca9ccbe7730e0eb8d54ef013b17d12719b0ec --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item-change-button-container/forwarding-item-change-button-container.component.ts @@ -0,0 +1,17 @@ +import { OrganisationsEinheitService, ZUSTAENDIGE_STELLE_SERVICE } from '@alfa-client/zustaendige-stelle-shared'; +import { Component, inject } from '@angular/core'; +import { ButtonComponent } from '@ods/system'; + +@Component({ + selector: 'alfa-forwarding-item-change-button-container', + standalone: true, + imports: [ButtonComponent], + templateUrl: './forwarding-item-change-button-container.component.html', +}) +export class ForwardingItemChangeButtonContainerComponent { + private readonly organisationsEinheitService = inject(ZUSTAENDIGE_STELLE_SERVICE) as OrganisationsEinheitService; + + public onClick(): void { + this.organisationsEinheitService.clearSelectedResult(); + } +} diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.html new file mode 100644 index 0000000000000000000000000000000000000000..bd41e43d6a1c75eb03bca208ca264c7553aaa5a8 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.html @@ -0,0 +1,3 @@ +<ods-forwarding-item [label]="organisationsEinheitResource.name" [address]="organisationsEinheitResource.anschrift | anschriftToString" > + <alfa-forwarding-item-change-button-container /> +</ods-forwarding-item> \ No newline at end of file diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8ffb55d8ab7ff80771ddd8cdd2d1e6611dbe459 --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.spec.ts @@ -0,0 +1,42 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { getMockComponent } from '@alfa-client/test-utils'; +import { Anschrift, OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; +import { ForwardingItemComponent } from '@ods/system'; +import { MockComponent } from 'ng-mocks'; +import { createOrganisationsEinheitResource } from '../../../../../../zustaendige-stelle-shared/test/organisations-einheit'; +import { ForwardingItemChangeButtonContainerComponent } from './forwarding-item-change-button-container/forwarding-item-change-button-container.component'; +import { ForwardingItemInDialogComponent } from './forwarding-item.component'; + +describe('ForwardingDialogForwardingItemComponent', () => { + let component: ForwardingItemInDialogComponent; + let fixture: ComponentFixture<ForwardingItemInDialogComponent>; + + const organisationsEinheitResource: OrganisationsEinheitResource = createOrganisationsEinheitResource(); + const anschrift: Anschrift = organisationsEinheitResource.anschrift; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ForwardingItemInDialogComponent], + declarations: [MockComponent(ForwardingItemChangeButtonContainerComponent), MockComponent(ForwardingItemComponent)], + }).compileComponents(); + + fixture = TestBed.createComponent(ForwardingItemInDialogComponent); + component = fixture.componentInstance; + component.organisationsEinheitResource = organisationsEinheitResource; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('forwarding item', () => { + it('should exist with input', () => { + const forwardingItem: ForwardingItemComponent = getMockComponent(fixture, ForwardingItemComponent); + + expect(forwardingItem.label).toBe(organisationsEinheitResource.name); + expect(forwardingItem.address).toBe(`${anschrift.strasse} ${anschrift.hausnummer}, ${anschrift.plz} ${anschrift.ort}`); + }); + }); +}); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..9828f682d8860e851cc15cde31fef24150120f4a --- /dev/null +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-item/forwarding-item.component.ts @@ -0,0 +1,14 @@ +import { AnschriftToStringPipe, OrganisationsEinheitResource } from '@alfa-client/zustaendige-stelle-shared'; +import { Component, Input } from '@angular/core'; +import { ForwardingItemComponent } from '@ods/system'; +import { ForwardingItemChangeButtonContainerComponent } from './forwarding-item-change-button-container/forwarding-item-change-button-container.component'; + +@Component({ + selector: 'alfa-forwarding-item-in-dialog', + standalone: true, + imports: [ForwardingItemChangeButtonContainerComponent, AnschriftToStringPipe, ForwardingItemComponent], + templateUrl: './forwarding-item.component.html', +}) +export class ForwardingItemInDialogComponent { + @Input() organisationsEinheitResource: OrganisationsEinheitResource; +} diff --git a/alfa-client/libs/forwarding/src/lib/forwarding.module.ts b/alfa-client/libs/forwarding/src/lib/forwarding.module.ts index 973cf7b7a1603273e98ca30ee0bd511c57bb9cc1..387ac14e53f0810db203dcbe110b33cabe8b5ab0 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding.module.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding.module.ts @@ -24,22 +24,17 @@ import { CommandSharedModule } from '@alfa-client/command-shared'; import { ForwardingSharedModule } from '@alfa-client/forwarding-shared'; import { FormatDateWithTimePipe, HasLinkPipe, ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared'; -import { - ExpansionPanelComponent, - OzgcloudStrokedButtonWithSpinnerComponent, - OzgcloudTextEditorComponent, - SpinnerComponent, -} from '@alfa-client/ui'; +import { ExpansionPanelComponent, OzgcloudStrokedButtonWithSpinnerComponent, OzgcloudTextEditorComponent, SpinnerComponent, } from '@alfa-client/ui'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { MatIcon } from '@angular/material/icon'; -import { VorgangForwardFormComponent } from './vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-form/vorgang-forward-form.component'; -import { VorgangForwardFormularComponent } from './vorgang-forwarding-container/vorgang-forward-formular/vorgang-forward-formular.component'; -import { VorgangForwardingContainerComponent } from './vorgang-forwarding-container/vorgang-forwarding-container.component'; -import { VorgangForwardingInfoListComponent } from './vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info-list.component'; -import { VorgangForwardingInfoComponent } from './vorgang-forwarding-container/vorgang-forwarding-info-list/vorgang-forwarding-info/vorgang-forwarding-info.component'; -import { VorgangForwardZustellenContainerComponent } from './vorgang-forwarding-zustellen-container/vorgang-forward-zustellen-container.component'; +import { ForwardingByEmailContainerComponent } from './forwarding-by-email-container/forwarding-by-email-container.component'; +import { ForwardingByEmailFormComponent } from './forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-form/forwarding-by-email-form.component'; +import { ForwardingByEmailFormularComponent } from './forwarding-by-email-container/forwarding-by-email-formular/forwarding-by-email-formular.component'; +import { ForwardingByEmailInfoListComponent } from './forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info-list.component'; +import { ForwardingByEmailInfoComponent } from './forwarding-by-email-container/forwarding-by-email-info-list/forwarding-by-email-info/forwarding-by-email-info.component'; +import { ForwardingByEmailZustellenContainerComponent } from './forwarding-by-email-zustellen-container/forwarding-by-email-zustellen-container.component'; @NgModule({ imports: [ @@ -57,15 +52,15 @@ import { VorgangForwardZustellenContainerComponent } from './vorgang-forwarding- ReactiveFormsModule, ], declarations: [ - VorgangForwardZustellenContainerComponent, - VorgangForwardingContainerComponent, - VorgangForwardFormularComponent, - VorgangForwardingInfoComponent, - VorgangForwardingInfoListComponent, - VorgangForwardFormularComponent, - VorgangForwardZustellenContainerComponent, - VorgangForwardFormComponent, + ForwardingByEmailZustellenContainerComponent, + ForwardingByEmailContainerComponent, + ForwardingByEmailFormularComponent, + ForwardingByEmailInfoComponent, + ForwardingByEmailInfoListComponent, + ForwardingByEmailFormularComponent, + ForwardingByEmailZustellenContainerComponent, + ForwardingByEmailFormComponent, ], - exports: [VorgangForwardingContainerComponent], + exports: [ForwardingByEmailContainerComponent], }) export class ForwardingModule {} diff --git a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts index 600a9dc3f5573f1eec31c8f9c75b4131bdcb42ea..e791715114f5878ddd0b44f26a5f8457675035a7 100644 --- a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts +++ b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts @@ -22,8 +22,19 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { BinaryFileListResource, BinaryFileService } from '@alfa-client/binary-file-shared'; -import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; -import { createEmptyStateResource, EMPTY_STRING, isNotEmpty, StateResource } from '@alfa-client/tech-shared'; +import { CommandOrder, tapOnCommandSuccessfullyDone, CommandResource, CommandService, CreateCommand, isDone } from '@alfa-client/command-shared'; +import { NavigationService } from '@alfa-client/navigation-shared'; +import { + createEmptyStateResource, + createStateResource, + doIfLoadingRequired, + EMPTY_STRING, + isLoaded, + isNotEmpty, + isNotNull, + StateResource, +} from '@alfa-client/tech-shared'; +import { VorgangResource, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Injectable } from '@angular/core'; import { getUrl, hasLink, ResourceUri } from '@ngxp/rest'; import { BehaviorSubject, combineLatest, map, Observable, of } from 'rxjs'; @@ -34,8 +45,14 @@ import { Kommentar, KOMMENTAR_UPLOADED_ATTACHMENTS, KommentarListResource, Komme @Injectable() export class KommentarService { + readonly kommentarList$: BehaviorSubject<StateResource<KommentarListResource>> = new BehaviorSubject( + createEmptyStateResource<KommentarListResource>(), + ); readonly formularVisibility$: BehaviorSubject<boolean> = new BehaviorSubject(false); - readonly _currentlyEdited$: BehaviorSubject<ResourceUri> = new BehaviorSubject(''); + readonly _currentlyEdited$: BehaviorSubject<ResourceUri> = new BehaviorSubject(EMPTY_STRING); + + + shouldReload: boolean = false; constructor( private binaryFileService: BinaryFileService, @@ -79,7 +96,7 @@ export class KommentarService { this.kommentarListResourceService.refresh(); } - getAttachments(kommentar: KommentarResource): Observable<StateResource<BinaryFileListResource>> { + _getAttachments(kommentar: KommentarResource): Observable<StateResource<BinaryFileListResource>> { if (hasLink(kommentar, KommentarLinkRel.ATTACHMENTS)) { return this.binaryFileService.getFiles(kommentar, KommentarLinkRel.ATTACHMENTS); } diff --git a/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.spec.ts b/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.spec.ts index 9753cc7fa2dafde144f13618d84c55a24b1bc1a3..4470d7d9b7d85481c65e909ef9e12fef63b59194 100644 --- a/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.spec.ts +++ b/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.spec.ts @@ -102,7 +102,7 @@ describe('KommentarFormComponent', () => { const patchSpy = jest.spyOn(KommentarFormService.prototype, 'patch').mockImplementation(); const kommentarResource = createKommentarResource([KommentarLinkRel.ATTACHMENTS]); component.kommentar = kommentarResource; - kommentarService.getAttachments.mockReturnValue(of(createStateResource(createBinaryFileListResource()))); + kommentarService._getAttachments.mockReturnValue(of(createStateResource(createBinaryFileListResource()))); component.ngOnChanges(); @@ -111,7 +111,7 @@ describe('KommentarFormComponent', () => { it('should load attachments', (done) => { component.kommentar = createKommentarResource([KommentarLinkRel.ATTACHMENTS]); - kommentarService.getAttachments.mockReturnValue(of(createStateResource(createBinaryFileListResource()))); + kommentarService._getAttachments.mockReturnValue(of(createStateResource(createBinaryFileListResource()))); component.ngOnChanges(); @@ -124,11 +124,11 @@ describe('KommentarFormComponent', () => { it('should call kommentarService', () => { const kommentarResource = createKommentarResource([KommentarLinkRel.ATTACHMENTS]); component.kommentar = kommentarResource; - kommentarService.getAttachments.mockReturnValue(of(createStateResource(createBinaryFileListResource()))); + kommentarService._getAttachments.mockReturnValue(of(createStateResource(createBinaryFileListResource()))); component.ngOnChanges(); - expect(kommentarService.getAttachments).toHaveBeenCalledWith(kommentarResource); + expect(kommentarService._getAttachments).toHaveBeenCalledWith(kommentarResource); }); describe('submit', () => { diff --git a/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.ts b/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.ts index 0566d0f19efcc3e09aff3d5a726465eae21371d9..851cf4590f31bd8877ee22a935ca569c804c6aa1 100644 --- a/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.ts +++ b/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar-form.component.ts @@ -23,7 +23,14 @@ */ import { BinaryFileListLinkRel, BinaryFileResource } from '@alfa-client/binary-file-shared'; import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; -import { KOMMENTAR_UPLOADED_ATTACHMENTS, KommentarLinkRel, KommentarListLinkRel, KommentarListResource, KommentarResource, KommentarService, } from '@alfa-client/kommentar-shared'; +import { + KOMMENTAR_UPLOADED_ATTACHMENTS, + KommentarLinkRel, + KommentarListLinkRel, + KommentarListResource, + KommentarResource, + KommentarService, +} from '@alfa-client/kommentar-shared'; import { createEmptyStateResource, getEmbeddedResources, StateResource } from '@alfa-client/tech-shared'; import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; import { isNil } from 'lodash-es'; @@ -66,7 +73,7 @@ export class KommentarFormComponent implements OnChanges { private updateAttachments() { this.attachments$ = this.kommentarService - .getAttachments(this.kommentar) + ._getAttachments(this.kommentar) .pipe(map((stateResource) => getEmbeddedResources<BinaryFileResource>(stateResource, BinaryFileListLinkRel.FILE_LIST))); } diff --git a/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-list-in-vorgang/kommentar-list-item-in-vorgang/kommentar-list-item-in-vorgang.component.html b/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-list-in-vorgang/kommentar-list-item-in-vorgang/kommentar-list-item-in-vorgang.component.html index e856036f76052c80ba99a7311b4c12933ed5b1be..74f9254e1d5d892bb4d7af0c3cf6099230772c63 100644 --- a/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-list-in-vorgang/kommentar-list-item-in-vorgang/kommentar-list-item-in-vorgang.component.html +++ b/alfa-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-list-in-vorgang/kommentar-list-item-in-vorgang/kommentar-list-item-in-vorgang.component.html @@ -32,9 +32,8 @@ *ngIf="kommentar | hasLink: KommentarLinkRel.CREATED_BY" [kommentar]="kommentar" data-test-class="kommentar-created-by" - > - </alfa-user-profile-in-kommentar-container> - <span data-test-id="kommentar-created-at" class="date text-sm"> + ></alfa-user-profile-in-kommentar-container> + <span data-test-class="kommentar-created-at" class="date text-sm"> {{ kommentar.createdAt | formatDateWithTimePipe: false }} </span> </div> @@ -50,11 +49,11 @@ </div> <alfa-kommentar-form - *ngIf="editMode " + *ngIf="editMode" data-test-id="kommentar-list-item-form" [kommentar]="kommentar" [kommentarListStateResource]="kommentarListStateResource" - (cancel)="editMode=false" + (cancel)="editMode = false" class="edit-text" > </alfa-kommentar-form> diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts index 678219f735fd5882a763a535687688c630bd5045..9149471c8d22327948bb18ae382aeeeb45cafe32 100644 --- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts +++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts @@ -35,7 +35,13 @@ import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; import { createCommandErrorResource, createCommandResource } from 'libs/command-shared/test/command'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { BehaviorSubject, of } from 'rxjs'; -import { createPostfachFeatures, createPostfachMail, createPostfachMailListResource, createPostfachMailResource, createPostfachSettings, } from '../../test/postfach'; +import { + createPostfachFeatures, + createPostfachMail, + createPostfachMailListResource, + createPostfachMailResource, + createPostfachSettings, +} from '../../test/postfach'; import { PostfachFacade } from './+state/postfach.facade'; import { PostfachMailLinkRel, PostfachMailListLinkRel } from './postfach.linkrel'; import { PostfachMessages } from './postfach.message'; @@ -50,7 +56,7 @@ describe('PostfachService', () => { let repository: Mock<PostfachRepository>; const commandService: Mock<CommandService> = mock(CommandService); const navigationService: Mock<NavigationService> = mock(NavigationService); - const vorgangService: Mock<VorgangService> = mock(VorgangService); + let vorgangService: Mock<VorgangService>; const snackbarService: Mock<SnackBarService> = mock(SnackBarService); const dialog: Mock<MatDialog> = <Mock<MatDialog>>{ closeAll: jest.fn() }; const postfachFacade: Mock<PostfachFacade> = mock(PostfachFacade); @@ -58,7 +64,14 @@ describe('PostfachService', () => { const urlChangedParams = {}; + const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource(); + const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = createStateResource(vorgang); + beforeEach(() => { + vorgangService = { + ...mock(VorgangService), + getVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)), + }; navigationService.urlChanged = jest.fn(); navigationService.urlChanged.mockReturnValue(of(urlChangedParams)); @@ -114,7 +127,7 @@ describe('PostfachService', () => { describe('reload postfach list', () => { beforeEach(() => { - service.refreshPostfachMailList = jest.fn(); + service._refreshPostfachMailList = jest.fn(); }); it('should execute on command is done', () => { @@ -125,7 +138,7 @@ describe('PostfachService', () => { service.sendMail(postfachMail); - expect(service.refreshPostfachMailList).toHaveBeenCalledWith(commandStateResource); + expect(service._refreshPostfachMailList).toHaveBeenCalledWith(commandStateResource); }); it('should not execute on pending command', () => { @@ -133,7 +146,7 @@ describe('PostfachService', () => { service.sendMail(postfachMail); - expect(service.refreshPostfachMailList).not.toHaveBeenCalled(); + expect(service._refreshPostfachMailList).not.toHaveBeenCalled(); }); }); }); @@ -145,13 +158,13 @@ describe('PostfachService', () => { const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); it('should call doSendNachricht', () => { - service.doSendNachricht = jest.fn(); + service._doSendNachricht = jest.fn(); commandService.createCommand.mockReturnValue(of(commandStateResource)); vorgangService.getPendingSendPostfachMailCommand.mockReturnValue(of(commandStateResource)); service.sendExistingMail(postfachNachricht, nachricht); - expect(service.doSendNachricht).toHaveBeenCalledWith( + expect(service._doSendNachricht).toHaveBeenCalledWith( postfachNachricht, PostfachMailLinkRel.SEND, createSendPostfachMailCommand(nachricht), @@ -163,7 +176,7 @@ describe('PostfachService', () => { const postfachMailResource: PostfachMailResource = createPostfachMailResource(); beforeEach(() => { - service.handleSendPostfachMailIsDone = jest.fn(); + service._handleSendPostfachMailIsDone = jest.fn(); commandService.createCommand.mockReturnValue(of(createStateResource(createCommandResource()))); vorgangService.getPendingSendPostfachMailCommand.mockReturnValue(of(createStateResource(createCommandResource()))); @@ -191,7 +204,7 @@ describe('PostfachService', () => { commandService.createCommand.mockReturnValue(of(createStateResource(createCommandResource([CommandLinkRel.UPDATE])))); service.resendMail(postfachMailResource); - expect(service.handleSendPostfachMailIsDone).not.toHaveBeenCalled(); + expect(service._handleSendPostfachMailIsDone).not.toHaveBeenCalled(); }); it('should call handleSendPostfachMailIsDone if command is done', () => { @@ -202,7 +215,7 @@ describe('PostfachService', () => { service.resendMail(postfachMailResource); - expect(service.handleSendPostfachMailIsDone).toHaveBeenCalledWith(commandResponse); + expect(service._handleSendPostfachMailIsDone).toHaveBeenCalledWith(commandResponse); }); }); @@ -210,25 +223,25 @@ describe('PostfachService', () => { const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); beforeEach(() => { - service.commandIsDone = jest.fn(); + service._commandIsDone = jest.fn(); }); it('should call vorgang service', () => { - service.handleSendNachrichtCommand(commandStateResource); + service._handleSendNachrichtCommand(commandStateResource); expect(vorgangService.setPendingSendPostfachMailCommand).toHaveBeenCalledWith(commandStateResource); }); it('should call commandIsDone', () => { - service.handleSendNachrichtCommand(commandStateResource); + service._handleSendNachrichtCommand(commandStateResource); - expect(service.commandIsDone).toHaveBeenCalledWith(commandStateResource); + expect(service._commandIsDone).toHaveBeenCalledWith(commandStateResource); }); }); describe('commandIsDone', () => { beforeEach(() => { - service.handleSendPostfachMailIsDone = jest.fn(); + service._handleSendPostfachMailIsDone = jest.fn(); }); it('should call handleSendPostfachMailIsDone', () => { @@ -236,9 +249,9 @@ describe('PostfachService', () => { createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), ); - service.commandIsDone(commandStateResource); + service._commandIsDone(commandStateResource); - expect(service.handleSendPostfachMailIsDone).toHaveBeenCalledWith(commandStateResource); + expect(service._handleSendPostfachMailIsDone).toHaveBeenCalledWith(commandStateResource); }); describe('on command is done', () => { @@ -248,7 +261,7 @@ describe('PostfachService', () => { errorMessage: null, }); - service.commandIsDone(commandStateResource); + service._commandIsDone(commandStateResource); expect(snackbarService.show).toHaveBeenCalledWith(commandStateResource.resource, PostfachMessages.SEND_SUCCESSFUL); }); @@ -260,7 +273,7 @@ describe('PostfachService', () => { createCommandErrorResource([CommandLinkRel.EFFECTED_RESOURCE]), ); - service.commandIsDone(commandStateResource); + service._commandIsDone(commandStateResource); expect(snackbarService.showError).toHaveBeenCalledWith(PostfachMessages.SEND_FAILED); }); @@ -269,58 +282,58 @@ describe('PostfachService', () => { describe('listenToNavigation', () => { it('should call usnsubcribeToNavigation', () => { - service.listenToNavigation(); + service._listenToNavigation(); expect(navigationService.urlChanged).toHaveBeenCalled(); }); it('should call navigation service', () => { - service.unsubscribeToNavigation = jest.fn(); + service._unsubscribeToNavigation = jest.fn(); - service.listenToNavigation(); + service._listenToNavigation(); - expect(service.unsubscribeToNavigation).toHaveBeenCalled(); + expect(service._unsubscribeToNavigation).toHaveBeenCalled(); }); it('should call onNavigation', () => { - service.onNavigation = jest.fn(); + service._onNavigation = jest.fn(); - service.listenToNavigation(); + service._listenToNavigation(); - expect(service.onNavigation).toHaveBeenCalledWith(urlChangedParams); + expect(service._onNavigation).toHaveBeenCalledWith(urlChangedParams); }); }); describe('onNavigation', () => { describe('to vorgang list', () => { beforeEach(() => { - service.setPollingFalse = jest.fn(); - service.clearPostfachMailList = jest.fn(); - service.unsubscribe = jest.fn(); + service._setPollingFalse = jest.fn(); + service._clearPostfachMailList = jest.fn(); + service._unsubscribe = jest.fn(); }); it('should set polling false', () => { - service.onNavigation({}); + service._onNavigation({}); - expect(service.setPollingFalse).toHaveBeenCalled(); + expect(service._setPollingFalse).toHaveBeenCalled(); }); it('should call clearPostfachMailList', () => { - service.onNavigation({}); + service._onNavigation({}); - expect(service.clearPostfachMailList).toHaveBeenCalled(); + expect(service._clearPostfachMailList).toHaveBeenCalled(); }); it('should call closeOpenDialogs', () => { - service.onNavigation({}); + service._onNavigation({}); expect(dialog.closeAll).toHaveBeenCalled(); }); it('should call unsubscribe', () => { - service.onNavigation({}); + service._onNavigation({}); - expect(service.unsubscribe).toHaveBeenCalled(); + expect(service._unsubscribe).toHaveBeenCalled(); }); }); @@ -328,7 +341,7 @@ describe('PostfachService', () => { it('should set postfach nachrichten list to reload', () => { service.postfachMailList$.next(createEmptyStateResource()); - service.onNavigation({ vorgangWithEingangUrl: 'X' }); + service._onNavigation({ vorgangWithEingangUrl: 'X' }); expect(service.postfachMailList$.value.reload).toEqual(true); }); @@ -336,12 +349,12 @@ describe('PostfachService', () => { describe('to postfach page', () => { beforeEach(() => { - service.resetHasNewPostfachNachrichten = jest.fn(); + service._resetHasNewPostfachNachrichten = jest.fn(); navigationService.isPostfachPage.mockReturnValue(true); }); it('should call navigationService', () => { - service.onNavigation({}); + service._onNavigation({}); expect(navigationService.isPostfachPage).toHaveBeenCalled(); }); @@ -349,17 +362,17 @@ describe('PostfachService', () => { it('should reset hasNewPostfachNachrichten', () => { navigationService.isPostfachPage.mockReturnValue(true); - service.onNavigation({}); + service._onNavigation({}); - expect(service.resetHasNewPostfachNachrichten).toHaveBeenCalled(); + expect(service._resetHasNewPostfachNachrichten).toHaveBeenCalled(); }); }); }); describe('getPendingSendPostfachMailCommand', () => { beforeEach(() => { - service.unsubscribe = jest.fn(); - service.pollSendPostfachMailCommand = jest.fn(); + service._unsubscribe = jest.fn(); + service._pollSendPostfachMailCommand = jest.fn(); commandService.pollCommand.mockReturnValue(of(createStateResource(createCommandResource()))); vorgangService.getPendingSendPostfachMailCommand.mockReturnValue(of(createStateResource(createCommandResource()))); @@ -377,12 +390,12 @@ describe('PostfachService', () => { it('should call doResetHasNewPostfachNachrichten', () => { service.getPostfachMailListByVorgang = jest.fn(); - service.doResetHasNewPostfachNachrichten = jest.fn(); + service._doResetHasNewPostfachNachrichten = jest.fn(); (<any>service.getPostfachMailListByVorgang).mockReturnValue(of(postfachListNachrichtenResource)); - service.resetHasNewPostfachNachrichten(); + service._resetHasNewPostfachNachrichten(); - expect(service.doResetHasNewPostfachNachrichten).toHaveBeenCalled(); + expect(service._doResetHasNewPostfachNachrichten).toHaveBeenCalled(); }); }); @@ -398,7 +411,7 @@ describe('PostfachService', () => { }); it('should call repository if link exists', () => { - service.doResetHasNewPostfachNachrichten(); + service._doResetHasNewPostfachNachrichten(); expect(repository.resetHasNewPostfachNachrichten).toHaveBeenCalledWith(postfachNachrichtenListResource); }); @@ -408,7 +421,7 @@ describe('PostfachService', () => { const postfachNachrichtenListResource: PostfachMailListResource = createPostfachMailListResource(); service.postfachMailList$.next(createStateResource(postfachNachrichtenListResource)); - service.doResetHasNewPostfachNachrichten(); + service._doResetHasNewPostfachNachrichten(); expect(repository.resetHasNewPostfachNachrichten).not.toHaveBeenCalled(); }); @@ -419,16 +432,23 @@ describe('PostfachService', () => { beforeEach(() => { repository.loadPostfachMailList.mockReturnValue(of(postfachMailList)); - service.setPostfachMailListLoading = jest.fn(); - service.setPostfachMailList = jest.fn(); + service._setPostfachMailListLoading = jest.fn(); + service._setPostfachMailList = jest.fn(); vorgangService.getVorgangWithEingang.mockReturnValue(of(createStateResource(createVorgangWithEingangResource()))); service.postfachMailList$.next(createEmptyStateResource()); + service._refreshVorgangSubscription = jest.fn(); + }); + + it('should call refresh vorgang subscription', () => { + service.getPostfachMailListByVorgang(); + + expect(service._refreshVorgangSubscription).toHaveBeenCalled(); }); it('should set loading to true', () => { service.getPostfachMailListByVorgang(); - expect(service.setPostfachMailListLoading).toHaveBeenCalled(); + expect(service._setPostfachMailListLoading).toHaveBeenCalled(); }); it('should call vorgang service', () => { @@ -446,7 +466,7 @@ describe('PostfachService', () => { it('should set loading to false', () => { service.getPostfachMailListByVorgang(); - expect(service.setPostfachMailList).toHaveBeenCalled(); + expect(service._setPostfachMailList).toHaveBeenCalled(); }); }); @@ -454,28 +474,28 @@ describe('PostfachService', () => { const stateResource: StateResource<CommandResource> = createStateResource(createCommandResource()); beforeEach(() => { - service.setPollingFalse = jest.fn(); - service.setPostfachMailList = jest.fn(); + service._setPollingFalse = jest.fn(); + service._setPostfachMailList = jest.fn(); commandService.getEffectedResource.mockReturnValue(of(createCommandResource())); }); it('should call command service to get effected resource', () => { - service.handleSendPostfachMailIsDone(stateResource); + service._handleSendPostfachMailIsDone(stateResource); expect(commandService.getEffectedResource).toHaveBeenCalledWith(stateResource.resource); }); it('should set postfachMailList', () => { - service.handleSendPostfachMailIsDone(stateResource); + service._handleSendPostfachMailIsDone(stateResource); - expect(service.setPostfachMailList).toHaveBeenCalled(); + expect(service._setPostfachMailList).toHaveBeenCalled(); }); it('should set polling to false', () => { - service.handleSendPostfachMailIsDone(stateResource); + service._handleSendPostfachMailIsDone(stateResource); - expect(service.setPollingFalse).toHaveBeenCalled(); + expect(service._setPollingFalse).toHaveBeenCalled(); }); }); @@ -548,9 +568,68 @@ describe('PostfachService', () => { }); it('should clear uploaded files', () => { - service.closeOpenDialogs(); + service._closeOpenDialogs(); expect(service.clearUploadedFiles).toHaveBeenCalled(); }); }); + + describe('listen to vorgang change', () => { + beforeEach(() => { + service._handleVorgangChange = jest.fn(); + }); + + it('should call vorgang service to get vorgang with eingang', () => { + service._listenToVorgangChange(); + + expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled(); + }); + + it('should call handle vorgang change', () => { + service._listenToVorgangChange(); + + expect(service._handleVorgangChange).toHaveBeenCalledWith(vorgangWithEingangStateResource); + }); + }); + + describe('handle vorgang change', () => { + it('should set reload flag if list is loaded and state resource is loading', () => { + service.shouldReload = false; + service.postfachMailList$.next(createStateResource(createPostfachMailListResource())); + + service._handleVorgangChange({ ...vorgangWithEingangStateResource, loading: true }); + + expect(service.shouldReload).toBeTruthy(); + }); + + it('should set reload flag if list is loaded and state resource is reloading', () => { + service.postfachMailList$.next(createStateResource(createPostfachMailListResource())); + service.shouldReload = false; + + service._handleVorgangChange({ ...vorgangWithEingangStateResource, reload: true }); + + expect(service.shouldReload).toBeTruthy(); + }); + + describe('on setted reload flag', () => { + beforeEach(() => { + service._setPostfachMailOnReload = jest.fn(); + service.shouldReload = true; + }); + + describe('and loaded vorgang resource', () => { + it('should call set kommentar list reload', () => { + service._handleVorgangChange(vorgangWithEingangStateResource); + + expect(service._setPostfachMailOnReload).toHaveBeenCalled(); + }); + + it('and loaded vorgang resource should call set kommentar list reload', () => { + service._handleVorgangChange(vorgangWithEingangStateResource); + + expect(service.shouldReload).toBeFalsy(); + }); + }); + }); + }); }); diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts index e39019766d5f873a246643dec3c951cc4e2efd39..f650edd3f4c598a309482fe95658930794deaae8 100644 --- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts +++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts @@ -23,11 +23,26 @@ */ import { POSTFACH_NACHRICHT_UPLOADED_ATTACHMENTS } from '@admin-client/postfach-shared'; import { BinaryFileService } from '@alfa-client/binary-file-shared'; -import { CommandResource, CommandService, doIfCommandIsDone, hasCommandError, isDone, isPending, } from '@alfa-client/command-shared'; +import { + CommandResource, + CommandService, + doIfCommandIsDone, + hasCommandError, + isDone, + isPending, +} from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { createEmptyStateResource, createStateResource, doIfLoadingRequired, isNotNull, isNotUndefined, StateResource, } from '@alfa-client/tech-shared'; +import { + createEmptyStateResource, + createStateResource, + doIfLoadingRequired, + isLoaded, + isNotNull, + isNotUndefined, + StateResource, +} from '@alfa-client/tech-shared'; import { SnackBarService } from '@alfa-client/ui'; -import { VorgangResource, VorgangService } from '@alfa-client/vorgang-shared'; +import { VorgangResource, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { inject, Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Params } from '@angular/router'; @@ -38,7 +53,14 @@ import { first, map, take, tap } from 'rxjs/operators'; import { PostfachFacade } from './+state/postfach.facade'; import { PostfachMailLinkRel, PostfachMailListLinkRel } from './postfach.linkrel'; import { PostfachMessages } from './postfach.message'; -import { CreatePostfachMailCommand, PostfachFeatures, PostfachMail, PostfachMailListResource, PostfachMailResource, PostfachSettings, } from './postfach.model'; +import { + CreatePostfachMailCommand, + PostfachFeatures, + PostfachMail, + PostfachMailListResource, + PostfachMailResource, + PostfachSettings, +} from './postfach.model'; import { PostfachRepository } from './postfach.repository'; import { createResendPostfachMailCommand, createSendPostfachMailCommand } from './postfach.util'; @@ -65,12 +87,17 @@ export class PostfachService { private vorgangSubscription: Subscription; private postfachNachrichtenListSubscription: Subscription; + private vorgangChangeSubscription: Subscription; + + shouldReload: boolean = false; + constructor() { - this.listenToNavigation(); + this._listenToNavigation(); + this._listenToVorgangChange(); } public sendMail(postfachMail: PostfachMail): Observable<StateResource<CommandResource>> { - return this.doSendNachricht( + return this._doSendNachricht( this.postfachMailList$.value.resource, PostfachMailListLinkRel.SEND_POSTFACH_MAIL, createSendPostfachMailCommand(postfachMail), @@ -81,18 +108,18 @@ export class PostfachService { postfachMailResource: PostfachMailResource, postfachMail: PostfachMail, ): Observable<StateResource<CommandResource>> { - return this.doSendNachricht(postfachMailResource, PostfachMailLinkRel.SEND, createSendPostfachMailCommand(postfachMail)); + return this._doSendNachricht(postfachMailResource, PostfachMailLinkRel.SEND, createSendPostfachMailCommand(postfachMail)); } public resendMail(postfachMailResource: PostfachMailResource): Observable<StateResource<CommandResource>> { - return this.doSendNachricht( + return this._doSendNachricht( postfachMailResource, PostfachMailLinkRel.RESEND_POSTFACH_MAIL, createResendPostfachMailCommand(), ); } - doSendNachricht( + _doSendNachricht( resource: Resource, linkRel: string, command: CreatePostfachMailCommand, @@ -102,20 +129,20 @@ export class PostfachService { this.commandService .createCommand(resource, linkRel, command) .pipe(first()) - .subscribe((createdCommand) => this.handleSendNachrichtCommand(createdCommand)); + .subscribe((createdCommand) => this._handleSendNachrichtCommand(createdCommand)); return this.getPendingSendPostfachMailCommand(); } - handleSendNachrichtCommand(commandStateResource: StateResource<CommandResource>): void { + _handleSendNachrichtCommand(commandStateResource: StateResource<CommandResource>): void { this.vorgangService.setPendingSendPostfachMailCommand(commandStateResource); - this.commandIsDone(commandStateResource); + this._commandIsDone(commandStateResource); } - commandIsDone(commandStateResource: StateResource<CommandResource>): void { + _commandIsDone(commandStateResource: StateResource<CommandResource>): void { doIfCommandIsDone(commandStateResource.resource, () => { this.showSnackbar(commandStateResource.resource); - this.handleSendPostfachMailIsDone(commandStateResource); + this._handleSendPostfachMailIsDone(commandStateResource); }); } @@ -130,79 +157,79 @@ export class PostfachService { public getPendingSendPostfachMailCommand(): Observable<StateResource<CommandResource>> { return this.vorgangService .getPendingSendPostfachMailCommand() - .pipe(map((pendingCommand) => this.pollSendPostfachMailCommand(pendingCommand))); + .pipe(map((pendingCommand) => this._pollSendPostfachMailCommand(pendingCommand))); } - listenToNavigation(): void { - this.unsubscribeToNavigation(); - this.navigationSubscription = this.navigationService.urlChanged().subscribe((params) => this.onNavigation(params)); + _listenToNavigation(): void { + this._unsubscribeToNavigation(); + this.navigationSubscription = this.navigationService.urlChanged().subscribe((params) => this._onNavigation(params)); } - unsubscribeToNavigation(): void { + _unsubscribeToNavigation(): void { if (!isNil(this.navigationSubscription)) this.navigationSubscription.unsubscribe(); } - onNavigation(params: Params): void { + _onNavigation(params: Params): void { if (NavigationService.isVorgangListPage(params)) { - this.setPollingFalse(); - this.clearPostfachMailList(); - this.closeOpenDialogs(); - this.unsubscribe(); + this._setPollingFalse(); + this._clearPostfachMailList(); + this._closeOpenDialogs(); + this._unsubscribe(); } if (NavigationService.isVorgangDetailPage(params, VorgangService.VORGANG_WITH_EINGANG_URL)) { - this.setPostfachMailOnReload(); + this._setPostfachMailOnReload(); } if (this.navigationService.isPostfachPage()) { - this.resetHasNewPostfachNachrichten(); + this._resetHasNewPostfachNachrichten(); } } - setPollingFalse(): void { + _setPollingFalse(): void { this.isPollSendPostachMail.next(false); } - clearPostfachMailList(): void { + _clearPostfachMailList(): void { this.postfachMailList$.next(createEmptyStateResource<PostfachMailListResource>()); } - closeOpenDialogs(): void { + _closeOpenDialogs(): void { this.dialog.closeAll(); this.clearUploadedFiles(); } - unsubscribe(): void { + _unsubscribe(): void { if (isNotUndefined(this.sendPostfachMailSubscription)) this.sendPostfachMailSubscription.unsubscribe(); if (isNotUndefined(this.loadPostfachMailSubscription)) this.loadPostfachMailSubscription.unsubscribe(); if (isNotUndefined(this.vorgangSubscription)) this.vorgangSubscription.unsubscribe(); } - setPostfachMailOnReload(): void { + _setPostfachMailOnReload(): void { this.postfachMailList$.next({ ...this.postfachMailList$.value, reload: true }); } - resetHasNewPostfachNachrichten(): void { + _resetHasNewPostfachNachrichten(): void { this.postfachNachrichtenListSubscription = this.getPostfachMailListByVorgang().subscribe((postfachNachrichtenList) => { if (isNotNull(postfachNachrichtenList.resource)) { setTimeout(() => this.postfachNachrichtenListSubscription.unsubscribe(), 0); - this.doResetHasNewPostfachNachrichten(); + this._doResetHasNewPostfachNachrichten(); } }); } - doResetHasNewPostfachNachrichten(): void { + _doResetHasNewPostfachNachrichten(): void { if (hasLink(this.postfachMailList$.value.resource, PostfachMailListLinkRel.RESET_HAS_NEW_POSTFACH_NACHRICHT)) { this.repository.resetHasNewPostfachNachrichten(this.postfachMailList$.value.resource).pipe(take(1)).subscribe(); } } - pollSendPostfachMailCommand(command: StateResource<CommandResource>): StateResource<CommandResource> { + _pollSendPostfachMailCommand(command: StateResource<CommandResource>): StateResource<CommandResource> { if (this.shouldPoll(command)) { - this.setPollingTrue(); + this._setPollingTrue(); this.sendPostfachMailSubscription = this.commandService.pollCommand(command.resource).subscribe((updatedStateResource) => { this.vorgangService.setPendingSendPostfachMailCommand(updatedStateResource); if (isDone(updatedStateResource.resource)) { - this.handleSendPostfachMailIsDone(updatedStateResource); + this._handleSendPostfachMailIsDone(updatedStateResource); setTimeout(() => this.sendPostfachMailSubscription.unsubscribe(), 0); } }); @@ -214,39 +241,40 @@ export class PostfachService { return command.loaded && isPending(command.resource) && !this.isPollSendPostachMail.value; } - setPollingTrue(): void { + _setPollingTrue(): void { this.isPollSendPostachMail.next(true); } - handleSendPostfachMailIsDone(updatedStateResource: StateResource<CommandResource>): void { - this.refreshPostfachMailList(updatedStateResource); - this.setPollingFalse(); + _handleSendPostfachMailIsDone(updatedStateResource: StateResource<CommandResource>): void { + this._refreshPostfachMailList(updatedStateResource); + this._setPollingFalse(); } - refreshPostfachMailList(updatedStateResource: StateResource<CommandResource>): void { - this.setPostfachMailListLoading(); - this.getEffectedResource(updatedStateResource) + _refreshPostfachMailList(updatedStateResource: StateResource<CommandResource>): void { + this._setPostfachMailListLoading(); + this._getEffectedResource(updatedStateResource) .pipe(first()) .subscribe((effectedResource) => { - this.setPostfachMailList(effectedResource); + this._setPostfachMailList(effectedResource); }); } - getEffectedResource(updatedStateResource: StateResource<CommandResource>): Observable<PostfachMailListResource> { + _getEffectedResource(updatedStateResource: StateResource<CommandResource>): Observable<PostfachMailListResource> { return this.commandService.getEffectedResource<PostfachMailListResource>(updatedStateResource.resource); } public getPostfachMailListByGivenVorgang(vorgang: VorgangResource): Observable<StateResource<PostfachMailListResource>> { doIfLoadingRequired(this.postfachMailList$.value, () => { - this.setPostfachMailListLoading(); + this._setPostfachMailListLoading(); this.loadPostfachMailsByVorgang(vorgang); }); return this.postfachMailList$.asObservable(); } public getPostfachMailListByVorgang(): Observable<StateResource<PostfachMailListResource>> { + this._refreshVorgangSubscription(); doIfLoadingRequired(this.postfachMailList$.value, () => { - this.setPostfachMailListLoading(); + this._setPostfachMailListLoading(); this.vorgangSubscription = this.vorgangService.getVorgangWithEingang().subscribe((vorgangWithEingangStateResource) => { if (vorgangWithEingangStateResource.resource) { this.loadPostfachMailsByVorgang(vorgangWithEingangStateResource.resource); @@ -257,20 +285,50 @@ export class PostfachService { return this.postfachMailList$.asObservable(); } - setPostfachMailListLoading(): void { + _refreshVorgangSubscription(): void { + this.vorgangChangeSubscription.unsubscribe(); + this._listenToVorgangChange(); + } + + _listenToVorgangChange(): void { + this.vorgangChangeSubscription = this.vorgangService + .getVorgangWithEingang() + .subscribe((vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>) => + this._handleVorgangChange(vorgangWithEingangStateResource), + ); + } + + _handleVorgangChange(vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>): void { + if (this.shouldReloadList(vorgangWithEingangStateResource)) { + this.shouldReload = true; + } + if (isLoaded(vorgangWithEingangStateResource) && this.shouldReload) { + this._setPostfachMailOnReload(); + this.shouldReload = false; + } + } + + private shouldReloadList(vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>): boolean { + return ( + (vorgangWithEingangStateResource.loading || vorgangWithEingangStateResource.reload) && + isNotNull(this.postfachMailList$.value.resource) + ); + } + + _setPostfachMailListLoading(): void { this.postfachMailList$.next({ ...this.postfachMailList$.value, loading: true }); } public loadPostfachMailsByVorgang(vorgang: VorgangResource): void { this.loadPostfachMailSubscription = this.repository.loadPostfachMailList(vorgang).subscribe((postfachMaiList) => { if (!isNull(postfachMaiList)) { - this.setPostfachMailList(postfachMaiList); + this._setPostfachMailList(postfachMaiList); setTimeout(() => this.loadPostfachMailSubscription.unsubscribe(), 0); } }); } - setPostfachMailList(postfachMailList: PostfachMailListResource): void { + _setPostfachMailList(postfachMailList: PostfachMailListResource): void { this.postfachMailList$.next(createStateResource(postfachMailList)); } diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.spec.ts index f2b47f34a70349440a1b12df07830044472fc724..62804bcc27411f45fac774d32995f4267b2162f7 100644 --- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.spec.ts +++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.spec.ts @@ -82,7 +82,7 @@ describe('PostfachMailListContainerComponent', () => { describe('reloadPostfachMailListOnVorgangReload', () => { beforeEach(() => { - postfachService.setPostfachMailOnReload.mockClear(); + postfachService._setPostfachMailOnReload.mockClear(); }); it('should call postfachService', () => { @@ -93,7 +93,7 @@ describe('PostfachMailListContainerComponent', () => { component.reloadPostfachMailListOnVorgangReload(); - expect(postfachService.setPostfachMailOnReload).toHaveBeenCalled(); + expect(postfachService._setPostfachMailOnReload).toHaveBeenCalled(); }); it('should not call postfachService', () => { @@ -104,7 +104,7 @@ describe('PostfachMailListContainerComponent', () => { component.reloadPostfachMailListOnVorgangReload(); - expect(postfachService.setPostfachMailOnReload).not.toHaveBeenCalled(); + expect(postfachService._setPostfachMailOnReload).not.toHaveBeenCalled(); }); }); }); diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.ts index 70ae1c3856ad88ebe07b61aaf03b800b79d5fd7a..14c858585f1b747ec7175b1d717c13f23e44d547 100644 --- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.ts +++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list-container.component.ts @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, Input, OnChanges } from '@angular/core'; import { ON_PAGE, PostfachMailListResource, PostfachService } from '@alfa-client/postfach-shared'; import { isNotNull, StateResource } from '@alfa-client/tech-shared'; import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; +import { Component, Input, OnChanges } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ @@ -51,7 +51,7 @@ export class PostfachMailListContainerComponent implements OnChanges { reloadPostfachMailListOnVorgangReload(): void { if (this.vorgangStateResource.reload) { - this.postfachService.setPostfachMailOnReload(); + this.postfachService._setPostfachMailOnReload(); } } } diff --git a/alfa-client/libs/test-utils/src/lib/mocking.ts b/alfa-client/libs/test-utils/src/lib/mocking.ts index fbf27ea40e6738db50a256e625f97579f130b929..21a8ceba099c6664d21f8663841747dd51f3d396 100644 --- a/alfa-client/libs/test-utils/src/lib/mocking.ts +++ b/alfa-client/libs/test-utils/src/lib/mocking.ts @@ -77,3 +77,7 @@ export function mockWindowError(): any { window.onerror = errorHandler; return errorHandler; } + +export function assignValue<T>(object: any, attributeName: string, toAssignValue: any): T { + return Object.assign(object, { [attributeName]: toAssignValue }); +} diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts index b95396349c8cb79f0e97601877a7fcd108529e56..971f3982258f6c9b65e7c031763595d20a3f900a 100644 --- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts +++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.spec.ts @@ -123,21 +123,30 @@ describe('OzgcloudDialogService', () => { }); describe('openWizard', () => { + beforeEach(() => { + service.openInCallingComponentContext = jest.fn(); + }); + it('should open wizard dialog', () => { - service.openWizard(component); + service.openWizard(component, viewContainerRef); - expect(dialog.open).toHaveBeenCalledWith(component, { - ...service.WIZARD_DIALOG_CONFIG, - }); + expect(service.openInCallingComponentContext).toHaveBeenCalledWith( + component, + viewContainerRef, + undefined, + service.WIZARD_DIALOG_CONFIG, + ); }); it('should open wizard dialog with data', () => { - service.openWizard(component, dialogData); + service.openWizard(component, viewContainerRef, dialogData); - expect(dialog.open).toHaveBeenCalledWith(component, { - ...service.WIZARD_DIALOG_CONFIG, - data: dialogData, - }); + expect(service.openInCallingComponentContext).toHaveBeenCalledWith( + component, + viewContainerRef, + dialogData, + service.WIZARD_DIALOG_CONFIG, + ); }); }); diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts index aebed88efe5a54fafce9ec09283f0314c744fc5e..cbea4f7eb2ab5ed2a177d1ac3809fae3fabaaae8 100644 --- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts +++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts @@ -43,8 +43,8 @@ export class OzgcloudDialogService { disableClose: true, }; - public openWizard<C, D, R = unknown>(component: ComponentType<C>, data?: D): DialogRef<R> { - return this.openDialog<C, R>(component, this.buildDialogConfigWithData<D>(data, this.WIZARD_DIALOG_CONFIG)); + public openWizard<C, D, R = unknown>(component: ComponentType<C>, viewContainerRef: ViewContainerRef, data?: D): DialogRef<R> { + return this.openInCallingComponentContext<C, D, R>(component, viewContainerRef, data, this.WIZARD_DIALOG_CONFIG); } /** diff --git a/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.html b/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.html index 673ecf065e1b890e163cf98fab0335c180bea627..edc6820dfa4a6626a4e634f1116bff672bfc8fb6 100644 --- a/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.html +++ b/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.html @@ -23,6 +23,6 @@ Die sprachspezifischen Genehmigungen und Beschränkungen unter der Lizenz sind dem Lizenztext zu entnehmen. --> -@for (invalidParam of invalidParams; track invalidParam) { - <span>{{ message(invalidParam) }}</span> +@for (validationMessage of validationMessages; track validationMessage) { + <span>{{ validationMessage }}</span> } diff --git a/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.ts b/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.ts index eae4c1e99487d7fe169a73fee93d07af75f55676..3b2b26490f43530dfa97995a52cc1efed224f637 100644 --- a/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.ts +++ b/alfa-client/libs/ui/src/lib/ui/validation-error/validation-error.component.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { InvalidParam, getMessageForInvalidParam } from '@alfa-client/tech-shared'; +import { getMessageForInvalidParam, InvalidParam } from '@alfa-client/tech-shared'; import { Component, Input } from '@angular/core'; @Component({ @@ -32,9 +32,10 @@ import { Component, Input } from '@angular/core'; }) export class ValidationErrorComponent { @Input() label: string; - @Input() invalidParams: InvalidParam[]; - public message(invalidParam: InvalidParam): string { - return getMessageForInvalidParam(this.label, invalidParam); + @Input() set invalidParams(value: InvalidParam[]) { + this.validationMessages = value.map((invalidParam: InvalidParam) => getMessageForInvalidParam(this.label, invalidParam)); } + + public validationMessages: string[] = []; } diff --git a/alfa-client/libs/vorgang-detail/src/index.ts b/alfa-client/libs/vorgang-detail/src/index.ts index d9615b0082ac270218d00ecc945e2c2410bd0251..765983a28a264f4ee218a4b33ad3ee2cf3488959 100644 --- a/alfa-client/libs/vorgang-detail/src/index.ts +++ b/alfa-client/libs/vorgang-detail/src/index.ts @@ -23,5 +23,4 @@ */ export * from './lib/aktenzeichen-edit-dialog/aktenzeichen-edit-dialog.component'; export * from './lib/aktenzeichen-editable/aktenzeichen-editable.component'; -export * from './lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model'; export * from './lib/vorgang-detail.module'; diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts index 932363f2b33c3e0ebf50e8082a9389fd83a0a5a7..728a67f0542506e2c817191447c4fce7b5400b6c 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts @@ -24,18 +24,8 @@ import { BescheidWizardContainerComponent } from '@alfa-client/bescheid'; import { BescheidWizardDialogResult } from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; -import { createEmptyStateResource, createStateResource, HasLinkPipe, StateResource } from '@alfa-client/tech-shared'; -import { - createDialogRefMock, - DialogRefMock, - getElementComponentFromFixtureByCss, - getMockComponent, - Mock, - mock, - notExistsAsHtmlElement, - tooltipExistsWithText, - triggerEvent, -} from '@alfa-client/test-utils'; +import { createStateResource, HasLinkPipe, StateResource } from '@alfa-client/tech-shared'; +import { createDialogRefMock, DialogRefMock, getElementComponentFromFixtureByCss, getMockComponent, Mock, mock, notExistsAsHtmlElement, tooltipExistsWithText, triggerEvent, } from '@alfa-client/test-utils'; import { OzgcloudDialogService } from '@alfa-client/ui'; import { VorgangCommandService, VorgangService, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; import { DialogRef } from '@angular/cdk/dialog'; @@ -46,8 +36,7 @@ import { createCommandResource } from 'libs/command-shared/test/command'; import { getDataTestIdAttributeOf } from 'libs/tech-shared/test/data-test'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; -import { Observable, of } from 'rxjs'; -import { VorgangDetailBescheidenComponent } from '../../vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component'; +import { of } from 'rxjs'; import { BescheidenButtonComponent } from './bescheiden-button.component'; describe('BescheidenButtonComponent', () => { @@ -57,11 +46,13 @@ describe('BescheidenButtonComponent', () => { const bescheidenButton: string = getDataTestIdAttributeOf('bescheiden-button'); const bescheidenIconButton: string = getDataTestIdAttributeOf('bescheiden-icon-button'); + const viewContainerRef = <any>{}; + let vorgangCommandService: Mock<VorgangCommandService>; let ozgcloudDialogService: Mock<OzgcloudDialogService>; let vorgangService: Mock<VorgangService>; - const dialogRef = <DialogRef<VorgangDetailBescheidenComponent>>{}; + const dialogRef = <DialogRef<BescheidWizardDialogResult>>{}; beforeEach(() => { vorgangCommandService = mock(VorgangCommandService); @@ -96,6 +87,7 @@ describe('BescheidenButtonComponent', () => { fixture = TestBed.createComponent(BescheidenButtonComponent); component = fixture.componentInstance; + component.viewContainerRef = viewContainerRef; ozgcloudDialogService.openWizard = jest.fn().mockReturnValue(dialogRef); fixture.detectChanges(); }); @@ -132,29 +124,6 @@ describe('BescheidenButtonComponent', () => { expect(component.openBescheidenWizard).toHaveBeenCalled(); }); }); - - describe('should do bescheiden', () => { - const command: CommandResource = createCommandResource(); - const comandStateResource$: Observable<StateResource<CommandResource>> = of(createStateResource(command)); - - beforeEach(() => { - vorgangCommandService.bescheiden.mockReturnValue(comandStateResource$); - }); - - it('should call vorgangCommandService.bescheiden', () => { - component.bescheiden(); - - expect(vorgangCommandService.bescheiden).toHaveBeenCalled(); - }); - - it('should assign response', () => { - component.commandStateResource$ = of(createEmptyStateResource<CommandResource>()); - - component.bescheiden(); - - expect(component.commandStateResource$).toBe(comandStateResource$); - }); - }); }); describe('bescheiden icon button', () => { @@ -196,7 +165,7 @@ describe('BescheidenButtonComponent', () => { component.openBescheidenWizard(); - expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(BescheidWizardContainerComponent, { + expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(BescheidWizardContainerComponent, viewContainerRef, { vorgangWithEingangResource: vorgang, }); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts index 14105a18936391dbbf8646abed381e2b9273767c..eb3496cd4e8844f34b270c19ee130fc9722639c2 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts @@ -21,22 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { BescheidWizardContainerComponent } from '@alfa-client/bescheid'; +import { BescheidWizardContainerComponent, BescheidWizardDialogData } from '@alfa-client/bescheid'; import { BescheidWizardDialogResult } from '@alfa-client/bescheid-shared'; import { CommandResource } from '@alfa-client/command-shared'; import { createEmptyStateResource, isNotNil, StateResource } from '@alfa-client/tech-shared'; import { OzgcloudDialogService } from '@alfa-client/ui'; -import { - VorgangCommandService, - VorgangService, - VorgangWithEingangLinkRel, - VorgangWithEingangResource, -} from '@alfa-client/vorgang-shared'; +import { VorgangCommandService, VorgangService, VorgangWithEingangLinkRel, VorgangWithEingangResource, } from '@alfa-client/vorgang-shared'; import { DialogRef } from '@angular/cdk/dialog'; -import { Component, Input, OnInit } from '@angular/core'; +import { Component, inject, Input, OnInit, ViewContainerRef } from '@angular/core'; import { hasLink } from '@ngxp/rest'; import { Observable, of } from 'rxjs'; -import { BescheidenDialogData } from '../../vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model'; @Component({ selector: 'alfa-bescheiden-button', @@ -47,6 +41,11 @@ export class BescheidenButtonComponent implements OnInit { @Input() vorgang: VorgangWithEingangResource; @Input() showAsIconButton: boolean = false; + viewContainerRef = inject(ViewContainerRef); + private readonly vorgangCommandService = inject(VorgangCommandService); + private readonly vorgangService = inject(VorgangService); + private readonly ozgcloudDialogService = inject(OzgcloudDialogService); + commandStateResource$: Observable<StateResource<CommandResource>> = of(createEmptyStateResource<CommandResource>()); readonly linkRel = VorgangWithEingangLinkRel; @@ -61,38 +60,21 @@ export class BescheidenButtonComponent implements OnInit { ); } - constructor( - private vorgangCommandService: VorgangCommandService, - private vorgangService: VorgangService, - private ozgcloudDialogService: OzgcloudDialogService, - ) {} - ngOnInit(): void { this.commandStateResource$ = this.vorgangCommandService.getBeschiedenCommand(); } public bescheiden(): void { - if (this.shouldOpenBescheidenWizard()) { - this.openBescheidenWizard(); - } else { - this.commandStateResource$ = this.vorgangCommandService.bescheiden(this.vorgang); - } - } - - private shouldOpenBescheidenWizard(): boolean { - return ( - hasLink(this.vorgang, VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT) || - hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT) - ); + this.openBescheidenWizard(); } public openBescheidenWizard(): void { - const dialogData: BescheidenDialogData = { vorgangWithEingangResource: this.vorgang }; + const dialogData: BescheidWizardDialogData = { vorgangWithEingangResource: this.vorgang }; const dialogRef: DialogRef<BescheidWizardDialogResult> = this.ozgcloudDialogService.openWizard< BescheidWizardContainerComponent, - BescheidenDialogData, + BescheidWizardDialogData, BescheidWizardDialogResult - >(BescheidWizardContainerComponent, dialogData); + >(BescheidWizardContainerComponent, this.viewContainerRef, dialogData); dialogRef.closed.subscribe((dialogResult: BescheidWizardDialogResult) => this.handleBescheidWizardClosed(dialogResult)); } diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.html index 7170a1ee9d6a52391ff3841614a4dff0a9cb4171..650f1390dbfeb14e5663d263719b0fbdbc98b24c 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.html @@ -45,4 +45,4 @@ <alfa-create-wiedervorlage-button-container [showAsIconButton]="showAsIconButton" [vorgang]="vorgangWithEingang" /> <alfa-assign-user-profile-button-container [vorgang]="vorgangWithEingang" /> <alfa-postfach-mail-button-container [showAsIconButton]="showAsIconButton" [vorgang]="vorgangWithEingang" /> -<alfa-forward-by-ozgcloud-button-container [vorgangWithEingang]="vorgangWithEingang" [showAsIconButton]="showAsIconButton" /> +<alfa-forwarding-button-container [vorgangWithEingang]="vorgangWithEingang" [showAsIconButton]="showAsIconButton" /> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.spec.ts index b8c3aed662cf6e6034a2a80d3eb99bd13472e235..4d860217f0985c53335390280988192e7f2427c9 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component.spec.ts @@ -21,12 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ForwardByOzgcloudButtonContainerComponent } from '@alfa-client/forwarding'; -import { - EndgueltigLoeschenButtonContainerComponent, - LoeschAnforderungZuruecknehmenButtonContainerComponent, - LoeschenAnfordernButtonContainerComponent, -} from '@alfa-client/loesch-anforderung'; +import { ForwardingButtonContainerComponent } from '@alfa-client/forwarding'; +import { EndgueltigLoeschenButtonContainerComponent, LoeschAnforderungZuruecknehmenButtonContainerComponent, LoeschenAnfordernButtonContainerComponent, } from '@alfa-client/loesch-anforderung'; import { PostfachMailButtonContainerComponent } from '@alfa-client/postfach'; import { HasLinkPipe } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, getMockComponent, notExistsAsHtmlElement } from '@alfa-client/test-utils'; @@ -77,7 +73,7 @@ describe('VorgangDetailActionButtonsComponent', () => { MockComponent(LoeschenAnfordernButtonContainerComponent), MockComponent(EndgueltigLoeschenButtonContainerComponent), MockComponent(LoeschAnforderungZuruecknehmenButtonContainerComponent), - MockComponent(ForwardByOzgcloudButtonContainerComponent), + MockComponent(ForwardingButtonContainerComponent), ], }); }); @@ -123,10 +119,7 @@ describe('VorgangDetailActionButtonsComponent', () => { fixture.detectChanges(); - const button: ForwardByOzgcloudButtonContainerComponent = getMockComponent( - fixture, - ForwardByOzgcloudButtonContainerComponent, - ); + const button: ForwardingButtonContainerComponent = getMockComponent(fixture, ForwardingButtonContainerComponent); expect(button.vorgangWithEingang).toBe(vorgangWithEingang); expect(button.showAsIconButton).toBeTruthy(); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html index 772fdbd05969b74f6fe626e05d5b74123f595f02..af35bf9c288929c532d54c232e770b764d94795a 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html @@ -60,10 +60,10 @@ <div class="two-column"> <div class="section" *ngIf="vorgangResource | hasLink: vorgangWithEingangLinkRel.FORWARD_BY_EMAIL"> - <alfa-vorgang-forwarding-container + <alfa-forwarding-by-email-container [vorgang]="vorgangResource" data-test-id="forwarding-container-in-vorgang" - ></alfa-vorgang-forwarding-container> + ></alfa-forwarding-by-email-container> </div> <div class="section" *ngIf="vorgangResource | hasLink: vorgangHeaderLinkRel.WIEDERVORLAGEN"> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts index 79d55a0dd7c4b095933d59e78923e8e786ae86a2..9a60edf8103e922ac4c2ed206fb0d56907c0b6f0 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts @@ -22,10 +22,10 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { CollaborationInVorgangContainerComponent } from '@alfa-client/collaboration'; -import { VorgangForwardingContainerComponent } from '@alfa-client/forwarding'; +import { ForwardingByEmailContainerComponent } from '@alfa-client/forwarding'; import { KommentarListInVorgangContainerComponent } from '@alfa-client/kommentar'; import { PostfachMailListContainerComponent } from '@alfa-client/postfach'; -import { HasLinkPipe, ToEmbeddedResourcesPipe, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; +import { createEmptyStateResource, createStateResource, HasLinkPipe, ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, getMockComponent, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { ExpansionPanelComponent, OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui'; import { VorgangHeaderLinkRel, VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; @@ -72,7 +72,7 @@ describe('VorgangDetailAreaComponent', () => { MockComponent(PostfachMailListContainerComponent), MockComponent(VorgangDetailAntragstellerComponent), MockComponent(VorgangDetailFormularDatenComponent), - MockComponent(VorgangForwardingContainerComponent), + MockComponent(ForwardingByEmailContainerComponent), MockComponent(BescheidListInVorgangContainerComponent), MockComponent(ExpansionPanelComponent), MockComponent(CollaborationInVorgangContainerComponent), diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.html index 742a81193c28b8f3a3b199604b2ab1f36d8f5785..c11e59564e2b7878a53334eb7a9f1ed90fa3d63d 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.html @@ -37,4 +37,4 @@ } <alfa-endgueltig-loeschen-button-container [vorgang]="vorgangWithEingang" /> <alfa-loesch-anforderung-zuruecknehmen-button-container /> -<alfa-forward-by-ozgcloud-button-container [vorgangWithEingang]="vorgangWithEingang" /> +<alfa-forwarding-button-container [vorgangWithEingang]="vorgangWithEingang" /> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.spec.ts index 4b16a16ee53c7fda49274e3002b8e111b8f93d30..04956f9d574e55013fd19ba30851dfdaf0010110 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.spec.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component.spec.ts @@ -21,12 +21,8 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ForwardByOzgcloudButtonContainerComponent } from '@alfa-client/forwarding'; -import { - EndgueltigLoeschenButtonContainerComponent, - LoeschAnforderungZuruecknehmenButtonContainerComponent, - LoeschenAnfordernButtonContainerComponent, -} from '@alfa-client/loesch-anforderung'; +import { ForwardingButtonContainerComponent } from '@alfa-client/forwarding'; +import { EndgueltigLoeschenButtonContainerComponent, LoeschAnforderungZuruecknehmenButtonContainerComponent, LoeschenAnfordernButtonContainerComponent, } from '@alfa-client/loesch-anforderung'; import { HasLinkPipe } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, getMockComponent, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui'; @@ -70,7 +66,7 @@ describe('VorgangDetailFormularButtonsComponent', () => { MockComponent(LoeschenAnfordernButtonContainerComponent), MockComponent(EndgueltigLoeschenButtonContainerComponent), MockComponent(LoeschAnforderungZuruecknehmenButtonContainerComponent), - MockComponent(ForwardByOzgcloudButtonContainerComponent), + MockComponent(ForwardingButtonContainerComponent), ], }); }); @@ -106,10 +102,7 @@ describe('VorgangDetailFormularButtonsComponent', () => { component.vorgangWithEingang = vorgangWithEingang; fixture.detectChanges(); - const button: ForwardByOzgcloudButtonContainerComponent = getMockComponent( - fixture, - ForwardByOzgcloudButtonContainerComponent, - ); + const button: ForwardingButtonContainerComponent = getMockComponent(fixture, ForwardingButtonContainerComponent); expect(button.vorgangWithEingang).toBe(vorgangWithEingang); }); }); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts deleted file mode 100644 index f69a1d6f6d0127dbc83a1ead4b55b751d42714cb..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.spec.ts +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (C) 2024 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 { - Bescheid, - BescheidLinkRel, - BescheidResource, - BescheidSendBy, - BescheidService, - DocumentResource, -} from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { CommandLinkRel, CommandResource } from '@alfa-client/command-shared'; -import { - EMPTY_STRING, - StateResource, - createStateResource, - formatForDatabase, -} from '@alfa-client/tech-shared'; -import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; -import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { registerLocaleData } from '@angular/common'; -import localeDe from '@angular/common/locales/de'; -import { fakeAsync, tick } from '@angular/core/testing'; -import { UntypedFormBuilder } from '@angular/forms'; -import { faker } from '@faker-js/faker'; -import { Resource, ResourceUri } from '@ngxp/rest'; -import { cold } from 'jest-marbles'; -import { - createCommandResource, - createCommandStateResource, -} from 'libs/command-shared/test/command'; -import { toResource } from 'libs/tech-shared/test/resource'; -import { of } from 'rxjs'; -import { - createBescheid, - createBescheidResource, -} from '../../../../../bescheid-shared/src/test/bescheid'; -import { createDocumentResource } from '../../../../../bescheid-shared/src/test/document'; -import { createBinaryFileResource } from '../../../../../binary-file-shared/test/binary-file'; -import { singleCold } from '../../../../../tech-shared/test/marbles'; -import { createVorgangWithEingangResource } from '../../../../../vorgang-shared/test/vorgang'; -import { BescheidenFormService } from './bescheiden.formservice'; - -registerLocaleData(localeDe); - -describe('BescheidenFormService', () => { - let service: BescheidenFormService; - let bescheidService: Mock<BescheidService>; - const now: Date = new Date(); - Date.now = jest.fn().mockReturnValue(now); - - beforeEach(() => { - bescheidService = mock(BescheidService); - service = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - }); - - describe('constructor', () => { - it('should initialize form beschieden am', () => { - expect(service.getValue().beschiedenAm).toEqual(formatForDatabase(now)); - }); - - it('should initialize form bewilligt', () => { - expect(service.getValue().bewilligt).toBeTruthy(); - }); - - it('should initialize form send by', () => { - expect(service.getValue().sendBy).toEqual(BescheidSendBy.NACHRICHT); - }); - - it('should initialize form bescheid dokument', () => { - expect(service.getValue().bescheidDocument).toBeNull(); - }); - - it('should initialize form attachments', () => { - expect(service.getValue().attachments).toEqual([]); - }); - - it('should initialize form nachricht subject', () => { - expect(service.getValue().nachrichtSubject).toEqual(EMPTY_STRING); - }); - - it('should initialize form nachricht text', () => { - expect(service.getValue().nachrichtText).toEqual(EMPTY_STRING); - }); - }); - - describe('init', () => { - it('should subscribe to sendBy', () => { - service.subscribeToSendBy = jest.fn(); - - service.init(); - - expect(service.subscribeToSendBy).toHaveBeenCalled(); - }); - }); - - describe('subscribe to send by', () => { - it('should update send by on value change', () => { - service.updateSendByManual = jest.fn(); - - service.subscribeToSendBy(); - service.form.controls[BescheidenFormService.FIELD_SEND_BY].patchValue(BescheidSendBy.MANUAL); - - expect(service.updateSendByManual).toHaveBeenCalled(); - }); - }); - - describe('update send by manual', () => { - it('should set to true if its manual', () => { - service.updateSendByManual(BescheidSendBy.MANUAL); - - expect(service.sendByManual.value).toBeTruthy(); - }); - it('should set to false if its nachricht', () => { - service.updateSendByManual(BescheidSendBy.NACHRICHT); - - expect(service.sendByManual.value).toBeFalsy(); - }); - it('should not emit if value not changed', () => { - service.sendByManual.next(true); - service.sendByManual.next = jest.fn(); - - service.updateSendByManual(BescheidSendBy.MANUAL); - - expect(service.sendByManual.next).not.toHaveBeenCalled(); - }); - it('should emit on value change', () => { - service.sendByManual.next(false); - service.sendByManual.next = jest.fn(); - - service.updateSendByManual(BescheidSendBy.MANUAL); - - expect(service.sendByManual.next).toHaveBeenCalled(); - }); - }); - - describe('initializeFormChanges', () => { - it('should emit initial form value', () => { - expect(service.getBescheidChanges()).toBeObservable( - cold('a', { - a: { - beschiedenAm: now, - bewilligt: true, - attachments: [], - bescheidDocument: null, - sendBy: BescheidSendBy.NACHRICHT, - nachrichtSubject: '', - nachrichtText: '', - }, - }), - ); - }); - }); - - describe('getValue', () => { - let getFormValue: jest.Mock; - - beforeEach(() => { - getFormValue = service.getFormValue = jest.fn(); - getFormValue.mockReturnValue({ beschiedenAm: now, bewilligt: 'true' }); - }); - - it('should call getFormValue', () => { - service.getValue(); - - expect(getFormValue).toHaveBeenCalled(); - }); - - it('should return bescheid', () => { - const value: Bescheid = service.getValue(); - - expect(value).toEqual({ bewilligt: true, beschiedenAm: formatForDatabase(now) } as Bescheid); - }); - }); - - describe('getValueWithApproved', () => { - it('should convert string bewilligt from bescheid if it is not nil', () => { - const bescheid: Bescheid = { ...createBescheid(), bewilligt: 'true' }; - - const result = service.getValueWithApproved(bescheid); - - expect(result.bewilligt).toBeTruthy(); - }); - - it('should set bewilligt to false if it is nil', () => { - const bescheid: Bescheid = { ...createBescheid(), bewilligt: undefined }; - - const result = service.getValueWithApproved(bescheid); - - expect(result.bewilligt).toBeFalsy(); - }); - }); - - describe('getBescheidChanges', () => { - it('should emit initial form value', () => { - expect(service.getBescheidChanges()).toBeObservable( - singleCold({ - beschiedenAm: now, - bewilligt: true, - attachments: [], - bescheidDocument: null, - sendBy: BescheidSendBy.NACHRICHT, - nachrichtSubject: '', - nachrichtText: '', - }), - ); - }); - }); - - describe('patchValues', () => { - let bescheidResource: BescheidResource; - let patch: jest.Mock; - - beforeEach(() => { - bescheidResource = createBescheidResource(); - patch = service.patch = jest.fn(); - }); - - it('should call patch', () => { - service.patchValues(bescheidResource); - - expect(patch).toHaveBeenCalledWith({ - [BescheidenFormService.FIELD_BESCHIEDEN_AM]: bescheidResource.beschiedenAm, - [BescheidenFormService.FIELD_BEWILLIGT]: String(bescheidResource.bewilligt), - [BescheidenFormService.FIELD_BESCHEID_DOCUMENT]: null, - [BescheidenFormService.FIELD_SEND_BY]: String(bescheidResource.sendBy), - [BescheidenFormService.FIELD_NACHRICHT_SUBJECT]: bescheidResource.nachrichtSubject, - [BescheidenFormService.FIELD_NACHRICHT_TEXT]: bescheidResource.nachrichtText, - }); - }); - - it('should call patch with undefined sendBy', () => { - const bescheidDocumentUri: ResourceUri = faker.internet.url(); - service.patchValues({ - ...bescheidResource, - sendBy: undefined, - _links: { - ...bescheidResource._links, - [BescheidLinkRel.BESCHEID_DOCUMENT]: { href: bescheidDocumentUri }, - }, - }); - - expect(patch).toHaveBeenCalledWith({ - [BescheidenFormService.FIELD_BESCHIEDEN_AM]: bescheidResource.beschiedenAm, - [BescheidenFormService.FIELD_BEWILLIGT]: String(bescheidResource.bewilligt), - [BescheidenFormService.FIELD_SEND_BY]: BescheidSendBy.NACHRICHT, - [BescheidenFormService.FIELD_BESCHEID_DOCUMENT]: bescheidDocumentUri, - [BescheidenFormService.FIELD_NACHRICHT_SUBJECT]: bescheidResource.nachrichtSubject, - [BescheidenFormService.FIELD_NACHRICHT_TEXT]: bescheidResource.nachrichtText, - }); - }); - - it('should not call patch', () => { - service.patchValues(null); - - expect(patch).not.toHaveBeenCalled(); - }); - - it('should patch attachments', () => { - service.patchValues(bescheidResource); - - expect(service.getFormValue().attachments).toEqual(bescheidResource.attachments); - }); - }); - - describe('submit', () => { - const commandStateResource: StateResource<CommandResource> = - createStateResource(createCommandResource()); - - beforeEach(() => { - bescheidService.updateBescheid.mockReturnValue(of(commandStateResource)); - bescheidService.createBescheid.mockReturnValue(of(commandStateResource)); - service.updateNachrichtOnSuccess = jest.fn().mockReturnValue(() => of(commandStateResource)); - }); - - it('should call bescheid service update bescheid draft if is patch', (done) => { - const dummyPatchResource: Resource = toResource({}); - service.patch(dummyPatchResource); - - service.submit().subscribe(() => { - expect(bescheidService.updateBescheid).toHaveBeenCalledWith(service.getValue()); - done(); - }); - }); - - it('should call bescheid service update bescheid draft if bescheid draft exists', (done) => { - bescheidService.existsBescheidDraft.mockReturnValue(true); - - service.submit().subscribe(() => { - expect(bescheidService.updateBescheid).toHaveBeenCalledWith(service.getValue()); - done(); - }); - }); - - it('should call bescheid service create bescheid draft if bescheid draft not exists', (done) => { - bescheidService.existsBescheidDraft.mockReturnValue(false); - - service.submit().subscribe(() => { - expect(bescheidService.createBescheid).toHaveBeenCalledWith( - service.vorgangWithEingangResource, - service.getValue(), - ); - done(); - }); - }); - - it('should update nachricht after successful bescheid creation', (done) => { - bescheidService.existsBescheidDraft.mockReturnValue(false); - - service.submit().subscribe(() => { - expect(service.updateNachrichtOnSuccess).toHaveBeenCalled(); - done(); - }); - }); - }); - - describe('submit draft', () => { - const commandStateResource: StateResource<CommandResource> = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); - - beforeEach(() => { - service.submit = jest.fn().mockReturnValue(of(commandStateResource)); - }); - - it('should call submit', (done) => { - service.submitDraft().subscribe(() => { - expect(service.submit).toHaveBeenCalledWith(); - done(); - }); - }); - - it('should call service to reload vorgang', fakeAsync(() => { - service.submitDraft().subscribe(); - tick(); - - expect(bescheidService.reloadCurrentVorgang).toHaveBeenCalled(); - })); - }); - - describe('setVorgangWithEingangResource', () => { - it('should set vorgangWithEingangResource', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = - createVorgangWithEingangResource(); - - service.setVorgangWithEingangResource(vorgangWithEingangResource); - - expect(service.vorgangWithEingangResource).toBe(vorgangWithEingangResource); - }); - }); - - describe('getVorgangWithEingangResource', () => { - it('should reutrn vorgangWithEingangResource', () => { - const vorgangWithEingangResource: VorgangWithEingangResource = - createVorgangWithEingangResource(); - service.vorgangWithEingangResource = vorgangWithEingangResource; - - const vorang: VorgangWithEingangResource = service.getVorgangWithEingangResource(); - - expect(vorang).toBe(vorgangWithEingangResource); - }); - }); - - describe('deleteFile', () => { - it('should emit binary file resource', (done) => { - const file: BinaryFileResource = createBinaryFileResource(); - - service.getFileDelete().subscribe((deletedFile: BinaryFileResource) => { - expect(deletedFile).toEqual(file); - done(); - }); - - service.deleteFile(file); - }); - }); - - describe('setActiveStep', () => { - it('should emit step', () => { - service.setActiveStep(3); - - expect(service.getActiveStep()).toBeObservable(singleCold(3)); - }); - }); - - describe('patchNachricht', () => { - it('should patch nachrichtSubject with value from document', () => { - const documentResource: DocumentResource = createDocumentResource(); - - service.patchNachricht(documentResource); - - expect(service.getValue().nachrichtSubject).toEqual(documentResource.nachrichtSubject); - }); - - it('should not patch nachrichtSubject if given', () => { - const documentResource: DocumentResource = createDocumentResource(); - const bescheidResource: BescheidResource = createBescheidResource(); - service.patchValues(bescheidResource); - - service.patchNachricht(documentResource); - - expect(service.getValue().nachrichtSubject).toEqual(bescheidResource.nachrichtSubject); - }); - - it('should patch nachrichtText with value from document', () => { - const documentResource: DocumentResource = createDocumentResource(); - - service.patchNachricht(documentResource); - - expect(service.getValue().nachrichtText).toEqual(documentResource.nachrichtText); - }); - - it('should not patch nachrichtText if given', () => { - const documentResource: DocumentResource = createDocumentResource(); - const bescheidResource: BescheidResource = createBescheidResource(); - service.patchValues(bescheidResource); - - service.patchNachricht(documentResource); - - expect(service.getValue().nachrichtText).toEqual(bescheidResource.nachrichtText); - }); - }); - - describe('clearNachricht', () => { - it('should patch values', () => { - const documentResource: DocumentResource = createDocumentResource(); - - service.patchNachricht(documentResource); - service.clearNachricht(); - - expect(service.getValue().nachrichtSubject).toEqual(EMPTY_STRING); - expect(service.getValue().nachrichtText).toEqual(EMPTY_STRING); - }); - }); - - describe('setSendBy', () => { - it.each(Object.keys(BescheidSendBy))( - 'should set control value to %s', - (sendBy: BescheidSendBy) => { - service.setSendBy(sendBy); - - expect(service.getValue().sendBy).toEqual(sendBy); - }, - ); - }); - - describe('validateBescheidDocumentExists', () => { - it('should return true', () => { - service.getValue = jest.fn().mockReturnValue(createBescheid()); - - service.validateBescheidDocumentExists(); - - expect(service.validateBescheidDocumentExists()).toBeTruthy(); - }); - - it('should return false', () => { - service.getValue = jest.fn().mockReturnValue({ - ...createBescheid(), - bescheidDocument: null, - } as Bescheid); - - service.validateBescheidDocumentExists(); - - expect(service.validateBescheidDocumentExists()).toBeFalsy(); - }); - - describe('getShowMissingBescheidDocumentError', () => { - it('should emit true', () => { - service.getValue = jest.fn().mockReturnValue({ - ...createBescheid(), - bescheidDocument: null, - } as Bescheid); - - service.validateBescheidDocumentExists(); - - expect(service.getShowMissingBescheidDocumentError()).toBeObservable(singleCold(true)); - }); - - it('should emit false', () => { - service.getValue = jest.fn().mockReturnValue(createBescheid()); - - service.validateBescheidDocumentExists(); - - expect(service.getShowMissingBescheidDocumentError()).toBeObservable(singleCold(false)); - }); - }); - }); - - describe('isBetreffInvalid', () => { - it('should return true', () => { - service.form.controls[BescheidenFormService.FIELD_NACHRICHT_SUBJECT].setErrors({}); - - expect(service.isBetreffInvalid()).toBeTruthy(); - }); - - it('should return false', () => { - service.form.controls[BescheidenFormService.FIELD_NACHRICHT_SUBJECT].setErrors(null); - - expect(service.isBetreffInvalid()).toBeFalsy(); - }); - }); - - describe('isNachrichtInvalid', () => { - it('should return true', () => { - service.form.controls[BescheidenFormService.FIELD_NACHRICHT_TEXT].setErrors({}); - - expect(service.isNachrichtInvalid()).toBeTruthy(); - }); - - it('should return false', () => { - service.form.controls[BescheidenFormService.FIELD_NACHRICHT_TEXT].setErrors(null); - - expect(service.isNachrichtInvalid()).toBeFalsy(); - }); - }); - - describe('updateNachrichtOnSuccess', () => { - const subject: string = faker.lorem.words(3); - const text: string = faker.lorem.text(); - const bescheidResource: BescheidResource = createBescheidResource(); - - beforeEach(() => { - bescheidResource.nachrichtSubject = subject; - bescheidResource.nachrichtText = text; - bescheidService.getBescheidDraft.mockReturnValue(of(createStateResource(bescheidResource))); - }); - - it('should get bescheid draft', () => { - service - .updateNachrichtOnSuccess()( - of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE])), - ) - .subscribe(); - - expect(bescheidService.getBescheidDraft).toHaveBeenCalled(); - }); - - it('should set subject', () => { - service - .updateNachrichtOnSuccess()( - of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE])), - ) - .subscribe(); - - expect(service.getValue().nachrichtSubject).toEqual(subject); - }); - - it('should set text', () => { - service - .updateNachrichtOnSuccess()( - of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE])), - ) - .subscribe(); - - expect(service.getValue().nachrichtText).toEqual(text); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts deleted file mode 100644 index 27dd25492855e410c1ce03221a1b97da8fd67a77..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2024 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 { - Bescheid, - BescheidLinkRel, - BescheidResource, - BescheidSendBy, - BescheidService, - DocumentResource, -} from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; -import { - AbstractFormService, - EMPTY_STRING, - StateResource, - convertToBoolean, - formatForDatabase, - isLoaded, - isNotEmpty, - isNotNil, -} from '@alfa-client/tech-shared'; -import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { Injectable, OnDestroy } from '@angular/core'; -import { FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; -import { Resource, ResourceUri, getUrl, hasLink } from '@ngxp/rest'; -import { isEmpty, isNil, isUndefined } from 'lodash-es'; -import { BehaviorSubject, Observable, Subject, Subscription, combineLatest, filter, first, map, startWith } from 'rxjs'; - -@Injectable() -export class BescheidenFormService extends AbstractFormService<CommandResource> implements OnDestroy { - static readonly FIELD_BESCHIEDEN_AM = 'beschiedenAm'; - static readonly FIELD_BEWILLIGT = 'bewilligt'; - static readonly FIELD_BESCHEID_DOCUMENT = 'bescheidDocument'; - static readonly FIELD_ATTACHMENTS = 'attachments'; - public static readonly FIELD_SEND_BY = 'sendBy'; - static readonly FIELD_NACHRICHT_SUBJECT = 'nachrichtSubject'; - static readonly FIELD_NACHRICHT_TEXT = 'nachrichtText'; - - static readonly FIELD_PATH_PREFIX = 'command.body'; - - static readonly BETREFF_DEFAULT: string = 'Ihr Bescheid zum Antrag'; - - private readonly bescheidChanges$: BehaviorSubject<Bescheid>; - private readonly fileDelete$: Subject<BinaryFileResource>; - private readonly showMissingBescheidDocumentError$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); - - private readonly activeStep$: BehaviorSubject<number> = new BehaviorSubject(1); - readonly sendByManual: BehaviorSubject<boolean> = new BehaviorSubject(false); - - vorgangWithEingangResource: VorgangWithEingangResource; - - private formControlSubscriptions: Subscription; - private formChangesSubscription: Subscription; - - constructor( - formBuilder: UntypedFormBuilder, - private readonly bescheidService: BescheidService, - ) { - super(formBuilder); - - this.bescheidChanges$ = new BehaviorSubject<Bescheid>(this.getFormValue()); - this.fileDelete$ = new Subject<BinaryFileResource>(); - this.init(); - } - - init(): void { - this.formControlSubscriptions = this.subscribeToSendBy(); - this.initializeFormChanges(); - } - - subscribeToSendBy(): Subscription { - return this.form.controls[BescheidenFormService.FIELD_SEND_BY].valueChanges.subscribe((sendBy: BescheidSendBy) => - this.updateSendByManual(sendBy), - ); - } - - updateSendByManual(sendBy: BescheidSendBy): void { - const isSendByManual = sendBy === BescheidSendBy.MANUAL; - if (isSendByManual !== this.sendByManual.value) this.sendByManual.next(isSendByManual); - } - - initializeFormChanges(): void { - this.formChangesSubscription = this.form.valueChanges - .pipe( - startWith(this.getFormValue()), - map((value) => this.getValueWithApproved(value)), - ) - .subscribe((bescheid) => this.bescheidChanges$.next(bescheid)); - } - - ngOnDestroy(): void { - this.unsubscribe(); - } - - private unsubscribe(): void { - if (isNotNil(this.formChangesSubscription) && !this.formChangesSubscription.closed) { - this.formChangesSubscription.unsubscribe(); - } - if (isNotNil(this.formControlSubscriptions)) this.formControlSubscriptions.unsubscribe(); - } - - public patchValues(bescheid: BescheidResource): void { - if (isNil(bescheid)) { - return; - } - const bescheidDocumentUri: ResourceUri = this.getBescheidDocumentUri(bescheid); - this.bescheidService.setDocumentUri(bescheidDocumentUri); - this.patch({ - [BescheidenFormService.FIELD_BESCHIEDEN_AM]: bescheid.beschiedenAm, - [BescheidenFormService.FIELD_BEWILLIGT]: String(bescheid.bewilligt), - [BescheidenFormService.FIELD_BESCHEID_DOCUMENT]: bescheidDocumentUri, - [BescheidenFormService.FIELD_SEND_BY]: isUndefined(bescheid.sendBy) ? BescheidSendBy.NACHRICHT : bescheid.sendBy, - [BescheidenFormService.FIELD_NACHRICHT_SUBJECT]: bescheid.nachrichtSubject, - [BescheidenFormService.FIELD_NACHRICHT_TEXT]: bescheid.nachrichtText, - }); - bescheid.attachments.forEach((attachmentLink) => - (this.form.controls[BescheidenFormService.FIELD_ATTACHMENTS] as UntypedFormArray).push( - new UntypedFormControl(attachmentLink), - ), - ); - } - - private getBescheidDocumentUri(bescheid: BescheidResource): ResourceUri { - if (hasLink(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT)) { - return getUrl(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT); - } - return null; - } - - protected initForm(): UntypedFormGroup { - return this.formBuilder.group({ - [BescheidenFormService.FIELD_BESCHIEDEN_AM]: new UntypedFormControl(new Date(Date.now())), - [BescheidenFormService.FIELD_BEWILLIGT]: new UntypedFormControl('true'), - [BescheidenFormService.FIELD_SEND_BY]: new UntypedFormControl(BescheidSendBy.NACHRICHT), - [BescheidenFormService.FIELD_BESCHEID_DOCUMENT]: new UntypedFormControl(null), - [BescheidenFormService.FIELD_ATTACHMENTS]: new UntypedFormArray([]), - [BescheidenFormService.FIELD_NACHRICHT_SUBJECT]: new UntypedFormControl(''), - [BescheidenFormService.FIELD_NACHRICHT_TEXT]: new UntypedFormControl(''), - }); - } - - protected getPathPrefix(): string { - return BescheidenFormService.FIELD_PATH_PREFIX; - } - - protected doSubmit(): Observable<StateResource<CommandResource>> { - if (this.isPatch() || this.bescheidService.existsBescheidDraft()) { - return this.bescheidService.updateBescheid(this.getValue()); - } else { - return this.bescheidService - .createBescheid(this.vorgangWithEingangResource, this.getValue()) - .pipe(this.updateNachrichtOnSuccess()); - } - } - - updateNachrichtOnSuccess(): (source: Observable<StateResource<CommandResource>>) => Observable<StateResource<CommandResource>> { - return tapOnCommandSuccessfullyDone(() => { - this.bescheidService - .getBescheidDraft() - .pipe(filter(isLoaded), first()) - .subscribe((bescheidStateResource: StateResource<BescheidResource>) => { - this.setNachrichtSubject(bescheidStateResource.resource.nachrichtSubject); - this.setNachrichtText(bescheidStateResource.resource.nachrichtText); - }); - }); - } - - public submitDraft(): Observable<StateResource<Resource>> { - return this.submit().pipe(tapOnCommandSuccessfullyDone(() => this.bescheidService.reloadCurrentVorgang())); - } - - public getValue(): Bescheid { - const value: any = this.getFormValue(); - return { - ...value, - beschiedenAm: formatForDatabase(value.beschiedenAm), - bewilligt: convertToBoolean(value.bewilligt), - attachments: value.attachments, - }; - } - - public getValueWithApproved(value: any): Bescheid { - return { - ...value, - bewilligt: isNotNil(value.bewilligt) ? convertToBoolean(value.bewilligt) : false, - }; - } - - public getBescheidChanges(): Observable<Bescheid> { - return this.bescheidChanges$.asObservable(); - } - - public setVorgangWithEingangResource(vorgangWithEingangResource: VorgangWithEingangResource): void { - this.vorgangWithEingangResource = vorgangWithEingangResource; - } - - public getVorgangWithEingangResource(): VorgangWithEingangResource { - return this.vorgangWithEingangResource; - } - - public deleteFile(binaryFileResource: BinaryFileResource): void { - this.fileDelete$.next(binaryFileResource); - } - - public getFileDelete(): Observable<BinaryFileResource> { - return this.fileDelete$.asObservable(); - } - - public setActiveStep(step: number) { - this.activeStep$.next(step); - } - - public getActiveStep(): Observable<number> { - return this.activeStep$.asObservable(); - } - - public clearBescheidDocumentFile(): void { - this.updateBescheidDocumentFile(null); - } - - public updateBescheidDocumentFile(uri: ResourceUri): void { - this.getBescheidDocumentControl().patchValue(uri); - } - - private getBescheidDocumentControl(): FormControl { - return <FormControl>this.form.controls[BescheidenFormService.FIELD_BESCHEID_DOCUMENT]; - } - - public isSendByManual(): Observable<boolean> { - return this.sendByManual.asObservable(); - } - - public patchNachricht(documentResource: DocumentResource): void { - const value = this.getValue(); - if (isEmpty(value.nachrichtSubject)) { - if (isNotEmpty(documentResource.nachrichtSubject)) { - this.setNachrichtSubject(documentResource.nachrichtSubject); - } - } - - if (isEmpty(value.nachrichtText)) { - if (isNotEmpty(documentResource.nachrichtText)) { - this.setNachrichtText(documentResource.nachrichtText); - } - } - } - - public clearNachricht(): void { - this.setNachrichtSubject(EMPTY_STRING); - this.setNachrichtText(EMPTY_STRING); - } - - private setNachrichtSubject(value: string): void { - this.form.controls[BescheidenFormService.FIELD_NACHRICHT_SUBJECT].patchValue(value); - } - - private setNachrichtText(value: string): void { - this.form.controls[BescheidenFormService.FIELD_NACHRICHT_TEXT].patchValue(value); - } - - public setSendBy(sendBy: BescheidSendBy): void { - this.form.controls[BescheidenFormService.FIELD_SEND_BY].patchValue(sendBy); - } - - public getShowMissingBescheidDocumentError(): Observable<boolean> { - return combineLatest([this.showMissingBescheidDocumentError$.asObservable(), this.getBescheidChanges()]).pipe( - map( - ([showMissingBescheidDocumentError, bescheid]) => showMissingBescheidDocumentError && isEmpty(bescheid.bescheidDocument), - ), - ); - } - - public validateBescheidDocumentExists(): boolean { - this.showMissingBescheidDocumentError$.next(isEmpty(this.getValue().bescheidDocument)); - return isNotEmpty(this.getValue().bescheidDocument); - } - - public isBetreffInvalid(): boolean { - return this.form.controls[BescheidenFormService.FIELD_NACHRICHT_SUBJECT].invalid; - } - - public isNachrichtInvalid(): boolean { - return this.form.controls[BescheidenFormService.FIELD_NACHRICHT_TEXT].invalid; - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model.ts deleted file mode 100644 index 61f653e0c6e04b4e60bd03970bf9839d0a06ee07..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource } from '@alfa-client/bescheid-shared'; -import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; - -export interface BescheidenDialogData { - vorgangWithEingangResource: VorgangWithEingangResource; - bescheidDraftResource?: BescheidResource; -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html deleted file mode 100644 index b191b552c456fd14168b0df509afdc6a38ddd0fd..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html +++ /dev/null @@ -1,55 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<ods-attachment-wrapper> - <alfa-binary-file2-container - *ngFor="let attachment of existingAttachments" - [file]="attachment" - [deletable]="deletable" - (startDelete)="deleteFile($event)" - > - </alfa-binary-file2-container> - <ng-container *ngFor="let attachment of uploadedAttachments"> - <alfa-binary-file2-container - *ngIf="!attachment.loading && attachment.resource" - [file]="attachment.resource" - [deletable]="deletable" - (startDelete)="deleteFile($event)" - [attr.data-test-id]="(attachment.resource.name | convertForDataTest) + '-file2-container'" - > - </alfa-binary-file2-container> - </ng-container> - <ng-container *ngIf="uploadInProgress$ | async as uploadFileInProgress"> - <ods-attachment - data-test-id="attachment-upload-in-progress" - *ngIf="uploadFileInProgress.loading || uploadFileInProgress.error" - [loadingCaption]="uploadFileInProgress.fileName" - errorCaption="Fehler beim Hochladen" - [errorMessages]="uploadFileInProgress.error | convertProblemDetailToErrorMessages" - description="Anhang wird hochgeladen" - [isLoading]="uploadFileInProgress.loading" - ></ods-attachment> - </ng-container> -</ods-attachment-wrapper> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts deleted file mode 100644 index 237ed0fe684cfe2e873c2a2ff6d38865520476be..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { BinaryFile2ContainerComponent } from '@alfa-client/binary-file'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { - convertForDataTest, - ConvertForDataTestPipe, - createErrorStateResource, - createStateResource, - FileSizePipe, - StateResource, -} from '@alfa-client/tech-shared'; -import { existsAsHtmlElement, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; -import { OzgcloudSvgIconComponent, SpinnerComponent } from '@alfa-client/ui'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatIcon } from '@angular/material/icon'; -import { AttachmentComponent, AttachmentWrapperComponent, SpinnerIconComponent } from '@ods/system'; -import { ConvertProblemDetailToErrorMessagesPipe } from 'libs/tech-shared/src/lib/pipe/convert-problem-detail-to-error-messages.pipe'; -import { MockComponent, MockPipe } from 'ng-mocks'; -import { BehaviorSubject, EMPTY, Observable, of, Subscription } from 'rxjs'; -import { createUploadFileInProgress } from '../../../../../../../bescheid-shared/src/test/bescheid'; -import { - createBinaryFileResource, - createLoadedBinaryFileResource, - createLoadingBinaryFileStateResource, -} from '../../../../../../../binary-file-shared/test/binary-file'; -import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test'; -import { createApiError } from '../../../../../../../tech-shared/test/error'; -import { BescheidenFormService } from '../../bescheiden.formservice'; -import { VorgangDetailBescheidenResultAttachmentsComponent } from './vorgang-detail-bescheiden-result-attachments.component'; - -describe('VorgangDetailBescheidenResultAttachmentsComponent', () => { - let component: VorgangDetailBescheidenResultAttachmentsComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenResultAttachmentsComponent>; - - let bescheidService: Mock<BescheidService>; - let formService: Mock<BescheidenFormService>; - - beforeEach(async () => { - bescheidService = mock(BescheidService); - bescheidService.getAttachments.mockReturnValue(EMPTY); - bescheidService.getUploadedAttachment.mockReturnValue(EMPTY); - - formService = mock(BescheidenFormService); - formService.getBescheidChanges.mockReturnValue( - new BehaviorSubject({ beschiedenAm: new Date(), bewilligt: false }), - ); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenResultAttachmentsComponent, - ConvertForDataTestPipe, - MatIcon, - MockPipe(FileSizePipe), - MockPipe(ConvertProblemDetailToErrorMessagesPipe), - MockComponent(OzgcloudSvgIconComponent), - MockComponent(SpinnerComponent), - MockComponent(AttachmentWrapperComponent), - MockComponent(BinaryFile2ContainerComponent), - MockComponent(SpinnerIconComponent), - MockComponent(AttachmentComponent), - ], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenResultAttachmentsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render', () => { - const attachment = createStateResource(createBinaryFileResource()); - const dataTestId = getDataTestIdOf( - `${convertForDataTest(attachment.resource.name)}-file2-container`, - ); - const uploadInProgressDataTestId: string = getDataTestIdOf('attachment-upload-in-progress'); - - beforeEach(() => { - component.uploadedAttachments = [attachment]; - }); - - it('should render uploaded file container', () => { - component.ngOnInit(); - fixture.detectChanges(); - - existsAsHtmlElement(fixture, dataTestId); - }); - - it('should not render uploaded file container on loading', () => { - component.uploadedAttachments = [{ ...attachment, loading: true }]; - component.ngOnInit(); - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, dataTestId); - }); - - it('should not render uploaded file container on null resource', () => { - component.uploadedAttachments = [{ ...attachment, resource: null }]; - component.ngOnInit(); - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, dataTestId); - }); - - it('should render attachment in progress component when loading', () => { - component.uploadInProgress$ = of({ ...createUploadFileInProgress(), loading: true }); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, uploadInProgressDataTestId); - }); - - it('should render attachment in progress component on error', () => { - component.uploadInProgress$ = of({ - ...createUploadFileInProgress(), - loading: false, - error: createApiError(), - }); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, uploadInProgressDataTestId); - }); - - it('should not render attachment in progress component when not loading and no error', () => { - component.uploadInProgress$ = of({ - ...createUploadFileInProgress(), - loading: false, - error: null, - }); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, uploadInProgressDataTestId); - }); - }); - - describe('ngOnInit', () => { - let loadExistingAttachments: jest.Mock; - let subscribeToAttachmentUpload: jest.Mock; - - beforeEach(() => { - component.loadExistingAttachments = loadExistingAttachments = jest.fn(); - component.subscribeToAttachmentUpload = subscribeToAttachmentUpload = jest.fn(); - }); - - it('should load existing attachments', () => { - component.ngOnInit(); - - expect(loadExistingAttachments).toHaveBeenCalled(); - }); - - it('should subscribe to attachments upload', () => { - component.ngOnInit(); - - expect(subscribeToAttachmentUpload).toHaveBeenCalled(); - }); - - it('should get upload attachment in progress', () => { - component.ngOnInit(); - - expect(bescheidService.getUploadAttachmentInProgress).toHaveBeenCalled(); - }); - }); - - describe('ngOnDestroy', () => { - it('should unsubscribe', () => { - const subscription = mock(Subscription); - const observable = mock(Observable); - observable.subscribe.mockReturnValue(subscription); - bescheidService.getUploadedAttachment.mockReturnValue(observable); - component.ngOnInit(); - - component.ngOnDestroy(); - - expect(subscription.unsubscribe).toHaveBeenCalled(); - }); - }); - - describe('loadExistingAttachments', () => { - let attachment: BinaryFileResource; - - beforeEach(() => { - attachment = createBinaryFileResource(); - bescheidService.getAttachments.mockReturnValue(of([attachment])); - }); - - it('should get attachments', () => { - component.loadExistingAttachments(); - - expect(bescheidService.getAttachments).toHaveBeenCalled(); - }); - - it('should set existing attachments', () => { - component.loadExistingAttachments(); - - expect(component.existingAttachments).toEqual([attachment]); - }); - - it('should reset uploaded attachments', () => { - component.uploadedAttachments = [createStateResource(createBinaryFileResource())]; - - component.loadExistingAttachments(); - - expect(component.uploadedAttachments).toEqual([]); - }); - }); - - describe('subscribeToAttachmentUpload', () => { - let attachment: StateResource<BinaryFileResource>; - - beforeEach(() => { - attachment = createLoadedBinaryFileResource(); - bescheidService.getUploadedAttachment.mockReturnValue(of(attachment)); - }); - - it('should should set uploaded attachments', () => { - component.buildUploadedAttachments = jest.fn().mockReturnValue([attachment]); - - component.subscribeToAttachmentUpload(); - - expect(component.uploadedAttachments).toEqual([attachment]); - }); - }); - - describe('buildUploadedAttachments', () => { - let uploadedAttachment: StateResource<BinaryFileResource>; - let uploadedAttachments: StateResource<BinaryFileResource>[]; - let loadingAttachment: StateResource<BinaryFileResource>; - - beforeEach(() => { - uploadedAttachment = createLoadedBinaryFileResource(); - uploadedAttachments = [uploadedAttachment]; - component.uploadedAttachments = uploadedAttachments; - loadingAttachment = createLoadingBinaryFileStateResource(); - }); - - it('should add loaded state resource', () => { - const newBinaryFileResource = createLoadedBinaryFileResource(); - - const uploaded = component.buildUploadedAttachments(newBinaryFileResource); - - expect(uploaded).toEqual([uploadedAttachment, newBinaryFileResource]); - }); - - it('should add error state resource', () => { - const errorStateResource = createErrorStateResource(createApiError()); - - const uploaded = component.buildUploadedAttachments(errorStateResource); - - expect(uploaded).toEqual([uploadedAttachment, errorStateResource]); - }); - - it('should add loading state resource if none exists', () => { - const uploaded = component.buildUploadedAttachments(loadingAttachment); - - expect(uploaded).toEqual([uploadedAttachment, loadingAttachment]); - }); - - it('should not add loading state resource if one exists', () => { - component.uploadedAttachments = [...component.uploadedAttachments, loadingAttachment]; - - const uploaded = component.buildUploadedAttachments(createLoadingBinaryFileStateResource()); - - expect(uploaded).toEqual([uploadedAttachment, loadingAttachment]); - }); - - it('should should not have error state resource if loading in progress', () => { - component.uploadedAttachments = [createErrorStateResource(createApiError())]; - - const uploaded = component.buildUploadedAttachments(loadingAttachment); - - expect(uploaded).toEqual([loadingAttachment]); - }); - }); - - describe('deleteFile', () => { - let existingAttachment: BinaryFileResource; - let uploadedAttachmentStateResource: StateResource<BinaryFileResource>; - - beforeEach(() => { - existingAttachment = createBinaryFileResource(); - uploadedAttachmentStateResource = createStateResource(createBinaryFileResource()); - }); - - it('should call form service', () => { - const file = createBinaryFileResource(); - - component.deleteFile(file); - - expect(formService.deleteFile).toHaveBeenCalledWith(file); - }); - - it('should delete attachment from uploaded', () => { - component.uploadedAttachments = [uploadedAttachmentStateResource]; - - component.deleteFile(uploadedAttachmentStateResource.resource); - - expect(component.uploadedAttachments).toEqual([]); - }); - - it('should leave errors in uploaded', () => { - const error: StateResource<BinaryFileResource> = createStateResource( - createBinaryFileResource(), - ); - component.uploadedAttachments = [error]; - - component.deleteFile(uploadedAttachmentStateResource.resource); - - expect(component.uploadedAttachments).toEqual([error]); - }); - - it('should not delete attachment from existing', () => { - component.uploadedAttachments = [uploadedAttachmentStateResource]; - component.existingAttachments = [existingAttachment]; - - component.deleteFile(uploadedAttachmentStateResource.resource); - - expect(component.existingAttachments).toEqual([existingAttachment]); - }); - - it('should delete attachment from existing', () => { - component.existingAttachments = [existingAttachment]; - - component.deleteFile(existingAttachment); - - expect(component.existingAttachments).toEqual([]); - }); - - it('should not delete attachment from existing', () => { - component.uploadedAttachments = [uploadedAttachmentStateResource]; - component.existingAttachments = [existingAttachment]; - - component.deleteFile(existingAttachment); - - expect(component.uploadedAttachments).toEqual([uploadedAttachmentStateResource]); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts deleted file mode 100644 index 9095679deabf5902fdaed7faab0aafb234e6cda0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService, UploadFileInProgress } from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { - containsLoading, - getSuccessfullyLoaded, - hasStateResourceError, - isLoaded, - isNotNil, - StateResource, -} from '@alfa-client/tech-shared'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { getUrl } from '@ngxp/rest'; -import { first, Observable, Subscription } from 'rxjs'; -import { BescheidenFormService } from '../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-result-attachments', - templateUrl: './vorgang-detail-bescheiden-result-attachments.component.html', - styles: [], -}) -export class VorgangDetailBescheidenResultAttachmentsComponent implements OnDestroy, OnInit { - @Input() public deletable: boolean; - - existingAttachments: BinaryFileResource[] = []; - uploadedAttachments: StateResource<BinaryFileResource>[] = []; - uploadInProgress$: Observable<UploadFileInProgress>; - - private attachmentUploadSubscription: Subscription; - - constructor( - public formService: BescheidenFormService, - private readonly bescheidService: BescheidService, - ) {} - - ngOnInit(): void { - this.uploadInProgress$ = this.bescheidService.getUploadAttachmentInProgress(); - this.loadExistingAttachments(); - this.subscribeToAttachmentUpload(); - } - - ngOnDestroy(): void { - if (isNotNil(this.attachmentUploadSubscription)) - this.attachmentUploadSubscription.unsubscribe(); - } - - loadExistingAttachments() { - this.bescheidService - .getAttachments() - .pipe(first()) - .subscribe((attachments) => { - this.uploadedAttachments = []; - this.existingAttachments = attachments; - }); - } - - subscribeToAttachmentUpload() { - this.attachmentUploadSubscription = this.bescheidService - .getUploadedAttachment() - .subscribe( - (stateResource: StateResource<BinaryFileResource>) => - (this.uploadedAttachments = this.buildUploadedAttachments(stateResource)), - ); - } - - buildUploadedAttachments( - uploadStateResource: StateResource<BinaryFileResource>, - ): StateResource<BinaryFileResource>[] { - if (isLoaded(uploadStateResource) || hasStateResourceError(uploadStateResource)) { - return [...getSuccessfullyLoaded(this.uploadedAttachments), uploadStateResource]; - } else if (uploadStateResource.loading && !containsLoading(this.uploadedAttachments)) { - return [...getSuccessfullyLoaded(this.uploadedAttachments), uploadStateResource]; - } - return this.uploadedAttachments; - } - - deleteFile(file: BinaryFileResource): void { - this.formService.deleteFile(file); - this.uploadedAttachments = this.uploadedAttachments.filter( - (attachment: StateResource<BinaryFileResource>) => - !hasStateResourceError(attachment) && getUrl(attachment.resource) !== getUrl(file), - ); - this.existingAttachments = this.existingAttachments.filter( - (attachment: BinaryFileResource) => getUrl(attachment) !== getUrl(file), - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html deleted file mode 100644 index 549661320fea8f0ec24dd46a61d60959f3b360ed..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html +++ /dev/null @@ -1,67 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<p - *ngIf="showMissingBescheidDocumentError" - data-test-id="missing-bescheid-document-error-message" - class="text-base text-error" -> - Bitte fügen Sie ein Bescheiddokument hinzu. -</p> -<ods-attachment-wrapper> - <ng-container *ngIf="bescheidDocumentFile.resource"> - <alfa-binary-file2-container - *ngIf=" - !bescheidDocumentFile.loading && - !uploadBescheidDocumentInProgress.loading && - !createDocumentInProgess.loading - " - [file]="bescheidDocumentFile.resource" - [deletable]="deletable" - (startDelete)="deleteFile.emit()" - > - </alfa-binary-file2-container> - </ng-container> - <ods-attachment - *ngIf="uploadBescheidDocumentInProgress.loading || uploadBescheidDocumentInProgress.error" - errorCaption="Fehler beim Hochladen" - [loadingCaption]="uploadBescheidDocumentInProgress.fileName" - [attr.data-test-id]=" - 'upload-bescheid-document-error-' + !!uploadBescheidDocumentInProgress.error - " - [isLoading]="uploadBescheidDocumentInProgress.loading" - [errorMessages]="uploadBescheidDocumentInProgress.error | convertProblemDetailToErrorMessages" - description="Bescheiddokument wird hochgeladen" - ></ods-attachment> - <ods-attachment - *ngIf="createDocumentInProgess.loading || hasCreateDocumentError" - errorCaption="Fehler beim automatischen Erstellen" - loadingCaption="Bescheiddokument" - description="Bescheiddokument wird erstellt" - [isLoading]="createDocumentInProgess.loading" - [errorMessages]="createDocumentErrorMessages" - data-test-id="create-bescheid-document-attachment" - ></ods-attachment> -</ods-attachment-wrapper> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts deleted file mode 100644 index 5ea0a01d388e0491b87552821b48f5df9fe32750..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { BinaryFile2ContainerComponent } from '@alfa-client/binary-file'; -import { CommandResource } from '@alfa-client/command-shared'; -import { - StateResource, - createEmptyStateResource, - createStateResource, -} from '@alfa-client/tech-shared'; -import { Mock, existsAsHtmlElement, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { getUrl } from '@ngxp/rest'; -import { AttachmentComponent, AttachmentWrapperComponent } from '@ods/system'; -import { createBescheidResource } from 'libs/bescheid-shared/src/test/bescheid'; -import { createBinaryFileResource } from 'libs/binary-file-shared/test/binary-file'; -import { ConvertProblemDetailToErrorMessagesPipe } from 'libs/tech-shared/src/lib/pipe/convert-problem-detail-to-error-messages.pipe'; -import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { createApiError } from 'libs/tech-shared/test/error'; -import { MockComponent, MockPipe } from 'ng-mocks'; -import { - createCommandErrorStateResource, - createCommandResource, - createCommandStateResource, -} from '../../../../../../../command-shared/test/command'; -import { VorgangDetailBescheidenResultDokumentComponent } from './vorgang-detail-bescheiden-result-dokument.component'; - -describe('VorgangDetailBescheidenResultDokumentComponent', () => { - let component: VorgangDetailBescheidenResultDokumentComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenResultDokumentComponent>; - - const createBescheidDocumentAttachment: string = getDataTestIdOf( - 'create-bescheid-document-attachment', - ); - const uploadBescheidDocumentError: string = getDataTestIdOf( - 'upload-bescheid-document-error-true', - ); - const missingBescheidDocumentErrorMessage: string = getDataTestIdOf( - 'missing-bescheid-document-error-message', - ); - - let bescheidService: Mock<BescheidService>; - - beforeEach(async () => { - bescheidService = mock(BescheidService); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenResultDokumentComponent, - MockComponent(BinaryFile2ContainerComponent), - MockComponent(AttachmentComponent), - MockComponent(AttachmentWrapperComponent), - MockPipe(ConvertProblemDetailToErrorMessagesPipe), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenResultDokumentComponent); - component = fixture.componentInstance; - component.bescheidDocumentFile = createStateResource(createBinaryFileResource()); - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render', () => { - it('should show error message for missing bescheid document', () => { - component.showMissingBescheidDocumentError = true; - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, missingBescheidDocumentErrorMessage); - }); - - it('should not show error message for missing bescheid document', () => { - component.showMissingBescheidDocumentError = false; - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, missingBescheidDocumentErrorMessage); - }); - - describe('create bescheid document ods-attachment', () => { - it('should be shown if error exists', () => { - component.createBescheidDocumentInProgress = createCommandErrorStateResource(); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, createBescheidDocumentAttachment); - }); - - it('should be shown while loading', () => { - component.createBescheidDocumentInProgress = createStateResource( - createCommandResource(), - true, - ); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, createBescheidDocumentAttachment); - }); - - it('should be hidden on loaded without error', () => { - component.createBescheidDocumentInProgress = createCommandStateResource(); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, createBescheidDocumentAttachment); - }); - }); - }); - - describe('handle bescheid document', () => { - it('should call service to load bescheid document by uri if link is present', () => { - const bescheid: BescheidResource = createBescheidResource([ - BescheidLinkRel.BESCHEID_DOCUMENT, - ]); - - component.handleBescheidDocument(bescheid); - - expect(bescheidService.loadBescheidDocumentByUri).toHaveBeenCalledWith( - getUrl(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT), - ); - }); - - it('should NOT call service if link is missing', () => { - component.handleBescheidDocument(createBescheidResource()); - - expect(bescheidService.loadBescheidDocumentByUri).not.toHaveBeenCalled(); - }); - }); - - describe('upload bescheid document error', () => { - it('should be shown if error exists', () => { - component.uploadBescheidDocumentInProgress = { loading: false, error: createApiError() }; - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, uploadBescheidDocumentError); - }); - - it('should be hidden on non error', () => { - component.uploadBescheidDocumentInProgress = { loading: false }; - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, uploadBescheidDocumentError); - }); - }); - - describe('set create bescheid document in progress', () => { - beforeEach(() => { - component.handleCreateBescheidDocumentCommandError = jest.fn(); - }); - - it('should set create document in progress', () => { - const commandStateResource: StateResource<CommandResource> = createEmptyStateResource(); - - component.createBescheidDocumentInProgress = commandStateResource; - - expect(component.createDocumentInProgess).toBe(commandStateResource); - }); - - it('should handle command error', () => { - const commandStateResource: StateResource<CommandResource> = createEmptyStateResource(); - - component.createBescheidDocumentInProgress = commandStateResource; - - expect(component.handleCreateBescheidDocumentCommandError).toHaveBeenCalledWith( - commandStateResource, - ); - }); - }); - - describe('handleCreateBescheidDocumentCommandError', () => { - it('should set has error', () => { - component.handleCreateBescheidDocumentCommandError(createCommandErrorStateResource()); - - expect(component.hasCreateDocumentError).toBeTruthy(); - }); - - it('should not set has error', () => { - component.handleCreateBescheidDocumentCommandError(createCommandStateResource()); - - expect(component.hasCreateDocumentError).toBeFalsy(); - }); - - it('should not set has error on empty state resource', () => { - component.handleCreateBescheidDocumentCommandError(createEmptyStateResource()); - - expect(component.hasCreateDocumentError).toBeFalsy(); - }); - - it('should set error messages', () => { - component.handleCreateBescheidDocumentCommandError(createCommandErrorStateResource()); - - expect(component.createDocumentErrorMessages).toEqual([ - VorgangDetailBescheidenResultDokumentComponent.CREATE_DOCUMENT_ERROR_MESSAGE, - ]); - }); - - it('should not set error messages', () => { - component.handleCreateBescheidDocumentCommandError(createCommandStateResource()); - - expect(component.createDocumentErrorMessages).toEqual([]); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts deleted file mode 100644 index 86b59f535b00aed46987c43c573e79dc4d957a24..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2024 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 { - BescheidLinkRel, - BescheidResource, - BescheidService, - UploadFileInProgress, -} from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { CommandResource, hasCommandError } from '@alfa-client/command-shared'; -import { createEmptyStateResource, isNotNil, StateResource } from '@alfa-client/tech-shared'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { getUrl, hasLink } from '@ngxp/rest'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-result-dokument', - templateUrl: './vorgang-detail-bescheiden-result-dokument.component.html', -}) -export class VorgangDetailBescheidenResultDokumentComponent { - static readonly CREATE_DOCUMENT_ERROR_MESSAGE: string = - 'Bescheiddokument konnte nicht erzeugt werden.'; - - @Input() bescheidDocumentFile: StateResource<BinaryFileResource>; - @Input() uploadBescheidDocumentInProgress: UploadFileInProgress = { loading: false }; - - @Input() set createBescheidDocumentInProgress( - commandStateResource: StateResource<CommandResource>, - ) { - this.createDocumentInProgess = commandStateResource; - this.handleCreateBescheidDocumentCommandError(commandStateResource); - } - - @Input() set bescheidDraftStateResource(bescheidStateResource: StateResource<BescheidResource>) { - this.handleBescheidDocument(bescheidStateResource.resource); - } - - @Input() public deletable: boolean; - - @Input() public showMissingBescheidDocumentError: boolean; - @Output() deleteFile: EventEmitter<void> = new EventEmitter<void>(); - - createDocumentErrorMessages: string[] = []; - createDocumentInProgess: StateResource<CommandResource> = createEmptyStateResource(); - hasCreateDocumentError: boolean = false; - - constructor(private bescheidService: BescheidService) {} - - handleBescheidDocument(bescheid: BescheidResource): void { - if (hasLink(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT)) { - this.bescheidService.loadBescheidDocumentByUri( - getUrl(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT), - ); - } - } - - handleCreateBescheidDocumentCommandError( - commandStateResource: StateResource<CommandResource>, - ): void { - this.hasCreateDocumentError = - isNotNil(commandStateResource.resource) && hasCommandError(commandStateResource.resource); - if (this.hasCreateDocumentError) { - this.createDocumentErrorMessages = [ - VorgangDetailBescheidenResultDokumentComponent.CREATE_DOCUMENT_ERROR_MESSAGE, - ]; - } else { - this.createDocumentErrorMessages = []; - } - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.html deleted file mode 100644 index 3f492daf368d4f0e5a3c2c75c4c5740a8cefb757..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.html +++ /dev/null @@ -1,52 +0,0 @@ -<!-- - - Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den - Ministerpräsidenten des Landes Schleswig-Holstein - Staatskanzlei - Abteilung Digitalisierung und zentrales IT-Management der Landesregierung - - Lizenziert unter der EUPL, Version 1.2 oder - sobald - diese von der Europäischen Kommission genehmigt wurden - - Folgeversionen der EUPL ("Lizenz"); - Sie dürfen dieses Werk ausschließlich gemäß - dieser Lizenz nutzen. - Eine Kopie der Lizenz finden Sie hier: - - https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - - Sofern nicht durch anwendbare Rechtsvorschriften - gefordert oder in schriftlicher Form vereinbart, wird - die unter der Lizenz verbreitete Software "so wie sie - ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - ausdrücklich oder stillschweigend - verbreitet. - Die sprachspezifischen Genehmigungen und Beschränkungen - unter der Lizenz sind dem Lizenztext zu entnehmen. - ---> -<h3 class="mb-3 font-medium text-primary">Neue Nachricht</h3> -<p - *ngIf="empfaenger$ | async as empfaenger" - data-test-id="bescheid-nachricht-empfaenger" - class="mb-2 text-sm font-medium" -> - An: {{ empfaenger }} -</p> -<div [formGroup]="form"> - <ods-text-editor - [formControlName]="formServiceClass.FIELD_NACHRICHT_SUBJECT" - label="Betreff" - placeholder="Betreff hier eingeben" - [focus]="focusBetreff" - [isRequired]="true" - > - </ods-text-editor> - - <ods-textarea-editor - [formControlName]="formServiceClass.FIELD_NACHRICHT_TEXT" - label="Text" - placeholder="Nachrichtentext hier eingeben" - [focus]="focusNachricht" - [isRequired]="true" - > - </ods-textarea-editor> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.spec.ts deleted file mode 100644 index 74477d48db034ee0193f40bc099eb7be07495c3f..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.spec.ts +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService, DocumentResource } from '@alfa-client/bescheid-shared'; -import { - createEmptyStateResource, - createErrorStateResource, - createStateResource, - StateResource, -} from '@alfa-client/tech-shared'; -import { getElementFromFixture } from '@alfa-client/test-utils'; -import { registerLocaleData } from '@angular/common'; -import localeDe from '@angular/common/locales/de'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; -import { faker } from '@faker-js/faker'; -import { TextareaEditorComponent, TextEditorComponent } from '@ods/component'; -import { Mock, mock, useFromMock } from 'libs/test-utils/src/lib/mocking'; -import { OzgcloudSvgIconComponent } from 'libs/ui/src/lib/ui/ozgcloud-svgicon/ozgcloud-svgicon.component'; -import { MockComponent } from 'ng-mocks'; -import { EMPTY, of } from 'rxjs'; -import { createDocumentResource } from '../../../../../../../bescheid-shared/src/test/document'; -import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test'; -import { createApiError } from '../../../../../../../tech-shared/test/error'; -import { singleColdCompleted } from '../../../../../../../tech-shared/test/marbles'; -import { BescheidenFormService } from '../../bescheiden.formservice'; -import { VorgangDetailBescheidenResultNachrichtComponent } from './vorgang-detail-bescheiden-result-nachricht.component'; - -registerLocaleData(localeDe); - -describe('VorgangDetailBescheidenResultNachrichtComponent', () => { - let component: VorgangDetailBescheidenResultNachrichtComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenResultNachrichtComponent>; - - let bescheidService: Mock<BescheidService>; - let formService: BescheidenFormService; - - const bescheidNachrichtEmpfaengerElement: string = getDataTestIdOf( - 'bescheid-nachricht-empfaenger', - ); - - beforeEach(async () => { - bescheidService = mock(BescheidService); - formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - - await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule], - declarations: [ - VorgangDetailBescheidenResultNachrichtComponent, - MockComponent(OzgcloudSvgIconComponent), - MockComponent(TextEditorComponent), - MockComponent(TextareaEditorComponent), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: BescheidenFormService, - useValue: formService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenResultNachrichtComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render', () => { - it('should render Nachrichtenempfänger', () => { - const empfaenger: string = `${faker.person.firstName()} ${faker.person.lastName()}`; - bescheidService.getEmpfaenger.mockReturnValue(of(empfaenger)); - component.ngOnInit(); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, bescheidNachrichtEmpfaengerElement); - expect(element).toBeInstanceOf(HTMLElement); - }); - - it('should not render Nachrichtenempfänger', () => { - bescheidService.getEmpfaenger.mockReturnValue(EMPTY); - component.ngOnInit(); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, bescheidNachrichtEmpfaengerElement); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - }); - - describe('ngOnInit', () => { - it('should set Nachrichtenempfänger', () => { - const empfaenger: string = `${faker.person.firstName()} ${faker.person.lastName()}`; - bescheidService.getEmpfaenger.mockReturnValue(of(empfaenger)); - - component.ngOnInit(); - - expect(component.empfaenger$).toBeObservable(singleColdCompleted(empfaenger)); - }); - }); - - describe('set bescheidDocumentStateResource', () => { - beforeEach(() => { - formService.patchNachricht = jest.fn(); - }); - - it('should patch form', () => { - const documentStateResource: StateResource<DocumentResource> = - createStateResource(createDocumentResource()); - jest.spyOn(formService.form, 'valid', 'get').mockReturnValue(true); - - component.bescheidDocumentStateResource = documentStateResource; - - expect(formService.patchNachricht).toHaveBeenCalledWith(documentStateResource.resource); - }); - - it('should not patch if form is invalid', () => { - const documentStateResource: StateResource<DocumentResource> = - createStateResource(createDocumentResource()); - jest.spyOn(formService.form, 'valid', 'get').mockReturnValue(false); - - component.bescheidDocumentStateResource = documentStateResource; - - expect(formService.patchNachricht).not.toHaveBeenCalledWith(documentStateResource.resource); - }); - - it('should not patch form if document loading', () => { - component.bescheidDocumentStateResource = { ...createEmptyStateResource(), loading: true }; - - expect(formService.patchNachricht).not.toHaveBeenCalled(); - }); - - it('should not patch form if document loaded with error', () => { - component.bescheidDocumentStateResource = createErrorStateResource(createApiError()); - - expect(formService.patchNachricht).not.toHaveBeenCalled(); - }); - - it.each([null, undefined])( - 'should not patch form if document resource is %s', - (resource: DocumentResource) => { - component.bescheidDocumentStateResource = createStateResource(resource); - - expect(formService.patchNachricht).not.toHaveBeenCalled(); - }, - ); - }); - - describe('resetFocus', () => { - it('should reset betreff focus', () => { - component.focusBetreff = true; - - component.resetFocus(); - - expect(component.focusBetreff).toBeFalsy(); - }); - - it('should reset nachricht focus', () => { - component.focusNachricht = true; - - component.resetFocus(); - - expect(component.focusNachricht).toBeFalsy(); - }); - }); - - describe('sendWithNachrichtCommandStateResource', () => { - beforeEach(() => { - component.resetFocus = jest.fn(); - }); - - it('should reset focus', () => { - component.sendWithNachrichtCommandStateResource = createEmptyStateResource(); - - expect(component.resetFocus).toHaveBeenCalled(); - }); - - it('should focus betreff', () => { - component.focusBetreff = false; - formService.isBetreffInvalid = jest.fn().mockReturnValue(true); - formService.isNachrichtInvalid = jest.fn().mockReturnValue(false); - - component.sendWithNachrichtCommandStateResource = createErrorStateResource(createApiError()); - - expect(component.focusBetreff).toBeTruthy(); - }); - - it('should focus nachricht', () => { - component.focusNachricht = false; - formService.isBetreffInvalid = jest.fn().mockReturnValue(false); - formService.isNachrichtInvalid = jest.fn().mockReturnValue(true); - - component.sendWithNachrichtCommandStateResource = createErrorStateResource(createApiError()); - - expect(component.focusNachricht).toBeTruthy(); - }); - - it('should focus betreff first', () => { - component.focusNachricht = false; - component.focusBetreff = false; - formService.isBetreffInvalid = jest.fn().mockReturnValue(true); - formService.isNachrichtInvalid = jest.fn().mockReturnValue(true); - - component.sendWithNachrichtCommandStateResource = createErrorStateResource(createApiError()); - - expect(component.focusBetreff).toBeTruthy(); - expect(component.focusNachricht).toBeFalsy(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.ts deleted file mode 100644 index 9805935d7bf121a66c3c384046acfbb33f620261..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService, DocumentResource } from '@alfa-client/bescheid-shared'; -import { CommandResource } from '@alfa-client/command-shared'; -import { hasStateResourceError, isNotNil, StateResource } from '@alfa-client/tech-shared'; -import { Component, Input, OnInit } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { Observable } from 'rxjs'; -import { BescheidenFormService } from '../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-result-nachricht', - templateUrl: './vorgang-detail-bescheiden-result-nachricht.component.html', -}) -export class VorgangDetailBescheidenResultNachrichtComponent implements OnInit { - @Input() - set bescheidDocumentStateResource(stateResource: StateResource<DocumentResource>) { - if (!stateResource.loading && !stateResource.error && isNotNil(stateResource.resource)) { - if (isNotNil(this.form) && this.form.valid) { - this.formService.patchNachricht(stateResource.resource); - } - } - } - - @Input() - set sendWithNachrichtCommandStateResource(stateResource: StateResource<CommandResource>) { - this.resetFocus(); - if (isNotNil(stateResource) && hasStateResourceError(stateResource)) { - if (this.formService.isBetreffInvalid()) { - this.focusBetreff = true; - } else if (this.formService.isNachrichtInvalid()) { - this.focusNachricht = true; - } - } - } - - resetFocus() { - this.focusBetreff = false; - this.focusNachricht = false; - } - - empfaenger$: Observable<string>; - form: FormGroup; - - public focusBetreff: boolean = false; - public focusNachricht: boolean = false; - - readonly formServiceClass = BescheidenFormService; - - constructor( - private readonly bescheidService: BescheidService, - private readonly formService: BescheidenFormService, - ) {} - - ngOnInit(): void { - this.empfaenger$ = this.bescheidService.getEmpfaenger(); - this.form = this.formService.form; - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.html deleted file mode 100644 index 8326ca0d520668acd781ed322ee654779d593958..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.html +++ /dev/null @@ -1,30 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<ods-bescheid-status-text - [bewilligt]="bescheid.bewilligt" - [dateText]="bescheid.beschiedenAm | date: 'dd.MM.yyyy'" - [hasBescheidDraft]="false" -></ods-bescheid-status-text> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts deleted file mode 100644 index cab1ef05621a6e784834e5296528fc6aa3e8a320..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2024 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 { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatIcon } from '@angular/material/icon'; -import { MatIconTestingModule } from '@angular/material/icon/testing'; -import { BescheidStatusTextComponent } from '@ods/system'; -import { createBescheid } from 'libs/bescheid-shared/src/test/bescheid'; -import { FormatFullDatePipe } from 'libs/tech-shared/src/lib/pipe/format-full-date.pipe'; -import { OzgcloudSvgIconComponent } from 'libs/ui/src/lib/ui/ozgcloud-svgicon/ozgcloud-svgicon.component'; -import { MockComponent } from 'ng-mocks'; -import { VorgangDetailBescheidenResultStatusComponent } from './vorgang-detail-bescheiden-result-status.component'; - -registerLocaleData(localeDe); - -describe('VorgangDetailBescheidenResultStatusComponent', () => { - let component: VorgangDetailBescheidenResultStatusComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenResultStatusComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [MatIconTestingModule], - declarations: [ - VorgangDetailBescheidenResultStatusComponent, - MatIcon, - FormatFullDatePipe, - MockComponent(OzgcloudSvgIconComponent), - MockComponent(BescheidStatusTextComponent), - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenResultStatusComponent); - component = fixture.componentInstance; - component.bescheid = createBescheid(); - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.ts deleted file mode 100644 index 37662cc9de142103c614263b7c28b0848755de40..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2024 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 { Bescheid } from '@alfa-client/bescheid-shared'; -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-result-status', - templateUrl: './vorgang-detail-bescheiden-result-status.component.html', -}) -export class VorgangDetailBescheidenResultStatusComponent { - @Input() bescheid: Bescheid; -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.html deleted file mode 100644 index 1f1fef09c56f5e02db3a38fe54aa85107223fc5e..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.html +++ /dev/null @@ -1,134 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<section - class="flex w-full flex-col justify-between overflow-auto rounded-xl bg-background-100 px-4 py-5" - *ngIf="{ - activeStep: activeStep$ | async, - sendByManual: sendByManual$ | async - } as wizardData" - tabindex="0" -> - <div class="flex-1"> - <h3 - *ngIf="wizardData.sendByManual || wizardData.activeStep !== 3" - class="mb-4 text-base font-bold text-primary-600" - > - Bescheid - </h3> - - <div - class="my-4" - data-test-id="bescheid-status-text" - *ngIf=" - wizardData.activeStep === 1 || - wizardData.activeStep === 2 || - (wizardData.activeStep === 3 && wizardData.sendByManual) - " - > - <alfa-vorgang-detail-bescheiden-result-status - data-test-id="bescheid-status" - [bescheid]="bescheid$ | async" - ></alfa-vorgang-detail-bescheiden-result-status> - </div> - - <div *ngIf="!wizardData.sendByManual && wizardData.activeStep === 3 && (canSend$ | async)"> - <alfa-vorgang-detail-bescheiden-result-nachricht - [bescheidDocumentStateResource]="bescheidDocument$ | async" - [sendWithNachrichtCommandStateResource]="sendWithNachricht$ | async" - data-test-id="bescheid-nachricht-an-antragsteller" - ></alfa-vorgang-detail-bescheiden-result-nachricht> - </div> - - <div - class="my-4" - *ngIf=" - wizardData.activeStep === 2 || - (wizardData.activeStep === 3 && (wizardData.sendByManual || (canSend$ | async))) - " - data-test-id="bescheid-status-dokument" - > - <alfa-vorgang-detail-bescheiden-result-dokument - data-test-id="bescheid-document" - [deletable]="wizardData.activeStep === 2" - [bescheidDraftStateResource]="bescheidDraftStateResource$ | async" - [uploadBescheidDocumentInProgress]="uploadBescheidDocumentInProgress$ | async" - [createBescheidDocumentInProgress]="createBescheidDocumentInProgress$ | async" - [bescheidDocumentFile]="bescheidDocumentFile$ | async" - [showMissingBescheidDocumentError]="showMissingBescheidDocumentError$ | async" - (deleteFile)="deleteBescheidDocument()" - ></alfa-vorgang-detail-bescheiden-result-dokument> - </div> - - <div - class="my-4" - data-test-id="bescheid-status-attachments" - *ngIf=" - wizardData.activeStep === 2 || - (wizardData.activeStep === 3 && (wizardData.sendByManual || (canSend$ | async))) - " - > - <alfa-vorgang-detail-bescheiden-result-attachments - [deletable]="wizardData.activeStep === 2" - data-test-id="bescheid-attachments" - ></alfa-vorgang-detail-bescheiden-result-attachments> - </div> - </div> - <div class="flex-none"> - <div class="flex flex-col"> - <ng-container *ngIf="wizardData.sendByManual && wizardData.activeStep === 3"> - <p class="mb-8 text-base font-normal text-text"> - Der Bescheid muss manuell versendet werden. - </p> - - <ng-container *ngIf="bescheidDraftStateResource$ | async as bescheidDraftStateResource"> - <ods-button-with-spinner - class="self-end" - *ngIf="canSave$ | async" - data-test-id="confirm-and-save-button" - [stateResource]="saveAndSendInProgress$ | async" - text="Antrag bescheiden und speichern" - (clickEmitter)="saveAndSendManually(bescheidDraftStateResource.resource)" - ></ods-button-with-spinner> - </ng-container> - <!-- --> - </ng-container> - <ng-container - *ngIf="wizardData.activeStep === 3 && !wizardData.sendByManual && (canSend$ | async)" - > - <ng-container *ngIf="bescheidDraftStateResource$ | async as bescheidDraftStateResource"> - <ods-button-with-spinner - class="self-end" - *ngIf="canSend$ | async" - data-test-id="send-button" - [stateResource]="saveAndSendInProgress$ | async" - text="Bescheid senden" - (clickEmitter)="saveAndSendWithNachricht(bescheidDraftStateResource.resource)" - ></ods-button-with-spinner> - </ng-container> - </ng-container> - </div> - </div> -</section> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.spec.ts deleted file mode 100644 index 48eff7cb96f976e67260ca3bc8d6cb84723900cb..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.spec.ts +++ /dev/null @@ -1,719 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandOrder, CommandResource } from '@alfa-client/command-shared'; -import { - createEmptyStateResource, - createStateResource, - StateResource, -} from '@alfa-client/tech-shared'; -import { - dispatchEventFromFixture, - existsAsHtmlElement, - getElementFromFixture, - Mock, - mock, - notExistsAsHtmlElement, -} from '@alfa-client/test-utils'; -import { OzgcloudButtonWithSpinnerComponent } from '@alfa-client/ui'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ButtonWithSpinnerComponent } from '@ods/component'; -import { - createBescheidResource, - createBescheidStateResource, -} from 'libs/bescheid-shared/src/test/bescheid'; -import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { - createCommandResource, - createCommandStateResource, -} from 'libs/command-shared/test/command'; -import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; -import { BehaviorSubject, EMPTY, first, of } from 'rxjs'; -import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles'; -import { BescheidenFormService } from '../bescheiden.formservice'; -import { VorgangDetailBescheidenResultAttachmentsComponent } from './vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component'; -import { VorgangDetailBescheidenResultDokumentComponent } from './vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component'; -import { VorgangDetailBescheidenResultNachrichtComponent } from './vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component'; -import { VorgangDetailBescheidenResultStatusComponent } from './vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component'; -import { VorgangDetailBescheidenResultComponent } from './vorgang-detail-bescheiden-result.component'; - -describe('VorgangDetailBescheidenResultComponent', () => { - let component: VorgangDetailBescheidenResultComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenResultComponent>; - - let bescheidService: Mock<BescheidService>; - let formService: Mock<BescheidenFormService>; - - const bescheidStatus: string = getDataTestIdOf('bescheid-status'); - const bescheidDocument: string = getDataTestIdOf('bescheid-document'); - const bescheidAttachments: string = getDataTestIdOf('bescheid-attachments'); - const saveAndSendButton: string = getDataTestIdOf('confirm-and-save-button'); - const sendButton: string = getDataTestIdOf('send-button'); - const nachrichtAntragstellerComponent = getDataTestIdOf('bescheid-nachricht-an-antragsteller'); - - beforeEach(async () => { - bescheidService = mock(BescheidService); - bescheidService.getBescheidDraft.mockReturnValue(EMPTY); - - formService = mock(BescheidenFormService); - formService.getBescheidChanges.mockReturnValue( - new BehaviorSubject({ beschiedenAm: new Date(), bewilligt: false }), - ); - formService.getActiveStep.mockReturnValue(EMPTY); - formService.isSendByManual.mockReturnValue(EMPTY); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenResultComponent, - MockComponent(VorgangDetailBescheidenResultStatusComponent), - MockComponent(VorgangDetailBescheidenResultDokumentComponent), - MockComponent(VorgangDetailBescheidenResultAttachmentsComponent), - MockComponent(OzgcloudButtonWithSpinnerComponent), - MockComponent(VorgangDetailBescheidenResultNachrichtComponent), - MockComponent(ButtonWithSpinnerComponent), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: BescheidenFormService, - useValue: formService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenResultComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render Nachricht component', () => { - it('should render', () => { - formService.getActiveStep.mockReturnValue(of(3)); - formService.isSendByManual.mockReturnValue(of(false)); - component.ngOnInit(); - component.canSend$ = of(true); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, nachrichtAntragstellerComponent); - expect(element).toBeInstanceOf(HTMLElement); - }); - - it.each([1, 2])('should not render in step %d', (step) => { - formService.getActiveStep.mockReturnValue(of(step)); - formService.isSendByManual.mockReturnValue(of(false)); - component.ngOnInit(); - component.canSend$ = of(true); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, nachrichtAntragstellerComponent); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should not render if send by manual', () => { - formService.getActiveStep.mockReturnValue(of(3)); - formService.isSendByManual.mockReturnValue(of(true)); - component.ngOnInit(); - component.canSend$ = of(true); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, nachrichtAntragstellerComponent); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should not render if postfach not configured', () => { - formService.getActiveStep.mockReturnValue(of(3)); - formService.isSendByManual.mockReturnValue(of(false)); - component.ngOnInit(); - component.canSend$ = of(false); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, nachrichtAntragstellerComponent); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - }); - - describe('render send button', () => { - it('should render', () => { - formService.getActiveStep.mockReturnValue(of(3)); - formService.isSendByManual.mockReturnValue(of(false)); - bescheidService.getBescheidDraft.mockReturnValue( - of(createStateResource(createBescheidResource())), - ); - component.ngOnInit(); - component.canSend$ = of(true); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, sendButton); - expect(element).toBeInstanceOf(HTMLElement); - }); - - it.each([1, 2])('should not render in step %d', (step) => { - formService.getActiveStep.mockReturnValue(of(step)); - formService.isSendByManual.mockReturnValue(of(false)); - component.ngOnInit(); - component.canSend$ = of(true); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, sendButton); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should not render if send by manual', () => { - formService.getActiveStep.mockReturnValue(of(3)); - formService.isSendByManual.mockReturnValue(of(true)); - component.ngOnInit(); - component.canSend$ = of(true); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, sendButton); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should not render if postfach not configured', () => { - formService.getActiveStep.mockReturnValue(of(3)); - formService.isSendByManual.mockReturnValue(of(false)); - component.ngOnInit(); - component.canSend$ = of(false); - - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, sendButton); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - }); - - describe('ngOnInit', () => { - it('should call service to get bescheid document file', () => { - component.ngOnInit(); - - expect(bescheidService.getBescheidDocumentFile).toHaveBeenCalled(); - }); - - it('should call service to get bescheid draft', () => { - component.ngOnInit(); - - expect(bescheidService.getBescheidDraft).toHaveBeenCalled(); - }); - - it('should call service to get bescheid document', () => { - component.ngOnInit(); - - expect(bescheidService.getBescheidDocument).toHaveBeenCalled(); - }); - - it('should call formservice to get current bescheid/formular', () => { - component.ngOnInit(); - - expect(formService.getBescheidChanges).toHaveBeenCalled(); - }); - - it('should get is send by manual', () => { - component.getIsSendManually = jest.fn(); - - component.ngOnInit(); - - expect(component.getIsSendManually).toHaveBeenCalled(); - }); - - it('should call service to get upload bescheid document in progress', () => { - component.ngOnInit(); - - expect(bescheidService.getUploadBescheidDocumentInProgress).toHaveBeenCalled(); - }); - - it('should call service to get create bescheid document in progress', () => { - component.ngOnInit(); - - expect(bescheidService.getCreateBescheidDocumentInProgress).toHaveBeenCalled(); - }); - - it('should get active step', () => { - component.getActiveStep = jest.fn(); - - component.ngOnInit(); - - expect(component.getActiveStep).toHaveBeenCalled(); - }); - - describe('canSave$', () => { - it('should emit true', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of(createBescheidStateResource([BescheidLinkRel.BESCHEIDEN])), - ); - component.ngOnInit(); - - expect(component.canSave$).toBeObservable(singleColdCompleted(true)); - }); - - it('should emit false', () => { - bescheidService.getBescheidDraft.mockReturnValue(of(createBescheidStateResource())); - component.ngOnInit(); - - expect(component.canSave$).toBeObservable(singleColdCompleted(false)); - }); - }); - - describe('canSend$', () => { - it('should emit true', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of(createBescheidStateResource([BescheidLinkRel.BESCHEIDEN_UND_SENDEN])), - ); - component.ngOnInit(); - - expect(component.canSend$).toBeObservable(singleColdCompleted(true)); - }); - - it('should emit false', () => { - bescheidService.getBescheidDraft.mockReturnValue(of(createBescheidStateResource())); - component.ngOnInit(); - - expect(component.canSend$).toBeObservable(singleColdCompleted(false)); - }); - }); - - describe('showMissingBescheidDocumentError$', () => { - it('should emit true', () => { - formService.getShowMissingBescheidDocumentError.mockReturnValue(of(true)); - - component.ngOnInit(); - - expect(component.showMissingBescheidDocumentError$).toBeObservable( - singleColdCompleted(true), - ); - }); - - it('should emit false', () => { - formService.getShowMissingBescheidDocumentError.mockReturnValue(of(false)); - - component.ngOnInit(); - - expect(component.showMissingBescheidDocumentError$).toBeObservable( - singleColdCompleted(false), - ); - }); - }); - }); - - describe('deleteBescheidDocument', () => { - it('should call service to delete bescheid document', () => { - component.deleteBescheidDocument(); - - expect(bescheidService.deleteBescheidDocument).toHaveBeenCalled(); - }); - - it('should clear bescheid document file', () => { - component.deleteBescheidDocument(); - - expect(formService.clearBescheidDocumentFile).toHaveBeenCalled(); - }); - }); - - describe('save and send manually', () => { - const bescheidDraft: BescheidResource = createBescheidResource(); - const bescheidStateResource: StateResource<BescheidResource> = - createStateResource(bescheidDraft); - - beforeEach(() => { - component.bescheidDraftStateResource$ = of(bescheidStateResource); - component.sendByManual$ = of(true); - component.activeStep$ = of(3); - }); - - it('should clear nachricht', () => { - component.doUpdateAndSend = jest.fn(); - - component.saveAndSendManually(bescheidDraft); - - expect(formService.clearNachricht).toHaveBeenCalled(); - }); - - it('should call component on event dispatch', () => { - component.saveAndSendManually = jest.fn(); - component.canSave$ = of(true); - - fixture.detectChanges(); - - dispatchEventFromFixture(fixture, saveAndSendButton, 'clickEmitter'); - - expect(component.saveAndSendManually).toHaveBeenCalledWith(bescheidDraft); - }); - - it('should call do update and send', () => { - component.doUpdateAndSend = jest.fn(); - - component.saveAndSendManually(bescheidDraft); - - expect(component.doUpdateAndSend).toHaveBeenCalled(); - }); - }); - - describe('save and send with Nachricht', () => { - const bescheidDraft: BescheidResource = createBescheidResource(); - const bescheidStateResource: StateResource<BescheidResource> = - createStateResource(bescheidDraft); - let doUpdateAndSendMock: jest.Mock; - - beforeEach(() => { - component.bescheidDraftStateResource$ = of(bescheidStateResource); - component.sendByManual$ = of(true); - component.activeStep$ = of(3); - doUpdateAndSendMock = component.doUpdateAndSend = jest.fn(); - }); - - it('should call do update and send', () => { - component.saveAndSendWithNachricht(bescheidDraft); - - expect(doUpdateAndSendMock).toHaveBeenCalledWith(bescheidDraft, expect.any(Function)); - }); - - it('should send bescheid to antragsteller', () => { - bescheidService.sendBescheidToAntragsteller.mockReturnValue(of(createCommandStateResource())); - component.saveAndSendWithNachricht(bescheidDraft); - const sendCallback = doUpdateAndSendMock.mock.calls[0][1]; - - sendCallback(bescheidDraft); - - expect(bescheidService.sendBescheidToAntragsteller).toHaveBeenCalledWith(bescheidDraft); - }); - - it('should emit send nachricht', () => { - const sendCommandStateResource: StateResource<CommandResource> = createCommandStateResource(); - bescheidService.sendBescheidToAntragsteller.mockReturnValue(of(sendCommandStateResource)); - component.saveAndSendWithNachricht(bescheidDraft); - const sendCallback = doUpdateAndSendMock.mock.calls[0][1]; - - sendCallback(bescheidDraft).subscribe(); - - expect(component.sendWithNachricht$.value).toEqual(sendCommandStateResource); - }); - }); - - describe('doUpdateAndSend', () => { - const bescheidDraft: BescheidResource = createBescheidResource(); - const commandStateResource: StateResource<CommandResource> = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); - - beforeEach(() => { - component.sendByManual$ = of(true); - formService.submit = jest.fn().mockReturnValue(of(commandStateResource)); - }); - - it('should call formservice submit', () => { - component.doUpdateAndSend(bescheidDraft, jest.fn()).subscribe(); - - expect(formService.submit).toHaveBeenCalled(); - }); - - it('should call send after successfully update', () => { - component.doSendAfterSuccessfullyUpdate = jest.fn(); - const sendMock = jest.fn(); - - component.doUpdateAndSend(bescheidDraft, sendMock).subscribe(); - - expect(component.doSendAfterSuccessfullyUpdate).toHaveBeenCalledWith(bescheidDraft, sendMock); - }); - - it('should close dialog on successfully done command', () => { - const sendMock = jest.fn(); - formService.submit = jest.fn().mockReturnValue( - of( - createStateResource({ - ...createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - order: CommandOrder.SEND_BESCHEID, - }), - ), - ); - const emit = (component.closeDialog.emit = jest.fn()); - - component.doUpdateAndSend(bescheidDraft, sendMock).subscribe(); - - expect(emit).toHaveBeenCalled(); - }); - }); - - describe('doSendAfterSuccessfullyUpdate', () => { - const bescheidDraft: BescheidResource = createBescheidResource(); - - it('should call send', () => { - const commandStateResource: StateResource<CommandResource> = createStateResource( - createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]), - ); - const sendMock = jest.fn(); - - component - .doSendAfterSuccessfullyUpdate(bescheidDraft, sendMock)(of(commandStateResource)) - .subscribe(); - - expect(sendMock).toHaveBeenCalled(); - }); - - it('should not call send', () => { - const commandStateResource: StateResource<CommandResource> = createEmptyStateResource(); - const sendMock = jest.fn(); - - component - .doSendAfterSuccessfullyUpdate(bescheidDraft, sendMock)(of(commandStateResource)) - .subscribe(); - - expect(sendMock).not.toHaveBeenCalled(); - }); - }); - - describe('bescheid status text', () => { - it('should NOT be visible on NOT send by manual', () => { - component.sendByManual$ = of(false); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidStatus); - }); - - it('should NOT be visible on step 3 and NOT send by manual', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(3); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidStatus); - }); - }); - - describe('bescheid document', () => { - it('should NOT be visible on NOT send by manual', () => { - component.sendByManual$ = of(false); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidDocument); - }); - - it('should NOT be visible on step 3', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(3); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidDocument); - }); - - it('should NOT be visible on step 1', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(1); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidDocument); - }); - - it('should be visible in step 3 when link exists', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(3); - component.canSend$ = of(true); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, bescheidDocument); - }); - }); - - describe('bescheid attachments', () => { - it('should NOT be visible on NOT send by manual', () => { - component.sendByManual$ = of(false); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidAttachments); - }); - - it('should NOT be visible on step 3', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(3); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidAttachments); - }); - - it('should NOT be visible on step 1', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(1); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, bescheidAttachments); - }); - - it('should be visible in step 3 when postfach is configured', () => { - component.sendByManual$ = of(false); - component.activeStep$ = of(3); - component.canSend$ = of(true); - - fixture.detectChanges(); - - existsAsHtmlElement(fixture, bescheidAttachments); - }); - }); - - describe('update and bescheiden', () => { - it('should NOT be visible on step 1', () => { - component.sendByManual$ = of(false); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, saveAndSendButton); - }); - - it('should NOT be visible on setp 2', () => { - component.sendByManual$ = of(false); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, saveAndSendButton); - }); - it('should NOT be visible on step 3 and NOT send by manual', () => { - component.sendByManual$ = of(false); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, saveAndSendButton); - }); - }); - - describe('resetSend', () => { - it('should set to empty state resource', () => { - component.saveAndSendInProgress$ = of(createStateResource(createCommandResource())); - - component.resetSend(); - - expect(component.saveAndSendInProgress$).toBeObservable( - singleColdCompleted(createEmptyStateResource()), - ); - }); - }); - - describe('get active step', () => { - it('should call formService', () => { - component.getActiveStep().subscribe(); - - expect(formService.getActiveStep).toHaveBeenCalled(); - }); - - it.each([1, VorgangDetailBescheidenResultComponent.BESCHEID_VERSENDEN_STEP])( - 'should call bescheidService to clear attachment upload on step %s', - (step: number) => { - formService.getActiveStep.mockReturnValue(of(step)); - - component.getActiveStep().subscribe(); - - expect(bescheidService.clearAttachmentUpload).toHaveBeenCalled(); - }, - ); - - describe('reset send', () => { - beforeEach(() => { - component.resetSend = jest.fn(); - }); - - it.each([1, VorgangDetailBescheidenResultComponent.ADD_DOCUMENTS_STEP])( - 'should be called on step %s', - (step: number) => { - formService.getActiveStep.mockReturnValue(of(step)); - - component.getActiveStep().subscribe(); - - expect(component.resetSend).toHaveBeenCalled(); - }, - ); - - it('should not be called on last step', () => { - formService.getActiveStep.mockReturnValue(of(3)); - - component.getActiveStep().subscribe(); - - expect(component.resetSend).not.toHaveBeenCalled(); - }); - }); - }); - - describe('reset send', () => { - it('should clear saveAndSendInProgress', (done) => { - component.saveAndSendInProgress$ = of(createCommandStateResource()); - - component.resetSend(); - - component.saveAndSendInProgress$ - .subscribe((saveAndSendInProgress: StateResource<CommandResource>) => { - expect(saveAndSendInProgress).toEqual(createEmptyStateResource()); - done(); - }); - }); - - it('should clear sendWithNachricht', () => { - component.sendWithNachricht$.next(createCommandStateResource()); - - component.resetSend(); - - expect(component.sendWithNachricht$.value).toEqual(createEmptyStateResource()); - }); - }); - - describe('getIsSendManually', () => { - beforeEach(() => { - component.resetSend = jest.fn(); - }); - - it('should get is send by manual from from service', () => { - component.getIsSendManually(); - - expect(formService.isSendByManual).toHaveBeenCalled(); - }); - - it.each([true, false])( - 'should reset send if send by manual is %s', - (isSendByManual: boolean) => { - formService.isSendByManual.mockReturnValue(of(isSendByManual)); - - component.getIsSendManually().subscribe(); - - expect(component.resetSend).toHaveBeenCalled(); - }, - ); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.ts deleted file mode 100644 index 5b77ac192ea34a4479534bef624a6ba3e24bb3ac..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component.ts +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2024 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 { - Bescheid, - BescheidLinkRel, - BescheidResource, - BescheidService, - DocumentResource, - UploadFileInProgress, -} from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { - CommandOrder, - CommandResource, - switchMapCommandSuccessfullyDone, - tapOnCommandSuccessfullyDone, -} from '@alfa-client/command-shared'; -import { createEmptyStateResource, isLoaded, StateResource } from '@alfa-client/tech-shared'; -import { Component, EventEmitter, OnInit, Output } from '@angular/core'; -import { hasLink } from '@ngxp/rest'; -import { BehaviorSubject, filter, map, Observable, of, OperatorFunction, tap } from 'rxjs'; -import { BescheidenFormService } from '../bescheiden.formservice'; - -type sendBescheid = (BescheidResource: BescheidResource) => Observable<StateResource<CommandResource>>; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-result', - templateUrl: './vorgang-detail-bescheiden-result.component.html', -}) -export class VorgangDetailBescheidenResultComponent implements OnInit { - static readonly ADD_DOCUMENTS_STEP: number = 2; - static readonly BESCHEID_VERSENDEN_STEP: number = 3; - - @Output() closeDialog: EventEmitter<void> = new EventEmitter(); - - public activeStep$: Observable<number>; - public bescheid$: Observable<Bescheid>; - public sendByManual$: Observable<boolean>; - - public bescheidDraftStateResource$: Observable<StateResource<BescheidResource>> = - of(createEmptyStateResource<BescheidResource>()); - public bescheidDocumentFile$: Observable<StateResource<BinaryFileResource>> = - of(createEmptyStateResource<BinaryFileResource>()); - public bescheidDocument$: Observable<StateResource<DocumentResource>> = of(createEmptyStateResource<DocumentResource>()); - public saveAndSendInProgress$: Observable<StateResource<CommandResource>> = of(createEmptyStateResource<CommandResource>()); - - public uploadBescheidDocumentInProgress$: Observable<UploadFileInProgress> = of({ - loading: false, - }); - - public createBescheidDocumentInProgress$: Observable<StateResource<CommandResource>> = - of(createEmptyStateResource<CommandResource>()); - - public sendWithNachricht$: BehaviorSubject<StateResource<CommandResource>> = new BehaviorSubject( - createEmptyStateResource<CommandResource>(), - ); - - public canSave$: Observable<boolean> = of(true); - public canSend$: Observable<boolean> = of(true); - public showMissingBescheidDocumentError$: Observable<boolean> = of(false); - - public bescheidLinkRel = BescheidLinkRel; - - constructor( - private bescheidService: BescheidService, - public formService: BescheidenFormService, - ) {} - - ngOnInit(): void { - this.bescheidDraftStateResource$ = this.bescheidService.getBescheidDraft(); - this.bescheidDocumentFile$ = this.bescheidService.getBescheidDocumentFile(); - this.uploadBescheidDocumentInProgress$ = this.bescheidService.getUploadBescheidDocumentInProgress(); - this.createBescheidDocumentInProgress$ = this.bescheidService.getCreateBescheidDocumentInProgress(); - this.bescheidDocument$ = this.bescheidService.getBescheidDocument(); - - this.activeStep$ = this.getActiveStep(); - this.bescheid$ = this.formService.getBescheidChanges(); - this.sendByManual$ = this.getIsSendManually(); - - this.canSave$ = this.bescheidDraftStateResource$.pipe( - filter(isLoaded), - map((stateResource: StateResource<BescheidResource>) => hasLink(stateResource.resource, BescheidLinkRel.BESCHEIDEN)), - ); - this.canSend$ = this.bescheidDraftStateResource$.pipe( - filter(isLoaded), - map((stateResource: StateResource<BescheidResource>) => - hasLink(stateResource.resource, BescheidLinkRel.BESCHEIDEN_UND_SENDEN), - ), - ); - this.showMissingBescheidDocumentError$ = this.formService.getShowMissingBescheidDocumentError(); - } - - getActiveStep(): Observable<number> { - return this.formService.getActiveStep().pipe(tap((step: number) => this.resetStateOnStepChange(step))); - } - - getIsSendManually(): Observable<boolean> { - return this.formService.isSendByManual().pipe(tap(() => this.resetSend())); - } - - private resetStateOnStepChange(step: number): void { - if (this.isNotLast(step)) this.resetSend(); - if (this.shouldClearAttachmentInProgress(step)) this.bescheidService.clearAttachmentUpload(); - } - - private isNotLast(step: number): boolean { - return step < VorgangDetailBescheidenResultComponent.BESCHEID_VERSENDEN_STEP; - } - - private shouldClearAttachmentInProgress(step: number): boolean { - return step != VorgangDetailBescheidenResultComponent.ADD_DOCUMENTS_STEP; - } - - resetSend(): void { - this.saveAndSendInProgress$ = of(createEmptyStateResource<CommandResource>()); - this.sendWithNachricht$.next(createEmptyStateResource<CommandResource>()); - } - - public deleteBescheidDocument(): void { - this.formService.clearBescheidDocumentFile(); - this.bescheidService.deleteBescheidDocument(); - } - - public saveAndSendManually(bescheidDraft: BescheidResource): void { - this.formService.clearNachricht(); - this.saveAndSendInProgress$ = this.doUpdateAndSend(bescheidDraft, (bescheidResource) => - this.bescheidService.sendBescheidManually(bescheidResource), - ); - } - - public saveAndSendWithNachricht(bescheidDraft: BescheidResource): void { - this.saveAndSendInProgress$ = this.doUpdateAndSend(bescheidDraft, (bescheidResource) => - this.bescheidService - .sendBescheidToAntragsteller(bescheidResource) - .pipe( - tap((sendCommandStateResource: StateResource<CommandResource>) => - this.sendWithNachricht$.next(sendCommandStateResource), - ), - ), - ); - } - - doUpdateAndSend(bescheidDraft: BescheidResource, send: sendBescheid): Observable<StateResource<CommandResource>> { - return this.formService.submit(this.doSendAfterSuccessfullyUpdate(bescheidDraft, send)).pipe( - tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => { - if (this.isSendBescheidCommand(commandStateResource)) { - this.closeDialog.emit(); - } - }), - ); - } - - doSendAfterSuccessfullyUpdate( - bescheidDraft: BescheidResource, - send: sendBescheid, - ): OperatorFunction<StateResource<CommandResource>, StateResource<CommandResource>> { - return switchMapCommandSuccessfullyDone(() => send(bescheidDraft)); - } - - private isSendBescheidCommand(commandStateResource: StateResource<CommandResource>): boolean { - return commandStateResource.resource.order == CommandOrder.SEND_BESCHEID; - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.html deleted file mode 100644 index ebdc411aa0cc5ffaaed9348339c0817af48b2838..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.html +++ /dev/null @@ -1,86 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div class="relative z-10 flex min-h-28 flex-col items-center"> - <div - class="-z-1 absolute w-1" - [ngClass]=" - step === 1 ? - isPrevious() ? 'bottom-0 top-2 bg-primary-600' - : 'bottom-0 top-2 bg-gray-500' - : step === 2 ? - isPrevious() ? 'bottom-0 top-0 bg-primary-600' - : 'bottom-0 top-0 bg-gray-500' - : step === 3 ? - isActive() ? 'top-0 h-2 bg-primary-600' - : 'top-0 h-2 bg-gray-500' - : '' - " - aria-hidden="true" - ></div> - - <button - class="z-10 flex" - (click)="clickHandler(step)" - [ngClass]="isPrevious() ? 'cursor-pointer' : 'cursor-default'" - [attr.data-test-id]=" - step === 1 ? 'step-1-button' - : step === 2 ? 'step-2-button' - : step === 3 ? 'step-3-button' - : '' - " - role="tab" - [attr.aria-selected]="isActive()" - [attr.aria-disabled]="!isActive()" - attr.aria-controls="vorgang-detail-bescheiden-step-content-{{ step }}" - [tabindex]=" - isActive() ? '0' - : isPrevious() ? '0' - : '-1' - " - [attr.aria-label]=" - step === 1 ? 'Step 1. Antrag bescheiden' - : step === 2 ? 'Step 2. Dokumente hinzufügen' - : step === 3 ? 'Step 3. Bescheid versenden' - : '' - " - > - <span - class="flex size-10 items-center justify-center rounded-full" - [ngClass]=" - isActive() ? - 'border-4 border-primary-600 bg-background-50' - : 'border-transparent bg-transparent' - " - > - <span - class="flex size-7 items-center justify-center rounded-full text-sm text-whitetext" - [ngClass]="isPrevious() || isActive() ? 'bg-primary-600' : 'bg-gray-500'" - > - {{ step }} - </span> - </span> - </button> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.spec.ts deleted file mode 100644 index 80d87d9ba66ebeaf56908ce56266ae501417a6ec..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.spec.ts +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2024 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 { mock } from '@alfa-client/test-utils'; -import { EventEmitter } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { VorgangDetailBescheidenStepButtonComponent } from './vorgang-detail-bescheiden-step-button.component'; - -describe('VorgangDetailBescheidenStepButtonComponent', () => { - let component: VorgangDetailBescheidenStepButtonComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenStepButtonComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [VorgangDetailBescheidenStepButtonComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenStepButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('isActive', () => { - it('return true if step equals activeStep', () => { - component.step = 2; - component.activeStep = 2; - - expect(component.isActive()).toBeTruthy(); - }); - - it('return false if step not equals activeStep', () => { - component.step = 1; - component.activeStep = 2; - - expect(component.isActive()).toBeFalsy(); - }); - }); - - describe('isPrevious', () => { - it('return true if step is less than activeStep', () => { - component.step = 1; - component.activeStep = 2; - - expect(component.isPrevious()).toBeTruthy(); - }); - - it('return false if step equals activeStep', () => { - component.step = 2; - component.activeStep = 2; - - expect(component.isPrevious()).toBeFalsy(); - }); - - it('return false if step is greater than activeStep', () => { - component.step = 3; - component.activeStep = 2; - - expect(component.isPrevious()).toBeFalsy(); - }); - }); - - describe('isNext', () => { - it('return false if step is less than activeStep', () => { - component.step = 1; - component.activeStep = 2; - - expect(component.isNext()).toBeFalsy(); - }); - - it('return false if step equals activeStep', () => { - component.step = 2; - component.activeStep = 2; - - expect(component.isNext()).toBeFalsy(); - }); - - it('return true if step is greater than activeStep', () => { - component.step = 3; - component.activeStep = 2; - - expect(component.isNext()).toBeTruthy(); - }); - }); - - describe('clickHandler', () => { - const isPreviousMock = jest.fn(); - beforeEach(() => { - component.isPrevious = isPreviousMock; - component.activeStepChange = <any>mock(EventEmitter); - }); - - it('should emit step', () => { - isPreviousMock.mockReturnValue(true); - - component.clickHandler(1); - - expect(component.activeStepChange.emit).toHaveBeenCalledWith(1); - }); - - it('should not emit step', () => { - isPreviousMock.mockReturnValue(false); - - component.clickHandler(1); - - expect(component.activeStepChange.emit).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.ts deleted file mode 100644 index 31db0b3d312a443b44bb5dfce4ca48312e8f081b..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component, EventEmitter, Input, Output } from '@angular/core'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-step-button', - templateUrl: './vorgang-detail-bescheiden-step-button.component.html', -}) -export class VorgangDetailBescheidenStepButtonComponent { - @Input() step: number; - @Input() activeStep: number; - @Output() activeStepChange = new EventEmitter<number>(); - - clickHandler(step: number): void { - if (this.isPrevious()) { - this.activeStepChange.emit(step); - } - } - - isActive(): boolean { - return this.step === this.activeStep; - } - - isPrevious(): boolean { - return this.step < this.activeStep; - } - - isNext(): boolean { - return this.step > this.activeStep; - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.html deleted file mode 100644 index cab555ca05bae46a71f42f86ca9ace915ad4c98e..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.html +++ /dev/null @@ -1,42 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div role="tablist"> - <alfa-vorgang-detail-bescheiden-step-button - [activeStep]="activeStep" - (activeStepChange)="changeActiveStep($event)" - [step]="1" - ></alfa-vorgang-detail-bescheiden-step-button> - <alfa-vorgang-detail-bescheiden-step-button - [activeStep]="activeStep" - (activeStepChange)="changeActiveStep($event)" - [step]="2" - ></alfa-vorgang-detail-bescheiden-step-button> - <alfa-vorgang-detail-bescheiden-step-button - [activeStep]="activeStep" - (activeStepChange)="changeActiveStep($event)" - [step]="3" - ></alfa-vorgang-detail-bescheiden-step-button> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.spec.ts deleted file mode 100644 index c20c00972f5b3e09dce3b3455aa2ec25e3f453e0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.spec.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; -import { EventEmitter } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MockComponent } from 'ng-mocks'; -import { BescheidenFormService } from '../../bescheiden.formservice'; -import { VorgangDetailBescheidenStepButtonComponent } from './vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component'; -import { VorgangDetailBescheidenStepButtonsComponent } from './vorgang-detail-bescheiden-step-buttons.component'; - -describe('VorgangDetailBescheidenStepButtonsComponent', () => { - let component: VorgangDetailBescheidenStepButtonsComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenStepButtonsComponent>; - - const formService: Mock<BescheidenFormService> = mock(BescheidenFormService); - const bescheidService: Mock<BescheidService> = mock(BescheidService); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenStepButtonsComponent, - MockComponent(VorgangDetailBescheidenStepButtonComponent), - ], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenStepButtonsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('changeActiveStep', () => { - const step: number = 1; - beforeEach(() => { - component.activeStepChange = <any>mock(EventEmitter); - }); - - it('should emit step', () => { - component.changeActiveStep(step); - - expect(component.activeStepChange.emit).toHaveBeenCalledWith(step); - }); - - it('should set active step in formservice', () => { - component.changeActiveStep(step); - - expect(formService.setActiveStep).toHaveBeenCalledWith(step); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.ts deleted file mode 100644 index 41e080d47b77c6f46fed0a914131e8df9fc3f501..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component, EventEmitter, Input, Output } from '@angular/core'; -import { BescheidenFormService } from '../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-step-buttons', - templateUrl: './vorgang-detail-bescheiden-step-buttons.component.html', -}) -export class VorgangDetailBescheidenStepButtonsComponent { - @Input() activeStep: number = 1; - @Output() activeStepChange = new EventEmitter<number>(); - - constructor(private formService: BescheidenFormService) {} - - public changeActiveStep(step: number): void { - this.formService.setActiveStep(step); - this.activeStepChange.emit(step); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.html deleted file mode 100644 index 8a82e62b23b248ab3ba1b6521b34f0b6eba6538f..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.html +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div class="text-base font-bold text-primary-600" data-test-id="step-caption"> - {{ label }} -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.ts deleted file mode 100644 index b32755681354bc47070662b8a151ab1c21c78497..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component, Input } from '@angular/core'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-step-title', - templateUrl: './vorgang-detail-bescheiden-step-title.component.html', -}) -export class VorgangDetailBescheidenStepTitleComponent { - @Input() - public label: string; -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.html deleted file mode 100644 index 1670968d3dc1333bca788a7e6f9a3991d9c93942..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.html +++ /dev/null @@ -1,32 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<button - (click)="clickEmitter.emit()" - class="absolute right-3 top-3 text-text" - data-test-id="close-bescheid" -> - <mat-icon>close</mat-icon> -</button> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.spec.ts deleted file mode 100644 index f332bc85b62e81c0cdfa31a5f1f0596c42e89a1c..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2024 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 { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatIcon } from '@angular/material/icon'; -import { VorgangDetailBescheidenAbbrechenButtonComponent } from './vorgang-detail-bescheiden-abbrechen-button.component'; - -describe('VorgangDetailBescheidenAbbrechenButtonComponent', () => { - let component: VorgangDetailBescheidenAbbrechenButtonComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenAbbrechenButtonComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [VorgangDetailBescheidenAbbrechenButtonComponent], - imports: [MatIcon], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenAbbrechenButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.ts deleted file mode 100644 index aff28de42e789d535824c010ef79fcfc898e6ebc..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component, EventEmitter, Output } from '@angular/core'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-abbrechen-button', - templateUrl: './vorgang-detail-bescheiden-abbrechen-button.component.html', - styles: [], -}) -export class VorgangDetailBescheidenAbbrechenButtonComponent { - @Output() public clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.html deleted file mode 100644 index b535a27820affba89cb302cd71974c9a01dc863a..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.html +++ /dev/null @@ -1,61 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div - class="relative m-6 max-w-2xl rounded-lg bg-modalBg p-6 shadow-xl" - data-test-id="bescheid-close-dialog" -> - <div class="flex flex-col gap-6"> - <div> - <h4 class="text-lg font-medium text-primary">Bescheiderstellung abbrechen</h4> - </div> - <div class="grow"> - <p class="text-base"> - Soll der Bescheid-Entwurf zur späteren Bearbeitung gespeichert oder verworfen werden? - </p> - </div> - <div class="flex gap-4"> - <ozgcloud-stroked-button-with-spinner - (click)="saveBescheidDraft()" - data-test-id="bescheiderstellung-abbrechen-entwurf-speichern" - text="Entwurf speichern" - type="submit" - icon="check" - [stateResource]="saveDraftInProgress$ | async" - > - </ozgcloud-stroked-button-with-spinner> - <ozgcloud-stroked-button-with-spinner - (click)="onCancel()" - data-test-id="bescheiderstellung-abbrechen-entwurf-verwerfen" - text="Verwerfen" - color="" - icon="clear" - type="submit" - [stateResource]="deleteBescheid$ | async" - > - </ozgcloud-stroked-button-with-spinner> - </div> - </div> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.spec.ts deleted file mode 100644 index 8f5036fdc866a121e136dd39fc3fc9559019d77a..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.spec.ts +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandLinkRel, CommandResource } from '@alfa-client/command-shared'; -import { StateResource, createStateResource } from '@alfa-client/tech-shared'; -import { mock } from '@alfa-client/test-utils'; -import { OzgcloudDialogService, OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui'; -import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; -import { MatIcon } from '@angular/material/icon'; -import { - createCommandResource, - createCommandStateResource, -} from 'libs/command-shared/test/command'; -import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; -import { MockComponent } from 'ng-mocks'; -import { of } from 'rxjs'; -import { BescheidenFormService } from '../../../bescheiden.formservice'; -import { VorgangDetailBescheidenAbbrechenDialogComponent } from './vorgang-detail-bescheiden-abbrechen-dialog.component'; - -describe('VorgangDetailBescheidenAbbrechenDialogComponent', () => { - let component: VorgangDetailBescheidenAbbrechenDialogComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenAbbrechenDialogComponent>; - - const bescheidService = mock(BescheidService); - const ozgcloudDialogService = mock(OzgcloudDialogService); - const formService = mock(BescheidenFormService); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenAbbrechenDialogComponent, - MockComponent(OzgcloudStrokedButtonWithSpinnerComponent), - MockComponent(MatIcon), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: OzgcloudDialogService, - useValue: ozgcloudDialogService, - }, - { - provide: BescheidenFormService, - useValue: formService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenAbbrechenDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('saveBescheidDraft', () => { - beforeEach(() => { - const submitCommand: StateResource<CommandResource> = createCommandStateResource([ - CommandLinkRel.EFFECTED_RESOURCE, - ]); - formService.submitDraft = jest.fn().mockReturnValue(of(submitCommand)); - }); - - it('should call formService.submit', () => { - component.saveBescheidDraft(); - - expect(formService.submitDraft).toHaveBeenCalled(); - }); - - describe('on successfully done command', () => { - it('should call ozgcloudDialogService.closeAll', fakeAsync(() => { - component.saveBescheidDraft(); - component.saveDraftInProgress$.subscribe(); - tick(); - - expect(ozgcloudDialogService.closeAll).toHaveBeenCalled(); - })); - - it('should call bescheid service to refresh list', fakeAsync(() => { - component.saveBescheidDraft(); - component.saveDraftInProgress$.subscribe(); - tick(); - - expect(bescheidService.refreshList).toHaveBeenCalled(); - })); - }); - }); - - describe('onCancel', () => { - it('should call deleteBescheidDraft if Vorgang has bescheidDraft', () => { - bescheidService.existsBescheidDraft.mockReturnValue(true); - component.deleteBescheidDraft = jest.fn(); - - component.onCancel(); - - expect(component.deleteBescheidDraft).toHaveBeenCalled(); - }); - - it('should call ozgcloudDialogService.closeAll if Vorgang has no bescheidDraft', () => { - bescheidService.existsBescheidDraft.mockReturnValue(false); - - component.onCancel(); - - expect(ozgcloudDialogService.closeAll).toHaveBeenCalled(); - }); - }); - - describe('deleteBescheidDraft', () => { - beforeEach(() => { - const vorgangWithBescheid: VorgangWithEingangResource = createVorgangWithEingangResource([ - VorgangWithEingangLinkRel.BESCHEID_DRAFT, - ]); - formService.getVorgangWithEingangResource = jest.fn().mockReturnValue(vorgangWithBescheid); - - const commandResource: CommandResource = createCommandResource([ - CommandLinkRel.EFFECTED_RESOURCE, - ]); - const commandStateResource: StateResource<CommandResource> = - createStateResource(commandResource); - - bescheidService.bescheidVerwerfen = jest.fn().mockReturnValue(of(commandStateResource)); - }); - - it('should call bescheidService.bescheidVerwerfen', fakeAsync(() => { - component.deleteBescheidDraft(); - component.deleteBescheid$.subscribe(); - tick(); - - expect(bescheidService.bescheidVerwerfen).toHaveBeenCalled(); - })); - - it('should call ozgcloudDialogService.closeAll', () => { - component.deleteBescheidDraft(); - - expect(ozgcloudDialogService.closeAll).toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.ts deleted file mode 100644 index fb480448c1ac1fa88a18afe16ee02e950a637e58..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; -import { StateResource } from '@alfa-client/tech-shared'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { Component } from '@angular/core'; -import { Observable } from 'rxjs'; -import { BescheidenFormService } from '../../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-abbrechen-dialog', - templateUrl: './vorgang-detail-bescheiden-abbrechen-dialog.component.html', -}) -export class VorgangDetailBescheidenAbbrechenDialogComponent { - saveDraftInProgress$: Observable<StateResource<CommandResource>>; - deleteBescheid$: Observable<StateResource<CommandResource>>; - - constructor( - private readonly bescheidService: BescheidService, - private readonly ozgcloudDialogService: OzgcloudDialogService, - private readonly formService: BescheidenFormService, - ) {} - - public saveBescheidDraft() { - this.saveDraftInProgress$ = this.formService.submitDraft().pipe( - tapOnCommandSuccessfullyDone(() => { - this.ozgcloudDialogService.closeAll(); - this.bescheidService.refreshList(); - }), - ); - } - - public onCancel() { - if (this.bescheidService.existsBescheidDraft()) { - this.deleteBescheidDraft(); - } else { - this.ozgcloudDialogService.closeAll(); - } - } - - deleteBescheidDraft(): void { - this.deleteBescheid$ = this.bescheidService.bescheidVerwerfen().pipe( - tapOnCommandSuccessfullyDone(() => { - this.ozgcloudDialogService.closeAll(); - }), - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.html deleted file mode 100644 index 9f568635f1454de105701a1a31e25adda21d4e48..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.html +++ /dev/null @@ -1,54 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div [formGroup]="formService.form" role="radiogroup" aria-label="Bescheidstatus"> - <div class="my-10 flex max-w-2xl gap-8"> - <ods-radio-button-card - label="bewilligt" - [name]="formServiceClass.FIELD_BEWILLIGT" - value="true" - data-test-id="button-bewilligt" - variant="bescheid_bewilligt" - ><ods-stamp-icon size="large"></ods-stamp-icon> - </ods-radio-button-card> - <ods-radio-button-card - label="abgelehnt" - [name]="formServiceClass.FIELD_BEWILLIGT" - value="false" - data-test-id="button-abgelehnt" - variant="bescheid_abgelehnt" - ><ods-close-icon size="large" class="fill-abgelehnt"></ods-close-icon> - </ods-radio-button-card> - </div> - <div class="flex w-full"> - <ozgcloud-date-editor - [formControlName]="formServiceClass.FIELD_BESCHIEDEN_AM" - label="am" - aria-label="Bescheiddatum" - [required]="true" - > - </ozgcloud-date-editor> - </div> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.spec.ts deleted file mode 100644 index f476bc0b4a2a39aae84dfd41335ac0949456d628..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; -import { DateEditorComponent } from '@alfa-client/ui'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; -import { CloseIconComponent, RadioButtonCardComponent, StampIconComponent } from '@ods/system'; -import { MockComponent } from 'ng-mocks'; -import { BescheidenFormService } from '../../../bescheiden.formservice'; -import { VorgangDetailBescheidenAntragBescheidenComponent } from './vorgang-detail-bescheiden-antrag-bescheiden.component'; - -describe('VorgangDetailBescheidenAntragBescheidenComponent', () => { - let component: VorgangDetailBescheidenAntragBescheidenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenAntragBescheidenComponent>; - - let bescheidService: Mock<BescheidService>; - let formService: BescheidenFormService; - - beforeEach(async () => { - bescheidService = mock(BescheidService); - formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenAntragBescheidenComponent, - MockComponent(RadioButtonCardComponent), - MockComponent(DateEditorComponent), - MockComponent(StampIconComponent), - MockComponent(CloseIconComponent), - ], - imports: [ReactiveFormsModule], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenAntragBescheidenComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.ts deleted file mode 100644 index 0e8a3cb8ecaccc3d7d427ab77d549ce0566cb0a3..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component } from '@angular/core'; -import { BescheidenFormService } from '../../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-antrag-bescheiden', - templateUrl: './vorgang-detail-bescheiden-antrag-bescheiden.component.html', -}) -export class VorgangDetailBescheidenAntragBescheidenComponent { - protected readonly formServiceClass = BescheidenFormService; - - constructor(public formService: BescheidenFormService) {} -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.html deleted file mode 100644 index db7e7a2afbbe80ca4fef1198e35794870fc6f4a6..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.html +++ /dev/null @@ -1,53 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div - [formGroup]="formService.form" - class="mt-5 flex w-full max-w-72 flex-col gap-4" - role="radiogroup" - aria-level="Bescheid versenden" -> - <ng-container *ngIf="bescheidResource$ | async | hasLink: bescheidLinkRel.BESCHEIDEN_UND_SENDEN"> - <ods-radio-button-card - label="Als neue Nachricht an den Antragsteller senden" - [value]="sendBy.NACHRICHT" - [name]="formServiceClass.FIELD_SEND_BY" - variant="bescheid_save" - [fullWidthText]="true" - data-test-id="send-to-antragsteller-button" - ><ods-send-icon size="large"></ods-send-icon - ></ods-radio-button-card> - <ods-radio-button-card - *ngIf="bescheidResource$ | async | hasLink: bescheidLinkRel.BESCHEIDEN" - label="Nur speichern" - [value]="sendBy.MANUAL" - [name]="formServiceClass.FIELD_SEND_BY" - variant="bescheid_save" - [fullWidthText]="true" - data-test-id="save-button" - ><ods-save-icon size="large"></ods-save-icon - ></ods-radio-button-card> - </ng-container> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.spec.ts deleted file mode 100644 index cb8eeb6c18d18c4b49d98fe13a7025c05d61b923..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.spec.ts +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2024 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 { - BescheidLinkRel, - BescheidResource, - BescheidSendBy, - BescheidService, -} from '@alfa-client/bescheid-shared'; -import { HasLinkPipe, createStateResource } from '@alfa-client/tech-shared'; -import { Mock, getElementFromFixture, mock, useFromMock } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; -import { MatIconTestingModule } from '@angular/material/icon/testing'; -import { RadioButtonCardComponent, SaveIconComponent, SendIconComponent } from '@ods/system'; -import { MockComponent } from 'ng-mocks'; -import { EMPTY, of } from 'rxjs'; -import { createBescheidResource } from '../../../../../../../../bescheid-shared/src/test/bescheid'; -import { getDataTestIdOf } from '../../../../../../../../tech-shared/test/data-test'; -import { BescheidenFormService } from '../../../bescheiden.formservice'; -import { VorgangDetailBescheidenBescheidVersendenComponent } from './vorgang-detail-bescheiden-bescheid-versenden.component'; - -describe('VorgangDetailBescheidenBescheidVersendenComponent', () => { - let component: VorgangDetailBescheidenBescheidVersendenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenBescheidVersendenComponent>; - - let bescheidService: Mock<BescheidService>; - let formService: BescheidenFormService; - - const sendToAntragstellerButtonTestId: string = getDataTestIdOf('send-to-antragsteller-button'); - const saveAndSendButtonTestId: string = getDataTestIdOf('save-button'); - - beforeEach(async () => { - bescheidService = mock(BescheidService); - formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - - await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, MatIconTestingModule], - declarations: [ - VorgangDetailBescheidenBescheidVersendenComponent, - HasLinkPipe, - MockComponent(RadioButtonCardComponent), - MockComponent(SendIconComponent), - MockComponent(SaveIconComponent), - ], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenBescheidVersendenComponent); - component = fixture.componentInstance; - bescheidService.getBescheidDraft.mockReturnValue(EMPTY); - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render', () => { - it('should render send button', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of(createStateResource(createBescheidResource([BescheidLinkRel.BESCHEIDEN_UND_SENDEN]))), - ); - - component.ngOnInit(); - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, sendToAntragstellerButtonTestId); - expect(element).toBeInstanceOf(HTMLElement); - }); - - it('should not render send button', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of(createStateResource(createBescheidResource())), - ); - - component.ngOnInit(); - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, sendToAntragstellerButtonTestId); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should render save button', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of( - createStateResource( - createBescheidResource([ - BescheidLinkRel.BESCHEIDEN, - BescheidLinkRel.BESCHEIDEN_UND_SENDEN, - ]), - ), - ), - ); - - component.ngOnInit(); - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, saveAndSendButtonTestId); - expect(element).toBeInstanceOf(HTMLElement); - }); - - it('should not render save button if send link missing', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of(createStateResource(createBescheidResource([BescheidLinkRel.BESCHEIDEN]))), - ); - - component.ngOnInit(); - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, saveAndSendButtonTestId); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should not render save button if link is missing', () => { - bescheidService.getBescheidDraft.mockReturnValue( - of(createStateResource(createBescheidResource([BescheidLinkRel.BESCHEIDEN_UND_SENDEN]))), - ); - - component.ngOnInit(); - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, saveAndSendButtonTestId); - expect(element).not.toBeInstanceOf(HTMLElement); - }); - }); - - describe('ngOnInit', () => { - const bescheidResource: BescheidResource = createBescheidResource(); - - it('should set sendBy in form', () => { - component.initSendBy = jest.fn(); - bescheidService.getBescheidDraft.mockReturnValue(of(createStateResource(bescheidResource))); - - component.ngOnInit(); - component.bescheidResource$.subscribe(); - - expect(component.initSendBy).toHaveBeenCalledWith(bescheidResource); - }); - }); - - describe('initSendBy', () => { - it('should call form service', () => { - formService.setSendBy = jest.fn(); - - component.initSendBy(createBescheidResource()); - - expect(formService.setSendBy).toHaveBeenCalledWith(BescheidSendBy.MANUAL); - }); - - it('should not call form service', () => { - formService.setSendBy = jest.fn(); - - component.initSendBy(createBescheidResource([BescheidLinkRel.BESCHEIDEN_UND_SENDEN])); - - expect(formService.setSendBy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.ts deleted file mode 100644 index 4ffba257e5599d896ac6b90db7ae92c409eb6481..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2024 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 { - BescheidLinkRel, - BescheidResource, - BescheidSendBy, - BescheidService, -} from '@alfa-client/bescheid-shared'; -import { StateResource, isLoaded, notHasLink } from '@alfa-client/tech-shared'; -import { Component, OnInit } from '@angular/core'; -import { Observable, filter, map, tap } from 'rxjs'; -import { BescheidenFormService } from '../../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-bescheid-versenden', - templateUrl: './vorgang-detail-bescheiden-bescheid-versenden.component.html', -}) -export class VorgangDetailBescheidenBescheidVersendenComponent implements OnInit { - public bescheidResource$: Observable<BescheidResource>; - - public readonly formServiceClass = BescheidenFormService; - public readonly sendBy = BescheidSendBy; - - public bescheidLinkRel = BescheidLinkRel; - - constructor( - public formService: BescheidenFormService, - private readonly bescheidService: BescheidService, - ) {} - - ngOnInit(): void { - this.bescheidResource$ = this.bescheidService.getBescheidDraft().pipe( - filter(isLoaded), - map((stateResource: StateResource<BescheidResource>) => stateResource.resource), - tap((bescheidResource: BescheidResource) => this.initSendBy(bescheidResource)), - ); - } - - initSendBy(bescheidResource: BescheidResource): void { - if (notHasLink(bescheidResource, BescheidLinkRel.BESCHEIDEN_UND_SENDEN)) { - this.formService.setSendBy(BescheidSendBy.MANUAL); - } - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.html deleted file mode 100644 index 7dd1b32d5d178b5f907f7964ebb22734ad876cbe..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div [formGroup]="formService.form" class="mt-4"> - <ods-file-upload-editor - [attr.data-test-id]="'vorgang-bescheiden-upload-editor' + formServiceClass.FIELD_ATTACHMENTS" - [parentFormArrayName]="formServiceClass.FIELD_ATTACHMENTS" - [uploadInProgress]="uploadInProgress$ | async" - (newFile)="uploadFile($event)" - [fileLinkList]="getFileLinkList()" - label="Anhang hochladen" - > - </ods-file-upload-editor> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts deleted file mode 100644 index d4cecc3e41a00d51b537c0d189ec87e855a78f09..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { BinaryFileAttachmentContainerComponent } from '@alfa-client/binary-file'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { StateResource, createStateResource } from '@alfa-client/tech-shared'; -import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; -import { FileUploadEditorComponent } from '@ods/component'; -import { MockComponent } from 'ng-mocks'; -import { EMPTY, Observable, Subscription, of } from 'rxjs'; -import { createBescheidStateResource } from '../../../../../../../../../bescheid-shared/src/test/bescheid'; -import { createBinaryFileResource } from '../../../../../../../../../binary-file-shared/test/binary-file'; -import { createFile } from '../../../../../../../../../tech-shared/test/file'; -import { singleColdCompleted } from '../../../../../../../../../tech-shared/test/marbles'; -import { BescheidenFormService } from '../../../../bescheiden.formservice'; -import { VorgangDetailBescheidenAttachmentHochladenComponent } from './vorgang-detail-bescheiden-attachment-hochladen.component'; - -describe('VorgangDetailBescheidenDokumentHochladenComponent', () => { - let component: VorgangDetailBescheidenAttachmentHochladenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenAttachmentHochladenComponent>; - const selfLink: string = 'self'; - - let bescheidService: Mock<BescheidService>; - let formService: BescheidenFormService; - - beforeEach(async () => { - bescheidService = mock(BescheidService); - bescheidService.getAttachments.mockReturnValue(EMPTY); - - formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenAttachmentHochladenComponent, - MockComponent(BinaryFileAttachmentContainerComponent), - MockComponent(FileUploadEditorComponent), - ], - imports: [ReactiveFormsModule], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenAttachmentHochladenComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - let loadExistingAttachments: jest.Mock; - let subscribeToFileDeletion: jest.Mock; - - beforeEach(() => { - loadExistingAttachments = component.loadExistingAttachments = jest.fn(); - subscribeToFileDeletion = component.subscribeToFileDeletion = jest.fn(); - }); - - it('should load existing attachments', () => { - component.ngOnInit(); - - expect(loadExistingAttachments).toHaveBeenCalled(); - }); - - it('should subscribe to file deletion', () => { - component.ngOnInit(); - - expect(subscribeToFileDeletion).toHaveBeenCalled(); - }); - }); - - describe('ngOnDestroy', () => { - it('should unsubscribe from file deletion', () => { - const subscription = mock(Subscription); - const getDeleteFile = (formService.getFileDelete = jest.fn()); - const observable = mock(Observable); - getDeleteFile.mockReturnValue(observable); - observable.subscribe.mockReturnValue(subscription); - component.ngOnInit(); - - component.ngOnDestroy(); - - expect(subscription.unsubscribe).toHaveBeenCalled(); - }); - }); - - describe('loadExistingAttachments', () => { - let binaryFileResource: BinaryFileResource; - - beforeEach(() => { - binaryFileResource = createBinaryFileResource(); - bescheidService.getAttachments.mockReturnValue(of([binaryFileResource])); - }); - - it('should get attachments', () => { - component.loadExistingAttachments(); - - expect(bescheidService.getAttachments).toHaveBeenCalled(); - }); - - it('should add attachments to fileList', () => { - component.loadExistingAttachments(); - - expect(component.fileList).toEqual([binaryFileResource]); - }); - }); - - describe('subscribeToFileDeletion', () => { - let getFileDelete: jest.Mock; - let getFileDeleteObservable: Mock<Observable<BinaryFileResource>>; - - beforeEach(() => { - getFileDeleteObservable = mock(Observable); - getFileDelete = formService.getFileDelete = jest - .fn() - .mockReturnValue(getFileDeleteObservable); - }); - - it('should subscribe to file deletion', () => { - component.subscribeToFileDeletion(); - - expect(getFileDelete).toHaveBeenCalled(); - }); - }); - - describe('deleteFile', () => { - let binaryFileResource: BinaryFileResource; - - beforeEach(() => { - binaryFileResource = createBinaryFileResource(); - }); - - it('should remove file from list', () => { - component.fileList = [binaryFileResource]; - - component.deleteFile(binaryFileResource); - - expect(component.fileList).toEqual([]); - }); - }); - - describe('getFileLinkList', () => { - it('should return url list', () => { - const binaryFileResource = createBinaryFileResource([selfLink]); - component.fileList = [binaryFileResource]; - - const uriList = component.getFileLinkList(); - - expect(uriList[0]).toEqual(binaryFileResource._links.self.href); - }); - }); - - describe('uploadFile', () => { - const bescheidDraftStateResource: StateResource<BescheidResource> = - createBescheidStateResource(); - const file: File = createFile(); - const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource( - createBinaryFileResource(), - ); - - beforeEach(() => { - bescheidService.uploadAttachment.mockReturnValue(of(binaryFileStateResource)); - component.bescheidDraftStateResource = bescheidDraftStateResource; - }); - - it('should upload attachment', () => { - component.uploadFile(file); - - component.uploadInProgress$.subscribe(); - - expect(bescheidService.uploadAttachment).toHaveBeenCalledWith( - bescheidDraftStateResource.resource, - file, - ); - }); - - it('should add to file list', () => { - component.uploadFile(file); - - component.uploadInProgress$.subscribe(); - - expect(component.fileList).toEqual([binaryFileStateResource.resource]); - }); - - it('should emit', () => { - component.uploadFile(file); - - expect(component.uploadInProgress$).toBeObservable( - singleColdCompleted(binaryFileStateResource), - ); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts deleted file mode 100644 index 6c5fe5d18d04c4c3101987d76b7e68d14f869807..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { BinaryFileResource } from '@alfa-client/binary-file-shared'; -import { - StateResource, - createEmptyStateResource, - doOnValidStateResource, - isNotNil, -} from '@alfa-client/tech-shared'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { getUrl } from '@ngxp/rest'; -import { Observable, Subscription, first, of, tap } from 'rxjs'; -import { BescheidenFormService } from '../../../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-attachment-hochladen', - templateUrl: './vorgang-detail-bescheiden-attachment-hochladen.component.html', - styles: [], -}) -export class VorgangDetailBescheidenAttachmentHochladenComponent implements OnInit, OnDestroy { - @Input() bescheidDraftStateResource: StateResource<BescheidResource>; - - uploadInProgress$: Observable<StateResource<BinaryFileResource>>; - fileList: BinaryFileResource[] = []; - private deleteFileSubscription: Subscription; - - readonly formServiceClass = BescheidenFormService; - - constructor( - public readonly formService: BescheidenFormService, - private readonly bescheidService: BescheidService, - ) { - this.uploadInProgress$ = of(createEmptyStateResource<BinaryFileResource>()); - } - - ngOnInit(): void { - this.loadExistingAttachments(); - this.subscribeToFileDeletion(); - } - - ngOnDestroy(): void { - if (isNotNil(this.deleteFileSubscription)) this.deleteFileSubscription.unsubscribe(); - } - - loadExistingAttachments(): void { - this.bescheidService - .getAttachments() - .pipe(first()) - .subscribe((attachments) => (this.fileList = attachments)); - } - - subscribeToFileDeletion(): void { - this.deleteFileSubscription = this.formService - .getFileDelete() - .subscribe((binaryFileResource) => this.deleteFile(binaryFileResource)); - } - - deleteFile(binaryFileResource: BinaryFileResource) { - this.fileList = this.fileList.filter((file) => getUrl(file) !== getUrl(binaryFileResource)); - } - - getFileLinkList(): string[] { - return this.fileList.map((fileResource: BinaryFileResource) => getUrl(fileResource)); - } - - public uploadFile(file: File): void { - this.uploadInProgress$ = this.bescheidService - .uploadAttachment(this.bescheidDraftStateResource.resource, file) - .pipe( - tap((stateResource: StateResource<BinaryFileResource>) => - doOnValidStateResource( - stateResource, - () => (this.fileList = [...this.fileList, stateResource.resource]), - ), - ), - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.html deleted file mode 100644 index 93076b339f608ddd394e212c68c60457d40d82b1..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.html +++ /dev/null @@ -1,40 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<ng-container *ngIf="bescheidDraftStateResource.resource as bescheidDraft"> - <div class="mt-4"> - <ods-button-card - *ngIf="bescheidDraft | hasLink: bescheidLinkRel.CREATE_DOCUMENT" - class="w-72" - [isLoading]="(createBescheidDocumentInProgress$ | async).loading" - (click)="createBescheidDocument()" - data-test-id="create-bescheid-document-button" - text="Bescheiddokument" - subText="automatisch erstellen" - > - <ods-bescheid-generate-icon icon /> - </ods-button-card> - </div> -</ng-container> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.spec.ts deleted file mode 100644 index 28bf0e8b5ba83f7889afb81cb80bb5a7e1e8d320..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.spec.ts +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandLinkRel } from '@alfa-client/command-shared'; -import { - createEmptyStateResource, - createStateResource, - HasLinkPipe, -} from '@alfa-client/tech-shared'; -import { - dispatchEventFromFixture, - existsAsHtmlElement, - Mock, - mock, - notExistsAsHtmlElement, -} from '@alfa-client/test-utils'; -import { OzgcloudButtonWithSpinnerComponent } from '@alfa-client/ui'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { - BescheidGenerateIconComponent, - ButtonCardComponent, - SpinnerIconComponent, -} from '@ods/system'; -import { createBescheidResource } from 'libs/bescheid-shared/src/test/bescheid'; -import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; -import { of } from 'rxjs'; -import { - createCommandErrorStateResource, - createCommandStateResource, -} from '../../../../../../../../../command-shared/test/command'; -import { BescheidenFormService } from '../../../../bescheiden.formservice'; -import { VorgangDetailBescheidenBescheidAutomatischErstellenComponent } from './vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component'; - -describe('VorgangDetailBescheidenBescheidAutomatischErstellenComponent', () => { - let component: VorgangDetailBescheidenBescheidAutomatischErstellenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenBescheidAutomatischErstellenComponent>; - - const createBescheidDocumentButton: string = getDataTestIdOf('create-bescheid-document-button'); - - let bescheidService: Mock<BescheidService>; - let formService: Mock<BescheidenFormService>; - - beforeEach(async () => { - bescheidService = mock(BescheidService); - formService = mock(BescheidenFormService); - - await TestBed.configureTestingModule({ - imports: [HasLinkPipe], - declarations: [ - VorgangDetailBescheidenBescheidAutomatischErstellenComponent, - MockComponent(OzgcloudButtonWithSpinnerComponent), - MockComponent(ButtonCardComponent), - MockComponent(SpinnerIconComponent), - MockComponent(BescheidGenerateIconComponent), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: BescheidenFormService, - useValue: formService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenBescheidAutomatischErstellenComponent); - component = fixture.componentInstance; - component.bescheidDraftStateResource = createStateResource(createBescheidResource()); - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('create bescheid document button', () => { - beforeEach(() => { - component.bescheidDraftStateResource = createStateResource( - createBescheidResource([BescheidLinkRel.CREATE_DOCUMENT]), - ); - - fixture.detectChanges(); - }); - it('should call bescheid service on click', () => { - dispatchEventFromFixture(fixture, createBescheidDocumentButton, 'click'); - - expect(bescheidService.createBescheidDocument).toHaveBeenCalled(); - }); - - it('should be hidden if link is NOT present', () => { - component.bescheidDraftStateResource = createStateResource(createBescheidResource()); - - fixture.detectChanges(); - - notExistsAsHtmlElement(fixture, createBescheidDocumentButton); - }); - - it('should be visible if link is present', () => { - component.bescheidDraftStateResource = createStateResource( - createBescheidResource([BescheidLinkRel.CREATE_DOCUMENT]), - ); - fixture.detectChanges(); - - existsAsHtmlElement(fixture, createBescheidDocumentButton); - }); - - it('should clear nachricht', () => { - bescheidService.createBescheidDocument.mockReturnValue( - of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE])), - ); - - component.createBescheidDocument(); - - component.createBescheidDocumentInProgress$.subscribe(); - expect(formService.clearNachricht).toHaveBeenCalled(); - }); - - it('should not clear nachricht when loading', () => { - bescheidService.createBescheidDocument.mockReturnValue(of(createEmptyStateResource(true))); - - component.createBescheidDocument(); - - component.createBescheidDocumentInProgress$.subscribe(); - expect(formService.clearNachricht).not.toHaveBeenCalled(); - }); - - it('should not clear nachricht when error', () => { - bescheidService.createBescheidDocument.mockReturnValue(of(createCommandErrorStateResource())); - - component.createBescheidDocument(); - - component.createBescheidDocumentInProgress$.subscribe(); - expect(formService.clearNachricht).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.ts deleted file mode 100644 index 47ceb4fb1feeadc93da73eec593d1c69424a4ca1..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandResource, isSuccessfulDone } from '@alfa-client/command-shared'; -import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared'; -import { Component, Input } from '@angular/core'; -import { Observable, of, tap } from 'rxjs'; -import { BescheidenFormService } from '../../../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-bescheid-automatisch-erstellen', - templateUrl: './vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component.html', -}) -export class VorgangDetailBescheidenBescheidAutomatischErstellenComponent { - @Input() public bescheidDraftStateResource: StateResource<BescheidResource>; - - public createBescheidDocumentInProgress$: Observable<StateResource<CommandResource>> = of( - createEmptyStateResource<CommandResource>(), - ); - - public readonly bescheidLinkRel = BescheidLinkRel; - - constructor( - private readonly bescheidService: BescheidService, - private readonly formService: BescheidenFormService, - ) {} - - public createBescheidDocument(): void { - this.createBescheidDocumentInProgress$ = this.bescheidService.createBescheidDocument().pipe( - tap((commandStateResource: StateResource<CommandResource>) => { - if (isSuccessfulDone(commandStateResource.resource)) { - this.formService.clearNachricht(); - } - }), - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.html deleted file mode 100644 index cf032e3993238d0351d91cda1818be9dc7f0cb98..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.html +++ /dev/null @@ -1,39 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div [formGroup]="formService.form"> - <ods-single-file-upload-editor - *ngIf="bescheidDraftStateResource.resource | hasLink: bescheidLinkRel.UPLOAD_BESCHEID_FILE" - [uploadInProgress]="(uploadDocumentFileInProgress$ | async).loading" - class="w-72" - attr.data-test-id="vorgang-bescheiden-upload-editor" - [formControlName]="formServiceClass.FIELD_BESCHEID_DOCUMENT" - (newFile)="uploadFile($event)" - > - <ods-bescheid-upload-icon icon></ods-bescheid-upload-icon> - <ods-spinner-icon spinner size="extra-large"></ods-spinner-icon> - <div text class="text-center">Bescheiddokument hochladen</div> - </ods-single-file-upload-editor> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.spec.ts deleted file mode 100644 index 5b089dac014abc5a0da5991e964ba167b50edcf9..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.spec.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { HasLinkPipe } from '@alfa-client/tech-shared'; -import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; -import { MatIcon } from '@angular/material/icon'; -import { faker } from '@faker-js/faker'; -import { ResourceUri } from '@ngxp/rest'; -import { SingleFileUploadEditorComponent } from '@ods/component'; -import { SpinnerIconComponent } from '@ods/system'; -import { MockComponent, MockPipe } from 'ng-mocks'; -import { of } from 'rxjs'; -import { createBescheidStateResource } from '../../../../../../../../../bescheid-shared/src/test/bescheid'; -import { createFile } from '../../../../../../../../../tech-shared/test/file'; -import { BescheidenFormService } from '../../../../bescheiden.formservice'; -import { VorgangDetailBescheidenDokumentHochladenComponent } from './vorgang-detail-bescheiden-dokument-hochladen.component'; - -describe('VorgangDetailBescheidenDokumentHochladenComponent', () => { - let component: VorgangDetailBescheidenDokumentHochladenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenDokumentHochladenComponent>; - - let bescheidService: Mock<BescheidService>; - let formService: BescheidenFormService; - - beforeEach(async () => { - bescheidService = mock(BescheidService); - bescheidService.getDocumentUri.mockReturnValue(of(null)); - - formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenDokumentHochladenComponent, - MatIcon, - MockPipe(HasLinkPipe), - MockComponent(SingleFileUploadEditorComponent), - MockComponent(SpinnerIconComponent), - ], - imports: [ReactiveFormsModule], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenDokumentHochladenComponent); - component = fixture.componentInstance; - component.bescheidDraftStateResource = createBescheidStateResource(); - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - it('should handle document uri changes', () => { - bescheidService.getDocumentUri.mockReturnValue(of('DocumentUriDummy')); - component.handleDocumentUriChanges = jest.fn(); - - component.ngOnInit(); - - expect(component.handleDocumentUriChanges).toHaveBeenCalledWith('DocumentUriDummy'); - }); - }); - - describe('handle document uri changes', () => { - it('should update bescheid document file in form service', () => { - const documentUri: ResourceUri = faker.person.firstName(); - formService.updateBescheidDocumentFile = jest.fn(); - - component.handleDocumentUriChanges(documentUri); - - expect(formService.updateBescheidDocumentFile).toHaveBeenCalledWith(documentUri); - }); - it('should clear bescheid document file in form service', () => { - formService.clearBescheidDocumentFile = jest.fn(); - - component.handleDocumentUriChanges(null); - - expect(formService.clearBescheidDocumentFile).toHaveBeenCalled(); - }); - }); - - describe('upload file', () => { - it('should call service to upload bescheid document', () => { - const bescheidStateResource = createBescheidStateResource(); - const file = createFile(); - component.bescheidDraftStateResource = bescheidStateResource; - - component.uploadFile(file); - - expect(bescheidService.uploadBescheidDocument).toHaveBeenCalledWith(bescheidStateResource.resource, file); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.ts deleted file mode 100644 index ebf303e9cc6208ac2fb0908cd9c1c52bf8f693d1..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2024 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 { - BescheidLinkRel, - BescheidResource, - BescheidService, - UploadFileInProgress, -} from '@alfa-client/bescheid-shared'; -import { isNotNil, StateResource } from '@alfa-client/tech-shared'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { ResourceUri } from '@ngxp/rest'; -import { isNull } from 'lodash-es'; -import { Observable, of, Subscription } from 'rxjs'; -import { BescheidenFormService } from '../../../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-dokument-hochladen', - templateUrl: './vorgang-detail-bescheiden-dokument-hochladen.component.html', - styles: [], -}) -export class VorgangDetailBescheidenDokumentHochladenComponent implements OnInit, OnDestroy { - @Input() bescheidDraftStateResource: StateResource<BescheidResource>; - - public uploadDocumentFileInProgress$: Observable<UploadFileInProgress> = of({ loading: false }); - - public readonly formServiceClass = BescheidenFormService; - public readonly bescheidLinkRel = BescheidLinkRel; - - private documentUriChangeSubscription: Subscription; - - constructor( - public readonly formService: BescheidenFormService, - private bescheidService: BescheidService, - ) {} - - ngOnInit(): void { - this.documentUriChangeSubscription = this.bescheidService - .getDocumentUri() - .subscribe((documentUri) => this.handleDocumentUriChanges(documentUri)); - } - - handleDocumentUriChanges(uri: ResourceUri): void { - if (isNull(uri)) { - this.formService.clearBescheidDocumentFile(); - } else { - this.formService.updateBescheidDocumentFile(uri); - } - } - - public uploadFile(file: File): void { - this.uploadDocumentFileInProgress$ = this.bescheidService.uploadBescheidDocument( - this.bescheidDraftStateResource.resource, - file, - ); - } - - ngOnDestroy(): void { - if (isNotNil(this.documentUriChangeSubscription)) - this.documentUriChangeSubscription.unsubscribe(); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html deleted file mode 100644 index 93c14522705e5f06a802280c49be66dc224a4721..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div class="flex flex-col gap-4"> - <alfa-vorgang-detail-bescheiden-bescheid-automatisch-erstellen - [bescheidDraftStateResource]="bescheidDraftStateResource$ | async" - ></alfa-vorgang-detail-bescheiden-bescheid-automatisch-erstellen> - <alfa-vorgang-detail-bescheiden-dokument-hochladen - [bescheidDraftStateResource]="bescheidDraftStateResource$ | async" - ></alfa-vorgang-detail-bescheiden-dokument-hochladen> - <alfa-vorgang-detail-bescheiden-attachment-hochladen - [bescheidDraftStateResource]="bescheidDraftStateResource$ | async" - ></alfa-vorgang-detail-bescheiden-attachment-hochladen> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.spec.ts deleted file mode 100644 index ea893f621e61c4bac925b2cb8a3a0a1155047548..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MockComponent } from 'ng-mocks'; -import { VorgangDetailBescheidenAttachmentHochladenComponent } from './vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component'; -import { VorgangDetailBescheidenBescheidAutomatischErstellenComponent } from './vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component'; -import { VorgangDetailBescheidenDokumentHochladenComponent } from './vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component'; -import { VorgangDetailBescheidenDokumenteHinzufuegenComponent } from './vorgang-detail-bescheiden-dokumente-hinzufuegen.component'; - -describe('VorgangDetailBescheidenDokumenteHinzufuegenComponent', () => { - let component: VorgangDetailBescheidenDokumenteHinzufuegenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenDokumenteHinzufuegenComponent>; - - const bescheidService: Mock<BescheidService> = mock(BescheidService); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenDokumenteHinzufuegenComponent, - MockComponent(VorgangDetailBescheidenBescheidAutomatischErstellenComponent), - MockComponent(VorgangDetailBescheidenDokumentHochladenComponent), - MockComponent(VorgangDetailBescheidenAttachmentHochladenComponent), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - ], - }).compileComponents(); - fixture = TestBed.createComponent(VorgangDetailBescheidenDokumenteHinzufuegenComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - it('should call service get bescheid draft if exists', () => { - component.ngOnInit(); - - expect(bescheidService.getBescheidDraft).toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.ts deleted file mode 100644 index ae454a1d2e50138e617e6f7e8cd82d6ee7da39f5..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { StateResource, createEmptyStateResource } from '@alfa-client/tech-shared'; -import { Component, OnInit } from '@angular/core'; -import { Observable, of } from 'rxjs'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-dokumente-hinzufuegen', - templateUrl: './vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html', - styles: [], -}) -export class VorgangDetailBescheidenDokumenteHinzufuegenComponent implements OnInit { - public bescheidDraftStateResource$: Observable<StateResource<BescheidResource>> = of( - createEmptyStateResource<BescheidResource>(), - ); - - constructor(private bescheidService: BescheidService) {} - - ngOnInit(): void { - this.bescheidDraftStateResource$ = this.bescheidService.getBescheidDraft(); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.html deleted file mode 100644 index d940d1a0b6ee4e24b612f371157e5df63a171fdc..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.html +++ /dev/null @@ -1,40 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div - *ngIf="shouldShowStep()" - class="min-h-28 flex-1" - id="vorgang-detail-bescheiden-step-content-{{ step }}" - role="tabpanel" - [tabindex]="shouldShowStepContent() ? '0' : '-1'" -> - <alfa-vorgang-detail-bescheiden-step-title - [label]="stepTitle" - data-test-id="step-caption" - ></alfa-vorgang-detail-bescheiden-step-title> - <div *ngIf="shouldShowStepContent()"> - <ng-content></ng-content> - </div> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.spec.ts deleted file mode 100644 index 825d6d08b617426f04782aedd866d705a96bbc08..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.spec.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2024 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 { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MockComponent } from 'ng-mocks'; -import { VorgangDetailBescheidenStepTitleComponent } from '../../vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component'; -import { VorgangDetailBescheidenWeiterButtonComponent } from '../../vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; -import { VorgangDetailBescheidenStepContentComponent } from './vorgang-detail-bescheiden-step-content.component'; - -describe('VorgangDetailBescheidenStepsContentComponent', () => { - let component: VorgangDetailBescheidenStepContentComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenStepContentComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenStepContentComponent, - MockComponent(VorgangDetailBescheidenWeiterButtonComponent), - MockComponent(VorgangDetailBescheidenStepTitleComponent), - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenStepContentComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('shouldShowStep', () => { - it('should return true', () => { - component.activeStep = 2; - component.step = 2; - - const shouldShowStep = component.shouldShowStep(); - - expect(shouldShowStep).toBeTruthy(); - }); - - it('should return false', () => { - component.activeStep = 2; - component.step = 3; - - const shouldShowStep = component.shouldShowStep(); - - expect(shouldShowStep).toBeFalsy(); - }); - }); - - describe('shouldShowStepContent', () => { - it('should return true', () => { - component.activeStep = 2; - component.step = 2; - - const shouldShowStep = component.shouldShowStepContent(); - - expect(shouldShowStep).toBeTruthy(); - }); - - it('should return false', () => { - component.activeStep = 2; - component.step = 1; - - const shouldShowStep = component.shouldShowStepContent(); - - expect(shouldShowStep).toBeFalsy(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.ts deleted file mode 100644 index 4ab18f4714f922f27232a7b0a66d48bb5d08f9f0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component, Input } from '@angular/core'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-step-content', - templateUrl: './vorgang-detail-bescheiden-step-content.component.html', - styles: [':host {@apply flex}'], -}) -export class VorgangDetailBescheidenStepContentComponent { - @Input() stepTitle: string; - @Input() step: number; - @Input() nextStep: number; - @Input() activeStep: number = 1; - - public shouldShowStep(): boolean { - return this.activeStep > this.step - 1; - } - - public shouldShowStepContent(): boolean { - return this.activeStep === this.step; - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.html deleted file mode 100644 index ab8c1d21a70bcd3eadfb8bf884a6215e961019be..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.html +++ /dev/null @@ -1,69 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<alfa-vorgang-detail-bescheiden-step-content - stepTitle="Antrag bescheiden" - [step]="1" - [nextStep]="2" - [activeStep]="activeStep$ | async" -> - <alfa-vorgang-detail-bescheiden-antrag-bescheiden></alfa-vorgang-detail-bescheiden-antrag-bescheiden> - <alfa-vorgang-detail-bescheiden-weiter-button - (clickEmitter)="changeActiveStep(2)" - [submitResource]="submitResource" - ></alfa-vorgang-detail-bescheiden-weiter-button> -</alfa-vorgang-detail-bescheiden-step-content> - -<alfa-vorgang-detail-bescheiden-step-content - stepTitle="Dokumente hinzufügen" - [step]="2" - [nextStep]="3" - [activeStep]="activeStep$ | async" -> - <alfa-vorgang-detail-bescheiden-dokumente-hinzufuegen - *ngIf="(activeStep$ | async) === 2" - data-test-id="bescheid-documents-upload" - ></alfa-vorgang-detail-bescheiden-dokumente-hinzufuegen> - <alfa-vorgang-detail-bescheiden-weiter-button - (clickEmitter)="changeActiveStep(3)" - [submitResource]="submitResource" - ></alfa-vorgang-detail-bescheiden-weiter-button> -</alfa-vorgang-detail-bescheiden-step-content> - -<alfa-vorgang-detail-bescheiden-step-content - stepTitle="Bescheid versenden" - [step]="3" - [nextStep]="3" - [activeStep]="activeStep$ | async" -> - <alfa-vorgang-detail-bescheiden-bescheid-versenden - *ngIf="(activeStep$ | async) === 3" - data-test-id="bescheiden-bescheid-versenden" - ></alfa-vorgang-detail-bescheiden-bescheid-versenden> -</alfa-vorgang-detail-bescheiden-step-content> - -<alfa-vorgang-detail-bescheiden-ueberspringen-button - *ngIf="showBescheidErstellungUeberspringen$ | async" -></alfa-vorgang-detail-bescheiden-ueberspringen-button> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts deleted file mode 100644 index d9ff1e4db615920247c80afd51992b5a2f7bf266..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.spec.ts +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { - createEmptyStateResource, - createErrorStateResource, - createStateResource, -} from '@alfa-client/tech-shared'; -import { Mock, getElementFromFixture, mock } from '@alfa-client/test-utils'; -import { VorgangService, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; -import { EventEmitter } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { createApiError } from 'libs/tech-shared/test/error'; -import { MockComponent } from 'ng-mocks'; -import { EMPTY, of } from 'rxjs'; -import { - createCommandResource, - createCommandStateResource, -} from '../../../../../../../command-shared/test/command'; -import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test'; -import { singleCold } from '../../../../../../../tech-shared/test/marbles'; -import { createVorgangWithEingangResource } from '../../../../../../../vorgang-shared/test/vorgang'; -import { BescheidenFormService } from '../../bescheiden.formservice'; -import { VorgangDetailBescheidenStepTitleComponent } from '../vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component'; -import { VorgangDetailBescheidenWeiterButtonComponent } from '../vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; -import { VorgangDetailBescheidenAntragBescheidenComponent } from './vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component'; -import { VorgangDetailBescheidenBescheidVersendenComponent } from './vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component'; -import { VorgangDetailBescheidenDokumenteHinzufuegenComponent } from './vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component'; -import { VorgangDetailBescheidenStepContentComponent } from './vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component'; -import { VorgangDetailBescheidenStepsContentComponent } from './vorgang-detail-bescheiden-steps-content.component'; -import { VorgangDetailBescheidenUeberspringenButtonComponent } from './vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component'; - -describe('VorgangDetailBescheidenStepsContentComponent', () => { - let component: VorgangDetailBescheidenStepsContentComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenStepsContentComponent>; - - let vorgangService: Mock<VorgangService>; - let bescheidService: Mock<BescheidService>; - let formService: Mock<BescheidenFormService>; - - const bescheidVersendenTestId: string = getDataTestIdOf('bescheiden-bescheid-versenden'); - - beforeEach(async () => { - vorgangService = mock(VorgangService); - vorgangService.getVorgangWithEingang.mockReturnValue(EMPTY); - - bescheidService = mock(BescheidService); - formService = mock(BescheidenFormService); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenStepsContentComponent, - MockComponent(VorgangDetailBescheidenWeiterButtonComponent), - MockComponent(VorgangDetailBescheidenStepTitleComponent), - MockComponent(VorgangDetailBescheidenStepContentComponent), - MockComponent(VorgangDetailBescheidenUeberspringenButtonComponent), - MockComponent(VorgangDetailBescheidenAntragBescheidenComponent), - MockComponent(VorgangDetailBescheidenDokumenteHinzufuegenComponent), - MockComponent(VorgangDetailBescheidenBescheidVersendenComponent), - ], - providers: [ - { - provide: VorgangService, - useValue: vorgangService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: BescheidenFormService, - useValue: formService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenStepsContentComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('render', () => { - it('should show documents component in step 2', () => { - component.activeStep = 2; - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, getDataTestIdOf('bescheid-documents-upload')); - - expect(element).toBeInstanceOf(HTMLElement); - }); - - it.each([1, 3])('should not show documents component in step %d', (step) => { - component.activeStep = step; - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, getDataTestIdOf('bescheid-documents-upload')); - - expect(element).not.toBeInstanceOf(HTMLElement); - }); - - it('should show bescheid versenden in step 3', () => { - component.activeStep = 3; - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, bescheidVersendenTestId); - - expect(element).toBeInstanceOf(HTMLElement); - }); - - it.each([1, 2])('should not show bescheid versenden in step %d', (step: number) => { - component.activeStep = step; - fixture.detectChanges(); - - const element = getElementFromFixture(fixture, bescheidVersendenTestId); - - expect(element).not.toBeInstanceOf(HTMLElement); - }); - }); - - describe('changeActiveStep', () => { - beforeEach(() => { - component.activeStepChange = <any>mock(EventEmitter); - formService.submit = jest.fn(); - }); - - it('should submit', () => { - component.canChangeTo = jest.fn().mockReturnValue(true); - formService.submit = jest.fn().mockReturnValue(EMPTY); - - component.changeActiveStep(1); - - expect(formService.submit).toHaveBeenCalled(); - }); - - it('should not submit', () => { - component.canChangeTo = jest.fn().mockReturnValue(false); - formService.submit = jest.fn().mockReturnValue(EMPTY); - - component.changeActiveStep(1); - - expect(formService.submit).not.toHaveBeenCalled(); - }); - }); - - describe('canChangeTo', () => { - it.each([1, 2])('should true for step %d', (step: number) => { - const canChange = component.canChangeTo(step); - - expect(canChange).toBeTruthy(); - }); - - it('should return true for step 3', () => { - formService.validateBescheidDocumentExists.mockReturnValue(true); - - const canChange = component.canChangeTo(3); - - expect(canChange).toBeTruthy(); - }); - - it('should return false for step 3', () => { - formService.validateBescheidDocumentExists.mockReturnValue(false); - - const canChange = component.canChangeTo(3); - - expect(canChange).toBeFalsy(); - }); - }); - - describe('ngOnInit', () => { - it('should render überspringen und abschliessen button', () => { - component.activeStep = 1; - vorgangService.getVorgangWithEingang.mockReturnValue( - of( - createStateResource( - createVorgangWithEingangResource([VorgangWithEingangLinkRel.ABSCHLIESSEN]), - ), - ), - ); - - component.ngOnInit(); - - expect(component.showBescheidErstellungUeberspringen$).toBeObservable(singleCold(true)); - }); - - it('should not render überspringen und abschliessen button for active step 2', () => { - component.activeStep = 2; - vorgangService.getVorgangWithEingang.mockReturnValue( - of( - createStateResource( - createVorgangWithEingangResource([VorgangWithEingangLinkRel.ABSCHLIESSEN]), - ), - ), - ); - - component.ngOnInit(); - - expect(component.showBescheidErstellungUeberspringen$).toBeObservable(singleCold(false)); - }); - - it('should not render überspringen und abschliessen button if link missing', () => { - component.activeStep = 1; - vorgangService.getVorgangWithEingang.mockReturnValue( - of(createStateResource(createVorgangWithEingangResource())), - ); - - component.ngOnInit(); - - expect(component.showBescheidErstellungUeberspringen$).toBeObservable(singleCold(false)); - }); - }); - - describe('noError', () => { - it('should return true', () => { - const noError = component.noError(createCommandStateResource()); - - expect(noError).toBeTruthy(); - }); - - it('should return false on not loaded state resource', () => { - const noError = component.noError(createEmptyStateResource()); - - expect(noError).toBeFalsy(); - }); - - it('should return false on loading state resource', () => { - const noError = component.noError(createStateResource(createCommandResource(), true)); - - expect(noError).toBeFalsy(); - }); - - it('should return false on error state resource', () => { - const noError = component.noError(createErrorStateResource(createApiError())); - - expect(noError).toBeFalsy(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts deleted file mode 100644 index c880db36f7f58edf7f7865beb016deedf5d69ed2..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2024 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 { - StateResource, - createEmptyStateResource, - hasStateResourceError, - isLoaded, -} from '@alfa-client/tech-shared'; -import { - VorgangService, - VorgangWithEingangLinkRel, - VorgangWithEingangResource, -} from '@alfa-client/vorgang-shared'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Resource, hasLink } from '@ngxp/rest'; -import { BehaviorSubject, Observable, combineLatest, filter, first, map, tap } from 'rxjs'; -import { BescheidenFormService } from '../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-steps-content', - templateUrl: './vorgang-detail-bescheiden-steps-content.component.html', - styles: [':host {@apply flex flex-col}'], -}) -export class VorgangDetailBescheidenStepsContentComponent implements OnInit { - readonly activeStep$ = new BehaviorSubject(1); - - @Input() set activeStep(step: number) { - this.activeStep$.next(step); - } - @Output() activeStepChange = new EventEmitter<number>(); - - showBescheidErstellungUeberspringen$: Observable<boolean>; - - submitResource: StateResource<Resource> = createEmptyStateResource(); - - constructor( - private readonly vorgangService: VorgangService, - private formService: BescheidenFormService, - ) {} - - ngOnInit(): void { - this.showBescheidErstellungUeberspringen$ = combineLatest([ - this.vorgangService.getVorgangWithEingang().pipe( - filter(isLoaded), - map((stateResource: StateResource<VorgangWithEingangResource>) => - hasLink(stateResource.resource, VorgangWithEingangLinkRel.ABSCHLIESSEN), - ), - ), - this.activeStep$.pipe(map((step) => step === 1)), - ]).pipe(map(([hasAbschliessenLink, isFirstStep]) => hasAbschliessenLink && isFirstStep)); - } - - public changeActiveStep(step: number): void { - if (this.canChangeTo(step)) { - this.formService - .submit() - .pipe( - tap((resource: StateResource<Resource>) => (this.submitResource = resource)), - filter(this.noError), - first(), - ) - .subscribe(() => { - this.formService.setActiveStep(step); - this.activeStepChange.emit(step); - }); - } - } - - canChangeTo(nextStep: number): boolean { - if (nextStep < 3) { - return true; - } - return this.formService.validateBescheidDocumentExists(); - } - - noError(stateResource: StateResource<Resource>): boolean { - return isLoaded(stateResource) && !hasStateResourceError(stateResource); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.html deleted file mode 100644 index c12b66319d09caa61ccb7b5289dd79f5ccf5ca12..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.html +++ /dev/null @@ -1,32 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<button - (click)="onClick()" - data-test-id="bescheid-ueberspringen" - class="mt-6 select-none text-left text-primary hover:underline" -> - Bescheiderstellung überspringen<br />und abschließen -</button> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.spec.ts deleted file mode 100644 index 6b574a970798d3521230f50d7fe14dab66087a02..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2024 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 { Mock, mock } from '@alfa-client/test-utils'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { VorgangDetailBescheidenUeberspringenDialogComponent } from '../vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component'; -import { VorgangDetailBescheidenUeberspringenButtonComponent } from './vorgang-detail-bescheiden-ueberspringen-button.component'; - -describe('VorgangDetailBescheidenUeberspringenButtonComponent', () => { - let component: VorgangDetailBescheidenUeberspringenButtonComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenUeberspringenButtonComponent>; - - let ozgcloudDialogService: Mock<OzgcloudDialogService>; - - beforeEach(async () => { - ozgcloudDialogService = mock(OzgcloudDialogService); - - await TestBed.configureTestingModule({ - declarations: [VorgangDetailBescheidenUeberspringenButtonComponent], - providers: [ - { - provide: OzgcloudDialogService, - useValue: ozgcloudDialogService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenUeberspringenButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('onClick', () => { - it('should open dialog', () => { - component.onClick(); - - expect(ozgcloudDialogService.open).toHaveBeenCalledWith( - VorgangDetailBescheidenUeberspringenDialogComponent, - ); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.ts deleted file mode 100644 index 37aa7deb4c581124eb3be9a57d30cf784c0951cd..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2024 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 { OzgcloudDialogService } from '@alfa-client/ui'; -import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { Component, Input } from '@angular/core'; -import { VorgangDetailBescheidenUeberspringenDialogComponent } from '../vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-ueberspringen-button', - templateUrl: './vorgang-detail-bescheiden-ueberspringen-button.component.html', - styles: [':host {@apply flex flex-1 items-end}'], -}) -export class VorgangDetailBescheidenUeberspringenButtonComponent { - @Input() vorgang: VorgangWithEingangResource; - - constructor(private readonly ozgcloudDialogService: OzgcloudDialogService) {} - - public onClick(): void { - this.ozgcloudDialogService.open<VorgangDetailBescheidenUeberspringenDialogComponent>( - VorgangDetailBescheidenUeberspringenDialogComponent, - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.html deleted file mode 100644 index 407ab86311898af6a4bfcd3eda4eebe1d03ac20f..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.html +++ /dev/null @@ -1,68 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div - class="relative m-6 max-w-2xl rounded-lg bg-modalBg p-6 shadow-xl" - data-test-id="bescheid-ueberspringen-dialog" -> - <button - class="absolute right-4 top-4 flex size-12 items-center justify-center rounded-full hover:bg-background-100" - (click)="onClose()" - > - <mat-icon>close</mat-icon> - </button> - - <div class="flex flex-col gap-6"> - <div> - <h4 class="text-lg font-medium text-primary">Bescheiderstellung überspringen</h4> - </div> - <div class="grow"> - <p class="text-base"> - Soll die Bescheiderstellung übersprungen und der Vorgang direkt in den Status Abgeschlossen - gesetzt werden? - </p> - </div> - <div class="flex gap-4"> - <ozgcloud-stroked-button-with-spinner - (click)="onConfirm()" - data-test-id="ueberspringen-abschliessen-button" - text="Überspringen und abschließen" - type="submit" - icon="check" - [stateResource]="bescheiderstellungUeberspringen$ | async" - > - </ozgcloud-stroked-button-with-spinner> - <ozgcloud-stroked-button-with-spinner - (click)="onCancel()" - data-test-id="ueberspringen-abbrechen-button" - text="Abbrechen" - color="" - icon="clear" - type="submit" - > - </ozgcloud-stroked-button-with-spinner> - </div> - </div> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.spec.ts deleted file mode 100644 index 8429d3185620d549723b4fbbaa1c620e1a5c6cb8..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.spec.ts +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandResource } from '@alfa-client/command-shared'; -import { - StateResource, - createEmptyStateResource, - createStateResource, -} from '@alfa-client/tech-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; -import { OzgcloudDialogService, OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui'; -import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { DialogRef } from '@angular/cdk/dialog'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatIcon } from '@angular/material/icon'; -import { cold } from 'jest-marbles'; -import { MockComponent } from 'ng-mocks'; -import { of } from 'rxjs'; -import { CommandLinkRel } from '../../../../../../../../command-shared/src/lib/command.linkrel'; -import { createCommandResource } from '../../../../../../../../command-shared/test/command'; -import { createVorgangWithEingangResource } from '../../../../../../../../vorgang-shared/test/vorgang'; -import { VorgangDetailBescheidenUeberspringenDialogComponent } from './vorgang-detail-bescheiden-ueberspringen-dialog.component'; - -describe('VorgangDetailBescheidenUeberspringenButtonComponent', () => { - let component: VorgangDetailBescheidenUeberspringenDialogComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenUeberspringenDialogComponent>; - - let dialogRef: Mock<DialogRef>; - let bescheidService: Mock<BescheidService>; - let ozgcloudDialogService: Mock<OzgcloudDialogService>; - let vorgangService: Mock<VorgangService>; - - beforeEach(async () => { - dialogRef = mock(DialogRef); - bescheidService = mock(BescheidService); - ozgcloudDialogService = mock(OzgcloudDialogService); - vorgangService = mock(VorgangService); - - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenUeberspringenDialogComponent, - MockComponent(OzgcloudStrokedButtonWithSpinnerComponent), - MockComponent(MatIcon), - ], - providers: [ - { - provide: DialogRef, - useValue: dialogRef, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: OzgcloudDialogService, - useValue: ozgcloudDialogService, - }, - { - provide: VorgangService, - useValue: vorgangService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenUeberspringenDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('onCancel', () => { - it('should close dialog', () => { - component.onCancel(); - - expect(dialogRef.close).toHaveBeenCalled(); - }); - }); - - describe('onConfirm', () => { - let vorgangWithEingangResource: VorgangWithEingangResource; - const successfullyDoneCommandStateResource: StateResource<CommandResource> = - createStateResource(createCommandResource([CommandLinkRel.EFFECTED_RESOURCE])); - - beforeEach(() => { - vorgangWithEingangResource = createVorgangWithEingangResource(); - vorgangService.getVorgangWithEingang.mockReturnValue( - of(createStateResource(vorgangWithEingangResource)), - ); - bescheidService.bescheidErstellungUeberspringen.mockReturnValue( - of(successfullyDoneCommandStateResource), - ); - }); - - it('should get vorgang with eingang', () => { - component.onConfirm(); - - expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled(); - }); - - it('should call bescheid service erstellung ueberspringen', (done) => { - component.onConfirm(); - - component.bescheiderstellungUeberspringen$.subscribe(() => { - expect(bescheidService.bescheidErstellungUeberspringen).toHaveBeenCalledWith( - vorgangWithEingangResource, - ); - done(); - }); - }); - - it('should close all dialogs on success', (done) => { - component.onConfirm(); - - component.bescheiderstellungUeberspringen$.subscribe(() => { - expect(ozgcloudDialogService.closeAll).toHaveBeenCalled(); - done(); - }); - }); - - it('should not close all dialogs on command not done successfully', (done) => { - bescheidService.bescheidErstellungUeberspringen.mockReturnValue( - of(createEmptyStateResource()), - ); - - component.onConfirm(); - - component.bescheiderstellungUeberspringen$.subscribe(() => { - expect(ozgcloudDialogService.closeAll).not.toHaveBeenCalled(); - done(); - }); - }); - - it('should return command', () => { - component.onConfirm(); - - expect(component.bescheiderstellungUeberspringen$).toBeObservable( - cold('(a|)', { a: successfullyDoneCommandStateResource }), - ); - }); - }); - - describe('onClose', () => { - it('should close dialog', () => { - component.onClose(); - - expect(dialogRef.close).toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.ts deleted file mode 100644 index c960ee26ac2d189260e5afa2ec4ce95ef56ec95b..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidService } from '@alfa-client/bescheid-shared'; -import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared'; -import { StateResource, isLoaded } from '@alfa-client/tech-shared'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { VorgangService } from '@alfa-client/vorgang-shared'; -import { DialogRef } from '@angular/cdk/dialog'; -import { Component } from '@angular/core'; -import { Observable, filter, first, switchMap } from 'rxjs'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-ueberspringen-dialog', - templateUrl: './vorgang-detail-bescheiden-ueberspringen-dialog.component.html', -}) -export class VorgangDetailBescheidenUeberspringenDialogComponent { - bescheiderstellungUeberspringen$: Observable<StateResource<CommandResource>>; - - constructor( - private readonly dialogRef: DialogRef, - private readonly bescheidService: BescheidService, - private readonly ozgcloudDialogService: OzgcloudDialogService, - private readonly vorgangService: VorgangService, - ) {} - - public onClose(): void { - this.dialogRef.close(); - } - - public onConfirm(): void { - this.bescheiderstellungUeberspringen$ = this.vorgangService.getVorgangWithEingang().pipe( - filter(isLoaded), - first(), - switchMap((stateResource) => - this.bescheidService.bescheidErstellungUeberspringen(stateResource.resource).pipe( - tapOnCommandSuccessfullyDone(() => { - this.ozgcloudDialogService.closeAll(); - }), - ), - ), - ); - } - - public onCancel(): void { - this.dialogRef.close(); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.html deleted file mode 100644 index 5036dc81f87a4906d55be87f32a538b6e50679aa..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.html +++ /dev/null @@ -1,34 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div class="flex w-full flex-row gap-7" role="tablist" aria-orientation="vertical"> - <alfa-vorgang-detail-bescheiden-step-buttons - [(activeStep)]="activeStep" - ></alfa-vorgang-detail-bescheiden-step-buttons> - <alfa-vorgang-detail-bescheiden-steps-content - class="flex-1" - [(activeStep)]="activeStep" - ></alfa-vorgang-detail-bescheiden-steps-content> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.spec.ts deleted file mode 100644 index 3f3fe9261b3e5fda926612eb2714c91df04f6079..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2024 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 { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MockComponent } from 'ng-mocks'; -import { VorgangDetailBescheidenStepButtonsComponent } from './vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component'; -import { VorgangDetailBescheidenStepsContentComponent } from './vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component'; -import { VorgangDetailBescheidenStepsComponent } from './vorgang-detail-bescheiden-steps.component'; -import { VorgangDetailBescheidenWeiterButtonComponent } from './vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; - -describe('VorgangDetailBescheidenStepsComponent', () => { - let component: VorgangDetailBescheidenStepsComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenStepsComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenStepsComponent, - MockComponent(VorgangDetailBescheidenStepButtonsComponent), - MockComponent(VorgangDetailBescheidenWeiterButtonComponent), - MockComponent(VorgangDetailBescheidenStepsContentComponent), - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenStepsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('changeActiveStep', () => { - it('should set activeStep', () => { - const step: number = 1; - - component.changeActiveStep(step); - - expect(component.activeStep).toBe(step); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.ts deleted file mode 100644 index c77004f343469a304d8b498a52223b77b5452da0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2024 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 { Component, Input } from '@angular/core'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-steps', - templateUrl: './vorgang-detail-bescheiden-steps.component.html', -}) -export class VorgangDetailBescheidenStepsComponent { - @Input() activeStep: number = 1; - - public changeActiveStep(step: number): void { - this.activeStep = step; - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html deleted file mode 100644 index 49e6a9a7906c47445d2c667004494a94170ee84d..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<ods-button-with-spinner - *ngIf="showButton$ | async" - (clickEmitter)="clickEmitter.emit()" - [stateResource]="submitResource" - variant="primary" - size="medium" - class="mt-8 flex" - dataTestId="bescheid-weiter-button" - text="Weiter" -> -</ods-button-with-spinner> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts deleted file mode 100644 index 510d50d1bc34aac1039966aad3cc53fe389cbc42..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidService } from '@alfa-client/bescheid-shared'; -import { createStateResource } from '@alfa-client/tech-shared'; -import { Mock, mock } from '@alfa-client/test-utils'; -import { VorgangService, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { cold } from 'jest-marbles'; -import { EMPTY, of } from 'rxjs'; -import { createBescheidResource } from '../../../../../../../bescheid-shared/src/test/bescheid'; -import { createVorgangWithEingangResource } from '../../../../../../../vorgang-shared/test/vorgang'; -import { BescheidenFormService } from '../../bescheiden.formservice'; -import { VorgangDetailBescheidenWeiterButtonComponent } from './vorgang-detail-bescheiden-weiter-button.component'; - -describe('VorgangDetailBescheidenWeiterButtonComponent', () => { - let component: VorgangDetailBescheidenWeiterButtonComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenWeiterButtonComponent>; - - let formService: Mock<BescheidenFormService>; - let bescheidService: Mock<BescheidService>; - let vorgangService: Mock<VorgangService>; - - beforeEach(async () => { - formService = mock(BescheidenFormService); - bescheidService = mock(BescheidService); - vorgangService = mock(VorgangService); - bescheidService.getBescheidDraftIfExists.mockReturnValue(EMPTY); - vorgangService.getVorgangWithEingang.mockReturnValue(EMPTY); - - await TestBed.configureTestingModule({ - declarations: [VorgangDetailBescheidenWeiterButtonComponent], - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: VorgangService, - useValue: vorgangService, - }, - ], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenWeiterButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - it('should show button if update link available', () => { - const bescheidResource = createBescheidResource([BescheidLinkRel.UPDATE]); - bescheidService.getBescheidDraftIfExists.mockReturnValue( - of(createStateResource(bescheidResource)), - ); - - component.ngOnInit(); - - expect(component.showButton$).toBeObservable(cold('(a|)', { a: true })); - }); - - it('should not show button if update link unavailable', () => { - const bescheidResource = createBescheidResource(); - bescheidService.getBescheidDraftIfExists.mockReturnValue( - of(createStateResource(bescheidResource)), - ); - - component.ngOnInit(); - - expect(component.showButton$).toBeObservable(cold('(a|)', { a: false })); - }); - - it('should show button if create bescheid draft link available', () => { - const vorgangWithEingangResource = createVorgangWithEingangResource([ - VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT, - ]); - vorgangService.getVorgangWithEingang.mockReturnValue( - of(createStateResource(vorgangWithEingangResource)), - ); - - component.ngOnInit(); - - expect(component.showButton$).toBeObservable(cold('(a|)', { a: true })); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts deleted file mode 100644 index 8a231cf355b524c3556ce59914bcb001b222d2e0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidLinkRel, BescheidService } from '@alfa-client/bescheid-shared'; -import { StateResource, createEmptyStateResource, isLoaded } from '@alfa-client/tech-shared'; -import { VorgangService, VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Resource, hasLink } from '@ngxp/rest'; -import { Observable, filter, map, merge } from 'rxjs'; -import { BescheidenFormService } from '../../bescheiden.formservice'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden-weiter-button', - templateUrl: './vorgang-detail-bescheiden-weiter-button.component.html', -}) -export class VorgangDetailBescheidenWeiterButtonComponent implements OnInit { - @Input() submitResource: StateResource<Resource> = createEmptyStateResource(); - @Output() clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); - - showButton$: Observable<boolean>; - - constructor( - public formService: BescheidenFormService, - private readonly bescheidService: BescheidService, - private readonly vorgangService: VorgangService, - ) {} - - ngOnInit(): void { - this.showButton$ = merge( - this.vorgangService.getVorgangWithEingang(), - this.bescheidService.getBescheidDraftIfExists(), - ).pipe( - filter(isLoaded), - map( - (stateResource) => - hasLink(stateResource.resource, VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT) || - hasLink(stateResource.resource, BescheidLinkRel.UPDATE), - ), - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html deleted file mode 100644 index da99c64248a271a75a7a429e570b7146c1fa2baa..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.html +++ /dev/null @@ -1,54 +0,0 @@ -<!-- - - Copyright (C) 2024 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. - ---> -<div - class="relative z-10 duration-500 ease-in-out" - aria-label="Bescheid Dialog" - role="dialog" - aria-modal="true" - data-test-id="bescheid-wizard" -> - <div class="fixed inset-0 z-10 w-screen overflow-y-auto"> - <div class="flex h-full items-center justify-center p-8"> - <div - class="relative h-full w-full max-w-7xl transform overflow-hidden rounded-lg bg-background-200 px-6 py-10 text-left shadow-xl transition-all" - > - <alfa-vorgang-detail-bescheiden-abbrechen-button - (clickEmitter)="cancelWizard()" - ></alfa-vorgang-detail-bescheiden-abbrechen-button> - <form [formGroup]="formService.form" class="flex h-full flex-row gap-11"> - <alfa-vorgang-detail-bescheiden-steps - class="flex w-1/2" - ></alfa-vorgang-detail-bescheiden-steps> - <alfa-vorgang-detail-bescheiden-result - data-test-id="bescheiden-result" - (closeDialog)="onClose()" - class="flex w-1/2" - ></alfa-vorgang-detail-bescheiden-result> - </form> - </div> - </div> - </div> -</div> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts deleted file mode 100644 index b976d702d642721c317985fad672a8fe7b94fd48..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.spec.ts +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared'; -import { PostfachService } from '@alfa-client/postfach-shared'; -import { Mock, dispatchEventFromFixture, mock, useFromMock } from '@alfa-client/test-utils'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; -import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; -import { MatIcon } from '@angular/material/icon'; -import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { MockComponent } from 'ng-mocks'; -import { Subscription, of } from 'rxjs'; -import { createBescheidResource } from '../../../../../bescheid-shared/src/test/bescheid'; -import { createVorgangWithEingangResource } from '../../../../../vorgang-shared/test/vorgang'; -import { BescheidenFormService } from './bescheiden.formservice'; -import { VorgangDetailBescheidenResultComponent } from './vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component'; -import { VorgangDetailBescheidenAbbrechenButtonComponent } from './vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component'; -import { VorgangDetailBescheidenAbbrechenDialogComponent } from './vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component'; -import { VorgangDetailBescheidenStepsComponent } from './vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component'; -import { VorgangDetailBescheidenComponent } from './vorgang-detail-bescheiden.component'; - -describe('VorgangDetailBescheidenComponent', () => { - let component: VorgangDetailBescheidenComponent; - let fixture: ComponentFixture<VorgangDetailBescheidenComponent>; - - let bescheidService: Mock<BescheidService>; - let vorgangService: Mock<VorgangService>; - let formService: BescheidenFormService; - let postfachService: Mock<PostfachService>; - let ozgcloudDialogService: Mock<OzgcloudDialogService>; - - let vorgangWithEingangResource: VorgangWithEingangResource; - let bescheidDraftResource: BescheidResource; - - const bescheidenResult: string = getDataTestIdOf('bescheiden-result'); - - beforeEach(async () => { - bescheidService = mock(BescheidService); - vorgangService = mock(VorgangService); - formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService)); - postfachService = mock(PostfachService); - ozgcloudDialogService = mock(OzgcloudDialogService); - - vorgangWithEingangResource = createVorgangWithEingangResource(); - bescheidDraftResource = createBescheidResource(); - - TestBed.overrideComponent(VorgangDetailBescheidenComponent, { - set: { - providers: [ - { - provide: BescheidenFormService, - useValue: formService, - }, - ], - }, - }); - await TestBed.configureTestingModule({ - declarations: [ - VorgangDetailBescheidenComponent, - MockComponent(VorgangDetailBescheidenStepsComponent), - MockComponent(VorgangDetailBescheidenResultComponent), - MockComponent(VorgangDetailBescheidenAbbrechenButtonComponent), - MockComponent(MatIcon), - ], - providers: [ - { - provide: BescheidService, - useValue: bescheidService, - }, - { - provide: VorgangService, - useValue: vorgangService, - }, - { - provide: DialogRef, - useValue: { keydownEvents: of(KeyboardEvent), close: jest.fn(), disableClose: false }, - }, - { - provide: DIALOG_DATA, - useValue: { vorgangWithEingangResource, bescheidDraftResource }, - }, - { - provide: PostfachService, - useValue: postfachService, - }, - { - provide: OzgcloudDialogService, - useValue: ozgcloudDialogService, - }, - ], - imports: [ReactiveFormsModule], - }).compileComponents(); - - fixture = TestBed.createComponent(VorgangDetailBescheidenComponent); - component = fixture.componentInstance; - - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - it('should set vorgang on form service', () => { - const setVorgangWithEingangResource = (formService.setVorgangWithEingangResource = jest.fn()); - - component.ngOnInit(); - - expect(setVorgangWithEingangResource).toHaveBeenCalledWith(vorgangWithEingangResource); - }); - - it('should patch values', () => { - const patchValues = (formService.patchValues = jest.fn()); - - component.ngOnInit(); - - expect(patchValues).toHaveBeenCalledWith(bescheidDraftResource); - }); - - it('should call handleEscapeKey', () => { - component.handleEscapeKey = jest.fn(); - - component.ngOnInit(); - - expect(component.handleEscapeKey).toHaveBeenCalled(); - }); - }); - - describe('handleEscapeKey', () => { - it('should subscribe to dialogRef.keydownEvents', () => { - component.handleEscapeKey(); - - expect(component.keydownEventsSubscription).toBeInstanceOf(Subscription); - }); - }); - - describe('ngOnDestroy', () => { - it('should unsubscribe keydownEventsSubscription', () => { - component.keydownEventsSubscription = new Subscription(); - jest.spyOn(component.keydownEventsSubscription, 'unsubscribe'); - - component.ngOnDestroy(); - - expect(component.keydownEventsSubscription.unsubscribe).toHaveBeenCalled(); - }); - }); - - describe('onClose', () => { - it('should call dialogRef.close', () => { - component.onClose(); - - expect(component.dialogRef.close).toHaveBeenCalled(); - }); - - it('should call vorgang service to reload current vorgang', () => { - component.onClose(); - - expect(vorgangService.reloadCurrentVorgang).toHaveBeenCalled(); - }); - - it('should reload postfach mail list', () => { - component.onClose(); - - expect(postfachService.setPostfachMailOnReload).toHaveBeenCalled(); - }); - }); - - describe('close dialog on bescheiden result', () => { - it('should close dialog ref', () => { - dispatchEventFromFixture(fixture, bescheidenResult, 'closeDialog'); - - expect(component.dialogRef.close).toHaveBeenCalled(); - }); - }); - - describe('cancelWizard', () => { - it('should call ozgcloudDialogService.open', () => { - component.cancelWizard(); - - expect(ozgcloudDialogService.openInCallingComponentContext).toHaveBeenCalledWith( - VorgangDetailBescheidenAbbrechenDialogComponent, - component.viewContainerRef, - ); - }); - }); -}); diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts deleted file mode 100644 index 24f030b71967c3b4ea1a4d4f9c0e3ad3a780166d..0000000000000000000000000000000000000000 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2024 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 { BescheidResource } from '@alfa-client/bescheid-shared'; -import { PostfachService } from '@alfa-client/postfach-shared'; -import { isEscapeKey } from '@alfa-client/tech-shared'; -import { OzgcloudDialogService } from '@alfa-client/ui'; -import { VorgangService } from '@alfa-client/vorgang-shared'; -import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; -import { Component, Inject, OnDestroy, OnInit, ViewContainerRef } from '@angular/core'; -import { Subscription, filter } from 'rxjs'; -import { BescheidenFormService } from './bescheiden.formservice'; -import { BescheidenDialogData } from './bescheiden.model'; -import { VorgangDetailBescheidenAbbrechenDialogComponent } from './vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component'; - -@Component({ - selector: 'alfa-vorgang-detail-bescheiden', - templateUrl: './vorgang-detail-bescheiden.component.html', - providers: [BescheidenFormService], -}) -export class VorgangDetailBescheidenComponent implements OnDestroy, OnInit { - private readonly bescheidDraftResource: BescheidResource; - - keydownEventsSubscription: Subscription; - - public activeStep: number = 1; - - constructor( - public dialogRef: DialogRef, - public readonly formService: BescheidenFormService, - private readonly vorgangService: VorgangService, - private readonly postfachService: PostfachService, - @Inject(DIALOG_DATA) private readonly dialogData: BescheidenDialogData, - private readonly ozgcloudDialogService: OzgcloudDialogService, - readonly viewContainerRef: ViewContainerRef, - ) { - this.bescheidDraftResource = dialogData.bescheidDraftResource; - } - - ngOnInit(): void { - this.formService.setVorgangWithEingangResource(this.dialogData.vorgangWithEingangResource); - this.formService.patchValues(this.bescheidDraftResource); - this.handleEscapeKey(); - } - - handleEscapeKey(): void { - this.keydownEventsSubscription = this.dialogRef.keydownEvents - .pipe(filter(isEscapeKey)) - .subscribe(() => this.cancelWizard()); - } - - ngOnDestroy(): void { - this.keydownEventsSubscription.unsubscribe(); - } - - public onClose(): void { - this.dialogRef.close(); - this.vorgangService.reloadCurrentVorgang(); - this.postfachService.setPostfachMailOnReload(); - } - - public cancelWizard(): void { - this.ozgcloudDialogService.openInCallingComponentContext<VorgangDetailBescheidenAbbrechenDialogComponent>( - VorgangDetailBescheidenAbbrechenDialogComponent, - this.viewContainerRef, - ); - } -} diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts index da1e96c72686b1b996e89ff6ac1e6a5a15af3c9f..150d74f675519f8e62932689e2f2294daeea5fe5 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.ts @@ -24,23 +24,16 @@ import { CommandResource } from '@alfa-client/command-shared'; import { LoeschAnforderungService } from '@alfa-client/loesch-anforderung-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { StateResource } from '@alfa-client/tech-shared'; +import { isResourceNotFoundError, StateResource } from '@alfa-client/tech-shared'; import { Messages, SnackBarService } from '@alfa-client/ui'; -import { - VorgangCommandService, - VorgangService, - VorgangWithEingangResource, -} from '@alfa-client/vorgang-shared'; +import { VorgangCommandService, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Component, OnInit } from '@angular/core'; -import { isResourceNotFoundError } from 'libs/tech-shared/src/lib/error/error.util'; import { Observable, tap } from 'rxjs'; -import { BescheidenFormService } from './vorgang-detail-bescheiden/bescheiden.formservice'; @Component({ selector: 'alfa-vorgang-detail-page', templateUrl: './vorgang-detail-page.component.html', styleUrls: ['./vorgang-detail-page.component.scss'], - providers: [BescheidenFormService], }) export class VorgangDetailPageComponent implements OnInit { vorgangStateResource$: Observable<StateResource<VorgangWithEingangResource>>; @@ -58,12 +51,9 @@ export class VorgangDetailPageComponent implements OnInit { ngOnInit(): void { this.vorgangStateResource$ = this.vorgangService .getVorgangWithEingang() - .pipe( - tap((resource: StateResource<VorgangWithEingangResource>) => this.handleApiError(resource)), - ); + .pipe(tap((resource: StateResource<VorgangWithEingangResource>) => this.handleApiError(resource))); this.revokeCommandStateResource$ = this.vorgangCommandService.getRevokeCommand(); - this.vorgangLoeschenCommandStateResource$ = - this.loeschAnforderungService.getEndgueltigLoeschenCommand(); + this.vorgangLoeschenCommandStateResource$ = this.loeschAnforderungService.getEndgueltigLoeschenCommand(); } handleApiError(resource: StateResource<VorgangWithEingangResource>) { diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts index df1ec6563ff01d6130ab2cf54e144c5bfc970465..1d749edd60cabb56f750dd00852651e0fc41b1cf 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts @@ -24,7 +24,7 @@ import { BescheidModule } from '@alfa-client/bescheid'; import { BinaryFileModule } from '@alfa-client/binary-file'; import { CollaborationModule } from '@alfa-client/collaboration'; -import { ForwardByOzgcloudButtonContainerComponent, ForwardingModule } from '@alfa-client/forwarding'; +import { ForwardingButtonContainerComponent, ForwardingModule } from '@alfa-client/forwarding'; import { HistorieModule } from '@alfa-client/historie'; import { KommentarModule } from '@alfa-client/kommentar'; import { LoeschAnforderungModule } from '@alfa-client/loesch-anforderung'; @@ -32,21 +32,7 @@ import { LoeschAnforderungSharedModule } from '@alfa-client/loesch-anforderung-s import { PostfachModule } from '@alfa-client/postfach'; import { PostfachSharedModule } from '@alfa-client/postfach-shared'; import { ConvertForDataTestPipe, ConvertProblemDetailToErrorMessagesPipe, HasLinkPipe } from '@alfa-client/tech-shared'; -import { - BackButtonComponent, - DateEditorComponent, - ExpansionPanelComponent, - IconButtonWithSpinnerComponent, - OzgcloudIconButtonPrimaryComponent, - OzgcloudIconComponent, - OzgcloudMenuComponent, - OzgcloudPasteTextButtonComponent, - OzgcloudStrokedButtonWithSpinnerComponent, - OzgcloudTextEditorComponent, - SpinnerComponent, - SpinnerTransparencyComponent, - SubnavigationComponent, -} from '@alfa-client/ui'; +import { BackButtonComponent, DateEditorComponent, ExpansionPanelComponent, IconButtonWithSpinnerComponent, OzgcloudIconButtonPrimaryComponent, OzgcloudIconComponent, OzgcloudMenuComponent, OzgcloudPasteTextButtonComponent, OzgcloudStrokedButtonWithSpinnerComponent, OzgcloudTextEditorComponent, SpinnerComponent, SpinnerTransparencyComponent, SubnavigationComponent, } from '@alfa-client/ui'; import { UserProfileModule } from '@alfa-client/user-profile'; import { UserProfileSharedModule } from '@alfa-client/user-profile-shared'; import { VorgangSharedModule } from '@alfa-client/vorgang-shared'; @@ -60,13 +46,7 @@ import { MatIcon } from '@angular/material/icon'; import { MatMenuTrigger } from '@angular/material/menu'; import { MatTab, MatTabContent, MatTabGroup } from '@angular/material/tabs'; import { RouterModule, Routes } from '@angular/router'; -import { - ButtonWithSpinnerComponent, - FileUploadEditorComponent, - SingleFileUploadEditorComponent, - TextareaEditorComponent, - TextEditorComponent, -} from '@ods/component'; +import { ButtonWithSpinnerComponent, FileUploadEditorComponent, SingleFileUploadEditorComponent, TextareaEditorComponent, TextEditorComponent, } from '@ods/component'; import { ArchiveIconComponent, AttachmentComponent, @@ -119,29 +99,6 @@ import { VorgangDetailFormularDatenComponent } from './vorgang-detail-page/vorga import { VorgangDetailHeaderComponent } from './vorgang-detail-page/vorgang-detail-area/vorgang-detail-header/vorgang-detail-header.component'; import { VorgangDetailBackButtonContainerComponent } from './vorgang-detail-page/vorgang-detail-back-button-container/vorgang-detail-back-button-container.component'; import { VorgangDetailBackButtonComponent } from './vorgang-detail-page/vorgang-detail-back-button-container/vorgang-detail-back-button/vorgang-detail-back-button.component'; -import { VorgangDetailBescheidenResultAttachmentsComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component'; -import { VorgangDetailBescheidenResultDokumentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component'; -import { VorgangDetailBescheidenResultNachrichtComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-nachricht/vorgang-detail-bescheiden-result-nachricht.component'; -import { VorgangDetailBescheidenResultStatusComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-status/vorgang-detail-bescheiden-result-status.component'; -import { VorgangDetailBescheidenResultComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result.component'; -import { VorgangDetailBescheidenStepButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-button/vorgang-detail-bescheiden-step-button.component'; -import { VorgangDetailBescheidenStepButtonsComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-buttons/vorgang-detail-bescheiden-step-buttons.component'; -import { VorgangDetailBescheidenStepTitleComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-step-title/vorgang-detail-bescheiden-step-title.component'; -import { VorgangDetailBescheidenAbbrechenButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-button/vorgang-detail-bescheiden-abbrechen-button.component'; -import { VorgangDetailBescheidenAbbrechenDialogComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-abbrechen-dialog/vorgang-detail-bescheiden-abbrechen-dialog.component'; -import { VorgangDetailBescheidenAntragBescheidenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-antrag-bescheiden/vorgang-detail-bescheiden-antrag-bescheiden.component'; -import { VorgangDetailBescheidenBescheidVersendenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-bescheid-versenden/vorgang-detail-bescheiden-bescheid-versenden.component'; -import { VorgangDetailBescheidenAttachmentHochladenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component'; -import { VorgangDetailBescheidenBescheidAutomatischErstellenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen/vorgang-detail-bescheiden-bescheid-automatisch-erstellen.component'; -import { VorgangDetailBescheidenDokumentHochladenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokument-hochladen/vorgang-detail-bescheiden-dokument-hochladen.component'; -import { VorgangDetailBescheidenDokumenteHinzufuegenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component'; -import { VorgangDetailBescheidenStepContentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-step-content/vorgang-detail-bescheiden-step-content.component'; -import { VorgangDetailBescheidenStepsContentComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-steps-content.component'; -import { VorgangDetailBescheidenUeberspringenButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-button/vorgang-detail-bescheiden-ueberspringen-button.component'; -import { VorgangDetailBescheidenUeberspringenDialogComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-ueberspringen-dialog/vorgang-detail-bescheiden-ueberspringen-dialog.component'; -import { VorgangDetailBescheidenStepsComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps.component'; -import { VorgangDetailBescheidenWeiterButtonComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-weiter-button/vorgang-detail-bescheiden-weiter-button.component'; -import { VorgangDetailBescheidenComponent } from './vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component'; import { VorgangArchiveConfirmationDialogContainerComponent } from './vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component'; import { VorgangArchiveConfirmationDialogComponent } from './vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog/vorgang-archive-confirmation-dialog.component'; import { VorgangArchiveContainerComponent } from './vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-container.component'; @@ -230,7 +187,7 @@ const routes: Routes = [ DropdownMenuTextItemComponent, MoreIconComponent, FileIconComponent, - ForwardByOzgcloudButtonContainerComponent, + ForwardingButtonContainerComponent, TooltipDirective, EditIconComponent, DiscardVorgangIconComponent, @@ -262,34 +219,11 @@ const routes: Routes = [ ProcessVorgangContainerComponent, AktenzeichenEditableComponent, AktenzeichenEditDialogComponent, - VorgangDetailBescheidenComponent, - VorgangDetailBescheidenResultComponent, - VorgangDetailBescheidenStepButtonComponent, - VorgangDetailBescheidenStepsComponent, - VorgangDetailBescheidenStepButtonsComponent, - VorgangDetailBescheidenWeiterButtonComponent, - VorgangDetailBescheidenStepTitleComponent, - VorgangDetailBescheidenStepsContentComponent, - VorgangDetailBescheidenStepContentComponent, - VorgangDetailBescheidenResultStatusComponent, - VorgangDetailBescheidenUeberspringenButtonComponent, - VorgangDetailBescheidenUeberspringenDialogComponent, - VorgangDetailBescheidenAbbrechenDialogComponent, - VorgangDetailBescheidenAbbrechenButtonComponent, - VorgangDetailBescheidenDokumentHochladenComponent, - VorgangDetailBescheidenBescheidAutomatischErstellenComponent, - VorgangDetailBescheidenDokumenteHinzufuegenComponent, - VorgangDetailBescheidenAntragBescheidenComponent, - VorgangDetailBescheidenAttachmentHochladenComponent, - VorgangDetailBescheidenResultDokumentComponent, - VorgangDetailBescheidenResultAttachmentsComponent, - VorgangDetailBescheidenBescheidVersendenComponent, - VorgangDetailBescheidenResultNachrichtComponent, VorgangDetailDateienContainerComponent, VorgangArchiveContainerComponent, VorgangArchiveConfirmationDialogContainerComponent, VorgangArchiveConfirmationDialogComponent, ], - exports: [VorgangDetailAntragstellerComponent, VorgangDetailAntragDataComponent, VorgangDetailBescheidenComponent], + exports: [VorgangDetailAntragstellerComponent, VorgangDetailAntragDataComponent], }) export class VorgangDetailModule {} diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts index c3358acb510534afa4df0bca712d8b2ff8161bb5..c2e342d93cc22a74bd18be0d1c135b5e51606c50 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts @@ -1054,6 +1054,12 @@ describe('Vorgang Reducer', () => { expect(vorgangStatistic.resource.byStatus.verworfen).toBeNull(); }); + it('should have null as weitergeleitet', () => { + const vorgangStatistic: StateResource<VorgangStatistic> = Reducer.initialState.vorgangStatistic; + + expect(vorgangStatistic.resource.byStatus.weitergeleitet).toBeNull(); + }); + it('should have null as zuLoeschen', () => { const vorgangStatistic: StateResource<VorgangStatistic> = Reducer.initialState.vorgangStatistic; diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts index 0f200a551da43386ab80c67938d561a277bed11d..2601e8b7044b3d484d2556d1e418d1642dffa17f 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts @@ -126,6 +126,7 @@ function createEmptyVorgangStatistic(): VorgangStatistic { inBearbeitung: null, beschieden: null, verworfen: null, + weitergeleitet: null, zuLoeschen: null, }, wiedervorlagen: null, diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts index 76c2de5b4f697f184580a6ec74c0ebaaaf1705be..c522a0f4fcc3a6dfb8ee4d11c373ad4030d1717a 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { UrlSegment } from '@angular/router'; -import { faker } from '@faker-js/faker'; import { ApiRootLinkRel } from '@alfa-client/api-root-shared'; import { RouteData } from '@alfa-client/navigation-shared'; import { EMPTY_STRING } from '@alfa-client/tech-shared'; +import { UrlSegment } from '@angular/router'; +import { faker } from '@faker-js/faker'; import { createRouteData } from 'libs/navigation-shared/test/navigation-test-factory'; import { initialState, VorgangState } from './+state/vorgang.reducer'; import { @@ -130,9 +130,7 @@ describe('Vorgang Navigation Util', () => { it('should return value on uebersichtsSeite', () => { jest.spyOn(VorgangNavigationUtil, 'isUebersichtsSeite').mockReturnValue(true); - const vorgangFilter: VorgangFilter = getVorgangFilter( - buildWithRouteParam(VorgangFilter.ALLE), - ); + const vorgangFilter: VorgangFilter = getVorgangFilter(buildWithRouteParam(VorgangFilter.ALLE)); expect(vorgangFilter).toBe(VorgangFilter.ALLE); }); @@ -152,10 +150,7 @@ describe('Vorgang Navigation Util', () => { const vorgangView: VorgangView = VorgangView.ANGENOMMEN; jest.spyOn(VorgangNavigationUtil, 'getVorgangView').mockReturnValue(vorgangView); - const isSelected: boolean = VorgangNavigationUtil.isViewSelected( - createRouteData(), - vorgangView, - ); + const isSelected: boolean = VorgangNavigationUtil.isViewSelected(createRouteData(), vorgangView); expect(isSelected).toBeTruthy(); }); @@ -164,10 +159,7 @@ describe('Vorgang Navigation Util', () => { const vorgangView: VorgangView = VorgangView.ANGENOMMEN; jest.spyOn(VorgangNavigationUtil, 'getVorgangView').mockReturnValue(VorgangView.NEU); - const isSelected: boolean = VorgangNavigationUtil.isViewSelected( - createRouteData(), - vorgangView, - ); + const isSelected: boolean = VorgangNavigationUtil.isViewSelected(createRouteData(), vorgangView); expect(isSelected).toBeFalsy(); }); @@ -198,7 +190,7 @@ describe('Vorgang Navigation Util', () => { const vorgangView: VorgangView = VorgangNavigationUtil.getVorgangView(routeData); - expect(vorgangView).toBe(6); + expect(vorgangView).toBe(VorgangView.VORGANG_LIST); }); it('should return VorgangView.NEU if routeData contains this view', () => { @@ -261,9 +253,7 @@ describe('Vorgang Navigation Util', () => { }); it('should build by given filter and view', () => { - jest - .spyOn(Storage, 'getViewFromLocalStorage') - .mockReturnValue(ROUTE_PARAM_BY_VORGANG_VIEW[VorgangView.ANGENOMMEN]); + jest.spyOn(Storage, 'getViewFromLocalStorage').mockReturnValue(ROUTE_PARAM_BY_VORGANG_VIEW[VorgangView.ANGENOMMEN]); jest .spyOn(Storage, 'getFilterFromLocalStorage') .mockReturnValue(ROUTE_PARAM_BY_VORGANG_FILTER[VorgangFilter.MEINE_VORGAENGE]); @@ -340,10 +330,7 @@ describe('Vorgang Navigation Util', () => { it('should build by meine vorgänge filter and view', () => { const state: VorgangState = { ...initialState, vorgangView: VorgangView.NEU }; - const routePath: string = buildVorgangListRouteWithVorgangFilter( - state, - VorgangFilter.MEINE_VORGAENGE, - ); + const routePath: string = buildVorgangListRouteWithVorgangFilter(state, VorgangFilter.MEINE_VORGAENGE); expect(routePath).toEqual('/meine/neu'); }); @@ -354,10 +341,7 @@ describe('Vorgang Navigation Util', () => { vorgangView: VorgangView.SEARCH, searchString: 'testSearchString', }; - const routePath: string = buildVorgangListRouteWithVorgangFilter( - state, - VorgangFilter.MEINE_VORGAENGE, - ); + const routePath: string = buildVorgangListRouteWithVorgangFilter(state, VorgangFilter.MEINE_VORGAENGE); expect(routePath).toEqual('/meine/search/testSearchString'); }); @@ -368,10 +352,7 @@ describe('Vorgang Navigation Util', () => { vorgangView: VorgangView.ANGENOMMEN, searchString: 'testSearchString', }; - const routePath: string = buildVorgangListRouteWithVorgangFilter( - state, - VorgangFilter.MEINE_VORGAENGE, - ); + const routePath: string = buildVorgangListRouteWithVorgangFilter(state, VorgangFilter.MEINE_VORGAENGE); expect(routePath).toEqual('/meine/angenommen'); }); @@ -406,19 +387,13 @@ describe('Vorgang Navigation Util', () => { }); it('return linkRel for Meine Vorgänge Filter', () => { - const linkRel: string = buildLinkRel( - VorgangFilter.MEINE_VORGAENGE, - VorgangView.VORGANG_LIST, - ); + const linkRel: string = buildLinkRel(VorgangFilter.MEINE_VORGAENGE, VorgangView.VORGANG_LIST); expect(linkRel).toBe('vorgaenge_my'); }); it('return linkRel for Nicht Zugewiesen Filter', () => { - const linkRel: string = buildLinkRel( - VorgangFilter.NICHT_ZUGEWIESEN, - VorgangView.VORGANG_LIST, - ); + const linkRel: string = buildLinkRel(VorgangFilter.NICHT_ZUGEWIESEN, VorgangView.VORGANG_LIST); expect(linkRel).toBe('vorgaenge_unassigned'); }); @@ -456,21 +431,13 @@ describe('Vorgang Navigation Util', () => { const vorgangView: VorgangView = VorgangView.NEU; it('should return routePath of view and filter', () => { - const routePath: string = buildVorgangFilterViewRoutePath( - vorgangFilter, - vorgangView, - EMPTY_STRING, - ); + const routePath: string = buildVorgangFilterViewRoutePath(vorgangFilter, vorgangView, EMPTY_STRING); expect(routePath).toBe('/alle/neu'); }); it('should return routePath of view and filter and searchString', () => { - const routePath: string = buildVorgangFilterViewRoutePath( - vorgangFilter, - vorgangView, - 'searchString', - ); + const routePath: string = buildVorgangFilterViewRoutePath(vorgangFilter, vorgangView, 'searchString'); expect(routePath).toBe('/alle/neu/searchString'); }); diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts index d525cd4e9a1614ee19f2db106387e0ed2937fe5b..053d9eb1c84a2b396d86b45fbf8908b4790f76a9 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts @@ -40,6 +40,7 @@ export const ANGENOMMEN_ROUTE_PARAM: string = 'angenommen'; export const IN_BEARBEITUNG_ROUTE_PARAM: string = 'in_bearbeitung'; export const BESCHIEDEN_ROUTE_PARAM: string = 'beschieden'; export const ABGESCHLOSSEN_ROUTE_PARAM: string = 'abgeschlossen'; +export const WEITERGELEITET_ROUTE_PARAM: string = 'weitergeleitet'; export const VERWORFEN_ROUTE_PARAM: string = 'verworfen'; export const WIEDERVORLAGEN_ROUTE_PARAM: string = 'wiedervorlagen'; export const UNGELESENE_NACHRICHTEN_ROUTE_PARAM: string = 'ungelesene_nachrichten'; @@ -54,6 +55,7 @@ export const ROUTE_PARAM_BY_VORGANG_VIEW: { [view: string]: string } = { [VorgangView.IN_BEARBEITUNG]: IN_BEARBEITUNG_ROUTE_PARAM, [VorgangView.BESCHIEDEN]: BESCHIEDEN_ROUTE_PARAM, [VorgangView.ABGESCHLOSSEN]: ABGESCHLOSSEN_ROUTE_PARAM, + [VorgangView.WEITERGELEITET]: WEITERGELEITET_ROUTE_PARAM, [VorgangView.VERWORFEN]: VERWORFEN_ROUTE_PARAM, [VorgangView.VORGANG_LIST]: EMPTY_STRING, [VorgangView.WIEDERVORLAGEN]: WIEDERVORLAGEN_ROUTE_PARAM, @@ -68,6 +70,7 @@ export const VORGANG_VIEW_BY_ROUTE_PARAM: { [routeParam: string]: VorgangView } [IN_BEARBEITUNG_ROUTE_PARAM]: VorgangView.IN_BEARBEITUNG, [BESCHIEDEN_ROUTE_PARAM]: VorgangView.BESCHIEDEN, [ABGESCHLOSSEN_ROUTE_PARAM]: VorgangView.ABGESCHLOSSEN, + [WEITERGELEITET_ROUTE_PARAM]: VorgangView.WEITERGELEITET, [VERWORFEN_ROUTE_PARAM]: VorgangView.VERWORFEN, [WIEDERVORLAGEN_ROUTE_PARAM]: VorgangView.WIEDERVORLAGEN, [UNGELESENE_NACHRICHTEN_ROUTE_PARAM]: VorgangView.UNGELESENE_NACHRICHTEN, @@ -115,9 +118,7 @@ export function isViewSelected(routeData: RouteData, vorgangView: VorgangView): export function getVorgangView(routeData: RouteData): VorgangView { const vorgangViewValue: string = VorgangNavigationUtil.getRouteUrlSegment(routeData, 1); if (VorgangNavigationUtil.isUebersichtsSeite(routeData)) { - return isNotUndefined(vorgangViewValue) ? - VORGANG_VIEW_BY_ROUTE_PARAM[vorgangViewValue] - : VorgangView.VORGANG_LIST; + return isNotUndefined(vorgangViewValue) ? VORGANG_VIEW_BY_ROUTE_PARAM[vorgangViewValue] : VorgangView.VORGANG_LIST; } return undefined; } @@ -133,9 +134,7 @@ export function isUebersichtsSeite(routeData: RouteData): boolean { } export function getRouteUrlSegment(routeData: RouteData, num: number): string { - return routeData.urlSegments.length > num ? - routeData.urlSegments[num].path.toString() - : undefined; + return routeData.urlSegments.length > num ? routeData.urlSegments[num].path.toString() : undefined; } export function buildBackButtonUrl(state: VorgangState): string { @@ -153,17 +152,11 @@ export function isStateEqualLocalStorage(state: VorgangState): boolean { ); } -export function buildVorgangListRoutePathWithFilter( - state: VorgangState, - filter: VorgangFilter, -): string { +export function buildVorgangListRoutePathWithFilter(state: VorgangState, filter: VorgangFilter): string { return VorgangNavigationUtil.buildVorgangListRouteWithVorgangFilter(state, filter); } -export function buildVorgangListRouteWithVorgangFilter( - state: VorgangState, - filter: VorgangFilter, -): string { +export function buildVorgangListRouteWithVorgangFilter(state: VorgangState, filter: VorgangFilter): string { let route = '/' + ROUTE_PARAM_BY_VORGANG_FILTER[filter]; if (state.vorgangView !== VorgangView.VORGANG_LIST) { @@ -198,9 +191,7 @@ export function buildLinkRelFromPathSegments(pathSegments: string[]): string { } const vorgangView: VorgangView = - isEmpty(pathSegments[1]) ? - VorgangView.VORGANG_LIST - : VORGANG_VIEW_BY_ROUTE_PARAM[pathSegments[1]]; + isEmpty(pathSegments[1]) ? VorgangView.VORGANG_LIST : VORGANG_VIEW_BY_ROUTE_PARAM[pathSegments[1]]; return buildLinkRel(vorgangFilter, vorgangView); } @@ -210,11 +201,7 @@ export function buildVorgangFilterViewRoutePath( vorgangView: VorgangView, searchString: string, ): string { - let baseRoutePath: string = - '/' + - ROUTE_PARAM_BY_VORGANG_FILTER[vorgangFilter] + - '/' + - ROUTE_PARAM_BY_VORGANG_VIEW[vorgangView]; + let baseRoutePath: string = '/' + ROUTE_PARAM_BY_VORGANG_FILTER[vorgangFilter] + '/' + ROUTE_PARAM_BY_VORGANG_VIEW[vorgangView]; if (isNotEmpty(searchString)) { return baseRoutePath + '/' + searchString; } diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts index 8417137108330ec18fd817f11a55d134e9e47f24..956adad470e23174c4cd6360ab7853420a9e5cc9 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.model.ts @@ -118,6 +118,7 @@ export interface ByStatus { beschieden: number; abgeschlossen: number; verworfen: number; + weitergeleitet: number; zuLoeschen: number; } @@ -160,6 +161,7 @@ export enum VorgangView { ABGESCHLOSSEN, VERWORFEN, VORGANG_LIST, + WEITERGELEITET, WIEDERVORLAGEN, SEARCH, ZU_LOESCHEN, diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts index 0aa3ead988609bc5416e593f13cfdf6e44bd8a6e..5e9995262ed38703521d02d10ee078a330163cbd 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts @@ -23,27 +23,33 @@ */ import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared'; import { BinaryFileListResource } from '@alfa-client/binary-file-shared'; -import { CommandOrder, CommandResource, CommandService, CreateCommandProps } from '@alfa-client/command-shared'; +import { + CommandOrder, + CommandResource, + CommandService, + CreateCommandProps, + CreateCommandPropsWithoutResource, +} from '@alfa-client/command-shared'; import { Environment } from '@alfa-client/environment-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { EMPTY_STRING, StateResource, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { HttpErrorResponse } from '@angular/common/http'; +import { faker } from '@faker-js/faker'; import { ResourceUri, getUrl } from '@ngxp/rest'; import { cold, hot } from 'jest-marbles'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { createBinaryFileListResource } from 'libs/binary-file-shared/test/binary-file'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; -import { createCommandResource } from 'libs/command-shared/test/command'; +import { createCommandResource, createCreateCommandPropsWithoutResource } from 'libs/command-shared/test/command'; +import { singleColdCompleted } from 'libs/tech-shared/test/marbles'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { Observable, of } from 'rxjs'; import { VorgangFacade } from './+state/vorgang.facade'; import { VorgangWithEingangLinkRel } from './vorgang.linkrel'; -import { AdditionalActions, VorgangWithEingangResource } from './vorgang.model'; +import { AdditionalActions, VorgangResource, VorgangWithEingangResource } from './vorgang.model'; import { VorgangService } from './vorgang.service'; -import { faker } from '@faker-js/faker'; - import * as VorgangNavigationUtil from './vorgang-navigation.util'; describe('VorgangService', () => { @@ -515,4 +521,64 @@ describe('VorgangService', () => { }); }); }); + + describe('select vorgang with eingang', () => { + const vorgangStateResource: StateResource<VorgangResource> = createStateResource(createVorgangWithEingangResource()); + + beforeEach(() => { + facade.getVorgangWithEingang.mockReturnValue(of(vorgangStateResource)); + }); + + it('should call facade to get vorgang with eingang', () => { + service.selectVorgangWithEingang(); + + expect(facade.getVorgangWithEingang).toHaveBeenCalled(); + }); + + it('should return value', () => { + const vorgangWithEingangStateResource$: Observable<StateResource<VorgangWithEingangResource>> = + service.selectVorgangWithEingang(); + + expect(vorgangWithEingangStateResource$).toBeObservable(singleColdCompleted(vorgangStateResource)); + }); + }); + + describe('create command', () => { + const vorgangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); + + const createCommandProps: CreateCommandPropsWithoutResource = createCreateCommandPropsWithoutResource(); + const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); + + beforeEach(() => { + facade.getVorgangWithEingang.mockReturnValue(of(createStateResource(vorgangResource))); + commandService.createCommandByProps.mockReturnValue(of(commandStateResource)); + }); + + it('should call facade to get vorgang with eingang', () => { + service.createCommand(createCommandProps).subscribe(); + + expect(facade.getVorgangWithEingang).toHaveBeenCalled(); + }); + + it('should call command service to create command', () => { + service.createCommand(createCommandProps).subscribe(); + + expect(commandService.createCommandByProps).toHaveBeenCalledWith({ ...createCommandProps, resource: vorgangResource }); + }); + + it('should return response from command service', () => { + const forwardCommand$: Observable<StateResource<CommandResource>> = service.createCommand(createCommandProps); + + expect(forwardCommand$).toBeObservable(singleColdCompleted(commandStateResource)); + }); + + it('should call reload if command is done and reload flag is true', () => { + service.reloadVorgang = jest.fn(); + + service.createCommand(createCommandProps, true).subscribe(); + + expect(service.reloadVorgang).toHaveBeenCalled(); + }); + }); }); diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts index 1af6e12ff7877e9e221d05730199423689663082..7e43262e9757d58e030c4bbe2900aae791255e96 100644 --- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts +++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts @@ -28,15 +28,17 @@ import { CommandResource, CommandService, CreateCommandProps, + CreateCommandPropsWithoutResource, getEffectedResourceUrl, + tapOnCommandSuccessfullyDone, } from '@alfa-client/command-shared'; import { ENVIRONMENT_CONFIG, Environment } from '@alfa-client/environment-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { StateResource, createEmptyStateResource, doIfLoadingRequired, isNotNull } from '@alfa-client/tech-shared'; +import { StateResource, createEmptyStateResource, doIfLoadingRequired, isNotNull, mapToResource } from '@alfa-client/tech-shared'; import { Inject, Injectable } from '@angular/core'; import { ResourceUri, hasLink } from '@ngxp/rest'; import { Observable, combineLatest } from 'rxjs'; -import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators'; +import { filter, first, map, startWith, switchMap, tap, withLatestFrom } from 'rxjs/operators'; import { VorgangFacade } from './+state/vorgang.facade'; import { buildLinkRelFromPathSegments } from './vorgang-navigation.util'; import { VorgangWithEingangLinkRel } from './vorgang.linkrel'; @@ -142,10 +144,6 @@ export class VorgangService { return this.facade.getAssignUserCommand(); } - public reloadVorgang(commandResource: CommandResource): void { - this.facade.loadVorgangWithEingang(getEffectedResourceUrl(commandResource)); - } - public getBackButtonUrl(): Observable<string> { return this.facade.getBackButtonUrl(); } @@ -198,4 +196,28 @@ export class VorgangService { const createCommand = { order: CommandOrder.SET_AKTENZEICHEN, body: { aktenzeichen } }; return this.commandService.createCommand(vorgang, VorgangWithEingangLinkRel.SET_AKTENZEICHEN, createCommand); } + + public createCommand( + createCommandProps: CreateCommandPropsWithoutResource, + reloadResource: boolean = false, + ): Observable<StateResource<CommandResource>> { + return this.selectVorgangWithEingang().pipe( + first(), + mapToResource(), + switchMap((vorgang: VorgangWithEingangResource) => + this.commandService.createCommandByProps({ ...createCommandProps, resource: vorgang }), + ), + tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => { + if (reloadResource) this.reloadVorgang(commandStateResource.resource); + }), + ); + } + + public selectVorgangWithEingang(): Observable<StateResource<VorgangWithEingangResource>> { + return this.facade.getVorgangWithEingang(); + } + + public reloadVorgang(commandResource: CommandResource): void { + this.facade.loadVorgangWithEingang(getEffectedResourceUrl(commandResource)); + } } diff --git a/alfa-client/libs/vorgang-shared/test/vorgang.ts b/alfa-client/libs/vorgang-shared/test/vorgang.ts index 9eadf4c36b6fbb1e06bab1d81880a2d386db0246..0a98811ad59a31a8c735fa90e1efe5a296f6aceb 100644 --- a/alfa-client/libs/vorgang-shared/test/vorgang.ts +++ b/alfa-client/libs/vorgang-shared/test/vorgang.ts @@ -160,6 +160,7 @@ function createByStatus(): ByStatus { beschieden: faker.number.int(), abgeschlossen: faker.number.int(), verworfen: faker.number.int(), + weitergeleitet: faker.number.int(), zuLoeschen: faker.number.int(), }; } diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/_vorgang-views-menu.theme.scss b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/_vorgang-views-menu.theme.scss index 01889d5e0d21fe759a533c2415fe3ccfac84c804..b29f62b51b0da42f61a47a11583e6e11445e272e 100644 --- a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/_vorgang-views-menu.theme.scss +++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/_vorgang-views-menu.theme.scss @@ -90,22 +90,15 @@ alfa-vorgang-view-item { border-color: #155ab4; } - &.angenommen { - background-color: #f6ebce; - border-color: #f1c14e; - } - + &.angenommen, &.in_bearbeitung { background-color: #f6ebce; border-color: #f1c14e; } - &.beschieden { - background-color: #d9eec5; - border-color: #7ccb2b; - } - - &.abgeschlossen { + &.beschieden, + &.abgeschlossen, + &.weitergeleitet { background-color: #d9eec5; border-color: #7ccb2b; } diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html index 21f2c7272fe3695da90ec1ffd5685265b2a0e4be..fde89f0449a26cb2ab766ff0c4eef29de14fd154 100644 --- a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html +++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.html @@ -28,10 +28,7 @@ <alfa-vorgang-view-item-container *ngIf=" apiRootResource - | hasAnyLink - : apiRootLinkRel.ALLE_VORGAENGE_NEU - : apiRootLinkRel.MEINE_VORGAENGE_NEU - : apiRootLinkRel.UNASSIGNED_NEU + | hasAnyLink: apiRootLinkRel.ALLE_VORGAENGE_NEU : apiRootLinkRel.MEINE_VORGAENGE_NEU : apiRootLinkRel.UNASSIGNED_NEU " data-test-id="vorgang-neu-view" label="Neu" @@ -100,6 +97,22 @@ > <div class="dot abgeschlossen"></div> </alfa-vorgang-view-item-container> + @if ( + apiRootResource + | hasAnyLink + : apiRootLinkRel.ALLE_VORGAENGE_WEITERGELEITET + : apiRootLinkRel.MEINE_VORGAENGE_WEITERGELEITET + : apiRootLinkRel.UNASSIGNED_WEITERGELEITET + ) { + <alfa-vorgang-view-item-container + data-test-id="vorgang-weitergeleitet-view" + label="Weitergeleitet" + [view]="vorgangView.WEITERGELEITET" + [count]="statistic.byStatus.weitergeleitet" + > + <div class="dot weitergeleitet"></div> + </alfa-vorgang-view-item-container> + } <alfa-vorgang-view-item-container *ngIf=" apiRootResource @@ -159,17 +172,11 @@ [view]="vorgangView.WIEDERVORLAGEN" [count]="statistic.wiedervorlagen" > - <alfa-wiedervorlage-icon - [isOverdue]="statistic.existsWiedervorlageOverdue" - ></alfa-wiedervorlage-icon> + <alfa-wiedervorlage-icon [isOverdue]="statistic.existsWiedervorlageOverdue"></alfa-wiedervorlage-icon> </alfa-vorgang-view-item-container> <alfa-vorgang-view-item-container *ngIf=" - apiRootResource - | hasAnyLink - : apiRootLinkRel.ALLE_VORGAENGE - : apiRootLinkRel.MEINE_VORGAENGE - : apiRootLinkRel.UNASSIGNED + apiRootResource | hasAnyLink: apiRootLinkRel.ALLE_VORGAENGE : apiRootLinkRel.MEINE_VORGAENGE : apiRootLinkRel.UNASSIGNED " data-test-id="vorgang-vorgang-list-view" label="Vorgangsliste" @@ -180,11 +187,7 @@ </alfa-vorgang-view-item-container> <alfa-vorgang-search-view-item-container *ngIf=" - apiRootResource - | hasAnyLink - : apiRootLinkRel.SEARCH_ALLE - : apiRootLinkRel.SEARCH_MEINE - : apiRootLinkRel.SEARCH_UNASSIGNED + apiRootResource | hasAnyLink: apiRootLinkRel.SEARCH_ALLE : apiRootLinkRel.SEARCH_MEINE : apiRootLinkRel.SEARCH_UNASSIGNED " data-test-id="vorgang-search-view" class="top-border" diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts index 002788d2e9ecf9fc8c9f0e23f9797b125c7edc8d..d7cd88c0faf1e5ca2ec114a6908733f27df88fe8 100644 --- a/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts +++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page/vorgang-views-menu/vorgang-views-menu.component.spec.ts @@ -24,11 +24,7 @@ import { ApiRootLinkRel } from '@alfa-client/api-root-shared'; import { HasLinkPipe, createStateResource } from '@alfa-client/tech-shared'; import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils'; -import { - OzgcloudIconComponent, - OzgcloudSvgIconComponent, - PostfachIconComponent, -} from '@alfa-client/ui'; +import { OzgcloudIconComponent, OzgcloudSvgIconComponent, PostfachIconComponent } from '@alfa-client/ui'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { HasAnyLinkPipe } from 'libs/tech-shared/src/lib/pipe/has-any-link.pipe'; @@ -50,6 +46,7 @@ describe('VorgangViewsMenuComponent', () => { const inBearbeitungView: string = getDataTestIdOf('vorgang-in-bearbeitung-view'); const beschiedenView: string = getDataTestIdOf('vorgang-beschieden-view'); const abgeschlossenView: string = getDataTestIdOf('vorgang-abgeschlossen-view'); + const weitergeleitetView: string = getDataTestIdOf('vorgang-weitergeleitet-view'); const verworfenView: string = getDataTestIdOf('vorgang-verworfen-view'); const wiedervorlagenView: string = getDataTestIdOf('vorgang-wiedervorlagen-view'); const ungeleseneNachrichtenView: string = getDataTestIdOf('vorgang-ungelesene-nachrichten-view'); @@ -83,16 +80,15 @@ describe('VorgangViewsMenuComponent', () => { }); describe('neu view', () => { - it.each([ - ApiRootLinkRel.ALLE_VORGAENGE_NEU, - ApiRootLinkRel.MEINE_VORGAENGE_NEU, - ApiRootLinkRel.UNASSIGNED_NEU, - ])('should show if %s link exists', (linkRel: string) => { - component.apiRootResource = createApiRootResource([linkRel]); - fixture.detectChanges(); + it.each([ApiRootLinkRel.ALLE_VORGAENGE_NEU, ApiRootLinkRel.MEINE_VORGAENGE_NEU, ApiRootLinkRel.UNASSIGNED_NEU])( + 'should show if %s link exists', + (linkRel: string) => { + component.apiRootResource = createApiRootResource([linkRel]); + fixture.detectChanges(); - existsAsHtmlElement(fixture, neuView); - }); + existsAsHtmlElement(fixture, neuView); + }, + ); it('should hide if both links not exists', () => { component.apiRootResource = createApiRootResource(); @@ -182,6 +178,26 @@ describe('VorgangViewsMenuComponent', () => { }); }); + describe('weitergeleitet view', () => { + it.each([ + ApiRootLinkRel.ALLE_VORGAENGE_WEITERGELEITET, + ApiRootLinkRel.MEINE_VORGAENGE_WEITERGELEITET, + ApiRootLinkRel.UNASSIGNED_WEITERGELEITET, + ])('should show if %s link exists', (linkRel: string) => { + component.apiRootResource = createApiRootResource([linkRel]); + fixture.detectChanges(); + + existsAsHtmlElement(fixture, weitergeleitetView); + }); + + it('should hide if both links not exists', () => { + component.apiRootResource = createApiRootResource(); + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, beschiedenView); + }); + }); + describe('verworfen view', () => { it.each([ ApiRootLinkRel.ALLE_VORGAENGE_VERWORFEN, @@ -203,16 +219,15 @@ describe('VorgangViewsMenuComponent', () => { }); describe('wiedervorlagen view', () => { - it.each([ - ApiRootLinkRel.ALL_WIEDERVORLAGEN, - ApiRootLinkRel.MY_WIEDERVORLAGEN, - ApiRootLinkRel.UNASSIGNED_WIEDERVORLAGEN, - ])('should show if %s link exists', (linkRel: string) => { - component.apiRootResource = createApiRootResource([linkRel]); - fixture.detectChanges(); + it.each([ApiRootLinkRel.ALL_WIEDERVORLAGEN, ApiRootLinkRel.MY_WIEDERVORLAGEN, ApiRootLinkRel.UNASSIGNED_WIEDERVORLAGEN])( + 'should show if %s link exists', + (linkRel: string) => { + component.apiRootResource = createApiRootResource([linkRel]); + fixture.detectChanges(); - existsAsHtmlElement(fixture, wiedervorlagenView); - }); + existsAsHtmlElement(fixture, wiedervorlagenView); + }, + ); it('should hide if link not exists', () => { component.apiRootResource = createApiRootResource(); @@ -243,16 +258,15 @@ describe('VorgangViewsMenuComponent', () => { }); describe('vorgangList view', () => { - it.each([ - ApiRootLinkRel.ALLE_VORGAENGE, - ApiRootLinkRel.MEINE_VORGAENGE, - ApiRootLinkRel.UNASSIGNED, - ])('should show if %s link exists', (linkRel: string) => { - component.apiRootResource = createApiRootResource([linkRel]); - fixture.detectChanges(); + it.each([ApiRootLinkRel.ALLE_VORGAENGE, ApiRootLinkRel.MEINE_VORGAENGE, ApiRootLinkRel.UNASSIGNED])( + 'should show if %s link exists', + (linkRel: string) => { + component.apiRootResource = createApiRootResource([linkRel]); + fixture.detectChanges(); - existsAsHtmlElement(fixture, vorgangListView); - }); + existsAsHtmlElement(fixture, vorgangListView); + }, + ); it('should hide if link not exists', () => { component.apiRootResource = createApiRootResource(); @@ -263,16 +277,15 @@ describe('VorgangViewsMenuComponent', () => { }); describe('search view', () => { - it.each([ - ApiRootLinkRel.SEARCH_ALLE, - ApiRootLinkRel.SEARCH_MEINE, - ApiRootLinkRel.SEARCH_UNASSIGNED, - ])('should show if %s link exists', (linkRel: string) => { - component.apiRootResource = createApiRootResource([linkRel]); - fixture.detectChanges(); - - existsAsHtmlElement(fixture, searchView); - }); + it.each([ApiRootLinkRel.SEARCH_ALLE, ApiRootLinkRel.SEARCH_MEINE, ApiRootLinkRel.SEARCH_UNASSIGNED])( + 'should show if %s link exists', + (linkRel: string) => { + component.apiRootResource = createApiRootResource([linkRel]); + fixture.detectChanges(); + + existsAsHtmlElement(fixture, searchView); + }, + ); it('should hide if no link not exists', () => { component.apiRootResource = createApiRootResource(); diff --git a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts index 3b37f2ba12ba7a1fe70501e190a918d95d8d1430..13e5fcd714c9800fd2dbd9b8fdacc3135037bd58 100644 --- a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts +++ b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts @@ -24,7 +24,6 @@ import { BinaryFileService } from '@alfa-client/binary-file-shared'; import { CommandOrder, CommandResource, CommandService } from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import * as TechShared from '@alfa-client/tech-shared'; import { createEmptyStateResource, createStateResource, decodeUrlFromEmbedding, StateResource } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { SnackBarService } from '@alfa-client/ui'; @@ -35,14 +34,25 @@ import { cold, hot } from 'jest-marbles'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; import { createCommandResource } from 'libs/command-shared/test/command'; import { createVorgangResource, createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; -import { createWiedervorlage, createWiedervorlageListResource, createWiedervorlageResource, } from 'libs/wiedervorlage-shared/test/wiedervorlage'; -import { of } from 'rxjs'; +import { + createWiedervorlage, + createWiedervorlageListResource, + createWiedervorlageResource, +} from 'libs/wiedervorlage-shared/test/wiedervorlage'; +import { of, Subscription } from 'rxjs'; import { WiedervorlageLinkRel, WiedervorlageListLinkRel } from './wiedervorlage.linkrel'; import { WiedervorlageMessages } from './wiedervorlage.message'; -import { Wiedervorlage, WIEDERVORLAGE_UPLOADED_ATTACHMENTS, WiedervorlageListResource, WiedervorlageResource, } from './wiedervorlage.model'; +import { + Wiedervorlage, + WIEDERVORLAGE_UPLOADED_ATTACHMENTS, + WiedervorlageListResource, + WiedervorlageResource, +} from './wiedervorlage.model'; import { WiedervorlageRepository } from './wiedervorlage.repository'; import { WiedervorlageService } from './wiedervorlage.service'; +import * as TechShared from '@alfa-client/tech-shared'; + jest.mock('@alfa-client/tech-shared', () => mockAsEsModule('@alfa-client/tech-shared')); function mockAsEsModule(module: string) { @@ -59,11 +69,14 @@ describe('WiedervorlageService', () => { let commandService: Mock<CommandService>; let snackbarService: Mock<SnackBarService>; let binaryFileService: Mock<BinaryFileService>; - let vorgangService: Mock<VorgangService> = mock(VorgangService); + let vorgangService: Mock<VorgangService>; const vorgangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); + const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = createStateResource(vorgangResource); + const wiedervorlageResource: WiedervorlageResource = createWiedervorlageResource(); const wiedervorlage: Wiedervorlage = createWiedervorlage(); + const commandResource: CommandResource = createCommandResource(); const commandResourceWithEffectedResourceLink: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); @@ -73,7 +86,10 @@ describe('WiedervorlageService', () => { commandService = mock(CommandService); snackbarService = mock(SnackBarService); binaryFileService = mock(BinaryFileService); - vorgangService = mock(VorgangService); + vorgangService = { + ...mock(VorgangService), + getVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)), + }; navigationService.urlChanged.mockReturnValue(of({})); @@ -93,10 +109,6 @@ describe('WiedervorlageService', () => { const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = createStateResource(vorgangResource); - beforeEach(() => { - vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangWithEingangStateResource)); - }); - it('should call vorgangFacade getVorgangWithEingang', () => { service.getWiedervorlageList(); @@ -113,11 +125,11 @@ describe('WiedervorlageService', () => { }); it.skip('should call loadWiedervorlagenByVorgang if required', (done) => { - service.loadWiedervorlagenByVorgang = jest.fn(); + service._loadWiedervorlagenByVorgang = jest.fn(); // service.wiedervorlageList$.next({ ...wiedervorlageListStateResource, reload: true }); service.getWiedervorlageList().subscribe((list) => { - expect(service.loadWiedervorlagenByVorgang).toHaveBeenCalled(); + expect(service._loadWiedervorlagenByVorgang).toHaveBeenCalled(); done(); }); // expect(service.loadWiedervorlagenByVorgang).toHaveBeenCalled(); @@ -127,12 +139,12 @@ describe('WiedervorlageService', () => { }); it('should NOT call loadWiedervorlagenByVorgang if already loaded', () => { - service.loadWiedervorlagenByVorgang = jest.fn(); + service._loadWiedervorlagenByVorgang = jest.fn(); service.wiedervorlageList$.asObservable = jest.fn().mockReturnValue(of(wiedervorlageListStateResource)); service.getWiedervorlageList(); - expect(service.loadWiedervorlagenByVorgang).not.toHaveBeenCalled(); + expect(service._loadWiedervorlagenByVorgang).not.toHaveBeenCalled(); }); }); @@ -142,6 +154,16 @@ describe('WiedervorlageService', () => { const wiedervorlageListStateResource: StateResource<WiedervorlageListResource> = createStateResource(wiedervorlageListResource); + beforeEach(() => { + service._refreshVorgangSubscription = jest.fn(); + }); + + it('should call refresh vorgang subscription', () => { + service.getWiedervorlageListByGivenVorgang(vorgang); + + expect(service._refreshVorgangSubscription).toHaveBeenCalled(); + }); + it('should return initial value', () => { service.wiedervorlageList$.asObservable = jest.fn().mockReturnValue(hot('-a', { a: wiedervorlageListResource })); @@ -151,21 +173,39 @@ describe('WiedervorlageService', () => { }); it('should load wiedervorlagen by vorgang if required', () => { - service.loadWiedervorlagenByVorgang = jest.fn(); + service._loadWiedervorlagenByVorgang = jest.fn(); service.wiedervorlageList$.next(createEmptyStateResource()); service.getWiedervorlageListByGivenVorgang(vorgang).subscribe(); - expect(service.loadWiedervorlagenByVorgang).toHaveBeenCalledWith(vorgang); + expect(service._loadWiedervorlagenByVorgang).toHaveBeenCalledWith(vorgang); }); it('should NOT load wiedervorlagen by vorgang if already loaded', () => { - service.loadWiedervorlagenByVorgang = jest.fn(); + service._loadWiedervorlagenByVorgang = jest.fn(); service.wiedervorlageList$.next(wiedervorlageListStateResource); service.getWiedervorlageListByGivenVorgang(vorgang).subscribe(); - expect(service.loadWiedervorlagenByVorgang).not.toHaveBeenCalled(); + expect(service._loadWiedervorlagenByVorgang).not.toHaveBeenCalled(); + }); + }); + + describe('refresh vorgang subscription', () => { + beforeEach(() => { + service.vorgangSubscription = <any>mock(Subscription); + service._listenToVorgangChange = jest.fn(); + }); + + it('should unsubscribe existing subscription', () => { + service._refreshVorgangSubscription(); + + expect(service.vorgangSubscription.unsubscribe).toHaveBeenCalled(); + }); + it('should call listen to vorgang change', () => { + service._refreshVorgangSubscription(); + + expect(service._listenToVorgangChange).toHaveBeenCalled(); }); }); @@ -187,11 +227,11 @@ describe('WiedervorlageService', () => { }); it('should set loading to true', () => { - service.setWiedervorlageLoading = jest.fn(); + service._setWiedervorlageLoading = jest.fn(); service.getWiedervorlage().subscribe(); - expect(service.setWiedervorlageLoading).toHaveBeenCalled(); + expect(service._setWiedervorlageLoading).toHaveBeenCalled(); }); it('should call navigationService', () => { @@ -251,12 +291,12 @@ describe('WiedervorlageService', () => { }); it('should call proceedAfterRecieveCommand', () => { - service.proceedAfterReceiveCommand = jest.fn(); + service._proceedAfterReceiveCommand = jest.fn(); service.saveWiedervorlage(wiedervorlageResource, wiedervorlage).subscribe(); const expectedMessage = WiedervorlageMessages.SAVED.replace('{betreff}', wiedervorlage.betreff); - expect(service.proceedAfterReceiveCommand).toHaveBeenCalledWith( + expect(service._proceedAfterReceiveCommand).toHaveBeenCalledWith( createStateResource(commandResourceWithEffectedResourceLink), expectedMessage, ); @@ -296,12 +336,12 @@ describe('WiedervorlageService', () => { }); it('should call proceedAfterReceiveCommand', () => { - service.proceedAfterReceiveCommand = jest.fn(); + service._proceedAfterReceiveCommand = jest.fn(); service.createWiedervorlage(wiedervorlage).subscribe(); const expectedMessage = WiedervorlageMessages.CREATED.replace('{betreff}', wiedervorlage.betreff); - expect(service.proceedAfterReceiveCommand).toHaveBeenCalledWith(createStateResource(commandResource), expectedMessage); + expect(service._proceedAfterReceiveCommand).toHaveBeenCalledWith(createStateResource(commandResource), expectedMessage); }); }); @@ -311,13 +351,13 @@ describe('WiedervorlageService', () => { }); it('should set reload on wiedervorlageList', () => { - service.proceedAfterReceiveCommand(createStateResource(commandResourceWithEffectedResourceLink), null); + service._proceedAfterReceiveCommand(createStateResource(commandResourceWithEffectedResourceLink), null); expect(service.wiedervorlageList$.value.reload).toBe(true); }); it('should do nothing on apiError', () => { - service.proceedAfterReceiveCommand(createEmptyStateResource(), null); + service._proceedAfterReceiveCommand(createEmptyStateResource(), null); expect(service.wiedervorlageList$.value.reload).toBe(false); }); @@ -326,13 +366,13 @@ describe('WiedervorlageService', () => { snackbarService.show = jest.fn(); const snackbarMessage: string = 'XX wurde XX'; - service.proceedAfterReceiveCommand(createStateResource(commandResourceWithEffectedResourceLink), snackbarMessage); + service._proceedAfterReceiveCommand(createStateResource(commandResourceWithEffectedResourceLink), snackbarMessage); expect(snackbarService.show).toHaveBeenCalledWith(commandResourceWithEffectedResourceLink, snackbarMessage); }); it('should clear uploaded files', () => { - service.proceedAfterReceiveCommand(createStateResource(commandResourceWithEffectedResourceLink), null); + service._proceedAfterReceiveCommand(createStateResource(commandResourceWithEffectedResourceLink), null); expect(service.clearUploadedFiles).toHaveBeenCalled(); }); @@ -421,7 +461,7 @@ describe('WiedervorlageService', () => { it('should call service if command is done', () => { const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); - service.showSnackBar(commandResource, message); + service._showSnackBar(commandResource, message); expect(snackbarService.show).toHaveBeenCalledWith(commandResource, message); }); @@ -429,7 +469,7 @@ describe('WiedervorlageService', () => { it('should NOT call service if command is pending', () => { const commandResource: CommandResource = createCommandResource(); - service.showSnackBar(commandResource, message); + service._showSnackBar(commandResource, message); expect(snackbarService.show).not.toHaveBeenCalled(); }); @@ -439,9 +479,16 @@ describe('WiedervorlageService', () => { beforeEach(() => { (<any>service).navigateToVorgangDetailPage = jest.fn(); - service.setWiedervorlageListReload = jest.fn(); + service._setWiedervorlageListReload = jest.fn(); (<any>service).forceWiedervorlageReload = jest.fn(); - service.clearWiedervorlagenList = jest.fn(); + service._clearWiedervorlagenList = jest.fn(); + service.clearUploadedFiles = jest.fn(); + }); + + it('should clear uploaded files', () => { + service._onNavigation({}); + + expect(service.clearUploadedFiles).toHaveBeenCalled(); }); describe('to vorgang detail', () => { @@ -450,13 +497,13 @@ describe('WiedervorlageService', () => { }); it('should set wiedervorlage list on reload', () => { - service.onNavigation({}); + service._onNavigation({}); - expect(service.setWiedervorlageListReload).toHaveBeenCalled(); + expect(service._setWiedervorlageListReload).toHaveBeenCalled(); }); it('should set wiedervorlage on reload', () => { - service.onNavigation({}); + service._onNavigation({}); expect((<any>service).forceWiedervorlageReload).toHaveBeenCalled(); }); @@ -464,9 +511,9 @@ describe('WiedervorlageService', () => { describe('to vorgang list', () => { it('should clear list', () => { - service.onNavigation({}); + service._onNavigation({}); - expect(service.clearWiedervorlagenList).toHaveBeenCalled(); + expect(service._clearWiedervorlagenList).toHaveBeenCalled(); }); }); }); @@ -527,4 +574,63 @@ describe('WiedervorlageService', () => { expect(binaryFileService.clearUploadedFiles).toHaveBeenCalledWith(WIEDERVORLAGE_UPLOADED_ATTACHMENTS); }); }); + + describe('listen to vorgang change', () => { + beforeEach(() => { + service._handleVorgangChange = jest.fn(); + }); + + it('should call vorgang service to get vorgang with eingang', () => { + service._listenToVorgangChange(); + + expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled(); + }); + + it('should call handle vorgang change', () => { + service._listenToVorgangChange(); + + expect(service._handleVorgangChange).toHaveBeenCalledWith(vorgangWithEingangStateResource); + }); + }); + + describe('handle vorgang change', () => { + it('should set reload flag if list is loaded and state resource is loading', () => { + service.shouldReload = false; + service.wiedervorlageList$.next(createStateResource(createWiedervorlageListResource())); + + service._handleVorgangChange({ ...vorgangWithEingangStateResource, loading: true }); + + expect(service.shouldReload).toBeTruthy(); + }); + + it('should set reload flag if list is loaded and state resource is reloading', () => { + service.wiedervorlageList$.next(createStateResource(createWiedervorlageListResource())); + service.shouldReload = false; + + service._handleVorgangChange({ ...vorgangWithEingangStateResource, reload: true }); + + expect(service.shouldReload).toBeTruthy(); + }); + + describe('on setted reload flag', () => { + beforeEach(() => { + service._setWiedervorlageListReload = jest.fn(); + service.shouldReload = true; + }); + + describe('and loaded vorgang resource', () => { + it('should call set wiedervorlage list reload', () => { + service._handleVorgangChange(vorgangWithEingangStateResource); + + expect(service._setWiedervorlageListReload).toHaveBeenCalled(); + }); + + it('and loaded vorgang resource should call set wiedervorlage list reload', () => { + service._handleVorgangChange(vorgangWithEingangStateResource); + + expect(service.shouldReload).toBeFalsy(); + }); + }); + }); + }); }); diff --git a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts index 38a7b041ad76c71ef06a78f5f7184a0260fd31f0..6590ff67384d09ef8d8f46a867bfdfb9536648a3 100644 --- a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts +++ b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts @@ -24,9 +24,20 @@ import { BinaryFileService } from '@alfa-client/binary-file-shared'; import { CommandOrder, CommandResource, CommandService, CreateCommand, isDone } from '@alfa-client/command-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; -import { createEmptyStateResource, createStateResource, decodeUrlFromEmbedding, doIfLoadingRequired, hasStateResourceError, isNotNull, isNotUndefined, replacePlaceholder, StateResource, } from '@alfa-client/tech-shared'; +import { + createEmptyStateResource, + createStateResource, + decodeUrlFromEmbedding, + doIfLoadingRequired, + hasStateResourceError, + isLoaded, + isNotNull, + isNotUndefined, + replacePlaceholder, + StateResource, +} from '@alfa-client/tech-shared'; import { SnackBarService } from '@alfa-client/ui'; -import { VorgangHeaderLinkRel, VorgangResource, VorgangService } from '@alfa-client/vorgang-shared'; +import { VorgangHeaderLinkRel, VorgangResource, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared'; import { Injectable, OnDestroy } from '@angular/core'; import { Params } from '@angular/router'; import { hasLink, ResourceUri } from '@ngxp/rest'; @@ -35,7 +46,12 @@ import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import { filter, map, startWith, tap } from 'rxjs/operators'; import { WiedervorlageLinkRel, WiedervorlageListLinkRel } from './wiedervorlage.linkrel'; import { WiedervorlageMessages } from './wiedervorlage.message'; -import { Wiedervorlage, WIEDERVORLAGE_UPLOADED_ATTACHMENTS, WiedervorlageListResource, WiedervorlageResource, } from './wiedervorlage.model'; +import { + Wiedervorlage, + WIEDERVORLAGE_UPLOADED_ATTACHMENTS, + WiedervorlageListResource, + WiedervorlageResource, +} from './wiedervorlage.model'; import { WiedervorlageRepository } from './wiedervorlage.repository'; import { WiedervorlageRoutes } from './wiedervorlage.route'; import { createErledigenCommand, createWiedereroeffnenCommand } from './wiedervorlage.util'; @@ -62,7 +78,10 @@ export class WiedervorlageService implements OnDestroy { StateResource<CommandResource> >(createEmptyStateResource<CommandResource>()); + shouldReload: boolean = false; + private subscription: Subscription; + vorgangSubscription: Subscription; constructor( private repository: WiedervorlageRepository, @@ -73,13 +92,14 @@ export class WiedervorlageService implements OnDestroy { private vorgangService: VorgangService, ) { this.listenToNavigation(); + this._listenToVorgangChange(); } public getWiedervorlageList(): Observable<StateResource<WiedervorlageListResource>> { return combineLatest([this.wiedervorlageList$.asObservable(), this.vorgangService.getVorgangWithEingang()]).pipe( tap(([wiedervorlageList, vorgangResource]) => { if (isNotNull(vorgangResource.resource)) { - doIfLoadingRequired(wiedervorlageList, () => this.loadWiedervorlagenByVorgang(vorgangResource.resource)); + doIfLoadingRequired(wiedervorlageList, () => this._loadWiedervorlagenByVorgang(vorgangResource.resource)); } }), map(([wiedervorlageList]) => wiedervorlageList), @@ -90,20 +110,51 @@ export class WiedervorlageService implements OnDestroy { public getWiedervorlageListByGivenVorgang( vorgangResource: VorgangResource, ): Observable<StateResource<WiedervorlageListResource>> { - doIfLoadingRequired(this.wiedervorlageList$.value, () => this.loadWiedervorlagenByVorgang(vorgangResource)); + this._refreshVorgangSubscription(); + doIfLoadingRequired(this.wiedervorlageList$.value, () => this._loadWiedervorlagenByVorgang(vorgangResource)); return this.wiedervorlageList$.asObservable(); } - loadWiedervorlagenByVorgang(vorgangResource: VorgangResource): void { + _refreshVorgangSubscription(): void { + this.vorgangSubscription.unsubscribe(); + this._listenToVorgangChange(); + } + + _listenToVorgangChange(): void { + this.vorgangSubscription = this.vorgangService + .getVorgangWithEingang() + .subscribe((vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>) => + this._handleVorgangChange(vorgangWithEingangStateResource), + ); + } + + _handleVorgangChange(vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>): void { + if (this.shouldReloadList(vorgangWithEingangStateResource)) { + this.shouldReload = true; + } + if (isLoaded(vorgangWithEingangStateResource) && this.shouldReload) { + this._setWiedervorlageListReload(); + this.shouldReload = false; + } + } + + private shouldReloadList(vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>): boolean { + return ( + (vorgangWithEingangStateResource.loading || vorgangWithEingangStateResource.reload) && + isNotNull(this.wiedervorlageList$.value.resource) + ); + } + + _loadWiedervorlagenByVorgang(vorgangResource: VorgangResource): void { if (hasLink(vorgangResource, VorgangHeaderLinkRel.WIEDERVORLAGEN)) { const subscription: Subscription = this.repository.getWiedervorlageList(vorgangResource).subscribe((wiedervorlagenList) => { if (!isNull(wiedervorlagenList)) { - this.setWiedervorlagenList(wiedervorlagenList); + this._setWiedervorlagenList(wiedervorlagenList); subscription.unsubscribe(); } }); } else { - this.clearWiedervorlagenList(); + this._clearWiedervorlagenList(); } } @@ -116,7 +167,7 @@ export class WiedervorlageService implements OnDestroy { ); } - setWiedervorlagenList(wiedervorlagenList: WiedervorlageListResource): void { + _setWiedervorlagenList(wiedervorlagenList: WiedervorlageListResource): void { this.wiedervorlageList$.next(createStateResource(wiedervorlagenList)); } @@ -128,13 +179,13 @@ export class WiedervorlageService implements OnDestroy { } private updateWiedervorlage(): void { - this.setWiedervorlageLoading(); + this._setWiedervorlageLoading(); this.loadAndSetWiedervorlageByUrl(this.getWiedervorlageUri()); } private loadAndSetWiedervorlageByUrl(url: ResourceUri): void { - this.setWiedervorlageLoading(); + this._setWiedervorlageLoading(); const subscription: Subscription = this.repository.getWiedervorlage(url).subscribe((wiedervorlage) => { this.wiedervorlage$.next(createStateResource(wiedervorlage)); @@ -148,22 +199,23 @@ export class WiedervorlageService implements OnDestroy { private listenToNavigation(): void { this.unsubscribe(); - this.subscription = this.navigationService.urlChanged().subscribe((params) => this.onNavigation(params)); + this.subscription = this.navigationService.urlChanged().subscribe((params) => this._onNavigation(params)); } - onNavigation(params: Params): void { + _onNavigation(params: Params): void { + this.clearUploadedFiles(); if (this.navigateToVorgangDetailPage(params)) { - this.setWiedervorlageListReload(); + this._setWiedervorlageListReload(); this.forceWiedervorlageReload(); this.submitInProgress$.next(createEmptyStateResource<CommandResource>()); } if (NavigationService.isVorgangListPage(params)) { - this.clearWiedervorlagenList(); + this._clearWiedervorlagenList(); this.submitInProgress$.next(createEmptyStateResource<CommandResource>()); } } - clearWiedervorlagenList(): void { + _clearWiedervorlagenList(): void { this.wiedervorlageList$.next(createEmptyStateResource<WiedervorlageListResource>()); } @@ -182,23 +234,23 @@ export class WiedervorlageService implements OnDestroy { return this.navigationService.getDecodedParam(WiedervorlageService.encodedWiedervorlageUriParam); } - setWiedervorlageLoading(): void { + _setWiedervorlageLoading(): void { this.wiedervorlage$.next({ ...this.wiedervorlage$.value, loading: true }); } public createWiedervorlage(wiedervorlage: Wiedervorlage): Observable<StateResource<CommandResource>> { this.setSubmitInProgressLoading(); - return this.createCreateWiedervorlageCommand(this.wiedervorlageList$.value.resource, wiedervorlage).pipe( + return this._createCreateWiedervorlageCommand(this.wiedervorlageList$.value.resource, wiedervorlage).pipe( filter((commandStateResource) => !commandStateResource.loading), tap((commandStateResource) => - this.proceedAfterReceiveCommand(commandStateResource, this.buildMessage(WiedervorlageMessages.CREATED, wiedervorlage)), + this._proceedAfterReceiveCommand(commandStateResource, this.buildMessage(WiedervorlageMessages.CREATED, wiedervorlage)), ), startWith(createEmptyStateResource<CommandResource>(true)), ); } - createCreateWiedervorlageCommand( + _createCreateWiedervorlageCommand( wiedervorlageListResource: WiedervorlageListResource, wiedervorlage: Wiedervorlage, ): Observable<StateResource<CommandResource>> { @@ -219,10 +271,10 @@ export class WiedervorlageService implements OnDestroy { ): Observable<StateResource<CommandResource>> { this.setSubmitInProgressLoading(); - return this.createSaveWiedervorlageCommand(wiedervorlageResource, wiedervorlage).pipe( + return this._createSaveWiedervorlageCommand(wiedervorlageResource, wiedervorlage).pipe( filter((commandStateResource) => !commandStateResource.loading), tap((commandStateResource) => - this.proceedAfterReceiveCommand(commandStateResource, this.buildMessage(WiedervorlageMessages.SAVED, wiedervorlage)), + this._proceedAfterReceiveCommand(commandStateResource, this.buildMessage(WiedervorlageMessages.SAVED, wiedervorlage)), ), startWith(createEmptyStateResource<CommandResource>(true)), ); @@ -232,7 +284,7 @@ export class WiedervorlageService implements OnDestroy { this.submitInProgress$.next({ ...this.submitInProgress$.value, loading: true }); } - createSaveWiedervorlageCommand( + _createSaveWiedervorlageCommand( wiedervorlageResource: WiedervorlageResource, wiedervorlage: Wiedervorlage, ): Observable<StateResource<CommandResource>> { @@ -247,7 +299,7 @@ export class WiedervorlageService implements OnDestroy { return { order: CommandOrder.EDIT_WIEDERVORLAGE, body: wiedervorlage }; } - proceedAfterReceiveCommand(commandStateResource: StateResource<CommandResource>, message: string): void { + _proceedAfterReceiveCommand(commandStateResource: StateResource<CommandResource>, message: string): void { this.submitInProgress$.next({ ...this.submitInProgress$.value, resource: commandStateResource.resource, @@ -255,14 +307,14 @@ export class WiedervorlageService implements OnDestroy { if (isDone(commandStateResource.resource)) { this.submitInProgress$.next(createStateResource(commandStateResource.resource)); this.snackbarService.show(commandStateResource.resource, message); - this.setWiedervorlageListReload(); + this._setWiedervorlageListReload(); this.clearUploadedFiles(); } else if (hasStateResourceError(commandStateResource)) { this.submitInProgress$.next(createStateResource(commandStateResource.resource)); } } - setWiedervorlageListReload(): void { + _setWiedervorlageListReload(): void { this.wiedervorlageList$.next({ ...this.wiedervorlageList$.value, reload: true }); } @@ -297,7 +349,7 @@ export class WiedervorlageService implements OnDestroy { .subscribe((commandStateResource) => { if (isDone(commandStateResource.resource)) { this.handleSource(commandStateResource.resource); - this.showSnackBar( + this._showSnackBar( commandStateResource.resource, this.buildMessage(snackBarMessage, this.wiedervorlage$.value.resource), ); @@ -320,7 +372,7 @@ export class WiedervorlageService implements OnDestroy { return replacePlaceholder(message, 'betreff', wiedervorlage.betreff); } - showSnackBar(commandResource: CommandResource, message: string) { + _showSnackBar(commandResource: CommandResource, message: string) { if (isDone(commandResource)) { this.snackbarService.show(commandResource, message); } diff --git a/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.spec.ts b/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.spec.ts index 305ae85a3562debef815c485cc0820e6971e9139..533f48ef565166aac55ae5fcf355ed99f86a81ce 100644 --- a/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.spec.ts +++ b/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.spec.ts @@ -86,7 +86,7 @@ describe('WiedervorlageListInVorgangContainerComponent', () => { describe('reloadWiedervorlageListOnVorgangReload', () => { beforeEach(() => { - wiedervorlageService.setWiedervorlageListReload.mockClear(); + wiedervorlageService._setWiedervorlageListReload.mockClear(); }); it('should call wiedervorlageService', () => { @@ -97,7 +97,7 @@ describe('WiedervorlageListInVorgangContainerComponent', () => { component.reloadWiedervorlageListOnVorgangReload(); - expect(wiedervorlageService.setWiedervorlageListReload).toHaveBeenCalled(); + expect(wiedervorlageService._setWiedervorlageListReload).toHaveBeenCalled(); }); it('should not call wiedervorlageService', () => { @@ -108,7 +108,7 @@ describe('WiedervorlageListInVorgangContainerComponent', () => { component.reloadWiedervorlageListOnVorgangReload(); - expect(wiedervorlageService.setWiedervorlageListReload).not.toHaveBeenCalled(); + expect(wiedervorlageService._setWiedervorlageListReload).not.toHaveBeenCalled(); }); }); }); diff --git a/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.ts b/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.ts index 6a99467e90164b63414677a0e80f4f9ea2470759..4313ee4c1f9ee06cd1515686c8985ec0806fa068 100644 --- a/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.ts +++ b/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-list-in-vorgang-container/wiedervorlage-list-in-vorgang-container.component.ts @@ -21,11 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, Input, OnChanges } from '@angular/core'; -import { StateResource } from '@alfa-client/tech-shared'; +import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared'; import { VorgangHeaderLinkRel, VorgangResource } from '@alfa-client/vorgang-shared'; import { WiedervorlageListResource, WiedervorlageService } from '@alfa-client/wiedervorlage-shared'; -import { Observable } from 'rxjs'; +import { Component, Input, OnChanges } from '@angular/core'; +import { Observable, of } from 'rxjs'; @Component({ selector: 'alfa-wiedervorlage-list-in-vorgang-container', @@ -35,7 +35,8 @@ import { Observable } from 'rxjs'; export class WiedervorlageListInVorgangContainerComponent implements OnChanges { @Input() vorgangStateResource: StateResource<VorgangResource>; - wiedervorlagenStateResource$: Observable<StateResource<WiedervorlageListResource>>; + wiedervorlagenStateResource$: Observable<StateResource<WiedervorlageListResource>> = + of(createEmptyStateResource<WiedervorlageListResource>()); readonly vorgangLinkRel = VorgangHeaderLinkRel; @@ -43,15 +44,14 @@ export class WiedervorlageListInVorgangContainerComponent implements OnChanges { ngOnChanges(): void { this.reloadWiedervorlageListOnVorgangReload(); - this.wiedervorlagenStateResource$ = - this.wiedervorlageService.getWiedervorlageListByGivenVorgang( - this.vorgangStateResource.resource, - ); + this.wiedervorlagenStateResource$ = this.wiedervorlageService.getWiedervorlageListByGivenVorgang( + this.vorgangStateResource.resource, + ); } reloadWiedervorlageListOnVorgangReload(): void { if (this.vorgangStateResource.reload) { - this.wiedervorlageService.setWiedervorlageListReload(); + this.wiedervorlageService._setWiedervorlageListReload(); } } } diff --git a/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-page.component.html b/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-page.component.html index 8f0c3d3c5dfb5e59a191e8e18c725e098376b2fe..99cc6d70f2db39cd1ab3fb16016af9f8f07288ac 100644 --- a/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-page.component.html +++ b/alfa-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-page.component.html @@ -24,31 +24,19 @@ --> <ozgcloud-spinner [stateResource]="wiedervorlageStateResource"> - <ozgcloud-subnavigation - data-test-id="subnavigation-wiedervorlage" - class="mat-typography mat-app-background" - > - <alfa-wiedervorlage-action-buttons [wiedervorlage]="wiedervorlageStateResource.resource"> - </alfa-wiedervorlage-action-buttons> + <ozgcloud-subnavigation data-test-id="subnavigation-wiedervorlage" class="mat-typography mat-app-background"> + <alfa-wiedervorlage-action-buttons [wiedervorlage]="wiedervorlageStateResource.resource"> </alfa-wiedervorlage-action-buttons> </ozgcloud-subnavigation> <div class="l-scroll-area--full"> <div class="wrapper grow"> - <h1 class="text-lg font-medium">Wiedervorlage</h1> + <h1 class="text-lg font-medium" data-test-id="wiedervorlage-headline">Wiedervorlage</h1> <alfa-wiedervorlage-breadcrumb-container [wiedervorlage]="wiedervorlageStateResource.resource" ></alfa-wiedervorlage-breadcrumb-container> - <alfa-wiedervorlage-status - class="status" - [wiedervorlageResource]="wiedervorlageStateResource.resource" - [diameter]="16" - > - <span>{{ - wiedervorlageStateResource.resource && wiedervorlageStateResource.resource.done ? - 'erledigt' - : 'offen' - }}</span> + <alfa-wiedervorlage-status class="status" [wiedervorlageResource]="wiedervorlageStateResource.resource" [diameter]="16"> + <span>{{ wiedervorlageStateResource.resource && wiedervorlageStateResource.resource.done ? 'erledigt' : 'offen' }}</span> </alfa-wiedervorlage-status> <alfa-wiedervorlage-form diff --git a/alfa-client/libs/zustaendige-stelle-shared/src/index.ts b/alfa-client/libs/zustaendige-stelle-shared/src/index.ts index ab0148d00ba42af2a0c6694c0d937c998fa0513e..f7b4ea3e3c9ec0c95e32d63ad0aa526cc1de0ac0 100644 --- a/alfa-client/libs/zustaendige-stelle-shared/src/index.ts +++ b/alfa-client/libs/zustaendige-stelle-shared/src/index.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +export * from './lib/anschrift-to-string.pipe'; export * from './lib/externe-fachstelle/externe-fachstelle.model'; export * from './lib/externe-fachstelle/externe-fachstelle.service'; export * from './lib/organisations-einheit/organisations-einheit.model'; diff --git a/alfa-client/libs/zustaendige-stelle-shared/src/lib/anschrift-to-string.pipe.spec.ts b/alfa-client/libs/zustaendige-stelle-shared/src/lib/anschrift-to-string.pipe.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..06d89cf735cd854d61513363f8937933e6a6f106 --- /dev/null +++ b/alfa-client/libs/zustaendige-stelle-shared/src/lib/anschrift-to-string.pipe.spec.ts @@ -0,0 +1,29 @@ +import { EMPTY_STRING } from '@alfa-client/tech-shared'; +import { Anschrift } from '@alfa-client/zustaendige-stelle-shared'; +import { AnschriftToStringPipe } from './anschrift-to-string.pipe'; + +describe('AnschriftToString', () => { + let pipe: AnschriftToStringPipe; + + beforeEach(() => { + pipe = new AnschriftToStringPipe(); + }); + + it('should create an instance', () => { + expect(pipe).toBeTruthy(); + }); + + it('should format anschrift', () => { + const anschrift: Anschrift = { + strasse: 'Musterstraße', + hausnummer: '12', + plz: '12345', + ort: 'Musterstadt', + }; + expect(pipe.transform(anschrift)).toBe('Musterstraße 12, 12345 Musterstadt'); + }); + + it('should return empty string if anschrift is null', () => { + expect(pipe.transform(null)).toBe(EMPTY_STRING); + }); +}); diff --git a/alfa-client/libs/zustaendige-stelle-shared/src/lib/anschrift-to-string.pipe.ts b/alfa-client/libs/zustaendige-stelle-shared/src/lib/anschrift-to-string.pipe.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ea502cd2724879010e7b9e963d45c34ac151c28 --- /dev/null +++ b/alfa-client/libs/zustaendige-stelle-shared/src/lib/anschrift-to-string.pipe.ts @@ -0,0 +1,15 @@ +import { EMPTY_STRING } from '@alfa-client/tech-shared'; +import { Anschrift } from '@alfa-client/zustaendige-stelle-shared'; +import { Pipe, PipeTransform } from '@angular/core'; +import { isNil } from 'lodash-es'; + +@Pipe({ + standalone: true, + name: 'anschriftToString', +}) +export class AnschriftToStringPipe implements PipeTransform { + transform(anschrift: Anschrift): string { + if (isNil(anschrift)) return EMPTY_STRING; + return `${anschrift.strasse} ${anschrift.hausnummer}, ${anschrift.plz} ${anschrift.ort}`; + } +} diff --git a/alfa-client/libs/zustaendige-stelle/src/index.ts b/alfa-client/libs/zustaendige-stelle/src/index.ts index 114de029cc81a1f13b64444b0e91753a8cd09094..014f02c0b948630b4ec7c854d46a0274796d227b 100644 --- a/alfa-client/libs/zustaendige-stelle/src/index.ts +++ b/alfa-client/libs/zustaendige-stelle/src/index.ts @@ -23,4 +23,5 @@ */ export * from './lib/search-externe-fachstelle-container/search-externe-fachstelle-container.component'; export * from './lib/search-organisations-einheit-container/search-organisations-einheit-container.component'; +export * from './lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component'; export * from './lib/zustaendige-stelle.module'; diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts index bd7e92ef2892f13b038358e99393ddc4c81bbbb8..5706c8cde9a1fe2d14f1433b2f31139bd9508242 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-organisations-einheit-container/search-organisations-einheit-container.component.ts @@ -83,7 +83,7 @@ export class SearchOrganisationsEinheitContainerComponent implements OnInit, OnD } } -function createOrganisationEinheitService( +export function createOrganisationEinheitService( resourceRepository: ResourceRepository, vorgangService: VorgangService, ): OrganisationsEinheitService { diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.html b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.html index 9ff703cfa41d11c22550814030a0f6f2ce5a230f..bc4470c5402969cc5497369b92107fc74cd2cff9 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.html +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.html @@ -30,11 +30,5 @@ <ods-close-icon class="fill-primary" icon /> </ods-button> </div> - <alfa-search-zustaendige-stelle-form - data-test-id="search-organisations-einheit" - [searchResults]="searchResults$ | async" - (search)="search($event)" - (selectSearchResult)="selectSearchResult($event)" - (clearSearchResult)="clearSearchResult()" - ></alfa-search-zustaendige-stelle-form> + <alfa-search-zustaendige-stelle-form-container (searchResultSelected)="searchResultSelected($event)" /> </div> diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts index 1b4f822ac5579604de0bef351c85ff8df436ee93..0cd130bb32e24de99cff81a5e9355dcd124f4f22 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts @@ -22,46 +22,25 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared'; -import { - createDialogRefMock, - DialogRefMock, - EventData, - getMockComponent, - Mock, - mock, - triggerEvent, -} from '@alfa-client/test-utils'; -import { - OrganisationsEinheitResource, - OrganisationsEinheitService, - ZUSTAENDIGE_STELLE_SERVICE, -} from '@alfa-client/zustaendige-stelle-shared'; +import { createDialogRefMock, DialogRefMock, Mock, mock } from '@alfa-client/test-utils'; +import { OrganisationsEinheitService, ZUSTAENDIGE_STELLE_SERVICE } from '@alfa-client/zustaendige-stelle-shared'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { faker } from '@faker-js/faker'; import { Resource } from '@ngxp/rest'; -import { ButtonComponent, CloseIconComponent, InstantSearchResult } from '@ods/system'; -import { createInstantSearchResult } from 'libs/design-system/src/test/search'; +import { ButtonComponent, CloseIconComponent } from '@ods/system'; import { MockComponent } from 'ng-mocks'; -import { of } from 'rxjs'; -import { getDataTestIdOf } from '../../../../tech-shared/test/data-test'; -import { createOrganisationsEinheitResource } from '../../../../zustaendige-stelle-shared/test/organisations-einheit'; import { SearchZustaendigeStelleDialogComponent } from '././search-zustaendige-stelle-dialog.component'; -import { SearchZustaendigeStelleFormComponent } from './search-zustaendige-stelle-form/search-zustaendige-stelle-form.component'; +import { SearchZustaendigeStelleFormContainerComponent } from './search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component'; describe('SearchZustaendigeStelleDialogComponent', () => { let component: SearchZustaendigeStelleDialogComponent<Resource>; let fixture: ComponentFixture<SearchZustaendigeStelleDialogComponent<Resource>>; - const searchOrganisationsEinheitComp: string = getDataTestIdOf('search-organisations-einheit'); - const service: Mock<OrganisationsEinheitService> = mock(OrganisationsEinheitService); const title: string = 'dummyTitle'; let dialogRefMock: DialogRefMock; - const organisationsEinheitResource: OrganisationsEinheitResource = createOrganisationsEinheitResource(); - beforeEach(() => { dialogRefMock = createDialogRefMock(); }); @@ -71,7 +50,7 @@ describe('SearchZustaendigeStelleDialogComponent', () => { declarations: [ SearchZustaendigeStelleDialogComponent, ToEmbeddedResourcesPipe, - MockComponent(SearchZustaendigeStelleFormComponent), + MockComponent(SearchZustaendigeStelleFormContainerComponent), MockComponent(ButtonComponent), MockComponent(CloseIconComponent), ], @@ -100,149 +79,11 @@ describe('SearchZustaendigeStelleDialogComponent', () => { expect(component).toBeTruthy(); }); - describe('ngOnInit', () => { - it('should call service', () => { - component.ngOnInit(); - - expect(service.getSearchResultList).toHaveBeenCalled(); - }); - }); - - describe('onKeyDownHandler', () => { - it('should prevent default behavior for enter key on non buttons', () => { - const keyboardEvent: KeyboardEvent = { - ...new KeyboardEvent('enter'), - key: 'Enter', - preventDefault: jest.fn(), - target: new EventTarget(), - }; - - component.onKeyDownHandler(keyboardEvent); - - expect(keyboardEvent.preventDefault).toHaveBeenCalled(); - }); - - it('should not prevent default behavior for enter key on buttons', () => { - const keyboardEvent: KeyboardEvent = { - ...new KeyboardEvent('enter'), - key: 'Enter', - preventDefault: jest.fn(), - target: { ...new EventTarget(), tagName: 'BUTTON' } as Element, - }; - - component.onKeyDownHandler(keyboardEvent); - - expect(keyboardEvent.preventDefault).not.toHaveBeenCalled(); - }); - }); - - describe('search organisationsEinheit component', () => { - const result: InstantSearchResult<Resource> = createInstantSearchResult(); - - beforeEach(() => { - component.searchResults$ = of([result]); - fixture.detectChanges(); - }); - - it('should be called with searchResult', () => { - const comp: SearchZustaendigeStelleFormComponent<Resource> = getMockComponent< - SearchZustaendigeStelleFormComponent<Resource> - >(fixture, SearchZustaendigeStelleFormComponent); - - expect(comp.searchResults).toEqual([result]); - }); - - it('should call search on openSearchDialog output', () => { - component.search = jest.fn(); - const searchBy: string = faker.word.sample(); - const eventData: EventData<SearchZustaendigeStelleDialogComponent<Resource>> = { - fixture, - elementSelector: searchOrganisationsEinheitComp, - name: 'search', - data: searchBy, - }; - - triggerEvent(eventData); - - expect(component.search).toHaveBeenCalledWith(searchBy); - }); - - it('should call selectSearchResult on selectSearchResult output', () => { - component.selectSearchResult = jest.fn(); - - const eventData: EventData<SearchZustaendigeStelleDialogComponent<Resource>> = { - fixture, - elementSelector: searchOrganisationsEinheitComp, - name: 'selectSearchResult', - data: organisationsEinheitResource, - }; - - triggerEvent(eventData); - - expect(component.selectSearchResult).toHaveBeenCalledWith(organisationsEinheitResource); - }); - - it('should call clearSearchResult', () => { - component.clearSearchResult = jest.fn(); - - const eventData: EventData<SearchZustaendigeStelleDialogComponent<Resource>> = { - fixture, - elementSelector: searchOrganisationsEinheitComp, - name: 'clearSearchResult', - data: organisationsEinheitResource, - }; - - triggerEvent(eventData); - - expect(component.clearSearchResult).toHaveBeenCalled(); - }); - }); - - describe('search', () => { - const searchBy: string = faker.word.sample(); - - it('should call service', () => { - component.search(searchBy); - - expect(service.search).toHaveBeenCalledWith(searchBy); - }); - }); - - describe('select search result', () => { - it('should set select result', () => { - component.selectSearchResult(organisationsEinheitResource); - - expect(service.selectSearchResult).toHaveBeenCalledWith(organisationsEinheitResource); - }); - - it('should call service', () => { - component.selectSearchResult(organisationsEinheitResource); - - expect(service.clearSearchResult).toHaveBeenCalled(); - }); - - it('should close dialog with result', () => { - component.selectSearchResult(organisationsEinheitResource); - - expect(dialogRefMock.close).toHaveBeenCalledWith(organisationsEinheitResource); - }); - }); - - describe('clear search result', () => { - it('should call service', () => { - component.clearSearchResult(); - - expect(service.clearSearchResult).toHaveBeenCalled(); - }); - }); - describe('close dialog', () => { it('should clear search result', () => { - component.clearSearchResult = jest.fn(); - component.closeDialog(); - expect(component.clearSearchResult).toHaveBeenCalled(); + expect(service.clearSearchResult).toHaveBeenCalled(); }); it('should close dialog', () => { @@ -251,22 +92,4 @@ describe('SearchZustaendigeStelleDialogComponent', () => { expect(dialogRefMock.close).toHaveBeenCalled(); }); }); - - describe('isNotButtonElement', () => { - it('should return false', () => { - const element: Element = { tagName: 'BUTTON' } as Element; - - const result: boolean = component.isNotButtonElement(element); - - expect(result).toBe(false); - }); - - it('should return true', () => { - const element: Element = { tagName: 'INPUT' } as Element; - - const result: boolean = component.isNotButtonElement(element); - - expect(result).toBe(true); - }); - }); }); diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.ts index 492c3c800690e5ca9c929299dee8f765f514b76a..b00b5a3a722ac05864396fb4825b67db72694a44 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.ts +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.ts @@ -23,7 +23,7 @@ */ import { ZUSTAENDIGE_STELLE_SERVICE, ZustaendigeStelleService } from '@alfa-client/zustaendige-stelle-shared'; import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; -import { Component, HostListener, Inject, OnInit } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { Resource } from '@ngxp/rest'; import { InstantSearchResult } from '@ods/system'; import { Observable } from 'rxjs'; @@ -33,47 +33,21 @@ import { Observable } from 'rxjs'; selector: 'search-zustaendige-stelle-dialog', templateUrl: './search-zustaendige-stelle-dialog.component.html', }) -export class SearchZustaendigeStelleDialogComponent<T extends Resource> implements OnInit { +export class SearchZustaendigeStelleDialogComponent<T extends Resource> { public searchResults$: Observable<InstantSearchResult<T>[]>; constructor( private dialogRef: DialogRef, - @Inject(ZUSTAENDIGE_STELLE_SERVICE) - private service: ZustaendigeStelleService<T>, + @Inject(ZUSTAENDIGE_STELLE_SERVICE) private service: ZustaendigeStelleService<T>, @Inject(DIALOG_DATA) public title: string, ) {} - ngOnInit(): void { - this.searchResults$ = this.service.getSearchResultList(); - } - - @HostListener('document:keydown', ['$event']) - onKeyDownHandler(e: KeyboardEvent) { - if (e.key === 'Enter' && this.isNotButtonElement(e.target as Element)) { - e.preventDefault(); - } - } - - public search(searchBy: string): void { - this.service.search(searchBy); - } - - public selectSearchResult(zustaendigeStelle: T): void { - this.service.selectSearchResult(zustaendigeStelle); - this.service.clearSearchResult(); - this.dialogRef.close(zustaendigeStelle); - } - - public clearSearchResult(): void { - this.service.clearSearchResult(); - } - public closeDialog(): void { - this.clearSearchResult(); + this.service.clearSearchResult(); this.dialogRef.close(); } - public isNotButtonElement(e: Element): boolean { - return e.tagName !== 'BUTTON'; + public searchResultSelected(zustaendigeStelle: T): void { + this.dialogRef.close(zustaendigeStelle); } } diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.html b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..2c884df36afc8721e62bc85b99d0c60606287986 --- /dev/null +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.html @@ -0,0 +1,8 @@ +<alfa-search-zustaendige-stelle-form + data-test-id="search-organisations-einheit" + [searchResults]="searchResults$ | async" + [focusOnSearchField]="focusOnSearchField" + (search)="search($event)" + (selectSearchResult)="selectSearchResult($event)" + (clearSearchResult)="clearSearchResult()" +/> \ No newline at end of file diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.spec.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..61763e91ba325e6355d54fdab3055f39b0399151 --- /dev/null +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.spec.ts @@ -0,0 +1,207 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EventData, getMockComponent, mock, Mock, triggerEvent } from '@alfa-client/test-utils'; +import { + OrganisationsEinheitResource, + OrganisationsEinheitService, + ZUSTAENDIGE_STELLE_SERVICE, +} from '@alfa-client/zustaendige-stelle-shared'; +import { faker } from '@faker-js/faker'; +import { Resource } from '@ngxp/rest'; +import { InstantSearchResult } from '@ods/system'; +import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; +import { createInstantSearchResult } from '../../../../../design-system/src/test/search'; +import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; +import { createOrganisationsEinheitResource } from '../../../../../zustaendige-stelle-shared/test/organisations-einheit'; +import { SearchZustaendigeStelleFormContainerComponent } from './search-zustaendige-stelle-form-container.component'; +import { SearchZustaendigeStelleFormComponent } from './search-zustaendige-stelle-form/search-zustaendige-stelle-form.component'; + +describe('SearchZustaendigeStelleFormContainerComponent', () => { + let component: SearchZustaendigeStelleFormContainerComponent<Resource>; + let fixture: ComponentFixture<SearchZustaendigeStelleFormContainerComponent<Resource>>; + + let service: Mock<OrganisationsEinheitService>; + + const searchOrganisationsEinheitComp: string = getDataTestIdOf('search-organisations-einheit'); + + const organisationsEinheitResource: OrganisationsEinheitResource = createOrganisationsEinheitResource(); + + beforeEach(async () => { + service = mock(OrganisationsEinheitService); + await TestBed.configureTestingModule({ + imports: [SearchZustaendigeStelleFormContainerComponent], + declarations: [MockComponent(SearchZustaendigeStelleFormComponent)], + providers: [ + { + provide: ZUSTAENDIGE_STELLE_SERVICE, + useValue: service, + }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(SearchZustaendigeStelleFormContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('ngOnInit', () => { + it('should call service', () => { + component.ngOnInit(); + + expect(service.getSearchResultList).toHaveBeenCalled(); + }); + }); + + describe('onKeyDownHandler', () => { + it('should prevent default behavior for enter key on non buttons', () => { + const keyboardEvent: KeyboardEvent = { + ...new KeyboardEvent('enter'), + key: 'Enter', + preventDefault: jest.fn(), + target: new EventTarget(), + }; + + component.onKeyDownHandler(keyboardEvent); + + expect(keyboardEvent.preventDefault).toHaveBeenCalled(); + }); + + it('should not prevent default behavior for enter key on buttons', () => { + const keyboardEvent: KeyboardEvent = { + ...new KeyboardEvent('enter'), + key: 'Enter', + preventDefault: jest.fn(), + target: { ...new EventTarget(), tagName: 'BUTTON' } as Element, + }; + + component.onKeyDownHandler(keyboardEvent); + + expect(keyboardEvent.preventDefault).not.toHaveBeenCalled(); + }); + }); + + describe('search organisationsEinheit component', () => { + const result: InstantSearchResult<Resource> = createInstantSearchResult(); + + beforeEach(() => { + component.searchResults$ = of([result]); + fixture.detectChanges(); + }); + + it('should be called with searchResult', () => { + const comp: SearchZustaendigeStelleFormComponent<Resource> = getMockComponent< + SearchZustaendigeStelleFormComponent<Resource> + >(fixture, SearchZustaendigeStelleFormComponent); + + expect(comp.searchResults).toEqual([result]); + }); + + it('should call search on openSearchDialog output', () => { + component.search = jest.fn(); + const searchBy: string = faker.word.sample(); + const eventData: EventData<SearchZustaendigeStelleFormContainerComponent<Resource>> = { + fixture, + elementSelector: searchOrganisationsEinheitComp, + name: 'search', + data: searchBy, + }; + + triggerEvent(eventData); + + expect(component.search).toHaveBeenCalledWith(searchBy); + }); + + it('should call selectSearchResult on selectSearchResult output', () => { + component.selectSearchResult = jest.fn(); + + const eventData: EventData<SearchZustaendigeStelleFormContainerComponent<Resource>> = { + fixture, + elementSelector: searchOrganisationsEinheitComp, + name: 'selectSearchResult', + data: organisationsEinheitResource, + }; + + triggerEvent(eventData); + + expect(component.selectSearchResult).toHaveBeenCalledWith(organisationsEinheitResource); + }); + + it('should call clearSearchResult', () => { + component.clearSearchResult = jest.fn(); + + const eventData: EventData<SearchZustaendigeStelleFormContainerComponent<Resource>> = { + fixture, + elementSelector: searchOrganisationsEinheitComp, + name: 'clearSearchResult', + data: organisationsEinheitResource, + }; + + triggerEvent(eventData); + + expect(component.clearSearchResult).toHaveBeenCalled(); + }); + }); + + describe('search', () => { + const searchBy: string = faker.word.sample(); + + it('should call service', () => { + component.search(searchBy); + + expect(service.search).toHaveBeenCalledWith(searchBy); + }); + }); + + describe('select search result', () => { + it('should set select result', () => { + component.selectSearchResult(organisationsEinheitResource); + + expect(service.selectSearchResult).toHaveBeenCalledWith(organisationsEinheitResource); + }); + + it('should call service', () => { + component.selectSearchResult(organisationsEinheitResource); + + expect(service.clearSearchResult).toHaveBeenCalled(); + }); + + it('should emit search result selected', () => { + component.searchResultSelected.emit = jest.fn(); + + component.selectSearchResult(organisationsEinheitResource); + + expect(component.searchResultSelected.emit).toHaveBeenCalledWith(organisationsEinheitResource); + }); + }); + + describe('clear search result', () => { + it('should call service', () => { + component.clearSearchResult(); + + expect(service.clearSearchResult).toHaveBeenCalled(); + }); + }); + + describe('isNotButtonElement', () => { + it('should return false', () => { + const element: Element = { tagName: 'BUTTON' } as Element; + + const result: boolean = component.isNotButtonElement(element); + + expect(result).toBe(false); + }); + + it('should return true', () => { + const element: Element = { tagName: 'INPUT' } as Element; + + const result: boolean = component.isNotButtonElement(element); + + expect(result).toBe(true); + }); + }); +}); diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..e67f36dfbf550f3f5d8f5678a165ca687833442e --- /dev/null +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component.ts @@ -0,0 +1,50 @@ +import { ZUSTAENDIGE_STELLE_SERVICE, ZustaendigeStelleService } from '@alfa-client/zustaendige-stelle-shared'; +import { Component, EventEmitter, HostListener, Inject, Input, OnInit, Output } from '@angular/core'; +import { Resource } from '@ngxp/rest'; +import { InstantSearchResult } from '@ods/system'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'alfa-search-zustaendige-stelle-form-container', + templateUrl: './search-zustaendige-stelle-form-container.component.html', +}) +export class SearchZustaendigeStelleFormContainerComponent<T extends Resource> implements OnInit { + @Output() searchResultSelected = new EventEmitter<T>(); + @Input() focusOnSearchField: boolean = false; + + public searchResults$: Observable<InstantSearchResult<T>[]>; + + constructor( + @Inject(ZUSTAENDIGE_STELLE_SERVICE) + private service: ZustaendigeStelleService<T>, + ) {} + + ngOnInit(): void { + this.searchResults$ = this.service.getSearchResultList(); + } + + @HostListener('document:keydown', ['$event']) + onKeyDownHandler(e: KeyboardEvent) { + if (e.key === 'Enter' && this.isNotButtonElement(e.target as Element)) { + e.preventDefault(); + } + } + + public search(searchBy: string): void { + this.service.search(searchBy); + } + + public selectSearchResult(zustaendigeStelle: T): void { + this.service.selectSearchResult(zustaendigeStelle); + this.service.clearSearchResult(); + this.searchResultSelected.emit(zustaendigeStelle); + } + + public clearSearchResult(): void { + this.service.clearSearchResult(); + } + + public isNotButtonElement(e: Element): boolean { + return e.tagName !== 'BUTTON'; + } +} 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-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html similarity index 96% rename from alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html rename to alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html index d9025b3bb2e2f7e1a9f080bc2311535315f97036..b5f1e583173c2aff41e33d3e0d06a3ed2352131e 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-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.html @@ -28,6 +28,7 @@ data-test-id="search" placeholder="Name des Amts oder Adresse eingeben" [control]="formService.form.controls.search" + [focusOnSearchField]="focusOnSearchField" [searchResults]="searchResults" (searchResultSelected)="selectSearchResult.emit($event.data)" (searchQueryChanged)="search.emit($event.searchBy)" diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts similarity index 93% rename from alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts rename to alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts index 936e0398d636e323fe154040409c50c876a8f736..92a65e293c4dbea6409338e24fd449c2f4c7ec16 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts @@ -28,11 +28,11 @@ import { ReactiveFormsModule } from '@angular/forms'; import { faker } from '@faker-js/faker'; import { Resource } from '@ngxp/rest'; import { InstantSearchComponent, InstantSearchResult } from '@ods/system'; +import { createInstantSearchResult } from 'libs/design-system/src/test/search'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { createOrganisationsEinheitResource } from 'libs/zustaendige-stelle-shared/test/organisations-einheit'; import { MockComponent } from 'ng-mocks'; -import { createInstantSearchResult } from '../../../../../design-system/src/test/search'; -import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test'; -import { createOrganisationsEinheitResource } from '../../../../../zustaendige-stelle-shared/test/organisations-einheit'; -import { SearchZustaendigeStelleFormservice } from '../search-zustaendige-stelle.formservice'; +import { SearchZustaendigeStelleFormservice } from '../../search-zustaendige-stelle.formservice'; import { SearchZustaendigeStelleFormComponent } from './search-zustaendige-stelle-form.component'; describe('SearchZustaendigeStelleFormComponent', () => { diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.ts similarity index 91% rename from alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.ts rename to alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.ts index dff8515301abf57281a9c617a711bf42d46e71c2..a36f2cb5dbabc228ef35fbb7a4dc3f0fd9de5fbd 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.ts +++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.ts @@ -24,7 +24,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Resource } from '@ngxp/rest'; import { InstantSearchResult } from '@ods/system'; -import { SearchZustaendigeStelleFormservice } from '../search-zustaendige-stelle.formservice'; +import { SearchZustaendigeStelleFormservice } from '../../search-zustaendige-stelle.formservice'; @Component({ selector: 'alfa-search-zustaendige-stelle-form', @@ -33,6 +33,7 @@ import { SearchZustaendigeStelleFormservice } from '../search-zustaendige-stelle }) export class SearchZustaendigeStelleFormComponent<T extends Resource> { @Input() public searchResults: InstantSearchResult<T>[]; + @Input() public focusOnSearchField: boolean = false; @Output() public search: EventEmitter<string> = new EventEmitter(); @Output() public selectSearchResult: EventEmitter<T> = new EventEmitter(); diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/zustaendige-stelle.module.ts b/alfa-client/libs/zustaendige-stelle/src/lib/zustaendige-stelle.module.ts index 820da330c99f8e0d184b5c6b38096db8c03604bb..11e5ee19eafa8a59c361e8b260507fe6c32c4ef1 100644 --- a/alfa-client/libs/zustaendige-stelle/src/lib/zustaendige-stelle.module.ts +++ b/alfa-client/libs/zustaendige-stelle/src/lib/zustaendige-stelle.module.ts @@ -40,7 +40,8 @@ import { SearchExterneFachstelleContainerComponent } from './search-externe-fach import { OrganisationsEinheitComponent } from './search-organisations-einheit-container/organisations-einheit/organisations-einheit.component'; import { SearchOrganisationsEinheitContainerComponent } from './search-organisations-einheit-container/search-organisations-einheit-container.component'; import { SearchZustaendigeStelleDialogComponent } from './search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component'; -import { SearchZustaendigeStelleFormComponent } from './search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component'; +import { SearchZustaendigeStelleFormContainerComponent } from './search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form-container.component'; +import { SearchZustaendigeStelleFormComponent } from './search-zustaendige-stelle-dialog/search-zustaendige-stelle-form-container/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component'; import { ZustaendigeStelleButtonComponent } from './zustaendige-stelle-button/zustaendige-stelle-button.component'; import { ZustaendigeStelleHeaderComponent } from './zustaendige-stelle-header/zustaendige-stelle-header.component'; @@ -68,6 +69,7 @@ import { ZustaendigeStelleHeaderComponent } from './zustaendige-stelle-header/zu SearchExterneFachstelleContainerComponent, EditZustaendigeStelleButtonComponent, ZustaendigeStelleHeaderComponent, + SearchZustaendigeStelleFormContainerComponent, ], exports: [ OrganisationsEinheitComponent, @@ -75,6 +77,7 @@ import { ZustaendigeStelleHeaderComponent } from './zustaendige-stelle-header/zu SearchZustaendigeStelleDialogComponent, SearchOrganisationsEinheitContainerComponent, SearchExterneFachstelleContainerComponent, + SearchZustaendigeStelleFormContainerComponent, ], }) export class ZustaendigeStelleModule {} diff --git a/alfa-client/pom.xml b/alfa-client/pom.xml deleted file mode 100644 index 017bc5fd3f5d2419879bc3a31934f0f0612d1473..0000000000000000000000000000000000000000 --- a/alfa-client/pom.xml +++ /dev/null @@ -1,135 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - - Copyright (C) 2023 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. - ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - - <parent> - <groupId>de.ozgcloud.alfa</groupId> - <artifactId>alfa</artifactId> - <version>2.18.0-SNAPSHOT</version> - </parent> - - <modelVersion>4.0.0</modelVersion> - <artifactId>alfa-client</artifactId> - <name>Alfa Client</name> - <packaging>pom</packaging> - <inceptionYear>2020</inceptionYear> - - <build> - <plugins> - <plugin> - <artifactId>maven-clean-plugin</artifactId> - <configuration> - <filesets> - <fileset> - <directory>dist</directory> - <includes> - <include>*</include> - <include>**/*</include> - </includes> - </fileset> - </filesets> - </configuration> - </plugin> - - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <version>3.0.0</version> - <executions> - <execution> - <id>test-application</id> - <phase>test</phase> - <configuration> - <workingDirectory>./</workingDirectory> - <executable>pnpm</executable> - <arguments> - <argument>run</argument> - <argument>test</argument> - </arguments> - <skip>${skipTests}</skip> - </configuration> - <goals> - <goal>exec</goal> - </goals> - </execution> - <execution> - <id>build-application</id> - <phase>compile</phase> - <configuration> - <workingDirectory>./</workingDirectory> - <executable>pnpm</executable> - <arguments> - <argument>run</argument> - <argument>ci-build</argument> - </arguments> - </configuration> - <goals> - <goal>exec</goal> - </goals> - </execution> - </executions> - </plugin> - </plugins> - </build> - - <profiles> - <profile> - <activation> - <property> - <name>!skipNpmInstall</name> - </property> - </activation> - <id>npmInstall</id> - <build> - <plugins> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <version>3.0.0</version> - <executions> - <execution> - <id>install-dependencies</id> - <phase>generate-sources</phase> - <configuration> - <workingDirectory>./</workingDirectory> - <executable>pnpm</executable> - <arguments> - <argument>install</argument> - </arguments> - </configuration> - <goals> - <goal>exec</goal> - </goals> - </execution> - </executions> - </plugin> - </plugins> - </build> - </profile> - </profiles> - -</project> diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 1becad5631bbd10ec78b3b254a89d26b82c1ffcd..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null @@ -1,172 +0,0 @@ -<?xml version="1.0"?> -<!-- - - Copyright (C) 2020 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. - ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>de.ozgcloud.common</groupId> - <artifactId>ozgcloud-common-parent</artifactId> - <version>4.6.0</version> - </parent> - - <groupId>de.ozgcloud.alfa</groupId> - <artifactId>alfa</artifactId> - <version>2.19.0</version> - <name>Alfa Parent</name> - <packaging>pom</packaging> - <inceptionYear>2020</inceptionYear> - - <modules> - <module>alfa-client</module> - <module>alfa-server</module> - <module>alfa-service</module> - </modules> - - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - - <vorgang-manager.version>2.19.0-SNAPSHOT</vorgang-manager.version> - <nachrichten-manager.version>2.11.0</nachrichten-manager.version> - <ozgcloud-common-pdf.version>3.0.1</ozgcloud-common-pdf.version> - <user-manager.version>2.8.0</user-manager.version> - <zufi-manager.version>1.5.0</zufi-manager.version> - <collaboration-manager.version>0.5.0</collaboration-manager.version> - <archive-manager.version>0.1.0-SNAPSHOT</archive-manager.version> - <document-manager.version>1.1.0</document-manager.version> - <spring-cloud-config-client.version>4.1.3</spring-cloud-config-client.version> - - <!-- TODO: die Version über ozgcloud-common ziehen --> - <jjwt.version>0.12.6</jjwt.version> - </properties> - - <build> - <pluginManagement> - <plugins> - <plugin> - <groupId>com.mycila</groupId> - <artifactId>license-maven-plugin</artifactId> - </plugin> - </plugins> - </pluginManagement> - </build> - - <dependencyManagement> - <dependencies> - <dependency> - <groupId>de.ozgcloud.vorgang</groupId> - <artifactId>vorgang-manager-interface</artifactId> - <version>${vorgang-manager.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.zufi</groupId> - <artifactId>zufi-manager-interface</artifactId> - <version>${zufi-manager.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.nachrichten</groupId> - <artifactId>nachrichten-manager-interface</artifactId> - <version>${nachrichten-manager.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.vorgang</groupId> - <artifactId>vorgang-manager-utils</artifactId> - <version>${vorgang-manager.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.common</groupId> - <artifactId>ozgcloud-common-pdf</artifactId> - <version>${ozgcloud-common-pdf.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.user</groupId> - <artifactId>user-manager-interface</artifactId> - <version>${user-manager.version}</version> - <exclusions> - <exclusion> - <groupId>io.quarkus</groupId> - <artifactId>quarkus-grpc</artifactId> - </exclusion> - <exclusion> - <groupId>org.jboss.slf4j</groupId> - <artifactId>slf4j-jboss-logmanager</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>de.ozgcloud.collaboration</groupId> - <artifactId>collaboration-manager-interface</artifactId> - <version>${collaboration-manager.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.archive</groupId> - <artifactId>archive-manager-interface</artifactId> - <version>${archive-manager.version}</version> - </dependency> - <dependency> - <groupId>de.ozgcloud.document</groupId> - <artifactId>document-manager-interface</artifactId> - <version>${document-manager.version}</version> - </dependency> - - <dependency> - <groupId>io.jsonwebtoken</groupId> - <artifactId>jjwt-api</artifactId> - <version>${jjwt.version}</version> - </dependency> - <dependency> - <groupId>io.jsonwebtoken</groupId> - <artifactId>jjwt-impl</artifactId> - <version>${jjwt.version}</version> - </dependency> - <dependency> - <groupId>io.jsonwebtoken</groupId> - <artifactId>jjwt-jackson</artifactId> - <version>${jjwt.version}</version> - <scope>runtime</scope> - </dependency> - <dependency> - <groupId>org.springframework.cloud</groupId> - <artifactId>spring-cloud-starter-config</artifactId> - <version>${spring-cloud-config-client.version}</version> - </dependency> - </dependencies> - </dependencyManagement> - - <distributionManagement> - <repository> - <id>ozg-nexus</id> - <name>ozg-releases</name> - <url>https://nexus.ozg-sh.de/repository/ozg-releases/</url> - </repository> - <snapshotRepository> - <id>ozg-snapshots-nexus</id> - <name>ozg-snapshots</name> - <url>https://nexus.ozg-sh.de/repository/ozg-snapshots/</url> - </snapshotRepository> - </distributionManagement> -</project> diff --git a/release-erstellen.sh b/release-erstellen.sh deleted file mode 100755 index 182ce07649b687a7ac150227283ae58547da58ec..0000000000000000000000000000000000000000 --- a/release-erstellen.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2023 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. -# - - -if [ "$#" -ne 1 ]; then - echo "Aufruf: ozg-release-erstellen.sh JA" - echo "Als Parameter bitte 'JA' eintragen zur Sicherheit" - exit 1 -fi - - -## alle -SNAPSHOT in pom.xmls entfernen -#find . -name pom.xml -exec sed -i 's/-SNAPSHOT//g' {} + -SED_PARAMS="-i" -if [[ "$OSTYPE" =~ ^darwin ]]; then - SED_PARAMS="$SED_PARAMS '' -e" -fi -find . -name pom.xml -exec sed $SED_PARAMS 's/-SNAPSHOT//g' {} + - -## release version auslesen -NEWVERSION=$(xmlstarlet sel -N w="http://maven.apache.org/POM/4.0.0" -t -v '//w:project/w:version' -n pom.xml) - -(cd alfa-client && nx release version --projects alfa -d $NEWVERSION) - -echo -echo "NEXT STEPS:" -echo "***********" -echo "Änderungen prüfen" -echo "git commit -a -m 'release version "$NEWVERSION"'" -echo "git push" -echo "git tag "$NEWVERSION -echo "git push --tags" diff --git a/release-startdev.sh b/release-startdev.sh deleted file mode 100755 index 49290eeba6165ff19c1023c2592576a3bd0412b8..0000000000000000000000000000000000000000 --- a/release-startdev.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 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. -# - - -#set -x - -if [ "$#" -ne 1 ]; then - echo "Aufruf: ozg-release-startdev.sh NEWVERSION" - exit 1 -fi - -NEWVERSION=$1 - -echo - -# pom.xml:main -> project.version setzen -# projectname/pom.xml:parent -> project.parent.version setzen -# projectname/pom.xml:parent,main -> project.parent.version und project.version setzen -# -PROJECTS="pom.xml:main - alfa-service/pom.xml:parent - alfa-server/pom.xml:parent - alfa-client/pom.xml:parent " - -for PROJECT in $PROJECTS; -do - POMFILE=$(echo $PROJECT | cut -d':' -f1) - ACTIONS=$(echo $PROJECT | cut -d':' -f2) - - ## Auf SNAPSHOT Versionen testen - if fgrep -q "SNAPSHOT" $POMFILE; then - RED='\033[0;31m' - NC='\033[0m' - echo "${RED}ERROR: Datei "$POMFILE" enthält noch SNAPSHOT Versionen, das sollte hier nicht passieren.${NC}" - exit 1 - fi - - ## Versionen setzen - if [[ $ACTIONS == *"main"* ]] ; then - xmlstarlet ed --pf -L -N w="http://maven.apache.org/POM/4.0.0" -u '//w:project/w:version' -v $NEWVERSION $POMFILE - fi - - if [[ $ACTIONS == *"parent"* ]]; then - xmlstarlet ed --pf -L -N w="http://maven.apache.org/POM/4.0.0" -u '//w:project/w:parent/w:version' -v $NEWVERSION $POMFILE - fi -done - - - -echo -echo "NEXT STEPS:" -echo "***********" -echo "Änderungen prüfen" -echo "git commit -a -m 'start development "$NEWVERSION"'" -echo "git push" -