diff --git a/stack/keycloak/migration/add-authorities-basisdaten-referendumvorlagen.yml b/stack/keycloak/migration/add-authorities-basisdaten-referendumvorlagen.yml new file mode 100644 index 000000000..cbe2c71f6 --- /dev/null +++ b/stack/keycloak/migration/add-authorities-basisdaten-referendumvorlagen.yml @@ -0,0 +1,66 @@ +id: add authorities basisdaten referendumvorlagen +author: MrSebastian +realm: ${SSO_REALM} +changes: + - addRole: + name: Basisdaten_BUSINESSACTION_GetReferendumvorlagen + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_BUSINESSACTION_GetReferendumvorlagen + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Basisdaten_READ_Referendumvorlagen + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_READ_Referendumvorlagen + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Basisdaten_WRITE_Referendumvorlagen + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_WRITE_Referendumvorlagen + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Basisdaten_DELETE_Referendumvorlagen + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_DELETE_Referendumvorlagen + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Basisdaten_READ_Referendumvorlage + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_READ_Referendumvorlage + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Basisdaten_WRITE_Referendumvorlage + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_WRITE_Referendumvorlage + clientId: ${SSO_CLIENT_ID} + + - addRole: + name: Basisdaten_DELETE_Referendumvorlage + clientRole: true + clientId: ${SSO_CLIENT_ID} + - assignRoleToGroup: + group: allBasisdatenAuthorities + role: Basisdaten_DELETE_Referendumvorlage + clientId: ${SSO_CLIENT_ID} diff --git a/stack/keycloak/migration/keycloak-changelog.yml b/stack/keycloak/migration/keycloak-changelog.yml index c9d9ccb6d..105651be4 100644 --- a/stack/keycloak/migration/keycloak-changelog.yml +++ b/stack/keycloak/migration/keycloak-changelog.yml @@ -37,3 +37,4 @@ includes: - path: add-authorities-basisdaten-wahltage.yml - path: add-authorities-basisdaten-ungueltigewahlscheine.yml - path: add-authorities-eai-wahlbeteiligung.yml + - path: add-authorities-basisdaten-referendumvorlagen.yml \ No newline at end of file diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/DummyClientImpl.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/DummyClientImpl.java index 649647902..a121e0564 100644 --- a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/DummyClientImpl.java +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/DummyClientImpl.java @@ -1,6 +1,11 @@ package de.muenchen.oss.wahllokalsystem.basisdatenservice.clients; import de.muenchen.oss.wahllokalsystem.basisdatenservice.configuration.Profiles; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumoptionModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlageModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenClient; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenReferenceModel; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltagModel; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltageClient; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlvorschlag.KandidatModel; @@ -17,7 +22,7 @@ @Component @Profile(Profiles.DUMMY_CLIENTS) -public class DummyClientImpl implements WahlvorschlaegeClient, WahltageClient { +public class DummyClientImpl implements WahlvorschlaegeClient, WahltageClient, ReferendumvorlagenClient { @Override public WahlvorschlaegeModel getWahlvorschlaege(BezirkUndWahlID bezirkUndWahlID) { @@ -38,4 +43,12 @@ public List getWahltage(LocalDate tag) { new WahltagModel("wahltagID3", LocalDate.now().plusMonths(1), "Beschreibung Wahltag 3", "2"), new WahltagModel("wahltagID2", LocalDate.now().minusMonths(1), "Beschreibung Wahltag 2", "1")); } + + @Override + public ReferendumvorlagenModel getReferendumvorlagen(ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel) { + return new ReferendumvorlagenModel("stimmzettelgebiedID", Set.of(new ReferendumvorlageModel("wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new ReferendumoptionModel("optionID11", "option11", 1L), new ReferendumoptionModel("optionID12", "option12", 2L))), + new ReferendumvorlageModel("wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new ReferendumoptionModel("optionID21", "option21", 1L), new ReferendumoptionModel("optionID22", "option22", 2L))))); + } } diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/ReferendumvorlagenClientMapper.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/ReferendumvorlagenClientMapper.java new file mode 100644 index 000000000..725c1af74 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/ReferendumvorlagenClientMapper.java @@ -0,0 +1,14 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.clients; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlageDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlagenDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlageModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModel; +import org.mapstruct.Mapper; + +@Mapper +public interface ReferendumvorlagenClientMapper { + ReferendumvorlagenModel toModel(ReferendumvorlagenDTO referendumvorlagenDTO); + + ReferendumvorlageModel toModel(ReferendumvorlageDTO referendumvorlageDTO); +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/WahlvorschlaegeClientImpl.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/WahlvorschlaegeClientImpl.java index 6c347d937..07695edbb 100644 --- a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/WahlvorschlaegeClientImpl.java +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/clients/WahlvorschlaegeClientImpl.java @@ -2,8 +2,12 @@ import de.muenchen.oss.wahllokalsystem.basisdatenservice.configuration.Profiles; import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.client.WahlvorschlagControllerApi; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlagenDTO; import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.WahlvorschlaegeDTO; import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenClient; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenReferenceModel; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlvorschlag.WahlvorschlaegeClient; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlvorschlag.WahlvorschlaegeModel; import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory; @@ -17,12 +21,13 @@ @Profile(Profiles.NOT + Profiles.DUMMY_CLIENTS) @RequiredArgsConstructor @Slf4j -public class WahlvorschlaegeClientImpl implements WahlvorschlaegeClient { +public class WahlvorschlaegeClientImpl implements WahlvorschlaegeClient, ReferendumvorlagenClient { private final ExceptionFactory exceptionFactory; private final WahlvorschlagControllerApi wahlvorschlagControllerApi; private final WahlvorschlaegeClientMapper wahlvorschlaegeClientMapper; + private final ReferendumvorlagenClientMapper referendumvorlagenClientMapper; @Override public WahlvorschlaegeModel getWahlvorschlaege(final BezirkUndWahlID bezirkUndWahlID) { @@ -39,4 +44,20 @@ public WahlvorschlaegeModel getWahlvorschlaege(final BezirkUndWahlID bezirkUndWa return wahlvorschlaegeClientMapper.toModel(wahlvorschlaege); } + + @Override + public ReferendumvorlagenModel getReferendumvorlagen(ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel) { + final ReferendumvorlagenDTO referendumvorlagen; + try { + referendumvorlagen = wahlvorschlagControllerApi.loadReferendumvorlagen(referendumvorlagenReferenceModel.wahlID(), + referendumvorlagenReferenceModel.wahlbezirkID()); + } catch (final Exception exception) { + log.info("exception on loadrefendumvorlagen from external", exception); + throw exceptionFactory.createTechnischeWlsException(ExceptionConstants.FAILED_COMMUNICATION_WITH_EAI); + } + if (referendumvorlagen == null) { + throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.NULL_FROM_CLIENT); + } + return referendumvorlagenClientMapper.toModel(referendumvorlagen); + } } diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumoption.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumoption.java new file mode 100644 index 000000000..76d080644 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumoption.java @@ -0,0 +1,31 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen; + +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Embeddable +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@EqualsAndHashCode +@ToString(onlyExplicitlyIncluded = true) +public class Referendumoption { + + @NotNull + @ToString.Include + private String id; + + @NotNull + @ToString.Include + private String name; + + @ToString.Include + private Long position; +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumvorlage.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumvorlage.java new file mode 100644 index 000000000..6cd1f9a88 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumvorlage.java @@ -0,0 +1,65 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen; + +import static java.sql.Types.VARCHAR; + +import jakarta.persistence.CollectionTable; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.validation.constraints.NotNull; +import java.util.Set; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.annotations.UuidGenerator; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@EqualsAndHashCode +@ToString(onlyExplicitlyIncluded = true) +public class Referendumvorlage { + + @Id + @GeneratedValue(generator = "uuid") + @UuidGenerator + @JdbcTypeCode(VARCHAR) + @ToString.Include + private UUID id; + + @ManyToOne + @JoinColumn(name = "referendumvorlagenID") + @EqualsAndHashCode.Exclude + private Referendumvorlagen referendumvorlagen; + + @NotNull + @ToString.Include + private String wahlvorschlagID; + + @NotNull + @ToString.Include + private Long ordnungszahl; + + @NotNull + @ToString.Include + private String kurzname; + + @NotNull + @ToString.Include + private String frage; + + @ElementCollection + @CollectionTable(name = "referendumoption", joinColumns = @JoinColumn(name = "referendumvorlageID")) + @NotNull + private Set referendumoptionen; +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/ReferendumvorlageRepository.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/ReferendumvorlageRepository.java new file mode 100644 index 000000000..709df6cf2 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/ReferendumvorlageRepository.java @@ -0,0 +1,54 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +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; + +@PreAuthorize("hasAuthority('Basisdaten_READ_Referendumvorlage')") +public interface ReferendumvorlageRepository extends CrudRepository { + + String CACHE = "WLSREFERENDUMVORSCHLAEGE_CACHE"; + + @Override + List findAll(); + + @Override + @Cacheable(value = CACHE, key = "#p0") + Optional findById(UUID referendumvorlageId); + + @Override + @CachePut(value = CACHE, key = "#p0.bezirkUndWahlID") + @PreAuthorize("hasAuthority('Basisdaten_WRITE_Referendumvorlage')") + S save(S entity); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Basisdaten_WRITE_Referendumvorlage')") + Iterable saveAll(Iterable entities); + + @Override + @CacheEvict(value = CACHE, key = "#p0") + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlage')") + void deleteById(UUID referendumvorlageId); + + @Override + @CacheEvict(value = CACHE, key = "#p0.bezirkUndWahlID") + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlage')") + void delete(Referendumvorlage entity); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlage')") + void deleteAll(Iterable entities); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlage')") + void deleteAll(); + +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumvorlagen.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumvorlagen.java new file mode 100644 index 000000000..c6d452eb1 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/Referendumvorlagen.java @@ -0,0 +1,56 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen; + +import static java.sql.Types.VARCHAR; + +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotNull; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.UuidGenerator; + +@Entity +@Getter +@Setter +@EqualsAndHashCode +@ToString(onlyExplicitlyIncluded = true) +@NoArgsConstructor +@AllArgsConstructor +public class Referendumvorlagen { + + @Id + @GeneratedValue(generator = "uuid") + @UuidGenerator + @JdbcTypeCode(VARCHAR) + @ToString.Include + private UUID id; + + @NaturalId + @Embedded + private BezirkUndWahlID bezirkUndWahlID; + + @NotNull + private String stimmzettelgebietID; + + @OneToMany(mappedBy = "referendumvorlagen", orphanRemoval = true) + @NotNull + private Set referendumvorlagen = new HashSet<>(); + + public void addReferendumvorlage(Referendumvorlage referendumvorlage) { + referendumvorlage.setReferendumvorlagen(this); + referendumvorlagen.add(referendumvorlage); + } +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/ReferendumvorlagenRepository.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/ReferendumvorlagenRepository.java new file mode 100644 index 000000000..9c1abe933 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/domain/referendumvorlagen/ReferendumvorlagenRepository.java @@ -0,0 +1,51 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +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; + +@PreAuthorize("hasAuthority('Basisdaten_READ_Referendumvorlagen')") +public interface ReferendumvorlagenRepository extends CrudRepository { + + String CACHE = "WLSREFERENDUMVORSCHLAEGE_CACHE"; + + @Override + List findAll(); + + @Override + @Cacheable(value = CACHE, key = "#p0") + Optional findById(UUID referendumvorlagenId); + + Optional findByBezirkUndWahlID(BezirkUndWahlID bezirkUndWahlID); + + @Override + @CachePut(value = CACHE, key = "#p0.bezirkUndWahlID") + @PreAuthorize("hasAuthority('Basisdaten_WRITE_Referendumvorlagen')") + S save(S entity); + + @Override + @CacheEvict(value = CACHE, key = "#p0") + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlagen')") + void deleteById(UUID referendumvorlagenId); + + @Override + @CacheEvict(value = CACHE, key = "#p0.bezirkUndWahlID") + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlagen')") + void delete(Referendumvorlagen entity); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlagen')") + void deleteAll(Iterable entities); + + @Override + @CacheEvict(value = CACHE, allEntries = true) + @PreAuthorize("hasAuthority('Basisdaten_DELETE_Referendumvorlagen')") + void deleteAll(); +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/exception/ExceptionConstants.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/exception/ExceptionConstants.java index a425cd217..9dea00cfd 100644 --- a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/exception/ExceptionConstants.java +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/exception/ExceptionConstants.java @@ -41,4 +41,7 @@ public class ExceptionConstants { public static ExceptionDataWrapper POSTUNGUELTIGEWS_SPEICHERN_NICHT_ERFOLGREICH = new ExceptionDataWrapper("346", "postUngueltigews: Das speichern der ungueltigen Wahlscheine war nicht erfolgreich."); + public static ExceptionDataWrapper GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("308", + "getReferendumvorlagen: Suchkriterien unvollständig."); + } diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumoptionDTO.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumoptionDTO.java new file mode 100644 index 000000000..69dab3986 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumoptionDTO.java @@ -0,0 +1,8 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; + +public record ReferendumoptionDTO(@NotNull String id, + @NotNull String name, + Long position) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlageDTO.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlageDTO.java new file mode 100644 index 000000000..377c040d4 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlageDTO.java @@ -0,0 +1,11 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; +import java.util.Set; + +public record ReferendumvorlageDTO(@NotNull String wahlvorschlagID, + @NotNull Long ordnungszahl, + @NotNull String kurzname, + @NotNull String frage, + @NotNull Set referendumoptionen) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenController.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenController.java new file mode 100644 index 000000000..d93fd7473 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenController.java @@ -0,0 +1,47 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenService; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.rest.model.WlsExceptionDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import lombok.RequiredArgsConstructor; +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/referendumvorlagen") +@RequiredArgsConstructor +public class ReferendumvorlagenController { + + private final ReferendumvorlagenService referendumvorlagenService; + + private final ReferendumvorlagenDTOMapper referendumvorlagenDTOMapper; + + @Operation(description = "Laden der Referendumsvorlagen des Wahllokals {wahlbezirkID} für eine Wahl {wahlID}.") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", description = "OK", + content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ReferendumvorlagenDTO.class)) } + ), + @ApiResponse( + responseCode = "500", description = "Probleme bei der Kommunikation mit dem externen System von dem die Daten importiert werden", + content = { @Content(mediaType = "application/json", schema = @Schema(implementation = WlsExceptionDTO.class)) } + ), + @ApiResponse( + responseCode = "204", description = "Keine Daten vom Fremdsystem geliefert", + content = @Content(schema = @Schema()) + ) + } + ) + @GetMapping("{wahlID}/{wahlbezirkID}") + public ReferendumvorlagenDTO getReferendumvorlagen(@PathVariable("wahlID") final String wahlID, @PathVariable("wahlbezirkID") final String wahlbezirkID) { + return referendumvorlagenDTOMapper.toDTO( + referendumvorlagenService.getReferendumvorlagen(referendumvorlagenDTOMapper.toModel(wahlbezirkID, wahlID))); + } +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTO.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTO.java new file mode 100644 index 000000000..04621b532 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTO.java @@ -0,0 +1,8 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; +import java.util.Set; + +public record ReferendumvorlagenDTO(@NotNull String stimmzettelgebietID, + @NotNull Set referendumvorlage) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTOMapper.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTOMapper.java new file mode 100644 index 000000000..cd0e5d5a7 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTOMapper.java @@ -0,0 +1,15 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenReferenceModel; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface ReferendumvorlagenDTOMapper { + + @Mapping(target = "referendumvorlage", source = "referendumvorlagen") + ReferendumvorlagenDTO toDTO(ReferendumvorlagenModel referendumvorlagenModel); + + ReferendumvorlagenReferenceModel toModel(String wahlbezirkID, String wahlID); +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumoptionModel.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumoptionModel.java new file mode 100644 index 000000000..25eb763f1 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumoptionModel.java @@ -0,0 +1,8 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; + +public record ReferendumoptionModel(@NotNull String id, + @NotNull String name, + Long position) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlageModel.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlageModel.java new file mode 100644 index 000000000..b63c32cc8 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlageModel.java @@ -0,0 +1,11 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; +import java.util.Set; + +public record ReferendumvorlageModel(@NotNull String wahlvorschlagID, + @NotNull Long ordnungszahl, + @NotNull String kurzname, + @NotNull String frage, + @NotNull Set referendumoptionen) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenClient.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenClient.java new file mode 100644 index 000000000..54476e46d --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenClient.java @@ -0,0 +1,6 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +public interface ReferendumvorlagenClient { + + ReferendumvorlagenModel getReferendumvorlagen(ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel); +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModel.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModel.java new file mode 100644 index 000000000..652fe96bb --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModel.java @@ -0,0 +1,8 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; +import java.util.Set; + +public record ReferendumvorlagenModel(@NotNull String stimmzettelgebietID, + @NotNull Set referendumvorlagen) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModelMapper.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModelMapper.java new file mode 100644 index 000000000..6d9c66b9d --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModelMapper.java @@ -0,0 +1,23 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumvorlage; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumvorlagen; +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface ReferendumvorlagenModelMapper { + + BezirkUndWahlID toBezirkUndWahlID(ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel); + + ReferendumvorlagenModel toModel(Referendumvorlagen entity); + + @Mapping(target = "id", ignore = true) + Referendumvorlagen toEntity(ReferendumvorlagenModel model, BezirkUndWahlID bezirkUndWahlID); + + @Mapping(target = "id", ignore = true) + @Mapping(target = "referendumvorlagen", ignore = true) + Referendumvorlage toEntity(ReferendumvorlageModel model); +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenReferenceModel.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenReferenceModel.java new file mode 100644 index 000000000..709157885 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenReferenceModel.java @@ -0,0 +1,9 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import jakarta.validation.constraints.NotNull; +import lombok.Builder; + +@Builder +public record ReferendumvorlagenReferenceModel(@NotNull String wahlID, + @NotNull String wahlbezirkID) { +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenService.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenService.java new file mode 100644 index 000000000..8630f1f27 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenService.java @@ -0,0 +1,66 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlageRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumvorlagen; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlagenRepository; +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +@Service +@RequiredArgsConstructor +@Slf4j +public class ReferendumvorlagenService { + + private final ReferendumvorlagenValidator referendumvorlagenValidator; + + private final ReferendumvorlagenModelMapper referendumvorlagenModelMapper; + + private final ReferendumvorlagenClient referendumvorlagenClient; + + private final ReferendumvorlageRepository referendumvorlageRepository; + private final ReferendumvorlagenRepository referendumvorlagenRepository; + + private final TransactionTemplate transactionTemplate; + + @PreAuthorize("hasAuthority('Basisdaten_BUSINESSACTION_GetReferendumvorlagen')") + public ReferendumvorlagenModel getReferendumvorlagen(final ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel) { + log.info("#getReferendumvorlagen"); + + referendumvorlagenValidator.validReferumvorlageReferenceModelOrThrow(referendumvorlagenReferenceModel); + + val referendumBezirkUndWahlID = referendumvorlagenModelMapper.toBezirkUndWahlID(referendumvorlagenReferenceModel); + val existingReferendumvorlagen = referendumvorlagenRepository.findByBezirkUndWahlID(referendumBezirkUndWahlID); + + if (existingReferendumvorlagen.isEmpty()) { + return cacheReferendumvorlagen(referendumvorlagenReferenceModel, referendumBezirkUndWahlID); + } else { + return referendumvorlagenModelMapper.toModel(existingReferendumvorlagen.get()); + } + } + + private ReferendumvorlagenModel cacheReferendumvorlagen(ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel, + BezirkUndWahlID referendumBezirkUndWahlID) { + val importedReferendumvorlagen = referendumvorlagenClient.getReferendumvorlagen(referendumvorlagenReferenceModel); + + val entitiesToSave = referendumvorlagenModelMapper.toEntity(importedReferendumvorlagen, referendumBezirkUndWahlID); + saveReferendumvorlagen(entitiesToSave); + + return importedReferendumvorlagen; + } + + private void saveReferendumvorlagen(final Referendumvorlagen referendumvorlagenToSave) { + try { + transactionTemplate.executeWithoutResult(transactionStatus -> { + referendumvorlagenRepository.save(referendumvorlagenToSave); + referendumvorlageRepository.saveAll(referendumvorlagenToSave.getReferendumvorlagen()); + }); + } catch (final Exception e) { + log.error("#getReferendumvorlagen: Fehler beim Cachen", e); + } + } +} diff --git a/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenValidator.java b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenValidator.java new file mode 100644 index 000000000..d8392a647 --- /dev/null +++ b/wls-basisdaten-service/src/main/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenValidator.java @@ -0,0 +1,21 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ReferendumvorlagenValidator { + + private final ExceptionFactory exceptionFactory; + + public void validReferumvorlageReferenceModelOrThrow(final ReferendumvorlagenReferenceModel referendumvorlagenReferenceModel) { + if (referendumvorlagenReferenceModel == null || StringUtils.isEmpty(referendumvorlagenReferenceModel.wahlID()) || StringUtils.isEmpty( + referendumvorlagenReferenceModel.wahlbezirkID())) { + throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG); + } + } +} diff --git a/wls-basisdaten-service/src/main/resources/db/migrations/h2/V5_0__createTablesReferendumvorlage.sql b/wls-basisdaten-service/src/main/resources/db/migrations/h2/V5_0__createTablesReferendumvorlage.sql new file mode 100644 index 000000000..ab07d3f1a --- /dev/null +++ b/wls-basisdaten-service/src/main/resources/db/migrations/h2/V5_0__createTablesReferendumvorlage.sql @@ -0,0 +1,39 @@ +CREATE TABLE referendumvorlagen +( + id VARCHAR2(36) NOT NULL, + wahlID VARCHAR2(1000) NOT NULL, + wahlbezirkID VARCHAR2(1000) NOT NULL, + stimmzettelgebietID VARCHAR2(1000) NOT NULL, + + UNIQUE (wahlID, wahlbezirkID), + + PRIMARY KEY (id) + +); + +CREATE TABLE referendumvorlage +( + id VARCHAR2(36) NOT NULL, + wahlvorschlagID VARCHAR2(1000) NOT NULL, + ordnungszahl BIGINT NOT NULL, + kurzname VARCHAR2(1000) NOT NULL, + frage VARCHAR2(1000) NOT NULL, + + referendumvorlagenID VARCHAR2(36) NOT NULL, + + + FOREIGN KEY (referendumvorlagenID) REFERENCES referendumvorlagen (id), + + PRIMARY KEY (id) +); + +CREATE TABLE referendumoption +( + id VARCHAR2(1000) NOT NULL, + name VARCHAR2(1000) NOT NULL, + position BIGINT, + referendumvorlageID VARCHAR2(36) NOT NULL, + + UNIQUE (id), + FOREIGN KEY (referendumvorlageID) REFERENCES referendumvorlage (id) +); \ No newline at end of file diff --git a/wls-basisdaten-service/src/main/resources/db/migrations/oracle/V5_0__createTablesReferendumvorlage.sql b/wls-basisdaten-service/src/main/resources/db/migrations/oracle/V5_0__createTablesReferendumvorlage.sql new file mode 100644 index 000000000..f496e9141 --- /dev/null +++ b/wls-basisdaten-service/src/main/resources/db/migrations/oracle/V5_0__createTablesReferendumvorlage.sql @@ -0,0 +1,39 @@ +CREATE TABLE referendumvorlagen +( + id VARCHAR2(36) NOT NULL, + wahlID VARCHAR2(1000) NOT NULL, + wahlbezirkID VARCHAR2(1000) NOT NULL, + stimmzettelgebietID VARCHAR2(1000) NOT NULL, + + UNIQUE (wahlID, wahlbezirkID), + + PRIMARY KEY (id) + +); + +CREATE TABLE referendumvorlage +( + id VARCHAR2(36) NOT NULL, + wahlvorschlagID VARCHAR2(1000) NOT NULL, + ordnungszahl NUMBER NOT NULL, + kurzname VARCHAR2(1000) NOT NULL, + frage VARCHAR2(1000) NOT NULL, + + referendumvorlagenID VARCHAR2(36) NOT NULL, + + + FOREIGN KEY (referendumvorlagenID) REFERENCES referendumvorlagen (id), + + PRIMARY KEY (id) +); + +CREATE TABLE referendumoption +( + id VARCHAR2(1000) NOT NULL, + name VARCHAR2(1000) NOT NULL, + position NUMBER, + referendumvorlageID VARCHAR2(36) NOT NULL, + + UNIQUE (id), + FOREIGN KEY (referendumvorlageID) REFERENCES referendumvorlage (id) +); \ No newline at end of file diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/configuration/SecurityConfigurationTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/configuration/SecurityConfigurationTest.java index 032f40ab2..841e07760 100644 --- a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/configuration/SecurityConfigurationTest.java +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/configuration/SecurityConfigurationTest.java @@ -8,9 +8,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import de.muenchen.oss.wahllokalsystem.basisdatenservice.MicroServiceApplication; -import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltageService; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.handbuch.HandbuchService; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenService; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.ungueltigewahlscheine.UngueltigeWahlscheineService; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltageService; import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlvorschlag.WahlvorschlaegeService; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -45,6 +46,9 @@ class SecurityConfigurationTest { @MockBean UngueltigeWahlscheineService ungueltigeWahlscheineService; + @MockBean + ReferendumvorlagenService referendumvorlagenService; + @Test void accessSecuredResourceRootThenUnauthorized() throws Exception { api.perform(get("/")) @@ -175,4 +179,20 @@ void accessPostUngueltigeWahlscheineAuthorizedThenOk() throws Exception { } } + @Nested + class Referendumvorlagen { + + @Test + @WithAnonymousUser + void accessGetReferendumvorlagenUnauthorizedThenUnauthorized() throws Exception { + api.perform(get("/businessActions/referendumvorlagen/wahlID/wahlbezirkID")).andExpect(status().isUnauthorized()); + } + + @Test + @WithMockUser + void accessGetReferendumvorlagenAuthorizedThenOk() throws Exception { + api.perform(get("/businessActions/referendumvorlagen/wahlID/wahlbezirkID")).andExpect(status().isOk()); + } + } + } diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenControllerIntegrationTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenControllerIntegrationTest.java new file mode 100644 index 000000000..39d88e4a3 --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenControllerIntegrationTest.java @@ -0,0 +1,244 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import static de.muenchen.oss.wahllokalsystem.basisdatenservice.TestConstants.SPRING_NO_SECURITY_PROFILE; +import static de.muenchen.oss.wahllokalsystem.basisdatenservice.TestConstants.SPRING_TEST_PROFILE; +import static org.mockito.ArgumentMatchers.any; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.client.WireMock; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.MicroServiceApplication; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.clients.ReferendumvorlagenClientMapper; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlageRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlagenRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumoptionDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlageDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModelMapper; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenReferenceModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenValidator; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.utils.Authorities; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.rest.model.WlsExceptionCategory; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.rest.model.WlsExceptionDTO; +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import de.muenchen.oss.wahllokalsystem.wls.common.testing.SecurityUtils; +import jakarta.transaction.Transactional; +import java.util.Set; +import javax.annotation.Nullable; +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.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.http.HttpStatus; +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) +@AutoConfigureMockMvc +@AutoConfigureWireMock +@ActiveProfiles(profiles = { SPRING_TEST_PROFILE, SPRING_NO_SECURITY_PROFILE }) +public class ReferendumvorlagenControllerIntegrationTest { + + public static final String BUSINESS_ACTIONS_REFERENDUMVORLAGEN = "/businessActions/referendumvorlagen/"; + + @Value("${service.info.oid}") + String serviceOid; + + @Autowired + MockMvc mockMvc; + + @Autowired + ObjectMapper objectMapper; + + @Autowired + ReferendumvorlagenRepository referendumvorlagenRepository; + + @SpyBean + ReferendumvorlageRepository referendumvorlageRepository; + + @Autowired + ReferendumvorlagenClientMapper referendumvorlagenClientMapper; + + @Autowired + ReferendumvorlagenModelMapper referendumvorlagenModelMapper; + + @Autowired + ReferendumvorlagenDTOMapper referendumvorlagenDTOMapper; + + @SpyBean + ReferendumvorlagenValidator referendumvorlagenValidator; + + @AfterEach + void tearDown() { + SecurityUtils.runWith(Authorities.REPOSITORY_DELETE_REFERENDUMVORLAGEN); + referendumvorlagenRepository.deleteAll(); + } + + @Nested + class GetReferendumvorlagen { + + @Test + void loadedFromExternal() throws Exception { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val eaiReferendumvorschlage = createClientReferendumvorlagenDTO(); + defineStubForGetReferendumvorlage(eaiReferendumvorschlage, wahlID, wahlbezirkID, HttpStatus.OK); + + val request = MockMvcRequestBuilders.get(BUSINESS_ACTIONS_REFERENDUMVORLAGEN + wahlID + "/" + wahlbezirkID); + + val response = mockMvc.perform(request).andExpect(status().isOk()).andReturn(); + val responseBodyAsDTO = objectMapper.readValue(response.getResponse().getContentAsByteArray(), ReferendumvorlagenDTO.class); + + val expectedBodyDTO = referendumvorlagenDTOMapper.toDTO(referendumvorlagenClientMapper.toModel(eaiReferendumvorschlage)); + Assertions.assertThat(responseBodyAsDTO).isEqualTo(expectedBodyDTO); + } + + @Test + @Transactional + void returnExistingDataWithoutImport() throws Exception { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val eaiReferendumvorschlage = createClientReferendumvorlagenDTO(); + defineStubForGetReferendumvorlage(eaiReferendumvorschlage, wahlID, wahlbezirkID, HttpStatus.OK); + + val request = MockMvcRequestBuilders.get(BUSINESS_ACTIONS_REFERENDUMVORLAGEN + wahlID + "/" + wahlbezirkID); + + mockMvc.perform(request).andExpect(status().isOk()); + + val referendumvorlagenEntity = referendumvorlagenRepository.findByBezirkUndWahlID(new BezirkUndWahlID(wahlID, wahlbezirkID)).get(); + + val expectedEntity = referendumvorlagenModelMapper.toEntity(referendumvorlagenClientMapper.toModel(eaiReferendumvorschlage), + new BezirkUndWahlID(wahlID, wahlbezirkID)); + val ignoreableFieldOfIdsAndParenEntityRefs = new String[] { "id", "referendumvorlagen.id", "referendumvorlagen.referendumvorlagen" }; + Assertions.assertThat(referendumvorlagenEntity).usingRecursiveComparison().ignoringCollectionOrder() + .ignoringFields(ignoreableFieldOfIdsAndParenEntityRefs) + .isEqualTo(expectedEntity); + } + + @Test + void technischeWlsExceptionWhenNoDataFoundExternal() throws Exception { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + defineStubForGetReferendumvorlage(null, wahlID, wahlbezirkID, HttpStatus.OK); + + val request = MockMvcRequestBuilders.get(BUSINESS_ACTIONS_REFERENDUMVORLAGEN + wahlID + "/" + wahlbezirkID); + + val response = mockMvc.perform(request).andExpect(status().isNoContent()).andReturn(); + + Assertions.assertThat(response.getResponse().getContentAsByteArray()).isEmpty(); + } + + @Test + void technischeWlsExceptionWhenCommunicationFailed() throws Exception { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val eaiReferendumvorschlage = new de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.WlsExceptionDTO(); + defineStubForGetReferendumvorlage(eaiReferendumvorschlage, wahlID, wahlbezirkID, HttpStatus.INSUFFICIENT_STORAGE); + + val request = MockMvcRequestBuilders.get(BUSINESS_ACTIONS_REFERENDUMVORLAGEN + wahlID + "/" + wahlbezirkID); + + val response = mockMvc.perform(request).andExpect(status().isInternalServerError()).andReturn(); + val responseBodyAsDTO = objectMapper.readValue(response.getResponse().getContentAsByteArray(), WlsExceptionDTO.class); + + val expectedWlsExceptionDTO = new WlsExceptionDTO(WlsExceptionCategory.T, ExceptionConstants.FAILED_COMMUNICATION_WITH_EAI.code(), serviceOid, + ExceptionConstants.FAILED_COMMUNICATION_WITH_EAI.message()); + Assertions.assertThat(responseBodyAsDTO).isEqualTo(expectedWlsExceptionDTO); + } + + @Test + void fachlicheWlsExceptionWhenPathVariableIsInvalid() throws Exception { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val mockedWlsExceptionCode = "123"; + val mockedWlsExceptionMessage = "faked validation exception"; + val mockedWlsExceptionService = "mockedServiceID"; + val mockedValidationException = FachlicheWlsException.withCode(mockedWlsExceptionCode).inService(mockedWlsExceptionService) + .buildWithMessage(mockedWlsExceptionMessage); + Mockito.doThrow(mockedValidationException).when(referendumvorlagenValidator) + .validReferumvorlageReferenceModelOrThrow(new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID)); + + val request = MockMvcRequestBuilders.get(BUSINESS_ACTIONS_REFERENDUMVORLAGEN + wahlID + "/" + wahlbezirkID); + + val response = mockMvc.perform(request).andExpect(status().isBadRequest()).andReturn(); + val responseBodyAsDTO = objectMapper.readValue(response.getResponse().getContentAsByteArray(), WlsExceptionDTO.class); + + val expectedBodyDTO = new WlsExceptionDTO(WlsExceptionCategory.F, mockedWlsExceptionCode, mockedWlsExceptionService, mockedWlsExceptionMessage); + Assertions.assertThat(responseBodyAsDTO).isEqualTo(expectedBodyDTO); + } + + @Test + void alleReferendumdataIsStoredTransactional() throws Exception { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val eaiReferendumvorschlage = createClientReferendumvorlagenDTO(); + defineStubForGetReferendumvorlage(eaiReferendumvorschlage, wahlID, wahlbezirkID, HttpStatus.OK); + + val mockedSaveAllException = new RuntimeException("save all failed"); + Mockito.doThrow(mockedSaveAllException).when(referendumvorlageRepository).saveAll(any()); + + val request = MockMvcRequestBuilders.get(BUSINESS_ACTIONS_REFERENDUMVORLAGEN + wahlID + "/" + wahlbezirkID); + + val response = mockMvc.perform(request).andExpect(status().isOk()).andReturn(); + val responseBodyAsDTO = objectMapper.readValue(response.getResponse().getContentAsByteArray(), ReferendumvorlagenDTO.class); + + val expectedBodyDTO = referendumvorlagenDTOMapper.toDTO(referendumvorlagenClientMapper.toModel(eaiReferendumvorschlage)); + Assertions.assertThat(responseBodyAsDTO).isEqualTo(expectedBodyDTO); + + Assertions.assertThat(referendumvorlagenRepository.count()).isEqualTo(0); + Assertions.assertThat(referendumvorlageRepository.count()).isEqualTo(0); + } + + private de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlagenDTO createClientReferendumvorlagenDTO() { + val dto = new de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlagenDTO(); + + dto.setStimmzettelgebietID("szgID"); + + val referendumOption = new ReferendumoptionDTO(); + referendumOption.setId("optionID"); + referendumOption.setName("optionName"); + referendumOption.setPosition(1L); + + val vorlage = new ReferendumvorlageDTO(); + vorlage.setFrage("frage"); + vorlage.setKurzname("kurzname"); + vorlage.setOrdnungszahl(1L); + vorlage.setWahlvorschlagID("wahlvorschlagID"); + vorlage.setReferendumoptionen(Set.of(referendumOption)); + + dto.setReferendumvorlagen(Set.of(vorlage)); + + return dto; + } + + private void defineStubForGetReferendumvorlage( + @Nullable final Object wiremockPayload, final String wahlID, + final String wahlbezirkID, + final HttpStatus httpStatus) throws Exception { + val wireMockResponse = WireMock.aResponse().withHeader("Content-Type", "application/json").withStatus( + httpStatus.value()); + + if (wireMockResponse != null) { + wireMockResponse.withBody(objectMapper.writeValueAsBytes(wiremockPayload)); + } + + WireMock.stubFor(WireMock.get("/vorschlaege/referendum/" + wahlID + "/" + wahlbezirkID) + .willReturn(wireMockResponse)); + } + } +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenControllerTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenControllerTest.java new file mode 100644 index 000000000..f60466ac6 --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenControllerTest.java @@ -0,0 +1,53 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import static org.mockito.ArgumentMatchers.eq; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenReferenceModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenService; +import java.util.Collections; +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 ReferendumvorlagenControllerTest { + + @Mock + ReferendumvorlagenService referendumvorlagenService; + + @Mock + ReferendumvorlagenDTOMapper referendumvorlagenDTOMapper; + + @InjectMocks + ReferendumvorlagenController unitUnderTest; + + @Nested + class GetReferendumvorlagen { + + @Test + void serviceIsCalled() { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val mockedReferenceModel = new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID); + val mockedServiceResponse = new ReferendumvorlagenModel("szgID", Collections.emptySet()); + val mockedServiceResponseAsDTO = new ReferendumvorlagenDTO("szgID", Collections.emptySet()); + + Mockito.when(referendumvorlagenDTOMapper.toModel(eq(wahlbezirkID), eq(wahlID))).thenReturn(mockedReferenceModel); + Mockito.when(referendumvorlagenDTOMapper.toDTO(mockedServiceResponse)).thenReturn(mockedServiceResponseAsDTO); + Mockito.when(referendumvorlagenService.getReferendumvorlagen(mockedReferenceModel)).thenReturn(mockedServiceResponse); + + val result = unitUnderTest.getReferendumvorlagen(wahlID, wahlbezirkID); + + Assertions.assertThat(result).isSameAs(mockedServiceResponseAsDTO); + } + } + +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTOMapperTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTOMapperTest.java new file mode 100644 index 000000000..284668baa --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/rest/referendumvorlagen/ReferendumvorlagenDTOMapperTest.java @@ -0,0 +1,63 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumoptionModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlageModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenModel; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen.ReferendumvorlagenReferenceModel; +import java.util.Set; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +class ReferendumvorlagenDTOMapperTest { + + private final ReferendumvorlagenDTOMapper unitUnderTest = Mappers.getMapper(ReferendumvorlagenDTOMapper.class); + + @Nested + class ToDTO { + + @Test + void isMapped() { + val stimmzettelgebietID = "stimmzettelgebietID"; + + val modelToMap = new ReferendumvorlagenModel(stimmzettelgebietID, + Set.of(new ReferendumvorlageModel("wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new ReferendumoptionModel("option11", "optionsName11", 1L), + new ReferendumoptionModel("option12", "optionsName12", 2L))), + new ReferendumvorlageModel("wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new ReferendumoptionModel("option21", "optionsName21", 3L), + new ReferendumoptionModel("option22", "optionsName22", 4L))))); + + val result = unitUnderTest.toDTO(modelToMap); + + val expectedResult = new ReferendumvorlagenDTO(stimmzettelgebietID, + Set.of(new ReferendumvorlageDTO("wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new ReferendumoptionDTO("option11", "optionsName11", 1L), + new ReferendumoptionDTO("option12", "optionsName12", 2L))), + new ReferendumvorlageDTO("wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new ReferendumoptionDTO("option21", "optionsName21", 3L), + new ReferendumoptionDTO("option22", "optionsName22", 4L))))); + Assertions.assertThat(result).isEqualTo(expectedResult); + Assertions.assertThat(result).hasNoNullFieldsOrProperties(); + } + } + + @Nested + class ToModel { + + @Test + void isMapped() { + val wahlbezirkID = "wahlbezirkID"; + val wahlID = "wahlID"; + + val result = unitUnderTest.toModel(wahlbezirkID, wahlID); + + val expectedResult = new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID); + Assertions.assertThat(result).isEqualTo(expectedResult); + } + + } + +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModelMapperTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModelMapperTest.java new file mode 100644 index 000000000..cbed7c718 --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenModelMapperTest.java @@ -0,0 +1,112 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumoption; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumvorlage; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumvorlagen; +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import java.util.Set; +import java.util.UUID; +import lombok.val; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +class ReferendumvorlagenModelMapperTest { + + private final ReferendumvorlagenModelMapper unitUnderTest = Mappers.getMapper(ReferendumvorlagenModelMapper.class); + + @Nested + class ToBezirkUndWahlID { + + @Test + void isMapped() { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + val modelToMap = new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID); + + val result = unitUnderTest.toBezirkUndWahlID(modelToMap); + + val expectedResult = new BezirkUndWahlID(wahlID, wahlbezirkID); + Assertions.assertThat(result).isEqualTo(expectedResult); + } + } + + @Nested + class ToModel { + + @Test + void isMapped() { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + val stimmzettelgebietID = "stimmzettelgebietID"; + + val entityToMap = new Referendumvorlagen(UUID.randomUUID(), new BezirkUndWahlID(wahlID, wahlbezirkID), stimmzettelgebietID, + Set.of(new Referendumvorlage(null, null, "wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new Referendumoption("option11", "optionsName11", 1L), new Referendumoption("option12", "optionsName12", 2L))), + new Referendumvorlage(null, null, "wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new Referendumoption("option21", "optionsName21", 3L), new Referendumoption("option22", "optionsName22", 4L))))); + + val result = unitUnderTest.toModel(entityToMap); + + val expectedResult = new ReferendumvorlagenModel(stimmzettelgebietID, + Set.of(new ReferendumvorlageModel("wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new ReferendumoptionModel("option11", "optionsName11", 1L), + new ReferendumoptionModel("option12", "optionsName12", 2L))), + new ReferendumvorlageModel("wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new ReferendumoptionModel("option21", "optionsName21", 3L), + new ReferendumoptionModel("option22", "optionsName22", 4L))))); + Assertions.assertThat(result).isEqualTo(expectedResult); + Assertions.assertThat(result).hasNoNullFieldsOrProperties(); + } + } + + @Nested + class ToEntity { + + @Nested + class OfReferendumvorlagenModel { + + @Test + void isMapped() { + val stimmzettelgebietID = "stimmzettelgebietID"; + + val modelToMap = new ReferendumvorlagenModel(stimmzettelgebietID, + Set.of(new ReferendumvorlageModel("wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new ReferendumoptionModel("option11", "optionsName11", 1L), + new ReferendumoptionModel("option12", "optionsName12", 2L))), + new ReferendumvorlageModel("wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new ReferendumoptionModel("option21", "optionsName21", 3L), + new ReferendumoptionModel("option22", "optionsName22", 4L))))); + val bezirkUndWahlID = new BezirkUndWahlID("wahlID", "wahlbezirkID"); + + val result = unitUnderTest.toEntity(modelToMap, bezirkUndWahlID); + + val expectedResult = new Referendumvorlagen(null, bezirkUndWahlID, stimmzettelgebietID, + Set.of(new Referendumvorlage(null, null, "wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new Referendumoption("option11", "optionsName11", 1L), new Referendumoption("option12", "optionsName12", 2L))), + new Referendumvorlage(null, null, "wahlvorschlagID2", 2L, "kurzname2", "frage2", + Set.of(new Referendumoption("option21", "optionsName21", 3L), new Referendumoption("option22", "optionsName22", 4L))))); + Assertions.assertThat(result).isEqualTo(expectedResult); + } + } + + @Nested + class OfReferendumvorlageModel { + + @Test + void isMapped() { + val modelToMap = new ReferendumvorlageModel("wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new ReferendumoptionModel("option11", "optionsName11", 1L), + new ReferendumoptionModel("option12", "optionsName12", 2L))); + + val result = unitUnderTest.toEntity(modelToMap); + + val expectedResult = new Referendumvorlage(null, null, "wahlvorschlagID1", 1L, "kurzname1", "frage1", + Set.of(new Referendumoption("option11", "optionsName11", 1L), new Referendumoption("option12", "optionsName12", 2L))); + Assertions.assertThat(result).isEqualTo(expectedResult); + } + } + } + +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenServiceSecurityTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenServiceSecurityTest.java new file mode 100644 index 000000000..bcc90af7e --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenServiceSecurityTest.java @@ -0,0 +1,149 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.client.WireMock; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.MicroServiceApplication; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.TestConstants; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlageRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlagenRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumoptionDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlageDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.ReferendumvorlagenDTO; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.utils.Authorities; +import de.muenchen.oss.wahllokalsystem.wls.common.testing.SecurityUtils; +import java.util.Set; +import java.util.stream.Stream; +import lombok.val; +import org.apache.commons.lang3.ArrayUtils; +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.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.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest(classes = MicroServiceApplication.class) +@ActiveProfiles(TestConstants.SPRING_TEST_PROFILE) +@AutoConfigureWireMock +public class ReferendumvorlagenServiceSecurityTest { + + @Autowired + ReferendumvorlagenService referendumvorlagenService; + + @Autowired + ReferendumvorlagenRepository referendumvorlagenRepository; + + @Autowired + ReferendumvorlageRepository referendumvorlageRepository; + + @Autowired + ObjectMapper objectMapper; + + @AfterEach + void tearDown() { + SecurityUtils.runWith(Authorities.REPOSITORY_DELETE_REFERENDUMVORLAGEN, Authorities.REPOSITORY_DELETE_REFERENDUMVORLAGE); + referendumvorlagenRepository.deleteAll(); + referendumvorlageRepository.deleteAll(); + } + + @Nested + class LoadReferendumvorlagen { + + @Test + void accessGranted() throws Exception { + SecurityUtils.runWith(Authorities.ALL_AUTHORITIES_GET_REFERENDUMVORLAGEN); + + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val eaiReferendumvorschlage = createClientReferendumvorlagenDTO(); + WireMock.stubFor(WireMock.get("/vorschlaege/referendum/" + wahlID + "/" + wahlbezirkID) + .willReturn(WireMock.aResponse().withHeader("Content-Type", "application/json").withStatus( + HttpStatus.OK.value()).withBody(objectMapper.writeValueAsBytes(eaiReferendumvorschlage)))); + + Assertions.assertThatNoException() + .isThrownBy( + () -> referendumvorlagenService.getReferendumvorlagen(new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID))); + //we have to check is data is stores because access denied exceptions are caught too + SecurityUtils.runWith(Authorities.REPOSITORY_READ_REFERENDUMVORLAGEN); + Assertions.assertThat(referendumvorlagenRepository.count()).isEqualTo(1); + } + + @Test + void missingServiceAuthorityCausesAccessDenied() throws Exception { + SecurityUtils.runWith(Authorities.REPOSITORY_READ_REFERENDUMVORLAGEN, Authorities.REPOSITORY_WRITE_REFERENDUMVORLAGEN, + Authorities.REPOSITORY_WRITE_REFERENDUMVORLAGE); + + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + Assertions.assertThatThrownBy( + () -> referendumvorlagenService.getReferendumvorlagen(new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID))) + .isInstanceOf( + AccessDeniedException.class); + //we have to check is data is stores because access denied exceptions are caught too + SecurityUtils.runWith(Authorities.REPOSITORY_READ_REFERENDUMVORLAGEN); + Assertions.assertThat(referendumvorlagenRepository.count()).isEqualTo(0); + } + + @ParameterizedTest(name = "{index} - {1} missing") + @MethodSource("getMissingRepositoryAuthoritiesVariations") + void missingRepositoryAuthoritiesCausesNoFailWithAccessDenied(final ArgumentsAccessor argumentsAccessor) throws Exception { + SecurityUtils.runWith(argumentsAccessor.get(0, String[].class)); + + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + + val eaiReferendumvorschlage = createClientReferendumvorlagenDTO(); + WireMock.stubFor(WireMock.get("/vorschlaege/referendum/" + wahlID + "/" + wahlbezirkID) + .willReturn(WireMock.aResponse().withHeader("Content-Type", "application/json").withStatus( + HttpStatus.OK.value()).withBody(objectMapper.writeValueAsBytes(eaiReferendumvorschlage)))); + + Assertions.assertThatThrownBy( + () -> referendumvorlagenService.getReferendumvorlagen(new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID))) + .isInstanceOf( + AccessDeniedException.class); + //we have to check is data is stores because access denied exceptions are caught too + SecurityUtils.runWith(Authorities.REPOSITORY_READ_REFERENDUMVORLAGEN); + Assertions.assertThat(referendumvorlagenRepository.count()).isEqualTo(0); + } + + private static Stream getMissingRepositoryAuthoritiesVariations() { + val serviceAuthoritiesWithoutServiceAuthority = ArrayUtils.removeElements(Authorities.ALL_AUTHORITIES_GET_REFERENDUMVORLAGEN, + Authorities.SERVICE_GET_REFERENDUMVORLAGEN); + return SecurityUtils.buildArgumentsForMissingAuthoritiesVariations(serviceAuthoritiesWithoutServiceAuthority); + } + + private ReferendumvorlagenDTO createClientReferendumvorlagenDTO() { + val dto = new ReferendumvorlagenDTO(); + + dto.setStimmzettelgebietID("szgID"); + + val referendumOption = new ReferendumoptionDTO(); + referendumOption.setId("optionID"); + referendumOption.setName("optionName"); + referendumOption.setPosition(1L); + + val vorlage = new ReferendumvorlageDTO(); + vorlage.setFrage("frage"); + vorlage.setKurzname("kurzname"); + vorlage.setOrdnungszahl(1L); + vorlage.setWahlvorschlagID("wahlvorschlagID"); + vorlage.setReferendumoptionen(Set.of(referendumOption)); + + dto.setReferendumvorlagen(Set.of(vorlage)); + + return dto; + } + + } + +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenServiceTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenServiceTest.java new file mode 100644 index 000000000..45a390012 --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenServiceTest.java @@ -0,0 +1,137 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import static org.mockito.ArgumentMatchers.eq; + +import ch.qos.logback.classic.Level; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlageRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.Referendumvorlagen; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.referendumvorlagen.ReferendumvorlagenRepository; +import de.muenchen.oss.wahllokalsystem.basisdatenservice.utils.LoggerExtension; +import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID; +import java.util.Collections; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Consumer; +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.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionTemplate; + +@ExtendWith(MockitoExtension.class) +class ReferendumvorlagenServiceTest { + + @Mock + ReferendumvorlagenValidator referendumvorlagenValidator; + + @Mock + ReferendumvorlagenModelMapper referendumvorlagenModelMapper; + + @Mock + ReferendumvorlagenClient referendumvorlagenClient; + + @Mock + ReferendumvorlageRepository referendumvorlageRepository; + + @Mock + ReferendumvorlagenRepository referendumvorlagenRepository; + + @Spy + TransactionTemplate transactionTemplate = new TransactionTemplate() { + @Override + public void executeWithoutResult(Consumer action) throws TransactionException { + action.accept(Mockito.mock(TransactionStatus.class)); + } + }; + + @InjectMocks + ReferendumvorlagenService unitUnderTest; + + @RegisterExtension + public LoggerExtension loggerExtension = new LoggerExtension(); + + @Nested + class LoadReferendumvorlagen { + + @Test + void dataImportedAndSavedWhenNoDataExists() { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + val referendumvorlagenReference = new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID); + + val mockedBezirkUndWahlID = new BezirkUndWahlID(); + val mockedClientRerefendumvorlagenModel = new ReferendumvorlagenModel("szgID", Collections.emptySet()); + val mockedMappendModelAsEntity = new Referendumvorlagen(UUID.randomUUID(), mockedBezirkUndWahlID, "szgID", Collections.emptySet()); + + Mockito.when(referendumvorlagenModelMapper.toBezirkUndWahlID(referendumvorlagenReference)).thenReturn(mockedBezirkUndWahlID); + Mockito.when(referendumvorlagenModelMapper.toEntity(eq(mockedClientRerefendumvorlagenModel), eq(mockedBezirkUndWahlID))) + .thenReturn(mockedMappendModelAsEntity); + Mockito.when(referendumvorlagenRepository.findByBezirkUndWahlID(mockedBezirkUndWahlID)).thenReturn(Optional.empty()); + Mockito.when(referendumvorlagenClient.getReferendumvorlagen(referendumvorlagenReference)).thenReturn(mockedClientRerefendumvorlagenModel); + + val result = unitUnderTest.getReferendumvorlagen(referendumvorlagenReference); + + Assertions.assertThat(result).isEqualTo(mockedClientRerefendumvorlagenModel); + + Mockito.verify(referendumvorlagenRepository).save(mockedMappendModelAsEntity); + Mockito.verify(referendumvorlageRepository).saveAll(Collections.emptySet()); + } + + @Test + void returnExistingDataWithoutImport() { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + val referendumvorlagenReference = new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID); + + val mockedBezirkUndWahlID = new BezirkUndWahlID(); + val mockedRepoEntity = new Referendumvorlagen(UUID.randomUUID(), mockedBezirkUndWahlID, "szgID", Collections.emptySet()); + val mockedRepoEntityAsModel = new ReferendumvorlagenModel("szgID", Collections.emptySet()); + + Mockito.when(referendumvorlagenModelMapper.toBezirkUndWahlID(referendumvorlagenReference)).thenReturn(mockedBezirkUndWahlID); + Mockito.when(referendumvorlagenModelMapper.toModel(mockedRepoEntity)).thenReturn(mockedRepoEntityAsModel); + Mockito.when(referendumvorlagenRepository.findByBezirkUndWahlID(mockedBezirkUndWahlID)).thenReturn(Optional.of(mockedRepoEntity)); + + val result = unitUnderTest.getReferendumvorlagen(referendumvorlagenReference); + + Assertions.assertThat(result).isEqualTo(mockedRepoEntityAsModel); + Mockito.verifyNoMoreInteractions(referendumvorlageRepository, referendumvorlagenRepository, referendumvorlagenClient); + Assertions.assertThat(loggerExtension.getLoggedEventsStream().filter(event -> event.getLevel() == Level.ERROR).count()).isEqualTo(0); + } + + @Test + void noExceptionWhenSaveOfImportedFailed() { + val wahlID = "wahlID"; + val wahlbezirkID = "wahlbezirkID"; + val referendumvorlagenReference = new ReferendumvorlagenReferenceModel(wahlID, wahlbezirkID); + + val mockedBezirkUndWahlID = new BezirkUndWahlID(); + val mockedClientRerefendumvorlagenModel = new ReferendumvorlagenModel("szgID", Collections.emptySet()); + val mockedMappendModelAsEntity = new Referendumvorlagen(UUID.randomUUID(), mockedBezirkUndWahlID, "szgID", Collections.emptySet()); + val mockedRepoException = new RuntimeException("saving failed"); + + Mockito.when(referendumvorlagenModelMapper.toBezirkUndWahlID(referendumvorlagenReference)).thenReturn(mockedBezirkUndWahlID); + Mockito.when(referendumvorlagenModelMapper.toEntity(eq(mockedClientRerefendumvorlagenModel), eq(mockedBezirkUndWahlID))) + .thenReturn(mockedMappendModelAsEntity); + Mockito.when(referendumvorlagenRepository.findByBezirkUndWahlID(mockedBezirkUndWahlID)).thenReturn(Optional.empty()); + Mockito.when(referendumvorlagenClient.getReferendumvorlagen(referendumvorlagenReference)).thenReturn(mockedClientRerefendumvorlagenModel); + Mockito.doThrow(mockedRepoException).when(referendumvorlagenRepository).save(mockedMappendModelAsEntity); + + val result = unitUnderTest.getReferendumvorlagen(referendumvorlagenReference); + + Assertions.assertThat(result).isEqualTo(mockedClientRerefendumvorlagenModel); + + Mockito.verifyNoMoreInteractions(referendumvorlageRepository, referendumvorlagenRepository); + Assertions.assertThat(loggerExtension.getLoggedEventsStream().filter(event -> event.getLevel() == Level.ERROR).count()).isEqualTo(1); + } + } + +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenValidatorTest.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenValidatorTest.java new file mode 100644 index 000000000..08671d4a8 --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/services/referendumvorlagen/ReferendumvorlagenValidatorTest.java @@ -0,0 +1,91 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.referendumvorlagen; + +import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException; +import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory; +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 ReferendumvorlagenValidatorTest { + + @Mock + ExceptionFactory exceptionFactory; + + @InjectMocks + ReferendumvorlagenValidator unitUnderTest; + + @Nested + class ValidReferumvorlageReferenceModelOrThrow { + + private final FachlicheWlsException mockedWlsException = FachlicheWlsException.withCode("").buildWithMessage(""); + + @Test + void noExceptionWhenModelIsValid() { + val validModel = initValidModel().build(); + + Assertions.assertThatNoException().isThrownBy(() -> unitUnderTest.validReferumvorlageReferenceModelOrThrow(validModel)); + } + + @Test + void exceptionWhenModelIsNull() { + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG)) + .thenReturn(mockedWlsException); + + Assertions.assertThatThrownBy(() -> unitUnderTest.validReferumvorlageReferenceModelOrThrow(null)).isSameAs(mockedWlsException); + } + + @Test + void exceptionWhenWahlIDIsNull() { + val invalidModel = initValidModel().wahlID(null).build(); + + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG)) + .thenReturn(mockedWlsException); + + Assertions.assertThatThrownBy(() -> unitUnderTest.validReferumvorlageReferenceModelOrThrow(invalidModel)).isSameAs(mockedWlsException); + } + + @Test + void exceptionWhenWahlIDIsEmptyString() { + val invalidModel = initValidModel().wahlID("").build(); + + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG)) + .thenReturn(mockedWlsException); + + Assertions.assertThatThrownBy(() -> unitUnderTest.validReferumvorlageReferenceModelOrThrow(invalidModel)).isSameAs(mockedWlsException); + } + + @Test + void exceptionWhenWahlbezirkIDIsNull() { + val invalidModel = initValidModel().wahlbezirkID(null).build(); + + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG)) + .thenReturn(mockedWlsException); + + Assertions.assertThatThrownBy(() -> unitUnderTest.validReferumvorlageReferenceModelOrThrow(invalidModel)).isSameAs(mockedWlsException); + } + + @Test + void exceptionWhenWahlbezirkIDIsEmptyString() { + val invalidModel = initValidModel().wahlbezirkID("").build(); + + Mockito.when(exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG)) + .thenReturn(mockedWlsException); + + Assertions.assertThatThrownBy(() -> unitUnderTest.validReferumvorlageReferenceModelOrThrow(invalidModel)).isSameAs(mockedWlsException); + } + + private ReferendumvorlagenReferenceModel.ReferendumvorlagenReferenceModelBuilder initValidModel() { + return ReferendumvorlagenReferenceModel.builder().wahlbezirkID("wahlbezirkID").wahlID("wahlID"); + } + + } + +} diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/Authorities.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/Authorities.java index 07ad185b3..0845c2e15 100644 --- a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/Authorities.java +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/Authorities.java @@ -15,6 +15,8 @@ public class Authorities { public static final String SERVICE_GET_UNGUELTIGEWAHLSCHEINE = "Basisdaten_BUSINESSACTION_GetUngueltigews"; public static final String SERVICE_POST_UNGUELTIGEWAHLSCHEINE = "Basisdaten_BUSINESSACTION_PostUngueltigews"; + public static final String SERVICE_GET_REFERENDUMVORLAGEN = "Basisdaten_BUSINESSACTION_GetReferendumvorlagen"; + public static final String REPOSITORY_READ_WAHLVORSCHLAEGE = "Basisdaten_READ_WLSWahlvorschlaege"; public static final String REPOSITORY_DELETE_WAHLVORSCHLAEGE = "Basisdaten_DELETE_WLSWahlvorschlaege"; public static final String REPOSITORY_WRITE_WAHLVORSCHLAEGE = "Basisdaten_WRITE_WLSWahlvorschlaege"; @@ -39,6 +41,14 @@ public class Authorities { public static final String REPOSITORY_WRITE_UNGUELTIGEWAHLSCHEINE = "Basisdaten_WRITE_Ungueltigews"; public static final String REPOSITORY_DELETE_UNGUELTIGEWAHLSCHEINE = "Basisdaten_DELETE_Ungueltigews"; + public static final String REPOSITORY_READ_REFERENDUMVORLAGEN = "Basisdaten_READ_Referendumvorlagen"; + public static final String REPOSITORY_WRITE_REFERENDUMVORLAGEN = "Basisdaten_WRITE_Referendumvorlagen"; + public static final String REPOSITORY_DELETE_REFERENDUMVORLAGEN = "Basisdaten_DELETE_Referendumvorlagen"; + + public static final String REPOSITORY_READ_REFERENDUMVORLAGE = "Basisdaten_READ_Referendumvorlage"; + public static final String REPOSITORY_WRITE_REFERENDUMVORLAGE = "Basisdaten_WRITE_Referendumvorlage"; + public static final String REPOSITORY_DELETE_REFERENDUMVORLAGE = "Basisdaten_DELETE_Referendumvorlage"; + public static final String[] ALL_AUTHORITIES_GET_WAHLVORSCHLAEGE = new String[] { SERVICE_GET_WAHLVORSCHLAEGE, REPOSITORY_READ_WAHLVORSCHLAEGE, @@ -88,4 +98,11 @@ public class Authorities { REPOSITORY_WRITE_UNGUELTIGEWAHLSCHEINE }; + public static final String[] ALL_AUTHORITIES_GET_REFERENDUMVORLAGEN = { + SERVICE_GET_REFERENDUMVORLAGEN, + REPOSITORY_READ_REFERENDUMVORLAGEN, + REPOSITORY_WRITE_REFERENDUMVORLAGEN, + REPOSITORY_WRITE_REFERENDUMVORLAGE + }; + } diff --git a/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/LoggerExtension.java b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/LoggerExtension.java new file mode 100644 index 000000000..4933679f2 --- /dev/null +++ b/wls-basisdaten-service/src/test/java/de/muenchen/oss/wahllokalsystem/basisdatenservice/utils/LoggerExtension.java @@ -0,0 +1,33 @@ +package de.muenchen.oss.wahllokalsystem.basisdatenservice.utils; + +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import java.util.stream.Stream; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.LoggerFactory; + +public class LoggerExtension implements BeforeEachCallback, AfterEachCallback { + + private final ListAppender listAppender = new ListAppender<>(); + private final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + + @Override + public void afterEach(ExtensionContext extensionContext) { + listAppender.stop(); + listAppender.list.clear(); + logger.detachAppender(listAppender); + } + + @Override + public void beforeEach(ExtensionContext extensionContext) { + logger.addAppender(listAppender); + listAppender.start(); + } + + public Stream getLoggedEventsStream() { + return listAppender.list.stream(); + } +} diff --git a/wls-basisdaten-service/src/test/resources/logback-spring.xml b/wls-basisdaten-service/src/test/resources/logback-spring.xml new file mode 100644 index 000000000..4bb7f20ac --- /dev/null +++ b/wls-basisdaten-service/src/test/resources/logback-spring.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + %date{yyyy.MM.dd HH:mm:ss.SSS} | ${springAppName} | TraceId: %X{traceId:-} | SpanId: %X{spanId:-}] | %level | [%thread] | %logger{0} | [%file : %line] - %msg%n + + + + + + + + + + + + + + + diff --git a/wls-basisdaten-service/src/test/resources/referendumvorlagen.http b/wls-basisdaten-service/src/test/resources/referendumvorlagen.http new file mode 100644 index 000000000..d60290f90 --- /dev/null +++ b/wls-basisdaten-service/src/test/resources/referendumvorlagen.http @@ -0,0 +1,22 @@ +### Get token wls_all +POST {{ SSO_URL }}/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 {{ SSO_URL }}/auth/realms/wls_realm/protocol/openid-connect/userinfo +Authorization: {{ token_type }} {{ auth_token }} + +### get vorlagen +GET {{ WLS_BASISDATEN_SERVICE_URL }}/businessActions/referendumvorlagen/wahl1/wbz1 +Authorization: {{ token_type }} {{ auth_token }} \ No newline at end of file