Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import de.muenchen.dave.services.ChatMessageService;
import de.muenchen.dave.services.persist.ExternalZaehlungPersistierungsService;
import de.muenchen.dave.services.persist.InternalZaehlungPersistierungsService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -81,7 +82,7 @@ public ResponseEntity<BackendIdDTO> saveWithZeitintervall(@RequestBody @NotNull

@PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasRole(T(de.muenchen.dave.security.AuthoritiesEnum).FACHADMIN.name())")
public ResponseEntity<BackendIdDTO> saveZaehlung(@RequestBody @NotNull final BearbeiteZaehlungDTO zaehlung,
public ResponseEntity<BackendIdDTO> saveZaehlung(@RequestBody @NotNull @Valid final BearbeiteZaehlungDTO zaehlung,
@RequestParam(value = REQUEST_PARAMETER_ZAEHLSTELLE_ID) @NotNull final String zaehlstelleId) {
log.debug("Zaehlung speichern: {}", zaehlung);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import de.muenchen.dave.domain.dtos.PkwEinheitDTO;
import de.muenchen.dave.domain.enums.Fahrzeug;
import de.muenchen.dave.validation.BearbeiteZaehlungValid;
import java.time.LocalDate;
import java.util.List;
import lombok.Data;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;

@Data
@BearbeiteZaehlungValid
public class BearbeiteZaehlungDTO {

String id;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.muenchen.dave.validation;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BearbeiteZaehlungValidator.class)
@Documented
public @interface BearbeiteZaehlungValid {
String message() default "Die zu speichernde Zählung ist nicht valide.";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package de.muenchen.dave.validation;

import de.muenchen.dave.domain.dtos.bearbeiten.BearbeiteKnotenarmDTO;
import de.muenchen.dave.domain.dtos.bearbeiten.BearbeiteZaehlungDTO;
import de.muenchen.dave.domain.enums.Fahrzeug;
import de.muenchen.dave.domain.enums.Zaehlart;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.List;
import java.util.Optional;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

@Component
@NoArgsConstructor
public class BearbeiteZaehlungValidator implements ConstraintValidator<BearbeiteZaehlungValid, BearbeiteZaehlungDTO> {

/**
* Prüft, ob die zu speichernde Zählung valide ist.
*
* @param toValidate {@link BearbeiteZaehlungDTO} zum Validieren.
* @param constraintValidatorContext in welchem die Validierung stattfindet.
* @return true, wenn die Zählung valide ist, sonst false.
*/
@Override
public boolean isValid(final BearbeiteZaehlungDTO toValidate, final ConstraintValidatorContext constraintValidatorContext) {
return toValidate != null && validateZaehlung(toValidate);
}

/**
* Ruft die einzelnen Validierungsmethoden auf und sammelt die Ergebnisse.
*
* @param toValidate {@link BearbeiteZaehlungDTO} zum Validieren.
* @return true, wenn alle Validierungen erfolgreich waren, sonst false.
*/
private boolean validateZaehlung(final BearbeiteZaehlungDTO toValidate) {
return areZaehlartAndSelectedCategoriesValid(toValidate) && areZaehlartAndSelectedKnotenarmeValid(toValidate);
}

/**
* Validiert anhand der ausgewaehlten Zaehlart, ob exakt 2 sich gegenueberliegende Knotenarme
* ausgewaehlt wurden.
* Erlaubte Knotenarme bei der {@link Zaehlart#QJS} : 1 & 3 || 2 & 4 || 5 & 7 || 6 & 8
*
* @param toValidate {@link BearbeiteZaehlungDTO} zum Validieren.
* @return true, wenn die Validierung erfolgreich waren, sonst false.
*/
protected boolean areZaehlartAndSelectedKnotenarmeValid(final BearbeiteZaehlungDTO toValidate) {
boolean isValid = true;
if (Zaehlart.QJS.name().equals(toValidate.getZaehlart())) {
isValid = toValidate.getKnotenarme().size() == 2;
if (isValid) {
final Optional<Integer> reduce = toValidate.getKnotenarme()
.stream()
.map(BearbeiteKnotenarmDTO::getNummer)
.reduce((integer, integer2) -> Math.abs(integer - integer2));
isValid = reduce.get() == 2;
}
}
return isValid;
}

/**
* Validiert anhand der ausgewaehlten Zaehlart, ob die richtigen Fahrzeuge ausgewaehlt wurden.
* Bei den {@link Zaehlart#QJS}, {@link Zaehlart#FJS} und {@link Zaehlart#QU} darf nur
* {@link Fahrzeug#RAD}.RAD und/oder {@link Fahrzeug#FUSS} ausgewaehlt sein
* sein.
*
* @param toValidate {@link BearbeiteZaehlungDTO} zum Validieren.
* @return true, wenn die Validierung erfolgreich waren, sonst false.
*/
protected boolean areZaehlartAndSelectedCategoriesValid(final BearbeiteZaehlungDTO toValidate) {
// Wenn die Zählart QJS, FJS oder QU ist, dann darf nur RAD oder FUSS ausgewählt sein
boolean isValid = true;
final List<String> zaehlarten = List.of(Zaehlart.QJS.name(), Zaehlart.FJS.name(), Zaehlart.QU.name());
if (toValidate.getZaehlart() != null && zaehlarten.contains(toValidate.getZaehlart())) {
final List<Fahrzeug> selectedCategoriesWithoutRadAndFuss = toValidate.getKategorien()
.stream()
.filter(fahrzeug -> !(fahrzeug.equals(Fahrzeug.RAD) || fahrzeug.equals(Fahrzeug.FUSS)))
.toList();
isValid = CollectionUtils.isEmpty(selectedCategoriesWithoutRadAndFuss);
}
return isValid;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package de.muenchen.dave.validation;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import de.muenchen.dave.domain.dtos.bearbeiten.BearbeiteKnotenarmDTO;
import de.muenchen.dave.domain.dtos.bearbeiten.BearbeiteZaehlungDTO;
import de.muenchen.dave.domain.enums.Fahrzeug;
import de.muenchen.dave.domain.enums.Zaehlart;
import java.util.ArrayList;
import org.junit.jupiter.api.Test;

public class BearbeiteZaehlungValidatorTest {

private final BearbeiteZaehlungValidator validator = new BearbeiteZaehlungValidator();

@Test
void isValidTest() {
assertThat(this.validator.isValid(null, null), is(false));
assertThat(this.validator.isValid(new BearbeiteZaehlungDTO(), null), is(true));
}

@Test
void areZaehlartAndSelectedKnotenarmeValidTest() {
final BearbeiteZaehlungDTO toValidate = new BearbeiteZaehlungDTO();
toValidate.setZaehlart(Zaehlart.FJS.name());
assertThat(this.validator.areZaehlartAndSelectedKnotenarmeValid(toValidate), is(true));
toValidate.setZaehlart(Zaehlart.QJS.name());
toValidate.setKnotenarme(new ArrayList<>());
assertThat(this.validator.areZaehlartAndSelectedKnotenarmeValid(toValidate), is(false));
final BearbeiteKnotenarmDTO node1 = new BearbeiteKnotenarmDTO();
node1.setNummer(1);
toValidate.getKnotenarme().add(node1);
final BearbeiteKnotenarmDTO node2 = new BearbeiteKnotenarmDTO();
toValidate.getKnotenarme().add(node2);
assertThat(this.validator.areZaehlartAndSelectedKnotenarmeValid(toValidate), is(false));
node2.setNummer(2);
assertThat(this.validator.areZaehlartAndSelectedKnotenarmeValid(toValidate), is(false));
node2.setNummer(3);
assertThat(this.validator.areZaehlartAndSelectedKnotenarmeValid(toValidate), is(true));
toValidate.getKnotenarme().add(new BearbeiteKnotenarmDTO());
assertThat(this.validator.areZaehlartAndSelectedKnotenarmeValid(toValidate), is(false));
}

@Test
void areZaehlartAndSelectedCategoriesValidTest() {
final BearbeiteZaehlungDTO toValidate = new BearbeiteZaehlungDTO();
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.setZaehlart(null);
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.setZaehlart(Zaehlart.N.name());
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.setZaehlart(Zaehlart.QJS.name());
toValidate.setKategorien(new ArrayList<>());
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.getKategorien().add(Fahrzeug.FUSS);
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.setZaehlart(Zaehlart.QU.name());
toValidate.getKategorien().add(Fahrzeug.RAD);
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.setZaehlart(Zaehlart.FJS.name());
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(true));
toValidate.getKategorien().add(Fahrzeug.KFZ);
assertThat(this.validator.areZaehlartAndSelectedCategoriesValid(toValidate), is(false));
}

}
Loading