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..a06f373d6
--- /dev/null
+++ b/stack/keycloak/migration/add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml
@@ -0,0 +1,39 @@
+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_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
+ 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
diff --git a/wls-briefwahl-service/pom.xml b/wls-briefwahl-service/pom.xml
index 6d5f72c50..9185ce4ce 100644
--- a/wls-briefwahl-service/pom.xml
+++ b/wls-briefwahl-service/pom.xml
@@ -446,7 +446,7 @@
com.puppycrawl.tools
checkstyle
- 10.16.0
+ 10.17.0
diff --git a/wls-broadcast-service/pom.xml b/wls-broadcast-service/pom.xml
index 25a3eb10e..89a62a005 100644
--- a/wls-broadcast-service/pom.xml
+++ b/wls-broadcast-service/pom.xml
@@ -447,7 +447,7 @@
com.puppycrawl.tools
checkstyle
- 10.16.0
+ 10.17.0
diff --git a/wls-common/pom.xml b/wls-common/pom.xml
index 0597b2de5..4ff61edc8 100644
--- a/wls-common/pom.xml
+++ b/wls-common/pom.xml
@@ -174,7 +174,7 @@
com.puppycrawl.tools
checkstyle
- 10.16.0
+ 10.17.0
diff --git a/wls-eai-service/pom.xml b/wls-eai-service/pom.xml
index e5a09a73d..0fba2fc62 100644
--- a/wls-eai-service/pom.xml
+++ b/wls-eai-service/pom.xml
@@ -425,7 +425,7 @@
com.puppycrawl.tools
checkstyle
- 10.16.0
+ 10.17.0
diff --git a/wls-infomanagement-service/pom.xml b/wls-infomanagement-service/pom.xml
index 15bf68763..1120f2d57 100644
--- a/wls-infomanagement-service/pom.xml
+++ b/wls-infomanagement-service/pom.xml
@@ -446,7 +446,7 @@
com.puppycrawl.tools
checkstyle
- 10.16.0
+ 10.17.0
diff --git a/wls-wahlvorbereitung-service/pom.xml b/wls-wahlvorbereitung-service/pom.xml
index 608361a9f..791b2ebf3 100644
--- a/wls-wahlvorbereitung-service/pom.xml
+++ b/wls-wahlvorbereitung-service/pom.xml
@@ -447,7 +447,7 @@
com.puppycrawl.tools
checkstyle
- 10.16.0
+ 10.17.0
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(
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())
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..24a9464da
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/domain/UrnenwahlVorbereitung.java
@@ -0,0 +1,41 @@
+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)
+ @Builder.Default
+ 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 extends UrnenwahlVorbereitung> 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/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/UrnenwahlvorbereitungController.java b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java
new file mode 100644
index 000000000..df52425f8
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungController.java
@@ -0,0 +1,34 @@
+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;
+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;
+
+ @Operation(description = "Laden der Wahlvorbereitungsdaten des Urnenwahllokals {wahlbezirkID}")
+ @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..8e5fb4a51
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungDTO.java
@@ -0,0 +1,25 @@
+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(@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) {
+ this.wahlbezirkID = wahlbezirkID;
+ this.anzahlWahlkabinen = anzahlWahlkabinen;
+ this.anzahlWahltische = anzahlWahltische;
+ this.anzahlNebenraeume = anzahlNebenraeume;
+ this.urnenAnzahl = Objects.requireNonNullElseGet(urnenAnzahl, ArrayList::new);
+ }
+}
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..9a25dda72
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/main/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModel.java
@@ -0,0 +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);
+ }
+}
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/main/resources/application.yml b/wls-wahlvorbereitung-service/src/main/resources/application.yml
index f19584667..28898a0ea 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}
@@ -14,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
@@ -22,8 +24,11 @@ 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:
+ oid: WLS-WAHLVORBEREITUNG
# Define the local keycloak realm here
realm: wls_realm
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)
+);
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..0f47fc341
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/configuration/SecurityConfigurationTest.java
@@ -0,0 +1,66 @@
+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;
+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;
+
+ @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 {
+
+ @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..c39059778
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/exception/ExceptionFactoryTest.java
@@ -0,0 +1,45 @@
+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..3293980a5
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/rest/urnenwahlvorbereitung/UrnenwahlvorbereitungControllerIntegrationTest.java
@@ -0,0 +1,96 @@
+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/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..e65f3198e
--- /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();
+ }
+ }
+
+}
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/UrnenwahlvorbereitungModelTest.java b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungModelTest.java
new file mode 100644
index 000000000..f3b84975f
--- /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();
+ }
+ }
+
+}
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..536b1d2e7
--- /dev/null
+++ b/wls-wahlvorbereitung-service/src/test/java/de/muenchen/oss/wahllokalsystem/wahlvorbereitungservice/service/urnenwahlvorbereitung/UrnenwahlvorbereitungValidatorTest.java
@@ -0,0 +1,52 @@
+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);
+ }
+}
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