From 0d63d4ffa18d6e4d4150f531ab101f61464998c5 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:02:49 +0200 Subject: [PATCH 01/20] add keycloak migration files for wahlvorbereitung --- ...wahlvorbereitung-urnenwahlvorbereitung.yml | 30 +++++++++++++++++++ ...-and-assign-group-all-wahlvorbereitung.yml | 9 ++++++ .../keycloak/migration/keycloak-changelog.yml | 4 ++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml create mode 100644 stack/keycloak/migration/create-and-assign-group-all-wahlvorbereitung.yml diff --git a/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml b/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml new file mode 100644 index 000000000..05cb2af36 --- /dev/null +++ b/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml @@ -0,0 +1,30 @@ +id: add authorities wahlvorbereitung urnenwahlvorbereitung +author: MrSebastian +realm: ${SSO_REALM} +changes: + - addRole: + name: Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allWahlvorbereitungAuthorities + role: Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Wahlvorbereitung_WRITE_UrnenwahlVorbereitung + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allWahlvorbereitungAuthorities + role: Wahlvorbereitung_WRITE_UrnenwahlVorbereitung + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Wahlvorbereitung_DELETE_UrnenwahlVorbereitung + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allWahlvorbereitungAuthorities + role: Wahlvorbereitung_DELETE_UrnenwahlVorbereitung + clientId: ${SSO_CLIENT_ID} \ No newline at end of file diff --git a/stack/keycloak/migration/create-and-assign-group-all-wahlvorbereitung.yml b/stack/keycloak/migration/create-and-assign-group-all-wahlvorbereitung.yml new file mode 100644 index 000000000..cf39c29c8 --- /dev/null +++ b/stack/keycloak/migration/create-and-assign-group-all-wahlvorbereitung.yml @@ -0,0 +1,9 @@ +id: create group allWahlvorbereitungAuthorities +author: MrSebastian +realm: ${SSO_REALM} +changes: + - addGroup: + name: allWahlvorbereitungAuthorities + - assignGroup: + user: wls_all + group: allWahlvorbereitungAuthorities \ No newline at end of file diff --git a/stack/keycloak/migration/keycloak-changelog.yml b/stack/keycloak/migration/keycloak-changelog.yml index 5a1c89173..371a27932 100644 --- a/stack/keycloak/migration/keycloak-changelog.yml +++ b/stack/keycloak/migration/keycloak-changelog.yml @@ -12,4 +12,6 @@ includes: - path: 07_add-briefwahl-beanstandete-wahlbriefe-authorities.yml - path: 08_create-group-all-briefwahl-and-assign.yml - path: 09_add-briefwahl-beanstandete-wahbriefe-to-group-all-briefwahl.yml - - path: add-authorities-infomanagement-konfigurierterwahltag.yml \ No newline at end of file + - path: add-authorities-infomanagement-konfigurierterwahltag.yml + - path: create-and-assign-group-all-wahlvorbereitung.yml + - path: add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml \ No newline at end of file From 88287fb692cf9e18a9b14880c76bca5a2fc4cc11 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:03:27 +0200 Subject: [PATCH 02/20] add flyway for urnenwahlvorbereitung --- ...1_0__createTablesUrnenwahlvorbereitung.sql | 19 +++++++++++++++++++ ...1_0__createTablesUrnenwahlvorbereitung.sql | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 wls-wahlvorbereitung-service/src/main/resources/db/migrations/h2/V1_0__createTablesUrnenwahlvorbereitung.sql create mode 100644 wls-wahlvorbereitung-service/src/main/resources/db/migrations/oracle/V1_0__createTablesUrnenwahlvorbereitung.sql diff --git a/wls-wahlvorbereitung-service/src/main/resources/db/migrations/h2/V1_0__createTablesUrnenwahlvorbereitung.sql b/wls-wahlvorbereitung-service/src/main/resources/db/migrations/h2/V1_0__createTablesUrnenwahlvorbereitung.sql new file mode 100644 index 000000000..6153c1eb8 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/resources/db/migrations/h2/V1_0__createTablesUrnenwahlvorbereitung.sql @@ -0,0 +1,19 @@ +create table UrnenwahlVorbereitung +( + wahlbezirkid varchar(1000) not null, + anzahlwahlkabinen BIGINT not null, + anzahlwahltische BIGINT not null, + anzahlnebenraeume BIGINT not null, + primary key (wahlbezirkid) +); + +create table UWVorbereitung_Urnen +( + vorbereitung_wahlbezirkID varchar(1000) not null, + wahlid varchar(1000) not null, + anzahl BIGINT not null, + urneversiegelt BOOLEAN, + constraint fk_UrnenwahlVorbereitung + foreign key (vorbereitung_wahlbezirkID) + references UrnenwahlVorbereitung (wahlbezirkID) +); diff --git a/wls-wahlvorbereitung-service/src/main/resources/db/migrations/oracle/V1_0__createTablesUrnenwahlvorbereitung.sql b/wls-wahlvorbereitung-service/src/main/resources/db/migrations/oracle/V1_0__createTablesUrnenwahlvorbereitung.sql new file mode 100644 index 000000000..8e8165c67 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/resources/db/migrations/oracle/V1_0__createTablesUrnenwahlvorbereitung.sql @@ -0,0 +1,19 @@ +create table UrnenwahlVorbereitung +( + wahlbezirkid varchar(1000) not null, + anzahlwahlkabinen NUMBER(19, 0) not null, + anzahlwahltische NUMBER(19, 0) not null, + anzahlnebenraeume NUMBER(19, 0) not null, + primary key (wahlbezirkid) +); + +create table UWVorbereitung_Urnen +( + vorbereitung_wahlbezirkID varchar(1000) not null, + wahlid varchar(1000) not null, + anzahl NUMBER(19, 0) not null, + urneversiegelt NUMBER(1), + constraint fk_UrnenwahlVorbereitung + foreign key (vorbereitung_wahlbezirkID) + references UrnenwahlVorbereitung (wahlbezirkID) +); From 4fc2986af551c5f648a31e03329dc1a213bb2a05 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:03:54 +0200 Subject: [PATCH 03/20] add service.info.oid property to default profile --- .../src/main/resources/application.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wls-wahlvorbereitung-service/src/main/resources/application.yml b/wls-wahlvorbereitung-service/src/main/resources/application.yml index f19584667..1c331cdcb 100644 --- a/wls-wahlvorbereitung-service/src/main/resources/application.yml +++ b/wls-wahlvorbereitung-service/src/main/resources/application.yml @@ -24,6 +24,9 @@ security: oauth2: resource.user-info-uri: http://kubernetes.docker.internal:8100/auth/realms/${realm}/protocol/openid-connect/userinfo +service: + info: + oid: WLS-WAHLVORBEREITUNG # Define the local keycloak realm here realm: wls_realm From dac73c33f5a91b1a92a15b8769b35557b5aae554 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:04:19 +0200 Subject: [PATCH 04/20] include dummy bezirkID evaluator on no-sec profile --- wls-wahlvorbereitung-service/src/main/resources/application.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wls-wahlvorbereitung-service/src/main/resources/application.yml b/wls-wahlvorbereitung-service/src/main/resources/application.yml index 1c331cdcb..8864647f1 100644 --- a/wls-wahlvorbereitung-service/src/main/resources/application.yml +++ b/wls-wahlvorbereitung-service/src/main/resources/application.yml @@ -5,6 +5,8 @@ spring: group: local: - db-oracle + no-security: + - dummy.nobezirkid.check flyway: locations: - classpath:db/migrations/{vendor} From 718891ffa2b7d0e5e4f9cce973a3d40d7ecdb1a4 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:04:41 +0200 Subject: [PATCH 05/20] fix and change keycloak config --- .../src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wls-wahlvorbereitung-service/src/main/resources/application.yml b/wls-wahlvorbereitung-service/src/main/resources/application.yml index 8864647f1..28898a0ea 100644 --- a/wls-wahlvorbereitung-service/src/main/resources/application.yml +++ b/wls-wahlvorbereitung-service/src/main/resources/application.yml @@ -16,7 +16,7 @@ spring: oauth2: resourceserver: jwt: - jwk-set-uri: http://kubernetes.docker.internal:8100/auth/realms/${realm}/protocol/openid-connect/userinfo + jwk-set-uri: http://localhost:8100/auth/realms/${realm}/protocol/openid-connect/certs @@ -24,7 +24,7 @@ security: # possible values: none, all, changing (With changing, only changing requests such as POST, PUT, DELETE are logged) logging.requests: all oauth2: - resource.user-info-uri: http://kubernetes.docker.internal:8100/auth/realms/${realm}/protocol/openid-connect/userinfo + resource.user-info-uri: http://localhost:8100/auth/realms/${realm}/protocol/openid-connect/userinfo service: info: From 47b1cd743a7ed14954df9d0f6d0052114e35e75c Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:05:08 +0200 Subject: [PATCH 06/20] add wls-common packages for component scan --- .../wahlvorbereitungservice/MicroServiceApplication.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/MicroServiceApplication.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/MicroServiceApplication.java index 4aeebc94b..38d6d56d3 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/MicroServiceApplication.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/MicroServiceApplication.java @@ -18,7 +18,9 @@ @ComponentScan( basePackages = { "org.springframework.data.jpa.convert.threeten", - "de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice" + "de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice", + "de.muenchen.oss.wahllokalsystem.wls.common.exception", + "de.muenchen.oss.wahllokalsystem.wls.common.security" } ) @EntityScan( From e1fd83a39fd36f958d14b1e0fb9152668320c1ff Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:05:30 +0200 Subject: [PATCH 07/20] add example http requests for get urnenwahlvorbereitung --- .../test/resources/urnenwahlvorbereitung.http | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wls-wahlvorbereitung-service/src/test/resources/urnenwahlvorbereitung.http diff --git a/wls-wahlvorbereitung-service/src/test/resources/urnenwahlvorbereitung.http b/wls-wahlvorbereitung-service/src/test/resources/urnenwahlvorbereitung.http new file mode 100644 index 000000000..44995e556 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/resources/urnenwahlvorbereitung.http @@ -0,0 +1,21 @@ +POST http://localhost:8100/auth/realms/wls_realm/protocol/openid-connect/token +Content-Type: application/x-www-form-urlencoded + +password = test & +grant_type = password & +client_secret = top-secret & +client_id = wls & +username = wls_all + +> {% + client.global.set("auth_token", response.body.access_token); + client.global.set("token_type", response.body.token_type); +%} + +### get userinfo with auth_token +GET http://localhost:8100/auth/realms/wls_realm/protocol/openid-connect/userinfo +Authorization: {{ token_type }} {{ auth_token }} + +### GET wbzID-1 +GET http://localhost:39150/businessActions/urnenwahlVorbereitung/wbzID-1 +Authorization: {{ token_type }} {{ auth_token }} \ No newline at end of file From 168219ed11fef6a41addb1ab70904640e13f0c4a Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:09:18 +0200 Subject: [PATCH 08/20] impl and testing get UrnenwahlVorbereitung --- .../domain/UrnenwahlVorbereitung.java | 40 ++++++++ .../UrnenwahlVorbereitungRepository.java | 45 +++++++++ .../domain/Wahlurne.java | 2 + .../exception/ExceptionConstants.java | 15 +++ .../exception/ExceptionDataWrapper.java | 6 ++ .../exception/ExceptionFactory.java | 18 ++++ .../UrnenwahlvorbereitungController.java | 32 ++++++ .../UrnenwahlvorbereitungDTO.java | 8 ++ .../UrnenwahlvorbereitungDTOMapper.java | 11 +++ .../UrnenwahlvorbereitungModel.java | 10 ++ .../UrnenwahlvorbereitungModelMapper.java | 11 +++ .../UrnenwahlvorbereitungService.java | 38 ++++++++ .../UrnenwahlvorbereitungValidator.java | 19 ++++ .../SecurityConfigurationTest.java | 53 ++++++++++ .../exception/ExceptionFactoryTest.java | 46 +++++++++ ...vorbereitungControllerIntegrationTest.java | 97 +++++++++++++++++++ .../UrnenwahlvorbereitungControllerTest.java | 62 ++++++++++++ .../UrnenwahlvorbereitungDTOMapperTest.java | 44 +++++++++ .../UrnenwahlvorbereitungModelMapperTest.java | 42 ++++++++ .../UrnenwahlvorbereitungSecurityTest.java | 83 ++++++++++++++++ .../UrnenwahlvorbereitungServiceTest.java | 78 +++++++++++++++ .../UrnenwahlvorbereitungValidatorTest.java | 54 +++++++++++ .../utils/Authorities.java | 17 ++++ .../utils/SecurityUtils.java | 32 ++++++ ...UrnenwahlVorbereitungTestdatenfactory.java | 12 +++ .../testdaten/WahlurneTestdatenfactory.java | 10 ++ 26 files changed, 885 insertions(+) create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitungRepository.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionConstants.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionDataWrapper.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactory.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapper.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapper.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungService.java create mode 100644 wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidator.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapperTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapperTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungSecurityTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungServiceTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/Authorities.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/SecurityUtils.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/UrnenwahlVorbereitungTestdatenfactory.java create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/WahlurneTestdatenfactory.java diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java new file mode 100644 index 000000000..0049d8b74 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java @@ -0,0 +1,40 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain; + +import jakarta.persistence.CollectionTable; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UrnenwahlVorbereitung { + + @Id + @NotNull + @Size(max = 255) + private String wahlbezirkID; + + @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(name = "UWVorbereitung_Urnen", joinColumns = @JoinColumn(name = "vorbereitung_wahlbezirkID")) + @NotNull + @Size(min = 1) + private java.util.List urnenAnzahl = new java.util.ArrayList<>(); + + private long anzahlWahlkabinen; + + private long anzahlWahltische; + + private long anzahlNebenraeume; + +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitungRepository.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitungRepository.java new file mode 100644 index 000000000..bf2d1827a --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitungRepository.java @@ -0,0 +1,45 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain; + +import java.util.Optional; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.repository.CrudRepository; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface UrnenwahlVorbereitungRepository extends CrudRepository { + + String CACHE = "UrnenwahlVorbereitungCACHE"; + + @Override + Iterable findAll(); + + @Override + @Cacheable(value = CACHE, key = "#p0") + Optional findById(String wahlbezirkID); + + @Override + @CachePut(value = CACHE, key = "#p0.wahlbezirkID") + @PreAuthorize("hasAuthority('Wahlvorbereitung_WRITE_UrnenwahlVorbereitung')") + S save(S urnenwahlVorbereitung); + + @Override + @CacheEvict(value = CACHE, key = "#p0") + @PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')") + void deleteById(String wahlbezirkID); + + @Override + @CacheEvict(value = CACHE, key = "#p0.wahlbezirkID") + @PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')") + void delete(UrnenwahlVorbereitung entity); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')") + void deleteAll(Iterable entities); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')") + void deleteAll(); +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/Wahlurne.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/Wahlurne.java index 36fd1710c..6619c1bb8 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/Wahlurne.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/Wahlurne.java @@ -4,6 +4,7 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @@ -11,6 +12,7 @@ @Data @NoArgsConstructor @AllArgsConstructor +@Builder public class Wahlurne { @NotNull diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionConstants.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionConstants.java new file mode 100644 index 000000000..cb532dd81 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionConstants.java @@ -0,0 +1,15 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ExceptionConstants { + + private static final String CODE_SUCHKRITERIEN_UNVOLLSTAENDIG = "901"; + private static final String MSG_SUCHKRITERIEN_UNVOLLSTAENDIG = "Fehler beim Laden: Suchkriterien unvollständig."; + + public static ExceptionDataWrapper SUCHKRITERIEN_UNVOLLSTAENDIG = new ExceptionDataWrapper(CODE_SUCHKRITERIEN_UNVOLLSTAENDIG, + MSG_SUCHKRITERIEN_UNVOLLSTAENDIG); + +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionDataWrapper.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionDataWrapper.java new file mode 100644 index 000000000..1bcdfd2eb --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionDataWrapper.java @@ -0,0 +1,6 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception; + +import jakarta.validation.constraints.NotNull; + +public record ExceptionDataWrapper(@NotNull String code, @NotNull String message) { +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactory.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactory.java new file mode 100644 index 000000000..c43666b25 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactory.java @@ -0,0 +1,18 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception; + +import de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ServiceIDFormatter; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ExceptionFactory { + + private final ServiceIDFormatter serviceIDFormatter; + + public FachlicheWlsException createFachlicheWlsException(final ExceptionDataWrapper exceptionDataWrapper) { + return FachlicheWlsException.withCode(exceptionDataWrapper.code()).inService(serviceIDFormatter.getId()) + .buildWithMessage(exceptionDataWrapper.message()); + } +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java new file mode 100644 index 000000000..fad72fc5a --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java @@ -0,0 +1,32 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungService; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.val; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/businessActions/urnenwahlVorbereitung") +@RequiredArgsConstructor +public class UrnenwahlvorbereitungController { + + private final UrnenwahlvorbereitungService service; + + private final UrnenwahlvorbereitungDTOMapper urnenwahlvorbereitungDTOMapper; + + @GetMapping("{wahlbezirkID}") + public ResponseEntity getUrnenwahlVorbereitung(@PathVariable("wahlbezirkID") final String wahlbezirkID) { + val urnenwahlvorbereitungModel = service.getUrnenwahlvorbereitung(wahlbezirkID); + + return withBodyOrNoContent(urnenwahlvorbereitungModel.map(urnenwahlvorbereitungDTOMapper::toDTO)); + } + + private ResponseEntity withBodyOrNoContent(final Optional body) { + return body.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.noContent().build()); + } +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java new file mode 100644 index 000000000..774d9c550 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java @@ -0,0 +1,8 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTO; +import java.util.List; + +public record UrnenwahlvorbereitungDTO(String wahlbezirkID, long anzahlWahlkabinen, long anzahlWahltische, long anzahlNebenraeume, + List urnenAnzahl) { +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapper.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapper.java new file mode 100644 index 000000000..a2c52b1d7 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapper.java @@ -0,0 +1,11 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTOMapper; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungModel; +import org.mapstruct.Mapper; + +@Mapper(uses = WahlurneDTOMapper.class) +public interface UrnenwahlvorbereitungDTOMapper { + + UrnenwahlvorbereitungDTO toDTO(UrnenwahlvorbereitungModel model); +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java new file mode 100644 index 000000000..426ffecc9 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java @@ -0,0 +1,10 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModel; +import java.util.List; +import lombok.Builder; + +@Builder +public record UrnenwahlvorbereitungModel(String wahlbezirkID, long anzahlWahlkabinen, long anzahlWahltische, long anzahlNebenraeume, + List urnenAnzahl) { +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapper.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapper.java new file mode 100644 index 000000000..902453c18 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapper.java @@ -0,0 +1,11 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitung; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModelMapper; +import org.mapstruct.Mapper; + +@Mapper(uses = WahlurneModelMapper.class) +public interface UrnenwahlvorbereitungModelMapper { + + UrnenwahlvorbereitungModel toModel(UrnenwahlVorbereitung entity); +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungService.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungService.java new file mode 100644 index 000000000..a5ff923ee --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungService.java @@ -0,0 +1,38 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitungRepository; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.parameters.P; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class UrnenwahlvorbereitungService { + + private final UrnenwahlVorbereitungRepository urnenwahlVorbereitungRepository; + + private final UrnenwahlvorbereitungModelMapper urnenwahlvorbereitungModelMapper; + + private final UrnenwahlvorbereitungValidator urnenwahlvorbereitungValidator; + + @PreAuthorize( + "hasAuthority('Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung')" + + "and @bezirkIdPermisionEvaluator.tokenUserBezirkIdMatches(#wahlbezirkID, authentication)" + ) + public Optional getUrnenwahlvorbereitung(@P("wahlbezirkID") final String wahlbezirkID) { + log.debug("#getUrnenwahlVorbereitung"); + log.debug("in: wahlbezirkID > {}", wahlbezirkID); + + urnenwahlvorbereitungValidator.validWahlbezirkIDOrThrow(wahlbezirkID); + + val dataFromRepo = urnenwahlVorbereitungRepository.findById(wahlbezirkID); + log.debug("out: urnenwahlVorbereitung > {}", dataFromRepo.orElse(null)); + + return dataFromRepo.map(urnenwahlvorbereitungModelMapper::toModel); + } +} diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidator.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidator.java new file mode 100644 index 000000000..94120257a --- /dev/null +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidator.java @@ -0,0 +1,19 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception.ExceptionConstants; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception.ExceptionFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class UrnenwahlvorbereitungValidator { + + private final ExceptionFactory exceptionFactory; + + public void validWahlbezirkIDOrThrow(final String wahlbezirkID) { + if (wahlbezirkID == null || wahlbezirkID.isEmpty()) { + throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.SUCHKRITERIEN_UNVOLLSTAENDIG); + } + } +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java new file mode 100644 index 000000000..c6394cdf5 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java @@ -0,0 +1,53 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.configuration; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.MicroServiceApplication; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.TestConstants; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungService; +import lombok.val; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithAnonymousUser; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +@SpringBootTest(classes = MicroServiceApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@AutoConfigureMockMvc +@AutoConfigureObservability +@ActiveProfiles(profiles = { TestConstants.SPRING_TEST_PROFILE }) +public class SecurityConfigurationTest { + + @MockBean + UrnenwahlvorbereitungService urnenwahlvorbereitungService; + + @Autowired + MockMvc mockMvc; + + @Nested + class Urnenwahlvorbereitung { + + @Test + @WithAnonymousUser + void accessGetUrnenwahlvorbereitungUnauthorizedThenUnauthorized() throws Exception { + val request = MockMvcRequestBuilders.get("/businessActions/urnenwahlVorbereitung/wahlbezirkID"); + + mockMvc.perform(request).andExpect(status().isUnauthorized()); + } + + @Test + @WithMockUser + void accessGetUrnenwahlvorbereitungAuthorizedThenNoContent() throws Exception { + val request = MockMvcRequestBuilders.get("/businessActions/urnenwahlVorbereitung/wahlbezirkID"); + + mockMvc.perform(request).andExpect(status().isNoContent()); + } + } +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java new file mode 100644 index 000000000..68c0c0fe5 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java @@ -0,0 +1,46 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception; + +import de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ServiceIDFormatter; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class ExceptionFactoryTest { + + @Mock + ServiceIDFormatter serviceIDFormatter; + + @InjectMocks + ExceptionFactory unitUnderTest; + + @Nested + class CreateFachlicheWlsException { + + @Test + void buildWithExceptionDataWrapperData() { + val code = "0815"; + val message = "Everything Everywhere All at Once"; + val wrappedData = new ExceptionDataWrapper(code, message); + + val serviceID = "serviceID"; + Mockito.when(serviceIDFormatter.getId()).thenReturn(serviceID); + + val result = unitUnderTest.createFachlicheWlsException(wrappedData); + + val expectedResult = FachlicheWlsException.withCode(code).inService(serviceID).buildWithMessage(message); + + Assertions.assertThat(result).usingRecursiveComparison().isEqualTo(expectedResult); + + } + + } + +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java new file mode 100644 index 000000000..9cb095302 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java @@ -0,0 +1,97 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.databind.ObjectMapper; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.MicroServiceApplication; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.TestConstants; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitungRepository; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungModelMapper; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.Authorities; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.SecurityUtils; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.testdaten.UrnenwahlVorbereitungTestdatenfactory; +import de.muenchen.oss.wahllokalsystem.wls.common.security.Profiles; +import java.util.List; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest(classes = MicroServiceApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@AutoConfigureMockMvc +@ActiveProfiles({ TestConstants.SPRING_TEST_PROFILE, Profiles.NO_BEZIRKS_ID_CHECK }) +public class UrnenwahlvorbereitungControllerIntegrationTest { + + @Autowired + MockMvc mockMvc; + + @Autowired + ObjectMapper objectMapper; + + @Autowired + UrnenwahlvorbereitungModelMapper urnenwahlvorbereitungModelMapper; + + @Autowired + UrnenwahlvorbereitungDTOMapper urnenwahlvorbereitungDTOMapper; + + @Autowired + UrnenwahlVorbereitungRepository urnenwahlVorbereitungRepository; + + @AfterEach + void tearDown() throws Exception { + SecurityUtils.runAs(Authorities.REPOSITORY_DELETE_URNENWAHLVORBEREITUNG); + urnenwahlVorbereitungRepository.deleteAll(); + } + + @Nested + class GetUrnenwahlVorbereitung { + + @Test + @WithMockUser(authorities = { Authorities.SERVICE_GET_URNENWAHLVORBEREITUNG }) + void dataFound() throws Exception { + val wahlbezirkIDToFind = "wahlbezirkIDToFind"; + + val wahlbezirk1 = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk1", "wahlID1").build(); + val wahlbezirk2 = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk2", "wahlID2").build(); + val wahlbezirkToFind = UrnenwahlVorbereitungTestdatenfactory.initValid(wahlbezirkIDToFind, "wahlID3").build(); + val wahlbezirk4 = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk4", "wahlID4").build(); + urnenwahlVorbereitungRepository.saveAll(List.of(wahlbezirk1, wahlbezirk2, wahlbezirkToFind, wahlbezirk4)); + + val request = get("/businessActions/urnenwahlVorbereitung/" + wahlbezirkIDToFind); + + val response = mockMvc.perform(request).andExpect(status().isOk()).andReturn(); + val responseBodyAsDTO = objectMapper.readValue(response.getResponse().getContentAsString(), UrnenwahlvorbereitungDTO.class); + + val expectedResponseBody = urnenwahlvorbereitungDTOMapper.toDTO(urnenwahlvorbereitungModelMapper.toModel(wahlbezirkToFind)); + + Assertions.assertThat(responseBodyAsDTO).isEqualTo(expectedResponseBody); + } + + @Test + @WithMockUser(authorities = { Authorities.SERVICE_GET_URNENWAHLVORBEREITUNG }) + void noDataFound() throws Exception { + val wahlbezirkIDToLookup = "wahlbezirkIDToFind"; + + val wahlbezirk1 = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk1", "wahlID1").build(); + val wahlbezirk2 = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk2", "wahlID2").build(); + val wahlbezirkToFind = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk3", "wahlID3").build(); + val wahlbezirk4 = UrnenwahlVorbereitungTestdatenfactory.initValid("wahlbezirk4", "wahlID4").build(); + urnenwahlVorbereitungRepository.saveAll(List.of(wahlbezirk1, wahlbezirk2, wahlbezirkToFind, wahlbezirk4)); + + val request = get("/businessActions/urnenwahlVorbereitung/" + wahlbezirkIDToLookup); + + val response = mockMvc.perform(request).andExpect(status().isNoContent()).andReturn(); + + Assertions.assertThat(response.getResponse().getContentAsString()).isEmpty(); + + } + } +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerTest.java new file mode 100644 index 000000000..55fdb0710 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerTest.java @@ -0,0 +1,62 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungModel; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungService; +import java.util.Collections; +import java.util.Optional; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; + +@ExtendWith(MockitoExtension.class) +class UrnenwahlvorbereitungControllerTest { + + @Mock + UrnenwahlvorbereitungService service; + + @Mock + UrnenwahlvorbereitungDTOMapper urnenwahlvorbereitungDTOMapper; + + @InjectMocks + UrnenwahlvorbereitungController unitUnderTest; + + @Nested + class GetUrnenwahlVorbereitung { + + @Test + void gotDataFromService() { + val wahlbezirkID = "wahlbezirkID"; + + val mockedServiceOptionalBody = new UrnenwahlvorbereitungModel(wahlbezirkID, 0, 0, 0, Collections.emptyList()); + val mockedMappedServiceResponseAsDTO = new UrnenwahlvorbereitungDTO(wahlbezirkID, 0, 0, 0, Collections.emptyList()); + + Mockito.when(service.getUrnenwahlvorbereitung(wahlbezirkID)).thenReturn(Optional.of(mockedServiceOptionalBody)); + Mockito.when(urnenwahlvorbereitungDTOMapper.toDTO(mockedServiceOptionalBody)).thenReturn(mockedMappedServiceResponseAsDTO); + + val result = unitUnderTest.getUrnenwahlVorbereitung(wahlbezirkID); + + Assertions.assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); + Assertions.assertThat(result.getBody()).isEqualTo(mockedMappedServiceResponseAsDTO); + } + + @Test + void gotNoDataFromService() { + val wahlbezirkID = "wahlbezirkID"; + + Mockito.when(service.getUrnenwahlvorbereitung(wahlbezirkID)).thenReturn(Optional.empty()); + + val result = unitUnderTest.getUrnenwahlVorbereitung(wahlbezirkID); + + Assertions.assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + Assertions.assertThat(result.getBody()).isNull(); + } + } + +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapperTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapperTest.java new file mode 100644 index 000000000..04b52cfa6 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOMapperTest.java @@ -0,0 +1,44 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTO; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTOMapperImpl; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModel; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungModel; +import java.util.List; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = { UrnenwahlvorbereitungDTOMapperImpl.class, WahlurneDTOMapperImpl.class }) +class UrnenwahlvorbereitungDTOMapperTest { + + @Autowired + private UrnenwahlvorbereitungDTOMapper unitUnderTest; + + @Nested + class ToDTO { + + @Test + void isMapped() { + val wahlbezirkID = "wahlbezirkID"; + val anzahlKabinen = 12; + val anzahlWahltische = 21; + val anzahlNebenraeume = 4; + val urne1 = new WahlurneModel("wahlID1", 2, true); + val urne2 = new WahlurneModel("wahlID2", 4, false); + val urnen = List.of(urne1, urne2); + val modelToMap = new UrnenwahlvorbereitungModel(wahlbezirkID, anzahlKabinen, anzahlWahltische, anzahlNebenraeume, urnen); + + val result = unitUnderTest.toDTO(modelToMap); + + val expectedUrnen = List.of(new WahlurneDTO("wahlID1", 2, true), new WahlurneDTO("wahlID2", 4, false)); + val expectedResult = new UrnenwahlvorbereitungDTO(wahlbezirkID, anzahlKabinen, anzahlWahltische, anzahlNebenraeume, expectedUrnen); + + Assertions.assertThat(result).isEqualTo(expectedResult); + } + } + +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapperTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapperTest.java new file mode 100644 index 000000000..9c177161b --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelMapperTest.java @@ -0,0 +1,42 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitung; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.Wahlurne; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModel; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModelMapperImpl; +import java.util.List; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = { WahlurneModelMapperImpl.class, UrnenwahlvorbereitungModelMapperImpl.class }) +class UrnenwahlvorbereitungModelMapperTest { + + @Autowired + private UrnenwahlvorbereitungModelMapper unitUnderTest; + + @Nested + class ToModel { + + @Test + void isMapped() { + val wahlbezirkID = "wahlbezirkID"; + val anzahlKabinen = 21; + val anzahlNebenraeume = 3; + val anzahlTische = 7; + val urnen = List.of(new Wahlurne("wahlID1", 3, true), new Wahlurne("wahlID5", 17, false)); + val entityToMap = new UrnenwahlVorbereitung(wahlbezirkID, urnen, anzahlKabinen, anzahlTische, anzahlNebenraeume); + + val result = unitUnderTest.toModel(entityToMap); + + val expectedUrnen = List.of(new WahlurneModel("wahlID1", 3, true), new WahlurneModel("wahlID5", 17, false)); + val expecetedResult = new UrnenwahlvorbereitungModel(wahlbezirkID, anzahlKabinen, anzahlTische, anzahlNebenraeume, expectedUrnen); + + Assertions.assertThat(result).isEqualTo(expecetedResult); + } + } + +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungSecurityTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungSecurityTest.java new file mode 100644 index 000000000..48e10d4c2 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungSecurityTest.java @@ -0,0 +1,83 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.MicroServiceApplication; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.TestConstants; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.Authorities; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.SecurityUtils; +import de.muenchen.oss.wahllokalsystem.wls.common.security.BezirkIDPermissionEvaluator; +import java.util.stream.Stream; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.aggregator.ArgumentsAccessor; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest(classes = MicroServiceApplication.class) +@ActiveProfiles({ TestConstants.SPRING_TEST_PROFILE }) +public class UrnenwahlvorbereitungSecurityTest { + + @MockBean(name = "bezirkIdPermisionEvaluator") + BezirkIDPermissionEvaluator bezirkIDPermissionEvaluator; + + @Autowired + UrnenwahlvorbereitungService unitUnderTest; + + @BeforeEach + void setup() { + SecurityContextHolder.clearContext(); + } + + @Nested + class GetUrnenwahlvorbereitung { + + @Test + void accessGranted() { + SecurityUtils.runAs(Authorities.ALL_AUTHORITIES_GET_URNENWAHLVORBEREITUNG); + + val wahlbezirkID = "wahlbezirkID"; + + Mockito.when(bezirkIDPermissionEvaluator.tokenUserBezirkIdMatches(Mockito.eq(wahlbezirkID), Mockito.any())).thenReturn(true); + + Assertions.assertThatNoException().isThrownBy(() -> unitUnderTest.getUrnenwahlvorbereitung(wahlbezirkID)); + } + + @Test + void bezirkIDPermissionEvaluatorFailed() { + SecurityUtils.runAs(Authorities.ALL_AUTHORITIES_GET_URNENWAHLVORBEREITUNG); + + val wahlbezirkID = "wahlbezirkID"; + + Mockito.when(bezirkIDPermissionEvaluator.tokenUserBezirkIdMatches(Mockito.eq(wahlbezirkID), Mockito.any())).thenReturn(false); + + Assertions.assertThatException().isThrownBy(() -> unitUnderTest.getUrnenwahlvorbereitung(wahlbezirkID)) + .isExactlyInstanceOf(AccessDeniedException.class); + } + + @ParameterizedTest(name = "{index} - {1} missing") + @MethodSource("getMissingAuthoritiesVariations") + void anyMissingAuthorityCausesFail(final ArgumentsAccessor argumentsAccessor) { + SecurityUtils.runAs(argumentsAccessor.get(0, String[].class)); + + val wahlbezirkID = "wahlbezirkID"; + Mockito.when(bezirkIDPermissionEvaluator.tokenUserBezirkIdMatches(Mockito.eq(wahlbezirkID), Mockito.any())).thenReturn(true); + + Assertions.assertThatThrownBy(() -> unitUnderTest.getUrnenwahlvorbereitung(wahlbezirkID)) + .isExactlyInstanceOf(AccessDeniedException.class); + } + + private static Stream getMissingAuthoritiesVariations() { + return SecurityUtils.buildArgumentsForMissingAuthoritiesVariations(Authorities.ALL_AUTHORITIES_GET_URNENWAHLVORBEREITUNG); + } + } +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungServiceTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungServiceTest.java new file mode 100644 index 000000000..c8011f8fc --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungServiceTest.java @@ -0,0 +1,78 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitung; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitungRepository; +import java.util.Optional; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class UrnenwahlvorbereitungServiceTest { + + @Mock + UrnenwahlVorbereitungRepository urnenwahlVorbereitungRepository; + + @Mock + UrnenwahlvorbereitungModelMapper urnenwahlvorbereitungModelMapper; + + @Mock + UrnenwahlvorbereitungValidator urnenwahlvorbereitungValidator; + + @InjectMocks + UrnenwahlvorbereitungService unitUnderTest; + + @Nested + class getUrnenwahlvorbereitung { + @Test + void dataFound() { + val wahlbezirkID = "wahlbezirkID"; + + val mockedRepoResponse = new UrnenwahlVorbereitung(); + val mockedMappedRepoResponseAsModel = UrnenwahlvorbereitungModel.builder().build(); + + Mockito.doNothing().when(urnenwahlvorbereitungValidator).validWahlbezirkIDOrThrow(wahlbezirkID); + Mockito.when(urnenwahlVorbereitungRepository.findById(wahlbezirkID)).thenReturn(Optional.of(mockedRepoResponse)); + Mockito.when(urnenwahlvorbereitungModelMapper.toModel(mockedRepoResponse)).thenReturn(mockedMappedRepoResponseAsModel); + + val result = unitUnderTest.getUrnenwahlvorbereitung(wahlbezirkID); + + Assertions.assertThat(result.get()).isEqualTo(mockedMappedRepoResponseAsModel); + } + + @Test + void noDataFound() { + val wahlbezirkID = "wahlbezirkID"; + + Mockito.doNothing().when(urnenwahlvorbereitungValidator).validWahlbezirkIDOrThrow(wahlbezirkID); + Mockito.when(urnenwahlVorbereitungRepository.findById(wahlbezirkID)).thenReturn(Optional.empty()); + + val result = unitUnderTest.getUrnenwahlvorbereitung(wahlbezirkID); + + Assertions.assertThat(result).isEmpty(); + + Mockito.verify(urnenwahlvorbereitungModelMapper, times(0)).toModel(any()); + } + + @Test + void exceptionFromValidator() { + val wahlbezirkID = "wahlbezirkID"; + + val mockedValidatorException = new RuntimeException("validation failed"); + + Mockito.doThrow(mockedValidatorException).when(urnenwahlvorbereitungValidator).validWahlbezirkIDOrThrow(wahlbezirkID); + + Assertions.assertThatException().isThrownBy(() -> unitUnderTest.getUrnenwahlvorbereitung(wahlbezirkID)).isSameAs(mockedValidatorException); + } + } + +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java new file mode 100644 index 000000000..ac45bd1c7 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java @@ -0,0 +1,54 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception.ExceptionConstants; +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception.ExceptionFactory; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class UrnenwahlvorbereitungValidatorTest { + + @Mock + ExceptionFactory exceptionFactory; + + @InjectMocks + UrnenwahlvorbereitungValidator unitUnderTest; + + @Nested + class ValidWahlbezirkIDOrThrow { + + @Test + void noExceptionOnValidWahlbezirkID() { + val idToValidate = "wahlbezirkID"; + + Assertions.assertThatNoException().isThrownBy(() -> unitUnderTest.validWahlbezirkIDOrThrow(idToValidate)); + } + + @Test + void exceptionWhenWahlbezirkIDIsNull() { + val exceptionToThrow = FachlicheWlsException.withCode("000").buildWithMessage("error"); + + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.SUCHKRITERIEN_UNVOLLSTAENDIG)).thenReturn(exceptionToThrow); + + Assertions.assertThatException().isThrownBy(() -> unitUnderTest.validWahlbezirkIDOrThrow(null)).isSameAs(exceptionToThrow); + } + + @Test + void exceptionWhenWahlbezirkIDIsEmpty() { + val exceptionToThrow = FachlicheWlsException.withCode("000").buildWithMessage("error"); + + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.SUCHKRITERIEN_UNVOLLSTAENDIG)).thenReturn(exceptionToThrow); + + Assertions.assertThatException().isThrownBy(() -> unitUnderTest.validWahlbezirkIDOrThrow("")).isSameAs(exceptionToThrow); + } + } + +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/Authorities.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/Authorities.java new file mode 100644 index 000000000..121e9d81f --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/Authorities.java @@ -0,0 +1,17 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class Authorities { + + public static final String SERVICE_GET_URNENWAHLVORBEREITUNG = "Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung"; + + public static final String REPOSITORY_DELETE_URNENWAHLVORBEREITUNG = "Wahlvorbereitung_DELETE_UrnenwahlVorbereitung"; + public static final String REPOSITORY_WRITE_URNENWAHLVORBEREITUNG = "Wahlvorbereitung_WRITE_UrnenwahlVorbereitung"; + + public static final String[] ALL_AUTHORITIES_GET_URNENWAHLVORBEREITUNG = { + SERVICE_GET_URNENWAHLVORBEREITUNG + }; +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/SecurityUtils.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/SecurityUtils.java new file mode 100644 index 000000000..e7990afa5 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/SecurityUtils.java @@ -0,0 +1,32 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils; + +import java.util.Arrays; +import java.util.stream.Stream; +import org.junit.jupiter.params.provider.Arguments; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.context.SecurityContextHolder; + +public class SecurityUtils { + + public static final String TESTUSER_DEFAULT = "TESTUSER"; + + public static final String TESTUSER_PASSWORD_DEFUALT = "TESTUSER_PASSWORD"; + + public static void runAs(String username, String password, String... authorities) { + SecurityContextHolder.getContext().setAuthentication( + new UsernamePasswordAuthenticationToken(username, password, AuthorityUtils.createAuthorityList(authorities))); + } + + public static void runAs(String... authorities) { + SecurityUtils.runAs(TESTUSER_DEFAULT, TESTUSER_PASSWORD_DEFUALT, authorities); + } + + public static Stream buildArgumentsForMissingAuthoritiesVariations(final String[] allRequiredAuthorities) { + return Arrays.stream(allRequiredAuthorities) + .map(authorityToRemove -> + //remove one authority from all required authorities + Arguments.of(Arrays.stream(allRequiredAuthorities) + .filter(authority -> !authority.equals(authorityToRemove)).toArray(String[]::new), authorityToRemove)); + } +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/UrnenwahlVorbereitungTestdatenfactory.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/UrnenwahlVorbereitungTestdatenfactory.java new file mode 100644 index 000000000..de9b87448 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/UrnenwahlVorbereitungTestdatenfactory.java @@ -0,0 +1,12 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.testdaten; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitung; +import java.util.List; + +public class UrnenwahlVorbereitungTestdatenfactory { + + public static UrnenwahlVorbereitung.UrnenwahlVorbereitungBuilder initValid(final String wahlbezirkID, String wahlID) { + return UrnenwahlVorbereitung.builder().wahlbezirkID(wahlbezirkID).urnenAnzahl(List.of(WahlurneTestdatenfactory.initValid(wahlID).build())) + .anzahlWahlkabinen(10).anzahlWahltische(12).anzahlNebenraeume(0); + } +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/WahlurneTestdatenfactory.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/WahlurneTestdatenfactory.java new file mode 100644 index 000000000..35a6caace --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/utils/testdaten/WahlurneTestdatenfactory.java @@ -0,0 +1,10 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.utils.testdaten; + +import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.Wahlurne; + +public class WahlurneTestdatenfactory { + + public static Wahlurne.WahlurneBuilder initValid(final String wahlID) { + return Wahlurne.builder().wahlID(wahlID).anzahl(1).urneVersiegelt(true); + } +} From ee92914817d5bad466174d76cf296bd0cf961c0c Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:15:14 +0200 Subject: [PATCH 09/20] open access to swagger --- .../configuration/SecurityConfiguration.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfiguration.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfiguration.java index ba5c912a5..3179d2531 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfiguration.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfiguration.java @@ -47,7 +47,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // allow access to /actuator/health/readiness for OpenShift Readiness Check AntPathRequestMatcher.antMatcher("/actuator/health/readiness"), // allow access to /actuator/metrics for Prometheus monitoring in OpenShift - AntPathRequestMatcher.antMatcher("/actuator/metrics")) + AntPathRequestMatcher.antMatcher("/actuator/metrics"), + AntPathRequestMatcher.antMatcher("/v3/api-docs/**"), + AntPathRequestMatcher.antMatcher("/swagger-ui/**")) .permitAll()) .authorizeHttpRequests((requests) -> requests.requestMatchers("/**") .authenticated()) From 74626c4377144b8927e2bd335ea45de6361472d3 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:15:45 +0200 Subject: [PATCH 10/20] add get operation description --- .../urnenwahlvorbereitung/UrnenwahlvorbereitungController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java index fad72fc5a..df52425f8 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java @@ -1,6 +1,7 @@ package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungService; +import io.swagger.v3.oas.annotations.Operation; import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.val; @@ -19,6 +20,7 @@ public class UrnenwahlvorbereitungController { private final UrnenwahlvorbereitungDTOMapper urnenwahlvorbereitungDTOMapper; + @Operation(description = "Laden der Wahlvorbereitungsdaten des Urnenwahllokals {wahlbezirkID}") @GetMapping("{wahlbezirkID}") public ResponseEntity getUrnenwahlVorbereitung(@PathVariable("wahlbezirkID") final String wahlbezirkID) { val urnenwahlvorbereitungModel = service.getUrnenwahlvorbereitung(wahlbezirkID); From 6c8163d365527676252d7dce01692c4b9ca47925 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:16:05 +0200 Subject: [PATCH 11/20] update security config test for swagger --- .../configuration/SecurityConfigurationTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java index c6394cdf5..0f47fc341 100644 --- a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java @@ -1,5 +1,6 @@ package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.configuration; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.MicroServiceApplication; @@ -31,6 +32,18 @@ public class SecurityConfigurationTest { @Autowired MockMvc mockMvc; + @Test + void accessUnsecuredResourceV3ApiDocsThenOk() throws Exception { + mockMvc.perform(get("/v3/api-docs")) + .andExpect(status().isOk()); + } + + @Test + void accessUnsecuredResourceSwaggerUiThenOk() throws Exception { + mockMvc.perform(get("/swagger-ui/index.html")) + .andExpect(status().isOk()); + } + @Nested class Urnenwahlvorbereitung { From 848c9568c499a721117175ca9f93208bde0255f6 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Tue, 21 May 2024 17:27:17 +0200 Subject: [PATCH 12/20] feedback - remove empty lines --- .../wahlvorbereitungservice/exception/ExceptionFactoryTest.java | 1 - .../UrnenwahlvorbereitungControllerIntegrationTest.java | 1 - .../UrnenwahlvorbereitungValidatorTest.java | 2 -- 3 files changed, 4 deletions(-) diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java index 68c0c0fe5..c39059778 100644 --- a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java @@ -38,7 +38,6 @@ void buildWithExceptionDataWrapperData() { val expectedResult = FachlicheWlsException.withCode(code).inService(serviceID).buildWithMessage(message); Assertions.assertThat(result).usingRecursiveComparison().isEqualTo(expectedResult); - } } diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java index 9cb095302..3293980a5 100644 --- a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java @@ -91,7 +91,6 @@ void noDataFound() throws Exception { val response = mockMvc.perform(request).andExpect(status().isNoContent()).andReturn(); Assertions.assertThat(response.getResponse().getContentAsString()).isEmpty(); - } } } diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java index ac45bd1c7..536b1d2e7 100644 --- a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java @@ -35,7 +35,6 @@ void noExceptionOnValidWahlbezirkID() { @Test void exceptionWhenWahlbezirkIDIsNull() { val exceptionToThrow = FachlicheWlsException.withCode("000").buildWithMessage("error"); - Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.SUCHKRITERIEN_UNVOLLSTAENDIG)).thenReturn(exceptionToThrow); Assertions.assertThatException().isThrownBy(() -> unitUnderTest.validWahlbezirkIDOrThrow(null)).isSameAs(exceptionToThrow); @@ -44,7 +43,6 @@ void exceptionWhenWahlbezirkIDIsNull() { @Test void exceptionWhenWahlbezirkIDIsEmpty() { val exceptionToThrow = FachlicheWlsException.withCode("000").buildWithMessage("error"); - Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.SUCHKRITERIEN_UNVOLLSTAENDIG)).thenReturn(exceptionToThrow); Assertions.assertThatException().isThrownBy(() -> unitUnderTest.validWahlbezirkIDOrThrow("")).isSameAs(exceptionToThrow); From f1bc76fd2dbea5c059bc91f79b9682e0b914d51d Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:14:26 +0200 Subject: [PATCH 13/20] add post authority --- ...uthorities-wahlvorbereitung-urnenwahlvorbereitung.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml b/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml index 05cb2af36..a06f373d6 100644 --- a/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml +++ b/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml @@ -11,6 +11,15 @@ changes: role: Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung clientId: ${SSO_CLIENT_ID} + - addRole: + name: Wahlvorbereitung_BUSINESSACTION_PostUrnenwahlVorbereitung + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allWahlvorbereitungAuthorities + role: Wahlvorbereitung_BUSINESSACTION_PostUrnenwahlVorbereitung + clientId: ${SSO_CLIENT_ID} + - addRole: name: Wahlvorbereitung_WRITE_UrnenwahlVorbereitung clientRole: true From 5e1f1791122d668b4cce7acb08080dc797d504df Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:17:14 +0200 Subject: [PATCH 14/20] add builder.default annotation --- .../wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java | 1 + 1 file changed, 1 insertion(+) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java index 0049d8b74..24a9464da 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java @@ -29,6 +29,7 @@ public class UrnenwahlVorbereitung { @CollectionTable(name = "UWVorbereitung_Urnen", joinColumns = @JoinColumn(name = "vorbereitung_wahlbezirkID")) @NotNull @Size(min = 1) + @Builder.Default private java.util.List urnenAnzahl = new java.util.ArrayList<>(); private long anzahlWahlkabinen; From e5023f978b616ea59edb204a08b69a70f199f726 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:22:38 +0200 Subject: [PATCH 15/20] add test to verify that List-Property is not null --- .../UrnenwahlvorbereitungDTOTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java new file mode 100644 index 000000000..01eb19eaf --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java @@ -0,0 +1,21 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; + +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class UrnenwahlvorbereitungDTOTest { + + @Nested + class ConstructionTests { + + @Test + void listOfWahlurneIsNotNullOnNullParameter() { + val result = new UrnenwahlvorbereitungDTO(null, 0, 0, 0, null); + + Assertions.assertThat(result.urnenAnzahl()).isNotNull(); + } + } + +} \ No newline at end of file From adaa7c11056784e270c5848edee69b2bc4f3be2c Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:22:55 +0200 Subject: [PATCH 16/20] override constructor to ensure that list is not null --- .../UrnenwahlvorbereitungDTO.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java index 774d9c550..443194e73 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java @@ -1,8 +1,19 @@ package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTO; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; public record UrnenwahlvorbereitungDTO(String wahlbezirkID, long anzahlWahlkabinen, long anzahlWahltische, long anzahlNebenraeume, List urnenAnzahl) { + + public UrnenwahlvorbereitungDTO(final String wahlbezirkID, final long anzahlWahlkabinen, final long anzahlWahltische, final long anzahlNebenraeume, + final List urnenAnzahl) { + this.wahlbezirkID = wahlbezirkID; + this.anzahlWahlkabinen = anzahlWahlkabinen; + this.anzahlWahltische = anzahlWahltische; + this.anzahlNebenraeume = anzahlNebenraeume; + this.urnenAnzahl = Objects.requireNonNullElseGet(urnenAnzahl, ArrayList::new); + } } From 280a71a6dd49ec4153907ebdfede9393e701adf7 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:24:54 +0200 Subject: [PATCH 17/20] add test to verify that List-Property is not null --- .../UrnenwahlvorbereitungModelTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java new file mode 100644 index 000000000..c80bd8e99 --- /dev/null +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java @@ -0,0 +1,21 @@ +package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; + +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class UrnenwahlvorbereitungModelTest { + + @Nested + class ConstructionTests { + + @Test + void listOfWahlurneIsNotNullOnNullParameter() { + val result = new UrnenwahlvorbereitungModel(null, 0, 0, 0, null); + + Assertions.assertThat(result.urnenAnzahl()).isNotNull(); + } + } + +} \ No newline at end of file From 060b187283b8768bb97fdf08c3cf6691be08003b Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:25:03 +0200 Subject: [PATCH 18/20] override constructor to ensure that list is not null --- .../UrnenwahlvorbereitungModel.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java index 426ffecc9..9a25dda72 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java @@ -1,10 +1,21 @@ package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung; import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModel; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import lombok.Builder; @Builder public record UrnenwahlvorbereitungModel(String wahlbezirkID, long anzahlWahlkabinen, long anzahlWahltische, long anzahlNebenraeume, List urnenAnzahl) { + + public UrnenwahlvorbereitungModel(final String wahlbezirkID, final long anzahlWahlkabinen, final long anzahlWahltische, final long anzahlNebenraeume, + final List urnenAnzahl) { + this.wahlbezirkID = wahlbezirkID; + this.anzahlWahlkabinen = anzahlWahlkabinen; + this.anzahlWahltische = anzahlWahltische; + this.anzahlNebenraeume = anzahlNebenraeume; + this.urnenAnzahl = Objects.requireNonNullElseGet(urnenAnzahl, ArrayList::new); + } } From 3792c64565c78317a922fdbd1dd9b2efb87f8756 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 10:30:11 +0200 Subject: [PATCH 19/20] spotless:apply --- .../urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java | 2 +- .../urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java index 01eb19eaf..e65f3198e 100644 --- a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTOTest.java @@ -18,4 +18,4 @@ void listOfWahlurneIsNotNullOnNullParameter() { } } -} \ No newline at end of file +} diff --git a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java index c80bd8e99..f3b84975f 100644 --- a/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java +++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java @@ -18,4 +18,4 @@ void listOfWahlurneIsNotNullOnNullParameter() { } } -} \ No newline at end of file +} From 9589d603af1738aed4639f6fd0ec31805c617900 Mon Sep 17 00:00:00 2001 From: MrSebastian <13592751+MrSebastian@users.noreply.github.com> Date: Wed, 22 May 2024 15:27:43 +0200 Subject: [PATCH 20/20] update swagger spec --- .../rest/common/WahlurneDTO.java | 7 ++++++- .../UrnenwahlvorbereitungDTO.java | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/common/WahlurneDTO.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/common/WahlurneDTO.java index baf33359f..667105934 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/common/WahlurneDTO.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/common/WahlurneDTO.java @@ -1,7 +1,12 @@ package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Builder; @Builder -public record WahlurneDTO(String wahlID, long anzahl, Boolean urneVersiegelt) { +public record WahlurneDTO(@NotNull @Size(max = 255) String wahlID, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahl, + Boolean urneVersiegelt) { } diff --git a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java index 443194e73..8e5fb4a51 100644 --- a/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java +++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java @@ -1,12 +1,18 @@ package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung; import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import java.util.ArrayList; import java.util.List; import java.util.Objects; -public record UrnenwahlvorbereitungDTO(String wahlbezirkID, long anzahlWahlkabinen, long anzahlWahltische, long anzahlNebenraeume, - List urnenAnzahl) { +public record UrnenwahlvorbereitungDTO(@NotNull String wahlbezirkID, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahlWahlkabinen, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahlWahltische, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahlNebenraeume, + @NotNull @Size(min = 1) List urnenAnzahl) { public UrnenwahlvorbereitungDTO(final String wahlbezirkID, final long anzahlWahlkabinen, final long anzahlWahltische, final long anzahlNebenraeume, final List urnenAnzahl) {