Browse Source

CensusEntry BirthYear Validation

Andrew Grant 7 months ago
parent
commit
7d2881f1ae
24 changed files with 500 additions and 201 deletions
  1. 4 0
      src/main/java/scot/carricksoftware/grants/constants/ValidationConstants.java
  2. 5 5
      src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerImpl.java
  3. 5 5
      src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerImpl.java
  4. 3 60
      src/main/java/scot/carricksoftware/grants/validators/census/CensusCommandValidator.java
  5. 74 0
      src/main/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImpl.java
  6. 2 81
      src/main/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidator.java
  7. 184 0
      src/main/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImpl.java
  8. 1 1
      src/main/resources/liquibase.properties
  9. 4 4
      src/test/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerSaveOrUpdateTest.java
  10. 3 3
      src/test/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerTest.java
  11. 4 4
      src/test/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerSaveOrUpdateTest.java
  12. 3 3
      src/test/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerTest.java
  13. 3 3
      src/test/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerUpdateRecordedBirthDateTest.java
  14. 8 8
      src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImplRoomWithWindowsTest.java
  15. 6 6
      src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImplRoomsInhabitedTest.java
  16. 6 6
      src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImplTest.java
  17. 71 0
      src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplBIrthYearAndAgeTest.java
  18. 102 0
      src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplBirthDayTest.java
  19. 3 3
      src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplBirthYearTest.java
  20. 3 3
      src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplNameTest.java
  21. 3 3
      src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplTest.java
  22. 1 1
      src/test/java/scot/carricksoftware/grants/validators/places/CountryCensusCommandValidatorImplTest.java
  23. 1 1
      src/test/java/scot/carricksoftware/grants/validators/places/PlaceCensusCommandValidatorImplTest.java
  24. 1 1
      src/test/java/scot/carricksoftware/grants/validators/places/RegionCensusCommandValidatorImplTest.java

+ 4 - 0
src/main/java/scot/carricksoftware/grants/constants/ValidationConstants.java

@@ -38,4 +38,8 @@ public class ValidationConstants {
     public static final String BOUNDARY_TYPE_IS_NULL = "The boundary type cannot be null.";
 
     public static final String FIELD_NOT_NEGATIVE_INTEGER = "Not a non negative integer.";
+
+    public static final String BIRTHDAY_INCORRECT_FORMAT = "Format should be dd/mm";
+    public static final String BIRTH_YEAR_AND_AGE_CANNOT_COEXIST = "Birth Year and Age cannot exist.";
+    public static final String BIRTH_DAY_AND_AGE_CANNOT_COEXIST = "BirthDay and Age cannot exist.";
 }

+ 5 - 5
src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerImpl.java

@@ -23,7 +23,7 @@ import scot.carricksoftware.grants.constants.ViewConstants;
 import scot.carricksoftware.grants.converters.census.CensusConverter;
 import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.places.places.PlaceService;
-import scot.carricksoftware.grants.validators.census.CensusCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusCommandValidatorImpl;
 
 @SuppressWarnings("LoggingSimilarMessage")
 @Controller
@@ -31,16 +31,16 @@ public class CensusFormControllerImpl implements CensusFormController {
 
     private static final Logger logger = LogManager.getLogger(CensusFormControllerImpl.class);
     private final CensusService censusService;
-    private final CensusCommandValidator censusCommandValidator;
+    private final CensusCommandValidatorImpl censusCommandValidatorImpl;
     private final CensusConverter censusConverter;
     private final PlaceService placeService;
 
 
     public CensusFormControllerImpl(CensusService censusService,
-                                    CensusCommandValidator censusCommandValidator,
+                                    CensusCommandValidatorImpl censusCommandValidatorImpl,
                                     CensusConverter censusConverter, PlaceService placeService) {
         this.censusService = censusService;
-        this.censusCommandValidator = censusCommandValidator;
+        this.censusCommandValidatorImpl = censusCommandValidatorImpl;
         this.censusConverter = censusConverter;
         this.placeService = placeService;
     }
@@ -69,7 +69,7 @@ public class CensusFormControllerImpl implements CensusFormController {
     public String saveOrUpdate(@Valid @ModelAttribute CensusCommand censusCommand, BindingResult bindingResult, Model model) {
         logger.debug("CensusFormControllerImpl::saveOrUpdate");
 
-        censusCommandValidator.validate(censusCommand, bindingResult);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResult);
 
 
         if (bindingResult.hasErrors()) {

+ 5 - 5
src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerImpl.java

@@ -26,7 +26,7 @@ import scot.carricksoftware.grants.services.census.censusentry.CensusEntryServic
 import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.census.censusentry.UpdateRecordedYearOfBirth;
 import scot.carricksoftware.grants.services.people.PersonService;
-import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidatorImpl;
 
 @SuppressWarnings("LoggingSimilarMessage")
 @Controller
@@ -34,7 +34,7 @@ public class CensusEntryFormControllerImpl implements CensusEntryFormController
 
     private static final Logger logger = LogManager.getLogger(CensusEntryFormControllerImpl.class);
     private final CensusEntryService censusEntryService;
-    private final CensusEntryCommandValidator censusEntryCommandValidator;
+    private final CensusEntryCommandValidatorImpl censusEntryCommandValidatorImpl;
     private final CensusEntryConverter censusEntryConverter;
     private final Capitalisation capitalisation;
     private final PersonService personService;
@@ -44,13 +44,13 @@ public class CensusEntryFormControllerImpl implements CensusEntryFormController
 
 
     public CensusEntryFormControllerImpl(CensusEntryService censusEntryService,
-                                         CensusEntryCommandValidator censusEntryCommandValidator,
+                                         CensusEntryCommandValidatorImpl censusEntryCommandValidatorImpl,
                                          CensusEntryConverter censusEntryConverter,
                                          Capitalisation capitalisation,
                                          PersonService personService,
                                          CensusService censusService, UpdateRecordedYearOfBirth updateRecordedYearOfBirth) {
         this.censusEntryService = censusEntryService;
-        this.censusEntryCommandValidator = censusEntryCommandValidator;
+        this.censusEntryCommandValidatorImpl = censusEntryCommandValidatorImpl;
         this.censusEntryConverter = censusEntryConverter;
         this.capitalisation = capitalisation;
         this.personService = personService;
@@ -84,7 +84,7 @@ public class CensusEntryFormControllerImpl implements CensusEntryFormController
     public String saveOrUpdate(@Valid @ModelAttribute CensusEntryCommand censusEntryCommand, BindingResult bindingResult, Model model) {
         logger.debug("CensusEntryFormControllerImpl::saveOrUpdate");
 
-        censusEntryCommandValidator.validate(censusEntryCommand, bindingResult);
+        censusEntryCommandValidatorImpl.validate(censusEntryCommand, bindingResult);
         censusEntryCommand.setName(capitalisation.getCapitalisation(censusEntryCommand.getName()));
 
         if (bindingResult.hasErrors()) {

+ 3 - 60
src/main/java/scot/carricksoftware/grants/validators/census/CensusCommandValidator.java

@@ -5,70 +5,13 @@
 
 package scot.carricksoftware.grants.validators.census;
 
-import org.springframework.stereotype.Component;
 import org.springframework.validation.BindingResult;
 import scot.carricksoftware.grants.commands.census.CensusCommand;
-import scot.carricksoftware.grants.constants.ApplicationConstants;
-import scot.carricksoftware.grants.constants.ValidationConstants;
 
-@Component
-public class CensusCommandValidator {
 
-    public void validate(CensusCommand censusCommand, BindingResult bindingResult) {
-        validateDate(censusCommand, bindingResult);
-        validateRoomsInhabited(censusCommand, bindingResult);
-        validateRoomsWithWindows(censusCommand, bindingResult);
-    }
+public interface CensusCommandValidator {
 
-    private void validateRoomsWithWindows(CensusCommand censusCommand, BindingResult bindingResult) {
-        if (notANonNegativeInteger(censusCommand.getRoomsWithWindows())) {
-            bindingResult.rejectValue("roomsWithWindows", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.FIELD_NOT_NEGATIVE_INTEGER);
-        }
-    }
-
-    private void validateRoomsInhabited(CensusCommand censusCommand, BindingResult bindingResult) {
-        if (notANonNegativeInteger(censusCommand.getInhabitedRooms())) {
-            bindingResult.rejectValue("inhabitedRooms", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.FIELD_NOT_NEGATIVE_INTEGER);
-        }
-    }
-
-    private boolean notANonNegativeInteger(String field) {
-        if (field == null || field.isEmpty()) {
-            return false;
-        } else {
-            try {
-                int number = Integer.parseInt(field);
-                if (number < 0) {
-                   return true;
-                }
-            } catch (NumberFormatException e) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void validateDate(CensusCommand censusCommand, BindingResult bindingResult) {
-        if (censusCommand.getCensusDate() == null) {
-            bindingResult.rejectValue("date", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.DATE_IS_NULL);
-        }
-        if (censusCommand.getBoundaryType() == null) {
-            bindingResult.rejectValue("boundaryType", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.BOUNDARY_TYPE_IS_NULL);
-        }
-        if (censusCommand.getPlace() == null) {
-            bindingResult.rejectValue("place", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.PLACE_IS_NULL);
-        }
-
-    }
+    @SuppressWarnings("unused")
+    void validate(CensusCommand censusCommand, BindingResult bindingResult);
 }
 

+ 74 - 0
src/main/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImpl.java

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 19/03/2025, 09:50. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.validators.census;
+
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import scot.carricksoftware.grants.commands.census.CensusCommand;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.ValidationConstants;
+
+@Component
+public class CensusCommandValidatorImpl implements CensusCommandValidator {
+
+    public void validate(CensusCommand censusCommand, BindingResult bindingResult) {
+        validateDate(censusCommand, bindingResult);
+        validateRoomsInhabited(censusCommand, bindingResult);
+        validateRoomsWithWindows(censusCommand, bindingResult);
+    }
+
+    private void validateRoomsWithWindows(CensusCommand censusCommand, BindingResult bindingResult) {
+        if (notANonNegativeInteger(censusCommand.getRoomsWithWindows())) {
+            bindingResult.rejectValue("roomsWithWindows", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.FIELD_NOT_NEGATIVE_INTEGER);
+        }
+    }
+
+    private void validateRoomsInhabited(CensusCommand censusCommand, BindingResult bindingResult) {
+        if (notANonNegativeInteger(censusCommand.getInhabitedRooms())) {
+            bindingResult.rejectValue("inhabitedRooms", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.FIELD_NOT_NEGATIVE_INTEGER);
+        }
+    }
+
+    private boolean notANonNegativeInteger(String field) {
+        if (field == null || field.isEmpty()) {
+            return false;
+        } else {
+            try {
+                int number = Integer.parseInt(field);
+                if (number < 0) {
+                   return true;
+                }
+            } catch (NumberFormatException e) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void validateDate(CensusCommand censusCommand, BindingResult bindingResult) {
+        if (censusCommand.getCensusDate() == null) {
+            bindingResult.rejectValue("date", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.DATE_IS_NULL);
+        }
+        if (censusCommand.getBoundaryType() == null) {
+            bindingResult.rejectValue("boundaryType", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.BOUNDARY_TYPE_IS_NULL);
+        }
+        if (censusCommand.getPlace() == null) {
+            bindingResult.rejectValue("place", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.PLACE_IS_NULL);
+        }
+
+    }
+}
+

+ 2 - 81
src/main/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidator.java

@@ -5,93 +5,14 @@
 
 package scot.carricksoftware.grants.validators.census;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.springframework.stereotype.Component;
 import org.springframework.validation.BindingResult;
 import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
-import scot.carricksoftware.grants.constants.ApplicationConstants;
-import scot.carricksoftware.grants.constants.ValidationConstants;
 
-@Component
-public class CensusEntryCommandValidator {
 
-    private static final Logger logger = LogManager.getLogger(CensusEntryCommandValidator.class);
+public interface CensusEntryCommandValidator {
 
     @SuppressWarnings("unused")
-    public void validate(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
-        logger.debug("censusEntryCommandValidator::validate");
-        validateCensus(censusEntryCommand, bindingResult);
-        validateNameAndPerson(censusEntryCommand, bindingResult);
-        validateBirthYear(censusEntryCommand, bindingResult);
-    }
-
-    private void validateBirthYear(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
-        if (censusEntryCommand.getBirthYear() != null) {
-            if (!isPositiveInteger(censusEntryCommand.getBirthYear())) {
-                bindingResult.rejectValue("birthYear", ApplicationConstants.EMPTY_STRING,
-                        null,
-                        ValidationConstants.FIELD_NOT_NEGATIVE_INTEGER);
-            }
-        }
-    }
-
-    private boolean isPositiveInteger(String string) {
-        try {
-            int Number;
-            Number = Integer.parseInt(string);
-            return Number > 0;
-        } catch (RuntimeException e) {
-            return false;
-        }
-    }
-
-    private void validateNameAndPerson(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
-        if (censusEntryCommand.getPerson() == null) {
-            if (censusEntryCommand.getName() == null || censusEntryCommand.getName().isEmpty()) {
-                bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
-                        null,
-                        ValidationConstants.CENSUS_NAME_IS_NULL);
-                bindingResult.rejectValue("person", ApplicationConstants.EMPTY_STRING,
-                        null,
-                        ValidationConstants.CENSUS_NAME_IS_NULL);
-            } else {
-                validateUntrackedPerson(censusEntryCommand, bindingResult);
-            }
-        } else {
-            if (censusEntryCommand.getName() != null && !censusEntryCommand.getName().isEmpty()) {
-                bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
-                        null,
-                        ValidationConstants.CENSUS_NAME_IS_NOT_NULL);
-                bindingResult.rejectValue("person", ApplicationConstants.EMPTY_STRING,
-                        null,
-                        ValidationConstants.CENSUS_NAME_IS_NOT_NULL);
-            }
-        }
-    }
-
-    private void validateCensus(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
-        if (censusEntryCommand.getCensus() == null) {
-            bindingResult.rejectValue("census", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.CENSUS_IS_NULL);
-        }
-    }
-
-    private void validateUntrackedPerson(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
-        if (censusEntryCommand.getName().length() < ApplicationConstants.MINIMUM_NAME_LENGTH) {
-            bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
-                    null,
-                    ValidationConstants.NAME_IS_TOO_SHORT);
-        } else {
-            if (censusEntryCommand.getName().length() > ApplicationConstants.MAXIMUM_NAME_LENGTH) {
-                bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
-                        null,
-                        ValidationConstants.NAME_IS_TOO_LONG);
-            }
-        }
-    }
-
+    void validate(CensusEntryCommand censusEntryCommand, BindingResult bindingResult);
 
 }
 

+ 184 - 0
src/main/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImpl.java

@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 19/03/2025, 09:50. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.validators.census;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.ValidationConstants;
+
+@Component
+public class CensusEntryCommandValidatorImpl implements CensusEntryCommandValidator {
+
+    private static final Logger logger = LogManager.getLogger(CensusEntryCommandValidatorImpl.class);
+
+    @Override
+    public void validate(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        logger.debug("censusEntryCommandValidator::validate");
+        validateCensus(censusEntryCommand, bindingResult);
+        validateNameAndPerson(censusEntryCommand, bindingResult);
+        validateBirthYear(censusEntryCommand, bindingResult);
+        validateBirthDay(censusEntryCommand, bindingResult);
+        validateAgeAndBirthYear(censusEntryCommand, bindingResult);
+        validateAgeAndBirthDay(censusEntryCommand, bindingResult);
+    }
+
+    private void validateAgeAndBirthDay(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getBirthDay() != null) {
+            if (censusEntryCommand.getAge() != null) {
+                bindingResult.rejectValue("birthDay", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.BIRTH_DAY_AND_AGE_CANNOT_COEXIST);
+
+                bindingResult.rejectValue("age", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.BIRTH_DAY_AND_AGE_CANNOT_COEXIST);
+            }
+        }
+    }
+
+    private void validateAgeAndBirthYear(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getBirthYear() != null) {
+            if (censusEntryCommand.getAge() != null) {
+                bindingResult.rejectValue("birthYear", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.BIRTH_YEAR_AND_AGE_CANNOT_COEXIST);
+
+                bindingResult.rejectValue("age", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.BIRTH_YEAR_AND_AGE_CANNOT_COEXIST);
+            }
+        }
+    }
+
+    private void validateBirthDay(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getBirthDay() != null) {
+            if (!censusEntryCommand.getBirthDay().contains("/")) {
+                bindingResult.rejectValue("birthDay", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+            } else {
+                String[] parts = censusEntryCommand.getBirthDay().split("/");
+                if (parts.length == 2) {
+                    validateDays(parts[0], bindingResult);
+                    validateYears(parts[1], bindingResult);
+                } else {
+                    bindingResult.rejectValue("birthDay", ApplicationConstants.EMPTY_STRING,
+                            null,
+                            ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+                }
+            }
+        }
+    }
+
+    private void validateYears(String part, BindingResult bindingResult) {
+        boolean invalidYear = false;
+        try {
+            int year = Integer.parseInt(part);
+            if (year <= 0) {
+                invalidYear = true;
+            }
+        } catch (RuntimeException e) {
+            invalidYear = true;
+        }
+        if (invalidYear) {
+            bindingResult.rejectValue("birthDay", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+        }
+    }
+
+    private void validateDays(String part, BindingResult bindingResult) {
+        boolean invalidDay = false;
+        try {
+            int day = Integer.parseInt(part);
+            if (day < 1 || day > 31) {
+                invalidDay = true;
+            }
+        } catch (RuntimeException e) {
+            invalidDay = true;
+        }
+        if (invalidDay) {
+            bindingResult.rejectValue("birthDay", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+        }
+    }
+
+
+    private void validateBirthYear(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getBirthYear() != null) {
+            if (!isPositiveInteger(censusEntryCommand.getBirthYear())) {
+                bindingResult.rejectValue("birthYear", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.FIELD_NOT_NEGATIVE_INTEGER);
+            }
+        }
+    }
+
+    private boolean isPositiveInteger(String string) {
+        try {
+            int Number;
+            Number = Integer.parseInt(string);
+            return Number > 0;
+        } catch (RuntimeException e) {
+            return false;
+        }
+    }
+
+    private void validateNameAndPerson(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getPerson() == null) {
+            if (censusEntryCommand.getName() == null || censusEntryCommand.getName().isEmpty()) {
+                bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.CENSUS_NAME_IS_NULL);
+                bindingResult.rejectValue("person", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.CENSUS_NAME_IS_NULL);
+            } else {
+                validateUntrackedPerson(censusEntryCommand, bindingResult);
+            }
+        } else {
+            if (censusEntryCommand.getName() != null && !censusEntryCommand.getName().isEmpty()) {
+                bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.CENSUS_NAME_IS_NOT_NULL);
+                bindingResult.rejectValue("person", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.CENSUS_NAME_IS_NOT_NULL);
+            }
+        }
+    }
+
+    private void validateCensus(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getCensus() == null) {
+            bindingResult.rejectValue("census", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.CENSUS_IS_NULL);
+        }
+    }
+
+    private void validateUntrackedPerson(CensusEntryCommand censusEntryCommand, BindingResult bindingResult) {
+        if (censusEntryCommand.getName().length() < ApplicationConstants.MINIMUM_NAME_LENGTH) {
+            bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
+                    null,
+                    ValidationConstants.NAME_IS_TOO_SHORT);
+        } else {
+            if (censusEntryCommand.getName().length() > ApplicationConstants.MAXIMUM_NAME_LENGTH) {
+                bindingResult.rejectValue("name", ApplicationConstants.EMPTY_STRING,
+                        null,
+                        ValidationConstants.NAME_IS_TOO_LONG);
+            }
+        }
+    }
+
+
+
+}
+

+ 1 - 1
src/main/resources/liquibase.properties

@@ -1,6 +1,6 @@
 #changeLogFile: src/main/resources/db/changelog/master.xml
 logging: debug
-#driver: org.postgresql.Driver
+
 url: jdbc:mariadb://git.carricksoftware.co.uk:3306/grants_uat
 
 username: apg

+ 4 - 4
src/test/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerSaveOrUpdateTest.java

@@ -17,7 +17,7 @@ import scot.carricksoftware.grants.commands.census.CensusCommandImpl;
 import scot.carricksoftware.grants.converters.census.CensusConverterImpl;
 import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.places.places.PlaceService;
-import scot.carricksoftware.grants.validators.census.CensusCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusCommandValidatorImpl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -35,7 +35,7 @@ public class CensusFormControllerSaveOrUpdateTest {
     private CensusService censusServiceMock;
 
     @Mock
-    CensusCommandValidator censusCommandValidatorMock;
+    CensusCommandValidatorImpl censusCommandValidatorImplMock;
 
     @Mock
     private CensusConverterImpl censusConverterMock;
@@ -54,7 +54,7 @@ public class CensusFormControllerSaveOrUpdateTest {
     @BeforeEach
     public void setUp() {
         censusController = new CensusFormControllerImpl(censusServiceMock,
-                censusCommandValidatorMock,
+                censusCommandValidatorImplMock,
                 censusConverterMock,
                 placeServiceMock);
         censusCommand = new CensusCommandImpl();
@@ -82,7 +82,7 @@ public class CensusFormControllerSaveOrUpdateTest {
         censusCommand.setId(id);
         when(censusServiceMock.saveCensusCommand(any(CensusCommand.class))).thenReturn(censusCommand);
         censusController.saveOrUpdate(censusCommand, bindingResultMock, modelMock);
-        verify(censusCommandValidatorMock).validate(censusCommand, bindingResultMock);
+        verify(censusCommandValidatorImplMock).validate(censusCommand, bindingResultMock);
     }
 
 

+ 3 - 3
src/test/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerTest.java

@@ -19,7 +19,7 @@ import scot.carricksoftware.grants.converters.census.CensusConverterImpl;
 import scot.carricksoftware.grants.domains.census.Census;
 import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.places.places.PlaceService;
-import scot.carricksoftware.grants.validators.census.CensusCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusCommandValidatorImpl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -50,13 +50,13 @@ public class CensusFormControllerTest {
     private Model modelMock;
 
     @Mock
-    CensusCommandValidator censusCommandValidatorMock;
+    CensusCommandValidatorImpl censusCommandValidatorImplMock;
 
 
     @BeforeEach
     public void setUp() {
         censusController = new CensusFormControllerImpl(censusServiceMock,
-                censusCommandValidatorMock,
+                censusCommandValidatorImplMock,
                 censusConverterMock,
                 placeServiceMock);
     }

+ 4 - 4
src/test/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerSaveOrUpdateTest.java

@@ -20,7 +20,7 @@ import scot.carricksoftware.grants.services.census.censusentry.CensusEntryServic
 import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.census.censusentry.UpdateRecordedYearOfBirth;
 import scot.carricksoftware.grants.services.people.PersonService;
-import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidatorImpl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -39,7 +39,7 @@ public class CensusEntryFormControllerSaveOrUpdateTest {
     private CensusEntryService censusEntryServiceMock;
 
     @Mock
-    CensusEntryCommandValidator censusEntryCommandValidatorMock;
+    CensusEntryCommandValidatorImpl censusEntryCommandValidatorImplMock;
 
     @Mock
     private CensusEntryConverterImpl censusEntryConverterMock;
@@ -67,7 +67,7 @@ public class CensusEntryFormControllerSaveOrUpdateTest {
     @BeforeEach
     public void setUp() {
         censusEntryController = new CensusEntryFormControllerImpl(censusEntryServiceMock,
-                censusEntryCommandValidatorMock,
+                censusEntryCommandValidatorImplMock,
                 censusEntryConverterMock,
                 capitalisationMock,
                 personServiceMock,
@@ -99,7 +99,7 @@ public class CensusEntryFormControllerSaveOrUpdateTest {
         censusEntryCommand.setId(id);
         when(censusEntryServiceMock.saveCensusEntryCommand(any(CensusEntryCommand.class))).thenReturn(censusEntryCommand);
         censusEntryController.saveOrUpdate(censusEntryCommand, bindingResultMock, modelMock);
-        verify(censusEntryCommandValidatorMock).validate(censusEntryCommand, bindingResultMock);
+        verify(censusEntryCommandValidatorImplMock).validate(censusEntryCommand, bindingResultMock);
     }
 
     @Test

+ 3 - 3
src/test/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerTest.java

@@ -22,7 +22,7 @@ import scot.carricksoftware.grants.services.census.censusentry.CensusEntryServic
 import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.census.censusentry.UpdateRecordedYearOfBirth;
 import scot.carricksoftware.grants.services.people.PersonService;
-import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidatorImpl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -52,7 +52,7 @@ public class CensusEntryFormControllerTest {
     private CensusService censusServiceMock;
 
     @Mock
-    private CensusEntryCommandValidator censusEntryCommandValidatorMock;
+    private CensusEntryCommandValidatorImpl censusEntryCommandValidatorImplMock;
 
     @Mock
     private Capitalisation capitalisationMock;
@@ -67,7 +67,7 @@ public class CensusEntryFormControllerTest {
     @BeforeEach
     public void setUp() {
         censusEntryController = new CensusEntryFormControllerImpl(censusEntryServiceMock,
-                censusEntryCommandValidatorMock,
+                censusEntryCommandValidatorImplMock,
                 censusEntryConverterMock,
                 capitalisationMock,
                 personServiceMock,

+ 3 - 3
src/test/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerUpdateRecordedBirthDateTest.java

@@ -20,7 +20,7 @@ import scot.carricksoftware.grants.services.census.census.CensusService;
 import scot.carricksoftware.grants.services.census.censusentry.CensusEntryService;
 import scot.carricksoftware.grants.services.census.censusentry.UpdateRecordedYearOfBirth;
 import scot.carricksoftware.grants.services.people.PersonService;
-import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidator;
+import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidatorImpl;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verify;
@@ -37,7 +37,7 @@ public class CensusEntryFormControllerUpdateRecordedBirthDateTest {
     private CensusEntryService censusEntryServiceMock;
 
     @Mock
-    CensusEntryCommandValidator censusEntryCommandValidatorMock;
+    CensusEntryCommandValidatorImpl censusEntryCommandValidatorImplMock;
 
     @Mock
     private CensusEntryConverterImpl censusEntryConverterMock;
@@ -65,7 +65,7 @@ public class CensusEntryFormControllerUpdateRecordedBirthDateTest {
     @BeforeEach
     public void setUp() {
         censusEntryController = new CensusEntryFormControllerImpl(censusEntryServiceMock,
-                censusEntryCommandValidatorMock,
+                censusEntryCommandValidatorImplMock,
                 censusEntryConverterMock,
                 capitalisationMock,
                 personServiceMock,

+ 8 - 8
src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorRoomWithWindowsTest.java → src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImplRoomWithWindowsTest.java

@@ -24,9 +24,9 @@ import static scot.carricksoftware.grants.GenerateCensusRandomEnums.GetRandomCen
 import static scot.carricksoftware.grants.GenerateRandomPlaceValues.GetRandomPlace;
 
 @ExtendWith(MockitoExtension.class)
-class CensusCommandValidatorRoomWithWindowsTest {
+class CensusCommandValidatorImplRoomWithWindowsTest {
 
-    private CensusCommandValidator censusCommandValidator = new CensusCommandValidator();
+    private CensusCommandValidatorImpl censusCommandValidatorImpl = new CensusCommandValidatorImpl();
 
     private ArgumentCaptor<String> stringArgumentCaptor;
     private ArgumentCaptor<String> stringArgumentCaptor2;
@@ -40,7 +40,7 @@ class CensusCommandValidatorRoomWithWindowsTest {
 
     @BeforeEach
     void setUp() {
-        censusCommandValidator = new CensusCommandValidator();
+        censusCommandValidatorImpl = new CensusCommandValidatorImpl();
         stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
         stringArgumentCaptor2 = ArgumentCaptor.forClass(String.class);
         stringArgumentCaptor3 = ArgumentCaptor.forClass(String.class);
@@ -56,7 +56,7 @@ class CensusCommandValidatorRoomWithWindowsTest {
     public void validateRoomsWithWindowsNegativeTest() {
         censusCommand.setInhabitedRooms("1");
         censusCommand.setRoomsWithWindows("-5");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock, atLeast(1)).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("roomsWithWindows", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());
@@ -69,7 +69,7 @@ class CensusCommandValidatorRoomWithWindowsTest {
     public void validateRoomsWithWindowsNonNumberTest() {
         censusCommand.setInhabitedRooms("1");
         censusCommand.setRoomsWithWindows("z");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock, atLeast(1)).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("roomsWithWindows", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());
@@ -81,7 +81,7 @@ class CensusCommandValidatorRoomWithWindowsTest {
     public void validateRoomsWithWindowsValidNumberTest() {
         censusCommand.setInhabitedRooms("3");
         censusCommand.setRoomsWithWindows("5");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verifyNoInteractions(bindingResultMock);
     }
 
@@ -89,7 +89,7 @@ class CensusCommandValidatorRoomWithWindowsTest {
     public void validateRoomsWithWindowsNullTest() {
         censusCommand.setInhabitedRooms("3");
         censusCommand.setRoomsWithWindows(null);
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verifyNoInteractions(bindingResultMock);
     }
 
@@ -97,7 +97,7 @@ class CensusCommandValidatorRoomWithWindowsTest {
     public void validateRoomsWithWindowsZeroTest() {
         censusCommand.setInhabitedRooms("3");
         censusCommand.setRoomsWithWindows("0");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verifyNoInteractions(bindingResultMock);
     }
 

+ 6 - 6
src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorRoomsInhabitedTest.java → src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImplRoomsInhabitedTest.java

@@ -24,9 +24,9 @@ import static scot.carricksoftware.grants.GenerateCensusRandomEnums.GetRandomCen
 import static scot.carricksoftware.grants.GenerateRandomPlaceValues.GetRandomPlace;
 
 @ExtendWith(MockitoExtension.class)
-class CensusCommandValidatorRoomsInhabitedTest {
+class CensusCommandValidatorImplRoomsInhabitedTest {
 
-    private CensusCommandValidator censusCommandValidator = new CensusCommandValidator();
+    private CensusCommandValidatorImpl censusCommandValidatorImpl = new CensusCommandValidatorImpl();
 
     private ArgumentCaptor<String> stringArgumentCaptor;
     private ArgumentCaptor<String> stringArgumentCaptor2;
@@ -40,7 +40,7 @@ class CensusCommandValidatorRoomsInhabitedTest {
 
     @BeforeEach
     void setUp() {
-        censusCommandValidator = new CensusCommandValidator();
+        censusCommandValidatorImpl = new CensusCommandValidatorImpl();
         stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
         stringArgumentCaptor2 = ArgumentCaptor.forClass(String.class);
         stringArgumentCaptor3 = ArgumentCaptor.forClass(String.class);
@@ -56,7 +56,7 @@ class CensusCommandValidatorRoomsInhabitedTest {
     public void validateRoomsInhabitedNegativeTest() {
         censusCommand.setInhabitedRooms("-1");
         censusCommand.setRoomsWithWindows("5");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock, atLeast(1)).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("inhabitedRooms", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());
@@ -69,7 +69,7 @@ class CensusCommandValidatorRoomsInhabitedTest {
     public void validateRoomsInhabitedNonNumberTest() {
         censusCommand.setInhabitedRooms("z");
         censusCommand.setRoomsWithWindows("5");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock, atLeast(1)).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("inhabitedRooms", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());
@@ -81,7 +81,7 @@ class CensusCommandValidatorRoomsInhabitedTest {
     public void validateRoomsInhabitedValidNumberTest() {
         censusCommand.setInhabitedRooms("3");
         censusCommand.setRoomsWithWindows("5");
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verifyNoInteractions(bindingResultMock);
     }
 

+ 6 - 6
src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorTest.java → src/test/java/scot/carricksoftware/grants/validators/census/CensusCommandValidatorImplTest.java

@@ -24,9 +24,9 @@ import static scot.carricksoftware.grants.GenerateCensusRandomEnums.GetRandomCen
 import static scot.carricksoftware.grants.GenerateRandomPlaceValues.GetRandomPlace;
 
 @ExtendWith(MockitoExtension.class)
-class CensusCommandValidatorTest {
+class CensusCommandValidatorImplTest {
 
-    private CensusCommandValidator censusCommandValidator = new CensusCommandValidator();
+    private CensusCommandValidatorImpl censusCommandValidatorImpl = new CensusCommandValidatorImpl();
 
     private ArgumentCaptor<String> stringArgumentCaptor;
     private ArgumentCaptor<String> stringArgumentCaptor2;
@@ -40,7 +40,7 @@ class CensusCommandValidatorTest {
 
     @BeforeEach
     void setUp() {
-        censusCommandValidator = new CensusCommandValidator();
+        censusCommandValidatorImpl = new CensusCommandValidatorImpl();
         stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
         stringArgumentCaptor2 = ArgumentCaptor.forClass(String.class);
         stringArgumentCaptor3 = ArgumentCaptor.forClass(String.class);
@@ -55,7 +55,7 @@ class CensusCommandValidatorTest {
     public void nullDateTest() {
         censusCommand.setPlace(GetRandomPlace());
         censusCommand.setBoundaryType(GetRandomCensusBoundaryType());
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("date", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());
@@ -67,7 +67,7 @@ class CensusCommandValidatorTest {
     public void nullBoundaryTest() {
         censusCommand.setPlace(GetRandomPlace());
         censusCommand.setCensusDate(GetRandomCensusDate());
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("boundaryType", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());
@@ -79,7 +79,7 @@ class CensusCommandValidatorTest {
     public void nullPlaceTest() {
         censusCommand.setCensusDate(GetRandomCensusDate());
         censusCommand.setBoundaryType(GetRandomCensusBoundaryType());
-        censusCommandValidator.validate(censusCommand, bindingResultMock);
+        censusCommandValidatorImpl.validate(censusCommand, bindingResultMock);
         verify(bindingResultMock, atLeast(1)).rejectValue(stringArgumentCaptor.capture(), stringArgumentCaptor2.capture(), objectArgumentCaptor.capture(), stringArgumentCaptor3.capture());
         assertEquals("place", stringArgumentCaptor.getValue());
         assertEquals("", stringArgumentCaptor2.getValue());

+ 71 - 0
src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplBIrthYearAndAgeTest.java

@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 24/03/2025, 09:07. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.validators.census;
+
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.validation.BindingResult;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommandImpl;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.ValidationConstants;
+
+import static org.mockito.Mockito.verify;
+import static scot.carricksoftware.grants.GenerateRandomCensusValues.GetRandomCensus;
+import static scot.carricksoftware.grants.GenerateRandomPeopleValues.GetRandomPerson;
+
+@ExtendWith(MockitoExtension.class)
+class CensusEntryCommandValidatorImplBIrthYearAndAgeTest {
+
+    private CensusEntryCommandValidatorImpl validator;
+
+    private CensusEntryCommand censusEntryCommand;
+
+
+    @Mock
+    BindingResult bindingResultMock;
+
+    @BeforeEach
+    void setUp() {
+        validator = new CensusEntryCommandValidatorImpl();
+        censusEntryCommand = new CensusEntryCommandImpl();
+        censusEntryCommand.setCensus(GetRandomCensus());
+        censusEntryCommand.setPerson(GetRandomPerson());
+    }
+
+    @Test
+    public void BirthYearAndAgeMustNotCoexistTest() {
+        censusEntryCommand.setBirthYear("1880");
+        censusEntryCommand.setAge("80");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthYear", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTH_YEAR_AND_AGE_CANNOT_COEXIST);
+        verify(bindingResultMock).rejectValue("age", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTH_YEAR_AND_AGE_CANNOT_COEXIST);
+    }
+
+    @Test
+    public void BirthDayAndAgeMustNotCoexistTest() {
+        censusEntryCommand.setBirthDay("25/01");
+        censusEntryCommand.setAge("80");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTH_DAY_AND_AGE_CANNOT_COEXIST);
+        verify(bindingResultMock).rejectValue("age", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTH_DAY_AND_AGE_CANNOT_COEXIST);
+    }
+
+
+
+
+
+
+
+
+
+
+
+}

+ 102 - 0
src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplBirthDayTest.java

@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 24/03/2025, 09:07. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.validators.census;
+
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.validation.BindingResult;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommandImpl;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.ValidationConstants;
+
+import static org.mockito.Mockito.verify;
+import static scot.carricksoftware.grants.GenerateRandomCensusValues.GetRandomCensus;
+import static scot.carricksoftware.grants.GenerateRandomPeopleValues.GetRandomPerson;
+
+@ExtendWith(MockitoExtension.class)
+class CensusEntryCommandValidatorImplBirthDayTest {
+
+    private CensusEntryCommandValidatorImpl validator;
+
+    private CensusEntryCommand censusEntryCommand;
+
+
+    @Mock
+    BindingResult bindingResultMock;
+
+    @BeforeEach
+    void setUp() {
+        validator = new CensusEntryCommandValidatorImpl();
+        censusEntryCommand = new CensusEntryCommandImpl();
+        censusEntryCommand.setCensus(GetRandomCensus());
+        censusEntryCommand.setPerson(GetRandomPerson());
+    }
+
+    @Test
+    public void NoSlashTest() {
+        censusEntryCommand.setBirthDay("2501");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+    @Test
+    public void NoPartsTest() {
+        censusEntryCommand.setBirthDay("/");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+    @Test
+    public void NegativeDaysTest() {
+        censusEntryCommand.setBirthDay("-12/85");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+    @Test
+    public void NonValidDaysTest() {
+        censusEntryCommand.setBirthDay("z/85");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+    @Test
+    public void ExcessiveDaysTest() {
+        censusEntryCommand.setBirthDay("55/85");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+    @Test
+    public void NegativeYearsTest() {
+        censusEntryCommand.setBirthDay("11/-7");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+    @Test
+    public void NonValidYearsTest() {
+        censusEntryCommand.setBirthDay("11/zz");
+        validator.validate(censusEntryCommand, bindingResultMock);
+        verify(bindingResultMock).rejectValue("birthDay", ApplicationConstants.EMPTY_STRING, null, ValidationConstants.BIRTHDAY_INCORRECT_FORMAT);
+    }
+
+
+
+
+
+
+
+
+
+
+
+}

+ 3 - 3
src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorBirthYearTest.java → src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplBirthYearTest.java

@@ -21,9 +21,9 @@ import static org.mockito.Mockito.verify;
 import static scot.carricksoftware.grants.GenerateRandomCensusValues.GetRandomCensus;
 
 @ExtendWith(MockitoExtension.class)
-class CensusEntryCommandValidatorBirthYearTest {
+class CensusEntryCommandValidatorImplBirthYearTest {
 
-    private CensusEntryCommandValidator validator;
+    private CensusEntryCommandValidatorImpl validator;
 
     private CensusEntryCommand censusEntryCommand;
 
@@ -33,7 +33,7 @@ class CensusEntryCommandValidatorBirthYearTest {
 
     @BeforeEach
     void setUp() {
-        validator = new CensusEntryCommandValidator();
+        validator = new CensusEntryCommandValidatorImpl();
         censusEntryCommand = new CensusEntryCommandImpl();
         censusEntryCommand.setCensus(GetRandomCensus());
     }

+ 3 - 3
src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorNameTest.java → src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplNameTest.java

@@ -22,9 +22,9 @@ import static org.mockito.Mockito.verifyNoInteractions;
 import static scot.carricksoftware.grants.GenerateRandomCensusValues.GetRandomCensus;
 
 @ExtendWith(MockitoExtension.class)
-class CensusEntryCommandValidatorNameTest {
+class CensusEntryCommandValidatorImplNameTest {
 
-    private CensusEntryCommandValidator validator;
+    private CensusEntryCommandValidatorImpl validator;
 
     private CensusEntryCommand censusEntryCommand;
 
@@ -34,7 +34,7 @@ class CensusEntryCommandValidatorNameTest {
 
     @BeforeEach
     void setUp() {
-        validator = new CensusEntryCommandValidator();
+        validator = new CensusEntryCommandValidatorImpl();
         censusEntryCommand = new CensusEntryCommandImpl();
         censusEntryCommand.setCensus(GetRandomCensus());
     }

+ 3 - 3
src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorTest.java → src/test/java/scot/carricksoftware/grants/validators/census/CensusEntryCommandValidatorImplTest.java

@@ -23,9 +23,9 @@ import static scot.carricksoftware.grants.GenerateRandomCensusValues.GetRandomCe
 import static scot.carricksoftware.grants.GenerateRandomPeopleValues.GetRandomPerson;
 
 @ExtendWith(MockitoExtension.class)
-class CensusEntryCommandValidatorTest {
+class CensusEntryCommandValidatorImplTest {
 
-    private CensusEntryCommandValidator validator;
+    private CensusEntryCommandValidatorImpl validator;
 
     private CensusEntryCommand censusEntryCommand;
 
@@ -34,7 +34,7 @@ class CensusEntryCommandValidatorTest {
 
     @BeforeEach
     void setUp() {
-        validator = new CensusEntryCommandValidator();
+        validator = new CensusEntryCommandValidatorImpl();
         censusEntryCommand = new CensusEntryCommandImpl();
     }
 

+ 1 - 1
src/test/java/scot/carricksoftware/grants/validators/places/CountryCensusCommandValidatorTest.java → src/test/java/scot/carricksoftware/grants/validators/places/CountryCensusCommandValidatorImplTest.java

@@ -22,7 +22,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 
 @ExtendWith(MockitoExtension.class)
-class CountryCensusCommandValidatorTest {
+class CountryCensusCommandValidatorImplTest {
 
     private CountryCommandValidator validator;
 

+ 1 - 1
src/test/java/scot/carricksoftware/grants/validators/places/PlaceCensusCommandValidatorTest.java → src/test/java/scot/carricksoftware/grants/validators/places/PlaceCensusCommandValidatorImplTest.java

@@ -23,7 +23,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 
 @ExtendWith(MockitoExtension.class)
-class PlaceCensusCommandValidatorTest {
+class PlaceCensusCommandValidatorImplTest {
 
     private PlaceCommandValidator validator;
 

+ 1 - 1
src/test/java/scot/carricksoftware/grants/validators/places/RegionCensusCommandValidatorTest.java → src/test/java/scot/carricksoftware/grants/validators/places/RegionCensusCommandValidatorImplTest.java

@@ -23,7 +23,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 
 @ExtendWith(MockitoExtension.class)
-class RegionCensusCommandValidatorTest {
+class RegionCensusCommandValidatorImplTest {
 
     private RegionCommandValidator validator;