US02: Make it possible for the user to assign a race to a horse

This commit is contained in:
Ivaylo Ivanov 2020-03-18 20:39:02 +01:00
parent 01268263de
commit 98d555327e
10 changed files with 88 additions and 23 deletions

View File

@ -1,5 +1,7 @@
package at.ac.tuwien.sepm.assignment.individual.endpoint.dto;
import at.ac.tuwien.sepm.assignment.individual.enums.ERace;
import java.time.LocalDateTime;
import java.util.Objects;
import java.sql.Date;
@ -10,25 +12,28 @@ public class HorseDto extends BaseDto {
private String name;
private String description;
private short score;
private ERace race;
private Date birthday;
private Long owner;
public HorseDto() {}
public HorseDto(String name, String description, short score, Date birthday, Long owner) {
public HorseDto(String name, String description, short score, Date birthday, ERace race, Long owner) {
this.name = name;
this.description = description;
this.score = score;
this.birthday = birthday;
this.race = race;
this.owner = owner;
}
public HorseDto(Long id, String name, String description, short score, Date birthday, LocalDateTime created, LocalDateTime updated, Long owner) {
public HorseDto(Long id, String name, String description, short score, Date birthday, ERace race, LocalDateTime created, LocalDateTime updated, Long owner) {
super(id, created, updated);
this.name = name;
this.description = description;
this.score = score;
this.birthday = birthday;
this.race = race;
this.owner = owner;
}
@ -64,6 +69,14 @@ public class HorseDto extends BaseDto {
this.birthday = birthday;
}
public ERace getRace() {
return race;
}
public void setRace(ERace race) {
this.race = race;
}
public Long getOwner() {
return owner;
}
@ -77,8 +90,13 @@ public class HorseDto extends BaseDto {
if (this == o) return true;
if (!(o instanceof HorseDto)) return false;
if (!super.equals(o)) return false;
HorseDto horseDto = (HorseDto) o;
return Objects.equals(name, horseDto.name);
HorseDto h = (HorseDto) o;
return Objects.equals(name, h.name) &&
Objects.equals(description, h.description) &&
Objects.equals(score, h.score) &&
Objects.equals(birthday, h.birthday) &&
Objects.equals(race, h.race) &&
Objects.equals(owner, h.owner);
}
@Override
@ -94,6 +112,7 @@ public class HorseDto extends BaseDto {
", description='" + description + '\'' +
", score='" + score + '\'' +
", birthday='" + df.format(birthday) + '\'' +
", race='" + race + '\'' +
", owner_id='" + owner + '\'';
}

View File

@ -8,10 +8,10 @@ import org.springframework.stereotype.Component;
@Component
public class HorseMapper {
public HorseDto entityToDto(Horse horse) {
return new HorseDto(horse.getId(), horse.getName(), horse.getDescription(), horse.getScore(), horse.getBirthday(), horse.getCreatedAt(), horse.getUpdatedAt(), horse.getOwner());
return new HorseDto(horse.getId(), horse.getName(), horse.getDescription(), horse.getScore(), horse.getBirthday(), horse.getRace(), horse.getCreatedAt(), horse.getUpdatedAt(), horse.getOwner());
}
public Horse dtoToEntity(HorseDto horse) {
return new Horse(horse.getId(), horse.getName(), horse.getDescription(), horse.getScore(), horse.getBirthday(), horse.getOwner());
return new Horse(horse.getId(), horse.getName(), horse.getDescription(), horse.getScore(), horse.getBirthday(), horse.getRace(), horse.getOwner());
}
}

View File

@ -5,39 +5,44 @@ import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.sql.Date;
import java.util.Objects;
import at.ac.tuwien.sepm.assignment.individual.enums.ERace;
public class Horse extends BaseEntity {
private String name;
private String description;
private short score;
private ERace race;
private Date birthday;
private Long owner;
public Horse() {}
public Horse(String name, String description, short score, Date birthday, Long owner) {
public Horse(String name, String description, short score, Date birthday, ERace race,Long owner) {
this.name = name;
this.description = description;
this.score = score;
this.birthday = birthday;
this.race = race;
this.owner = owner;
}
public Horse(Long id, String name, String description, short score, Date birthday, Long owner) {
public Horse(Long id, String name, String description, short score, Date birthday, ERace race, Long owner) {
super(id);
this.name = name;
this.description = description;
this.score = score;
this.birthday = birthday;
this.race = race;
this.owner = owner;
}
public Horse(Long id, String name, String description, short score, Date birthday, Long owner, LocalDateTime created, LocalDateTime updated) {
public Horse(Long id, String name, String description, short score, Date birthday, ERace race, Long owner, LocalDateTime created, LocalDateTime updated) {
super(id, created, updated);
this.name = name;
this.description = description;
this.score = score;
this.birthday = birthday;
this.race = race;
this.owner = owner;
}
@ -73,6 +78,14 @@ public class Horse extends BaseEntity {
this.birthday = birthday;
}
public ERace getRace() {
return race;
}
public void setRace(ERace race) {
this.race = race;
}
public Long getOwner() {
return owner;
}
@ -86,8 +99,13 @@ public class Horse extends BaseEntity {
if (this == o) return true;
if (!(o instanceof Horse)) return false;
if (!super.equals(o)) return false;
Horse Horse = (Horse) o;
return Objects.equals(name, Horse.name);
Horse h = (Horse) o;
return Objects.equals(name, h.name) &&
Objects.equals(description, h.description) &&
Objects.equals(score, h.score) &&
Objects.equals(birthday, h.birthday) &&
Objects.equals(race, h.race) &&
Objects.equals(owner, h.owner);
}
@Override
@ -103,6 +121,7 @@ public class Horse extends BaseEntity {
"description='" + description + '\'' +
", score='" + score + '\'' +
", birthday='" + df.format(birthday) + '\'' +
", race='" + race + '\'' +
", owner='" + owner + '\'';
}

View File

@ -1,11 +1,13 @@
package at.ac.tuwien.sepm.assignment.individual.persistence.impl;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
@ -48,9 +50,13 @@ public class HorseJdbcDao implements HorseDao {
@Override
public Horse addHorse(Horse horse) throws DataAccessException {
LOGGER.trace("Add horse {}", horse.toString());
String sql = "INSERT INTO " + TABLE_NAME + "(name, description, score, birthday, owner_id, created_at, updated_at) VALUES(?, ?, ?, ?, ?, ?, ?)";
String sql = "INSERT INTO " + TABLE_NAME + "(name, description, score, birthday, race, owner_id, created_at, updated_at) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
try {
// Check if the constraints are violated
if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getRace() == null)
throw new DataIntegrityViolationException("Required parameters for horse missing");
LocalDateTime currentTime = LocalDateTime.now();
horse.setCreatedAt(currentTime);
@ -61,18 +67,20 @@ public class HorseJdbcDao implements HorseDao {
int changes = jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
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
if(horse.getOwner() == null || horse.getOwner() == 0)
ps.setNull(5, Types.NULL);
ps.setNull(6, Types.NULL);
else
ps.setObject(5, horse.getOwner());
ps.setObject(6, horse.getOwner());
ps.setObject(6, horse.getCreatedAt());
ps.setObject(7, horse.getUpdatedAt());
ps.setObject(7, horse.getCreatedAt());
ps.setObject(8, horse.getUpdatedAt());
return ps;
}, keyHolder);
@ -97,7 +105,10 @@ public class HorseJdbcDao implements HorseDao {
horse.setDescription(resultSet.getString("description"));
horse.setScore(resultSet.getShort("score"));
horse.setBirthday(resultSet.getDate("birthday"));
horse.setRace(ERace.valueOf(resultSet.getString("race"))); // Convert to Enum for usage in objects
horse.setOwner(resultSet.getLong("owner_id"));
horse.setCreatedAt(resultSet.getTimestamp("created_at").toLocalDateTime());
horse.setUpdatedAt(resultSet.getTimestamp("updated_at").toLocalDateTime());
return horse;
}
}

View File

@ -16,8 +16,8 @@ public class Validator {
}
public void validateNewHorse(Horse horse) throws ValidationException {
if(horse.getName() == null || horse.getScore() == 0 || horse.getBirthday() == null || horse.getDescription() == null){
throw new ValidationException("All or some required values missing: name, description, score, birthday");
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.getScore() > 5 || horse.getScore() < 1) {
throw new ValidationException("Score value " + horse.getScore() + " not allowed. The score must be an integer between 1 and 5");

View File

@ -6,6 +6,9 @@ CREATE TABLE IF NOT EXISTS owner
updated_at DATETIME NOT NULL
);
-- Create enum for the race
CREATE TYPE IF NOT EXISTS RACE AS ENUM('ARABIAN', 'MORGAN', 'PAINT', 'APPALOOSA');
CREATE TABLE IF NOT EXISTS horse
(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
@ -13,9 +16,11 @@ CREATE TABLE IF NOT EXISTS horse
description TEXT,
score TINYINT NOT NULL CHECK(score >= 1 AND score <= 5),
birthday DATE NOT NULL,
race RACE NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
-- Add nullable owner foreign key
ALTER TABLE horse ADD IF NOT EXISTS owner_id BIGINT NULL;
ALTER TABLE horse ADD CONSTRAINT IF NOT EXISTS FL_OWNER FOREIGN KEY (owner_id) REFERENCES owner(id);

View File

@ -3,6 +3,7 @@ package at.ac.tuwien.sepm.assignment.individual.integration;
import static org.junit.jupiter.api.Assertions.*;
import at.ac.tuwien.sepm.assignment.individual.endpoint.dto.HorseDto;
import at.ac.tuwien.sepm.assignment.individual.enums.ERace;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@ -30,7 +31,7 @@ public class HorseEndpointTest {
@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), null);
HorseDto newHorse = new HorseDto("Zephyr", "Nice horse", (short) 4, Date.valueOf(birthday), ERace.APPALOOSA, null);
HttpEntity<HorseDto> request = new HttpEntity<>(newHorse);
ResponseEntity<HorseDto> response = REST_TEMPLATE

View File

@ -3,6 +3,7 @@ package at.ac.tuwien.sepm.assignment.individual.unit.persistence;
import static org.junit.jupiter.api.Assertions.*;
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.persistence.HorseDao;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -20,7 +21,7 @@ public abstract class HorseDaoTestBase {
@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), null);
Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf(birthday), ERace.APPALOOSA, null);
Horse savedHorse = horseDao.addHorse(newHorse);
assertEquals(newHorse, savedHorse);
}
@ -29,7 +30,7 @@ public abstract class HorseDaoTestBase {
@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);
Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 80, Date.valueOf(birthday), null, null);
assertThrows(DataAccessException.class, () -> horseDao.addHorse(newHorse));
}

View File

@ -3,6 +3,7 @@ package at.ac.tuwien.sepm.assignment.individual.unit.service;
import static org.junit.jupiter.api.Assertions.*;
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.service.HorseService;
import at.ac.tuwien.sepm.assignment.individual.util.ValidationException;
import org.junit.jupiter.api.DisplayName;
@ -28,7 +29,7 @@ public class HorseServiceTest {
@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), null);
Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf(birthday), ERace.APPALOOSA, null);
Horse savedHorse = horseService.addHorse(newHorse);
assertEquals(newHorse, savedHorse);
}
@ -37,7 +38,7 @@ public class HorseServiceTest {
@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);
Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 80, Date.valueOf(birthday), null, null);
assertThrows(ValidationException.class, () -> horseService.addHorse(newHorse));
}
}

View File

@ -5,6 +5,14 @@ export class Horse {
public description: string,
public score: number,
public birthday: Date,
public race: ERace,
public owner: number) {
}
}
enum ERace {
ARABIAN,
MORGAN,
PAINT,
APPALOOSA
}