diff --git a/Jenkinsfile b/Jenkinsfile index 7186b1e8cf72de1ac056f700f5aff9ecd8e21114..b4cea16216e7a1a96e37bc235c152026abc3a842 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,8 +1,3 @@ -def FAILED_STAGE -def IMAGE_TAG -def VERSION -def E2E_FAILED - pipeline { agent { node { @@ -14,6 +9,10 @@ pipeline { BLUE_OCEAN_URL = "https://jenkins.ozg-sh.de/blue/organizations/jenkins/goofy/detail/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/pipeline" RELEASE_REGEX = /\d+.\d+.\d+/ SNAPSHOT_REGEX = /\d+.\d+.\d+-SNAPSHOT/ + FAILED_STAGE = "" + IMAGE_TAG = "" + VERSION = "" + E2E_FAILED = "" } options { @@ -125,6 +124,24 @@ pipeline { } } } + stage('Init k8s') { + steps { + script { + FAILED_STAGE = env.STAGE_NAME + E2E_FAILED = "" + } + container("k8s") { + configFileProvider([configFile(fileId: 'jenkins-kuby-kubeconfig', variable: 'KUBE_CONFIG')]) { + sh 'mkdir ~/.kube' + sh 'cp ${KUBE_CONFIG} ~/.kube/config' + } + + initHelmRepo() + + sh 'helm version' + } + } + } stage('Deploy Maven Artifacts to Nexus') { when { anyOf { @@ -174,22 +191,6 @@ pipeline { } } } - stage('Init k8s') { - steps { - script { - FAILED_STAGE = env.STAGE_NAME - E2E_FAILED = "" - } - container("k8s") { - configFileProvider([configFile(fileId: 'jenkins-kuby-kubeconfig', variable: 'KUBE_CONFIG')]) { - sh 'mkdir ~/.kube' - sh 'cp ${KUBE_CONFIG} ~/.kube/config' - sh 'cat ~/.kube/config' - } - sh 'helm version' - } - } - } stage('Rollout Dev Goofy') { when { branch 'master' @@ -320,8 +321,8 @@ pipeline { post { failure { script { - if (env.BRANCH_NAME == 'master') { - slackSend(color: "danger", message: "Goofy: Build Failed. Stage: ${FAILED_STAGE} Build-ID: <${BLUE_OCEAN_URL}|${env.BUILD_NUMBER}>") + if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'release') { + sendFailureMessage() } } } @@ -359,33 +360,64 @@ Void checkIfNamespaceExists(String namespace) { def namespaceList = sh (script: 'kubectl get namespaces', returnStdout: true) if(namespaceList.contains(namespace)) { - sh "kubectl delete namespace ${namespace}" + deleteNamespace(namespace) } } } +Void deleteNamespace(String namespace) { + sh "kubectl delete namespace ${namespace}" +} + Void startPluto(String namespace, String values, String bezeichner) { container("k8s") { dir('goofy-client/apps/goofy-e2e/deployment-values/pluto') { - sh "helm upgrade --install --create-namespace pluto ozg-base-apps-snapshot/pluto -f ${values} --set kop.bezeichner=${bezeichner} --namespace ${namespace} --version ${getLatestChartVersion('pluto').trim()} --wait --wait-for-jobs" + if(env.BRANCH_NAME == 'release') { + startPlutoForReleaseTests(namespace, values, bezeichner) + } + else { + startPlutoForSnapshotTests(namespace, values, bezeichner) + } } sh "kubectl rollout status statefulset/pluto-database -n ${namespace}" } } +Void startPlutoForReleaseTests(String namespace, String values, String bezeichner) { + sh "helm upgrade --install --create-namespace pluto ozg-base-apps/pluto -f ${values} --set kop.bezeichner=${bezeichner} --namespace ${namespace} --wait --wait-for-jobs" +} + +Void startPlutoForSnapshotTests(String namespace, String values, String bezeichner) { + sh "helm upgrade --install --create-namespace pluto ozg-base-apps-snapshot/pluto -f ${values} --set kop.bezeichner=${bezeichner} --namespace ${namespace} --version ${getLatestChartVersion('pluto').trim()} --wait --wait-for-jobs" +} + Void startGoofy(String namespace, String values, String imageTag, String bezeichner) { container("k8s") { dir('goofy-client/apps/goofy-e2e/deployment-values/goofy') { - sh "helm upgrade --install --create-namespace goofy ozg-base-apps-snapshot/goofy -f ${values} --set image.tag=${imageTag} --set kop.bezeichner=${bezeichner} --namespace ${namespace} --version ${getLatestChartVersion('goofy').trim()} --wait --wait-for-jobs" + if(env.BRANCH_NAME == 'release') { + startGoofyForReleaseTests(namespace, values, bezeichner, imageTag) + } + else { + startGoofyForSnapshotTests(namespace, values, bezeichner, imageTag) + } } + waitForKeycloakClientCreation(namespace) createKeycloakGroups(namespace) generateKeycloakUserYaml(namespace) applyKeycloakUser(namespace) } } +Void startGoofyForReleaseTests(String namespace, String values, String bezeichner, String imageTag) { + sh "helm upgrade --install --create-namespace goofy ozg-base-apps/goofy -f ${values} --set image.tag=${imageTag} --set kop.bezeichner=${bezeichner} --namespace ${namespace} --wait --wait-for-jobs" +} + +Void startGoofyForSnapshotTests(String namespace, String values, String bezeichner, String imageTag) { + sh "helm upgrade --install --create-namespace goofy ozg-base-apps-snapshot/goofy -f ${values} --set image.tag=${imageTag} --set kop.bezeichner=${bezeichner} --namespace ${namespace} --version ${getLatestChartVersion('goofy').trim()} --wait --wait-for-jobs" +} + String getLatestChartVersion(String chart) { container("k8s") { return sh (script: "helm search repo ozg-base-apps-snapshot --devel -l -o json | jq -r 'first(.[] | select((.name==\"ozg-base-apps-snapshot/${chart}\") and (.version|match(\"SNAPSHOT\$\"))) | .version)'", returnStdout: true) @@ -429,13 +461,19 @@ String generateBezeichner(String stage) { def branchName = makeUrlConform(env.BRANCH_NAME) def stageName = makeUrlConform(stage) - def cutBranchNamePosition = 30 - (branchName.length() + stageName.length() + 8) + return "${cutBranchNameForKeycloakRealm(branchName, stageName)}${stageName}" +} + +String cutBranchNameForKeycloakRealm(String branchName, String stageName) { + def maxKeycloakRealmLength = 30 + def postPrefixLength = 8 + def cutBranchNamePosition = maxKeycloakRealmLength - (branchName.length() + stageName.length() + postPrefixLength) if(cutBranchNamePosition < 0) { branchName = branchName[0..cutBranchNamePosition] } - return "${branchName}${stageName}" + return branchName } String generateNamespaceName(String bezeichner) { @@ -557,4 +595,46 @@ String getKeycloakAccessToken() { return token.access_token } +} + +Void waitForKeycloakClientCreation(realm) { + def shScript = """curl -H 'Content-Type: application/json' \ + -H 'Authorization: bearer ${getKeycloakAccessToken()}' \ + 'https://sso.dev.ozg-sh.de/auth/admin/realms/${realm}/clients' \ + | grep -q ${realm}-goofy + """ + + while(sh(script: shScript, returnStatus: true)) { + sh 'sleep 5' + } +} + +Void sendFailureMessage() { + def room = '' + def data = """{"msgtype":"m.text", \ + "body":"Goofy: Build Failed. Stage: ${FAILED_STAGE} Build-ID: ${env.BUILD_NUMBER} Link: ${BLUE_OCEAN_URL}", \ + "format": "org.matrix.custom.html", \ + "formatted_body":"Goofy: Build Failed. Stage: ${FAILED_STAGE} Build-ID: <a href='${BLUE_OCEAN_URL}'>${env.BUILD_NUMBER}</a>"}""" + + if (env.BRANCH_NAME == 'master') { + room = "!iQPAvQIiRwRpNOszjw:matrix.ozg-sh.de" + } + else if (env.BRANCH_NAME == 'release') { + room = "!oWZpUGTFsxkJIYNfYg:matrix.ozg-sh.de" + } + + sh "curl -XPOST -H 'authorization: Bearer ${getElementAccessToken()}' -d '${data}' https://matrix.ozg-sh.de/_matrix/client/v3/rooms/$room/send/m.room.message" +} + +String getElementAccessToken() { + withCredentials([string(credentialsId: 'element-login-json', variable: 'LOGIN_JSON')]) { + return readJSON ( text: sh (script: '''curl -XPOST -d \"$LOGIN_JSON\" https://matrix.ozg-sh.de/_matrix/client/v3/login''', returnStdout: true)).access_token + } +} + +Void initHelmRepo() { + withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) { + sh 'helm repo add ozg-base-apps-snapshot https://nexus.ozg-sh.de/repository/ozg-base-apps-snapshot --username ${USER} --password ${PASSWORD}' + sh 'helm repo add ozg-base-apps https://nexus.ozg-sh.de/repository/ozg-base-apps --username ${USER} --password ${PASSWORD}' + } } \ No newline at end of file diff --git a/goofy-client/.gitignore b/goofy-client/.gitignore index 4fd9280cfc1fbd0aa4b37c6d3c2c5798c3aea859..92abdb41d7fa17686e58d3ccf2fcb843520c83e7 100644 --- a/goofy-client/.gitignore +++ b/goofy-client/.gitignore @@ -45,3 +45,5 @@ testem.log # System Files .DS_Store Thumbs.db + +.angular diff --git a/goofy-client/angular.json b/goofy-client/angular.json index dc95c00d557171ac0c83278366be1a3a1463395a..faabb2288332d4d7fda6e994cf2e3450a17e6c01 100644 --- a/goofy-client/angular.json +++ b/goofy-client/angular.json @@ -741,6 +741,32 @@ }, "tags": [] }, + "vorgang-historie": { + "projectType": "library", + "root": "libs/vorgang-historie", + "sourceRoot": "libs/vorgang-historie/src", + "prefix": "goofy-client", + "architect": { + "test": { + "builder": "@nrwl/jest:jest", + "outputs": ["coverage/libs/vorgang-historie"], + "options": { + "jestConfig": "libs/vorgang-historie/jest.config.js", + "passWithNoTests": true + } + }, + "lint": { + "builder": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": [ + "libs/vorgang-historie/src/**/*.ts", + "libs/vorgang-historie/src/**/*.html" + ] + } + } + }, + "tags": [] + }, "vorgang-shared": { "projectType": "library", "root": "libs/vorgang-shared", diff --git a/goofy-client/apps/goofy-e2e/cypress-ci.json b/goofy-client/apps/goofy-e2e/cypress-ci.json index 226e3b24a4874cf11e02abb708326aa56cc6f09e..e9ae33f9b5536c4362ae095cb37566d4b2eee0b3 100644 --- a/goofy-client/apps/goofy-e2e/cypress-ci.json +++ b/goofy-client/apps/goofy-e2e/cypress-ci.json @@ -18,7 +18,7 @@ "screenshotsFolder": "./reports/screenshots", "chromeWebSecurity": false, "reporter": "../../node_modules/cypress-mochawesome-reporter", - "defaultCommandTimeout": 30000, + "defaultCommandTimeout": 10000, "reporterOptions": { "html": false, "json": true, diff --git a/goofy-client/apps/goofy-e2e/cypress.json b/goofy-client/apps/goofy-e2e/cypress.json index e6a2f99932c1bebd99a5b710f42ed5ad0257a9fc..4122b625bd22da6b8d73513906d3bb83f608dc3e 100644 --- a/goofy-client/apps/goofy-e2e/cypress.json +++ b/goofy-client/apps/goofy-e2e/cypress.json @@ -19,7 +19,7 @@ "screenshotsFolder": "./reports/screenshots", "chromeWebSecurity": false, "reporter": "../../node_modules/cypress-mochawesome-reporter", - "defaultCommandTimeout": 30000, + "defaultCommandTimeout": 10000, "reporterOptions": { "html": false, "json": true, diff --git a/goofy-client/apps/goofy-e2e/deployment-values/goofy/ea-values.yaml b/goofy-client/apps/goofy-e2e/deployment-values/goofy/ea-values.yaml index 186bcf470603c5e114d0646583806d9bda3cf9e8..0f0c380e7742c42c4aac7aa8b20a3bdc2912690c 100644 --- a/goofy-client/apps/goofy-e2e/deployment-values/goofy/ea-values.yaml +++ b/goofy-client/apps/goofy-e2e/deployment-values/goofy/ea-values.yaml @@ -1,6 +1,7 @@ sso: serverUrl: 'https://sso.dev.ozg-sh.de/auth' role_einheitlicher_ansprechpartner: true + apiPassword: "Goofy1234!" env: overrideSpringProfiles: 'oc,dev,ea,e2e' plutoName: pluto diff --git a/goofy-client/apps/goofy-e2e/deployment-values/goofy/values.yaml b/goofy-client/apps/goofy-e2e/deployment-values/goofy/values.yaml index 7fc995858ebbf5ef31d5ef914a9f0b8f83a3edad..cf6d7c3b88614b1b205cd616a46dc332303752a3 100644 --- a/goofy-client/apps/goofy-e2e/deployment-values/goofy/values.yaml +++ b/goofy-client/apps/goofy-e2e/deployment-values/goofy/values.yaml @@ -1,5 +1,6 @@ sso: serverUrl: 'https://sso.dev.ozg-sh.de/auth' + apiPassword: "Goofy1234!" env: overrideSpringProfiles: 'oc, dev, e2e' plutoName: pluto diff --git a/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts b/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts index c963cd470c996f9bd2505a8e4f53427d3fb44209..8caf345fa69221ddf747bdd958aedbb6334bbe3b 100644 --- a/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts +++ b/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts @@ -15,6 +15,7 @@ export class PostfachMailE2EComponent { return cy.getTestElement(this.locatorRoot); } + //TODO Umbenennen in bspw. sendButton public getButton() { return cy.getTestElement(this.locatorButton); } diff --git a/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-list.e2e.component.ts b/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-list.e2e.component.ts index adf241c5f3fab6967a7add75d9755ba38abf02d1..b1e2ac805a7aaba0c03dc50efc52f00ec2d8083a 100644 --- a/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-list.e2e.component.ts +++ b/goofy-client/apps/goofy-e2e/src/components/vorgang/vorgang-list.e2e.component.ts @@ -6,6 +6,7 @@ export class VorgangListE2EComponent { private readonly spinnerComponent: SpinnerE2EComponent = new SpinnerE2EComponent(); private readonly locatorRoot: string = 'vorgang-list'; + private readonly locatorNoRoleMessage: string = 'user-no-role-message'; public getRoot() { return cy.getTestElement(this.locatorRoot); @@ -18,4 +19,8 @@ export class VorgangListE2EComponent { public getSpinner() { return this.spinnerComponent.findSpinner(this.getRoot()); } + + public getNoRoleMessage() { + return cy.getTestElement(this.locatorNoRoleMessage); + } } \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_emil.json b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_emil.json index a5e8c36bf6737e1c73a30939cd905fa0068aeb04..fdf45c69e17675488dcbb47134c0d2f941f5f74c 100644 --- a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_emil.json +++ b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_emil.json @@ -1,6 +1,6 @@ { "name": "emil", - "password": "Y9nk43yrQ_zzIPpfFU-I", + "password": "Ansprechpartner", "firstName": "Emil", "lastName": "Ansprechpartner", "fullName": "Emil Ansprechpartner", diff --git a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kfinder.json b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kfinder.json index 22f78e014b70157a4d6d26ba3604e7affcf06fc9..3a7a5dcf387c718ca6e9f91ca3b0e834b8f06212 100644 --- a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kfinder.json +++ b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kfinder.json @@ -1,5 +1,6 @@ { "name": "kfinder", "password": "Katrinfinder", - "groups": ["Abtl. 10.0.1 Versammlungsbehörde, Identitätsfeststellung, Fundbüro"] + "groups": ["Abtl. 10.0.1 Versammlungsbehörde, Identitätsfeststellung, Fundbüro"], + "clientRoles": ["VERWALTUNG_USER"] } \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kordner.json b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kordner.json index f1f4ebbbea2ffe18d2118a52470cf2b17be2a6ae..79b8c6c09a07eaf851ae30f92489b3afd057f71b 100644 --- a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kordner.json +++ b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_kordner.json @@ -1,5 +1,6 @@ { "name": "kordner", "password": "Klausordner", - "groups": ["Abtl. 10.5.1.2 Allgemeine Gefahrenabwehr und sonstige Ordnungsrechtsangelegenheiten"] + "groups": ["Abtl. 10.5.1.2 Allgemeine Gefahrenabwehr und sonstige Ordnungsrechtsangelegenheiten"], + "clientRoles": ["VERWALTUNG_USER"] } \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/fixtures/user/user_richard.json b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_richard.json new file mode 100644 index 0000000000000000000000000000000000000000..c1fa331c717ea67ff70dbeb7c599b91526189c7e --- /dev/null +++ b/goofy-client/apps/goofy-e2e/src/fixtures/user/user_richard.json @@ -0,0 +1,6 @@ +{ + "name": "richard", + "firstName": "Richard", + "lastName": "Rollenlos", + "password": "Y9nk43yrQ_zzIPpfFU-I" +} \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/navigation/navigation.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/navigation/navigation.e2e-spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0fcd0535bd473b973157f8a0d997b311fcc572c --- /dev/null +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/navigation/navigation.e2e-spec.ts @@ -0,0 +1,38 @@ +import { NavigationE2EComponent } from 'apps/goofy-e2e/src/components/navigation/navigation.e2e.component'; +import { VorgangListE2EComponent } from 'apps/goofy-e2e/src/components/vorgang/vorgang-list.e2e.component'; +import { MainPage, waitForSpinnerToDisappear } from 'apps/goofy-e2e/src/page-objects/main.po'; +import { dropCollections } from 'apps/goofy-e2e/src/support/cypress-helper'; +import { exist, notExist } from 'apps/goofy-e2e/src/support/cypress.util'; +import { loginAsEmil } from 'apps/goofy-e2e/src/support/user-util'; + +describe('Navigation', () => { + const mainPage: MainPage = new MainPage(); + const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); + + const navigation: NavigationE2EComponent = mainPage.getNavigation(); + + before(() => { + loginAsEmil(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }) + + after(() => { + dropCollections(); + }) + + describe('navigation item myVorgaenge', () => { + + it('should not exists', () => { + notExist(navigation.getMyVorgaengeItem()); + }) + }) + + describe('navigation item allVorgaenge', () => { + + it('should exists', () => { + exist(navigation.getAllVorgaengeItem()); + }) + }) +}) \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-abschliessen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-abschliessen.e2e-spec.ts index 06c04cf370028b782d68678eed6f5f88543020ea..e4c18311022168829fb39c3a0732dbe70e28119b 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-abschliessen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-abschliessen.e2e-spec.ts @@ -25,6 +25,7 @@ describe('Vorgang abschliessen', () => { loginAsEmil(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -37,6 +38,7 @@ describe('Vorgang abschliessen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbschliessen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -46,14 +48,11 @@ describe('Vorgang abschliessen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangAbschliessen.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangFormularButtons.clickAbschliessenByButton(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN) - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN) }) it('should close snackBar', () => { @@ -68,13 +67,12 @@ describe('Vorgang abschliessen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Abgeschlossen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAbschliessen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ABGESCHLOSSEN]); }) }) @@ -84,6 +82,7 @@ describe('Vorgang abschliessen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbschliessenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -94,35 +93,34 @@ describe('Vorgang abschliessen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangAbschliessenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().clickAbschliessenByIconButton(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) - it('should show status Beschieden', () => { + it('should show status Beschieden after progressbar dissapear', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Beschieden', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAbschliessenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]) }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.e2e-spec.ts index df4f9a76e881adcc96cf14d7323e62857e504320..409bded210ae8dc7b08be68647044ec2d7a5fda9 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forward.e2e-spec.ts @@ -24,6 +24,7 @@ describe('Vorgang forwarding', () => { loginAsEmil(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -35,6 +36,7 @@ describe('Vorgang forwarding', () => { it('should show vorgang header', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -55,6 +57,7 @@ describe('Vorgang forwarding', () => { forwardFormular.getPasswort().clear().type('zukurz'); forwardFormular.forward(); + waitForSpinnerToDisappear(); exist(forwardFormular.getPasswortError()); }) @@ -64,6 +67,7 @@ describe('Vorgang forwarding', () => { forwardFormular.getZustaendigeStelle().clear().type('invalidemail.com'); forwardFormular.forward(); + waitForSpinnerToDisappear(); exist(forwardFormular.getZustaendigeStelleError()); }) @@ -101,6 +105,7 @@ describe('Vorgang forwarding', () => { it('should show "zustellung success message" after click on button', () => { forwardingContainer.getMarkAsSuccessButton().click(); + waitForSpinnerToDisappear(); exist(forwardingContainer.getForwardingSuccessMessage()); }) @@ -110,7 +115,6 @@ describe('Vorgang forwarding', () => { it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET] + ' in list', () => { vorgangPage.getSubnavigation().clickBackButton(); - waitForSpinnerToDisappear(); haveText(vorgangList.getListItem(vorgang.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET]); @@ -121,6 +125,7 @@ describe('Vorgang forwarding', () => { it('should formular after switching vorgang without pending commands', () => { vorgangList.getListItem(vorgangEmpty.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(forwardingContainer.getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-e2e-spec.ts index 463be058e579c6309c498ab5d137cc2e9ab938cd..1c9bcbeddd8f52c7ed4b980949359601afdbdb9f 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding-failed-e2e-spec.ts @@ -23,6 +23,7 @@ describe('Vorgang forwarding failed', () => { loginAsEmil(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -34,6 +35,7 @@ describe('Vorgang forwarding failed', () => { it('should show vorgang header', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -52,13 +54,15 @@ describe('Vorgang forwarding failed', () => { formular.forward(); - waitForSpinnerToDisappear(); + exist(forwardingContainer.getSpinner()); }) }) describe('mark forwarding as fail', () => { it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET], () => { + waitForSpinnerToDisappear(); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.WEITERGELEITET]) }) @@ -97,7 +101,6 @@ describe('Vorgang forwarding failed', () => { it('should have status ' + vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG] + ' in list', () => { vorgangPage.getSubnavigation().clickBackButton(); - waitForSpinnerToDisappear(); haveText(vorgangList.getListItem(vorgang.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-verwerfen.ea.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-verwerfen.ea.e2e-spec.ts index b446c717078d72330f2b0bf982cbbad040e60d50..ebd21580474f4f60c91cf4789a799fa6a6d6e80e 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-verwerfen.ea.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-verwerfen.ea.e2e-spec.ts @@ -30,6 +30,7 @@ describe('Vorgang Verwerfen', () => { loginAsEmil(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -41,6 +42,7 @@ describe('Vorgang Verwerfen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangVerwerfen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -53,15 +55,13 @@ describe('Vorgang Verwerfen', () => { it('should show snackBar message', () => { vorgangFormularButtons.clickVerwerfenByButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); }) - it('should close snackBar', () => { + it('should close snackBar on close button', () => { snackbar.getCloseButton().click(); notExist(snackbar.getMessage()); @@ -78,13 +78,12 @@ describe('Vorgang Verwerfen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Verworfen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangVerwerfen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.VERWORFEN]); }) }) @@ -94,6 +93,7 @@ describe('Vorgang Verwerfen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangVerwerfenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -104,23 +104,24 @@ describe('Vorgang Verwerfen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangVerwerfenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().clickVerwerfenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackbar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackbar.getMessage()); }) - it('should show status Neu', () => { + it('should show status Neu after progressbar dissapear', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) @@ -131,13 +132,12 @@ describe('Vorgang Verwerfen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Neu', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangVerwerfenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-wiedereroeffnen.ea.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-wiedereroeffnen.ea.e2e-spec.ts index 19969db1281cf3cb0698290ae52ffe031d983814..efdab9bb0f489f1af5f5330f3ed6ba79f24e1832 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-wiedereroeffnen.ea.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-wiedereroeffnen.ea.e2e-spec.ts @@ -25,6 +25,7 @@ describe('Vorgang wiedereroeffnen', () => { loginAsEmil(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -38,6 +39,7 @@ describe('Vorgang wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -48,17 +50,15 @@ describe('Vorgang wiedereroeffnen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangAbgeschlossenWiedereroeffnen.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangFormularButtons.clickWiedereroeffnenByButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); }) - it('should close snackBar', () => { + it('should close snackBar on close', () => { snackbar.getCloseButton().click(); notExist(snackbar.getMessage()); @@ -70,13 +70,12 @@ describe('Vorgang wiedereroeffnen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status In Bearbeitung', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) }) @@ -86,6 +85,7 @@ describe('Vorgang wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -96,35 +96,35 @@ describe('Vorgang wiedereroeffnen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangAbgeschlossenWiedereroeffnenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().clickWiedereroeffnenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackbar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackbar.getMessage()); }) - it('should show status Abgeschlossen', () => { + it('should show status Abgeschlossen after progressbar dissapear', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ABGESCHLOSSEN]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Abgeschlossen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ABGESCHLOSSEN]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-zurueckholen.ea.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-zurueckholen.ea.e2e-spec.ts index a8cca227ed36bc17abfa2ab8a7e675db15184700..dd64bead9a1e543c106ebf8a050900a7503125a9 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-zurueckholen.ea.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-detail/vorgang-zurueckholen.ea.e2e-spec.ts @@ -30,6 +30,7 @@ describe('Vorgang Zurueckholen', () => { loginAsEmil(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -41,6 +42,7 @@ describe('Vorgang Zurueckholen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangZurueckholen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -51,17 +53,15 @@ describe('Vorgang Zurueckholen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangZurueckholen.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangFormularButtons.getZurueckholenButton().click(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); }) - it('should close snackBar', () => { + it('should close snackBar on close button', () => { snackBar.getCloseButton().click(); notExist(snackBar.getMessage()); @@ -77,13 +77,12 @@ describe('Vorgang Zurueckholen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Neu', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangZurueckholen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) }) @@ -93,6 +92,7 @@ describe('Vorgang Zurueckholen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangZurueckholenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -103,23 +103,24 @@ describe('Vorgang Zurueckholen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangZurueckholenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().getZurueckholenIconButton().click(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) - it('should show status Verworfen', () => { + it('should show status Verworfen after progressbar dissapear', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.VERWORFEN]); }) @@ -130,13 +131,12 @@ describe('Vorgang Zurueckholen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Verworfen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangZurueckholenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.VERWORFEN]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts index 203c52d1434d3ea22f67dfd6b4ab3f84a4ac87a7..f883346b68b13208de815768db5915a07186c443 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts @@ -31,8 +31,8 @@ describe('VorgangList Suche for EA User', () => { loginAsEmil(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/app/buildinfo.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/app/buildinfo.e2e-spec.ts index 5eb8d73a7a55affde88fd652bfabbdc5ea62aa0f..14f07f5139439315fc39e2a868ecd9111048655a 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/app/buildinfo.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/app/buildinfo.e2e-spec.ts @@ -13,8 +13,8 @@ describe('Buildinfo', () => { before(() => { loginAsSabine(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-connection-timout.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-connection-timout.e2e-spec.ts index 31d96367988452e667682d3352d353808f902fb4..16b0888357438675785587de4c1a998ea3243ceb 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-connection-timout.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-connection-timout.e2e-spec.ts @@ -3,7 +3,7 @@ import { ConnectionTimeoutRetryDialogE2EComponent, ConnectionTimeoutRetryFailDia import { VorgangDetailHeaderE2EComponent } from '../../../components/vorgang/vorgang-detail-header.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections, interceptWithResponse, waitOfInterceptor } from '../../../support/cypress-helper'; import { contains, exist } from '../../../support/cypress.util'; @@ -30,6 +30,7 @@ describe('Interceptor Connection Timeout', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -50,6 +51,7 @@ describe('Interceptor Connection Timeout', () => { it('should navigate to vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangHeader.getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-forbidden.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-forbidden.e2e-spec.ts index 6f971f3dce5e52e043a092c5c36efe36b2235337..d8c311a1f3424f7eb09ca478df052cdbe0f82c63 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-forbidden.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-forbidden.e2e-spec.ts @@ -4,7 +4,7 @@ import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-lis import { VorgangSubnavigationE2EComponent } from '../../../components/vorgang/vorgang-subnavigation'; import { HttpMethodE2E } from '../../../model/util'; import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections, interceptWithResponse, waitOfInterceptor } from '../../../support/cypress-helper'; import { contains, exist, notExist } from '../../../support/cypress.util'; @@ -28,6 +28,7 @@ describe('Interceptor Forbidden', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -48,6 +49,7 @@ describe('Interceptor Forbidden', () => { it('should show page and snackbar', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); waitOfInterceptor(interceptor).then((interception) => { assert(interception.response.statusCode, statusCode.toString()); @@ -59,8 +61,17 @@ describe('Interceptor Forbidden', () => { }) }) + it('should close snackbar on close button', () => { + snackbar.getCloseButton().click() + + notExist(snackbar.getMessage()); + }) + it('should navigate back on back button', () => { subnavigation.clickBackButton(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) }) }) \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-server-error.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-server-error.e2e-spec.ts index 01a057f45e4fdda8a23a26d4a21401ac8904fa8c..438160b38f2980878f20ccee42c6f7003e48ca59 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-server-error.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-server-error.e2e-spec.ts @@ -2,7 +2,7 @@ import { InternalServerErrorDialogE2EComponent } from '../../../components/ui/in import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { HttpMethodE2E } from '../../../model/util'; import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections, interceptWithResponse, waitOfInterceptor } from '../../../support/cypress-helper'; import { contains, exist, notExist } from '../../../support/cypress.util'; @@ -24,6 +24,7 @@ describe('Interceptor Server Error', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -44,6 +45,7 @@ describe('Interceptor Server Error', () => { it('should show page', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); waitOfInterceptor(interceptor).then(interception => { assert(interception.response.statusCode, statusCode.toString()); diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-unauthorized.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-unauthorized.e2e-spec.ts index fdd0153dd47f7ed0867268ea4823b188c8b3d1d8..9904eb389b800a0bfbc081e5b2f21af6167b4589 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-unauthorized.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/interceptor/interceptor-unauthorized.e2e-spec.ts @@ -25,6 +25,7 @@ describe('Interceptor unauthorized', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -42,6 +43,7 @@ describe('Interceptor unauthorized', () => { interceptWithResponse(HttpMethodE2E.GET, BASE_PATH + vorgang._id.$oid, { statusCode }).as(interceptorResponseUnauthorized); vorgangList.getListItem(vorgang.name).getRoot().click({ force: true }); + waitForSpinnerToDisappear(); waitOfInterceptor(interceptorResponseUnauthorized).then((interception) => { assert(interception.response.statusCode, statusCode.toString()); @@ -59,6 +61,9 @@ describe('Interceptor unauthorized', () => { it('should navigate back on back button', () => { subnavigation.clickBackButton(); + waitForSpinnerToDisappear(); + + exist(vorgangList.getRoot()); }) }) }) \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/kommentar/kommentar.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/kommentar/kommentar.e2e-spec.ts index aff539185f321f7c0c72a00d506d660e6834b2fc..ecaf35b5a3970e7fefb43c0dd1f9b1a5ce7787d3 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/kommentar/kommentar.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/kommentar/kommentar.e2e-spec.ts @@ -24,6 +24,7 @@ describe('Kommentar', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(mainPage.getVorgangList().getRoot()); }) @@ -35,6 +36,7 @@ describe('Kommentar', () => { it('Open Vorgang-Detail-Page', () => { mainPage.getVorgangList().getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -48,6 +50,7 @@ describe('Kommentar', () => { it('should show formular', () => { kommentarContainer.getHinzufuegenButton().click(); + waitForSpinnerToDisappear(); exist(kommentarContainer.getFormular()); }) @@ -65,9 +68,8 @@ describe('Kommentar', () => { describe('click on hinzufuegen button in formular', () => { it('should show error on invalid input', () => { - waitForSpinnerToDisappear(); - kommentarContainer.getFormularSpeichernButton().click(); + waitForSpinnerToDisappear(); exist(kommentarContainer.getTextError()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/navigation/navigation.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/navigation/navigation.e2e-spec.ts index 83e1ee78b3d2fdf94dc4c2ce754c059e3422841d..ea0f9b68a56773b16844691ab359166c59cd0ab3 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/navigation/navigation.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/navigation/navigation.e2e-spec.ts @@ -1,13 +1,13 @@ import { NavigationE2EComponent } from 'apps/goofy-e2e/src/components/navigation/navigation.e2e.component'; import { VorgangListE2EComponent } from 'apps/goofy-e2e/src/components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E } from 'apps/goofy-e2e/src/model/vorgang'; -import { MainPage } from 'apps/goofy-e2e/src/page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from 'apps/goofy-e2e/src/page-objects/main.po'; import { dropCollections } from 'apps/goofy-e2e/src/support/cypress-helper'; import { CypressKeyboardActions, exist, notExist } from 'apps/goofy-e2e/src/support/cypress.util'; import { getUserSabineUuid, loginAsSabine } from 'apps/goofy-e2e/src/support/user-util'; import { buildVorgang, createVorgang, initVorgaenge, objectIds } from 'apps/goofy-e2e/src/support/vorgang-util'; -describe.skip('Navigation', () => { +describe('Navigation', () => { const mainPage: MainPage = new MainPage(); const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); @@ -25,6 +25,10 @@ describe.skip('Navigation', () => { loginAsSabine(); + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + navigation.getAllVorgaengeItem().click(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -32,10 +36,25 @@ describe.skip('Navigation', () => { dropCollections(); }) + describe('navigation item myVorgaenge', () => { + + it('should exists', () => { + exist(navigation.getMyVorgaengeItem()); + }) + }) + + describe('navigation item allVorgaenge', () => { + + it('should exists', () => { + exist(navigation.getAllVorgaengeItem()); + }) + }) + describe('click on my vorgaenge', () => { it('should hide not to user assigned vorgaenge', () => { navigation.getMyVorgaengeItem().click(); + waitForSpinnerToDisappear(); notExist(vorgangList.getListItem(vorgang.name).getRoot()); notExist(vorgangList.getListItem(vorgangNotBeFiltered.name).getRoot()); @@ -45,6 +64,7 @@ describe.skip('Navigation', () => { it('should hide not matching vorgaenge after do search', () => { doSearch(searchString); + waitForSpinnerToDisappear(); notExist(vorgangList.getListItem(vorgang.name).getRoot()); notExist(vorgangList.getListItem(vorgangNotBeFiltered.name).getRoot()); @@ -57,6 +77,7 @@ describe.skip('Navigation', () => { it('should show all vorgaenge', () => { navigation.getAllVorgaengeItem().click(); + waitForSpinnerToDisappear(); exist(vorgangList.getListItem(vorgang.name).getRoot()); exist(vorgangList.getListItem(vorgangNotBeFiltered.name).getRoot()); @@ -66,6 +87,7 @@ describe.skip('Navigation', () => { it('should hide not matching vorgaenge after do search', () => { doSearch(searchString); + waitForSpinnerToDisappear(); notExist(vorgangList.getListItem(vorgang.name).getRoot()); exist(vorgangList.getListItem(vorgangNotBeFiltered.name).getRoot()); diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail-error.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail-error.e2e-spec.ts index 621dabf8a158720324163270a540d882c28f3c4a..7694fdeed57227d15a48267b26284576ebffa866 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail-error.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail-error.e2e-spec.ts @@ -4,7 +4,7 @@ import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-lis import { VorgangSubnavigationE2EComponent } from '../../../components/vorgang/vorgang-subnavigation'; import { VorgangE2E } from '../../../model/vorgang'; import { DirectionE2E, PostfachMailItemE2E, PostfachNachrichtMessageCodeE2E, PostfachNachrichtMessageCodeMessagesE2E, PostfachNachrichtSnackbarMessageE2E, VorgangAttachedItemE2E } from '../../../model/vorgang-attached-item'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { PostfachMailPage } from '../../../page-objects/postfach-mail.component.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections } from '../../../support/cypress-helper'; @@ -41,6 +41,7 @@ describe('PostfachMail error', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -52,6 +53,7 @@ describe('PostfachMail error', () => { it('should open vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -109,6 +111,7 @@ describe('PostfachMail error', () => { it('click on resend button should hide error', () => { listItem.getResendButton().click(); + waitForSpinnerToDisappear(); notExist(listItem.getMailSendErrorIcon()); }) @@ -120,6 +123,12 @@ describe('PostfachMail error', () => { notExist(snackbar.getRevokeButton()); }) + it('should close snackbar on close button', () => { + snackbar.getCloseButton().click(); + + notExist(snackbar.getMessage()); + }) + it('should show mail subject', () => { contains(listItem.getSubject(), postfachMailItem.subject); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts index 63ee7d0fd571d2ae8748978b8e57b100a507fe77..944b11a29574a0e637ac97d4841a894853e2daf2 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.e2e-spec.ts @@ -53,6 +53,7 @@ describe('PostfachMail', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -61,6 +62,7 @@ describe('PostfachMail', () => { }) describe('mail icon', () => { + it('should not be visible', () => { notExist(vorgangList.getListItem(vorgang.name).getPostfachStatus()); }) @@ -70,6 +72,7 @@ describe('PostfachMail', () => { it('should open vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -98,6 +101,7 @@ describe('PostfachMail', () => { it('should show fixed dialog header and content', () => { postfachMailContainer.getButton().click(); + waitForSpinnerToDisappear(); exist(fixedDialog.getDialogHeader()); exist(fixedDialog.getDialogContent()); @@ -124,6 +128,7 @@ describe('PostfachMail', () => { it('should open dialog click on icon button', () => { subnavigation.getPostfachMailIconButton().click(); + waitForSpinnerToDisappear(); exist(postfachMailFormular.getEmpfaenger()); }) @@ -146,6 +151,7 @@ describe('PostfachMail', () => { it('should show error on subject if send empty', () => { postfachMailFormular.getSendButton().click(); + waitForSpinnerToDisappear(); exist(postfachMailFormular.getBetreffError()); }) @@ -173,32 +179,35 @@ describe('PostfachMail', () => { it('should show empty attachment after uploading it', () => { uploadEmptyFile(attachmentContainer.getUploadInput(), TEST_FILE_WITHOUT_CONTENT) + waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); }) it('should show attachment with content after uploading it', () => { uploadFile(postfachMailFormular.getAttachmentContainer().getUploadInput(), TEST_FILE_WITH_CONTENT); + waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); }) it('should download empty attachment on click', () => { attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(TEST_FILE_WITHOUT_CONTENT)); }) it('should download attachment with content on click', () => { attachmentList.getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(TEST_FILE_WITH_CONTENT)); }) it('should not show empty attachment after deleting it', () => { attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDeleteButton().click(); + waitForSpinnerToDisappear(); notExist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); }) @@ -208,12 +217,13 @@ describe('PostfachMail', () => { it('should show error snackbar', () => { uploadFile(postfachMailFormular.getAttachmentContainer().getUploadInput(), TEST_FILE_WITH_CONTENT_4_MB); + waitForSpinnerToDisappear(); exist(snackbar.getMessage()); contains(snackbar.getMessage(), BinaryFileSnackbarMessageE2E.ATTACHMENT_NOT_ADDED.replace('{size}', '3MB')); }) - it('should close snackbar', () => { + it('should close snackbar on close button', () => { snackbar.getCloseButton().click(); notExist(snackbar.getCloseButton()); @@ -240,6 +250,7 @@ describe('PostfachMail', () => { it('should close dialog', () => { postfachMailFormular.getSendButton().click(); + waitForSpinnerToDisappear(); notExist(postfachMailFormular.getEmpfaenger()); }) @@ -249,6 +260,12 @@ describe('PostfachMail', () => { notExist(snackbar.getRevokeButton()); }) + it('should close snackbar on close button', () => { + snackbar.getCloseButton().click(); + + notExist(snackbar.getMessage()); + }) + it('should show postfach mail in list', () => { const postfachMailItem: PostfachMailListItem = postfachMailContainer.getListItem(postfachMailToSend.subject); @@ -280,8 +297,8 @@ describe('PostfachMail', () => { it('should download attachment after click', () => { const postfachListItem: PostfachMailListItem = postfachMailPage.getListItem(postfachMailToSend.subject); - waitForSpinnerToDisappear(); postfachListItem.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click(); + waitForSpinnerToDisappear(); exist(readFileFromDownloads(TEST_FILE_WITHOUT_CONTENT)); }); @@ -390,6 +407,9 @@ describe('PostfachMail', () => { it('should open full view of postfachMailList', () => { postfachMailReplyItem.getRoot().click(); + waitForSpinnerToDisappear(); + + exist(postfachMailPage.getRoot()); }) it('should show subnavigation', () => { @@ -424,6 +444,7 @@ describe('PostfachMail', () => { it('should navigate to vorgang detail', () => { postfachMailPage.getSubnavigation().getBackButton().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.e2e-spec.ts index 8c388898fd9a633fe3e8a968ef7cdc970060b646..bfd4a54ec45dbff7c02fd4008796b96f782a15e7 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.e2e-spec.ts @@ -46,13 +46,14 @@ describe('PostfachNachrichten filtered by organisationseinheit', () => { before(() => { loginAsKfinder(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) it('should open postfachNachrichten page', () => { logInParts(authorizedUrl); visitUrl(authorizedUrl); + waitForSpinnerToDisappear(); exist(postfachMailPage.getBreadcrump()); }); @@ -60,10 +61,15 @@ describe('PostfachNachrichten filtered by organisationseinheit', () => { it('should not open postfachNachrichten page', () => { logInParts(forbiddenUrl); visitUrl(forbiddenUrl); + waitForSpinnerToDisappear(); notExist(postfachMailPage.getBreadcrump()); + }) + + it('should show snackbar', () => { + exist(snackbar.getCloseButton()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); - }); + }) }) describe('on user kordner', () => { @@ -73,13 +79,14 @@ describe('PostfachNachrichten filtered by organisationseinheit', () => { before(() => { loginAsKordner(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) it('should open postfachNachrichten page', () => { logInParts(authorizedUrl); visitUrl(authorizedUrl); + waitForSpinnerToDisappear(); exist(postfachMailPage.getBreadcrump()) }) @@ -87,8 +94,13 @@ describe('PostfachNachrichten filtered by organisationseinheit', () => { it('should not open postfachNachrichten page', () => { logInParts(forbiddenUrl); visitUrl(forbiddenUrl); + waitForSpinnerToDisappear(); notExist(postfachMailPage.getBreadcrump()) + }) + + it('should show snackbar', () => { + exist(snackbar.getCloseButton()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.e2e-spec.ts index 417dc74f6409c2f42e5a22065a58d22e8fc141bc..1722f12188e52d052cb1b1c26e78a851e38362e0 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.e2e-spec.ts @@ -46,8 +46,8 @@ describe('Postfach Nachricht should be authorized by role', () => { it(`should show vorgang in Stauts ${VorgangStatusE2E.NEU}`, () => { visitUrl(vorgangInStatusNeuUrl); - waitForSpinnerToDisappear(); + exist(postfachNachrichtPage.getRoot()); }) @@ -55,24 +55,24 @@ describe('Postfach Nachricht should be authorized by role', () => { it(`${VorgangStatusE2E.IN_BEARBEITUNG}`, () => { visitUrl(vorgangInStatusInBearbeitungUrl); - waitForSpinnerToDisappear(); + notExist(postfachNachrichtPage.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) it(`${VorgangStatusE2E.ABGESCHLOSSEN}`, () => { visitUrl(vorgangInStatusAbgeschlossenUrl); - waitForSpinnerToDisappear(); + notExist(postfachNachrichtPage.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) it(`${VorgangStatusE2E.BESCHIEDEN}`, () => { visitUrl(vorgangInStatusBeschiedenUrl); - waitForSpinnerToDisappear(); + notExist(postfachNachrichtPage.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachrichten.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachrichten.e2e-spec.ts index 52bc2268b846b11854cdda954a91b9faa0c581fe..62892150267e504f3b6d627b46481f12d7d4ad7e 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachrichten.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/postfach-mail/postfach-nachrichten.e2e-spec.ts @@ -2,7 +2,7 @@ import { CyHttpMessages } from 'cypress/types/net-stubbing'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { HttpMethodE2E } from '../../../model/util'; import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections, interceptWithResponse } from '../../../support/cypress-helper'; import { exist, notExist } from '../../../support/cypress.util'; @@ -22,6 +22,7 @@ describe('Postfach Nachrichten', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -41,6 +42,7 @@ describe('Postfach Nachrichten', () => { it('navigate to vorgangDetail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-assign-unassign.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-assign-unassign.e2e-spec.ts index 4ee3b74623b6c6d794867813a49552103d1a0c49..d7f781d43afe7f14d579ea044c81769ac0591e3e 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-assign-unassign.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-assign-unassign.e2e-spec.ts @@ -17,7 +17,7 @@ describe('User Profile im ausgewählten Vorgang', () => { const vorgangPage: VorgangPage = new VorgangPage(); const userProfileContainer: UserProfileE2EComponent = vorgangPage.getVorgangDetailHeader().getUserContainer(); - let vorgang: VorgangE2E = createVorgang(); + const vorgang: VorgangE2E = createVorgang(); const userSabine: UserE2E = getUserSabine(); const userEmil: UserE2E = getUserEmil(); @@ -26,6 +26,7 @@ describe('User Profile im ausgewählten Vorgang', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -46,6 +47,7 @@ describe('User Profile im ausgewählten Vorgang', () => { it('open vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -62,14 +64,14 @@ describe('User Profile im ausgewählten Vorgang', () => { describe('fill formular', () => { - it('should show error on enter empty field', () => { + it('should show error on enter wrong input', () => { enterWith(userProfileContainer.getSearchContainer().getInput(), 'Clark Kent'); exist(userProfileContainer.getSearchContainer().getError()); exist(userProfileContainer.getIconContainer().getUnassignedIcon()); }) - it('should show error on enter wrong input', () => { + it('should show error on enter empty field', () => { enterWith(userProfileContainer.getSearchContainer().getInput(), ''); exist(userProfileContainer.getSearchContainer().getError()); @@ -112,6 +114,7 @@ describe('User Profile im ausgewählten Vorgang', () => { it('open vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-postfach-nachricht-error.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-postfach-nachricht-error.e2e-spec.ts index 5c03ba490c7ab7982627d486f315ce28c7390554..b01f639bb481756e382349c755592a29b6edffd8 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-postfach-nachricht-error.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-postfach-nachricht-error.e2e-spec.ts @@ -36,6 +36,7 @@ describe('Postfach nachricht user profile on backend error', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -47,6 +48,7 @@ describe('Postfach nachricht user profile on backend error', () => { it('should navigate to vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); waitForSpinnerToDisappear(); @@ -62,6 +64,9 @@ describe('Postfach nachricht user profile on backend error', () => { it('should navigate back to list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); + + exist(vorgangList.getRoot()); }) }) @@ -96,6 +101,9 @@ describe('Postfach nachricht user profile on backend error', () => { it('should navigate back', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); + + exist(vorgangList.getRoot()); }) }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-vorgang-error.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-vorgang-error.e2e-spec.ts index 3270339a9c28435a401ac8ef8d962eb9ac436c33..25a62e54666685b4258417722be004b5c6be6104 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-vorgang-error.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/user-profile/user-profile-icon-in-vorgang-error.e2e-spec.ts @@ -20,13 +20,14 @@ describe('User profile assigned to vorgang', () => { const vorgangPage: VorgangPage = new VorgangPage(); const userProfileContainer: UserProfileE2EComponent = vorgangPage.getVorgangDetailHeader().getUserContainer(); - let vorgang: VorgangE2E = { ...createVorgang(), assignedTo: faker.datatype.uuid() }; + const vorgang: VorgangE2E = { ...createVorgang(), assignedTo: faker.datatype.uuid() }; before(() => { initVorgang(vorgang); loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -40,9 +41,9 @@ describe('User profile assigned to vorgang', () => { it('should navigate to vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); - waitForSpinnerToDisappear(); }) it('should show icon', () => { @@ -55,6 +56,9 @@ describe('User profile assigned to vorgang', () => { it('should navigate back', () => { vorgangPage.getSubnavigation().clickBackButton(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) }) @@ -63,8 +67,6 @@ describe('User profile assigned to vorgang', () => { const userProfile: UserProfileIconE2EComponent = vorgangList.getListItem(vorgang.name).getUserProfile().getIconContainer(); it('should show icon', () => { - waitForSpinnerToDisappear(); - exist(userProfile.getErrorResourceNotFoundIcon()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-anhang/anhang-herunterladen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-anhang/anhang-herunterladen.e2e-spec.ts index d7c477c00215beb0d6768c4e33ddcb962b8a22b1..2cd258c55c852cf1e20ad2babe891387d8fd4676 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-anhang/anhang-herunterladen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-anhang/anhang-herunterladen.e2e-spec.ts @@ -47,6 +47,7 @@ describe('Vorgang Anhänge', () => { loginAsSabine(); + waitForSpinnerToDisappear() exist(vorgangList.getRoot()); }) @@ -58,8 +59,8 @@ describe('Vorgang Anhänge', () => { it('should open vorgang detail page on click on single vorgang', () => { vorgangList.getListItem(vorgangAnhangVorhanden.name).getRoot().click(); - waitForSpinnerToDisappear(); + exist(vorgangHeader.getRoot()); }) @@ -73,23 +74,23 @@ describe('Vorgang Anhänge', () => { it('should download jpg', () => { const jpgAttachmentName: string = getJpgAttachment().name; attachmentContainer.getList().getItem(jpgAttachmentName).getRoot().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(jpgAttachmentName)); }) it('should download pdf', () => { const pdfAttachmentName: string = getPdfAttachment().name; attachmentContainer.getList().getItem(convertToDataTestId(pdfAttachmentName)).getRoot().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(pdfAttachmentName)); }) it('should navigate to vorganglist on back button', () => { subnavigation.clickBackButton(); - waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) @@ -106,8 +107,8 @@ describe('Vorgang Anhänge', () => { it('should open vorgang detail page on click on single vorgang', () => { vorgangList.getListItem(vorgangAnhangVorhanden.name).getRoot().click(); - waitForSpinnerToDisappear(); + exist(vorgangHeader.getRoot()); }) @@ -120,15 +121,15 @@ describe('Vorgang Anhänge', () => { it('should download representation', () => { attachmentContainer.getList().getItem(xmlRepresentation.name).getRoot().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(xmlRepresentation.name)); }) it('should navigate to vorganglist on back button', () => { subnavigation.clickBackButton(); - waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-abschliessen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-abschliessen.e2e-spec.ts index 418c7631cfcffa90eb7157ac5dd19b4600aba17d..ca75d37cffb640113588983e344276215320c4a9 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-abschliessen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-abschliessen.e2e-spec.ts @@ -25,6 +25,7 @@ describe('Vorgang abschliessen(EA)', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -36,6 +37,7 @@ describe('Vorgang abschliessen(EA)', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbschliessen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -48,12 +50,10 @@ describe('Vorgang abschliessen(EA)', () => { it('should show snackBar message', () => { vorgangFormularButtons.clickAbschliessenByButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN) - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN) }) it('should close snackBar', () => { @@ -68,13 +68,12 @@ describe('Vorgang abschliessen(EA)', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Abgeschlossen', () => { - waitForSpinnerToDisappear() - haveText(vorgangList.getListItem(vorgangAbschliessen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ABGESCHLOSSEN]); }) }) @@ -84,6 +83,7 @@ describe('Vorgang abschliessen(EA)', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbschliessenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -96,33 +96,33 @@ describe('Vorgang abschliessen(EA)', () => { it('should show snackBar message', () => { vorgangPage.getSubnavigation().clickAbschliessenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ABGESCHLOSSEN); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) it('should show status Beschieden', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.BESCHIEDEN]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Beschieden', () => { - waitForSpinnerToDisappear() - haveText(vorgangList.getListItem(vorgangAbschliessenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.BESCHIEDEN]) }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-annehmen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-annehmen.e2e-spec.ts index 1e5c724078e13598c0f05f24941f0f19d1d14ae6..a7d9a247a87091fb9cd52fae58269d7e5148740c 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-annehmen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-annehmen.e2e-spec.ts @@ -30,6 +30,7 @@ describe('Vorgang Annehmen', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -41,6 +42,7 @@ describe('Vorgang Annehmen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAnnehmen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -53,15 +55,13 @@ describe('Vorgang Annehmen', () => { it('should show snackBar message', () => { vorgangFormularButtons.clickAnnehmenByButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ANGENOMMEN); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ANGENOMMEN); }) - it('should close snackBar', () => { + it('should close snackBar on close', () => { snackBar.getCloseButton().click(); notExist(snackBar.getMessage()); @@ -73,13 +73,12 @@ describe('Vorgang Annehmen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Angenommen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAnnehmen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ANGENOMMEN]); }) }) @@ -89,6 +88,7 @@ describe('Vorgang Annehmen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAnnehmenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -101,33 +101,32 @@ describe('Vorgang Annehmen', () => { it('should show snackBar message', () => { vorgangPage.getSubnavigation().clickAnnehmenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ANGENOMMEN); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ANGENOMMEN); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) it('should show status Neu', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Neu', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAnnehmenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bearbeiten.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bearbeiten.e2e-spec.ts index f22f6ee8e24337c7a53373fc226e043a712481d9..c2c9639eb69124f39c53a631c445737ae8ae46ea 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bearbeiten.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bearbeiten.e2e-spec.ts @@ -25,6 +25,7 @@ describe('Vorgang bearbeiten', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -36,6 +37,7 @@ describe('Vorgang bearbeiten', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangBearbeiten.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -46,17 +48,15 @@ describe('Vorgang bearbeiten', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangBearbeiten.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangFormularButtons.clickBearbeitenByButton(); + waitForSpinnerToDisappear(); contains(snackBar.getMessage(), VorgangMessagesE2E.BEARBEITET); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); }) - it('should close snackBar', () => { + it('should close snackBar on close button', () => { snackBar.getCloseButton().click(); notExist(snackBar.getMessage()); @@ -68,13 +68,12 @@ describe('Vorgang bearbeiten', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status In Bearbeitung', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangBearbeiten.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]) }) }) @@ -84,6 +83,7 @@ describe('Vorgang bearbeiten', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangBearbeitenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -94,35 +94,35 @@ describe('Vorgang bearbeiten', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangBearbeitenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().clickBearbeitenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.BEARBEITET); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.BEARBEITET); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) it('should show status Angenommen', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ANGENOMMEN]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Angenommen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangBearbeitenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ANGENOMMEN]) }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bescheiden.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bescheiden.e2e-spec.ts index 828b30bcfc7c56016230710851d2ffbe24ba0332..8a7507dc6faf733efb7e75a92ac8ac1361919ff1 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bescheiden.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-bescheiden.e2e-spec.ts @@ -25,6 +25,7 @@ describe('Vorgang bescheiden', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -36,6 +37,7 @@ describe('Vorgang bescheiden', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangBescheiden.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -48,6 +50,7 @@ describe('Vorgang bescheiden', () => { it('should show snackBar message', () => { vorgangFormularButtons.clickBescheidenByButton(); + waitForSpinnerToDisappear(); contains(snackBar.getMessage(), VorgangMessagesE2E.BESCHIEDEN); }) @@ -68,6 +71,7 @@ describe('Vorgang bescheiden', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -84,6 +88,7 @@ describe('Vorgang bescheiden', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangBescheidenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -96,6 +101,7 @@ describe('Vorgang bescheiden', () => { it('should show snackBar message', () => { vorgangPage.getSubnavigation().clickBescheidenByIconButton(); + waitForSpinnerToDisappear(); contains(snackBar.getMessage(), VorgangMessagesE2E.BESCHIEDEN); }) @@ -104,25 +110,27 @@ describe('Vorgang bescheiden', () => { exist(snackBar.getCloseButton()); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) - it('should show status In Bearbeitung', () => { + it('should show status Angenommen', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status In Bearbeitung', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangBescheidenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht-by-role.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht-by-role.e2e-spec.ts index 149ffcb5341df253331274d1a4580f85ceaba311..142169a91e9bffd79cb63977366549996c9874b5 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht-by-role.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht-by-role.e2e-spec.ts @@ -10,7 +10,7 @@ import { AntragstellerE2EComponent } from '../../../components/vorgang/vorgang-a import { VorgangDetailHeaderE2EComponent } from '../../../components/vorgang/vorgang-detail-header.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +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'; @@ -42,6 +42,7 @@ describe('Vorgang Detailansicht by role', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -53,6 +54,7 @@ describe('Vorgang Detailansicht by role', () => { it('should show vorgang header', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangHeader.getRoot()); }) @@ -145,6 +147,7 @@ describe('Vorgang Detailansicht by role', () => { loginAsPeter(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -156,6 +159,7 @@ describe('Vorgang Detailansicht by role', () => { it('should show vorgang header', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangHeader.getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.authorize-by-role.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.authorize-by-role.e2e-spec.ts index ef4580dcb7452922d2048e243a025cfd593d4535..3a142e56dcc6d31bbf8050116cfd248c30fdd072 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.authorize-by-role.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.authorize-by-role.e2e-spec.ts @@ -41,8 +41,8 @@ describe('Vorgang Detailansicht should be authorized by role', () => { it(`should show vorgang in Stauts ${VorgangStatusE2E.NEU}`, () => { visitUrl(vorgangInStatusNeuUrl); - waitForSpinnerToDisappear(); + exist(vorgangHeader.getRoot()); }) @@ -50,24 +50,24 @@ describe('Vorgang Detailansicht should be authorized by role', () => { it(`${VorgangStatusE2E.IN_BEARBEITUNG}`, () => { visitUrl(vorgangInStatusInBearbeitungUrl); - waitForSpinnerToDisappear(); + notExist(vorgangHeader.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) it(`${VorgangStatusE2E.ABGESCHLOSSEN}`, () => { visitUrl(vorgangInStatusAbgeschlossenUrl); - waitForSpinnerToDisappear(); + notExist(vorgangHeader.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) it(`${VorgangStatusE2E.BESCHIEDEN}`, () => { visitUrl(vorgangInStatusBeschiedenUrl); - waitForSpinnerToDisappear(); + notExist(vorgangHeader.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.e2e-spec.ts index 646844ed4200896472625a8675a0e92888172e45..a4379d6f5b9cec103dea4f24bdee60d6337b3f4d 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.e2e-spec.ts @@ -7,7 +7,7 @@ import { VorgangDetailHeaderE2EComponent } from '../../../components/vorgang/vor import { VorgangFormularDatenE2EComponent } from '../../../components/vorgang/vorgang-formular.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { NO_AKTENZEICHEN, VorgangE2E, vorgangStatusLabelE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { dropCollections, reload } from '../../../support/cypress-helper'; import { contains, exist, haveText, shouldFirstContains, shouldHaveAttributeBeGreaterThan, shouldHaveAttributeBeLowerThan } from '../../../support/cypress.util'; @@ -34,6 +34,7 @@ describe('Vorgang Detailansicht', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -47,6 +48,7 @@ describe('Vorgang Detailansicht', () => { it('should show header', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangHeader.getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.filtered-by-organisationseinheit.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.filtered-by-organisationseinheit.e2e-spec.ts index cb4b967375f9dac8017e703ffd3e9c8b4826164e..0db5f5c30dcf4202691e4baf5576b27a26020e78 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.filtered-by-organisationseinheit.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-detailansicht.filtered-by-organisationseinheit.e2e-spec.ts @@ -43,20 +43,26 @@ describe('Vorgang-detailansicht filtered by organisationseinheit', () => { before(() => { loginAsKfinder(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) it('should open detailpage', () => { - visitUrl(authorizedUrl) + visitUrl(authorizedUrl); + waitForSpinnerToDisappear(); exist(detailPage.getRoot()); }) it('should not open detailpage', () => { - visitUrl(forbiddenUrl) + visitUrl(forbiddenUrl); + waitForSpinnerToDisappear(); notExist(detailPage.getRoot()); + }) + + it('should show snackbar', () => { + exist(snackbar.getCloseButton()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) }) @@ -68,48 +74,72 @@ describe('Vorgang-detailansicht filtered by organisationseinheit', () => { before(() => { loginAsKordner(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) it('should open detailpage', () => { - visitUrl(authorizedUrl) + visitUrl(authorizedUrl); + waitForSpinnerToDisappear(); exist(detailPage.getRoot()); }) it('should not open detailpage', () => { - visitUrl(forbiddenUrl) + visitUrl(forbiddenUrl); + waitForSpinnerToDisappear(); notExist(detailPage.getRoot()); + }) + + it('should show snackbar', () => { + exist(snackbar.getCloseButton()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) }) - describe('on user zonk', () => { + describe.skip('on user zonk', () => { const authorizedUrl: string = vorgangUrlVisibleToKOrdner; const forbiddenUrl: string = vorgangUrlVisibleToKFinder; before(() => { loginAsZonk(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) describe('for vorgang with assigned organisationseinheitenId', () => { it('should not open detailpage (for kordner)', () => { - visitUrl(authorizedUrl) + visitUrl(authorizedUrl); + waitForSpinnerToDisappear(); notExist(detailPage.getRoot()); + }) + + it('should show snackbar', () => { + exist(snackbar.getCloseButton()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) + it('should close snackbar on close button', () => { + //FIXME Workaround, somewhere and somehow here are appearing multiple instances of snackbar(or the button) + snackbar.getCloseButton().click({ multiple: true }); + + notExist(snackbar.getCloseButton()); + notExist(snackbar.getMessage()); + }) + it('should not open detailpage (for kfinder)', () => { - visitUrl(forbiddenUrl) + visitUrl(forbiddenUrl); + waitForSpinnerToDisappear(); notExist(detailPage.getRoot()); + }) + + it('should show snackbar', () => { + exist(snackbar.getCloseButton()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-verwerfen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-verwerfen.e2e-spec.ts index 0d15e1c5b29f7d9e1acd5d833f6e47c1b08cc3cb..406f302306caf7fba1c9e696a8e0bd8580fca210 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-verwerfen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-verwerfen.e2e-spec.ts @@ -30,6 +30,7 @@ describe('Vorgang Verwerfen', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -41,6 +42,7 @@ describe('Vorgang Verwerfen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangVerwerfen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -51,17 +53,15 @@ describe('Vorgang Verwerfen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangVerwerfen.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangFormularButtons.clickVerwerfenByButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); }) - it('should close snackBar', () => { + it('should close snackBar on close button', () => { snackbar.getCloseButton().click(); notExist(snackbar.getMessage()); @@ -78,13 +78,12 @@ describe('Vorgang Verwerfen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Verworfen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangVerwerfen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.VERWORFEN]); }) }) @@ -94,6 +93,7 @@ describe('Vorgang Verwerfen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangVerwerfenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -104,23 +104,24 @@ describe('Vorgang Verwerfen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangVerwerfenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().clickVerwerfenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.VERWORFEN); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackbar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackbar.getMessage()); }) it('should show status Neu', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) @@ -131,13 +132,12 @@ describe('Vorgang Verwerfen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Neu', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangVerwerfenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-wiedereroeffnen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-wiedereroeffnen.e2e-spec.ts index 1858838d553977c8fb374a22588823053dbdf3a2..c8f66d7b542e403c20c0bed24cc5d23042c104ab 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-wiedereroeffnen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-wiedereroeffnen.e2e-spec.ts @@ -27,6 +27,7 @@ describe('Vorgang wiedereroeffnen', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -40,6 +41,7 @@ describe('Vorgang wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangBeschiedenWiedereroeffnen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -52,15 +54,13 @@ describe('Vorgang wiedereroeffnen', () => { it('should show snackBar message', () => { vorgangFormularButtons.clickWiedereroeffnenByButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); }) - it('should close snackBar', () => { + it('should close snackBar on close', () => { snackbar.getCloseButton().click(); notExist(snackbar.getMessage()); @@ -72,13 +72,12 @@ describe('Vorgang wiedereroeffnen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status In Bearbeitung', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangBeschiedenWiedereroeffnen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) }) @@ -88,6 +87,7 @@ describe('Vorgang wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangBeschiedenWiedereroeffnenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -99,18 +99,17 @@ describe('Vorgang wiedereroeffnen', () => { it('should show snackBar message', () => { vorgangPage.getSubnavigation().clickWiedereroeffnenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackbar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackbar.getMessage()); }) it('should show status Beschieden', () => { @@ -119,13 +118,12 @@ describe('Vorgang wiedereroeffnen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Beschieden', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangBeschiedenWiedereroeffnenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.BESCHIEDEN]); }) }) @@ -138,6 +136,7 @@ describe('Vorgang wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -148,17 +147,15 @@ describe('Vorgang wiedereroeffnen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangAbgeschlossenWiedereroeffnen.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangFormularButtons.clickWiedereroeffnenByButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); }) - it('should close snackBar', () => { + it('should close snackBar on close', () => { snackbar.getCloseButton().click(); notExist(snackbar.getMessage()); @@ -170,13 +167,12 @@ describe('Vorgang wiedereroeffnen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status In Bearbeitung', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) }) @@ -186,6 +182,7 @@ describe('Vorgang wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -196,35 +193,35 @@ describe('Vorgang wiedereroeffnen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangAbgeschlossenWiedereroeffnenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().clickWiedereroeffnenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); - }) - - it('should show snackBar close button', () => { exist(snackbar.getCloseButton()); + contains(snackbar.getMessage(), VorgangMessagesE2E.WIEDEREROEFFNET); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackbar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackbar.getMessage()); }) it('should show status Abgeschlossen', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ABGESCHLOSSEN]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Abgeschlossen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangAbgeschlossenWiedereroeffnenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ABGESCHLOSSEN]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckholen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckholen.e2e-spec.ts index f22c2435761230070c1ec32e386a11d41bfeb015..65e409c051f981a604756c121cea4c0ba6377b71 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckholen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckholen.e2e-spec.ts @@ -30,6 +30,7 @@ describe('Vorgang Zurueckholen', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -41,6 +42,7 @@ describe('Vorgang Zurueckholen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangZurueckholen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -53,15 +55,13 @@ describe('Vorgang Zurueckholen', () => { it('should show snackBar message', () => { vorgangFormularButtons.getZurueckholenButton().click(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); }) - it('should close snackBar', () => { + it('should close snackBar on close button', () => { snackBar.getCloseButton().click(); notExist(snackBar.getMessage()); @@ -77,13 +77,12 @@ describe('Vorgang Zurueckholen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Neu', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangZurueckholen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.NEU]); }) }) @@ -93,6 +92,7 @@ describe('Vorgang Zurueckholen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangZurueckholenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -103,23 +103,24 @@ describe('Vorgang Zurueckholen', () => { haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[vorgangZurueckholenRevoke.status]); }) - it('should show snackBar message', () => { + it('should show snackBar', () => { vorgangPage.getSubnavigation().getZurueckholenIconButton().click(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGEHOLT); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) - it('should show status Verworfen', () => { + it('should show status Abgeschlossen', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.VERWORFEN]); }) @@ -130,13 +131,12 @@ describe('Vorgang Zurueckholen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Verworfen', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangZurueckholenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.VERWORFEN]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckstellen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckstellen.e2e-spec.ts index 5369892a4a69a2dba8d398761ecc0cda846f714a..26b97a8d3e6246618865b62106ebe903914d2fd2 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckstellen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-detailansicht/vorgang-zurueckstellen.e2e-spec.ts @@ -32,6 +32,7 @@ describe('Vorgang Zurueckstellen', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -43,6 +44,7 @@ describe('Vorgang Zurueckstellen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangZurueckstellen.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -54,19 +56,16 @@ describe('Vorgang Zurueckstellen', () => { }) it('should have assigned user(Bearbeiter)', () => { - waitForSpinnerToDisappear(); exist(userContainer.getRoot()); exist(userContainer.getIconContainer().getAssignedIcon()); }) it('should show snackBar message', () => { vorgangFormularButtons.clickZurueckstellenByButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGESTELLT); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGESTELLT); }) it('should close snackBar', () => { @@ -81,13 +80,12 @@ describe('Vorgang Zurueckstellen', () => { it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status Zurückgestellt', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangZurueckstellen.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.ANGENOMMEN]); }) }) @@ -97,6 +95,7 @@ describe('Vorgang Zurueckstellen', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgangZurueckstellenRevoke.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -109,33 +108,33 @@ describe('Vorgang Zurueckstellen', () => { it('should show snackBar message', () => { vorgangPage.getSubnavigation().clickZurueckstellenByIconButton(); + waitForSpinnerToDisappear(); - contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGESTELLT); - }) - - it('should show snackBar close button', () => { exist(snackBar.getCloseButton()); + contains(snackBar.getMessage(), VorgangMessagesE2E.ZURUECKGESTELLT); }) - it('should show progressbar', () => { + it('should close snackbar on revoke', () => { snackBar.getRevokeButton().click(); + waitForSpinnerToDisappear(); - exist(vorgangPage.getProgressBar()); + notExist(snackBar.getMessage()); }) it('should show status In Bearbeitung', () => { + notExist(vorgangPage.getProgressBar()); + haveText(vorgangPage.getVorgangDetailHeader().getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) it('back to vorgang list', () => { vorgangPage.getSubnavigation().clickBackButton(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) it('should have status In Bearbeitung', () => { - waitForSpinnerToDisappear(); - haveText(vorgangList.getListItem(vorgangZurueckstellenRevoke.name).getStatus(), vorgangStatusLabelE2E[VorgangStatusE2E.IN_BEARBEITUNG]); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list-wiedervorlage/vorgang-list-wiedervorlagen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list-wiedervorlage/vorgang-list-wiedervorlagen.e2e-spec.ts index 67c6139fd149877e2ab73d2c0d283140bacd87eb..8f4f7a8ffd29da11826f5d8d9958988c5d96c929 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list-wiedervorlage/vorgang-list-wiedervorlagen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list-wiedervorlage/vorgang-list-wiedervorlagen.e2e-spec.ts @@ -57,8 +57,8 @@ describe('VorgangList Wiedervorlagen Next Frist', () => { loginAsSabine(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.e2e-spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..f1965d99c729fabcfa424f835f127b8057e1b0cb --- /dev/null +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.e2e-spec.ts @@ -0,0 +1,92 @@ +import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; +import { EingangE2E, VorgangE2E } from '../../../model/vorgang'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; +import { dropCollections } from '../../../support/cypress-helper'; +import { exist, notExist } from '../../../support/cypress.util'; +import { ORGANISATIONSEINHEITEN_ID_FOR_KFINDER, ORGANISATIONSEINHEITEN_ID_FOR_KORDNER } from '../../../support/data.util'; +import { loginAsKfinder, loginAsKordner, loginAsRichard, loginAsZonk } from '../../../support/user-util'; +import { buildVorgang, createVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util'; + +describe('VorgangList', () => { + const mainPage: MainPage = new MainPage(); + const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); + + const eingangForKFinder: EingangE2E = { ...createVorgang().eingangs[0], zustaendigeStelle: { organisationseinheitenId: ORGANISATIONSEINHEITEN_ID_FOR_KFINDER } }; + const vorgangForKFinder: VorgangE2E = { ...buildVorgang(objectIds[0], 'VorgangVisibleToKFinder'), eingangs: [eingangForKFinder] }; + + const eingangForKOrdner: EingangE2E = { ...createVorgang().eingangs[0], zustaendigeStelle: { organisationseinheitenId: ORGANISATIONSEINHEITEN_ID_FOR_KORDNER } }; + const vorgangForKOrdner: VorgangE2E = { ...buildVorgang(objectIds[1], 'VorgangVisibleToKOrdner'), eingangs: [eingangForKOrdner] }; + + before(() => { + initVorgaenge([vorgangForKFinder, vorgangForKOrdner]); + }) + + after(() => { + dropCollections(); + }) + + describe('filtered/authorized', () => { + + describe('by user kfinder', () => { + + before(() => { + loginAsKfinder(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }) + + it('should show authorized vorgaenge', () => { + exist(vorgangList.getListItem(vorgangForKFinder.name).getRoot()); + notExist(vorgangList.getListItem(vorgangForKOrdner.name).getRoot()); + }) + }) + + describe('by user kordner', () => { + + before(() => { + loginAsKordner(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }) + + it('should show authorized vorgaenge', () => { + exist(vorgangList.getListItem(vorgangForKOrdner.name).getRoot()); + notExist(vorgangList.getListItem(vorgangForKFinder.name).getRoot()); + }) + }) + + describe('by user zonk', () => { + + const vorgang: VorgangE2E = createVorgang(); + + before(() => { + loginAsZonk(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }) + + it('should show authorized empty vorgaenge', () => { + notExist(vorgangList.getListItem(vorgangForKOrdner.name).getRoot()); + notExist(vorgangList.getListItem(vorgangForKFinder.name).getRoot()); + notExist(vorgangList.getListItem(vorgang.name).getRoot()); + }) + }) + + describe('by user richard', () => { + + before(() => { + loginAsRichard(); + + waitForSpinnerToDisappear(); + }) + + it('should show hint message while have no roles', () => { + notExist(vorgangList.getRoot()); + exist(vorgangList.getNoRoleMessage()); + }) + }) + }) +}) \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.filtered-by-organisationseinheit.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.filtered-by-organisationseinheit.e2e-spec.ts deleted file mode 100644 index a34bf37792c33edaad29827f089cda91bf558ec6..0000000000000000000000000000000000000000 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.filtered-by-organisationseinheit.e2e-spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; -import { EingangE2E, VorgangE2E } from '../../../model/vorgang'; -import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; -import { dropCollections } from '../../../support/cypress-helper'; -import { exist, notExist } from '../../../support/cypress.util'; -import { ORGANISATIONSEINHEITEN_ID_FOR_KFINDER, ORGANISATIONSEINHEITEN_ID_FOR_KORDNER } from '../../../support/data.util'; -import { loginAsKfinder, loginAsKordner, loginAsZonk } from '../../../support/user-util'; -import { buildVorgang, createVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util'; - -describe('VorgangList filtered by organisationseinheit', () => { - const mainPage: MainPage = new MainPage(); - const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); - - const eingangForKFinder: EingangE2E = { ...createVorgang().eingangs[0], zustaendigeStelle: { organisationseinheitenId: ORGANISATIONSEINHEITEN_ID_FOR_KFINDER } }; - const vorgangForKFinder: VorgangE2E = { ...buildVorgang(objectIds[0], 'VorgangVisibleToKFinder'), eingangs: [eingangForKFinder] }; - - const eingangForKOrdner: EingangE2E = { ...createVorgang().eingangs[0], zustaendigeStelle: { organisationseinheitenId: ORGANISATIONSEINHEITEN_ID_FOR_KORDNER } }; - const vorgangForKOrdner: VorgangE2E = { ...buildVorgang(objectIds[1], 'VorgangVisibleToKOrdner'), eingangs: [eingangForKOrdner] }; - - before(() => { - initVorgaenge([vorgangForKFinder, vorgangForKOrdner]); - }) - - after(() => { - dropCollections(); - }) - - describe('on user kfinder', () => { - - before(() => { - loginAsKfinder(); - - exist(vorgangList.getRoot()); - waitForSpinnerToDisappear(); - }) - - it('should check list', () => { - exist(vorgangList.getListItem(vorgangForKFinder.name).getRoot()); - notExist(vorgangList.getListItem(vorgangForKOrdner.name).getRoot()); - }) - }) - - describe('on user kordner', () => { - - before(() => { - loginAsKordner(); - - exist(vorgangList.getRoot()); - waitForSpinnerToDisappear(); - }) - - it('should check list', () => { - exist(vorgangList.getListItem(vorgangForKOrdner.name).getRoot()); - notExist(vorgangList.getListItem(vorgangForKFinder.name).getRoot()); - }) - }) - - describe('on user zonk', () => { - - const vorgang: VorgangE2E = createVorgang(); - - before(() => { - loginAsZonk(); - - exist(vorgangList.getRoot()); - waitForSpinnerToDisappear(); - }) - - it('should check list', () => { - notExist(vorgangList.getListItem(vorgangForKOrdner.name).getRoot()); - notExist(vorgangList.getListItem(vorgangForKFinder.name).getRoot()); - notExist(vorgangList.getListItem(vorgang.name).getRoot()); - }) - }) -}) \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.search.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.search.e2e-spec.ts index b6952573e714611b15933a1e6454dd4ca50bc861..1fa2c0c8f192151232620a5b18288730884f2038 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.search.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-list/vorgang-list.search.e2e-spec.ts @@ -37,8 +37,8 @@ describe('VorgangList Suche', () => { loginAsSabine(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { @@ -81,8 +81,8 @@ describe('VorgangList Suche', () => { beforeEach(() => { doSearchWith(requestId); - waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); vorgangStayInList.getRoot().click(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); @@ -133,8 +133,8 @@ describe('VorgangList Suche', () => { loginAsSabine(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { @@ -263,8 +263,8 @@ describe('VorgangList Suche', () => { loginAsSabine();; - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { @@ -281,8 +281,8 @@ describe('VorgangList Suche', () => { it('should show result by vorgang name', () => { doSearchWith(vorgangNameToMatch); - waitForSpinnerToDisappear(); + exist(byVorgangName.getRoot()); notExist(byAktenzeichen.getRoot()); notExist(byAntragstellerVorname.getRoot()); @@ -292,8 +292,8 @@ describe('VorgangList Suche', () => { it('should show result by aktenzeichen', () => { doSearchWith(aktenzeichenToMatch); - waitForSpinnerToDisappear(); + notExist(byVorgangName.getRoot()); exist(byAktenzeichen.getRoot()); notExist(byAntragstellerVorname.getRoot()); @@ -303,8 +303,8 @@ describe('VorgangList Suche', () => { it('should show result by antragsteller vorname', () => { doSearchWith(antragstellerVornameToMatch); - waitForSpinnerToDisappear(); + notExist(byVorgangName.getRoot()); notExist(byAktenzeichen.getRoot()); exist(byAntragstellerVorname.getRoot()); @@ -314,8 +314,8 @@ describe('VorgangList Suche', () => { it('should show result by antragsteller nachname', () => { doSearchWith(antragstellerNachnameToMatch); - waitForSpinnerToDisappear(); + notExist(byVorgangName.getRoot()); notExist(byAktenzeichen.getRoot()); notExist(byAntragstellerVorname.getRoot()); @@ -325,8 +325,8 @@ describe('VorgangList Suche', () => { it('should show result by requestId/eingangskennzeichen', () => { doSearchWith(requestIdToMatch); - waitForSpinnerToDisappear(); + notExist(byVorgangName.getRoot()); notExist(byAktenzeichen.getRoot()); notExist(byAntragstellerVorname.getRoot()); @@ -336,8 +336,8 @@ describe('VorgangList Suche', () => { it('search button should show search result', () => { doSearchWith(requestIdToMatch); - waitForSpinnerToDisappear(); + notExist(byVorgangName.getRoot()); }) }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang-wiedervorlage.routing.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang-wiedervorlage.routing.e2e-spec.ts index d50a8ae4105283a7041facd9ddc2ad1566b3ed1c..10106d131b9ce4651c8cce2fad6f5fd6980c0ff6 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang-wiedervorlage.routing.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang-wiedervorlage.routing.e2e-spec.ts @@ -3,7 +3,7 @@ import localeDe from '@angular/common/locales/de'; import localeDeExtra from '@angular/common/locales/extra/de'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangE2E } from '../../../model/vorgang'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { WiedervorlagePage } from '../../../page-objects/wiedervorlage.po'; import { dropCollections } from '../../../support/cypress-helper'; @@ -20,13 +20,14 @@ describe('Vorgang Detailansicht Wiedervorlage routing', () => { const vorgangPage: VorgangPage = new VorgangPage(); const wiedervorlagePage: WiedervorlagePage = new WiedervorlagePage(); - let vorgang: VorgangE2E = createVorgang(); + const vorgang: VorgangE2E = createVorgang(); before(() => { initVorgang(vorgang); loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -36,30 +37,35 @@ describe('Vorgang Detailansicht Wiedervorlage routing', () => { it('Open Vorgang-Detail-Page', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) it('click on create wiedervorlage icon button should open page', () => { vorgangPage.getSubnavigation().clickWiedervorlageIconButton(); + waitForSpinnerToDisappear(); exist(wiedervorlagePage.getSubnavigation().getRoot()); }) it('click on navigate back', () => { wiedervorlagePage.getSubnavigation().navigateBack(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) it('click on create wiedervorlage button should open page', () => { vorgangPage.getWiedervorlagenContainer().getCreateWiedervorlageButton().click(); + waitForSpinnerToDisappear(); exist(wiedervorlagePage.getSubnavigation().getRoot()); }) it('click on navigate back', () => { wiedervorlagePage.getSubnavigation().navigateBack(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang.wiedervorlage-list.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang.wiedervorlage-list.e2e-spec.ts index f4cba20491929dc51591384784419a59a350e68b..d16dae4aa356bd1e72fc8b44c6c0015966b90fe4 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang.wiedervorlage-list.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/vorgang-wiedervorlage/vorgang.wiedervorlage-list.e2e-spec.ts @@ -51,8 +51,8 @@ describe('Vorgang Wiedervorlagen List', () => { loginAsSabine(); - exist(vorgangList.getRoot()); waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); }) after(() => { @@ -61,6 +61,7 @@ describe('Vorgang Wiedervorlagen List', () => { it('navigate to vorgang detail', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.e2e-spec.ts index ba33064224e38a6e59e2c85881154acd8d54170f..72f6b9bf35d522885ace442ade1a8eb6fcf07516 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage-attachment/wiedervorlage-attachment.e2e-spec.ts @@ -46,6 +46,7 @@ describe('Wiedervorlage attachments', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -57,48 +58,57 @@ describe('Wiedervorlage attachments', () => { it('should show vorgang detail page on click on list item', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) it('should show wiedervorlage page on click on create wiedervorlage button', () => { wiedervorlageContainerInVorgang.getCreateWiedervorlageButton().click(); - waitForSpinnerToDisappear(); + exist(wiedervorlagePage.getRoot()); }) it('should show empty attachment after upload', () => { - uploadEmptyFile(attachmentContainer.getUploadInput(), TEST_FILE_WITHOUT_CONTENT) + uploadEmptyFile(attachmentContainer.getUploadInput(), TEST_FILE_WITHOUT_CONTENT); + waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); }) it('should download empty attachment on click', () => { attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(TEST_FILE_WITHOUT_CONTENT)); }) it('should show attachment with content after download', () => { uploadFile(attachmentContainer.getUploadInput(), TEST_FILE_WITH_CONTENT); + waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); }) - it('should error snackbar after upload to large file', () => { + it('should error snackbar after upload to large file', { defaultCommandTimeout: 30000 }, () => { uploadFile(attachmentContainer.getUploadInput(), TEST_FILE_WITH_CONTENT_46MB); + waitForSpinnerToDisappear(); exist(snackbar.getMessage()); contains(snackbar.getMessage(), BinaryFileSnackbarMessageE2E.ATTACHMENT_NOT_ADDED.replace('{size}', '40MB')); + }) + + it('should close snackbar on close button', () => { snackbar.getCloseButton().click(); + + notExist(snackbar.getMessage()); }) it('should download attachment on click', () => { attachmentList.getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(TEST_FILE_WITH_CONTENT)); }) @@ -126,15 +136,15 @@ describe('Wiedervorlage attachments', () => { it('should download empty attachment on click in list', () => { wiedervorlageContainerInVorgang.getWiedervorlage(wiedervorlage.betreff).getAttachmentContainer().getList().getItem(TEST_FILE_WITHOUT_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(TEST_FILE_WITHOUT_CONTENT)); }) it('should download attachment on click in list', () => { wiedervorlageContainerInVorgang.getWiedervorlage(wiedervorlage.betreff).getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click(); - waitForSpinnerToDisappear(); + exist(readFileFromDownloads(TEST_FILE_WITH_CONTENT)); }) }) @@ -145,6 +155,7 @@ describe('Wiedervorlage attachments', () => { it('should open wiedervorlage page', () => { wiedervorlageComp.getLink().click(); + waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); @@ -183,6 +194,7 @@ describe('Wiedervorlage attachments', () => { it('should not show any attachments', () => { wiedervorlageComp.getLink().click(); + waitForSpinnerToDisappear(); notExist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITHOUT_CONTENT).getRoot()); notExist(wiedervorlageComp.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getRoot()); @@ -196,18 +208,21 @@ describe('Wiedervorlage attachments', () => { it('should open wiedervorlage page', () => { wiedervorlageComp.getLink().click(); + waitForSpinnerToDisappear(); exist(attachmentList.getItem(TEST_FILE_WITH_CONTENT).getRoot()); }) it('should mark as erledigt', () => { subnavigation.erledigen(); + waitForSpinnerToDisappear(); containClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) it('should mark as open', () => { subnavigation.wiedereroeffnen(); + waitForSpinnerToDisappear(); notContainClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) @@ -218,5 +233,4 @@ describe('Wiedervorlage attachments', () => { haveLength(attachmentList.getRoot(), 1); }) }) - }) \ No newline at end of file diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage-authorize-by-role.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage-authorize-by-role.e2e-spec.ts index c30efb2c9e26b234f830b35f6b3149a2c4b16b55..12e23b39b5bd51e5ad0046acd2cbff709e41299f 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage-authorize-by-role.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage-authorize-by-role.e2e-spec.ts @@ -49,9 +49,9 @@ describe('Wiedervorlage should be authorized by role', () => { it(`should NOT show vorgang in status ${VorgangStatusE2E.NEU}`, () => { visitUrl(vorgangInStatusNeuUrl); + waitForSpinnerToDisappear(); exist(mainPage.getHeader().getTitle()); - waitForSpinnerToDisappear(); notExist(wiedervorlagePage.getRoot()); }) @@ -59,18 +59,18 @@ describe('Wiedervorlage should be authorized by role', () => { it(`${VorgangStatusE2E.IN_BEARBEITUNG}`, () => { visitUrl(vorgangInStatusInBearbeitungUrl); + waitForSpinnerToDisappear(); exist(mainPage.getHeader().getTitle()); - waitForSpinnerToDisappear(); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); notExist(wiedervorlagePage.getRoot()); }) it(`${VorgangStatusE2E.ABGESCHLOSSEN}`, () => { visitUrl(vorgangInStatusAbgeschlossenUrl); + waitForSpinnerToDisappear(); exist(mainPage.getHeader().getTitle()); - waitForSpinnerToDisappear(); notExist(wiedervorlagePage.getRoot()); notExist(wiedervorlageSubnavigation.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); @@ -78,9 +78,9 @@ describe('Wiedervorlage should be authorized by role', () => { it(`${VorgangStatusE2E.BESCHIEDEN}`, () => { visitUrl(vorgangInStatusBeschiedenUrl); + waitForSpinnerToDisappear(); exist(mainPage.getHeader().getTitle()); - waitForSpinnerToDisappear(); notExist(wiedervorlagePage.getRoot()); notExist(wiedervorlageSubnavigation.getRoot()); contains(snackbar.getMessage(), MessagesE2E.HTTP_STATUS_FORBIDDEN); diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.e2e-spec.ts index 535e28642e37b956b3256a1335a634a6bfc858fe..2d3bcaa65cdf8b7948a87549e1c4c34e4206e7c7 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.e2e-spec.ts @@ -40,6 +40,7 @@ describe('Wiedervorlage', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(vorgangList.getRoot()); }) @@ -51,6 +52,7 @@ describe('Wiedervorlage', () => { it('should show vorgang detail by click on vorgang in list', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -60,6 +62,7 @@ describe('Wiedervorlage', () => { it('should open wiedervorlage pag by click on create wiedervorlage button', () => { vorgangPage.getWiedervorlagenContainer().getCreateWiedervorlageButton().click(); + waitForSpinnerToDisappear(); exist(wiedervorlagePage.getSubnavigation().getRoot()); }) @@ -68,6 +71,7 @@ describe('Wiedervorlage', () => { wiedervorlageCotainer.getBetreff().clear().type('Ab'); wiedervorlageCotainer.getSpeichernButton().click(); + waitForSpinnerToDisappear(); exist(wiedervorlageCotainer.getBetreffError()); }) @@ -76,6 +80,7 @@ describe('Wiedervorlage', () => { wiedervorlageCotainer.getBetreff().clear().type(faker.random.alphaNumeric(41)); wiedervorlageCotainer.getSpeichernButton().click(); + waitForSpinnerToDisappear(); exist(wiedervorlageCotainer.getBetreffError()); }) @@ -85,6 +90,7 @@ describe('Wiedervorlage', () => { wiedervorlageCotainer.getFrist().clear().type('1.1.2020'); wiedervorlageCotainer.getSpeichernButton().click(); + waitForSpinnerToDisappear(); exist(wiedervorlageCotainer.getDatumError()); }) @@ -95,6 +101,7 @@ describe('Wiedervorlage', () => { wiedervorlageCotainer.getFrist().clear().type(wiedervorlageFrist); wiedervorlageCotainer.getSpeichernButton().click(); + waitForSpinnerToDisappear(); exist(snackbar.getMessage()); haveText(snackbar.getMessage(), MessagesE2E.WIEDERVORLAGE_ANGELEGT.replace('%s', wiedervorlageBetreff)); @@ -127,6 +134,7 @@ describe('Wiedervorlage', () => { it('should open Vorgang-Detail-Page on click on vorgang in list', () => { vorgangList.getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -135,6 +143,7 @@ describe('Wiedervorlage', () => { const wiedervorlageInVorgang: WiedervorlageInVorgangE2EComponent = vorgangPage.getWiedervorlagenContainer().getWiedervorlage(wiedervorlageBetreff); wiedervorlageInVorgang.getLink().click(); + waitForSpinnerToDisappear(); exist(wiedervorlagePage.getSubnavigation().getRoot()); }) @@ -151,6 +160,7 @@ describe('Wiedervorlage', () => { wiedervorlageCotainer.getFrist().clear().type(formatDateLocal(new Date(), 'dd.MM.yyyy')); wiedervorlageCotainer.getSpeichernButton().click(); + waitForSpinnerToDisappear(); exist(snackbar.getMessage()); haveText(snackbar.getMessage(), MessagesE2E.WIEDERVORLAGE_GESPEICHERT.replace('%s', 'Editierter Betreff')); diff --git a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.erledigen.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.erledigen.e2e-spec.ts index 59a41a3ddf76e6be4e5a16b5689299f960b68974..8ed26664b938399c9619e0791efafdc7d567d775 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.erledigen.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/main-tests/wiedervorlage/wiedervorlage.erledigen.e2e-spec.ts @@ -7,7 +7,7 @@ import { WiedervorlageSubnavigationE2EComponent } from '../../../components/wied import { WiedervorlagenInVorgangE2EComponent } from '../../../components/wiedervorlage/wiedervorlagen-in-vorgang.e2e.component'; import { VorgangE2E } from '../../../model/vorgang'; import { WiedervorlageE2E } from '../../../model/wiedervorlage'; -import { MainPage } from '../../../page-objects/main.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; import { VorgangPage } from '../../../page-objects/vorgang.po'; import { WiedervorlagePage } from '../../../page-objects/wiedervorlage.po'; import { dropCollections } from '../../../support/cypress-helper'; @@ -41,6 +41,7 @@ describe('Wiedervorlage erledigen/wiedereroeffnen', () => { loginAsSabine(); + waitForSpinnerToDisappear(); exist(mainPage.getVorgangList().getRoot()); }) @@ -52,6 +53,7 @@ describe('Wiedervorlage erledigen/wiedereroeffnen', () => { it('Open Vorgang-Detail-Page', () => { mainPage.getVorgangList().getListItem(vorgang.name).getRoot().click(); + waitForSpinnerToDisappear(); exist(vorgangPage.getVorgangDetailHeader().getRoot()); }) @@ -63,18 +65,21 @@ describe('Wiedervorlage erledigen/wiedereroeffnen', () => { it('should open wiedervorlage on click', () => { wiedervorlage.getLink().click(); + waitForSpinnerToDisappear(); exist(subnavigation.getRoot()); }) it('should mark as erledigt after do erledigen', () => { subnavigation.erledigen(); + waitForSpinnerToDisappear(); containClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) it('should open vorgang detail on click on back', () => { subnavigation.navigateBack(); + waitForSpinnerToDisappear(); exist(vorgangDetailHeader.getRoot()); }) @@ -86,18 +91,21 @@ describe('Wiedervorlage erledigen/wiedereroeffnen', () => { it('should open wiedervorlage on click', () => { wiedervorlage.getLink().click(); + waitForSpinnerToDisappear(); exist(subnavigation.getRoot()); }) it('should mark as open after do wiedereroeffnen', () => { subnavigation.wiedereroeffnen(); + waitForSpinnerToDisappear(); notContainClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) it('should open vorgang detail on click on back', () => { subnavigation.navigateBack(); + waitForSpinnerToDisappear(); exist(vorgangDetailHeader.getRoot()); }) @@ -109,30 +117,35 @@ describe('Wiedervorlage erledigen/wiedereroeffnen', () => { it('should open wiedervorlage on click', () => { wiedervorlage.getLink().click(); + waitForSpinnerToDisappear(); exist(subnavigation.getRoot()); }) it('should mark as erledigt', () => { subnavigation.erledigen(); + waitForSpinnerToDisappear(); containClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) it('should mark as open', () => { subnavigation.wiedereroeffnen(); + waitForSpinnerToDisappear(); notContainClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) it('should mark as erledigt', () => { subnavigation.erledigen(); + waitForSpinnerToDisappear(); containClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) it('should mark as open', () => { subnavigation.wiedereroeffnen(); + waitForSpinnerToDisappear(); notContainClass(wiedervorlageContainer.getStatusDot(), 'erledigt'); }) diff --git a/goofy-client/apps/goofy-e2e/src/support/user-util.ts b/goofy-client/apps/goofy-e2e/src/support/user-util.ts index 8c205092db57422b6353aeef62a68bb03a41e614..148d262be6246794a3a93ed8b67b489f3f20c97f 100644 --- a/goofy-client/apps/goofy-e2e/src/support/user-util.ts +++ b/goofy-client/apps/goofy-e2e/src/support/user-util.ts @@ -21,6 +21,7 @@ enum DatabaseUser { KFINDER = 'user/user_kfinder.json', KORDNER = 'user/user_kordner.json', PETER = 'user/user_peter.json', + RICHARD = 'user/user_richard.json', SABINE = 'user/user_sabine.json', ZONK = 'user/user_zonk.json' } @@ -41,6 +42,10 @@ export function loginAsPeter(): void { login(DatabaseUser.PETER); } +export function loginAsRichard(): void { + login(DatabaseUser.RICHARD); +} + export function loginAsSabine(): void { login(DatabaseUser.SABINE); } diff --git a/goofy-client/apps/goofy/src/styles/abstracts/_variables.scss b/goofy-client/apps/goofy/src/styles/abstracts/_variables.scss index 89fc0e3b6c753a8f96b78f11004fe86ce9892805..25c38013e2a41900e131a44781410d0a7947294c 100644 --- a/goofy-client/apps/goofy/src/styles/abstracts/_variables.scss +++ b/goofy-client/apps/goofy/src/styles/abstracts/_variables.scss @@ -1,6 +1,7 @@ @use '@angular/material' as mat; $grey: #777; +$greyLight: rgba(0, 0, 0, 0.08); $background: #fafafa; $dark-background: #303030; diff --git a/goofy-client/libs/command-shared/src/lib/command.util.spec.ts b/goofy-client/libs/command-shared/src/lib/command.util.spec.ts index 1002d550218dfdc411faa7c542ed7b750b090e6e..432fb515888fcf6969ad36da92f7413eba1b08c7 100644 --- a/goofy-client/libs/command-shared/src/lib/command.util.spec.ts +++ b/goofy-client/libs/command-shared/src/lib/command.util.spec.ts @@ -65,25 +65,35 @@ describe('CommandUtil', () => { }) }) - describe('getPendingForwardCommand', () => { + describe('getPendingCommandByOrder', () => { const order: string = 'dummyOrder'; + const anotherOrder: string = 'anotherOrder'; it('should return null on non existing pending command', () => { const listResource: CommandListResource = createCommandListResource(); - const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, order); + const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, [order]); expect(pendingCommand).toBeNull(); }) - it('should return existing pending command', () => { - const pendingForwardCommand: CommandResource = { ...createCommandResource(), order }; - const listResource: CommandListResource = createCommandListResource([pendingForwardCommand]); + it('should return existing pending command on single order', () => { + const command: CommandResource = { ...createCommandResource(), order }; + const listResource: CommandListResource = createCommandListResource([command]); - const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, order); + const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, [order]); - expect(pendingCommand).toBe(pendingForwardCommand); + expect(pendingCommand).toBe(command); + }) + + it('should return existing pending command on multiple orders', () => { + const command: CommandResource = { ...createCommandResource(), order: anotherOrder }; + const listResource: CommandListResource = createCommandListResource([command]); + + const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, [order, anotherOrder]); + + expect(pendingCommand).toBe(command); }) }) }) \ No newline at end of file diff --git a/goofy-client/libs/command-shared/src/lib/command.util.ts b/goofy-client/libs/command-shared/src/lib/command.util.ts index 9dcbd90775befb85c776dc61492d959bdbd6423e..059d50eb855e30a32b0a9347d67662eefff8cd28 100644 --- a/goofy-client/libs/command-shared/src/lib/command.util.ts +++ b/goofy-client/libs/command-shared/src/lib/command.util.ts @@ -27,8 +27,8 @@ export function getEmbeddedCommandResources(commandListResource: CommandListReso return getEmbeddedResource<CommandResource[]>(commandListResource, CommandListLinkRel.COMMAND_LIST); } -export function getPendingCommandByOrder(pendingCommands: CommandListResource, commandOrder: any): CommandResource { - var commands: CommandResource[] = getEmbeddedCommandResources(pendingCommands).filter(command => command.order == commandOrder); +export function getPendingCommandByOrder(pendingCommands: CommandListResource, commandOrder: any[]): CommandResource { + var commands: CommandResource[] = getEmbeddedCommandResources(pendingCommands).filter(command => commandOrder.includes(command.order)); return commands.length > 0 ? commands[0] : null; } diff --git a/goofy-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar.formservice.ts b/goofy-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar.formservice.ts index e348fc3066c57679a84f5def9ef4bfc30db95e96..da289d23b08b39fc784ab6f47c0b1f9752a2b35e 100644 --- a/goofy-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar.formservice.ts +++ b/goofy-client/libs/kommentar/src/lib/kommentar-list-in-vorgang-container/kommentar-form/kommentar.formservice.ts @@ -8,7 +8,8 @@ import { Observable } from "rxjs"; export class KommentarFormService extends AbstractFormService { static readonly TEXT = 'text'; - static readonly FIELD_PATH_PREFIX = 'command.body'; + + static readonly FIELD_PATH_PREFIX = 'kommentar'; constructor(formBuilder: FormBuilder, private kommentarService: KommentarService) { super(formBuilder); diff --git a/goofy-client/libs/postfach-shared/src/lib/postfach.model.ts b/goofy-client/libs/postfach-shared/src/lib/postfach.model.ts index ac93192a7a4aeee007690262a9026467b5bbe414..16b14da973576f667d55f47b6a9e35ac31e94115 100644 --- a/goofy-client/libs/postfach-shared/src/lib/postfach.model.ts +++ b/goofy-client/libs/postfach-shared/src/lib/postfach.model.ts @@ -27,7 +27,7 @@ export enum ReplyOption { } export enum PostfachOrder { - SEND_POSTFACH_MAIL = 'SEND_POSTFACH_MAIL', + SEND_POSTFACH_NACHRICHT = 'SEND_POSTFACH_NACHRICHT', RESEND_POSTFACH_MAIL = 'RESEND_POSTFACH_MAIL' } diff --git a/goofy-client/libs/postfach-shared/src/lib/postfach.util.spec.ts b/goofy-client/libs/postfach-shared/src/lib/postfach.util.spec.ts index 8c4013d38bbb218b4ac52b3acf0852db3f6c9e59..4048bf842743adee9370e896f611b9a6ee26d910 100644 --- a/goofy-client/libs/postfach-shared/src/lib/postfach.util.spec.ts +++ b/goofy-client/libs/postfach-shared/src/lib/postfach.util.spec.ts @@ -13,7 +13,7 @@ describe('PostfachUtil', () => { it('should have order', () => { const command: CreatePostfachMailCommand = createSendPostfachMailCommand(postfachMail); - expect(command.order).toEqual(PostfachOrder.SEND_POSTFACH_MAIL); + expect(command.order).toEqual(PostfachOrder.SEND_POSTFACH_NACHRICHT); }) it('should have body', () => { diff --git a/goofy-client/libs/postfach-shared/src/lib/postfach.util.ts b/goofy-client/libs/postfach-shared/src/lib/postfach.util.ts index 45f7d021e76e5c50148c2dc47bedd0105038b428..42cb6bb5a63ffdc9360a5f51dd2aa1da444864d3 100644 --- a/goofy-client/libs/postfach-shared/src/lib/postfach.util.ts +++ b/goofy-client/libs/postfach-shared/src/lib/postfach.util.ts @@ -2,7 +2,7 @@ import { postfachNachrichtMessageCodeMessages } from './postfach.message-code'; import { CreatePostfachMailCommand, Direction, PostfachMail, PostfachMailResource, PostfachOrder } from './postfach.model'; export function createSendPostfachMailCommand(postfachMail: PostfachMail): CreatePostfachMailCommand { - return { order: PostfachOrder.SEND_POSTFACH_MAIL, body: postfachMail }; + return { order: PostfachOrder.SEND_POSTFACH_NACHRICHT, body: postfachMail }; } export function createResendPostfachMailCommand(): CreatePostfachMailCommand { diff --git a/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.ts b/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.ts index 8cd7157f628cb0c91d3e3009fb262dc4bd0c73ac..55b8c1f3d00ef72549b45be78b186d524de16f37 100644 --- a/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.ts +++ b/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.ts @@ -25,7 +25,7 @@ export class PostfachMailFormComponent implements OnInit { { type: ReplyOption.POSSIBLE, icon: 'reply', text: 'Antworten erlauben' }, { type: ReplyOption.FORBIDDEN, svgIcon: 'no_reply', text: 'Antworten unterbinden' } ]; - readonly defaultEnumItem: EnumEditorItem = { type: ReplyOption.FORBIDDEN, svgIcon: 'no_reply', text: 'Antworten unterbinden' }; + readonly defaultEnumItem: EnumEditorItem = { type: ReplyOption.POSSIBLE, icon: 'reply', text: 'Antworten erlauben' }; readonly postfachMailListLinkRel = PostfachMailListLinkRel; postfachMailListStateResource$: Observable<StateResource<PostfachMailListResource>>; diff --git a/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail.formservice.ts b/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail.formservice.ts index 9b7ee3c6f7673acf84deedf8b0ba9798fd272938..f5bbb8df2a044cee6e8df73803f18ed1a69d406d 100644 --- a/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail.formservice.ts +++ b/goofy-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail.formservice.ts @@ -24,7 +24,7 @@ export class PostfachMailFormservice extends AbstractFormService { return this.formBuilder.group({ [PostfachMailFormservice.FIELD_SUBJECT]: new FormControl(), [PostfachMailFormservice.FIELD_MAIL_BODY]: new FormControl(), - [PostfachMailFormservice.FIELD_REPLY_OPTION]: new FormControl(ReplyOption.FORBIDDEN), + [PostfachMailFormservice.FIELD_REPLY_OPTION]: new FormControl(ReplyOption.POSSIBLE), [PostfachMailFormservice.FIELD_ATTACHMENTS]: new FormArray([]), }) } diff --git a/goofy-client/libs/tech-shared/src/index.ts b/goofy-client/libs/tech-shared/src/index.ts index b607f46b67b53b24bfee67f8af75735ed9d821f2..7e0f749f00c0b9bc0c3f6c8895db70bec44535fb 100644 --- a/goofy-client/libs/tech-shared/src/index.ts +++ b/goofy-client/libs/tech-shared/src/index.ts @@ -11,6 +11,7 @@ export * from './lib/pipe/file-size.pipe'; export * from './lib/pipe/format-date-with-time.pipe'; export * from './lib/pipe/format-to-pretty-date.pipe'; export * from './lib/pipe/has-link.pipe'; +export * from './lib/pipe/not-has-link.pipe'; export * from './lib/pipe/to-embedded-resource.pipe'; export * from './lib/pipe/to-resource-uri.pipe'; export * from './lib/pipe/to-traffic-light-tooltip.pipe'; diff --git a/goofy-client/libs/tech-shared/src/lib/date.util.ts b/goofy-client/libs/tech-shared/src/lib/date.util.ts index 34d851251eaec52cbde18e46e63422f794d800ce..76550d07955305c27650f38cb9708a055ab50a2f 100644 --- a/goofy-client/libs/tech-shared/src/lib/date.util.ts +++ b/goofy-client/libs/tech-shared/src/lib/date.util.ts @@ -25,7 +25,6 @@ export function formatWithoutYear(date: Date): string { } export function formatToPrettyDate(date: Date): string { - // TODO date sollte schon beim Laden aus dem BE in Date umgewandelt werden date = isValid(date) ? date : parseISO(date as unknown as string); if (isSameYear(new Date(), date)) { diff --git a/goofy-client/libs/tech-shared/src/lib/pipe/not-has-link.pipe.spec.ts b/goofy-client/libs/tech-shared/src/lib/pipe/not-has-link.pipe.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c7517c2753666e5651cbfae1fcfa477f60780b86 --- /dev/null +++ b/goofy-client/libs/tech-shared/src/lib/pipe/not-has-link.pipe.spec.ts @@ -0,0 +1,21 @@ +import { Resource } from '@ngxp/rest'; +import { createDummyResource } from 'libs/tech-shared/test/resource'; +import { NotHasLinkPipe } from './not-has-link.pipe'; + +describe('NotHasLinkPipe', () => { + const selfLink: string = 'self'; + const dummyLink: string = 'dummy'; + const resource: Resource = createDummyResource([selfLink]); + const pipe: NotHasLinkPipe = new NotHasLinkPipe(); + + it('resource has link', () => { + const result: boolean = pipe.transform(resource, selfLink); + + expect(result).toBe(false); + }) + it('resource doesnt has link', () => { + const result: boolean = pipe.transform(resource, dummyLink); + + expect(result).toBe(true); + }) +}) diff --git a/goofy-client/libs/tech-shared/src/lib/pipe/not-has-link.pipe.ts b/goofy-client/libs/tech-shared/src/lib/pipe/not-has-link.pipe.ts new file mode 100644 index 0000000000000000000000000000000000000000..d68f0417cea19776db39a12a21129d85b0f11269 --- /dev/null +++ b/goofy-client/libs/tech-shared/src/lib/pipe/not-has-link.pipe.ts @@ -0,0 +1,9 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { hasLink, Resource } from '@ngxp/rest'; + +@Pipe({ name: 'notHasLink' }) +export class NotHasLinkPipe implements PipeTransform { + transform(resource: Resource, link: string) { + return !hasLink(resource, link); + } +} diff --git a/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light-tooltip.pipe.ts b/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light-tooltip.pipe.ts index 6f95e71f9fe63f452890536ddc592303dee58798..b3b318031e8d0dc9021e1a1296a0074dfd3c5c8c 100644 --- a/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light-tooltip.pipe.ts +++ b/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light-tooltip.pipe.ts @@ -4,7 +4,6 @@ import { isPast, isToday, isValid, parseISO } from 'date-fns'; @Pipe({ name: 'toTrafficLightTooltip' }) export class ToTrafficLightTooltipPipe implements PipeTransform { transform(date: Date): string { - // TODO date sollte schon beim Laden aus dem BE in Date umgewandelt werden date = isValid(date) ? date : parseISO(date as unknown as string); if (isToday(date)) return 'Die Frist endet Heute'; diff --git a/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light.pipe.ts b/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light.pipe.ts index 3c459c2d4b669ec55ec359f41967d8a97306809c..59cb494d28730be92499f7f08fb5e3dc4e19fd04 100644 --- a/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light.pipe.ts +++ b/goofy-client/libs/tech-shared/src/lib/pipe/to-traffic-light.pipe.ts @@ -4,7 +4,6 @@ import { isPast, isToday, isValid, parseISO } from 'date-fns'; @Pipe({ name: 'toTrafficLight' }) export class ToTrafficLightPipe implements PipeTransform { transform(date: Date): string { - // TODO date sollte schon beim Laden aus dem BE in Date umgewandelt werden date = isValid(date) ? date : parseISO(date as unknown as string); if (isToday(date)) return 'yellow'; diff --git a/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts b/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts index 2ed55173a712884078afff7af605bde8623913b7..67328c81f7d110f528ba7d4282651a251f6ddf24 100644 --- a/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts +++ b/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts @@ -8,6 +8,7 @@ import { FileSizePipe } from './pipe/file-size.pipe'; import { FormatDateWithTimePipe } from './pipe/format-date-with-time.pipe'; import { FormatToPrettyDatePipe } from './pipe/format-to-pretty-date.pipe'; import { HasLinkPipe } from './pipe/has-link.pipe'; +import { NotHasLinkPipe } from './pipe/not-has-link.pipe'; import { ToEmbeddedResourcesPipe } from './pipe/to-embedded-resource.pipe'; import { ToResourceUriPipe } from './pipe/to-resource-uri.pipe'; import { ToTrafficLightTooltipPipe } from './pipe/to-traffic-light-tooltip.pipe'; @@ -20,6 +21,7 @@ import { ToTrafficLightPipe } from './pipe/to-traffic-light.pipe'; EnumToLabelPipe, FormatDateWithTimePipe, HasLinkPipe, + NotHasLinkPipe, ToResourceUriPipe, ToTrafficLightPipe, ToTrafficLightTooltipPipe, @@ -32,6 +34,7 @@ import { ToTrafficLightPipe } from './pipe/to-traffic-light.pipe'; EnumToLabelPipe, FormatDateWithTimePipe, HasLinkPipe, + NotHasLinkPipe, ToResourceUriPipe, ToTrafficLightPipe, ToTrafficLightTooltipPipe, diff --git a/goofy-client/libs/test-utils/src/lib/helper.ts b/goofy-client/libs/test-utils/src/lib/helper.ts index e16d3029e0f10ca2d8a5602bc54d52a835d69c9e..94887c81370ac5a428485249e842ddc34158afdd 100644 --- a/goofy-client/libs/test-utils/src/lib/helper.ts +++ b/goofy-client/libs/test-utils/src/lib/helper.ts @@ -10,15 +10,15 @@ function getDebugElementFromFixtureByType<T>(fixture: ComponentFixture<any>, com return fixture.debugElement.query(By.directive(component)); } -export function getDebugElementFromFixtureByCss(fixture: ComponentFixture<any>, query: string): DebugElement { - return fixture.debugElement.query(By.css(query)); -} - export function getElementFromFixture(fixture: ComponentFixture<any>, htmlElement: string): any { return fixture.nativeElement.querySelector(htmlElement); } export function dispatchEventFromFixture(fixture: ComponentFixture<any>, elementSelector: string, event: string): void { - const element = fixture.debugElement.query(By.css(elementSelector)); + const element = getDebugElementFromFixtureByCss(fixture, elementSelector) element.nativeElement.dispatchEvent(new Event(event)); } + +export function getDebugElementFromFixtureByCss(fixture: ComponentFixture<any>, query: string): DebugElement { + return fixture.debugElement.query(By.css(query)); +} \ No newline at end of file diff --git a/goofy-client/libs/ui/src/lib/font/_font_material.scss b/goofy-client/libs/ui/src/lib/font/_font_material.scss index 7dcfb14e0a747b3f22f4f2f655fe7d3aed275528..97fc1a60760d3cca1e0686d55ab48450dfd061ed 100644 --- a/goofy-client/libs/ui/src/lib/font/_font_material.scss +++ b/goofy-client/libs/ui/src/lib/font/_font_material.scss @@ -1,13 +1,13 @@ // Kopiert von https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined @font-face { - font-family: 'Material Icons', sans-serif; + font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2) format('woff2'); } @font-face { - font-family: 'Material Icons Outlined', sans-serif; + font-family: 'Material Icons Outlined'; font-style: normal; font-weight: 400; src: url(gok-H7zzDkdnRel8-DQ6KAXJ69wP1tGnf4ZGhUcel5euIg.woff2) format('woff2'); diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.html b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.html new file mode 100644 index 0000000000000000000000000000000000000000..312d42ddadb72b90bf3559e644f3f8601a9a4955 --- /dev/null +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.html @@ -0,0 +1,3 @@ +<button mat-icon-button (click)="close.emit()" data-test-id="snackbar-close-button"> + <mat-icon data-test-class="icon">clear</mat-icon> +</button> \ No newline at end of file diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.scss b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..5e2fce20b698f7394eacec58ae3fbd517862d2ee --- /dev/null +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.scss @@ -0,0 +1,50 @@ +@use 'sass:map'; +@use '@angular/material' as mat; +@import 'variables'; + +.message { + white-space: pre-wrap +} + +::ng-deep .mat-snack-bar-container.error { + min-width: 240px; + max-width: 90vw; + + border: 3px solid mat.get-color-from-palette($warnPalette); + background-color: lighten(mat.get-color-from-palette($warnPalette), 38%); + color: rgba(#000, 0.89); + position: relative; + + &:before { + position: absolute; + content: url("/assets/icons/error_outline_white.svg"); + display: block; + background-color: mat.get-color-from-palette($warnPalette); + left: 0; + top: 0; + padding: 11px 9px 11px 7px; + color: #fff; + height: 100%; + } + + > div { + margin-left: 44px; + } +} + +.wrapper { + display: flex; + align-items: center; +} + +.mat-button { + color: mat.get-color-from-palette($primaryPalette, lighter); +} + +button { + margin: -12px -8px -12px 8px +} + +::ng-deep body.dark .mat-snack-bar-container .mat-button { + color: mat.get-color-from-palette($primaryPalette); +} diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.spec.ts b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..4a419ae9594946ac9edc382392cddd4bc5b1f47d --- /dev/null +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.spec.ts @@ -0,0 +1,39 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatIcon } from '@angular/material/icon'; +import { dispatchEventFromFixture, mock } from '@goofy-client/test-utils'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { EventEmitter } from 'stream'; +import { SnackbarCloseButtonComponent } from './snackbar-close-button.component'; + +describe('SnackbarCloseButtonComponent', () => { + let component: SnackbarCloseButtonComponent; + let fixture: ComponentFixture<SnackbarCloseButtonComponent>; + + const closeButton: string = getDataTestIdOf('snackbar-close-button'); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + MatIcon, + SnackbarCloseButtonComponent + ] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SnackbarCloseButtonComponent); + component = fixture.componentInstance; + component.close = { ...<any>mock(EventEmitter), emit: jest.fn() }; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('click should emit action', () => { + dispatchEventFromFixture(fixture, closeButton, 'click'); + + expect(component.close.emit).toHaveBeenCalled(); + }) +}); diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.ts b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..5c900fda5a90fde396aec8b66322c6e0fc2c28e9 --- /dev/null +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-close-button/snackbar-close-button.component.ts @@ -0,0 +1,11 @@ +import { Component, EventEmitter, Output } from '@angular/core'; + +@Component({ + selector: 'goofy-client-snackbar-close-button', + templateUrl: './snackbar-close-button.component.html', + styleUrls: ['./snackbar-close-button.component.scss'] +}) +export class SnackbarCloseButtonComponent { + + @Output() close: EventEmitter<void> = new EventEmitter(); +} diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.html b/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.html index c8c31801c567d84bb3da0905aaaf804bd5d15e57..1c87bdc69fac21eb254ec3b12845f862e50bb6cb 100644 --- a/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.html +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.html @@ -1,7 +1,5 @@ <div class="wrapper"> <span data-test-id="snackbar-message" class="message">{{ message }}</span> - <button mat-icon-button (click)="close()" data-test-id="snackbar-close-button"> - <mat-icon data-test-class="icon">clear</mat-icon> - </button> + <goofy-client-snackbar-close-button (close)="close()"></goofy-client-snackbar-close-button> </div> diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.spec.ts b/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.spec.ts index d0ead57221621e13aac4de1e9df89518b681e003..452e8208aff9c3aa5f9510af797dc2719f4b807b 100644 --- a/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.spec.ts +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-error/snackbar-error.component.spec.ts @@ -3,6 +3,8 @@ import { MatIconModule } from '@angular/material/icon'; import { MatSnackBarRef, MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar'; import { mock } from '@goofy-client/test-utils'; import { SnackBarData } from '@goofy-client/ui'; +import { MockComponent } from 'ng-mocks'; +import { SnackbarCloseButtonComponent } from '../snackbar-close-button/snackbar-close-button.component'; import { SnackbarErrorComponent } from './snackbar-error.component'; describe('SnackbarErrorComponent', () => { @@ -18,7 +20,8 @@ describe('SnackbarErrorComponent', () => { MatIconModule ], declarations: [ - SnackbarErrorComponent + SnackbarErrorComponent, + MockComponent(SnackbarCloseButtonComponent) ], providers: [ { @@ -42,4 +45,12 @@ describe('SnackbarErrorComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('close button', () => { + it('should close the snackbar', () => { + component.close(); + + expect(snackBarRef.dismiss).toHaveBeenCalled(); + }) + }) }); diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.html b/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.html index 5aefe84d96b0c8698f29084a2a58becac9a9a507..dae817d661748914e85446df69190ca1c0d3d6a2 100644 --- a/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.html +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.html @@ -7,6 +7,4 @@ Rückgängig </button> -<button mat-icon-button (click)="close()" data-test-id="snackbar-close-button"> - <mat-icon data-test-class="icon">clear</mat-icon> -</button> \ No newline at end of file +<goofy-client-snackbar-close-button (close)="close()"></goofy-client-snackbar-close-button> \ No newline at end of file diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.spec.ts b/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.spec.ts index 7e295a2c20d40831dc026a57ae107af79a6af03d..cd8a3825c547c18f2ffb7f83f8efeec7754c7b65 100644 --- a/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.spec.ts +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar-info/snackbar-info.component.spec.ts @@ -4,6 +4,9 @@ import { MatSnackBarModule, MatSnackBarRef, MAT_SNACK_BAR_DATA } from '@angular/ import { mock } from '@goofy-client/test-utils'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; import { createCommandResource } from 'libs/command-shared/test/command'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { MockComponent } from 'ng-mocks'; +import { SnackbarCloseButtonComponent } from '../snackbar-close-button/snackbar-close-button.component'; import { SnackBarData } from '../snackbar.service'; import { SnackbarInfoComponent } from './snackbar-info.component'; @@ -14,7 +17,7 @@ describe('SnackbarInfoComponent', () => { const snackBarData: SnackBarData = { message: 'Message', commandResource: createCommandResource() }; const snackBarRef = { ...mock(MatSnackBarRef), dissmis: jest.fn(), dismissWithAction: jest.fn() }; - const revokeButton: string = '[data-test-id="snackbar-revoke-button"]'; + const revokeButton: string = getDataTestIdOf('snackbar-revoke-button'); beforeEach(async () => { await TestBed.configureTestingModule({ @@ -22,7 +25,10 @@ describe('SnackbarInfoComponent', () => { MatSnackBarModule, MatIconModule ], - declarations: [SnackbarInfoComponent], + declarations: [ + SnackbarInfoComponent, + MockComponent(SnackbarCloseButtonComponent) + ], providers: [ { provide: MAT_SNACK_BAR_DATA, @@ -46,7 +52,7 @@ describe('SnackbarInfoComponent', () => { expect(component).toBeTruthy(); }); - describe('clear button', () => { + describe('close button', () => { it('should close the snackbar', () => { component.close(); diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.spec.ts b/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.spec.ts index 29774c23c1fc4365593a112e30c3f871977cc930..9ae931738e196b19d43fd0158c48cc82ed5d2213 100644 --- a/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.spec.ts +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.spec.ts @@ -21,8 +21,8 @@ describe('SnackBarService', () => { beforeEach(async () => { await TestBed.configureTestingModule({ providers: [ - { provide: MatSnackBar, useValue: mockMatSnackBar }, - ], + { provide: MatSnackBar, useValue: mockMatSnackBar }, + ], }).compileComponents(); service = TestBed.inject(SnackBarService); matSnackBar = TestBed.inject(MatSnackBar); @@ -37,6 +37,13 @@ describe('SnackBarService', () => { beforeEach(() => { service.listenOnRevokeAction = jest.fn(); service.listenOnAfterDismissed = jest.fn(); + service.closeSnackBarIfVisible = jest.fn(); + }) + + it('should close snackbar if exists', () => { + service.show(commandResource, message); + + expect(service.closeSnackBarIfVisible).toHaveBeenCalled(); }) it('should open from component', () => { @@ -73,8 +80,16 @@ describe('SnackBarService', () => { beforeEach(() => { service.listenOnAfterDismissed = jest.fn(); + service.closeSnackBarIfVisible = jest.fn(); }) + it('should close snackbar if exists', () => { + service.showError(message); + + expect(service.closeSnackBarIfVisible).toHaveBeenCalled(); + }) + + it('should open from component', () => { service.showError(message); @@ -89,4 +104,27 @@ describe('SnackBarService', () => { expect(service.listenOnAfterDismissed).toHaveBeenCalled(); }) }) + + describe('close snackbar if visible', () => { + + beforeEach(() => { + service.closeSnackBar = jest.fn(); + }) + + it('should dismiss snack bar if ref exists ', () => { + service.snackBarRef = <any>{}; + + service.closeSnackBarIfVisible(); + + expect(service.closeSnackBar).toHaveBeenCalled(); + }) + + it('should do nothing if ref not exists ', () => { + service.snackBarRef = undefined; + + service.closeSnackBarIfVisible(); + + expect(service.closeSnackBar).not.toHaveBeenCalled(); + }) + }) }) diff --git a/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.ts b/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.ts index 6921eaba96738d7df1a2049512b7a93917ee9ee6..f91d60b7cf1522da9ab8f7a954bcb8d4f51aee76 100644 --- a/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.ts +++ b/goofy-client/libs/ui/src/lib/snackbar/snackbar.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { MatSnackBar, MatSnackBarRef } from '@angular/material/snack-bar'; import { CommandResource, CommandStatus } from '@goofy-client/command-shared'; +import { isNotNil } from '@goofy-client/tech-shared'; import { isNil } from 'lodash-es'; import { Subscription } from 'rxjs'; import { SnackbarErrorComponent } from './snackbar-error/snackbar-error.component'; @@ -10,12 +11,13 @@ import { SnackbarInfoComponent } from './snackbar-info/snackbar-info.component'; export class SnackBarService { private subscription: Subscription; - private snackBarRef: MatSnackBarRef<SnackbarInfoComponent | SnackbarErrorComponent>; + snackBarRef: MatSnackBarRef<SnackbarInfoComponent | SnackbarErrorComponent>; private durationTime: number = 10000; constructor(private snackBar: MatSnackBar) { } public show(commandResource: CommandResource, message: string, revokeAction?: () => void): void { + this.closeSnackBarIfVisible(); if (commandResource.status === CommandStatus.ERROR) { this.showError(message); } else { @@ -25,10 +27,15 @@ export class SnackBarService { } public showError(message: string): void { + this.closeSnackBarIfVisible(); this.snackBarRef = this.snackBar.openFromComponent(SnackbarErrorComponent, { data: { message }, duration: this.durationTime, panelClass: 'error' }); this.listenOnAfterDismissed(); } + closeSnackBarIfVisible() { + if (isNotNil(this.snackBarRef)) this.closeSnackBar(); + } + private listenToActions(revokeAction: () => void): void { this.listenOnAfterDismissed(); this.listenOnRevokeAction(revokeAction); @@ -45,7 +52,7 @@ export class SnackBarService { this.subscription = this.snackBarRef.afterDismissed().subscribe(() => this.closeSnackBar()); } - private closeSnackBar(): void { + closeSnackBar(): void { this.snackBarRef.dismiss(); this.unsubscribe(); } diff --git a/goofy-client/libs/ui/src/lib/ui/progress-bar/progress-bar.component.html b/goofy-client/libs/ui/src/lib/ui/progress-bar/progress-bar.component.html index a55d8825a0d7c2ed79a65982b3f2ff5c4cf82981..5df4f31d06f208fdf8d4c19ba2202b046050b9ec 100644 --- a/goofy-client/libs/ui/src/lib/ui/progress-bar/progress-bar.component.html +++ b/goofy-client/libs/ui/src/lib/ui/progress-bar/progress-bar.component.html @@ -1,3 +1,3 @@ -<div class="progressbar-overlay" *ngIf="isVisible" data-test-class="progressbar-overlay"> - <mat-progress-bar mode="indeterminate"></mat-progress-bar> +<div *ngIf="isVisible" class="progressbar-overlay" data-test-class="progressbar-overlay"> + <mat-progress-bar data-test-id="progress-bar" mode="indeterminate"></mat-progress-bar> </div> diff --git a/goofy-client/libs/ui/src/lib/ui/ui.module.ts b/goofy-client/libs/ui/src/lib/ui/ui.module.ts index 06404bf99418f9d86b3ce83af7c10e3d41e756f1..c482f7fc5c5248928f8c0ac3a5b03f48d66ed7fe 100644 --- a/goofy-client/libs/ui/src/lib/ui/ui.module.ts +++ b/goofy-client/libs/ui/src/lib/ui/ui.module.ts @@ -24,6 +24,7 @@ import { TechSharedModule } from '@goofy-client/tech-shared'; import { de } from 'date-fns/locale'; import { HttpConnectionTimeoutInterceptor } from '../interceptor/http-connection-timeout.interceptor'; import { HttpErrorInterceptor } from '../interceptor/http-error.interceptor'; +import { SnackbarCloseButtonComponent } from '../snackbar/snackbar-close-button/snackbar-close-button.component'; import { SnackbarErrorComponent } from '../snackbar/snackbar-error/snackbar-error.component'; import { SnackbarInfoComponent } from '../snackbar/snackbar-info/snackbar-info.component'; import { ButtonWithSpinnerComponent } from './button-with-spinner/button-with-spinner.component'; @@ -102,6 +103,7 @@ const modules = [ InternalServerErrorDialogComponent, ConnectionTimeoutRetryDialogComponent, ConnectionTimeoutRetryFailDialogComponent, + SnackbarCloseButtonComponent ], imports: [ ...modules diff --git a/goofy-client/libs/user-profile/src/lib/link-with-user-name-tooltip-container/link-with-user-name-tooltip/link-with-user-name-tooltip.component.ts b/goofy-client/libs/user-profile/src/lib/link-with-user-name-tooltip-container/link-with-user-name-tooltip/link-with-user-name-tooltip.component.ts index ed8d4016caf59a0e2ae8be34f16607065d92456e..34bbd316cb2046e6524eb31e8ef7bd888dd6e999 100644 --- a/goofy-client/libs/user-profile/src/lib/link-with-user-name-tooltip-container/link-with-user-name-tooltip/link-with-user-name-tooltip.component.ts +++ b/goofy-client/libs/user-profile/src/lib/link-with-user-name-tooltip-container/link-with-user-name-tooltip/link-with-user-name-tooltip.component.ts @@ -15,8 +15,6 @@ export class LinkWithUserNameTooltipComponent implements OnInit { tooltip: string; - constructor() { } - ngOnInit(): void { this.tooltip = replacePlaceholders(this.tooltipTemplate, { firstName: this.userProfile.firstName, lastName: this.userProfile.lastName }); } diff --git a/goofy-client/libs/user-profile/src/lib/text-with-user-name-tooltip-container/text-with-user-name-tooltip/text-with-user-name-tooltip.component.ts b/goofy-client/libs/user-profile/src/lib/text-with-user-name-tooltip-container/text-with-user-name-tooltip/text-with-user-name-tooltip.component.ts index 12264360bf8450468ca1ef4ba0d5456841ab1643..5d48a5db547025d9bb839bc76754bc08ce3a62e1 100644 --- a/goofy-client/libs/user-profile/src/lib/text-with-user-name-tooltip-container/text-with-user-name-tooltip/text-with-user-name-tooltip.component.ts +++ b/goofy-client/libs/user-profile/src/lib/text-with-user-name-tooltip-container/text-with-user-name-tooltip/text-with-user-name-tooltip.component.ts @@ -15,8 +15,6 @@ export class TextWithUserNameTooltipComponent implements OnInit { tooltip: string; - constructor() { } - ngOnInit(): void { this.tooltip = replacePlaceholders(this.tooltipTemplate, { firstName: this.userProfile.firstName, lastName: this.userProfile.lastName }); } diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.html index 97fc42277eea4729dd3fa51424713417da6a6027..9c2459d066398fccc76b6c80b675274ab1a1951c 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.html +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.html @@ -12,17 +12,22 @@ </goofy-client-vorgang-detail-meta-data> </mat-tab> <mat-tab label="Datenrepräsentation ({{vorgangWithEingang.eingang.numberOfRepresentations}})" - [disabled]="!(vorgangWithEingang | hasLink:vorgangWithEingangLinkRel.REPRESENTATIONS)"> + [disabled]="vorgangWithEingang | notHasLink:vorgangWithEingangLinkRel.REPRESENTATIONS"> <ng-template matTabContent> <goofy-client-vorgang-detail-representation-list data-test-id="tab-representations-list" [vorgangWithEingang]="vorgangWithEingang"></goofy-client-vorgang-detail-representation-list> </ng-template> </mat-tab> <mat-tab label="Anhänge ({{vorgangWithEingang.eingang.numberOfAttachments}})" - [disabled]="!(vorgangWithEingang | hasLink:vorgangWithEingangLinkRel.ATTACHMENTS)"> + [disabled]="vorgangWithEingang | notHasLink:vorgangWithEingangLinkRel.ATTACHMENTS"> <ng-template matTabContent> <goofy-client-vorgang-detail-attachment-list data-test-id="tab-attachments-list" [vorgangWithEingang]="vorgangWithEingang"></goofy-client-vorgang-detail-attachment-list> </ng-template> </mat-tab> + <mat-tab label="Historie" *ngIf="vorgangWithEingang | hasLink:vorgangWithEingangLinkRel.HISTORIE"> + <ng-template matTabContent> + <goofy-client-vorgang-historie-container data-test-id="tab-historie-container" [vorgangWithEingang]="vorgangWithEingang"></goofy-client-vorgang-historie-container> + </ng-template> + </mat-tab> </mat-tab-group> </goofy-client-expansion-panel> diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.spec.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.spec.ts index 0511ec5727b1138a01d3327dddf91f25c386258d..a7694c5a1f8a67302f84f6cc55beb31caef24170 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.spec.ts +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-formular-daten/vorgang-detail-formular-daten.component.spec.ts @@ -1,9 +1,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatTabsModule } from '@angular/material/tabs'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { HasLinkPipe } from '@goofy-client/tech-shared'; +import { HasLinkPipe, NotHasLinkPipe } from '@goofy-client/tech-shared'; import { getElementFromFixture } from '@goofy-client/test-utils'; import { ExpansionPanelComponent } from '@goofy-client/ui'; +import { VorgangHistorieContainerComponent } from '@goofy-client/vorgang-historie'; import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; @@ -20,10 +21,12 @@ describe('VorgangDetailFormularDatenComponent', () => { const tabMetaData: string = 'div[role=tab]:nth-child(2)'; const tabRepresentations: string = 'div[role=tab]:nth-child(3)'; const tabAttachments: string = 'div[role=tab]:nth-child(4)'; + const tabHistorie: string = 'div[role=tab]:nth-child(5)'; const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource(); const vorgangWithAttachments: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.ATTACHMENTS]); const vorgangWithRepresentations: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.REPRESENTATIONS]); + const vorgangWithHistorie: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.HISTORIE]); beforeEach(async () => { await TestBed.configureTestingModule({ @@ -33,12 +36,14 @@ describe('VorgangDetailFormularDatenComponent', () => { ], declarations: [ HasLinkPipe, + NotHasLinkPipe, VorgangDetailFormularDatenComponent, MockComponent(VorgangDetailAntragDataComponent), MockComponent(VorgangDetailMetaDataComponent), MockComponent(VorgangDetailAttachmentListComponent), MockComponent(VorgangDetailRepresentationListComponent), MockComponent(ExpansionPanelComponent), + MockComponent(VorgangHistorieContainerComponent), ] }).compileComponents(); }); @@ -139,4 +144,24 @@ describe('VorgangDetailFormularDatenComponent', () => { }) }) + describe('Tab Historie', () => { + it('should be visible if Link "historie" exists', () => { + component.vorgangWithEingang = vorgangWithHistorie; + + fixture.detectChanges(); + const tab = getElementFromFixture(fixture, tabHistorie); + + expect(tab).toBeInTheDocument(); + }) + + it('should not be visible if no Link "historie"', () => { + component.vorgangWithEingang = vorgang; + + fixture.detectChanges(); + const tab = getElementFromFixture(fixture, tabHistorie); + + expect(tab).not.toBeInTheDocument(); + }) + }) + }); diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.html index 5e8ecaaa94dbfd9a031161240945412b77654320..d019a1ac5866afe7234426fd7c62d8f530898a10 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.html +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-page.component.html @@ -11,4 +11,4 @@ </ng-container> -<goofy-client-progress-bar data-test-id="progress-bar" [stateResource]="revokeCommandStateResource$ | async"></goofy-client-progress-bar> \ No newline at end of file +<goofy-client-progress-bar [stateResource]="revokeCommandStateResource$ | async"></goofy-client-progress-bar> \ No newline at end of file diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts index 4ea2a3fedfb8a38e50c2c0c1879bac72b8f830f6..fbb58cedeb0551ee16dbdaee75859f158ae3b8e6 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts @@ -10,6 +10,7 @@ import { TechSharedModule } from '@goofy-client/tech-shared'; import { UiModule } from '@goofy-client/ui'; import { UserProfileModule } from '@goofy-client/user-profile'; import { UserProfileSharedModule } from '@goofy-client/user-profile-shared'; +import { VorgangHistorieModule } from '@goofy-client/vorgang-historie'; import { VorgangSharedModule } from '@goofy-client/vorgang-shared'; import { VorgangSharedUiModule } from '@goofy-client/vorgang-shared-ui'; import { WiedervorlageModule } from '@goofy-client/wiedervorlage'; @@ -59,7 +60,8 @@ const routes: Routes = [ UserProfileModule, UserProfileSharedModule, PostfachSharedModule, - PostfachModule + PostfachModule, + VorgangHistorieModule ], declarations: [ VorgangDetailPageComponent, diff --git a/goofy-client/libs/vorgang-historie/.eslintrc.json b/goofy-client/libs/vorgang-historie/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..28f19b630511beab4ad3ff61ffce5a45f7430728 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nrwl/nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "goofyClient", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "goofy-client", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/goofy-client/libs/vorgang-historie/README.md b/goofy-client/libs/vorgang-historie/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0412a90d25be161803edbe2751e3635c48dcbc31 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/README.md @@ -0,0 +1,7 @@ +# vorgang-historie + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test vorgang-historie` to execute the unit tests. diff --git a/goofy-client/libs/vorgang-historie/jest.config.js b/goofy-client/libs/vorgang-historie/jest.config.js new file mode 100644 index 0000000000000000000000000000000000000000..707cb488ad0a8db33a85c90c2fab768d9ecac3f5 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/jest.config.js @@ -0,0 +1,21 @@ +module.exports = { + displayName: 'vorgang-historie', + preset: '../../jest.preset.js', + setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '<rootDir>/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + }, + coverageDirectory: '../../coverage/libs/vorgang-historie', + transform: { + '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular', + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/goofy-client/libs/vorgang-historie/src/index.ts b/goofy-client/libs/vorgang-historie/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..41a6b1400e8baf95216e1d8593b45b0b8faff17d --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/vorgang-historie.module'; + +export * from './lib/vorgang-historie-container/vorgang-historie-container.component'; diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.html b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..429eccc43389cd64517c4b3bb1998f2ba7ca5037 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.html @@ -0,0 +1 @@ +<goofy-client-vorgang-historie-list data-test-id="tab-historie-list-container" [vorgangWithEingang]="vorgangWithEingang"></goofy-client-vorgang-historie-list> \ No newline at end of file diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.scss b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.spec.ts b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..5fbc53485f39ab439b2bcff922b89ce61a04f872 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { VorgangHistorieContainerComponent } from './vorgang-historie-container.component'; + +describe('VorgangHistorieContainerComponent', () => { + let component: VorgangHistorieContainerComponent; + let fixture: ComponentFixture<VorgangHistorieContainerComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [VorgangHistorieContainerComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(VorgangHistorieContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.ts b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..7da65f22da2b3028a257b27b3826bfa7154d4461 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-container.component.ts @@ -0,0 +1,13 @@ +import { Component, Input } from '@angular/core'; +import { VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; + +@Component({ + selector: 'goofy-client-vorgang-historie-container', + templateUrl: './vorgang-historie-container.component.html', + styleUrls: ['./vorgang-historie-container.component.scss'], +}) +export class VorgangHistorieContainerComponent { + + @Input() vorgangWithEingang: VorgangWithEingangResource; + +} diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.html b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.html new file mode 100644 index 0000000000000000000000000000000000000000..4ffbccbc10733efb76f1ecaf553a57a727d43d2f --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.html @@ -0,0 +1,3 @@ +<ul> + <li data-test-id="created-at">Der Vorgang wurde am {{ vorgangWithEingang.createdAt | formatDateWithTimePipe:false }} erstellt.</li> +</ul> \ No newline at end of file diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.scss b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..72a25c5cf822d4d8165725a12287832f6269080d --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.scss @@ -0,0 +1,12 @@ +@import "variables"; + +ul { + margin-top: 0; + padding-left: 0; + width: 100%; + + li { + border-bottom: 1px solid $greyLight; + padding: 0.75rem 0; + } +} \ No newline at end of file diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.spec.ts b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..1908346811cd19a353c854de26805f98f5ad4073 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.spec.ts @@ -0,0 +1,48 @@ +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormatDateWithTimePipe } from '@goofy-client/tech-shared'; +import { getElementFromFixture } from '@goofy-client/test-utils'; +import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; +import { VorgangHistorieListComponent } from './vorgang-historie-list.component'; + +registerLocaleData(localeDe); + +describe('VorgangHistorieListComponent', () => { + let component: VorgangHistorieListComponent; + let fixture: ComponentFixture<VorgangHistorieListComponent>; + + const vorgangWithHistorie: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.HISTORIE]); + const createdAtElement: string = getDataTestIdOf('created-at'); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + FormatDateWithTimePipe, + VorgangHistorieListComponent + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(VorgangHistorieListComponent); + component = fixture.componentInstance; + component.vorgangWithEingang = vorgangWithHistorie; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('on vorgang', () => { + + it('should have Historie list', () => { + const element = getElementFromFixture(fixture, createdAtElement); + + expect(element).toBeInstanceOf(HTMLLIElement); + }); + }); +}); diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.ts b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..bd015726a6fe0a1979b9fdd5d83bff0d87d72670 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component.ts @@ -0,0 +1,13 @@ +import { Component, Input } from '@angular/core'; +import { VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; + +@Component({ + selector: 'goofy-client-vorgang-historie-list', + templateUrl: './vorgang-historie-list.component.html', + styleUrls: ['./vorgang-historie-list.component.scss'], +}) +export class VorgangHistorieListComponent { + + @Input() vorgangWithEingang: VorgangWithEingangResource; + +} diff --git a/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie.module.ts b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..41f06719072483d05854a282803e6dc699e8f779 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/lib/vorgang-historie.module.ts @@ -0,0 +1,20 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { TechSharedModule } from '@goofy-client/tech-shared'; +import { VorgangHistorieContainerComponent } from './vorgang-historie-container/vorgang-historie-container.component'; +import { VorgangHistorieListComponent } from './vorgang-historie-container/vorgang-historie-list/vorgang-historie-list.component'; + +@NgModule({ + imports: [ + CommonModule, + TechSharedModule + ], + declarations: [ + VorgangHistorieContainerComponent, + VorgangHistorieListComponent, + ], + exports: [ + VorgangHistorieContainerComponent, + ], +}) +export class VorgangHistorieModule {} diff --git a/goofy-client/libs/vorgang-historie/src/test-setup.ts b/goofy-client/libs/vorgang-historie/src/test-setup.ts new file mode 100644 index 0000000000000000000000000000000000000000..1100b3e8a6ed08f4b5c27a96471846d57023c320 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/goofy-client/libs/vorgang-historie/tsconfig.json b/goofy-client/libs/vorgang-historie/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..518abe89089dd06c8c6430da3f5f7c9105c10cd2 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/goofy-client/libs/vorgang-historie/tsconfig.lib.json b/goofy-client/libs/vorgang-historie/tsconfig.lib.json new file mode 100644 index 0000000000000000000000000000000000000000..a2a53880f8274e73d8c264e347047cbd8c1f1cf8 --- /dev/null +++ b/goofy-client/libs/vorgang-historie/tsconfig.lib.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"], + "include": ["**/*.ts"] +} diff --git a/goofy-client/libs/vorgang-historie/tsconfig.spec.json b/goofy-client/libs/vorgang-historie/tsconfig.spec.json new file mode 100644 index 0000000000000000000000000000000000000000..ff36e0edd33bbc39279480063c3c8e62e8be27ef --- /dev/null +++ b/goofy-client/libs/vorgang-historie/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts index aa3c06d5f237beb44245203e769956ba7a26d298..0f7f646640c7cff4edebda7b522e51b1c286e786 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.linkrel.ts @@ -28,4 +28,5 @@ export enum VorgangWithEingangLinkRel { PENDING_COMMANDS = 'pending-commands', ASSIGN = 'assign', REPRESENTATIONS = 'representations', + HISTORIE = 'historie', } \ No newline at end of file diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts index dc1f216f7bb4c5205dd12f7e9f7bd843e6656c73..05b8cef25a4727432d96f3806e1f22e4a999e6dc 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts @@ -85,7 +85,7 @@ export class VorgangService { setPendingForwardCommand(pendingCommandList: CommandListResource): void { if (!this.pendingForwardCommand$.value.loaded) { - this.setPendingForwardSingleCommand(createStateResource(getPendingCommandByOrder(pendingCommandList, VorgangOrder.FORWARD))); + this.setPendingForwardSingleCommand(createStateResource(getPendingCommandByOrder(pendingCommandList, [VorgangOrder.FORWARD]))); } } @@ -95,7 +95,7 @@ export class VorgangService { handlePendingSendPostfachMailCommand(pendingCommandList: CommandListResource): void { if (!this.pendingSendPostfachMailCommand$.value.loaded) { - this.setPendingSendPostfachMailCommand(createStateResource(getPendingCommandByOrder(pendingCommandList, PostfachOrder.SEND_POSTFACH_MAIL))); + this.setPendingSendPostfachMailCommand(createStateResource(getPendingCommandByOrder(pendingCommandList, [PostfachOrder.SEND_POSTFACH_NACHRICHT]))); } } diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.html b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..c244b2559d54624b7c16b7a010ecbef0eddeaa41 --- /dev/null +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.html @@ -0,0 +1 @@ +<goofy-client-vorgang-list-page [apiRootStateResource]="apiRootStateResource$ | async"></goofy-client-vorgang-list-page> \ No newline at end of file diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.scss b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.spec.ts b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..5151bc413161b0ac0029b4efdcb2be2eca0928b8 --- /dev/null +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.spec.ts @@ -0,0 +1,45 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ApiRootService } from '@goofy-client/api-root-shared'; +import { mock } from '@goofy-client/test-utils'; +import { MockComponent } from 'ng-mocks'; +import { VorgangListPageComponent } from '../vorgang-list-page/vorgang-list-page.component'; +import { VorgangListPageContainerComponent } from './vorgang-list-page-container.component'; + +describe('VorgangListPageContainerComponent', () => { + let component: VorgangListPageContainerComponent; + let fixture: ComponentFixture<VorgangListPageContainerComponent>; + + const apiRootService = mock(ApiRootService); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + VorgangListPageContainerComponent, + MockComponent(VorgangListPageComponent) + ], + providers: [{ + provide: ApiRootService, + useValue: apiRootService + }] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(VorgangListPageContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('onInit', () => { + + it('should call apiRootService', () => { + component.ngOnInit(); + + expect(apiRootService.getApiRoot).toHaveBeenCalled(); + }) + }) +}); diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.ts b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ecc0ea6837efe767b36e46c08a73ee662d041fc1 --- /dev/null +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page-container/vorgang-list-page-container.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; +import { ApiRootResource, ApiRootService } from '@goofy-client/api-root-shared'; +import { StateResource } from '@goofy-client/tech-shared'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'goofy-client-vorgang-list-page-container', + templateUrl: './vorgang-list-page-container.component.html', + styleUrls: ['./vorgang-list-page-container.component.scss'], +}) +export class VorgangListPageContainerComponent implements OnInit { + + apiRootStateResource$: Observable<StateResource<ApiRootResource>>; + + constructor(private apiRootService: ApiRootService) { } + + ngOnInit(): void { + this.apiRootStateResource$ = this.apiRootService.getApiRoot(); + } +} \ No newline at end of file diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.html b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.html index 2bf1a8ddb3fa9fe14514a55299a3034ef1045f33..bafd229827f85b6d530d8b78e524e068ddfccd90 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.html +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.html @@ -1,2 +1,6 @@ <goofy-client-subnavigation class="mat-app-background"></goofy-client-subnavigation> -<goofy-client-vorgang-list-container></goofy-client-vorgang-list-container> + +<goofy-client-vorgang-list-container *ngIf="apiRootStateResource?.resource | hasLink: apiRootLinkRel.VORGAENGE; else showNoRoleMessage" data-test-id="vorgaenge-list"></goofy-client-vorgang-list-container> +<ng-template #showNoRoleMessage> + <h1 data-test-id="user-no-role-message">Die Allgemeine Fachanwendung ist wegen fehlender Rollen nicht benutzbar.</h1> +</ng-template> \ No newline at end of file diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.scss b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.scss index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1f8ba303033ec012306500158c50e3a082bc3ab0 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.scss +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.scss @@ -0,0 +1,13 @@ +@import "variables"; + +h1 { + text-align: center; + margin: 0; + padding: 1rem; +} + +:host-context(.dark) { + h1 { + background-color: $dark-background; + } +} diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.spec.ts b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.spec.ts index 1548673e95fbf1a263d7a20160f9ff5403b8ec56..95184f30ba5b5314c55717c5969569c6bb2af316 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.spec.ts +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.spec.ts @@ -1,18 +1,28 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { VorgangListPageComponent } from './vorgang-list-page.component'; -import { MockComponent } from 'ng-mocks'; -import { SubnavigationComponent } from 'libs/ui/src/lib/ui/subnavigation/subnavigation.component'; +import { ApiRootLinkRel } from '@goofy-client/api-root-shared'; +import { createEmptyStateResource, createStateResource, HasLinkPipe } from '@goofy-client/tech-shared'; +import { getElementFromFixture } from '@goofy-client/test-utils'; +import { SpinnerComponent } from '@goofy-client/ui'; import { VorgangListContainerComponent } from '@goofy-client/vorgang'; +import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; +import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; +import { SubnavigationComponent } from 'libs/ui/src/lib/ui/subnavigation/subnavigation.component'; +import { MockComponent } from 'ng-mocks'; +import { VorgangListPageComponent } from './vorgang-list-page.component'; describe('VorgangListPageComponent', () => { let component: VorgangListPageComponent; let fixture: ComponentFixture<VorgangListPageComponent>; + const userMessage: string = getDataTestIdOf('user-no-role-message'); + const vorgaengeList: string = getDataTestIdOf('vorgaenge-list'); + beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ VorgangListPageComponent, + HasLinkPipe, + MockComponent(SpinnerComponent), MockComponent(SubnavigationComponent), MockComponent(VorgangListContainerComponent) ] @@ -23,10 +33,32 @@ describe('VorgangListPageComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(VorgangListPageComponent); component = fixture.componentInstance; + component.apiRootStateResource = createEmptyStateResource(); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + describe('page', () => { + + it('should show vorgaenge if link exists', () => { + component.apiRootStateResource = createStateResource(createApiRootResource([ApiRootLinkRel.VORGAENGE])); + fixture.detectChanges(); + + const element = getElementFromFixture(fixture, vorgaengeList); + + expect(element).toBeInstanceOf(HTMLElement); + }) + + it('should show hint message if link not exists', () => { + component.apiRootStateResource = createStateResource(createApiRootResource()); + fixture.detectChanges(); + + const element = getElementFromFixture(fixture, userMessage); + + expect(element).toBeInstanceOf(HTMLElement); + }) + }) }); diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.ts b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.ts index 1f16539089f801cd3d44329020eb290556386ad0..cfe7072d4a20ee7601805bac22084ed1dd197ec2 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.ts +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-page/vorgang-list-page.component.ts @@ -1,8 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; +import { ApiRootLinkRel, ApiRootResource } from '@goofy-client/api-root-shared'; +import { StateResource } from '@goofy-client/tech-shared'; +//TODO unter vorgang-list-page-container schieben @Component({ selector: 'goofy-client-vorgang-list-page', templateUrl: './vorgang-list-page.component.html', styleUrls: ['./vorgang-list-page.component.scss'] }) -export class VorgangListPageComponent { } +export class VorgangListPageComponent { + + @Input() apiRootStateResource: StateResource<ApiRootResource>; + + readonly apiRootLinkRel = ApiRootLinkRel; +} \ No newline at end of file diff --git a/goofy-client/libs/vorgang/src/lib/vorgang.module.ts b/goofy-client/libs/vorgang/src/lib/vorgang.module.ts index c300d818a54cdef72982b58b86d7278425a3f905..b9587df7dfb040efd4e874db0a8253fa217109ac 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang.module.ts +++ b/goofy-client/libs/vorgang/src/lib/vorgang.module.ts @@ -13,29 +13,30 @@ import { EmptyListComponent } from './vorgang-list-container/vorgang-list/empty- import { VorgangListItemComponent } from './vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component'; import { VorgangNextFristButton } from './vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-next-frist-button/vorgang-next-frist-button.component'; import { VorgangListComponent } from './vorgang-list-container/vorgang-list/vorgang-list.component'; +import { VorgangListPageContainerComponent } from './vorgang-list-page-container/vorgang-list-page-container.component'; import { VorgangListPageComponent } from './vorgang-list-page/vorgang-list-page.component'; const routes: Routes = [ { path: '', - component: VorgangListPageComponent + component: VorgangListPageContainerComponent, }, { path: 'search/:search', - component: VorgangListPageComponent + component: VorgangListPageContainerComponent, }, { path: 'myVorgaenge', - component: VorgangListPageComponent + component: VorgangListPageContainerComponent, }, { path: 'myVorgaenge/search/:search', - component: VorgangListPageComponent + component: VorgangListPageContainerComponent, }, { path: 'vorgang/:vorgangWithEingangUrl', - loadChildren: () => import('@goofy-client/vorgang-detail').then(m => m.VorgangDetailModule) - } + loadChildren: () => import('@goofy-client/vorgang-detail').then(m => m.VorgangDetailModule), + }, ]; @NgModule({ @@ -48,7 +49,7 @@ const routes: Routes = [ VorgangSharedModule, WiedervorlageModule, VorgangSharedUiModule, - UserProfileModule + UserProfileModule, ], declarations: [ VorgangListComponent, @@ -56,7 +57,8 @@ const routes: Routes = [ VorgangListContainerComponent, VorgangListPageComponent, EmptyListComponent, - VorgangNextFristButton - ] + VorgangNextFristButton, + VorgangListPageContainerComponent + ], }) export class VorgangModule { } diff --git a/goofy-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice.ts b/goofy-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice.ts index 57ab3de2f31a77602503da3fcf7d9b7412890279..5ab808bee6238f93a364ee6ed49803d0cc9b1de3 100644 --- a/goofy-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice.ts +++ b/goofy-client/libs/wiedervorlage/src/lib/wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice.ts @@ -12,7 +12,7 @@ export class WiedervorlageFormService extends AbstractFormService { static readonly FIELD_FRIST = 'frist'; static readonly FIELD_ATTACHMENTS = 'attachments'; - static readonly FIELD_PATH_PREFIX = 'command.body'; + static readonly FIELD_PATH_PREFIX = 'wiedervorlage'; constructor( formBuilder: FormBuilder, diff --git a/goofy-client/pom.xml b/goofy-client/pom.xml index d15e3eeb0414f326b8c9706fae66c062a8599b56..faad162ec16c487a9fbecefeff21c89a4683b9fa 100644 --- a/goofy-client/pom.xml +++ b/goofy-client/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>de.itvsh.ozg</groupId> <artifactId>goofy</artifactId> - <version>0.26.0-SNAPSHOT</version> + <version>0.27.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/goofy-client/tsconfig.base.json b/goofy-client/tsconfig.base.json index b68afb258404cae674d402b8eb66078fa7beab24..b077313028be1be67cf372d6f755f0cf1e126102 100644 --- a/goofy-client/tsconfig.base.json +++ b/goofy-client/tsconfig.base.json @@ -54,6 +54,9 @@ "@goofy-client/vorgang-detail": [ "libs/vorgang-detail/src/index.ts" ], + "@goofy-client/vorgang-historie": [ + "libs/vorgang-historie/src/index.ts" + ], "@goofy-client/vorgang-shared": [ "libs/vorgang-shared/src/index.ts" ], diff --git a/goofy-server/pom.xml b/goofy-server/pom.xml index df7eac60260003e0a8035c7a0d4d09cf33e850cd..00c500a456dd955aad006695ea5f4d62b6e2f2b5 100644 --- a/goofy-server/pom.xml +++ b/goofy-server/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>de.itvsh.ozg</groupId> <artifactId>goofy</artifactId> - <version>0.26.0-SNAPSHOT</version> + <version>0.27.0-SNAPSHOT</version> </parent> <artifactId>goofy-server</artifactId> diff --git a/goofy-server/src/main/java/de/itvsh/goofy/JwtTokenUtil.java b/goofy-server/src/main/java/de/itvsh/goofy/JwtTokenUtil.java index 35ff2b41ccd56e82d7f8a2875b075e34d57f9a1f..834e157f26cbfa4bfcdf3bbd369548651447062f 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/JwtTokenUtil.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/JwtTokenUtil.java @@ -1,6 +1,7 @@ package de.itvsh.goofy; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -31,9 +32,11 @@ public class JwtTokenUtil { public static final String TOKEN_ISSUER = "secure-api"; public static final String TOKEN_AUDIENCE = "secure-app"; public static final String ROLE_CLAIM = "roles"; + public static final String USERID_CLAIM = "userId"; public static final String FIRSTNAME_CLAIM = "firstName"; public static final String LASTNAME_CLAIM = "lastName"; public static final String FILEID_CLAIM = "fileId"; + public static final String ORGANSIATIONSEINHEIT_IDS_CLAIM = "organisationseinheitIds"; @Autowired private DownloadTokenProperties downloadTokenProperties; @@ -72,12 +75,26 @@ public class JwtTokenUtil { .toList(); } + @SuppressWarnings({ "unchecked" }) + public Collection<String> getOrganisationseinheitIdsFromToken(String token) { + List<String> organisationseinheitIds = new ArrayList<>(); + getAllClaimsFromToken(token) + .ifPresent(claims -> { + if (claims.get(ORGANSIATIONSEINHEIT_IDS_CLAIM) != null) { + organisationseinheitIds.addAll((Collection<String>) claims.get(ORGANSIATIONSEINHEIT_IDS_CLAIM)); + } + }); + return organisationseinheitIds; + } + public String generateToken(FileId fileId, GoofyUser user) { var claims = new HashMap<String, Object>(); + claims.put(USERID_CLAIM, user.getId().toString()); claims.put(FIRSTNAME_CLAIM, user.getFirstName()); claims.put(LASTNAME_CLAIM, user.getLastName()); claims.put(ROLE_CLAIM, user.getAuthorities()); claims.put(FILEID_CLAIM, fileId.toString()); + claims.put(ORGANSIATIONSEINHEIT_IDS_CLAIM, user.getOrganisationseinheitIds()); return doGenerateToken(claims, user.getId().toString()); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/RootController.java b/goofy-server/src/main/java/de/itvsh/goofy/RootController.java index f931023a603f2803a7b465cfc7a6c93181f676a7..97b2c40373c78b5024cc55eb7c6b5d917240e935 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/RootController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/RootController.java @@ -18,6 +18,7 @@ import de.itvsh.goofy.common.downloadtoken.DownloadTokenController; import de.itvsh.goofy.common.user.CurrentUserService; import de.itvsh.goofy.common.user.UserId; import de.itvsh.goofy.common.user.UserProfileController; +import de.itvsh.goofy.common.user.UserRole; import de.itvsh.goofy.vorgang.VorgangController; @RestController @@ -39,16 +40,27 @@ public class RootController { @GetMapping public EntityModel<RootResource> getRootResource() { return ModelBuilder.fromEntity(new RootResource()) - .addLink(linkTo(RootController.class).withSelfRel()) - .addLink(linkTo(VorgangController.class).withRel(REL_VORGAENGE)) - .addLink(linkTo(methodOn(UserProfileController.class).findUsers(null)).withRel(REL_SEARCH_USER)) - .addLink(linkTo(DownloadTokenController.class).withRel(REL_DOWNLOAD_TOKEN)) - .addLink(buildVorgangListByPageLink(REL_SEARCH, Optional.empty())) - .addLink(buildVorgangListByPageLink(REL_MY_VORGAENGE, Optional.of(currentUserService.getUserId()))) - .addLink(buildVorgangListByPageLink(REL_SEARCH_MY_VORGAENGE, Optional.of(currentUserService.getUserId()))) + .ifMatch(this::hasRole).addLinks( + linkTo(RootController.class).withSelfRel(), + linkTo(VorgangController.class).withRel(REL_VORGAENGE), + linkTo(methodOn(UserProfileController.class).findUsers(null)).withRel(REL_SEARCH_USER), + linkTo(DownloadTokenController.class).withRel(REL_DOWNLOAD_TOKEN), + buildVorgangListByPageLink(REL_SEARCH, Optional.empty())) + .ifMatch(this::hasVerwaltungRole).addLinks( + buildVorgangListByPageLink(REL_MY_VORGAENGE, Optional.of(currentUserService.getUserId())), + buildVorgangListByPageLink(REL_SEARCH_MY_VORGAENGE, Optional.of(currentUserService.getUserId()))) .buildModel(); } + boolean hasRole() { + return hasVerwaltungRole() || currentUserService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER); + } + + boolean hasVerwaltungRole() { + return currentUserService.hasRole(UserRole.VERWALTUNG_USER) + || currentUserService.hasRole(UserRole.VERWALTUNG_POSTSTELLE); + } + private Link buildVorgangListByPageLink(String linkRel, Optional<UserId> assignedTo) { return linkTo(methodOn(VorgangController.class).getVorgangListByPage(0, null, null, assignedTo)).withRel(linkRel); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItem.java b/goofy-server/src/main/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItem.java new file mode 100644 index 0000000000000000000000000000000000000000..68f99ec311c1e56478cd9bed891c5f4dd2b55955 --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItem.java @@ -0,0 +1,21 @@ +package de.itvsh.goofy.common.attacheditem; + +import java.util.Map; + +import de.itvsh.goofy.common.command.CommandBody; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class VorgangAttachedItem implements CommandBody { + + private String id; + private long version; + + private String client; + private String vorgangId; + private String itemName; + + private Map<String, Object> item; +} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemService.java new file mode 100644 index 0000000000000000000000000000000000000000..de236d619f152683cf74c467abb009421d8f143d --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemService.java @@ -0,0 +1,76 @@ +package de.itvsh.goofy.common.attacheditem; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.itvsh.goofy.common.command.Command; +import de.itvsh.goofy.common.command.CommandBody; +import de.itvsh.goofy.common.command.CommandBodyMapper; +import de.itvsh.goofy.common.command.CommandOrder; +import de.itvsh.goofy.common.command.CommandService; +import de.itvsh.goofy.common.command.CreateCommand; +import de.itvsh.goofy.kommentar.Kommentar; +import de.itvsh.goofy.wiedervorlage.Wiedervorlage; + +@Service +public class VorgangAttachedItemService { + + @Autowired + private CommandBodyMapper commandBodyMapper; + @Autowired + private CommandService commandService; + + static final String WIEDERVORLAGE_ITEM_NAME = "Wiedervorlage"; + static final String KOMMENTAR_ITEM_NAME = "Kommentar"; + + public Command createNewWiedervorlage(Wiedervorlage wiedervorlage, String vorgangId) { + var vorgangAttachedItem = buildVorgangAttachedItem(wiedervorlage, vorgangId, WIEDERVORLAGE_ITEM_NAME); + + return commandService.createCommand(buildCreateCommand(vorgangId, vorgangAttachedItem)); + } + + public Command createNewKommentar(Kommentar kommentar, String vorgangId) { + var vorgangAttachedItem = buildVorgangAttachedItem(kommentar, vorgangId, KOMMENTAR_ITEM_NAME); + + return commandService.createCommand(buildCreateCommand(vorgangId, vorgangAttachedItem)); + } + + CreateCommand buildCreateCommand(String vorgangId, CommandBody body) { + return CreateCommand.builder() + .vorgangId(vorgangId) + .relationId(vorgangId) + .order(CommandOrder.CREATE_ATTACHED_ITEM) + .body(body) + .build(); + } + + public Command editKommentar(Kommentar kommentar, String kommentarId, long kommentarVersion) { + var vorgangAttachedItem = buildVorgangAttachedItem(kommentar, kommentar.getVorgangId(), KOMMENTAR_ITEM_NAME); + + return commandService.createCommand(buildUpdateCommand(kommentar.getVorgangId(), kommentarId, vorgangAttachedItem), kommentarVersion); + } + + public Command editWiedervorlage(Wiedervorlage wiedervorlage, String wiedervorlageId, long wiedervorlageVersion) { + var vorgangAttachedItem = buildVorgangAttachedItem(wiedervorlage, wiedervorlage.getVorgangId(), WIEDERVORLAGE_ITEM_NAME); + + return commandService.createCommand(buildUpdateCommand(wiedervorlage.getVorgangId(), wiedervorlageId, vorgangAttachedItem), + wiedervorlageVersion); + } + + VorgangAttachedItem buildVorgangAttachedItem(CommandBody body, String vorgangId, String itemName) { + return VorgangAttachedItem.builder() + .vorgangId(vorgangId) + .itemName(itemName) + .item(commandBodyMapper.fromObjectToMap(body)) + .build(); + } + + CreateCommand buildUpdateCommand(String vorgangId, String kommentarId, CommandBody body) { + return CreateCommand.builder() + .vorgangId(vorgangId) + .relationId(kommentarId) + .order(CommandOrder.UPDATE_ATTACHED_ITEM) + .body(body) + .build(); + } +} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/DownloadGoofyUser.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/DownloadGoofyUser.java index 282f1b74bba6575ac710ef96318c5227484f1887..cf8d3a0506bbadc521974bad0144cd7c42bd6407 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/DownloadGoofyUser.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/DownloadGoofyUser.java @@ -10,6 +10,8 @@ import de.itvsh.goofy.common.user.GoofyUser; import lombok.Builder; import lombok.Getter; +//TODO rename this class - it es not a user, it is a user and a file id + @Builder @Getter public class DownloadGoofyUser { @@ -17,7 +19,7 @@ public class DownloadGoofyUser { private FileId fileId; - public Collection<? extends GrantedAuthority> getAuthorities() { // NOSONAR + public Collection<GrantedAuthority> getAuthorities() { return Objects.nonNull(user) ? user.getAuthorities() : List.of(); } } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/callcontext/ContextService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/callcontext/ContextService.java index 1679893f2f9dc7747c0d34900d1dd1d4b1ceca93..b80ba70fc1822726303a3e23551f91825e0758ee 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/callcontext/ContextService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/callcontext/ContextService.java @@ -14,6 +14,7 @@ import org.springframework.stereotype.Service; import de.itvsh.goofy.RequestAttributes; import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.UserRole; import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; import de.itvsh.ozg.pluto.grpc.command.GrpcUser; import io.grpc.Metadata; @@ -28,6 +29,7 @@ public class ContextService { static final String KEY_CLIENT_NAME = "CLIENT_NAME-bin"; static final String KEY_REQUEST_ID = "REQUEST_ID-bin"; static final String KEY_ACCESS_LIMITED_ORGAID = "ACCESS_LIMITED_TO_ORGANISATORISCHEEINHEITENID-bin"; + static final String KEY_ACCESS_LIMITED = "ACCESS_LIMITED-bin"; @Autowired private ApplicationContext context; @@ -54,6 +56,7 @@ public class ContextService { .build(); } + // TODO pruefen, ob die noch gebraucht wird public Map<String, Object> getContextMap() { var user = userService.getUser(); return Map.of( @@ -76,10 +79,18 @@ public class ContextService { .ifPresentOrElse(bytes -> metadata.put(createKeyOf(KEY_CLIENT_NAME), bytes), () -> LOG.warn("Missing value 'client name'")); user.getOrganisationseinheitIds().stream().map(String::getBytes) .forEach(bytes -> metadata.put(createKeyOf(KEY_ACCESS_LIMITED_ORGAID), bytes)); + metadata.put(createKeyOf(KEY_ACCESS_LIMITED), isOrganisationEinheitenIdCheckNecessary()); return metadata; } + private byte[] isOrganisationEinheitenIdCheckNecessary() { + var hasRoleWithNoCheckNecessary = userService.hasRole(UserRole.VERWALTUNG_POSTSTELLE) + || userService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER); + + return Boolean.toString(!hasRoleWithNoCheckNecessary).getBytes(); + } + private String formatListAsCommaSeperatedString(Collection<String> organisatorischeEinheitenIds) { return organisatorischeEinheitenIds.stream().collect(Collectors.joining(",")); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/Command.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/Command.java index a24fc7535ceea1e0e5030a168e18206df6087e6f..661d146cb6ca8ac8fbaf027243d780e8b0b4e61a 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/Command.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/Command.java @@ -40,5 +40,5 @@ public class Command { private RedirectRequest redirectRequest; - private Map<String, String> body; + private Map<String, ?> body; } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java index f8e2c4cf1f1bde9745c1a9bac2a2caf4b595777e..c1d7d2c1f5b225bba75aaa7b6a7b9a1d123634dc 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBody.java @@ -11,6 +11,7 @@ import de.itvsh.goofy.wiedervorlage.Wiedervorlage; @JsonSubTypes({ @Type(value = PostfachMail.class, name = "SEND_POSTFACH_MAIL"), + @Type(value = PostfachMail.class, name = "SEND_POSTFACH_NACHRICHT"), @Type(value = AssignUserCommandBody.class, name = "ASSIGN_USER"), @Type(value = RedirectRequest.class, name = "REDIRECT_VORGANG"), @Type(value = Wiedervorlage.class, name = "WIEDERVORLAGE"), diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBodyMapper.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBodyMapper.java index 18477d9d1fc068ab8472d07c7f04fefd525e8292..094c88df95e860744c2764df2e87820823ca155d 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBodyMapper.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandBodyMapper.java @@ -1,12 +1,17 @@ package de.itvsh.goofy.common.command; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Collectors; import org.apache.commons.beanutils.BeanMap; +import org.apache.commons.lang3.StringUtils; import org.mapstruct.Mapper; import de.itvsh.ozg.pluto.grpc.command.GrpcCommandBody; @@ -15,13 +20,17 @@ import de.itvsh.ozg.pluto.grpc.command.GrpcCommandBodyField; @Mapper public interface CommandBodyMapper { + final Predicate<Entry<Object, Object>> IS_NOT_CLASS_VALUE = entry -> !StringUtils.equals("class", entry.getKey().toString()); + final Predicate<Entry<Object, Object>> IS_NOT_VERSION_VALUE = entry -> !StringUtils.equals("version", entry.getKey().toString()); + static final String VORGANG_ID_PROPERTY = "vorgangId"; static final String ITEM_NAME_PROPERTY = "itemName"; static final String ITEM_PROPERTY = "item"; default GrpcCommandBody mapToBody(Map<String, String> bodyMap) { - if (Objects.isNull(bodyMap)) + if (Objects.isNull(bodyMap)) { return GrpcCommandBody.getDefaultInstance(); + } var builder = GrpcCommandBody.newBuilder(); @@ -34,22 +43,37 @@ public interface CommandBodyMapper { } default List<GrpcCommandBodyField> mapToBodyFields(CommandBody body) { - if (Objects.isNull(body)) + if (Objects.isNull(body)) { return Collections.emptyList(); + } return mapToBodyFields(new BeanMap(body)); } default List<GrpcCommandBodyField> mapToBodyFields(Map<Object, Object> bodyMap) { - if (Objects.isNull(bodyMap)) + if (Objects.isNull(bodyMap)) { return Collections.emptyList(); + } return bodyMap.entrySet().stream() - .filter(entry -> Objects.nonNull(entry.getValue())) - .map(entry -> GrpcCommandBodyField.newBuilder().setName(entry.getKey().toString()).setValue(entry.getValue().toString()).build()) + .filter(IS_NOT_CLASS_VALUE) + .map(this::buildBodyField) .collect(Collectors.toList()); } + default GrpcCommandBodyField buildBodyField(Entry<Object, Object> entry) { + var bodyFieldMapper = GrpcCommandBodyField.newBuilder().setName(entry.getKey().toString()); + + if (Objects.nonNull(entry.getValue())) { + bodyFieldMapper.setValue(getNullableStringValue(entry.getValue())); + } + return bodyFieldMapper.build(); + } + + default String getNullableStringValue(Object entryValue) { + return Optional.ofNullable(entryValue).map(Object::toString).orElse(null); + } + default Map<String, String> map(GrpcCommandBody body) { return body.getFieldList().stream().collect(Collectors.toMap(GrpcCommandBodyField::getName, GrpcCommandBodyField::getValue)); } @@ -58,6 +82,20 @@ public interface CommandBodyMapper { return Map.of( VORGANG_ID_PROPERTY, command.getVorgangId(), ITEM_NAME_PROPERTY, itemName, - ITEM_PROPERTY, new BeanMap(command.getBody())); + ITEM_PROPERTY, fromObjectToMap(command.getBody())); + } + + default Map<String, Object> fromObjectToMap(Object object) { + return new BeanMap(object).entrySet().stream() + .filter(IS_NOT_CLASS_VALUE) + .filter(IS_NOT_VERSION_VALUE) + .collect(HashMap::new, (map, entry) -> map.put(entry.getKey().toString(), checkEnumValue(entry.getValue())), Map::putAll); + } + + private Object checkEnumValue(Object entryValue) { + if (entryValue instanceof Enum<?> enumValue) { + return enumValue.name(); + } + return entryValue; } } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandController.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandController.java index 000c055d46c2c7fd56371fc63a03a617b70260ac..ad32f9c4794525c36f50f6d5ab79d82d3de45e99 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandController.java @@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.postfach.PostfachMail; -import de.itvsh.goofy.postfach.PostfachMailController; import de.itvsh.goofy.vorgang.VorgangController; import de.itvsh.goofy.vorgang.VorgangWithEingang; import lombok.Getter; @@ -74,47 +74,40 @@ public class CommandController { private CommandService service; @Autowired private VorgangController vorgangController; - @Autowired - private PostfachMailController postfachController; @PostMapping public ResponseEntity<Void> createCommand(@PathVariable String vorgangId, @PathVariable String relationId, @PathVariable long relationVersion, @RequestBody CreateCommand command) { - command = command.toBuilder().vorgangId(vorgangId).relationId(relationId).build(); - var created = createCommand(command, relationVersion); + command = command.toBuilder() + .vorgangId(vorgangId) + .relationId(relationId) + .build(); if (isSendPostfachMailOrder(command)) { - sendPostfachMail(created.getId(), buildPostfachMail(command)); + command = prepareCommandForPostfachNachricht(command, vorgangId); } - return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build(); - } - - public Command createCommand(CreateCommand command, long version) { - return service.createCommand(command, version); - } - - public Command createCommand(CreateCommand command, String itemName) { - return service.createCommand(command, itemName); - } + var created = service.createCommand(command, relationVersion); - public Command createCommandWithoutValidation(CreateCommand command, String itemName) { - return service.createCommandWithoutValidation(command, itemName); + return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build(); } private boolean isSendPostfachMailOrder(CreateCommand command) { - return command.getOrder() == CommandOrder.SEND_POSTFACH_MAIL; + return command.getOrder() == CommandOrder.SEND_POSTFACH_NACHRICHT; } - void sendPostfachMail(String commandId, PostfachMail postfachMail) { - postfachController.sendPostfachMail(commandId, postfachMail); + CreateCommand prepareCommandForPostfachNachricht(CreateCommand command, String vorgangId) { + var postfachBody = (PostfachMail) command.getBody(); + var attachments = postfachBody.getAttachments().stream().map(this::stripToFileId).toList(); + postfachBody = postfachBody.toBuilder().postfachId(getPostfachId(vorgangId)) + .clearAttachments().attachments(attachments) + .build(); + return command.toBuilder().body(postfachBody).build(); } - private PostfachMail buildPostfachMail(CreateCommand command) { - return ((PostfachMail) command.getBody()).toBuilder() - .vorgangId(command.getVorgangId()) - .postfachId(getPostfachId(command.getVorgangId())) - .build(); + private FileId stripToFileId(FileId fileUri) { + var fileUriStr = fileUri.toString(); + return FileId.from(fileUriStr.substring(fileUriStr.lastIndexOf("/") + 1, fileUriStr.length())); } private String getPostfachId(String vorgangId) { @@ -124,5 +117,13 @@ public class CommandController { private VorgangWithEingang getVorgang(String vorgangId) { return vorgangController.getVorgang(vorgangId); } + + public Command createCommandWithoutRelation(CreateCommand command) { + return service.createCommandWithoutRelation(command); + } + + public Command createCommandWithoutValidation(CreateCommand command, String itemName, long relationVersion) { + return service.createCommandWithoutValidation(command, itemName, relationVersion); + } } } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandMapper.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandMapper.java index e2b81a1c10ea9b0190034b7c31bd2f26fe52e6ab..cf44ac65b3a9065011f693fce1870bca2c4c1cde 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandMapper.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandMapper.java @@ -1,23 +1,56 @@ package de.itvsh.goofy.common.command; +import java.util.Map; +import java.util.Objects; + +import org.apache.commons.lang3.StringUtils; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; import org.mapstruct.ValueMapping; +import org.springframework.beans.factory.annotation.Autowired; import de.itvsh.goofy.common.TimeMapper; import de.itvsh.goofy.common.callcontext.CallContextMapper; -import de.itvsh.goofy.common.user.UserId; +import de.itvsh.goofy.common.user.UserIdMapper; import de.itvsh.goofy.vorgang.RedirectRequest; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; import de.itvsh.ozg.pluto.grpc.command.GrpcRedirectRequest; -@Mapper(uses = { CallContextMapper.class, TimeMapper.class, CommandBodyMapper.class }) -public interface CommandMapper { +@Mapper(uses = { CallContextMapper.class, TimeMapper.class, CommandBodyMapper.class, GrpcObjectMapper.class, UserIdMapper.class }) +public abstract class CommandMapper { + + @Autowired + private GrpcObjectMapper objectMapper; + @Autowired + private CommandBodyMapper bodyMapper; @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL) @ValueMapping(source = "UNDEFINED", target = MappingConstants.NULL) - Command toCommand(GrpcCommand grpcCommand); + @Mapping(target = "order", expression = "java(mapOrder(grpcCommand))") + @Mapping(target = "body", expression = "java(mapBody(grpcCommand))") + abstract Command toCommand(GrpcCommand grpcCommand); + + Map<String, ?> mapBody(GrpcCommand command) { + if (!Objects.isNull(command.getBodyObj())) { + return objectMapper.mapFromGrpc(command.getBodyObj()); + } else { + return bodyMapper.map(command.getBody()); + } + } + + CommandOrder mapOrder(GrpcCommand command) { + if (StringUtils.isNotBlank(command.getOrderString())) { + return CommandOrder.valueOf(command.getOrderString()); + } else { + return CommandOrder.valueOf(command.getOrder().name()); + } + } + + String mapStringtoNull(String in) { + return StringUtils.trimToNull(in); + } @Mapping(target = "mergeContext", ignore = true) @Mapping(target = "context", ignore = true) @@ -29,9 +62,6 @@ public interface CommandMapper { @Mapping(target = "passwordBytes", ignore = true) @Mapping(target = "unknownFields", ignore = true) @Mapping(target = "allFields", ignore = true) - GrpcRedirectRequest toGrpcRedirectRequest(RedirectRequest request); + abstract GrpcRedirectRequest toGrpcRedirectRequest(RedirectRequest request); - default UserId mapUserId(String userId) { - return UserId.from(userId); - } } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java index 136cf4ea625bb8e60c4cdb2e07b0da5ae29551ab..d486668a566b4d1a64939d5ca114873a81b3888a 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandOrder.java @@ -30,7 +30,9 @@ public enum CommandOrder { WIEDERVORLAGE_ERLEDIGEN(false, Type.WIEDERVORLAGE), WIEDERVORLAGE_WIEDEREROEFFNEN(false, Type.WIEDERVORLAGE), // + @Deprecated SEND_POSTFACH_MAIL(false, Type.POSTFACH), + SEND_POSTFACH_NACHRICHT(false, Type.POSTFACH), RESEND_POSTFACH_MAIL(false, Type.POSTFACH), CREATE_ATTACHED_ITEM(false, Type.VORGANG), diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandRemoteService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandRemoteService.java index 0185cb89bcfbf21d4288b96a9ce7b093b8510e93..2e23b23ba4ac35cea37447aa882ce3d52b3f7f1c 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandRemoteService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandRemoteService.java @@ -21,6 +21,8 @@ import net.devh.boot.grpc.client.inject.GrpcClient; @Service public class CommandRemoteService { + @GrpcClient("pluto") + private CommandServiceBlockingStub commandServiceStub; @Autowired private ContextService contextService; @Autowired @@ -30,11 +32,8 @@ public class CommandRemoteService { @Autowired private GrpcObjectMapper objectMapper; - @GrpcClient("pluto") - private CommandServiceBlockingStub commandServiceStub; - - public Command createCommand(CreateCommand command, long version) { - return doCreateCommand(buildCreateCommandRequest(command, version)); + public Command createCommand(CreateCommand command) { + return doCreateCommand(buildCreateCommandRequest(command)); } public Command createCommand(CreateCommand command, String itemName) { @@ -47,29 +46,30 @@ public class CommandRemoteService { return mapper.toCommand(response.getCommand()); } - GrpcCreateCommandRequest buildCreateCommandRequest(CreateCommand command, long version) { + GrpcCreateCommandRequest buildCreateCommandRequest(CreateCommand command) { + return buildCreateRequestBuilder(command) + .setBodyObj(objectMapper.fromMap(bodyMapper.fromObjectToMap(command.getBody()))) + .build(); + } + + GrpcCreateCommandRequest buildCreateAttachedItemCommandRequest(CreateCommand command, String itemName) { + return buildCreateRequestBuilder(command) + .setBodyObj(objectMapper.fromMap(bodyMapper.mapToBodyMap(command, itemName))) + .build(); + } + + GrpcCreateCommandRequest.Builder buildCreateRequestBuilder(CreateCommand command) { var requestBuilder = GrpcCreateCommandRequest.newBuilder() .setCallContext(contextService.createCallContext()) .setVorgangId(command.getVorgangId()) .setRelationId(command.getRelationId()) - .setRelationVersion(version) - .addAllBody(bodyMapper.mapToBodyFields(command.getBody())) - .setOrder(GrpcOrder.valueOf(command.getOrder().name())); + .setRelationVersion(command.getRelationVersion()) + .setOrderString(command.getOrder().name()) + .addAllBody(bodyMapper.mapToBodyFields(command.getBody())); Optional.ofNullable(command.getRedirectRequest()).map(mapper::toGrpcRedirectRequest).ifPresent(requestBuilder::setRedirectRequest); - return requestBuilder.build(); - } - - GrpcCreateCommandRequest buildCreateAttachedItemCommandRequest(CreateCommand command, String itemName) { - return GrpcCreateCommandRequest.newBuilder() - .setCallContext(contextService.createCallContext()) - .setRelationId(command.getVorgangId()) - .setRelationVersion(-1) - .setVorgangId(command.getVorgangId()) - .setOrder(GrpcOrder.valueOf(command.getOrder().name())) - .setBodyObj(objectMapper.fromMap(bodyMapper.mapToBodyMap(command, itemName))) - .build(); + return requestBuilder; } public Command revokeCommand(String commandId) { diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandService.java index 5d27b7f6d9e16955e61eefbe3ffbfce0272e7740..a70772101744018f0ec92d7669ae7b1334fe2ffd 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CommandService.java @@ -11,22 +11,36 @@ import org.springframework.validation.annotation.Validated; import lombok.NonNull; -@Service @Validated -class CommandService { +@Service +public class CommandService { + + static final long NO_RELATION_VERSION = -1; @Autowired private CommandRemoteService remoteService; - public Command createCommand(@Valid CreateCommand command, long version) { - return remoteService.createCommand(command, version); + public Command createCommand(CreateCommand command) { + command = command.toBuilder().relationVersion(NO_RELATION_VERSION).build(); + + return remoteService.createCommand(command); } - public Command createCommand(@Valid CreateCommand command, String itemName) { - return remoteService.createCommand(command, itemName); + public Command createCommand(@Valid CreateCommand command, long relationVersion) { + command = command.toBuilder().relationVersion(relationVersion).build(); + + return remoteService.createCommand(command); } - public Command createCommandWithoutValidation(CreateCommand command, String itemName) { + public Command createCommandWithoutRelation(CreateCommand command) { + command = command.toBuilder().relationVersion(NO_RELATION_VERSION).build(); + + return remoteService.createCommand(command); + } + + public Command createCommandWithoutValidation(CreateCommand command, String itemName, long relationVersion) { + command = command.toBuilder().relationVersion(relationVersion).build(); + return remoteService.createCommand(command, itemName); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CreateCommand.java b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CreateCommand.java index ce4bec48e195335fabb156ac73d405dfa437d6ec..c63125db8f2dc0cd58fb283d688e550ce8cf99ef 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/command/CreateCommand.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/command/CreateCommand.java @@ -28,6 +28,7 @@ public class CreateCommand { private String vorgangId; private String relationId; + private long relationVersion; private CommandOrder order; @Valid diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java index dd9ac1f05e25b5cba1a7ad46ea1bfd26bc6a68fd..bc1f6064da1de5322c28bf556679aa838d5d4948 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java @@ -18,10 +18,11 @@ import com.auth0.jwt.exceptions.JWTVerificationException; import de.itvsh.goofy.JwtTokenUtil; import de.itvsh.goofy.common.binaryfile.DownloadGoofyUser; -import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.binaryfile.DownloadGoofyUser.DownloadGoofyUserBuilder; +import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.user.CurrentUserService; import de.itvsh.goofy.common.user.GoofyUser; +import de.itvsh.goofy.common.user.UserId; import de.itvsh.kop.common.errorhandling.TechnicalException; import io.jsonwebtoken.Claims; import lombok.extern.log4j.Log4j2; @@ -68,9 +69,11 @@ class DownloadTokenService { final DownloadGoofyUserBuilder downloadUserBuilder = DownloadGoofyUser.builder(); claimsOptional.ifPresent(claims -> downloadUserBuilder.user( GoofyUser.builder() + .id(UserId.from(claims.get(USERID_CLAIM, String.class))) .firstName(claims.get(FIRSTNAME_CLAIM, String.class)) .lastName(claims.get(LASTNAME_CLAIM, String.class)) - .authorities(jwtTokenUtil.getRolesFromToken(token)).build()) + .authorities(jwtTokenUtil.getRolesFromToken(token)) + .organisationseinheitIds(jwtTokenUtil.getOrganisationseinheitIdsFromToken(token)).build()) .fileId(FileId.from(claims.get(FILEID_CLAIM, String.class)))); return downloadUserBuilder.build(); diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/user/CurrentUserService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/user/CurrentUserService.java index 0e1da92e75bbbd21e20b79babb1f58814e7da1c7..58040fd30f13c4f728a4c93ef9fb1b3bd0a2a90b 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/user/CurrentUserService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/user/CurrentUserService.java @@ -13,6 +13,8 @@ import org.keycloak.representations.AccessToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; +import de.itvsh.goofy.common.binaryfile.DownloadGoofyUser; + @Service public class CurrentUserService { @@ -29,6 +31,11 @@ public class CurrentUserService { } public GoofyUser getUser() { + var dlUser = getDownloadUser(); + if (dlUser.isPresent()) { + return dlUser.get(); + } + Optional<AccessToken> token = getCurrentSecurityToken(); var userBuilder = GoofyUser.builder() @@ -53,12 +60,21 @@ public class CurrentUserService { .stream().map(Object::toString).collect(Collectors.toList()); } + private Optional<GoofyUser> getDownloadUser() { + return Optional.of(CurrentUserHelper.getAuthentication().getPrincipal()) + .filter(DownloadGoofyUser.class::isInstance) + .map(DownloadGoofyUser.class::cast) + .map(DownloadGoofyUser::getUser); + + } + private Optional<AccessToken> getCurrentSecurityToken() { Object principal = CurrentUserHelper.getAuthentication().getPrincipal(); if (principal instanceof KeycloakPrincipal) { return Optional.of(((KeycloakPrincipal<?>) principal).getKeycloakSecurityContext().getToken()); } + return Optional.empty(); } } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java index 89eb1615fb6c468455689c949429c01e664907e6..9937eb74be669db72fbade1341a720cdeab908e7 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/Kommentar.java @@ -30,6 +30,8 @@ public class Kommentar implements CommandBody { @JsonIgnore private String id; + @JsonIgnore + private long version; @JsonIgnore private String vorgangId; diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java index b9040667714e68b01695b0ee0290d02d29e6b3cf..394259041336c6de405cf1a332948404d25922ad 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarCommandController.java @@ -2,8 +2,6 @@ package de.itvsh.goofy.kommentar; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; -import java.time.ZonedDateTime; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; @@ -14,48 +12,28 @@ import org.springframework.web.bind.annotation.RestController; import de.itvsh.goofy.common.command.Command; import de.itvsh.goofy.common.command.CommandController; -import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; -import de.itvsh.goofy.common.command.CommandOrder; -import de.itvsh.goofy.common.command.CreateCommand; -import de.itvsh.goofy.common.user.CurrentUserService; @RestController @RequestMapping(KommentarCommandController.KOMMENTAR_COMMANDS) public class KommentarCommandController { - static final String KOMMENTAR_COMMANDS = "/api/kommentars/{kommentarId}/commands"; - static final String NOT_SET = "-1"; + static final String KOMMENTAR_COMMANDS = "/api/kommentars/{kommentarId}/{kommentarVersion}/commands"; @Autowired private KommentarService service; - @Autowired - private CommandByRelationController commandByRelationController; - @PostMapping - public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand kommentarCommand, @PathVariable String kommentarId) { - var command = commandByRelationController.createCommand(buildCommand(service.getById(kommentarId), kommentarCommand), - KommentarRemoteService.ITEM_NAME); - return buildResponseLink(command); + public ResponseEntity<Void> editKommentar(@RequestBody KommentarCommand kommentarCommand, @PathVariable String kommentarId, + @PathVariable long kommentarVersion) { + var createdCommand = service.editKommentar(kommentarCommand.getKommentar(), kommentarId, kommentarVersion); + + return buildResponseLink(createdCommand); } private ResponseEntity<Void> buildResponseLink(Command createdKommentarCommand) { return ResponseEntity.created(linkTo(CommandController.class).slash(createdKommentarCommand.getId()).toUri()).build(); } - CreateCommand buildCommand(Kommentar kommentar, KommentarCommand command) { - var commandBuilder = CreateCommand.builder() - .order(CommandOrder.UPDATE_ATTACHED_ITEM) - .relationId(NOT_SET) - .vorgangId(kommentar.getVorgangId()); - - return commandBuilder.body(updateKommandByCommand(kommentar, command)).build(); - } - - private Kommentar updateKommandByCommand(Kommentar kommentar, KommentarCommand command) { - return kommentar.toBuilder().text(command.getKommentar().getText()).build(); - } - @RestController @RequestMapping(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG) public static class KommentarCommandByVorgangController { @@ -63,33 +41,13 @@ public class KommentarCommandController { static final String KOMMENTAR_COMMANDS_BY_VORGANG = "/api/vorgangs/{vorgangId}/kommentarCommands"; @Autowired - private CommandByRelationController commandByRelationController; - - @Autowired - private CurrentUserService userService; + private KommentarService service; - @PostMapping() - public ResponseEntity<Void> createCommand(@RequestBody KommentarCommand command, @PathVariable String vorgangId) { - var createdCommand = commandByRelationController.createCommand(buildCommand(vorgangId, command), KommentarRemoteService.ITEM_NAME); + @PostMapping + public ResponseEntity<Void> createKommentar(@RequestBody KommentarCommand command, @PathVariable String vorgangId) { + var createdCommand = service.createKommentar(command.getKommentar(), vorgangId); return ResponseEntity.created(linkTo(CommandController.class).slash(createdCommand.getId()).toUri()).build(); } - - CreateCommand buildCommand(String vorgangId, KommentarCommand command) { - return CreateCommand.builder() - .vorgangId(vorgangId) - .order(CommandOrder.CREATE_ATTACHED_ITEM) - .relationId(NOT_SET) - .body(buildBody(command.getKommentar())) - .build(); - } - - Kommentar buildBody(Kommentar kommentar) { - return kommentar.toBuilder() - .createdAt(ZonedDateTime.now().withNano(0)) - .createdBy(userService.getUserId().toString()) - .build(); - } - } -} +} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java index c36561d38afa4080e10c69b1782aa37e57095400..395c02868b9a1a1cf6c3f9656c6a19b50366af43 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarMapper.java @@ -9,25 +9,36 @@ import org.mapstruct.MappingConstants; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.ReportingPolicy; import org.mapstruct.ValueMapping; +import org.springframework.beans.factory.annotation.Autowired; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; @Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) -public interface KommentarMapper { +abstract class KommentarMapper { static final String ID = "id"; static final String TEXT = "text"; static final String CREATED_BY = "createdBy"; static final String CREATED_AT = "createdAt"; + @Autowired + private GrpcObjectMapper grpcObjectMapper; + @Mapping(target = "kommentar", ignore = true) @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL) @ValueMapping(source = "UNDEFINED", target = MappingConstants.NULL) - KommentarCommand toKommentarCommand(GrpcCommand command); + abstract KommentarCommand toKommentarCommand(GrpcCommand command); + + public Kommentar fromItem(GrpcVorgangAttachedItem vorgangAttachedItem) { + return fromItemMap(grpcObjectMapper.mapFromGrpc(vorgangAttachedItem.getItem()), vorgangAttachedItem.getVersion()); + } - default Kommentar fromItemMap(Map<String, Object> map) { + Kommentar fromItemMap(Map<String, Object> map, long version) { return Kommentar.builder() .id((String) map.get(ID)) + .version(version) .createdAt(ZonedDateTime.parse((String) map.get(CREATED_AT))) .createdBy((String) map.get(CREATED_BY)) .text((String) map.get(TEXT)) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarModelAssembler.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarModelAssembler.java index fda3d28ec5f38a9055c7ab517cf284cc5d52bfe3..f1fda7f7fe86d4ef4e4e257c96e08b69a7dc5759 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarModelAssembler.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarModelAssembler.java @@ -22,7 +22,7 @@ class KommentarModelAssembler implements RepresentationModelAssembler<Kommentar, @Override public EntityModel<Kommentar> toModel(Kommentar kommentar) { var selfLink = linkTo(KommentarController.class).slash(kommentar.getId()); - var commandLink = linkTo(methodOn(KommentarCommandController.class).createCommand(null, kommentar.getId())); + var commandLink = linkTo(methodOn(KommentarCommandController.class).editKommentar(null, kommentar.getId(), kommentar.getVersion())); return ModelBuilder.fromEntity(kommentar).addLink(selfLink.withSelfRel()) .addLink(commandLink.withRel(REL_EDIT)) @@ -32,6 +32,7 @@ class KommentarModelAssembler implements RepresentationModelAssembler<Kommentar, public CollectionModel<EntityModel<Kommentar>> toCollectionModel(Stream<Kommentar> entities, String vorgangId) { return CollectionModel.of(entities.map(this::toModel).collect(Collectors.toList()), linkTo(KommentarController.class).withSelfRel(), - linkTo(methodOn(KommentarCommandByVorgangController.class).createCommand(null, vorgangId)).withRel(REL_CREATE)); + linkTo(methodOn(KommentarCommandByVorgangController.class).createKommentar(null, vorgangId)) + .withRel(REL_CREATE)); } } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java index 2e2d6c6cb0ce3dab68978db6e72f06bafcb51ef7..c6873ea395c1988420c1bef8057ae5f95b125276 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarRemoteService.java @@ -6,31 +6,25 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import de.itvsh.goofy.GoofyServerApplication; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; -import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItemRequest; import de.itvsh.ozg.pluto.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceBlockingStub; import net.devh.boot.grpc.client.inject.GrpcClient; @Service class KommentarRemoteService { + static final String ITEM_NAME = "Kommentar"; @GrpcClient(GoofyServerApplication.GRPC_CLIENT) private VorgangAttachedItemServiceBlockingStub vorgangAttachedItemServiceStub; @Autowired private KommentarMapper mapper; - @Autowired - private GrpcObjectMapper grpcObjectMapper; public Stream<Kommentar> findByVorgangId(String vorgangId) { - GrpcFindVorgangAttachedItemResponse response = vorgangAttachedItemServiceStub - .find(buildFindRequest(vorgangId)); + var response = vorgangAttachedItemServiceStub.find(buildFindRequest(vorgangId)); - return response.getVorgangAttachedItemsList().stream() - .map(item -> grpcObjectMapper.mapFromGrpc(item.getItem())) - .map(mapper::fromItemMap); + return response.getVorgangAttachedItemsList().stream().map(mapper::fromItem); } GrpcFindVorgangAttachedItemRequest buildFindRequest(String vorgangId) { @@ -42,8 +36,8 @@ class KommentarRemoteService { public Kommentar getById(String kommentarId) { var response = vorgangAttachedItemServiceStub.getById(buildRequest(kommentarId)); - var kommentar = mapper.fromItemMap(grpcObjectMapper.mapFromGrpc(response.getVorgangAttachedItem().getItem())); - return kommentar.toBuilder().vorgangId(response.getVorgangAttachedItem().getVorgangId()).build(); + + return mapper.fromItem(response.getVorgangAttachedItem()).toBuilder().vorgangId(response.getVorgangAttachedItem().getVorgangId()).build(); } private GrpcVorgangAttachedItemRequest buildRequest(String kommentarId) { diff --git a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java index 8b14e5f2262ef7a7628d9c2526f3704fa9654707..1a6627031e2d66b5b420705f339c10c0ece767c4 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/kommentar/KommentarService.java @@ -1,17 +1,46 @@ package de.itvsh.goofy.kommentar; +import java.time.ZonedDateTime; import java.util.stream.Stream; +import javax.validation.Valid; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -@Service +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItemService; +import de.itvsh.goofy.common.command.Command; +import de.itvsh.goofy.common.user.CurrentUserService; + @Validated +@Service class KommentarService { @Autowired private KommentarRemoteService remoteService; + @Autowired + private CurrentUserService currentUserService; + @Autowired + private VorgangAttachedItemService vorgangAttachedItemService; + + public Command createKommentar(@Valid Kommentar kommentar, String vorgangId) { + return vorgangAttachedItemService.createNewKommentar(addCreated(kommentar), vorgangId); + } + + Kommentar addCreated(Kommentar kommentar) { + return kommentar.toBuilder() + .createdAt(ZonedDateTime.now().withNano(0)) + .createdBy(currentUserService.getUserId().toString()) + .build(); + } + + public Command editKommentar(@Valid Kommentar kommentar, String kommentarId, long kommentarVersion) { + var loadedKommentar = getById(kommentarId); + var preparedKommentar = loadedKommentar.toBuilder().text(kommentar.getText()).build(); + + return vorgangAttachedItemService.editKommentar(preparedKommentar, kommentarId, kommentarVersion); + } public Stream<Kommentar> findByVorgangId(String vorgangId) { return remoteService.findByVorgangId(vorgangId); @@ -20,4 +49,4 @@ class KommentarService { public Kommentar getById(String kommentarId) { return remoteService.getById(kommentarId); } -} +} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMail.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMail.java index a780e3d6883225dd238b908366be172535a96a65..ed84924b41b56f16d30afaf3cf5c259d52ca8c8e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMail.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMail.java @@ -10,11 +10,9 @@ import javax.validation.constraints.Size; import com.fasterxml.jackson.annotation.JsonIgnore; -import de.itvsh.goofy.common.LinkedResource; import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.command.CommandBody; import de.itvsh.goofy.common.user.UserId; -import de.itvsh.goofy.common.user.UserProfileController; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -42,7 +40,7 @@ public class PostfachMail implements CommandBody { private String vorgangId; private ZonedDateTime createdAt; - @LinkedResource(controllerClass = UserProfileController.class) + @JsonIgnore private UserId createdBy; private ZonedDateTime sentAt; diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailController.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailController.java index 2261c99b4463d0cf368c7baaaec0d563505f319c..aba1528f495b685b32fababbaeff557f283b4eae 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailController.java @@ -19,7 +19,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import de.itvsh.goofy.common.binaryfile.BinaryFileController; -import de.itvsh.goofy.common.command.Command; import de.itvsh.goofy.common.command.CommandController; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; import de.itvsh.goofy.common.command.CreateCommand; @@ -46,10 +45,6 @@ public class PostfachMailController { @Autowired private BinaryFileController binaryFileController; - public void sendPostfachMail(String commandId, PostfachMail message) { - service.sendPostfachMail(commandId, message); - } - @GetMapping(params = PARAM_VORGANG_ID) public CollectionModel<EntityModel<PostfachMail>> getAll(@RequestParam String vorgangId) { var vorgang = getVorgang(vorgangId); @@ -94,16 +89,15 @@ public class PostfachMailController { @PostMapping public ResponseEntity<Void> createCommand(@PathVariable String vorgangId, @PathVariable String postfachMailId, @RequestBody CreateCommand command) { - command = command.toBuilder().vorgangId(vorgangId).relationId(postfachMailId).build(); - var created = createCommand(command); + command = command.toBuilder() + .vorgangId(vorgangId) + .relationId(postfachMailId) + .build(); + var created = commandByRelationController.createCommandWithoutRelation(command); service.resendPostfachMail(created.getId(), postfachMailId); return ResponseEntity.created(linkTo(CommandController.class).slash(created.getId()).toUri()).build(); } - - Command createCommand(CreateCommand command) { - return commandByRelationController.createCommand(command, -1); - } } } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailModelAssembler.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailModelAssembler.java index a323d38ae2e7194e2edfcf8f33fa3b656d9322dd..0b49bcbc606db14e5096b9dea6af58360053a0b6 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailModelAssembler.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailModelAssembler.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; import de.itvsh.goofy.common.ModelBuilder; import de.itvsh.goofy.common.binaryfile.BinaryFileController; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; +import de.itvsh.goofy.common.user.UserProfileController; import de.itvsh.goofy.postfach.PostfachMailController.PostfachMailCommandController; @Component @@ -24,10 +25,15 @@ class PostfachMailModelAssembler implements RepresentationModelAssembler<Postfac public static final String REL_RESEND_POSTFACH_MAIL = "resendPostfachMail"; public static final String REL_ATTACHMENTS = "attachments"; static final String REL_UPLOAD_ATTACHMENT = "uploadAttachment"; + static final String REL_CREATED_BY = "createdBy"; private static final Predicate<PostfachMail> SENT_FAILED = postfachMail -> BooleanUtils.isFalse(postfachMail.getSentSuccessful()); private static final Predicate<PostfachMail> HAS_ATTACHMENTS = nachricht -> !nachricht.getAttachments().isEmpty(); + static final String SYSTEM_USER_IDENTIFIER = "system"; + private static final Predicate<PostfachMail> SENT_BY_CLIENT_USER = postfachNachricht -> Optional.ofNullable(postfachNachricht.getCreatedBy()) + .map(createdBy -> !createdBy.toString().startsWith(SYSTEM_USER_IDENTIFIER)).orElse(false); + public CollectionModel<EntityModel<PostfachMail>> toCollectionModel(Stream<PostfachMail> entities, String vorgangId, long vorgangVersion, Optional<String> postfachId) { CollectionModel<EntityModel<PostfachMail>> model = CollectionModel.of(entities.map(this::toModel).toList(), @@ -49,6 +55,8 @@ class PostfachMailModelAssembler implements RepresentationModelAssembler<Postfac .ifMatch(HAS_ATTACHMENTS) .addLink(linkTo(methodOn(PostfachMailController.class).findAttachments(PostfachNachrichtId.from(postfachMail.getId()))) .withRel(REL_ATTACHMENTS)) + .ifMatch(SENT_BY_CLIENT_USER) + .addLink(linkTo(UserProfileController.class).slash(postfachMail.getCreatedBy()).withRel(REL_CREATED_BY)) .buildModel(); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailRemoteService.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailRemoteService.java index be2e440130cb1c4452317a08f4924348d46e65e6..8a48ba36b825d2d51ffbbb4035aac4b427c3cb2e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailRemoteService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailRemoteService.java @@ -6,14 +6,12 @@ import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.callcontext.ContextService; import de.itvsh.ozg.mail.postfach.GrpcFindPostfachMailRequest; import de.itvsh.ozg.mail.postfach.GrpcFindPostfachMailsRequest; import de.itvsh.ozg.mail.postfach.GrpcFindPostfachMailsResponse; import de.itvsh.ozg.mail.postfach.GrpcIsPostfachConfiguredRequest; import de.itvsh.ozg.mail.postfach.GrpcResendPostfachMailRequest; -import de.itvsh.ozg.mail.postfach.GrpcSendPostfachMailRequest; import de.itvsh.ozg.mail.postfach.PostfachServiceGrpc.PostfachServiceBlockingStub; import net.devh.boot.grpc.client.inject.GrpcClient; @@ -27,29 +25,6 @@ class PostfachMailRemoteService { @Autowired private PostfachMailMapper postfachNachrichtMapper; - public void sendPostfachMail(String commandId, PostfachMail postfachMail) { - serviceStub.sendPostfachMail(buildSendPostfachMailRequest(commandId, postfachMail)); - } - - private GrpcSendPostfachMailRequest buildSendPostfachMailRequest(String commandId, PostfachMail postfachMail) { - var mail = postfachNachrichtMapper.toGrpcPostfachMail(postfachMail); - - // TODO Die Attachments direkt im Mapper setzen - var attachmentStringList = postfachMail.getAttachments().stream().map(this::stripToFileId).toList(); - mail = mail.toBuilder().addAllAttachment(attachmentStringList).build(); - - return GrpcSendPostfachMailRequest.newBuilder() - .setCommandId(commandId) - .setContext(contextService.createCallContext()) - .setMail(mail) - .build(); - } - - private String stripToFileId(FileId fileUri) { - var fileUriStr = fileUri.toString(); - return fileUriStr.substring(fileUriStr.lastIndexOf("/") + 1, fileUriStr.length()); - } - public Stream<PostfachMail> findPostfachMails(String vorgangId) { GrpcFindPostfachMailsResponse response = serviceStub.findPostfachMails(buildFindPostfachMailsRequest(vorgangId)); diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java index 789ebe855ae3446f964e90868a9ace0def327e1a..445aad6500dc4204f9947b517ff8b4c749689030 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java @@ -19,16 +19,6 @@ class PostfachMailService { @Autowired private PostfachMailRemoteService remoteService; - @Async - public void sendPostfachMail(String commandId, PostfachMail postfachMail) { - try { - remoteService.sendPostfachMail(commandId, postfachMail); - } catch (RuntimeException e) { - LOG.error("Error sending PostfachNachricht: " + e.getMessage(), e); -// FIXME mark command als error - } - } - public Stream<PostfachMail> getAll(String vorgangId) { return remoteService.findPostfachMails(vorgangId); } @@ -36,7 +26,6 @@ class PostfachMailService { public PostfachMail findById(PostfachNachrichtId nachrichtId) { return remoteService.findById(nachrichtId) .orElseThrow(() -> new ResourceNotFoundException(PostfachMail.class, nachrichtId)); - } @Async diff --git a/goofy-server/src/main/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessor.java b/goofy-server/src/main/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessor.java index 89b9dee2f56e78d599b55ac73c0ece2cedc2e803..072324a882b2bbbecb773f88723ab3f0a4cf8b01 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessor.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessor.java @@ -18,14 +18,12 @@ import de.itvsh.goofy.common.user.UserRole; import de.itvsh.goofy.vorgang.Vorgang.VorgangStatus; import de.itvsh.goofy.vorgang.VorgangWithEingang; import de.itvsh.goofy.vorgang.forwarding.ForwardingController; -import de.itvsh.goofy.wiedervorlage.WiedervorlageCommandController.WiedervorlageCommandByVorgangController; @Component public class VorgangWithEingangCommandProzessor implements RepresentationModelProcessor<EntityModel<VorgangWithEingang>> { static final LinkRelation REL_VORGANG_FORWARD = LinkRelation.of("forward"); static final LinkRelation REL_PENDING_COMMANDS = LinkRelation.of("pending-commands"); - static final LinkRelation REL_CREATE_WIEDERVORLAGE = LinkRelation.of("create-wiedervorlage"); @Autowired private CurrentUserService userService; @@ -45,9 +43,6 @@ public class VorgangWithEingangCommandProzessor implements RepresentationModelPr .addLink(linkTo( methodOn(CommandByRelationController.class).createCommand(vorgang.getId(), vorgang.getId(), vorgang.getVersion(), null)).withRel(REL_VORGANG_FORWARD)) - .ifMatch(() -> userService.hasRole(UserRole.VERWALTUNG_USER)) - .addLink(linkTo(methodOn(WiedervorlageCommandByVorgangController.class).createCommand(null, vorgang.getId())) - .withRel(REL_CREATE_WIEDERVORLAGE)) .ifMatch(this::existsPendingCommands) .addLink(linkTo(methodOn(CommandController.class).getPendingCommands(true, vorgang.getId())).withRel(REL_PENDING_COMMANDS)) .buildModel(); diff --git a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/Wiedervorlage.java b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/Wiedervorlage.java index f842842587530ad75cabe1c5246ec2bfdc2d6f08..950343c58851a274800b7b848f384f9241df6864 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/Wiedervorlage.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/Wiedervorlage.java @@ -42,6 +42,8 @@ public class Wiedervorlage implements CommandBody { @JsonIgnore private String vorgangId; + @JsonIgnore + private long version; @JsonProperty(access = Access.READ_ONLY) private boolean done; diff --git a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandController.java b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandController.java index e6270b5ad8ab05eeee8c8729d03aaa4e223102b2..95eee8f6422f37e547f8f059b22196c28b1d855b 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandController.java @@ -2,7 +2,6 @@ package de.itvsh.goofy.wiedervorlage; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; -import java.time.ZonedDateTime; import java.util.Objects; import org.springframework.beans.factory.annotation.Autowired; @@ -19,14 +18,12 @@ import de.itvsh.goofy.common.command.CommandController; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; import de.itvsh.goofy.common.command.CommandOrder; import de.itvsh.goofy.common.command.CreateCommand; -import de.itvsh.goofy.common.user.CurrentUserService; @RestController @RequestMapping(WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS) public class WiedervorlageCommandController { - static final String WIEDERVORLAGE_COMMANDS = "/api/wiedervorlages/{wiedervorlageId}/commands"; - static final String NOT_SET = "-1"; + static final String WIEDERVORLAGE_COMMANDS = "/api/wiedervorlages/{wiedervorlageId}/{wiedervorlageVersion}/commands"; @Autowired private CommandByRelationController commandByRelationController; @@ -35,8 +32,9 @@ public class WiedervorlageCommandController { private WiedervorlageService service; @PostMapping - public ResponseEntity<Void> createCommand(@RequestBody WiedervorlageCommand command, @PathVariable String wiedervorlageId) { - var commandWithUpdatedWiedervorlage = buildCommand(service.getById(wiedervorlageId), command); + public ResponseEntity<Void> updateWiedervorlage(@RequestBody WiedervorlageCommand command, @PathVariable String wiedervorlageId, + @PathVariable long wiedervorlageVersion) { + var commandWithUpdatedWiedervorlage = buildCommand(service.getById(wiedervorlageId), command, wiedervorlageVersion); var createdCommand = createByOrder(commandWithUpdatedWiedervorlage, command.getOrder()); @@ -45,10 +43,11 @@ public class WiedervorlageCommandController { return ResponseEntity.created(linkTo(CommandController.class).slash(createdCommand.getId()).toUri()).build(); } - CreateCommand buildCommand(Wiedervorlage wiedervorlage, WiedervorlageCommand command) { + CreateCommand buildCommand(Wiedervorlage wiedervorlage, WiedervorlageCommand command, long wiedervorlageVersion) { var commandBuilder = CreateCommand.builder() .order(CommandOrder.UPDATE_ATTACHED_ITEM) - .relationId(NOT_SET) + .relationId(wiedervorlage.getId()) + .relationVersion(wiedervorlageVersion) .vorgangId(wiedervorlage.getVorgangId()); switch (command.getOrder()) { @@ -65,9 +64,10 @@ public class WiedervorlageCommandController { Command createByOrder(CreateCommand command, CommandOrder commandOrder) { if (shouldBeValidated(commandOrder)) { - return commandByRelationController.createCommand(command, WiedervorlageRemoteService.ITEM_NAME); + return service.editWiedervorlage((Wiedervorlage) command.getBody(), command.getRelationId(), command.getRelationVersion()); } else { - return commandByRelationController.createCommandWithoutValidation(command, WiedervorlageRemoteService.ITEM_NAME); + return commandByRelationController.createCommandWithoutValidation(command, WiedervorlageRemoteService.ITEM_NAME, + command.getRelationVersion()); } } @@ -89,39 +89,18 @@ public class WiedervorlageCommandController { static final String WIEDERVORLAGE_COMMANDS_BY_VORGANG = "/api/vorgangs/{vorgangId}/wiedervorlageCommands"; - @Autowired - private CommandByRelationController commandByRelationController; - - @Autowired - private CurrentUserService userService; - @Autowired private WiedervorlageService service; @PostMapping - public ResponseEntity<Void> createCommand(@RequestBody WiedervorlageCommand command, @PathVariable String vorgangId) { - var createdCommand = commandByRelationController.createCommand(buildCommand(vorgangId, command), WiedervorlageRemoteService.ITEM_NAME); + public ResponseEntity<Void> createWiedervorlage(@RequestBody WiedervorlageCommand command, @PathVariable String vorgangId) { + var preparedWiedervorlage = stripAttachmentFileUriToId(command.getWiedervorlage()); + var createdCommand = service.createWiedervorlage(preparedWiedervorlage, vorgangId); - service.updateNextFrist(command.getWiedervorlage(), vorgangId); + service.updateNextFrist(preparedWiedervorlage, vorgangId); return ResponseEntity.created(linkTo(CommandController.class).slash(createdCommand.getId()).toUri()).build(); } - - CreateCommand buildCommand(String vorgangId, WiedervorlageCommand command) { - return CreateCommand.builder() - .vorgangId(vorgangId) - .order(CommandOrder.CREATE_ATTACHED_ITEM) - .body(buildBody(command.getWiedervorlage())) - .build(); - } - - Wiedervorlage buildBody(Wiedervorlage wiedervorlage) { - wiedervorlage = wiedervorlage.toBuilder() - .createdAt(ZonedDateTime.now().withNano(0)) - .createdBy(userService.getUserId().toString()) - .build(); - return stripAttachmentFileUriToId(wiedervorlage); - } } // TODO Durch LinkedResource am attachment Attribute ersetzen diff --git a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapper.java b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapper.java index 6213f6439493801330c7546683e2ffc6cb9a8a9b..3dd222c011ec78ab460a2911d869fc364cc09ca6 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapper.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapper.java @@ -11,15 +11,21 @@ import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.Mapper; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.ReportingPolicy; +import org.springframework.beans.factory.annotation.Autowired; import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.binaryfile.FileIdMapper; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; +import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; @Mapper(uses = { FileIdMapper.class }, unmappedTargetPolicy = ReportingPolicy.WARN, // unmappedSourcePolicy = ReportingPolicy.WARN, // nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, // collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) -public interface WiedervorlageMapper { +abstract class WiedervorlageMapper { + + @Autowired + private GrpcObjectMapper grpcObjectMapper; static final String ID = "id"; static final String DONE = "done"; @@ -31,9 +37,14 @@ public interface WiedervorlageMapper { static final String FRIST = "frist"; static final String ATTACHMENTS = "attachments"; - default Wiedervorlage fromItemMap(Map<String, Object> itemMap) { + public Wiedervorlage fromItem(GrpcVorgangAttachedItem item) { + return fromItemMap(grpcObjectMapper.mapFromGrpc(item.getItem()), item.getVersion()); + } + + Wiedervorlage fromItemMap(Map<String, Object> itemMap, long version) { return Wiedervorlage.builder() .id((String) itemMap.get(ID)) + .version(version) .done(Boolean.valueOf((String) itemMap.get(DONE))) .createdBy((String) itemMap.get(CREATED_BY)) .createdAt(ZonedDateTime.parse((String) itemMap.get(CREATED_AT))) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssembler.java b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssembler.java index 7743f050749d885035e39b3db23aa75d0c88ef6c..6bbdd7c7eca4940433d2149f7a6632e8d9d4da1e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssembler.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssembler.java @@ -34,7 +34,8 @@ class WiedervorlageModelAssembler implements RepresentationModelAssembler<Wieder @Override public EntityModel<Wiedervorlage> toModel(Wiedervorlage wiedervorlage) { var selfLink = linkTo(WiedervorlageController.class).slash(wiedervorlage.getId()); - var commandLink = linkTo(methodOn(WiedervorlageCommandController.class).createCommand(null, wiedervorlage.getId())); + var commandLink = linkTo( + methodOn(WiedervorlageCommandController.class).updateWiedervorlage(null, wiedervorlage.getId(), wiedervorlage.getVersion())); return ModelBuilder.fromEntity(wiedervorlage).addLink(selfLink.withSelfRel()) .addLink(commandLink.withRel(REL_EDIT)) @@ -48,7 +49,8 @@ class WiedervorlageModelAssembler implements RepresentationModelAssembler<Wieder public CollectionModel<EntityModel<Wiedervorlage>> toCollectionModel(Stream<Wiedervorlage> entities, String vorgangId) { return CollectionModel.of(entities.map(this::toModel).collect(Collectors.toList()), linkTo(WiedervorlageController.class).withSelfRel(), - linkTo(methodOn(WiedervorlageCommandByVorgangController.class).createCommand(null, vorgangId)).withRel(REL_CREATE), + linkTo(methodOn(WiedervorlageCommandByVorgangController.class).createWiedervorlage(null, vorgangId)) + .withRel(REL_CREATE), linkTo(BinaryFileController.class).slash(vorgangId).slash("wiedervorlageAttachment").slash("file") .withRel(REL_UPLOAD_FILE)); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteService.java b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteService.java index b39b3f0d9ef9efe82cb1f3a43d0fa15d84ab2a4c..73bc379fdacc8d16bd19750017c5ed90c35abae8 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteService.java @@ -10,7 +10,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import de.itvsh.goofy.GoofyServerApplication; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcClientAttribute; @@ -37,16 +36,12 @@ public class WiedervorlageRemoteService { @Autowired private WiedervorlageMapper mapper; @Autowired - private GrpcObjectMapper grpcObjectMapper; - @Autowired private ApplicationContext context; public Stream<Wiedervorlage> findByVorgangId(String vorgangId) { var response = vorgangAttachedItemServiceStub.find(buildFindRequest(vorgangId)); - return response.getVorgangAttachedItemsList().stream() - .map(item -> grpcObjectMapper.mapFromGrpc(item.getItem())) - .map(mapper::fromItemMap); + return response.getVorgangAttachedItemsList().stream().map(mapper::fromItem); } GrpcFindVorgangAttachedItemRequest buildFindRequest(String vorgangId) { @@ -58,8 +53,8 @@ public class WiedervorlageRemoteService { public Wiedervorlage getById(String wiedervorlageId) { var response = vorgangAttachedItemServiceStub.getById(GrpcVorgangAttachedItemRequest.newBuilder().setId(wiedervorlageId).build()); - var wiedervorlage = mapper.fromItemMap(grpcObjectMapper.mapFromGrpc(response.getVorgangAttachedItem().getItem())); - return wiedervorlage.toBuilder().vorgangId(response.getVorgangAttachedItem().getVorgangId()).build(); + + return mapper.fromItem(response.getVorgangAttachedItem()).toBuilder().vorgangId(response.getVorgangAttachedItem().getVorgangId()).build(); } public void updateNextFrist(String vorgangId, Optional<LocalDate> nextFrist) { diff --git a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageService.java b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageService.java index 4d6961375b53686657df8aa323f17c06f8eddd96..e508c813a169c3ed9570239ff1add9df2491c2ae 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/wiedervorlage/WiedervorlageService.java @@ -1,15 +1,24 @@ package de.itvsh.goofy.wiedervorlage; import java.time.LocalDate; +import java.time.ZonedDateTime; import java.util.Comparator; import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Stream; +import javax.validation.Valid; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItemService; +import de.itvsh.goofy.common.command.Command; +import de.itvsh.goofy.common.user.CurrentUserService; +@Validated @Service class WiedervorlageService { @@ -17,6 +26,25 @@ class WiedervorlageService { @Autowired private WiedervorlageRemoteService remoteService; + @Autowired + private VorgangAttachedItemService vorgangAttachedItemService; + @Autowired + private CurrentUserService currentUserService; + + public Command createWiedervorlage(@Valid Wiedervorlage wiedervorlage, String vorgangId) { + return vorgangAttachedItemService.createNewWiedervorlage(addCreated(wiedervorlage), vorgangId); + } + + Wiedervorlage addCreated(Wiedervorlage wiedervorlage) { + return wiedervorlage.toBuilder() + .createdAt(ZonedDateTime.now().withNano(0)) + .createdBy(currentUserService.getUserId().toString()) + .build(); + } + + public Command editWiedervorlage(@Valid Wiedervorlage wiedervorlage, String wiedervorlageId, long wiedervorlageVersion) { + return vorgangAttachedItemService.editWiedervorlage(wiedervorlage, wiedervorlageId, wiedervorlageVersion); + } public Wiedervorlage getById(String wiedervorlageId) { return remoteService.getById(wiedervorlageId); diff --git a/goofy-server/src/test/java/de/itvsh/goofy/JwtTokenUtilTest.java b/goofy-server/src/test/java/de/itvsh/goofy/JwtTokenUtilTest.java index 61548e5b6a4d7230b09465260f68ecc7dedf5702..21872772831a98e4addae01feaf3073624b3e7d8 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/JwtTokenUtilTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/JwtTokenUtilTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.*; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -72,6 +73,13 @@ class JwtTokenUtilTest { assertThat(expirationDate).isAfter(before).isBefore(after); } + @Test + void organisationseinheitIds() { + var organisationseinheitIds = jwtTokenUtil.getOrganisationseinheitIdsFromToken(generatedToken); + + assertThat(organisationseinheitIds).isEqualTo(List.of(UserTestFactory.ORGANISATORISCHE_EINHEITEN_ID)); + } + private Claims getParsedBody() { return Jwts.parser().setSigningKey(TOKEN_SECRET.getBytes()).parseClaimsJws(generatedToken).getBody(); } @@ -107,6 +115,7 @@ class JwtTokenUtilTest { claims.put(JwtTokenUtil.LASTNAME_CLAIM, SecurityTestFactory.USER_LASTNAME); claims.put(JwtTokenUtil.ROLE_CLAIM, SecurityTestFactory.AUTHORITIES); claims.put(JwtTokenUtil.FILEID_CLAIM, FileId.createNew()); + claims.put(JwtTokenUtil.ORGANSIATIONSEINHEIT_IDS_CLAIM, SecurityTestFactory.ORGANSIATIONSEINHEIT_IDS); return Jwts.builder() .setClaims(claims) diff --git a/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java index db4a5b8c67f1dab678a0733decd25231ad7f9c8b..bd32012c381f870f397df66abc0485a793c5c0db 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java @@ -1,6 +1,6 @@ package de.itvsh.goofy; -import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -9,10 +9,12 @@ import java.time.LocalDateTime; import java.time.ZoneOffset; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.springframework.boot.info.BuildProperties; import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; @@ -20,13 +22,17 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.UserRole; import de.itvsh.goofy.common.user.UserTestFactory; class RootControllerTest { private final String PATH = "/api"; + @Spy @InjectMocks // NOSONAR private RootController controller; @Mock @@ -43,62 +49,116 @@ class RootControllerTest { when(currentUserService.getUserId()).thenReturn(UserTestFactory.ID); } + @DisplayName("Links for user") @Nested class TestLinks { - @Test - void shouldHaveSelfLink() { - var model = controller.getRootResource(); + @DisplayName("with any verwaltung role") + @Nested + class TestWithVerwaltungRole { - assertThat(model.getLink(IanaLinkRelations.SELF)).isPresent(); - } + @BeforeEach + void mockCurrentUserService() { + doReturn(true).when(controller).hasVerwaltungRole(); + } - @Test - void shouldHaveLinkToVorgangList() { - var model = controller.getRootResource(); + @Test + void shouldHaveSelfLink() { + var model = controller.getRootResource(); - assertThat(model.getLink(RootController.REL_VORGAENGE)).isPresent().get() - .extracting(Link::getHref).isEqualTo("/api/vorgangs"); - } + assertThat(model.getLink(IanaLinkRelations.SELF)).isPresent(); + } - @Test - void shouldHaveSearchLinkWithLimit() { - var model = controller.getRootResource(); + @Test + void shouldHaveLinkToVorgangList() { + var model = controller.getRootResource(); - assertThat(model.getLink(RootController.REL_SEARCH)).isPresent().get() - .extracting(Link::getHref).isEqualTo("/api/vorgangs?page=0{&searchBy,limit,assignedTo}"); - } + assertThat(model.getLink(RootController.REL_VORGAENGE)).isPresent().get() + .extracting(Link::getHref).isEqualTo("/api/vorgangs"); + } - @Test - void shouldHaveSearchUserLink() { - var model = controller.getRootResource(); + @Test + void shouldHaveSearchLinkWithLimit() { + var model = controller.getRootResource(); - assertThat(model.getLink(RootController.REL_SEARCH_USER)).isPresent().get().extracting(Link::getHref) - .isEqualTo("/api/userProfiles?searchBy={searchBy}"); - } + assertThat(model.getLink(RootController.REL_SEARCH)).isPresent().get() + .extracting(Link::getHref).isEqualTo("/api/vorgangs?page=0{&searchBy,limit,assignedTo}"); + } + + @Test + void shouldHaveSearchUserLink() { + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_SEARCH_USER)).isPresent().get().extracting(Link::getHref) + .isEqualTo("/api/userProfiles?searchBy={searchBy}"); + } + + @Test + void shoulHaveMyVorgaengeLink() { + var model = controller.getRootResource(); - @Test - void shoulHaveMyVorgaengeLink() { - var model = controller.getRootResource(); + assertThat(model.getLink(RootController.REL_MY_VORGAENGE)).isPresent().get().extracting(Link::getHref) + .isEqualTo("/api/vorgangs?page=0&assignedTo=" + UserTestFactory.ID.toString() + "{&searchBy,limit}"); + } - assertThat(model.getLink(RootController.REL_MY_VORGAENGE)).isPresent().get().extracting(Link::getHref) - .isEqualTo("/api/vorgangs?page=0&assignedTo=" + UserTestFactory.ID.toString() + "{&searchBy,limit}"); + @Test + void shoulHaveSearchMyVorgaengeLink() { + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_SEARCH_MY_VORGAENGE)).isPresent().get().extracting(Link::getHref) + .isEqualTo("/api/vorgangs?page=0&assignedTo=" + UserTestFactory.ID.toString() + "{&searchBy,limit}"); + } + + @Test + void shoulHaveDownloadTokenLink() { + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_DOWNLOAD_TOKEN)).isPresent().get().extracting(Link::getHref) + .isEqualTo("/api/downloadtoken"); + } } - @Test - void shoulHaveSearchMyVorgaengeLink() { - var model = controller.getRootResource(); + @DisplayName("with role " + UserRole.EINHEITLICHER_ANSPRECHPARTNER) + @Nested + class TestWithEinheitlicherAnsprechpartnerRole { + + @BeforeEach + void mock() { + when(currentUserService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER)).thenReturn(true); + + doReturn(false).when(controller).hasVerwaltungRole(); + } - assertThat(model.getLink(RootController.REL_SEARCH_MY_VORGAENGE)).isPresent().get().extracting(Link::getHref) - .isEqualTo("/api/vorgangs?page=0&assignedTo=" + UserTestFactory.ID.toString() + "{&searchBy,limit}"); + @Test + void shoulNotHaveMyVorgaengeLink() { + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_MY_VORGAENGE)).isNotPresent(); + } + + @Test + void shoulNotHaveSearchMyVorgaengeLink() { + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_SEARCH_MY_VORGAENGE)).isNotPresent(); + } } - @Test - void shoulHaveDownloadTokenLink() { - var model = controller.getRootResource(); + @DisplayName("with no role") + @Nested + class TestWithNoRole { + + @BeforeEach + void mockCurrentUserService() { + when(currentUserService.hasRole(anyString())).thenReturn(false); + } + + @Test + void shouldHaveNoLinkAtAll() { + var model = controller.getRootResource(); - assertThat(model.getLink(RootController.REL_DOWNLOAD_TOKEN)).isPresent().get().extracting(Link::getHref) - .isEqualTo("/api/downloadtoken"); + assertThat(model.getLinks()).isEmpty(); + } } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/SecurityTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/SecurityTestFactory.java index 68298120a8b3c8725f65488b6849f024a2fe0f38..50885feffbd1c88f245154f41d16db71bafec558 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/SecurityTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/SecurityTestFactory.java @@ -1,6 +1,7 @@ package de.itvsh.goofy; import java.util.Arrays; +import java.util.Collection; import java.util.List; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -14,4 +15,5 @@ public class SecurityTestFactory { static final String USER_LASTNAME = "Tester"; static final String ROLE = "Testrolle"; static final List<SimpleGrantedAuthority> AUTHORITIES = Arrays.asList(new SimpleGrantedAuthority(ROLE)); + static final Collection<String> ORGANSIATIONSEINHEIT_IDS = List.of("812546"); } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..119c69476263cf2451c055d215dfefcb07ce74cb --- /dev/null +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemServiceTest.java @@ -0,0 +1,275 @@ +package de.itvsh.goofy.common.attacheditem; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import static org.assertj.core.api.Assertions.*; + +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItem; +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItemService; +import de.itvsh.goofy.common.command.Command; +import de.itvsh.goofy.common.command.CommandBodyMapper; +import de.itvsh.goofy.common.command.CommandOrder; +import de.itvsh.goofy.common.command.CommandService; +import de.itvsh.goofy.common.command.CommandTestFactory; +import de.itvsh.goofy.common.command.CreateCommand; +import de.itvsh.goofy.kommentar.Kommentar; +import de.itvsh.goofy.kommentar.KommentarTestFactory; +import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; +import de.itvsh.goofy.wiedervorlage.Wiedervorlage; +import de.itvsh.goofy.wiedervorlage.WiedervorlageTestFactory; + +class VorgangAttachedItemServiceTest { + + @Spy + @InjectMocks + private VorgangAttachedItemService service; + @Mock + private CommandBodyMapper commandBodyMapper; + @Mock + private CommandService commandService; + + @DisplayName("Create new wiedervorlage") + @Nested + class TestCreateNewWiedervorlage { + + private Wiedervorlage wiedervorlage = WiedervorlageTestFactory.create(); + + @BeforeEach + void mockServices() { + doReturn(VorgangAttachedItemTestFactory.create()).when(service).buildVorgangAttachedItem(any(), any(), any()); + doReturn(CommandTestFactory.createCreateCommand()).when(service).buildCreateCommand(any(), any()); + } + + @Test + void shouldBuildVorgangAttachedItem() { + callCreateNewWiedervorlage(); + + verify(service).buildVorgangAttachedItem(wiedervorlage, VorgangHeaderTestFactory.ID, VorgangAttachedItemService.WIEDERVORLAGE_ITEM_NAME); + } + + @Test + void shouldBuildCreateCommand() { + callCreateNewWiedervorlage(); + + verify(service).buildCreateCommand(eq(VorgangHeaderTestFactory.ID), any(VorgangAttachedItem.class)); + } + + @Test + void shouldCallCommandService() { + callCreateNewWiedervorlage(); + + verify(commandService).createCommand(any(CreateCommand.class)); + } + + private Command callCreateNewWiedervorlage() { + return service.createNewWiedervorlage(wiedervorlage, VorgangHeaderTestFactory.ID); + } + } + + @DisplayName("Edit wiedervorlage") + @Nested + class TestEditWiedervorlage { + + private Wiedervorlage wiedervorlage = WiedervorlageTestFactory.create(); + + @BeforeEach + void mockService() { + doReturn(VorgangAttachedItemTestFactory.create()).when(service).buildVorgangAttachedItem(any(), any(), any()); + doReturn(CommandTestFactory.createCreateCommand()).when(service).buildUpdateCommand(any(), any(), any()); + } + + @Test + void shouldBuildVorgangAttachedItem() { + callEditWiedervorlage(); + + verify(service).buildVorgangAttachedItem(wiedervorlage, VorgangHeaderTestFactory.ID, VorgangAttachedItemService.WIEDERVORLAGE_ITEM_NAME); + } + + @Test + void shouldBuildCreateCommand() { + callEditWiedervorlage(); + + verify(service).buildUpdateCommand(eq(VorgangHeaderTestFactory.ID), eq(WiedervorlageTestFactory.ID), any(VorgangAttachedItem.class)); + } + + @Test + void shouldCallCommandService() { + callEditWiedervorlage(); + + verify(commandService).createCommand(any(CreateCommand.class), eq(WiedervorlageTestFactory.VERSION)); + } + + private Command callEditWiedervorlage() { + return service.editWiedervorlage(wiedervorlage, WiedervorlageTestFactory.ID, WiedervorlageTestFactory.VERSION); + } + + } + + @DisplayName("Create new kommentar") + @Nested + class TestCreateNewKommentar { + + private Kommentar kommentar = KommentarTestFactory.create(); + + @BeforeEach + void mockServices() { + doReturn(VorgangAttachedItemTestFactory.create()).when(service).buildVorgangAttachedItem(any(), any(), any()); + doReturn(CommandTestFactory.createCreateCommand()).when(service).buildCreateCommand(any(), any()); + } + + @Test + void shouldBuildVorgangAttachedItem() { + callCreateNewKommentar(); + + verify(service).buildVorgangAttachedItem(kommentar, VorgangHeaderTestFactory.ID, VorgangAttachedItemService.KOMMENTAR_ITEM_NAME); + } + + @Test + void shouldBuildCreateCommand() { + callCreateNewKommentar(); + + verify(service).buildCreateCommand(eq(VorgangHeaderTestFactory.ID), any(VorgangAttachedItem.class)); + } + + @Test + void shouldCallCommandService() { + callCreateNewKommentar(); + + verify(commandService).createCommand(any(CreateCommand.class)); + } + + private Command callCreateNewKommentar() { + return service.createNewKommentar(kommentar, VorgangHeaderTestFactory.ID); + } + } + + @DisplayName("Edit kommentar") + @Nested + class TestEditKommentar { + + private Kommentar kommentar = KommentarTestFactory.create(); + + @BeforeEach + void mockService() { + doReturn(VorgangAttachedItemTestFactory.create()).when(service).buildVorgangAttachedItem(any(), any(), any()); + doReturn(CommandTestFactory.createCreateCommand()).when(service).buildUpdateCommand(any(), any(), any()); + } + + @Test + void shouldBuildVorgangAttachedItem() { + callEditKommentar(); + + verify(service).buildVorgangAttachedItem(kommentar, VorgangHeaderTestFactory.ID, VorgangAttachedItemService.KOMMENTAR_ITEM_NAME); + } + + @Test + void shouldBuildCreateCommand() { + callEditKommentar(); + + verify(service).buildUpdateCommand(eq(VorgangHeaderTestFactory.ID), eq(KommentarTestFactory.ID), any(VorgangAttachedItem.class)); + } + + @Test + void shouldCallCommandService() { + callEditKommentar(); + + verify(commandService).createCommand(any(CreateCommand.class), eq(KommentarTestFactory.VERSION)); + } + + private Command callEditKommentar() { + return service.editKommentar(kommentar, KommentarTestFactory.ID, KommentarTestFactory.VERSION); + } + } + + @DisplayName("build vorgang attached item") + @Nested + class TestBuildVorgangAttachedItem { + + private static final Wiedervorlage BODY = WiedervorlageTestFactory.create(); + + @BeforeEach + void mockServices() { + when(commandBodyMapper.fromObjectToMap(any())).thenReturn(VorgangAttachedItemTestFactory.ITEM); + } + + @Test + void shouldCallCommandBodyMapper() { + buildVorgangAttachedItem(); + + verify(commandBodyMapper).fromObjectToMap(BODY); + } + + @Test + void shouldContainsVorgangId() { + var vorgangAttachedItem = buildVorgangAttachedItem(); + + assertThat(vorgangAttachedItem.getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldContainsItemName() { + var vorgangAttachedItem = buildVorgangAttachedItem(); + + assertThat(vorgangAttachedItem.getItemName()).isEqualTo(VorgangAttachedItemService.WIEDERVORLAGE_ITEM_NAME); + } + + @Test + void shouldContainsItem() { + var vorgangAttachedItem = buildVorgangAttachedItem(); + + assertThat(vorgangAttachedItem.getItem()).isEqualTo(VorgangAttachedItemTestFactory.ITEM); + } + + private VorgangAttachedItem buildVorgangAttachedItem() { + return service.buildVorgangAttachedItem(BODY, VorgangHeaderTestFactory.ID, + VorgangAttachedItemService.WIEDERVORLAGE_ITEM_NAME); + } + } + + @DisplayName("build createCommand") + @Nested + class TestBuildCreateCommand { + + @Test + void shouldContainsVorgangId() throws Exception { + var createCommand = buildCommand(); + + assertThat(createCommand.getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldContainsRelationId() throws Exception { + var createCommand = buildCommand(); + + assertThat(createCommand.getRelationId()).isEqualTo(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldContainsOrder() throws Exception { + var createCommand = buildCommand(); + + assertThat(createCommand.getOrder()).isEqualTo(CommandOrder.CREATE_ATTACHED_ITEM); + } + + @Test + void shouldContainsBody() throws Exception { + var createCommand = buildCommand(); + + assertThat(((VorgangAttachedItem) createCommand.getBody())).usingRecursiveComparison() + .isEqualTo(VorgangAttachedItemTestFactory.create()); + } + + private CreateCommand buildCommand() { + return service.buildCreateCommand(VorgangHeaderTestFactory.ID, VorgangAttachedItemTestFactory.create()); + } + } +} \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..4ea3c9250428a4fb96f62434c21b8abebecb4416 --- /dev/null +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/attacheditem/VorgangAttachedItemTestFactory.java @@ -0,0 +1,28 @@ +package de.itvsh.goofy.common.attacheditem; + +import java.util.Map; +import java.util.UUID; + +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItem; + +public class VorgangAttachedItemTestFactory { + + public static final String ID = UUID.randomUUID().toString(); + public static final long VERSION = 42; + public static final String CLIENT = "Goofy"; + public static final String ITEM_NAME = "ItemName"; + public static final Map<String, Object> ITEM = Map.of("oneKey", "oneValue"); + + public static VorgangAttachedItem create() { + return createBuilder().build(); + } + + public static VorgangAttachedItem.VorgangAttachedItemBuilder createBuilder() { + return VorgangAttachedItem.builder() + .id(ID) + .version(VERSION) + .client(CLIENT) + .itemName(ITEM_NAME) + .item(ITEM); + } +} \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/callcontext/ContextServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/callcontext/ContextServiceTest.java index 49e7829b3e547e51576dd069ecc16f601f7ecffb..6a3331f7260afc7f02743a60723632df1e8333d6 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/callcontext/ContextServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/callcontext/ContextServiceTest.java @@ -1,12 +1,13 @@ package de.itvsh.goofy.common.callcontext; import static de.itvsh.goofy.common.callcontext.ContextService.*; -import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collection; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -16,10 +17,13 @@ import org.springframework.context.ApplicationContext; import com.thedeanda.lorem.LoremIpsum; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.RequestAttributes; import de.itvsh.goofy.RequestAttributesTestFactory; import de.itvsh.goofy.common.GrpcUtil; import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.UserRole; import de.itvsh.goofy.common.user.UserTestFactory; import de.itvsh.ozg.pluto.grpc.command.GrpcUser; @@ -43,9 +47,15 @@ class ContextServiceTest { when(userService.getUser()).thenReturn(UserTestFactory.create()); } + @DisplayName("Get context metas") @Nested class TestGetContextMetas { + @BeforeEach + void mockUserService() { + when(userService.hasRole(any())).thenReturn(Boolean.TRUE); + } + @Test void shouldHaveUserId() { var metadata = service.buildCallContextMetadata(); @@ -75,6 +85,39 @@ class ContextServiceTest { assertThat(GrpcUtil.getCollection(KEY_ACCESS_LIMITED_ORGAID, metadata)).isInstanceOf(Collection.class).hasSize(2) .contains(UserTestFactory.ORGANISATORISCHE_EINHEITEN_ID, "orgaid_2"); } + + @DisplayName("access limited") + @Nested + class TestAccessLimitedByUserRole { + + @Test + void shouldHaveTrueOnRoleVerwaltungUser() { + when(userService.hasRole(anyString())).thenReturn(Boolean.FALSE); + + var metadata = service.buildCallContextMetadata(); + + assertThat(GrpcUtil.getFromHeaders(KEY_ACCESS_LIMITED, metadata)).isEqualTo(Boolean.TRUE.toString()); + } + + @Test + void shouldHaveFalseOnRoleVerwaltungPoststelle() { + when(userService.hasRole(UserRole.VERWALTUNG_POSTSTELLE)).thenReturn(Boolean.TRUE); + + var metadata = service.buildCallContextMetadata(); + + assertThat(GrpcUtil.getFromHeaders(KEY_ACCESS_LIMITED, metadata)).isEqualTo(Boolean.FALSE.toString()); + } + + @Test + void shouldHaveFalseOnRoleEinheitlicherAnsprechpartner() { + when(userService.hasRole(UserRole.VERWALTUNG_POSTSTELLE)).thenReturn(Boolean.FALSE); + when(userService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER)).thenReturn(Boolean.TRUE); + + var metadata = service.buildCallContextMetadata(); + + assertThat(GrpcUtil.getFromHeaders(KEY_ACCESS_LIMITED, metadata)).isEqualTo(Boolean.FALSE.toString()); + } + } } @Nested diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandBodyMapperTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandBodyMapperTest.java index 89c4004a925bfbe95f29bce96367f38fb174c470..6f1e3eeeedae9ce2bdd44d2089de4bd7132a81fc 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandBodyMapperTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandBodyMapperTest.java @@ -1,16 +1,22 @@ package de.itvsh.goofy.common.command; -import static org.assertj.core.api.Assertions.*; - import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Spy; + +import static org.assertj.core.api.Assertions.*; import de.itvsh.goofy.common.binaryfile.BinaryFileTestFactory; +import de.itvsh.goofy.postfach.PostfachMailTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; import de.itvsh.goofy.wiedervorlage.WiedervorlageTestFactory; import de.itvsh.ozg.pluto.grpc.command.GrpcCommandBody; @@ -21,8 +27,55 @@ class CommandBodyMapperTest { private static final String FIELD = "FIELD"; private static final String VALUE = "VALUE"; + @Spy private CommandBodyMapper mapper = Mappers.getMapper(CommandBodyMapper.class); + @DisplayName("Map from object to map") + @Nested + class TestFromObjectToMap { + + @Test + void shouldMapAllValues() { + var commandAsObject = CommandTestFactory.create(); + + var mappedMap = mapper.fromObjectToMap(commandAsObject); + + assertThat(mappedMap).hasSize(12) + .containsEntry("id", CommandTestFactory.ID) + .containsEntry("status", CommandTestFactory.STATUS.name()) + .containsEntry("order", CommandTestFactory.ORDER.name()) + .containsEntry("relationId", CommandTestFactory.RELATION_ID) + .containsEntry("vorgangId", CommandTestFactory.VORGANG_ID); + } + + @Test + void shouldNotMapClass() { + var commandAsObject = CommandTestFactory.create(); + + var mappedMap = mapper.fromObjectToMap(commandAsObject); + + assertThat(mappedMap).doesNotContainKey("class"); + } + + @Test + void shouldMapNullValue() { + var commandAsObject = CommandTestFactory.createBuilder().status(null).build(); + + var mappedMap = mapper.fromObjectToMap(commandAsObject); + + assertThat(mappedMap).containsEntry("status", null); + } + + @Test + void shouldNotMapVersion() { + var commandAsObject = WiedervorlageTestFactory.create(); + + var mappedMap = mapper.fromObjectToMap(commandAsObject); + + assertThat(mappedMap).doesNotContainKey("version"); + } + } + @Nested class TestMapToBody { @Test @@ -62,6 +115,10 @@ class CommandBodyMapperTest { @Nested class TestMapToBodyFields { + + @Captor + private ArgumentCaptor<Map<Object, Object>> mapCaptor; + @Test void shouldReturnEmptyListOnNull() { var result = mapper.mapToBodyFields((CommandBody) null); @@ -69,6 +126,20 @@ class CommandBodyMapperTest { assertThat(result).isEmpty(); } + @Test + void shouldContainFields() { + var fieldList = mapper.mapToBodyFields(PostfachMailTestFactory.create()); + + assertThat(fieldList).hasSize(13); + } + + @Test + void shouldNOTContainClassEntry() { + var fieldList = mapper.mapToBodyFields(PostfachMailTestFactory.create()); + + assertThat(fieldList).isNotEmpty().allMatch(field -> !StringUtils.equals(field.getName(), "class")); + } + @Test void shouldReturnField() { var result = mapper.mapToBodyFields(buildBodyMap()); @@ -83,10 +154,11 @@ class CommandBodyMapperTest { } @Test - void shouldFilterEntriesWithNullValue() { + void shouldMapNullAsEmptyValue() { var result = mapper.mapToBodyFields(buildBodyMapWithNullValue()); - assertThat(result).isEmpty(); + assertThat(result).hasSize(1); + assertThat(result.get(0).getValue()).isEmpty(); } private Map<Object, Object> buildBodyMapWithNullValue() { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java index bc28c4d6a83a72d6ff9e8ec8009bdf2aafbee2ec..a920b70120ac24cb3e397292a8ea963d49200f03 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java @@ -1,7 +1,6 @@ package de.itvsh.goofy.common.command; import static de.itvsh.goofy.common.command.CommandController.*; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -17,16 +16,20 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import static org.assertj.core.api.Assertions.*; + +import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; import de.itvsh.goofy.common.errorhandling.ExceptionController; import de.itvsh.goofy.postfach.PostfachMail; -import de.itvsh.goofy.postfach.PostfachMailController; import de.itvsh.goofy.postfach.PostfachMailTestFactory; +import de.itvsh.goofy.vorgang.AntragstellerTestFactory; import de.itvsh.goofy.vorgang.VorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; import de.itvsh.goofy.vorgang.VorgangWithEingangTestFactory; @@ -40,8 +43,6 @@ class CommandControllerTest { private CommandService service; @Mock private CommandModelAssembler modelAssembler; - @Mock - private VorgangController vorgangController; private MockMvc mockMvc; @@ -119,6 +120,7 @@ class CommandControllerTest { @Nested class TestCommandByRelationController { + @Spy @InjectMocks // NOSONAR private CommandByRelationController controller; @Mock @@ -127,8 +129,6 @@ class CommandControllerTest { private CommandModelAssembler modelAssembler; @Mock private VorgangController vorgangController; - @Mock - private PostfachMailController postfachController; private MockMvc mockMvc; @@ -160,8 +160,11 @@ class CommandControllerTest { void callService() throws Exception { doRequest(); - verify(service).createCommand(createCommandCaptor.capture(), eq(VorgangHeaderTestFactory.VERSION)); + verify(service).createCommand(createCommandCaptor.capture(), eq(CommandTestFactory.RELATION_VERSION)); assertThat(createCommandCaptor.getValue().getOrder()).isEqualTo(CommandTestFactory.ORDER); + assertThat(createCommandCaptor.getValue().getVorgangId()).isEqualTo(CommandTestFactory.VORGANG_ID); + assertThat(createCommandCaptor.getValue().getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); + assertThat(createCommandCaptor.getValue().getRelationVersion()).isZero(); } @DisplayName("should have location header") @@ -175,35 +178,13 @@ class CommandControllerTest { @DisplayName("CreateCommand with postfach mail") class WithPostfachMail { - @BeforeEach - void mockVorgangController() { - when(vorgangController.getVorgang(anyString())).thenReturn(VorgangWithEingangTestFactory.create()); - } - @Test - void shouldHavePostfachMail() throws Exception { - doRequest(PostfachMailTestFactory.buildSendPostfachMailContent()); + void shouldPrepareForPostfachNachricht() throws Exception { + doReturn(CommandTestFactory.createCreateCommand()).when(controller).prepareCommandForPostfachNachricht(any(), any()); - verify(service).createCommand(createCommandCaptor.capture(), anyLong()); - assertThat(createCommandCaptor.getValue()).extracting(CreateCommand::getBody).usingRecursiveComparison() - .ignoringFields("id", "vorgangId", "postfachId", "createdAt", "createdBy", "direction", "sentAt", "sentSuccessful", - "messageCode", - "attachments") // TODO remove this when sending attachments - .isEqualTo(PostfachMailTestFactory.create()); - } - - @Test - void shouldCallVorgangController() throws Exception { doRequest(PostfachMailTestFactory.buildSendPostfachMailContent()); - verify(vorgangController).getVorgang(VorgangHeaderTestFactory.ID); - } - - @Test - void shouldCallPostfachController() throws Exception { - doRequest(PostfachMailTestFactory.buildSendPostfachMailContent()); - - verify(postfachController).sendPostfachMail(anyString(), any(PostfachMail.class)); + verify(controller).prepareCommandForPostfachNachricht(any(), eq(VorgangHeaderTestFactory.ID)); } } @@ -224,32 +205,81 @@ class CommandControllerTest { } @Nested - class CreateByVorgangAndItemName { + class TestPrepareCommandForPostfachNachricht { - private static final String ITEM_NAME = "Wiedervorlage"; - private final CreateCommand command = CommandTestFactory.createCreateCommand(); + @BeforeEach + void mockVorgangController() { + when(vorgangController.getVorgang(anyString())).thenReturn(VorgangWithEingangTestFactory.create()); + } - @Nested - class WithValidation { + @Test + void shouldCallVorgangController() { + controller.prepareCommandForPostfachNachricht(createPostfachCreateCommand(), + VorgangHeaderTestFactory.ID); - @Test - void shouldCallService() { - controller.createCommand(command, ITEM_NAME); + verify(vorgangController).getVorgang(VorgangHeaderTestFactory.ID); + } - verify(service).createCommand(command, ITEM_NAME); - } + @Test + void shouldMapAttachments() { + var preparedCommand = controller.prepareCommandForPostfachNachricht(createPostfachCreateCommand(), VorgangHeaderTestFactory.ID); + + assertThat(((PostfachMail) preparedCommand.getBody()).getAttachments()).contains(FileId.from(PostfachMailTestFactory.ID)); } + @Test + void shouldAddPostfachId() { + var preparedCommand = controller.prepareCommandForPostfachNachricht(createPostfachCreateCommand(), VorgangHeaderTestFactory.ID); + + assertThat(((PostfachMail) preparedCommand.getBody()).getPostfachId()).isEqualTo(AntragstellerTestFactory.POSTFACH_ID); + } + + @Test + void shouldProceedWithEmptyAttachments() { + var createCommand = CommandTestFactory.createCreateCommandBuilder() + .body(PostfachMailTestFactory.createBuilder().clearAttachments().build()).build(); + + var preparedCommand = controller.prepareCommandForPostfachNachricht(createCommand, VorgangHeaderTestFactory.ID); + + assertThat(((PostfachMail) preparedCommand.getBody()).getAttachments()).isEmpty(); + } + + private CreateCommand createPostfachCreateCommand() { + var postfachNachricht = PostfachMailTestFactory.createBuilder().clearAttachments() + .attachment(FileId.from("api/resource/" + PostfachMailTestFactory.ID)).build(); + return CommandTestFactory.createCreateCommandBuilder().body(postfachNachricht).build(); + } + } + + @DisplayName("Create by vorgang with relation id") + @Nested + class TestCreateByVorgangWithoutRelationId { + + private final CreateCommand command = CommandTestFactory.createCreateCommand(); + + @Test + void shouldCallSerice() { + controller.createCommandWithoutRelation(command); + + verify(service).createCommandWithoutRelation(command); + } + } + + @Nested + class CreateByVorgangAndItemName { + + private static final String ITEM_NAME = "Wiedervorlage"; + private final CreateCommand command = CommandTestFactory.createCreateCommand(); + @Nested class WithoutValidation { @Test void shouldCallService() { - controller.createCommandWithoutValidation(command, ITEM_NAME); + controller.createCommandWithoutValidation(command, ITEM_NAME, CommandTestFactory.RELATION_VERSION); - verify(service).createCommandWithoutValidation(command, ITEM_NAME); + verify(service).createCommandWithoutValidation(command, ITEM_NAME, CommandTestFactory.RELATION_VERSION); } - } } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java index ca0b874eddb7bf5fd8c6e99427081766af79a5f8..0aff0b1a2396b22a28acae4957f99cb21cc7ca37 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.common.command; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -22,6 +21,8 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.ValidationMessageCodes; import de.itvsh.goofy.common.user.UserTestFactory; import de.itvsh.goofy.postfach.PostfachMailTestFactory; @@ -52,14 +53,14 @@ public class CommandITCase { @BeforeEach void initTests() { - when(commandRemoteService.createCommand(any(), anyLong())).thenReturn(CommandTestFactory.create()); + when(commandRemoteService.createCommand(any())).thenReturn(CommandTestFactory.create()); } @Test void shouldExtractUserId() throws Exception { createCommand(); - verify(commandRemoteService).createCommand(commandCaptor.capture(), anyLong()); + verify(commandRemoteService).createCommand(commandCaptor.capture()); assertThat(commandCaptor.getValue().getBody()).hasFieldOrPropertyWithValue("assignedTo", UserTestFactory.ID); } @@ -180,7 +181,7 @@ public class CommandITCase { @BeforeEach void initMockCommand() { - when(commandRemoteService.createCommand(any(CreateCommand.class), anyLong())).thenReturn(CommandTestFactory.create()); + when(commandRemoteService.createCommand(any(CreateCommand.class))).thenReturn(CommandTestFactory.create()); } @Test @@ -232,7 +233,7 @@ public class CommandITCase { @Test void shouldProceedOnValidInput() throws Exception { - when(commandRemoteService.createCommand(any(CreateCommand.class), anyLong())).thenReturn(CommandTestFactory.create()); + when(commandRemoteService.createCommand(any(CreateCommand.class))).thenReturn(CommandTestFactory.create()); var content = PostfachMailTestFactory.buildSendPostfachMailContent(); @@ -243,7 +244,7 @@ public class CommandITCase { ResultActions doRequest(String content) throws Exception { return mockMvc.perform(post("/api/vorgangs/" + CommandTestFactory.VORGANG_ID + "/relations/" + CommandTestFactory.RELATION_ID + "/" - + CommandTestFactory.VERSION + "/commands") + + CommandTestFactory.RELATION_VERSION + "/commands") .contentType(MediaType.APPLICATION_JSON) .content(content)); } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandMapperTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..10ef5468a4fb0ddebedfd17aae38d5da074da314 --- /dev/null +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandMapperTest.java @@ -0,0 +1,41 @@ +package de.itvsh.goofy.common.command; + +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import static org.assertj.core.api.Assertions.*; + +import de.itvsh.goofy.common.TimeMapper; +import de.itvsh.goofy.common.callcontext.CallContextMapper; +import de.itvsh.goofy.common.user.UserIdMapper; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; +import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; + +class CommandMapperTest { + + @InjectMocks + private CommandMapper mapper = Mappers.getMapper(CommandMapper.class); + @Mock + private UserIdMapper userIdMapper; + @Mock + private GrpcObjectMapper grpcObjectMapper; + @Mock + private CommandBodyMapper bodyMapper; + @Mock + private TimeMapper timeMapper; + @Mock + private CallContextMapper callContextMapper; + + @Test + void shouldMapNonEnumOrder() { + var command = mapper.toCommand(GrpcCommandTestFactory.createBuilder() + .setOrder(GrpcOrder.UNDEFINED) + .setOrderString(CommandOrder.SEND_POSTFACH_NACHRICHT.name()) + .build()); + + assertThat(command.getOrder()).isEqualTo(CommandOrder.SEND_POSTFACH_NACHRICHT); + } + +} diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandModelAssemblerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandModelAssemblerTest.java index 095cd13ee643f93b18fd3669b01818566b0610ec..60795b04bf34f24b95dd21b33faee21bad70d6bd 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandModelAssemblerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandModelAssemblerTest.java @@ -2,7 +2,6 @@ package de.itvsh.goofy.common.command; import static de.itvsh.goofy.common.command.CommandModelAssembler.*; import static de.itvsh.goofy.common.command.CommandTestFactory.*; -import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -15,6 +14,8 @@ import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; class CommandModelAssemblerTest { @@ -160,7 +161,8 @@ class CommandModelAssemblerTest { @ParameterizedTest @EnumSource(mode = Mode.EXCLUDE, names = { "CREATE_WIEDERVORLAGE", "WIEDERVORLAGE_ERLEDIGEN", "EDIT_WIEDERVORLAGE", "WIEDERVORLAGE_WIEDEREROEFFNEN", "CREATE_KOMMENTAR", "EDIT_KOMMENTAR", "REDIRECT_VORGANG", "FORWARD_SUCCESSFULL", - "FORWARD_FAILED", "ASSIGN_USER", "SEND_POSTFACH_MAIL", "RESEND_POSTFACH_MAIL", "CREATE_ATTACHED_ITEM", "UPDATE_ATTACHED_ITEM" }) + "FORWARD_FAILED", "ASSIGN_USER", "SEND_POSTFACH_MAIL", "SEND_POSTFACH_NACHRICHT", "RESEND_POSTFACH_MAIL", "CREATE_ATTACHED_ITEM", + "UPDATE_ATTACHED_ITEM" }) void shouldHaveLink(CommandOrder order) { var model = toModelWithOrder(order); diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandRemoteServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandRemoteServiceTest.java index e187d76d1f402fba6bf262698365cf77221854c4..3e687d3a2c49b701a06b0547d922a4e57cb4a2fe 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandRemoteServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandRemoteServiceTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.common.command; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -23,10 +22,13 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.callcontext.ContextService; import de.itvsh.goofy.vorgang.RedirectRequestTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectTestFactory; import de.itvsh.ozg.pluto.common.GrpcObject; import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; @@ -76,28 +78,28 @@ class CommandRemoteServiceTest { @BeforeEach void initTest() { - doReturn(request).when(service).buildCreateCommandRequest(any(), anyLong()); + doReturn(request).when(service).buildCreateCommandRequest(any()); when(commandServiceStub.createCommand(any())).thenReturn(GrpcCommandResponse.newBuilder().build()); when(mapper.toCommand(any())).thenReturn(resultCommand); } @Test void shouldCreateRequest() { - service.createCommand(createCommand, CommandTestFactory.VERSION); + service.createCommand(createCommand); - verify(service).buildCreateCommandRequest(createCommand, CommandTestFactory.VERSION); + verify(service).buildCreateCommandRequest(createCommand); } @Test void shouldCallServiceStub() { - service.createCommand(createCommand, CommandTestFactory.VERSION); + service.createCommand(createCommand); verify(commandServiceStub).createCommand(request); } @Test void shouldReturnResultCommand() { - var result = service.createCommand(createCommand, CommandTestFactory.VERSION); + var result = service.createCommand(createCommand); assertThat(result).isSameAs(resultCommand); } @@ -111,6 +113,7 @@ class CommandRemoteServiceTest { @BeforeEach void initTest() { when(contextService.createCallContext()).thenReturn(grpcCallContext); + when(grpcObjectMapper.fromMap(any())).thenReturn(GrpcObjectTestFactory.create()); } @Test @@ -124,7 +127,7 @@ class CommandRemoteServiceTest { void shouldHaveOrder() { var request = buildRequest(); - assertThat(request.getOrder().name()).isEqualTo(CommandTestFactory.ORDER.name()); + assertThat(request.getOrderString()).isEqualTo(CommandTestFactory.ORDER.name()); } @Test @@ -148,6 +151,20 @@ class CommandRemoteServiceTest { assertThat(request.getVorgangId()).isEqualTo(CommandTestFactory.VORGANG_ID); } + @Test + void shouldCallBodyMapper() { + buildRequest(); + + verify(bodyMapper).fromObjectToMap(any(CommandBody.class)); + } + + @Test + void shouldCallObjectMapper() { + buildRequest(); + + verify(grpcObjectMapper).fromMap(any()); + } + @Test void shouldHaveVersion() { var request = buildRequest(); @@ -160,7 +177,7 @@ class CommandRemoteServiceTest { when(mapper.toGrpcRedirectRequest(any())).thenReturn(grpcRedirectRequest); var command = CommandTestFactory.createCreateCommandBuilder().redirectRequest(RedirectRequestTestFactory.create()).build(); - var request = service.buildCreateCommandRequest(command, CommandTestFactory.VERSION); + var request = service.buildCreateCommandRequest(command); assertThat(request.getRedirectRequest()).isNotNull().isSameAs(grpcRedirectRequest); } @@ -168,14 +185,14 @@ class CommandRemoteServiceTest { @ParameterizedTest @EnumSource void shouldHaveOrder(CommandOrder order) { - var request = service.buildCreateCommandRequest(CommandTestFactory.createCreateCommandBuilder().order(order).build(), - CommandTestFactory.VERSION); + var request = service.buildCreateCommandRequest(CommandTestFactory.createCreateCommandBuilder().order(order).build()); - assertThat(request.getOrder()).hasToString(order.name()); + assertThat(request.getOrderString()).isEqualTo(order.name()); } private GrpcCreateCommandRequest buildRequest() { - return service.buildCreateCommandRequest(CommandTestFactory.createCreateCommand(), CommandTestFactory.VERSION); + return service.buildCreateCommandRequest( + CommandTestFactory.createCreateCommandBuilder().body(RedirectRequestTestFactory.create()).build()); } } } @@ -243,17 +260,17 @@ class CommandRemoteServiceTest { } @Test - void shouldContainsVorgangIdAsRelationId() { + void shouldContainsRelationId() { var request = buildRequest(); - assertThat(request.getRelationId()).isEqualTo(CommandTestFactory.VORGANG_ID); + assertThat(request.getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); } @Test void shouldContainsRelationVersion() { var request = buildRequest(); - assertThat(request.getRelationVersion()).isEqualTo(-1); + assertThat(request.getRelationVersion()).isEqualTo(CommandTestFactory.RELATION_VERSION); } @Test @@ -264,10 +281,10 @@ class CommandRemoteServiceTest { } @Test - void shouldContainsOrder() { + void shouldContainsOrderString() { var request = buildRequest(); - assertThat(request.getOrder()).isEqualTo(GrpcOrder.VORGANG_ANNEHMEN); + assertThat(request.getOrderString()).isEqualTo(GrpcOrder.VORGANG_ANNEHMEN.name()); } private GrpcCreateCommandRequest buildRequest() { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandServiceTest.java index acd0c9ad4631dfe38a8eddc7a2f293dd66e2b706..4c49293df735c22d7bb628daa17870c1285aa927 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandServiceTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.common.command; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -11,6 +10,8 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; class CommandServiceTest { @@ -28,27 +29,61 @@ class CommandServiceTest { private final CreateCommand command = CommandTestFactory.createCreateCommand(); - @Test - void shouldCallRemoteServiceWithVersion() { - service.createCommand(command, CommandTestFactory.VERSION); + @Nested + class TestWithCreateCommandOnly { + + @Test + void shouldCallRemoteService() { + service.createCommand(command); + + verify(remoteService).createCommand(any(CreateCommand.class)); + } - verify(remoteService).createCommand(command, CommandTestFactory.VERSION); + @Test + void shouldHaveSetRelationVersion() { + service.createCommand(command); + + verify(remoteService).createCommand(createCommandCaptor.capture()); + assertThat(createCommandCaptor.getValue().getRelationVersion()).isEqualTo(CommandService.NO_RELATION_VERSION); + } } - @Test - void shouldHaveVorgangId() { - service.createCommand(command, CommandTestFactory.VERSION); + @Nested + class TestWithRelationVersion { + + @Test + void shouldCallRemoteService() { + service.createCommand(command, CommandTestFactory.RELATION_VERSION); + + verify(remoteService).createCommand(any(CreateCommand.class)); + } - verify(remoteService).createCommand(createCommandCaptor.capture(), anyLong()); - assertThat(createCommandCaptor.getValue().getVorgangId()).isEqualTo(CommandTestFactory.VORGANG_ID); + @Test + void shouldHaveSetRelationVersion() { + service.createCommand(command, CommandTestFactory.RELATION_VERSION); + + verify(remoteService).createCommand(createCommandCaptor.capture()); + assertThat(createCommandCaptor.getValue().getRelationVersion()).isEqualTo(CommandTestFactory.RELATION_VERSION); + } } - @Test - void shouldHaveRelationId() { - service.createCommand(command, CommandTestFactory.VERSION); + @Nested + class TestWithoutRelationVersion { + + @Test + void shouldCallRemoteService() { + service.createCommandWithoutRelation(command); + + verify(remoteService).createCommand(any(CreateCommand.class)); + } - verify(remoteService).createCommand(createCommandCaptor.capture(), anyLong()); - assertThat(createCommandCaptor.getValue().getRelationId()).isEqualTo(CommandTestFactory.RELATION_ID); + @Test + void shouldHaveSetRelationVersion() { + service.createCommandWithoutRelation(command); + + verify(remoteService).createCommand(createCommandCaptor.capture()); + assertThat(createCommandCaptor.getValue().getRelationVersion()).isEqualTo(CommandService.NO_RELATION_VERSION); + } } } @@ -59,24 +94,21 @@ class CommandServiceTest { private final CreateCommand command = CommandTestFactory.createCreateCommand(); @Nested - class WithValidation { + class WithoutValidation { @Test void shouldCallRemoteService() { - service.createCommand(command, ITEM_NAME); + service.createCommandWithoutValidation(command, ITEM_NAME, CommandTestFactory.RELATION_VERSION); - verify(remoteService).createCommand(command, ITEM_NAME); + verify(remoteService).createCommand(any(CreateCommand.class), eq(ITEM_NAME)); } - } - - @Nested - class WithoutValidation { @Test - void shouldCallRemoteService() { - service.createCommandWithoutValidation(command, ITEM_NAME); + void shouldHaveSetRelationVersion() { + service.createCommandWithoutValidation(command, ITEM_NAME, CommandTestFactory.RELATION_VERSION); - verify(remoteService).createCommand(command, ITEM_NAME); + verify(remoteService).createCommand(createCommandCaptor.capture(), eq(ITEM_NAME)); + assertThat(createCommandCaptor.getValue().getRelationVersion()).isEqualTo(CommandTestFactory.RELATION_VERSION); } } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandTestFactory.java index 0cebc6cf3ae6aa0cc843a73ded18ab21614c22e0..84072f84de42653a03d1f050b6c20c2dd2f46d74 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandTestFactory.java @@ -13,7 +13,7 @@ public class CommandTestFactory { public static final CommandOrder ORDER = CommandOrder.VORGANG_ANNEHMEN; public static final String RELATION_ID = ForwardingTestFactory.ID; - public static final long VERSION = VorgangHeaderTestFactory.VERSION; + public static final long RELATION_VERSION = VorgangHeaderTestFactory.VERSION; public static Command create() { return createBuilder().build(); @@ -36,6 +36,7 @@ public class CommandTestFactory { return CreateCommand.builder() .vorgangId(VORGANG_ID) .relationId(RELATION_ID) + .relationVersion(RELATION_VERSION) .order(ORDER); } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/GrpcCommandTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/GrpcCommandTestFactory.java index e974fd071f39dfc6e8366f5455690ee5225a9b92..37a52409f588d74043237f56d6f997923fe1ce45 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/GrpcCommandTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/GrpcCommandTestFactory.java @@ -4,15 +4,28 @@ import java.util.UUID; import de.itvsh.goofy.common.GrpcCallContextTestFactory; import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; +import de.itvsh.ozg.pluto.grpc.command.GrpcCommand; import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; import de.itvsh.ozg.pluto.grpc.command.GrpcOrder; public class GrpcCommandTestFactory { private static final String RELATION_ID = UUID.randomUUID().toString(); + private static final CommandStatus STATUS = CommandStatus.PENDING; private static final GrpcOrder ORDER = GrpcOrder.RESEND_POSTFACH_MAIL; private static final GrpcCallContext CALL_CONTEXT = GrpcCallContextTestFactory.create(); + public static GrpcCommand create() { + return createBuilder().build(); + } + + public static GrpcCommand.Builder createBuilder() { + return GrpcCommand.newBuilder() + .setStatus(STATUS.name()) + .setRelationId(RELATION_ID) + .setOrder(ORDER); + } + public static GrpcCreateCommandRequest createCommandRequest() { return createCommandRequestBuilder().build(); } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenAuthenticationFilterITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenAuthenticationFilterITCase.java index 260ec0db0d19212af471df04315e95f3d70adee9..479e63fb7804e00e7f792bea1c96fdcc2f77f372 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenAuthenticationFilterITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenAuthenticationFilterITCase.java @@ -45,6 +45,17 @@ class DownloadTokenAuthenticationFilterITCase { verify(filter).doFilterInternal(any(), any(), any()); } + @Test + void shouldCallFilterWhenNoOrganisationseinheitIds() throws Exception { + String token = DownloadTokenTestFactory.createTokenBuilder(downloadTokenProperties.getSecret(), downloadTokenProperties.getValidity()) + .setClaims(DownloadTokenTestFactory.CLAIMS_WITHOUT_ORGANSIATIONSEINHEIT_IDS).compact(); + + performRequest(DownloadTokenController.DOWNLOAD_TOKEN_PATH + "?" + DownloadTokenController.PARAM_TOKEN + "=" + token) + .andExpect(status().isOk()); + + verify(filter).doFilterInternal(any(), any(), any()); + } + @Test void shouldReturnUnauthorised() throws Exception { String token = DownloadTokenTestFactory.createToken("badSecret", downloadTokenProperties.getValidity()); diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java index d5b9f9e614f9d18d40bb37f267c7cc53928e5e56..d15ad742cb3d2f1fe6b4ee2feff81bc641363e95 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.Collection; +import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; @@ -41,6 +43,7 @@ class DownloadTokenServiceTest { private HttpServletResponse response; private final static String FAKE_TOKEN = "xxx"; + private final static Collection<String> ORGE_IDS = List.of("258994"); @Nested class TestCreateToken { @@ -99,10 +102,23 @@ class DownloadTokenServiceTest { assertThat(user).isNotNull(); } + @Test + void shouldGetOrganisationseinheitIdsFromToken() { + mockClaims(FIRSTNAME_CLAIM, LASTNAME_CLAIM); + + GoofyUser user = service.getUserFromToken(FAKE_TOKEN).getUser(); + + assertThat(user.getOrganisationseinheitIds()).isEqualTo(ORGE_IDS); + } + private void mockClaims(String firstnameClaim, String lastnameClaim) { Claims claims = mock(Claims.class); + when(claims.get(FIRSTNAME_CLAIM, String.class)).thenReturn(firstnameClaim); when(claims.get(LASTNAME_CLAIM, String.class)).thenReturn(lastnameClaim); + when(claims.get(USERID_CLAIM, String.class)).thenReturn(UserTestFactory.ID.toString()); + + when(jwtTokenUtil.getOrganisationseinheitIdsFromToken(any())).thenReturn(ORGE_IDS); when(jwtTokenUtil.getAllClaimsFromToken(any())).thenReturn(Optional.of(claims)); } @@ -119,6 +135,7 @@ class DownloadTokenServiceTest { assertThrows(TechnicalException.class, () -> handleToken()); } + } void handleToken() { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenTestFactory.java index 884ec1e1d43a663e2219ae17a6ae7f88242f4752..d549a1e792b12848c51aeb2fa9cb47b074a2d7c5 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenTestFactory.java @@ -2,6 +2,7 @@ package de.itvsh.goofy.common.downloadtoken; import static de.itvsh.goofy.JwtTokenUtil.*; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -17,9 +18,15 @@ public class DownloadTokenTestFactory { static final String SUBJECT = "subject"; static final String FIRSTNAME_CLAIM_VALUE = UserTestFactory.FIRSTNAME; static final String LASTNAME_CLAIM_VALUE = UserTestFactory.LASTNAME; + final static Collection<String> ORGE_IDS = List.of("258994"); static final List<?> ROLE_CLAIM_VALUE = List.of(); static final long VALIDITY = 5000; static final Map<String, Object> CLAIMS = new HashMap<>(Map.of( + FIRSTNAME_CLAIM, FIRSTNAME_CLAIM_VALUE, + LASTNAME_CLAIM, LASTNAME_CLAIM_VALUE, + ROLE_CLAIM, ROLE_CLAIM_VALUE, + ORGANSIATIONSEINHEIT_IDS_CLAIM, ORGE_IDS)); + static final Map<String, Object> CLAIMS_WITHOUT_ORGANSIATIONSEINHEIT_IDS = new HashMap<>(Map.of( FIRSTNAME_CLAIM, FIRSTNAME_CLAIM_VALUE, LASTNAME_CLAIM, LASTNAME_CLAIM_VALUE, ROLE_CLAIM, ROLE_CLAIM_VALUE)); diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/user/GoofyUserTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/common/user/GoofyUserTestFactory.java index dd713bdae5e65d6ada50b375071cc6adefb25c4c..fb8a5c667c83e35d0b986946b6a2c45cb59116ff 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/user/GoofyUserTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/user/GoofyUserTestFactory.java @@ -1,15 +1,20 @@ package de.itvsh.goofy.common.user; +import java.util.UUID; + import de.itvsh.goofy.vorgang.ZustaendigeStelleTestFactory; public class GoofyUserTestFactory { + public static final UserId ID = UserId.from(UUID.randomUUID().toString()); + public static GoofyUser create() { return createBuilder().build(); } public static GoofyUser.GoofyUserBuilder createBuilder() { return GoofyUser.builder() + .id(ID) .organisationseinheitId(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java index 3eb84c3ec6ae60f487ba067875086369004b81bc..f9332017ddd6264e6dd06c77e9d5f6126fd40282 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandControllerTest.java @@ -1,14 +1,11 @@ package de.itvsh.goofy.kommentar; import static de.itvsh.goofy.kommentar.KommentarCommandTestFactory.*; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import java.util.UUID; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -16,17 +13,14 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; -import de.itvsh.goofy.common.command.CommandOrder; import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.common.command.CreateCommand; -import de.itvsh.goofy.common.user.CurrentUserService; -import de.itvsh.goofy.common.user.UserId; import de.itvsh.goofy.kommentar.KommentarCommandController.KommentarCommandByVorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -38,53 +32,37 @@ class KommentarCommandControllerTest { @Nested class TestCreateKommentarCommandByVorgang { + @Spy @InjectMocks private KommentarCommandByVorgangController controller; @Mock private KommentarService service; - @Mock - private CommandByRelationController commandByRelationController; - @Mock - private CurrentUserService userService; private MockMvc mockMvc; @BeforeEach void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - when(userService.getUserId()).thenReturn(UserId.from(UUID.randomUUID())); - when(commandByRelationController.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); - } - @Test - void shouldReturnCreated() throws Exception { - doRequest().andExpect(status().isCreated()); + when(service.createKommentar(any(), any())).thenReturn(CommandTestFactory.create()); } @Test void shouldCallService() throws Exception { doRequest(); - verify(commandByRelationController).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME)); + verify(service).createKommentar(any(Kommentar.class), eq(VorgangHeaderTestFactory.ID)); } @Test - void shouldGiveCommandToService() throws Exception { - doRequest(); - - verify(commandByRelationController).createCommand(commandCaptor.capture(), anyString()); - var command = commandCaptor.getValue(); - - assertThat(command).usingRecursiveComparison() - .ignoringFields("body", "status") - .isEqualTo(CommandTestFactory.createBuilder().order(CommandOrder.CREATE_ATTACHED_ITEM) - .relationId(KommentarCommandController.NOT_SET) - .id(null).build()); + void shouldReturnCreated() throws Exception { + doRequest().andExpect(status().isCreated()); } private ResultActions doRequest() throws Exception { - return mockMvc.perform(post(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG, VorgangHeaderTestFactory.ID) - .content(createValidRequestContent()).contentType(MediaType.APPLICATION_JSON)) + return mockMvc.perform( + post(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG, VorgangHeaderTestFactory.ID) + .content(createValidRequestContent()).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().is2xxSuccessful()); } } @@ -92,13 +70,12 @@ class KommentarCommandControllerTest { @Nested class TestCreateEditKommentarCommand { - final String REPONSE_HEADER = "http://localhost/api/commands/" + KommentarCommandTestFactory.ID; + private final static String REPONSE_HEADER = "http://localhost/api/commands/" + KommentarCommandTestFactory.ID; + @Spy @InjectMocks private KommentarCommandController controller; @Mock - private CommandByRelationController commandByRelationController; - @Mock private KommentarService service; private MockMvc mockMvc; @@ -106,34 +83,20 @@ class KommentarCommandControllerTest { @BeforeEach void init() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - when(commandByRelationController.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); - when(service.getById(any())).thenReturn(KommentarTestFactory.createBuilder().vorgangId(VorgangHeaderTestFactory.ID).build()); - } - @Test - void shouldReturnCreated() throws Exception { - doRequest().andExpect(status().isCreated()); + when(service.editKommentar(any(), any(), anyLong())).thenReturn(CommandTestFactory.create()); } @Test void shouldCallService() throws Exception { doRequest(); - verify(service).getById(any()); + verify(service).editKommentar(any(Kommentar.class), eq(KommentarTestFactory.ID), eq(KommentarTestFactory.VERSION)); } @Test - void shouldGiveCommandToService() throws Exception { - doRequest(); - - verify(commandByRelationController).createCommand(commandCaptor.capture(), anyString()); - var command = commandCaptor.getValue(); - - assertThat(command).usingRecursiveComparison() - .ignoringFields("body", "status") - .isEqualTo(CommandTestFactory.createBuilder().order(CommandOrder.UPDATE_ATTACHED_ITEM) - .relationId(KommentarCommandController.NOT_SET).id(null) - .build()); + void shouldReturnCreated() throws Exception { + doRequest().andExpect(status().isCreated()); } @Test @@ -143,7 +106,7 @@ class KommentarCommandControllerTest { ResultActions doRequest() throws Exception { String content = createValidRequestContent(); - return mockMvc.perform(post(KommentarCommandController.KOMMENTAR_COMMANDS, KommentarTestFactory.ID) + return mockMvc.perform(post(KommentarCommandController.KOMMENTAR_COMMANDS, KommentarTestFactory.ID, KommentarTestFactory.VERSION) .content(content).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().is2xxSuccessful()); } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java index 37c96c2c937358f455fab7fcc967503267cf42ab..ef360511deca6b6b066d4e30a18be240a536be03 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandITCase.java @@ -46,14 +46,14 @@ class KommentarCommandITCase { @BeforeEach void initTest() { when(remoteService.getById(any())).thenReturn(KommentarTestFactory.create()); - when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); + when(commandRemoteService.createCommand(any())).thenReturn(CommandTestFactory.create()); } @Test void shouldCreateCommand() throws Exception { doRequestByKommentarId(createValidRequestContent()).andExpect(status().isCreated()); - verify(commandRemoteService).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME)); + verify(commandRemoteService).createCommand(any()); } @WithMockUser @@ -68,7 +68,7 @@ class KommentarCommandITCase { doRequestByKommentarId(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")) + .andExpect(jsonPath("$.issues.[0].field").value("kommentar.text")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -78,7 +78,7 @@ class KommentarCommandITCase { String content = buildContentWithText(StringUtils.EMPTY); doRequestByKommentarId(content).andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")); + .andExpect(jsonPath("$.issues.[0].field").value("kommentar.text")); } @@ -100,7 +100,7 @@ class KommentarCommandITCase { } private ResultActions doRequestByKommentarId(String content) throws Exception { - return mockMvc.perform(post(KommentarCommandController.KOMMENTAR_COMMANDS, KommentarTestFactory.ID) + return mockMvc.perform(post(KommentarCommandController.KOMMENTAR_COMMANDS, KommentarTestFactory.ID, KommentarTestFactory.VERSION) .contentType(MediaType.APPLICATION_JSON) .content(content)); } @@ -110,17 +110,19 @@ class KommentarCommandITCase { @Nested class TestCreateCommandByVorgangId { + private static final long RELATION_ID_ON_CREATE = -1; + @BeforeEach void initTest() { when(remoteService.getById(any())).thenReturn(KommentarTestFactory.create()); - when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); + when(commandRemoteService.createCommand(any())).thenReturn(CommandTestFactory.create()); } @Test void shouldCreateCommand() throws Exception { doRequestByVorgangId(createValidRequestContent()).andExpect(status().isCreated()); - verify(commandRemoteService).createCommand(any(), eq(KommentarRemoteService.ITEM_NAME)); + verify(commandRemoteService).createCommand(any()); } @WithMockUser @@ -135,7 +137,7 @@ class KommentarCommandITCase { doRequestByVorgangId(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")) + .andExpect(jsonPath("$.issues.[0].field").value("kommentar.text")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -145,7 +147,7 @@ class KommentarCommandITCase { String content = buildContentWithText(StringUtils.EMPTY); doRequestByVorgangId(content).andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.text")); + .andExpect(jsonPath("$.issues.[0].field").value("kommentar.text")); } @@ -167,9 +169,10 @@ class KommentarCommandITCase { } private ResultActions doRequestByVorgangId(String content) throws Exception { - return mockMvc.perform(post(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG, VorgangHeaderTestFactory.ID) - .contentType(MediaType.APPLICATION_JSON) - .content(content)); + return mockMvc.perform(post(KommentarCommandByVorgangController.KOMMENTAR_COMMANDS_BY_VORGANG, VorgangHeaderTestFactory.ID, + RELATION_ID_ON_CREATE) + .contentType(MediaType.APPLICATION_JSON) + .content(content)); } } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java index 74380e47bbbb5e6315f72c9cac7853d6aaf961a2..b059c5ec3dd1177dfd22673b6aa73594abf671e5 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarMapperTest.java @@ -1,17 +1,58 @@ package de.itvsh.goofy.kommentar; -import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import static org.assertj.core.api.Assertions.*; + +import de.itvsh.goofy.vorgang.GrpcVorgangAttachedItemTestFactory; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; class KommentarMapperTest { + @Spy + @InjectMocks private KommentarMapper mapper = Mappers.getMapper(KommentarMapper.class); + @Mock + private GrpcObjectMapper grpcObjectMapper; + @DisplayName("Map from item") + @Nested + class TestFromItem { + + @BeforeEach + void mockMapper() { + when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(KommentarTestFactory.createAsMap()); + } + + @Test + void shouldCallGrpcObjectMapper() { + mapper.fromItem(GrpcVorgangAttachedItemTestFactory.create()); + + verify(grpcObjectMapper).mapFromGrpc(GrpcVorgangAttachedItemTestFactory.ITEM); + } + + @Test + void shouldCallMapperFromItemMap() { + mapper.fromItem(GrpcVorgangAttachedItemTestFactory.create()); + + verify(mapper).fromItemMap(KommentarTestFactory.createAsMap(), KommentarTestFactory.VERSION); + } + } + + @DisplayName("Map from item map") @Nested class TestFromItemMap { + @Test void shouldMapId() { var kommentar = map(); @@ -19,6 +60,13 @@ class KommentarMapperTest { assertThat(kommentar.getId()).isEqualTo(KommentarTestFactory.ID); } + @Test + void shouldMapVersion() { + var kommentar = map(); + + assertThat(kommentar.getVersion()).isEqualTo(KommentarTestFactory.VERSION); + } + @Test void shouldMapCreatedBy() { var kommentar = map(); @@ -42,6 +90,6 @@ class KommentarMapperTest { } private Kommentar map() { - return mapper.fromItemMap(KommentarTestFactory.createAsMap()); + return mapper.fromItemMap(KommentarTestFactory.createAsMap(), KommentarTestFactory.VERSION); } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarModelAssemblerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarModelAssemblerTest.java index 250e85a35dc78caf6645cf7119933390e194a127..9e605466c1e115ca671e7152d75376ba46ada19d 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarModelAssemblerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarModelAssemblerTest.java @@ -1,7 +1,5 @@ package de.itvsh.goofy.kommentar; -import static org.assertj.core.api.Assertions.*; - import java.util.Collections; import org.junit.jupiter.api.Nested; @@ -13,6 +11,8 @@ import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.hateoas.server.EntityLinks; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.user.UserProfileTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -31,7 +31,9 @@ class KommentarModelAssemblerTest { class TestLinksOnModel { final String COMMAND_BY_KOMMENTAR_PATH = // - KommentarCommandController.KOMMENTAR_COMMANDS.replace("{kommentarId}", KommentarTestFactory.ID); + KommentarCommandController.KOMMENTAR_COMMANDS + .replace("{kommentarId}", KommentarTestFactory.ID) + .replace("{kommentarVersion}", String.valueOf(KommentarTestFactory.VERSION)); @Test void shouldHaveSelfLink() { @@ -73,7 +75,8 @@ class KommentarModelAssemblerTest { var link = collectionModel.getLink(KommentarModelAssembler.REL_CREATE); assertThat(link).isPresent(); - assertThat(link.get().getHref()).isEqualTo("/api/vorgangs/" + VorgangHeaderTestFactory.ID + "/kommentarCommands"); + assertThat(link.get().getHref()).isEqualTo( + "/api/vorgangs/" + VorgangHeaderTestFactory.ID + "/kommentarCommands"); } } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java index 6b8c32c2b10a75d57a416b112e405f229cc339cd..364b8af57e85a8873ad4f58d55988c094d21b392 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarRemoteServiceTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.*; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -14,7 +15,6 @@ import org.mockito.Spy; import de.itvsh.goofy.vorgang.GrpcVorgangAttachedItemTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest; import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcFindVorgangAttachedItemResponse; import de.itvsh.ozg.pluto.vorgangAttachedItem.GrpcVorgangAttachedItem; @@ -27,24 +27,23 @@ class KommentarRemoteServiceTest { @Spy @InjectMocks private KommentarRemoteService service; - @Mock private VorgangAttachedItemServiceBlockingStub vorgangAttachedItemServiceStub; @Mock private KommentarMapper mapper; - @Mock - private GrpcObjectMapper grpcObjectMapper; private GrpcVorgangAttachedItem kommentar = GrpcVorgangAttachedItemTestFactory.create(); + @DisplayName("Find by vorgangId") @Nested class TestFindByVorgangId { private GrpcFindVorgangAttachedItemRequest request = GrpcFindVorgangAttachedItemRequest.newBuilder() - .setVorgangId(VorgangHeaderTestFactory.ID).setItemName(KommentarRemoteService.ITEM_NAME).build(); + .setVorgangId(VorgangHeaderTestFactory.ID) + .setItemName(KommentarRemoteService.ITEM_NAME) + .build(); private GrpcFindVorgangAttachedItemResponse response = GrpcFindVorgangAttachedItemResponse.newBuilder() .clearVorgangAttachedItems() - .addVorgangAttachedItems(kommentar) .addVorgangAttachedItems(kommentar).build(); @BeforeEach @@ -61,10 +60,10 @@ class KommentarRemoteServiceTest { @Test void shouldCallMapper() { - Stream<Kommentar> result = service.findByVorgangId(VorgangHeaderTestFactory.ID); + var result = service.findByVorgangId(VorgangHeaderTestFactory.ID); collectStreamElementsToTriggerLazyStream(result); - verify(mapper, times(2)).fromItemMap(any()); + verify(mapper).fromItem(any()); } private void collectStreamElementsToTriggerLazyStream(Stream<Kommentar> stream) { @@ -72,17 +71,20 @@ class KommentarRemoteServiceTest { } } + @DisplayName("Find by id") @Nested class TestGetById { - GrpcVorgangAttachedItemResponse response = GrpcVorgangAttachedItemResponse.newBuilder() - .setVorgangAttachedItem(GrpcVorgangAttachedItemTestFactory.create()).build(); - GrpcVorgangAttachedItemRequest request = GrpcVorgangAttachedItemRequest.newBuilder().setId(KommentarTestFactory.ID).build(); + private GrpcVorgangAttachedItemResponse response = GrpcVorgangAttachedItemResponse.newBuilder() + .setVorgangAttachedItem(GrpcVorgangAttachedItemTestFactory.create()) + .build(); + private GrpcVorgangAttachedItemRequest request = GrpcVorgangAttachedItemRequest.newBuilder() + .setId(KommentarTestFactory.ID) + .build(); @BeforeEach void mockStub() { when(vorgangAttachedItemServiceStub.getById(any())).thenReturn(response); - when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(KommentarTestFactory.createAsMap()); - when(mapper.fromItemMap(any())).thenReturn(KommentarTestFactory.create()); + when(mapper.fromItem(any())).thenReturn(KommentarTestFactory.create()); } @Test @@ -96,7 +98,7 @@ class KommentarRemoteServiceTest { void shouldCallMapper() { service.getById(KommentarTestFactory.ID); - verify(mapper).fromItemMap(any()); + verify(mapper).fromItem(any()); } } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java index d7193d38b9d8ba7ae8385d7e2414f0e42a2d45e8..ab903893f2acdc5e4566c6606bf40c432388a609 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarServiceTest.java @@ -1,21 +1,145 @@ package de.itvsh.goofy.kommentar; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; + +import static org.assertj.core.api.Assertions.*; +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItemService; +import de.itvsh.goofy.common.command.Command; +import de.itvsh.goofy.common.command.CommandTestFactory; +import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.GoofyUserTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; class KommentarServiceTest { + @Spy @InjectMocks private KommentarService service; - @Mock private KommentarRemoteService remoteService; + @Mock + private VorgangAttachedItemService vorgangAttachedItemService; + @Mock + private CurrentUserService currentUserService; + + @DisplayName("Create kommentar") + @Nested + class TestCreateKommentar { + + @DisplayName("should") + @Nested + class TestCalls { + + @BeforeEach + void mockServices() { + doReturn(KommentarTestFactory.create()).when(service).addCreated(any()); + when(vorgangAttachedItemService.createNewKommentar(any(), any())).thenReturn(CommandTestFactory.create()); + } + + @DisplayName("add created") + @Test + void shouldAddCreated() { + callCreateKommentar(); + + verify(service).addCreated(any(Kommentar.class)); + } + + @DisplayName("call vorgangattacheditem service") + @Test + void shouldCallVorgangAttachedItemService() { + callCreateKommentar(); + + verify(vorgangAttachedItemService).createNewKommentar(any(Kommentar.class), eq(VorgangHeaderTestFactory.ID)); + } + } + + @DisplayName("Add created") + @Nested + class TestAddCreated { + + @BeforeEach + void mockServices() { + when(currentUserService.getUserId()).thenReturn(GoofyUserTestFactory.ID); + } + + @Test + void shouldSetCreatedAt() throws Exception { + var kommentar = callAddCreated(); + + assertThat(kommentar.getCreatedAt()).isNotNull().isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); + } + + @Test + void shouldSetCreatedBy() throws Exception { + var kommentar = callAddCreated(); + + assertThat(kommentar.getCreatedBy()).isEqualTo(GoofyUserTestFactory.ID.toString()); + } + + private Kommentar callAddCreated() { + return service.addCreated(KommentarTestFactory.createBuilder().createdAt(null).createdBy(null).build()); + } + } + + private Command callCreateKommentar() { + return service.createKommentar(KommentarTestFactory.create(), VorgangHeaderTestFactory.ID); + } + } + + @DisplayName("Edit kommentar") + @Nested + class TestEditKommentar { + + @Captor + private ArgumentCaptor<Kommentar> kommentarCaptor; + + @BeforeEach + void mockKommentarService() { + when(remoteService.getById(anyString())).thenReturn(KommentarTestFactory.createBuilder().text("text needs to be override").build()); + } + + @Test + void shouldCallGetById() { + callEditKommentar(); + + verify(service).getById(KommentarTestFactory.ID); + } + + @Test + void shouldReplaceText() { + callEditKommentar(); + + verify(vorgangAttachedItemService).editKommentar(kommentarCaptor.capture(), eq(KommentarTestFactory.ID), + eq(KommentarTestFactory.VERSION)); + assertThat(kommentarCaptor.getValue().getText()).isEqualTo(KommentarTestFactory.TEXT); + } + + @Test + void shouldCallVorgangAttachedItemService() { + callEditKommentar(); + + verify(vorgangAttachedItemService).editKommentar(any(Kommentar.class), eq(KommentarTestFactory.ID), eq(KommentarTestFactory.VERSION)); + } + + private Command callEditKommentar() { + return service.editKommentar(KommentarTestFactory.create(), KommentarTestFactory.ID, KommentarTestFactory.VERSION); + } + } @Nested class TestGetById { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java index 99abb0b24b22ca5ab6743ae4de507409dfdf0995..aee4801acc0698a5b90c1e4994552608fae227b5 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarTestFactory.java @@ -8,12 +8,14 @@ import com.thedeanda.lorem.Lorem; import com.thedeanda.lorem.LoremIpsum; import de.itvsh.goofy.common.user.UserProfileTestFactory; +import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; public class KommentarTestFactory { private static Lorem lorem = LoremIpsum.getInstance(); public static final String ID = UUID.randomUUID().toString(); + public static final long VERSION = 73; public static final String CREATED_BY = UserProfileTestFactory.ID.toString(); public static final String CREATED_AT_STR = "2021-01-10T10:30:00Z"; @@ -28,6 +30,8 @@ public class KommentarTestFactory { public static Kommentar.KommentarBuilder createBuilder() { return Kommentar.builder() .id(ID) + .vorgangId(VorgangHeaderTestFactory.ID) + .version(VERSION) .text(TEXT) .createdBy(CREATED_BY) .createdAt(CREATED_AT); diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailCommandControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailCommandControllerTest.java index dc3c4932db2382e4713c473d9fbcdb2980fd1ed7..77f85fb625a2744ebe45085cd8731efaf93104c1 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailCommandControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailCommandControllerTest.java @@ -8,6 +8,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.http.MediaType; @@ -40,9 +42,19 @@ class PostfachMailCommandControllerTest { @Nested class TestCreateCommand { + @Captor + private ArgumentCaptor<CreateCommand> createCommandCaptor; + @BeforeEach void mockController() { - when(commandByRelationController.createCommand(any(CreateCommand.class), anyLong())).thenReturn(CommandTestFactory.create()); + when(commandByRelationController.createCommandWithoutRelation(any(CreateCommand.class))).thenReturn(CommandTestFactory.create()); + } + + @Test + void shouldCallCommandByRelationController() throws Exception { + doRequest(); + + verify(commandByRelationController).createCommandWithoutRelation(createCommandCaptor.capture()); } @Test @@ -63,13 +75,4 @@ class PostfachMailCommandControllerTest { .content(PostfachMailTestFactory.buildResendPostfachMailContent())); } } - - @Test - void shouldCallCommandByRelationController() { - var createCommand = CommandTestFactory.createCreateCommand(); - - controller.createCommand(createCommand); - - verify(commandByRelationController).createCommand(createCommand, -1); - } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailControllerTest.java index 5698978fca53e1a27a1c11d99859c50781d82b0f..6cc924272be0a555cb5c7edd0911013be87f1ff0 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailControllerTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.postfach; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -21,8 +20,9 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.binaryfile.BinaryFileController; -import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.vorgang.Antragsteller; import de.itvsh.goofy.vorgang.EingangTestFactory; import de.itvsh.goofy.vorgang.VorgangController; @@ -50,19 +50,6 @@ class PostfachMailControllerTest { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } - @Nested - class TestPostfachSendMessage { - - final PostfachMail postfachMail = PostfachMailTestFactory.create(); - - @Test - void shouldCallService() { - controller.sendPostfachMail(CommandTestFactory.ID, postfachMail); - - verify(service).sendPostfachMail(CommandTestFactory.ID, postfachMail); - } - } - @Nested class TestPostfachMailGetAll { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java index 307738b87ea4cd29579b2845be5be1d0356e9bf6..06c76b268f59f851d66d840cf3e39e20ec3096bb 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java @@ -15,7 +15,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.util.ReflectionTestUtils; import de.itvsh.goofy.CallScope; -import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.vorgang.EingangTestFactory; import de.itvsh.goofy.vorgang.VorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -45,19 +44,6 @@ public class PostfachMailITCase { callScope.startScope(); } - @Nested - @WithMockUser - class TestSendeMail { - - @Test - void shouldCallPostfachGrpc() throws InterruptedException { - - controller.sendPostfachMail(CommandTestFactory.ID, PostfachMailTestFactory.createLikeFromClient()); - - verify(serviceStub, after(2000)).sendPostfachMail(any()); - } - } - @Nested @WithMockUser class TestGetAll { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailModelAssemblerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailModelAssemblerTest.java index b3b6db94568ed1eb142301e319d90736495d0709..100b7a73b6827e90dfd9af06f9aca36d7102f202 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailModelAssemblerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailModelAssemblerTest.java @@ -1,8 +1,7 @@ package de.itvsh.goofy.postfach; -import static org.assertj.core.api.Assertions.*; - import java.util.Optional; +import java.util.UUID; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -14,6 +13,9 @@ import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; +import static org.assertj.core.api.Assertions.*; + +import de.itvsh.goofy.common.user.UserId; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; class PostfachMailModelAssemblerTest { @@ -78,6 +80,37 @@ class PostfachMailModelAssemblerTest { } } + @DisplayName("created by link") + @Nested + class TestCreatedByLink { + + @Test + void shouldBePresent() { + var link = modelAssembler.toModel(PostfachMailTestFactory.create()).getLink(PostfachMailModelAssembler.REL_CREATED_BY); + + assertThat(link).isPresent().get().extracting(Link::getHref) + .isEqualTo("/api/userProfiles/" + PostfachMailTestFactory.CREATED_BY); + } + + @DisplayName("should not be present if the value of createdBy starts with 'system'") + @Test + void shouldNOTBePresentOnSystemUser() { + var link = modelAssembler + .toModel(PostfachMailTestFactory.createBuilder() + .createdBy(UserId.from(PostfachMailModelAssembler.SYSTEM_USER_IDENTIFIER + UUID.randomUUID().toString())).build()) + .getLink(PostfachMailModelAssembler.REL_CREATED_BY); + + assertThat(link).isNotPresent(); + } + + @Test + void shouldNotBePresentOnNull() { + var link = modelAssembler.toModel(PostfachMailTestFactory.createBuilder().createdBy(null).build()) + .getLink(PostfachMailModelAssembler.REL_CREATED_BY); + + assertThat(link).isNotPresent(); + } + } } @Nested diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailRemoteServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailRemoteServiceTest.java index fbf48356fa253c97dd4be99dca7630c4aca42cef..ca147f87a6f8d404da513aeb75ade4785f2c80ef 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailRemoteServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailRemoteServiceTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.postfach; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -15,6 +14,8 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.callcontext.ContextService; import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -24,7 +25,6 @@ import de.itvsh.ozg.mail.postfach.GrpcIsPostfachConfiguredRequest; import de.itvsh.ozg.mail.postfach.GrpcIsPostfachConfiguredResponse; import de.itvsh.ozg.mail.postfach.GrpcPostfachMail; import de.itvsh.ozg.mail.postfach.GrpcResendPostfachMailRequest; -import de.itvsh.ozg.mail.postfach.GrpcSendPostfachMailRequest; import de.itvsh.ozg.mail.postfach.PostfachServiceGrpc.PostfachServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.command.GrpcCallContext; @@ -46,50 +46,6 @@ class PostfachMailRemoteServiceTest { when(contextService.createCallContext()).thenReturn(callContext); } - @Nested - class TestSendPostfachMail { - - private GrpcPostfachMail postfachMail = GrpcPostfachMail.newBuilder().setPostfachId("42").build(); - - @Captor - private ArgumentCaptor<GrpcSendPostfachMailRequest> requestCaptor; - - @BeforeEach - void initMocks() { - when(postfachNachrichtMapper.toGrpcPostfachMail(any())).thenReturn(postfachMail); - } - - @Test - void shouldCallStub() { - service.sendPostfachMail(CommandTestFactory.ID, PostfachMailTestFactory.create()); - - verify(serviceStub).sendPostfachMail(any(GrpcSendPostfachMailRequest.class)); - } - - @Test - void shouldCallCallContextService() { - service.sendPostfachMail(CommandTestFactory.ID, PostfachMailTestFactory.create()); - - verify(contextService).createCallContext(); - } - - @Test - void shouldCallMapper() { - service.sendPostfachMail(CommandTestFactory.ID, PostfachMailTestFactory.create()); - - verify(postfachNachrichtMapper).toGrpcPostfachMail(any(PostfachMail.class)); - } - - @Test - void shouldAddAttachments() { - service.sendPostfachMail(CommandTestFactory.ID, PostfachMailTestFactory.create()); - - verify(serviceStub).sendPostfachMail(requestCaptor.capture()); - assertThat(requestCaptor.getValue().getMail().getAttachmentList()).hasSize(1); - assertThat(requestCaptor.getValue().getMail().getAttachmentList().get(0)).isEqualTo(PostfachMailTestFactory.ATTACHMENT.toString()); - } - } - @Nested class TestFindPostfachMail { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailServiceTest.java index 5690e5c2819effd6bd3cc76ba1aeb034e40fb96d..4e14e58beb7119298c477c241417a81cf375a985 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailServiceTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.postfach; -import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -14,6 +13,8 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.common.errorhandling.ResourceNotFoundException; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -25,19 +26,6 @@ class PostfachMailServiceTest { @Mock private PostfachMailRemoteService remoteService; - @Nested - class TestSendPostfachMail { - - final PostfachMail postfachMail = PostfachMailTestFactory.create(); - - @Test - void shouldCallRemoteService() { - service.sendPostfachMail(CommandTestFactory.ID, postfachMail); - - verify(remoteService).sendPostfachMail(CommandTestFactory.ID, postfachMail); - } - } - @Nested class TestGetAll { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java index fa99f37a3203f8a084d68ba29457f4e7ac2d9e03..bea7a39b6ed1b1679fde1f939ba50e3af2b06a95 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java @@ -72,10 +72,15 @@ public class PostfachMailTestFactory { } public static String buildSendPostfachMailContent(PostfachMail postfachMail) { - return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithPostfachMail.json.tmpl", CommandOrder.SEND_POSTFACH_MAIL.name(), + return buildSendPostfachMailContent(postfachMail, CommandOrder.SEND_POSTFACH_NACHRICHT); + } + + public static String buildSendPostfachMailContent(PostfachMail postfachMail, CommandOrder order) { + return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithPostfachMail.json.tmpl", order.name(), postfachMail.getReplyOption().name(), TestUtils.addQuote(postfachMail.getSubject()), - TestUtils.addQuote(postfachMail.getMailBody())); + TestUtils.addQuote(postfachMail.getMailBody()), + postfachMail.getAttachments().get(0).toString()); } public static String buildResendPostfachMailContent() { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/GrpcVorgangAttachedItemTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/GrpcVorgangAttachedItemTestFactory.java index 78b56c924b1bd1f4991f47d5bfc40cb3c5b0704a..216ba59a1db199deb47cbdf31d9f6b8189c50ce7 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/GrpcVorgangAttachedItemTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/GrpcVorgangAttachedItemTestFactory.java @@ -15,6 +15,7 @@ public class GrpcVorgangAttachedItemTestFactory { public final static String ITEM_NAME = LoremIpsum.getInstance().getWords(1); public final static String ITEM_KEY = LoremIpsum.getInstance().getWords(1); public final static String ITEM_VALUE = LoremIpsum.getInstance().getWords(1); + public final static long VERSION = 73; public static final GrpcObject ITEM = GrpcObject.newBuilder() .addProperty(GrpcProperty.newBuilder() @@ -33,6 +34,7 @@ public class GrpcVorgangAttachedItemTestFactory { .setClient(CLIENT) .setVorgangId(VorgangHeaderTestFactory.ID) .setItemName(ITEM_NAME) - .setItem(ITEM); + .setItem(ITEM) + .setVersion(VERSION); } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessorTest.java b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessorTest.java index 2c34ae5ee0a1ae740a3510031d6427eac5a2ffeb..54a15a5328b13dfe251e5a7afe6ca9935655978c 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessorTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/command/VorgangWithEingangCommandProzessorTest.java @@ -1,11 +1,9 @@ package de.itvsh.goofy.vorgang.command; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collections; -import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -22,6 +20,8 @@ import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.security.test.context.support.WithMockUser; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.command.CommandController; import de.itvsh.goofy.common.user.CurrentUserService; import de.itvsh.goofy.common.user.UserRole; @@ -187,31 +187,4 @@ class VorgangWithEingangCommandProzessorTest { .isEqualTo("/api/commands?pending=true&vorgangId=" + VorgangHeaderTestFactory.ID); } } - - @Nested - class TestCreateWiedervorlageLink { - - @Test - void shouldHaveCreateWiedervorlageLink() { - when(userService.hasRole(UserRole.VERWALTUNG_USER)).thenReturn(true); - when(userService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER)).thenReturn(false); - - EntityModel<VorgangWithEingang> model = processor.process(EntityModel.of(VorgangWithEingangTestFactory.create())); - var link = model.getLink(VorgangWithEingangCommandProzessor.REL_CREATE_WIEDERVORLAGE); - - assertThat(link).isPresent().get().extracting(Link::getHref) - .isEqualTo("/api/vorgangs/" + VorgangHeaderTestFactory.ID + "/wiedervorlageCommands"); - } - - @Test - void shouldNotHaveCreateWiedervorlageLink() { - when(userService.hasRole(UserRole.VERWALTUNG_USER)).thenReturn(false); - when(userService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER)).thenReturn(false); - - Optional<Link> model = processor.process(EntityModel.of(VorgangWithEingangTestFactory.create())) - .getLink(VorgangWithEingangCommandProzessor.REL_CREATE_WIEDERVORLAGE); - - assertThat(model).isNotPresent(); - } - } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandByVorgangControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandByVorgangControllerTest.java index 1bfc0085bc36578ff105d9ecac9a2b788f3b39fc..d15a8312ffff46ba61638a047f00a14df3768072 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandByVorgangControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandByVorgangControllerTest.java @@ -1,14 +1,10 @@ package de.itvsh.goofy.wiedervorlage; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -23,14 +19,10 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import de.itvsh.goofy.common.binaryfile.BinaryFileTestFactory; -import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; -import de.itvsh.goofy.common.command.CommandOrder; import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.common.command.CreateCommand; import de.itvsh.goofy.common.user.CurrentUserService; -import de.itvsh.goofy.common.user.UserTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; import de.itvsh.goofy.wiedervorlage.WiedervorlageCommandController.WiedervorlageCommandByVorgangController; @@ -61,23 +53,17 @@ class WiedervorlageCommandByVorgangControllerTest { @BeforeEach void mockUserService() { - when(userService.getUserId()).thenReturn(UserTestFactory.ID); + when(service.createWiedervorlage(any(), any())).thenReturn(CommandTestFactory.create()); } @Nested class ServiceMethod { - @BeforeEach - void initMocks() { - when(commandByRelationController.createCommand(any(), any())).thenReturn(CommandTestFactory.create()); - } - @Test - void shouldCallCommandByRelationController() throws Exception { + void shouldCallService() throws Exception { doRequest(); - verify(commandByRelationController).createCommand(any(CreateCommand.class), - eq(WiedervorlageRemoteService.ITEM_NAME)); + verify(service).createWiedervorlage(any(Wiedervorlage.class), eq(VorgangHeaderTestFactory.ID)); } @Test @@ -92,75 +78,6 @@ class WiedervorlageCommandByVorgangControllerTest { doRequest().andExpect(status().isCreated()); } } - - @Nested - class BuildCreateCommand { - - @Test - void shouldContainsOrder() throws Exception { - var createCommand = buildCommand(); - - assertThat(createCommand.getOrder()).isEqualTo(CommandOrder.CREATE_ATTACHED_ITEM); - } - - @Test - void shouldContainsVorgangId() throws Exception { - var createCommand = buildCommand(); - - assertThat(createCommand.getVorgangId()).isEqualTo(VorgangHeaderTestFactory.ID); - } - - @Test - void shouldContainsBody() throws Exception { - var createCommand = buildCommand(); - - assertThat(((Wiedervorlage) createCommand.getBody())).usingRecursiveComparison().ignoringFields("createdAt", "createdBy") - .isEqualTo(WiedervorlageTestFactory.create()); - } - - private CreateCommand buildCommand() { - return controller.buildCommand(VorgangHeaderTestFactory.ID, WiedervorlageCommandTestFactory.create()); - } - } - - @Nested - class BuildBody { - - private final Wiedervorlage wiedervorlage = WiedervorlageTestFactory.create(); - - @Test - void shouldSetCreatedAt() { - var enrichedWiedervorlage = buildBody(wiedervorlage.toBuilder().createdAt(null).build()); - - assertThat(enrichedWiedervorlage.getCreatedAt()).isCloseTo(ZonedDateTime.now().withNano(0), - within(2, ChronoUnit.SECONDS)); - } - - @Test - void shouldSetCreatedBy() { - var enrichedWiedervorlage = buildBody(wiedervorlage.toBuilder().createdBy(null).build()); - - assertThat(enrichedWiedervorlage.getCreatedBy()).isEqualTo(UserTestFactory.ID.toString()); - } - - @Nested - class StripAttachmentFileUriToId { - - @Test - void shouldStripFileUriToFileId() { - var fileIdAsUri = FileId.from("api/irgendwas/dazwischen/" + BinaryFileTestFactory.ID); - var wiedervorlageWithAttachmentAsFileUri = WiedervorlageTestFactory.createBuilder().attachment(fileIdAsUri).build(); - - var wiedervorlage = buildBody(wiedervorlageWithAttachmentAsFileUri); - - assertThat(wiedervorlage.getAttachments().get(0)).isEqualTo(BinaryFileTestFactory.FILE_ID); - } - } - - private Wiedervorlage buildBody(Wiedervorlage wiedervorlage) { - return controller.buildBody(wiedervorlage); - } - } } private ResultActions doRequest() throws Exception { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandControllerTest.java index 3e1834ad47c6dc23488c91e236b0717e2305228e..892c2c68b614fa0c57f8b1b17645a2310e1645ea 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandControllerTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.wiedervorlage; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -20,7 +19,10 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.binaryfile.BinaryFileTestFactory; +import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.command.Command; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; import de.itvsh.goofy.common.command.CommandOrder; @@ -95,9 +97,17 @@ class WiedervorlageCommandControllerTest { doRequest().andExpect(header().string("Location", RESPONSE_HEADER)); } + @Test + void shouldBuildCommand() throws Exception { + doRequest(); + + verify(controller).buildCommand(any(Wiedervorlage.class), any(WiedervorlageCommand.class), eq(WiedervorlageTestFactory.VERSION)); + } + private ResultActions doRequest() throws Exception { - return mockMvc.perform(post(WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS, WiedervorlageTestFactory.ID) - .content(WiedervorlageCommandTestFactory.createValidRequestContent()).contentType(MediaType.APPLICATION_JSON)) + return mockMvc.perform( + post(WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS, WiedervorlageTestFactory.ID, WiedervorlageTestFactory.VERSION) + .content(WiedervorlageCommandTestFactory.createValidRequestContent()).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().is2xxSuccessful()); } } @@ -116,7 +126,14 @@ class WiedervorlageCommandControllerTest { void shouldHaveRelationId() { var command = callBuildCommand(); - assertThat(command.getRelationId()).isEqualTo(WiedervorlageCommandController.NOT_SET); + assertThat(command.getRelationId()).isEqualTo(WiedervorlageTestFactory.ID); + } + + @Test + void shouldHaveRelationVersion() { + var command = callBuildCommand(); + + assertThat(command.getRelationVersion()).isEqualTo(WiedervorlageTestFactory.VERSION); } @Test @@ -216,7 +233,7 @@ class WiedervorlageCommandControllerTest { } CreateCommand callBuildCommand(WiedervorlageCommand command) { - return controller.buildCommand(WiedervorlageTestFactory.create(), command); + return controller.buildCommand(WiedervorlageTestFactory.create(), command, WiedervorlageTestFactory.VERSION); } } @@ -230,7 +247,8 @@ class WiedervorlageCommandControllerTest { void shouldCallCreateCommand() { createCommandByOrder(CommandOrder.EDIT_WIEDERVORLAGE); - verify(commandByRelationController).createCommand(any(), eq(WiedervorlageRemoteService.ITEM_NAME)); + verify(service).editWiedervorlage(any(Wiedervorlage.class), eq(CommandTestFactory.RELATION_ID), + eq(CommandTestFactory.RELATION_VERSION)); } } @@ -241,7 +259,8 @@ class WiedervorlageCommandControllerTest { void shouldCallCreateCommandWithoutValidation() { createCommandByOrder(CommandOrder.WIEDERVORLAGE_ERLEDIGEN); - verify(commandByRelationController).createCommandWithoutValidation(any(), eq(WiedervorlageRemoteService.ITEM_NAME)); + verify(commandByRelationController).createCommandWithoutValidation(any(), eq(WiedervorlageRemoteService.ITEM_NAME), + eq(CommandTestFactory.RELATION_VERSION)); } } @@ -252,13 +271,29 @@ class WiedervorlageCommandControllerTest { void shouldCallCreateCommandWithoutValidation() { createCommandByOrder(CommandOrder.WIEDERVORLAGE_WIEDEREROEFFNEN); - verify(commandByRelationController).createCommandWithoutValidation(any(), eq(WiedervorlageRemoteService.ITEM_NAME)); + verify(commandByRelationController).createCommandWithoutValidation(any(), eq(WiedervorlageRemoteService.ITEM_NAME), + eq(CommandTestFactory.RELATION_VERSION)); } } private Command createCommandByOrder(CommandOrder order) { - return controller.createByOrder(CommandTestFactory.createCreateCommand(), order); + return controller.createByOrder( + CommandTestFactory.createCreateCommandBuilder().body(WiedervorlageTestFactory.create()).build(), order); } } } + + @Nested + class StripAttachmentFileUriToId { + + @Test + void shouldStripFileUriToFileId() { + var fileIdAsUri = FileId.from("api/irgendwas/dazwischen/" + BinaryFileTestFactory.ID); + var wiedervorlageWithAttachmentAsFileUri = WiedervorlageTestFactory.createBuilder().attachment(fileIdAsUri).build(); + + var wiedervorlage = WiedervorlageCommandController.stripAttachmentFileUriToId(wiedervorlageWithAttachmentAsFileUri); + + assertThat(wiedervorlage.getAttachments().get(0)).isEqualTo(BinaryFileTestFactory.FILE_ID); + } + } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandITCase.java index 145aa620085692c67cf8f5a5739e69ed4e9b5c16..b4271cc9c0001e0b8046a0ba66186097fa46025d 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandITCase.java @@ -71,7 +71,7 @@ class WiedervorlageCommandITCase { doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.betreff")) + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.betreff")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -81,7 +81,7 @@ class WiedervorlageCommandITCase { String content = buildContentWithBetreff("a"); doRequest(content).andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.betreff")); + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.betreff")); } @@ -112,7 +112,7 @@ class WiedervorlageCommandITCase { doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.frist")) + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.frist")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_DATE_PAST)); } @@ -123,7 +123,7 @@ class WiedervorlageCommandITCase { doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.frist")) + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.frist")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -134,9 +134,10 @@ class WiedervorlageCommandITCase { } private ResultActions doRequest(String content) throws Exception { - return mockMvc.perform(post(WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS, WiedervorlageTestFactory.ID) - .contentType(MediaType.APPLICATION_JSON) - .content(content)); + return mockMvc.perform( + post(WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS, WiedervorlageTestFactory.ID, WiedervorlageTestFactory.VERSION) + .contentType(MediaType.APPLICATION_JSON) + .content(content)); } } @@ -145,9 +146,11 @@ class WiedervorlageCommandITCase { @Nested class TestCreateCreateCommand { + private static final long RELATION_ID_ON_CREATE = -1; + @BeforeEach void initTest() { - when(commandRemoteService.createCommand(any(), anyString())).thenReturn(CommandTestFactory.create()); + when(commandRemoteService.createCommand(any())).thenReturn(CommandTestFactory.create()); when(wiedervorlageRemoteService.getById(anyString())).thenReturn(WiedervorlageTestFactory.create()); } @@ -155,7 +158,7 @@ class WiedervorlageCommandITCase { void shouldCreateCommand() throws Exception { doRequest(createValidRequestContent()).andExpect(status().isCreated()); - verify(commandRemoteService).createCommand(any(), anyString()); + verify(commandRemoteService).createCommand(any()); } @WithMockUser @@ -170,7 +173,7 @@ class WiedervorlageCommandITCase { doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.betreff")) + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.betreff")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } @@ -180,7 +183,7 @@ class WiedervorlageCommandITCase { String content = buildContentWithBetreff("a"); doRequest(content).andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.betreff")); + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.betreff")); } @@ -212,7 +215,7 @@ class WiedervorlageCommandITCase { doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.frist")) + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.frist")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_DATE_PAST)); } @@ -224,16 +227,17 @@ class WiedervorlageCommandITCase { doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) - .andExpect(jsonPath("$.issues.[0].field").value("command.body.frist")) + .andExpect(jsonPath("$.issues.[0].field").value("wiedervorlage.frist")) .andExpect(jsonPath("$.issues.[0].messageCode").value(ValidationMessageCodes.FIELD_IS_EMPTY)); } } private ResultActions doRequest(String content) throws Exception { - return mockMvc.perform(post(WiedervorlageCommandByVorgangController.WIEDERVORLAGE_COMMANDS_BY_VORGANG, VorgangHeaderTestFactory.ID) - .contentType(MediaType.APPLICATION_JSON) - .content(content)); + return mockMvc.perform(post(WiedervorlageCommandByVorgangController.WIEDERVORLAGE_COMMANDS_BY_VORGANG, VorgangHeaderTestFactory.ID, + RELATION_ID_ON_CREATE) + .contentType(MediaType.APPLICATION_JSON) + .content(content)); } } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapperTest.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapperTest.java index c01ecfd503854baedb44893b6fd49692f3deb5cc..3b21f24d6a98eb7c2808706afdc8dcd35648ca81 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapperTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageMapperTest.java @@ -1,26 +1,62 @@ package de.itvsh.goofy.wiedervorlage; -import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.Spy; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.binaryfile.BinaryFileTestFactory; import de.itvsh.goofy.common.binaryfile.FileIdMapper; +import de.itvsh.goofy.vorgang.GrpcVorgangAttachedItemTestFactory; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; class WiedervorlageMapperTest { + @Spy @InjectMocks private WiedervorlageMapper mapper = Mappers.getMapper(WiedervorlageMapper.class); @Spy private FileIdMapper fileIdMapper = Mappers.getMapper(FileIdMapper.class); + @Mock + private GrpcObjectMapper grpcObjectMapper; + + @DisplayName("Map from item") + @Nested + class TestFromItem { + + @BeforeEach + void mockMapper() { + when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(WiedervorlageTestFactory.createAsMap()); + } + + @Test + void shouldCallGrpcObjectMapper() { + mapper.fromItem(GrpcVorgangAttachedItemTestFactory.create()); + + verify(grpcObjectMapper).mapFromGrpc(GrpcVorgangAttachedItemTestFactory.ITEM); + } + + @Test + void shouldCallMapperFromItemMap() { + mapper.fromItem(GrpcVorgangAttachedItemTestFactory.create()); + + verify(mapper).fromItemMap(WiedervorlageTestFactory.createAsMap(), GrpcVorgangAttachedItemTestFactory.VERSION); + } + } + @DisplayName("Map from item map") @Nested class TestFromItemMap { @@ -31,6 +67,13 @@ class WiedervorlageMapperTest { assertThat(wiedervorlage.getId()).isEqualTo(WiedervorlageTestFactory.ID); } + @Test + void shouldMapVersion() { + var wiedervorlage = map(); + + assertThat(wiedervorlage.getVersion()).isEqualTo(WiedervorlageTestFactory.VERSION); + } + @Test void shouldMapDone() { var wiedervorlage = map(); @@ -82,7 +125,7 @@ class WiedervorlageMapperTest { wiedervorlageWithoutAttachments.putAll(WiedervorlageTestFactory.createAsMap()); wiedervorlageWithoutAttachments.remove(WiedervorlageMapper.ATTACHMENTS); - var wiedervorlage = mapper.fromItemMap(wiedervorlageWithoutAttachments); + var wiedervorlage = mapper.fromItemMap(wiedervorlageWithoutAttachments, WiedervorlageTestFactory.VERSION); assertThat(wiedervorlage.getAttachments()).isEmpty(); } @@ -96,7 +139,7 @@ class WiedervorlageMapperTest { @Test void shouldMapAttachmentList() { - var wiedervorlage = mapper.fromItemMap(createWiedervorlageAsMapWithMultipleAttachments()); + var wiedervorlage = mapper.fromItemMap(createWiedervorlageAsMapWithMultipleAttachments(), WiedervorlageTestFactory.VERSION); assertThat(wiedervorlage.getAttachments()).hasSize(2); assertThat(wiedervorlage.getAttachments().get(0)).isEqualTo(BinaryFileTestFactory.FILE_ID); @@ -112,7 +155,7 @@ class WiedervorlageMapperTest { } private Wiedervorlage map() { - return mapper.fromItemMap(WiedervorlageTestFactory.createAsMap()); + return mapper.fromItemMap(WiedervorlageTestFactory.createAsMap(), WiedervorlageTestFactory.VERSION); } } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssemblerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssemblerTest.java index 7aeb26900300ecbf2698e4b0b60000839e685274..9106cf6495d827777b93143782f93cdc6d52dd1e 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssemblerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageModelAssemblerTest.java @@ -1,7 +1,5 @@ package de.itvsh.goofy.wiedervorlage; -import static org.assertj.core.api.Assertions.*; - import java.util.Collections; import org.junit.jupiter.api.Nested; @@ -12,6 +10,8 @@ import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.server.EntityLinks; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.common.file.OzgFileTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; @@ -28,8 +28,9 @@ class WiedervorlageModelAssemblerTest { @Nested class TestLinksOnModel { - private final String COMMAND_BY_WIEDERVORLAGE_PATH = WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS.replace("{wiedervorlageId}", - WiedervorlageTestFactory.ID); + private static final String COMMAND_BY_WIEDERVORLAGE_PATH = WiedervorlageCommandController.WIEDERVORLAGE_COMMANDS + .replace("{wiedervorlageId}", WiedervorlageTestFactory.ID) + .replace("{wiedervorlageVersion}", String.valueOf(WiedervorlageTestFactory.VERSION)); @Test void shouldHaveSelfLink() { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteServiceTest.java index ab6761aaee84a45d2ca86ffdf0051715abb25ea4..307fa72a02e549754a8dac1940e5bb4f38c5bd45 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageRemoteServiceTest.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.wiedervorlage; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -20,10 +19,11 @@ import org.mockito.Mock; import org.mockito.Spy; import org.springframework.context.ApplicationContext; +import static org.assertj.core.api.Assertions.*; + import de.itvsh.goofy.ApplicationTestFactory; import de.itvsh.goofy.vorgang.GrpcVorgangAttachedItemTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; -import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; import de.itvsh.ozg.pluto.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcAccessPermission; import de.itvsh.ozg.pluto.grpc.clientAttribute.GrpcDeleteClientAttributeRequest; @@ -47,8 +47,6 @@ class WiedervorlageRemoteServiceTest { @Mock private WiedervorlageMapper mapper; @Mock - private GrpcObjectMapper grpcObjectMapper; - @Mock private ApplicationContext applicationContext; @Nested @@ -78,21 +76,14 @@ class WiedervorlageRemoteServiceTest { @BeforeEach void mockGrpcMapper() { - when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(WiedervorlageTestFactory.createAsMap()); - } - - @Test - void shouldCallForGrpcObject() { - callFindById(); - - verify(grpcObjectMapper).mapFromGrpc(GrpcVorgangAttachedItemTestFactory.ITEM); + when(mapper.fromItem(any())).thenReturn(WiedervorlageTestFactory.create()); } @Test void shouldCallForWiedervorlage() { callFindById(); - verify(mapper).fromItemMap(WiedervorlageTestFactory.createAsMap()); + verify(mapper).fromItem(GrpcVorgangAttachedItemTestFactory.create()); } private void callFindById() { @@ -141,8 +132,7 @@ class WiedervorlageRemoteServiceTest { @BeforeEach void initMocks() { when(vorgangAttachedItemServiceStub.getById(any())).thenReturn(response); - when(grpcObjectMapper.mapFromGrpc(any())).thenReturn(WiedervorlageTestFactory.createAsMap()); - when(mapper.fromItemMap(any())).thenReturn(WiedervorlageTestFactory.create()); + when(mapper.fromItem(any())).thenReturn(WiedervorlageTestFactory.create()); } @Test @@ -152,18 +142,11 @@ class WiedervorlageRemoteServiceTest { verify(vorgangAttachedItemServiceStub).getById(request); } - @Test - void shouldCallGrpcObjectMapper() { - service.getById(WiedervorlageTestFactory.ID); - - verify(grpcObjectMapper).mapFromGrpc(GrpcVorgangAttachedItemTestFactory.ITEM); - } - @Test void shouldCallWiedervorlageMapper() { service.getById(WiedervorlageTestFactory.ID); - verify(mapper).fromItemMap(WiedervorlageTestFactory.createAsMap()); + verify(mapper).fromItem(GrpcVorgangAttachedItemTestFactory.create()); } @Test diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageServiceTest.java index 1609042fd1f5e58458f8dffa0dd91f1970e9c338..a3621a9d1f74a6170e124c36ad487de1520e733f 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageServiceTest.java @@ -1,22 +1,33 @@ package de.itvsh.goofy.wiedervorlage; -import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.time.LocalDate; +import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.Optional; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import static org.assertj.core.api.Assertions.*; + +import de.itvsh.goofy.common.attacheditem.VorgangAttachedItemService; +import de.itvsh.goofy.common.command.Command; +import de.itvsh.goofy.common.command.CommandService; +import de.itvsh.goofy.common.command.CommandTestFactory; +import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.GoofyUserTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; class WiedervorlageServiceTest { @@ -24,9 +35,98 @@ class WiedervorlageServiceTest { @Spy @InjectMocks private WiedervorlageService service; - @Mock private WiedervorlageRemoteService remoteService; + @Mock + private VorgangAttachedItemService vorgangAttachedItemService; + @Mock + private CommandService commandService; + @Mock + private CurrentUserService currentUserService; + + @DisplayName("Create wiedervorlage") + @Nested + class TestCreateWiedervorlage { + + @DisplayName("should") + @Nested + class TestCalls { + + @BeforeEach + void mockServices() { + doReturn(WiedervorlageTestFactory.create()).when(service).addCreated(any()); + when(vorgangAttachedItemService.createNewWiedervorlage(any(), any())).thenReturn(CommandTestFactory.create()); + } + + @DisplayName("add created") + @Test + void shouldAddCreated() { + callCreateWiedervorlage(); + + verify(service).addCreated(any(Wiedervorlage.class)); + } + + @DisplayName("call vorgangattacheditem service") + @Test + void shouldCallVorgangAttachedItemService() { + callCreateWiedervorlage(); + + verify(vorgangAttachedItemService).createNewWiedervorlage(any(Wiedervorlage.class), eq(VorgangHeaderTestFactory.ID)); + } + } + + @DisplayName("Add created") + @Nested + class TestAddCreated { + + @BeforeEach + void mockServices() { + when(currentUserService.getUserId()).thenReturn(GoofyUserTestFactory.ID); + } + + @Test + void shouldSetCreatedAt() throws Exception { + var wiedervorlage = callAddCreated(); + + assertThat(wiedervorlage.getCreatedAt()).isNotNull().isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); + } + + @Test + void shouldSetCreatedBy() throws Exception { + var wiedervorlage = callAddCreated(); + + assertThat(wiedervorlage.getCreatedBy()).isEqualTo(GoofyUserTestFactory.ID.toString()); + } + + private Wiedervorlage callAddCreated() { + return service.addCreated(WiedervorlageTestFactory.createBuilder().createdAt(null).createdBy(null).build()); + } + } + + private Command callCreateWiedervorlage() { + return service.createWiedervorlage(WiedervorlageTestFactory.create(), VorgangHeaderTestFactory.ID); + } + } + + @DisplayName("Edit wiedervorlage") + @Nested + class TestEditWiedervorlage { + + @Captor + private ArgumentCaptor<Wiedervorlage> wiedervorlageCaptor; + + @Test + void shouldCallVorgangAttachedItemService() { + callEditWiedervorlage(); + + verify(vorgangAttachedItemService).editWiedervorlage(any(Wiedervorlage.class), eq(WiedervorlageTestFactory.ID), + eq(WiedervorlageTestFactory.VERSION)); + } + + private Command callEditWiedervorlage() { + return service.editWiedervorlage(WiedervorlageTestFactory.create(), WiedervorlageTestFactory.ID, WiedervorlageTestFactory.VERSION); + } + } @Nested class TestGetById { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageTestFactory.java index 70efe8c69be101ce3dceeb1fbd71e92a34630067..60a2d19554191e09fbab178d699cec4e078a2cfd 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageTestFactory.java @@ -13,7 +13,7 @@ import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; public class WiedervorlageTestFactory { public static final String ID = UUID.randomUUID().toString(); - + public static final long VERSION = 73; public static final boolean DONE = false; public static final String CREATED_BY = UUID.randomUUID().toString(); public static final String CREATED_BY_NAME = LoremIpsum.getInstance().getName(); @@ -32,6 +32,7 @@ public class WiedervorlageTestFactory { public static Wiedervorlage.WiedervorlageBuilder createBuilder() { return Wiedervorlage.builder() .id(ID) + .version(VERSION) .done(DONE) .betreff(BETREFF) .beschreibung(BESCHREIBUNG) diff --git a/goofy-server/src/test/resources/jsonTemplates/command/createCommandWithPostfachMail.json.tmpl b/goofy-server/src/test/resources/jsonTemplates/command/createCommandWithPostfachMail.json.tmpl index 48616ee6e0851973aca270eeaf5cd3abc864081c..1481e0b8af4c3810e80c70855a01bab4351b59b8 100644 --- a/goofy-server/src/test/resources/jsonTemplates/command/createCommandWithPostfachMail.json.tmpl +++ b/goofy-server/src/test/resources/jsonTemplates/command/createCommandWithPostfachMail.json.tmpl @@ -3,6 +3,7 @@ "body": { "replyOption": "%s", "subject": %s, - "mailBody": %s + "mailBody": %s, + "attachments": ["%s"] } } \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8f2380ad5b37a33247b8a51bcc4724c841cd689f..c1ef0b7be4e8c3bcca6e7bf3c32d8fb63af4bb04 100644 --- a/pom.xml +++ b/pom.xml @@ -5,14 +5,14 @@ <groupId>de.itvsh.ozg</groupId> <artifactId>goofy</artifactId> - <version>0.26.0-SNAPSHOT</version> + <version>0.27.0-SNAPSHOT</version> <name>Goofy Parent</name> <packaging>pom</packaging> <parent> <groupId>de.itvsh.kop.common</groupId> <artifactId>kop-common-parent</artifactId> - <version>1.1.1-SNAPSHOT</version> + <version>1.1.3</version> </parent> <modules> @@ -24,7 +24,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - <pluto.version>0.25.0</pluto.version> + <pluto.version>0.27.0-SNAPSHOT</pluto.version> </properties> <dependencyManagement>