diff --git a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/HorseEndpoint.java b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/HorseEndpoint.java index ce2931b..87e97fe 100644 --- a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/HorseEndpoint.java +++ b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/HorseEndpoint.java @@ -61,6 +61,25 @@ public class HorseEndpoint { } } + @PutMapping(value = "/{id}") + @ResponseStatus(HttpStatus.OK) + public HorseDto updateHorse(@PathVariable("id") Long id, @RequestBody HorseDto horse) { + LOGGER.info("PUT " + BASE_URL + "/{}", id); + try { + Horse horseEntity = horseMapper.dtoToEntity(horse); + horseEntity.setId(id); + return horseMapper.entityToDto((horseService.updateHorse(horseEntity))); + } catch (ValidationException e) { + LOGGER.error(e.getMessage()); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, + "Error during updating horse with id " + id + ": " + e.getMessage(), e); + } catch (DataAccessException e) { + LOGGER.error(e.getMessage()); + throw new ResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY, + "Something went wrong during the communication with the database", e); + } + } + @PostMapping(value = "/upload") @ResponseStatus(HttpStatus.CREATED) public void addImage(@RequestParam("file") MultipartFile image) { diff --git a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/HorseDao.java b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/HorseDao.java index 58ea476..eeb4e28 100644 --- a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/HorseDao.java +++ b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/HorseDao.java @@ -20,4 +20,11 @@ public interface HorseDao { * @throws DataAccessException will be thrown if something goes wrong during the database access. */ Horse addHorse(Horse horse); + + /** + * @param horse that specifies the new horse values alongside with the id of the horse to update + * @return the updated horse + * @throws DataAccessException will be thrown if something goes wrong during the database access. + */ + Horse updateHorse(Horse horse); } diff --git a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/impl/HorseJdbcDao.java b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/impl/HorseJdbcDao.java index b37ae2a..c374f40 100644 --- a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/impl/HorseJdbcDao.java +++ b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/impl/HorseJdbcDao.java @@ -4,6 +4,7 @@ import at.ac.tuwien.sepm.assignment.individual.entity.Horse; import at.ac.tuwien.sepm.assignment.individual.enums.ERace; import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException; import at.ac.tuwien.sepm.assignment.individual.persistence.HorseDao; +import at.ac.tuwien.sepm.assignment.individual.util.ValidationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DataAccessException; @@ -54,8 +55,7 @@ public class HorseJdbcDao implements HorseDao { try { // Check if the constraints are violated - if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getRace() == null || horse.getImagePath() == null) - throw new DataIntegrityViolationException("Required parameters for horse missing"); + this.validateHorse(horse); LocalDateTime currentTime = LocalDateTime.now(); @@ -100,6 +100,60 @@ public class HorseJdbcDao implements HorseDao { } } + @Override + public Horse updateHorse(Horse horse) { + LOGGER.trace("Update horse {}", horse.toString()); + String sql = "UPDATE " + TABLE_NAME + " SET name=?, description=?, score=?, birthday=?, race=?, image_path=?, owner_id=?, updated_at=? WHERE id=?"; + + try { + this.validateHorse(horse); + + if(horse.getId() == null || horse.getId() == 0) + throw new DataIntegrityViolationException("Horse Id missing or 0"); + + Horse oldHorse = findOneById(horse.getId()); + LocalDateTime currentTime = LocalDateTime.now(); + + horse.setUpdatedAt(currentTime); + + int changes = jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql); + + ps.setString(1, horse.getName()); + ps.setString(2, horse.getDescription()); + ps.setInt(3, horse.getScore()); + ps.setDate(4, horse.getBirthday()); + ps.setString(5, horse.getRace().toString()); // Convert to string to be able to save in DB + ps.setString(6, horse.getImagePath()); + + if(horse.getOwner() == null || horse.getOwner() == 0) + ps.setNull(7, Types.NULL); + else + ps.setObject(7, horse.getOwner()); + + ps.setObject(8, horse.getUpdatedAt()); + ps.setObject(9, horse.getId()); + return ps; + }); + + if (changes == 0) + throw new NotFoundException("Updating horse failed, no rows affected"); + + horse.setCreatedAt(oldHorse.getCreatedAt()); + return horse; + + } catch (DataAccessException e) { + // We are doing this in order to not change the exception type + throw new DataAccessException("Updating records failed", e) {}; + } catch(NotFoundException e){ + throw new DataRetrievalFailureException("No new records updated", e); + } + } + + private void validateHorse(Horse horse) throws DataIntegrityViolationException { + if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getRace() == null || horse.getImagePath() == null) + throw new DataIntegrityViolationException("Required parameters for horse missing"); + } private Horse mapRow(ResultSet resultSet, int i) throws SQLException { final Horse horse = new Horse(); diff --git a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/HorseService.java b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/HorseService.java index 208753a..c0be2be 100644 --- a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/HorseService.java +++ b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/HorseService.java @@ -2,6 +2,8 @@ package at.ac.tuwien.sepm.assignment.individual.service; import at.ac.tuwien.sepm.assignment.individual.entity.Horse; import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException; +import at.ac.tuwien.sepm.assignment.individual.util.ValidationException; +import org.springframework.dao.DataAccessException; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @@ -17,15 +19,24 @@ public interface HorseService { /** * @param horse to add. - * @return the horse with the specified id. - * @throws RuntimeException will be thrown if something goes wrong during data processing. - * @throws NotFoundException will be thrown if the horse could not be found in the system. + * @return the new horse. + * @throws ValidationException will be thrown if something goes wrong during verification. + * @throws DataAccessException will be thrown if the horse could not be saved in the database. */ Horse addHorse(Horse horse); + /** + * @param horse that specifies the new horse values alongside with the id of the horse to update + * @return the updated horse + * @throws ValidationException will be thrown if something goes wrong during verification. + * @throws DataAccessException will be thrown if the horse could not be saved in the database. + */ + Horse updateHorse(Horse horse); + /** * @param img image to upload * @throws IOException will be thrown if something goes wrong with saving the file + * @throws ValidationException will be thrown if the file is in the incorrect format */ void saveImage(MultipartFile img) throws IOException; } diff --git a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/impl/SimpleHorseService.java b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/impl/SimpleHorseService.java index 96bd78b..c4ee63e 100644 --- a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/impl/SimpleHorseService.java +++ b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/impl/SimpleHorseService.java @@ -43,6 +43,13 @@ public class SimpleHorseService implements HorseService { return horseJdbcDao.addHorse(horse); } + @Override + public Horse updateHorse(Horse horse) { + this.validator.validateUpdateHorse(horse); + LOGGER.trace("updateHorse({})", horse.toString()); + return horseJdbcDao.updateHorse(horse); + } + @Override public void saveImage(MultipartFile img) throws ValidationException, IOException { this.validator.validateHorseImage(img); diff --git a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/util/Validator.java b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/util/Validator.java index 45e1432..6caefe4 100644 --- a/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/util/Validator.java +++ b/backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/util/Validator.java @@ -17,8 +17,23 @@ public class Validator { } public void validateNewHorse(Horse horse) throws ValidationException { - if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getRace() == null){ - throw new ValidationException("All or some required values missing: name, score, birthday, race"); + if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getRace() == null || horse.getImagePath() == null){ + throw new ValidationException("All or some required values missing: name, score, birthday, race, imagePath"); + } + if(horse.getScore() > 5 || horse.getScore() < 1) { + throw new ValidationException("Score value " + horse.getScore() + " not allowed. The score must be an integer between 1 and 5"); + } + if(!horse.getImagePath().endsWith(".png") && !horse.getImagePath().endsWith(".jpg") && !horse.getImagePath().endsWith(".jpeg")) { + throw new ValidationException("Unsupported file type supplied. Supported file types are jpg and png"); + } + } + + public void validateUpdateHorse(Horse horse) throws ValidationException { + if(horse.getId() == null || horse.getId() == 0) { + throw new ValidationException("Horse Id cannot be null or 0"); + } + if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getRace() == null || horse.getImagePath() == null){ + throw new ValidationException("All or some required values missing: name, score, birthday, race. imagePath"); } if(horse.getScore() > 5 || horse.getScore() < 1) { throw new ValidationException("Score value " + horse.getScore() + " not allowed. The score must be an integer between 1 and 5"); diff --git a/backend/src/main/resources/application-test.yml b/backend/src/main/resources/application-test.yml index e69de29..b50b7fc 100644 --- a/backend/src/main/resources/application-test.yml +++ b/backend/src/main/resources/application-test.yml @@ -0,0 +1,27 @@ +logging: + level: + root: INFO + file: + name: ./log/wendys-friends.log + +spring: + application: + name: wendys-friends + datasource: + url: "jdbc:h2:mem:testdb;INIT=RUNSCRIPT FROM 'classpath:sql/createSchema.sql'" + username: "sa" + password: "" + driver-class-name: "org.h2.Driver" + data: sql/insertData.sql + h2: + console: + enabled: true + upload: + path: /tmp/uploads/ + servlet: + multipart: + enabled: true + max-file-size: 10MB + max-request-size: 15MB +server: + port: 8080 diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 1081fcb..8405084 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -12,6 +12,7 @@ spring: username: "sa" password: "" driver-class-name: "org.h2.Driver" + data: sql/insertData.sql h2: console: enabled: true diff --git a/backend/src/main/resources/sql/insertData.sql b/backend/src/main/resources/sql/insertData.sql index 794f9d4..37904dd 100644 --- a/backend/src/main/resources/sql/insertData.sql +++ b/backend/src/main/resources/sql/insertData.sql @@ -5,3 +5,7 @@ VALUES (1, 'Fred', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()), (2, 'Julia', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()), (3, 'Kim', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); +INSERT INTO horse(id, name, description, score, birthday, race, image_path, owner, created_at, updated_at) +VALUES (1, 'Dorian', 'The fastest horse on Earth', 5, PARSEDATETIME('2019-01-01', 'yyyy-MM-dd'), 'ARABIAN', 'dorian.png', 1, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()), + (2, 'Katrina', 'Not slow, but not fast either', 3, PARSEDATETIME('2005-01-01', 'yyyy-MM-dd'), 'MORGAN', 'katrina.png', 2, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()), + (2, 'Andrew', 'Slowest of the bund', 1, PARSEDATETIME('1992-01-01', 'yyyy-MM-dd'), 'APPALOOSA', 'andrew.png', 3, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()) diff --git a/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/integration/HorseEndpointTest.java b/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/integration/HorseEndpointTest.java index ddcea3c..c93c89c 100644 --- a/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/integration/HorseEndpointTest.java +++ b/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/integration/HorseEndpointTest.java @@ -13,6 +13,7 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.http.*; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.event.annotation.AfterTestMethod; +import org.springframework.test.context.jdbc.Sql; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; @@ -35,8 +36,7 @@ public class HorseEndpointTest { @Test @DisplayName("Adding a new horse with the correct parameters will return HTTP 201 and the new HorseDto") public void addingNewHorse_correctParameters_shouldReturnStatus201AndHorse() { - String birthday = "2020-01-01"; - HorseDto newHorse = new HorseDto("Zephyr", "Nice horse", (short) 4, Date.valueOf(birthday), ERace.APPALOOSA, "files/test.png", null); + HorseDto newHorse = new HorseDto("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); HttpEntity request = new HttpEntity<>(newHorse); ResponseEntity response = REST_TEMPLATE @@ -52,6 +52,41 @@ public class HorseEndpointTest { assertEquals(newHorse.getOwner(), response.getBody().getOwner()); } + @Test + @DisplayName("Updating a horse with the correct parameters will return 200 and the new HorseDto") + public void updatingNewHorse_correctParameters_shouldReturnStatus200AndHorse() { + HorseDto newHorse = new HorseDto("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); + + // Create a new horse + HttpEntity request = new HttpEntity<>(newHorse); + ResponseEntity response = REST_TEMPLATE + .exchange(BASE_URL + port + HORSE_URL, HttpMethod.POST, request, HorseDto.class); + + // Update the horse + newHorse.setId(response.getBody().getId()); + newHorse.setName("Katrina"); + newHorse.setDescription("Fast horse"); + newHorse.setScore((short) 3); + newHorse.setBirthday(Date.valueOf("2005-01-01")); + newHorse.setRace(ERace.MORGAN); + newHorse.setImagePath("files/katrina.png"); + newHorse.setOwner(null); + + request = new HttpEntity<>(newHorse); + response = REST_TEMPLATE + .exchange(BASE_URL + port + HORSE_URL + '/' + newHorse.getId(), HttpMethod.PUT, request, HorseDto.class); + + // Compare everything except timestamps + assertEquals(response.getStatusCode(), HttpStatus.OK); + assertEquals(newHorse.getId(), response.getBody().getId()); + assertEquals(newHorse.getName(), response.getBody().getName()); + assertEquals(newHorse.getDescription(), response.getBody().getDescription()); + assertEquals(newHorse.getScore(), response.getBody().getScore()); + assertEquals(newHorse.getBirthday().toString(), response.getBody().getBirthday().toString()); + assertEquals(newHorse.getImagePath(), response.getBody().getImagePath()); + assertEquals(newHorse.getOwner(), response.getBody().getOwner()); + } + @Test @DisplayName("Uploading an image in the correct format will return HTTP 201") public void addingNewImage_correctFormat_shouldReturnStatus201() { diff --git a/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/persistence/HorseDaoTestBase.java b/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/persistence/HorseDaoTestBase.java index 2b66366..d7553c0 100644 --- a/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/persistence/HorseDaoTestBase.java +++ b/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/persistence/HorseDaoTestBase.java @@ -20,8 +20,7 @@ public abstract class HorseDaoTestBase { @Test @DisplayName("Adding a new horse with the correct parameters should return the horse") public void addingNewHorse_correctParameters_shouldReturnHorse() { - String birthday = "2020-01-01"; - Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf(birthday), ERace.APPALOOSA, "files/test.png", null); + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); Horse savedHorse = horseDao.addHorse(newHorse); assertEquals(newHorse, savedHorse); } @@ -29,8 +28,55 @@ public abstract class HorseDaoTestBase { @Test @DisplayName("Adding a new horse with the incorrect parameters should throw DataAccessException") public void addingNewHorse_incorrectParameters_shouldThrowDataAccess() { - String birthday = "2020-01-01"; - Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 80, Date.valueOf(birthday), null, null, null); + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 80, Date.valueOf("2020-01-01"), null, null, null); + assertThrows(DataAccessException.class, () -> horseDao.addHorse(newHorse)); + } + + @Test + @DisplayName("Updating a horse with the correct parameters should return the horse") + public void updatingHorse_correctParameters_shouldReturnHorse() { + // Create horse + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); + Horse savedHorse = horseDao.addHorse(newHorse); + + // Update horse + newHorse.setId(savedHorse.getId()); + newHorse.setName("Katrina"); + newHorse.setDescription("Fast horse"); + newHorse.setScore((short) 3); + newHorse.setBirthday(Date.valueOf("2005-01-01")); + newHorse.setRace(ERace.MORGAN); + newHorse.setImagePath("files/katrina.png"); + newHorse.setOwner(null); + Horse updatedHorse = horseDao.updateHorse(newHorse); + + // Compare everything except updated timestamp + assertEquals(updatedHorse.getId(), newHorse.getId()); + assertEquals(updatedHorse.getName(), newHorse.getName()); + assertEquals(updatedHorse.getDescription(), newHorse.getDescription()); + assertEquals(updatedHorse.getScore(), newHorse.getScore()); + assertEquals(updatedHorse.getBirthday().toString(), newHorse.getBirthday().toString()); + assertEquals(updatedHorse.getImagePath(), newHorse.getImagePath()); + assertEquals(updatedHorse.getOwner(), newHorse.getOwner()); + assertEquals(updatedHorse.getCreatedAt(), newHorse.getCreatedAt()); + } + + @Test + @DisplayName("Updating a horse with the incorrect parameters should throw DataAccessException") + public void updatingHorse_incorrectParameters_shouldThrowDataAccess() { + // Create horse + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); + Horse savedHorse = horseDao.addHorse(newHorse); + + // Update horse + newHorse.setId(savedHorse.getId()); + newHorse.setName("Katrina"); + newHorse.setDescription("Fast horse"); + newHorse.setScore((short) 80); + newHorse.setBirthday(Date.valueOf("2005-01-01")); + newHorse.setRace(null); + newHorse.setImagePath(null); + newHorse.setOwner(null); assertThrows(DataAccessException.class, () -> horseDao.addHorse(newHorse)); } diff --git a/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/service/HorseServiceTest.java b/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/service/HorseServiceTest.java index 11409de..ea71dd0 100644 --- a/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/service/HorseServiceTest.java +++ b/backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/service/HorseServiceTest.java @@ -28,8 +28,7 @@ public class HorseServiceTest { @Test @DisplayName("Adding a new horse with the correct parameters will return the new horse") public void addingNewHorse_correctParameters_shouldReturnHorse() { - String birthday = "2020-01-01"; - Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf(birthday), ERace.APPALOOSA, "files/test.png", null); + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); Horse savedHorse = horseService.addHorse(newHorse); assertEquals(newHorse, savedHorse); } @@ -37,8 +36,55 @@ public class HorseServiceTest { @Test @DisplayName("Adding a new horse with the incorrect parameters will throw a ValidationException") public void addingNewHorse_incorrectParameters_shouldThrowValidation() { - String birthday = "2020-01-01"; - Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 80, Date.valueOf(birthday), null, null, null); + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 80, Date.valueOf("2020-01-01"), null, null, null); assertThrows(ValidationException.class, () -> horseService.addHorse(newHorse)); } + + @Test + @DisplayName("Updating a horse with the correct parameters will return the new horse") + public void updatingHorse_correctParameters_shouldReturnHorse() { + // Create horse + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); + Horse savedHorse = horseService.addHorse(newHorse); + + // Update horse + newHorse.setId(savedHorse.getId()); + newHorse.setName("Katrina"); + newHorse.setDescription("Fast horse"); + newHorse.setScore((short) 3); + newHorse.setBirthday(Date.valueOf("2005-01-01")); + newHorse.setRace(ERace.MORGAN); + newHorse.setImagePath("files/katrina.png"); + newHorse.setOwner(null); + Horse updatedHorse = horseService.updateHorse(newHorse); + + // Compare everything except updated timestamp + assertEquals(updatedHorse.getId(), newHorse.getId()); + assertEquals(updatedHorse.getName(), newHorse.getName()); + assertEquals(updatedHorse.getDescription(), newHorse.getDescription()); + assertEquals(updatedHorse.getScore(), newHorse.getScore()); + assertEquals(updatedHorse.getBirthday().toString(), newHorse.getBirthday().toString()); + assertEquals(updatedHorse.getImagePath(), newHorse.getImagePath()); + assertEquals(updatedHorse.getOwner(), newHorse.getOwner()); + assertEquals(updatedHorse.getCreatedAt(), newHorse.getCreatedAt()); + } + + @Test + @DisplayName("Updating a horse with the incorrect parameters will return the new horse") + public void updatingHorse_incorrectParameters_shouldThrowValidation() { + // Create horse + Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", null); + Horse savedHorse = horseService.addHorse(newHorse); + + // Update horse + newHorse.setId(savedHorse.getId()); + newHorse.setName("Katrina"); + newHorse.setDescription("Fast horse"); + newHorse.setScore((short) 80); + newHorse.setBirthday(Date.valueOf("2005-01-01")); + newHorse.setRace(null); + newHorse.setImagePath(null); + newHorse.setOwner(null); + assertThrows(ValidationException.class, () -> horseService.updateHorse(newHorse)); + } }