Commit 89e5f798 authored by Ivaylo Ivanov's avatar Ivaylo Ivanov

US10: Add a method to the owner API that allows the user to get the horses...

US10: Add a method to the owner API that allows the user to get the horses owned by a specific owner
parent 9b1f7bcf
package at.ac.tuwien.sepm.assignment.individual.endpoint; package at.ac.tuwien.sepm.assignment.individual.endpoint;
import at.ac.tuwien.sepm.assignment.individual.endpoint.dto.HorseDto;
import at.ac.tuwien.sepm.assignment.individual.endpoint.dto.OwnerDto; import at.ac.tuwien.sepm.assignment.individual.endpoint.dto.OwnerDto;
import at.ac.tuwien.sepm.assignment.individual.endpoint.mapper.HorseMapper;
import at.ac.tuwien.sepm.assignment.individual.endpoint.mapper.OwnerMapper; import at.ac.tuwien.sepm.assignment.individual.endpoint.mapper.OwnerMapper;
import at.ac.tuwien.sepm.assignment.individual.entity.Owner; import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException; import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
...@@ -28,11 +30,13 @@ public class OwnerEndpoint { ...@@ -28,11 +30,13 @@ public class OwnerEndpoint {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final OwnerService ownerService; private final OwnerService ownerService;
private final OwnerMapper ownerMapper; private final OwnerMapper ownerMapper;
private final HorseMapper horseMapper;
@Autowired @Autowired
public OwnerEndpoint(OwnerService ownerService, OwnerMapper ownerMapper) { public OwnerEndpoint(OwnerService ownerService, OwnerMapper ownerMapper, HorseMapper horseMapper) {
this.ownerService = ownerService; this.ownerService = ownerService;
this.ownerMapper = ownerMapper; this.ownerMapper = ownerMapper;
this.horseMapper = horseMapper;
} }
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
...@@ -65,6 +69,18 @@ public class OwnerEndpoint { ...@@ -65,6 +69,18 @@ public class OwnerEndpoint {
} }
} }
@GetMapping(value="/{id}/horses")
@ResponseStatus(HttpStatus.OK)
public List<HorseDto> getOwnedHorses(@PathVariable("id") Long id) {
LOGGER.info("GET " + BASE_URL + "/{}/horses", id);
try {
return horseMapper.entityListToDtoList(ownerService.getOwnedHorses(id));
} catch (NotFoundException e) {
LOGGER.error(e.getMessage());
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Either the owner does not exist or has no horses assigned");
}
}
@PostMapping @PostMapping
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
public OwnerDto addOwner(@RequestBody OwnerDto owner) { public OwnerDto addOwner(@RequestBody OwnerDto owner) {
......
package at.ac.tuwien.sepm.assignment.individual.persistence; package at.ac.tuwien.sepm.assignment.individual.persistence;
import at.ac.tuwien.sepm.assignment.individual.entity.Horse;
import at.ac.tuwien.sepm.assignment.individual.entity.Owner; import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException; import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
...@@ -32,6 +33,14 @@ public interface OwnerDao { ...@@ -32,6 +33,14 @@ public interface OwnerDao {
*/ */
List<Owner> getFiltered(Map<String, String> filters) throws NotFoundException; List<Owner> getFiltered(Map<String, String> filters) throws NotFoundException;
/**
* @param id of the owner whose horses the database should obtain
* @return a list of all horses that the specified owner owns
* @throws NotFoundException will be thrown if the owner owns no horses or if the owner could not be found
* @throws DataAccessException will be thrown if something goes wrong during the database access
*/
List<Horse> getOwnedHorses(Long id) throws NotFoundException;
/** /**
* @param owner that specifies the owner to add * @param owner that specifies the owner to add
* @return the newly created owner * @return the newly created owner
......
...@@ -94,6 +94,18 @@ public class OwnerJdbcDao implements OwnerDao { ...@@ -94,6 +94,18 @@ public class OwnerJdbcDao implements OwnerDao {
return owners; return owners;
} }
@Override
public List<Horse> getOwnedHorses(Long id) throws NotFoundException {
LOGGER.trace("Get all horses for owner with id " + id);
final String sql = "SELECT * FROM " + HORSE_TABLE_NAME + " WHERE owner_id=?";
List<Horse> horses = jdbcTemplate.query(sql, new Object[] {id}, BeanPropertyRowMapper.newInstance(Horse.class));
if (horses.isEmpty()) throw new NotFoundException("Could not find horses for owner with id " + id);
return horses;
}
@Override @Override
public Owner addOwner(Owner owner) { public Owner addOwner(Owner owner) {
LOGGER.trace("Add owner {}", owner); LOGGER.trace("Add owner {}", owner);
......
package at.ac.tuwien.sepm.assignment.individual.service; package at.ac.tuwien.sepm.assignment.individual.service;
import at.ac.tuwien.sepm.assignment.individual.entity.Horse;
import at.ac.tuwien.sepm.assignment.individual.entity.Owner; import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException; import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
import at.ac.tuwien.sepm.assignment.individual.util.ValidationException; import at.ac.tuwien.sepm.assignment.individual.util.ValidationException;
...@@ -33,6 +34,14 @@ public interface OwnerService { ...@@ -33,6 +34,14 @@ public interface OwnerService {
*/ */
List<Owner> getFiltered(Map<String, String> filters) throws NotFoundException, ValidationException; List<Owner> getFiltered(Map<String, String> filters) throws NotFoundException, ValidationException;
/**
* @param id of the owner whose horses the database should obtain
* @return a list of all horses that the specified owner owns
* @throws NotFoundException will be thrown if the owner owns no horses or if the owner could not be found
* @throws DataAccessException will be thrown if something goes wrong during the database access
*/
List<Horse> getOwnedHorses(Long id) throws NotFoundException;
/** /**
* @param owner to create * @param owner to create
* @return the new owner * @return the new owner
......
package at.ac.tuwien.sepm.assignment.individual.service.impl; package at.ac.tuwien.sepm.assignment.individual.service.impl;
import at.ac.tuwien.sepm.assignment.individual.entity.Horse;
import at.ac.tuwien.sepm.assignment.individual.entity.Owner; import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException; import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
import at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao; import at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao;
...@@ -49,6 +50,12 @@ public class SimpleOwnerService implements OwnerService { ...@@ -49,6 +50,12 @@ public class SimpleOwnerService implements OwnerService {
return ownerDao.getFiltered(filters); return ownerDao.getFiltered(filters);
} }
@Override
public List<Horse> getOwnedHorses(Long id) throws NotFoundException {
LOGGER.trace("getOwnedHorses({})", id);
return ownerDao.getOwnedHorses(id);
}
@Override @Override
public Owner addOwner(Owner owner) throws ValidationException, DataAccessException { public Owner addOwner(Owner owner) throws ValidationException, DataAccessException {
LOGGER.trace("addOwner({})", owner); LOGGER.trace("addOwner({})", owner);
......
...@@ -118,6 +118,46 @@ public class OwnerEndpointTest { ...@@ -118,6 +118,46 @@ public class OwnerEndpointTest {
.exchange(builder.toUriString(), HttpMethod.GET, null, new ParameterizedTypeReference<OwnerDto>() {})); .exchange(builder.toUriString(), HttpMethod.GET, null, new ParameterizedTypeReference<OwnerDto>() {}));
} }
@Test
@DisplayName("Getting horses of an owner with one horse should return HTTP 200 and the horse")
public void gettingHorsesOfOwner_oneHorseAssigned_shouldReturnStatus200AndHorse() {
// Create the owner
OwnerDto newOwner = new OwnerDto("Chad");
HttpEntity<OwnerDto> request = new HttpEntity<>(newOwner);
OwnerDto savedOwner = REST_TEMPLATE
.exchange(BASE_URL + port + OWNER_URL, HttpMethod.POST, request, OwnerDto.class).getBody();
// Create the horse
HorseDto newHorse = new HorseDto("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", savedOwner.getId());
request = new HttpEntity(newHorse);
ResponseEntity<HorseDto> savedHorse = REST_TEMPLATE.exchange(BASE_URL + port + HORSE_URL, HttpMethod.POST, request, HorseDto.class);
ResponseEntity<List<HorseDto>> allHorses = REST_TEMPLATE
.exchange(BASE_URL + port + OWNER_URL + "/" + savedOwner.getId() + "/horses", HttpMethod.GET, null, new ParameterizedTypeReference<List<HorseDto>>() {});
// Temporary, until db mapping is fixed
savedHorse.getBody().setOwner(null);
assertEquals(allHorses.getStatusCode(), HttpStatus.OK);
assertTrue(allHorses.getBody().contains(savedHorse.getBody()));
}
@Test
@DisplayName("Getting horses of an owner without horses should return HTTP 404")
public void gettingHorsesOfOwner_noHorsesAssigned_shouldReturnStatus404() {
// Create the owner
OwnerDto newOwner = new OwnerDto("Chad");
HttpEntity<OwnerDto> request = new HttpEntity<>(newOwner);
OwnerDto savedOwner = REST_TEMPLATE
.exchange(BASE_URL + port + OWNER_URL, HttpMethod.POST, request, OwnerDto.class).getBody();
assertThrows(HttpClientErrorException.NotFound.class, () -> REST_TEMPLATE
.exchange(BASE_URL + port + OWNER_URL + "/" + savedOwner.getId() + "/horses", HttpMethod.GET, null, new ParameterizedTypeReference<List<HorseDto>>() {}));
}
@Test @Test
@DisplayName("Adding a new owner with the correct parameters will return HTTP 201 and the new OwnerDto") @DisplayName("Adding a new owner with the correct parameters will return HTTP 201 and the new OwnerDto")
public void addingNewOwner_correctParameters_shouldReturnStatus201AndOwner() { public void addingNewOwner_correctParameters_shouldReturnStatus201AndOwner() {
...@@ -157,7 +197,7 @@ public class OwnerEndpointTest { ...@@ -157,7 +197,7 @@ public class OwnerEndpointTest {
} }
@Test @Test
@DisplayName("Deleting an existing owner without owners will return HTTP 204") @DisplayName("Deleting an existing owner without horses will return HTTP 204")
public void deletingOwner_existingNoOwnersOwned_shouldReturnStatus204() { public void deletingOwner_existingNoOwnersOwned_shouldReturnStatus204() {
// Create the owner // Create the owner
OwnerDto newOwner = new OwnerDto("Chad"); OwnerDto newOwner = new OwnerDto("Chad");
......
...@@ -77,6 +77,28 @@ public abstract class OwnerDaoTestBase { ...@@ -77,6 +77,28 @@ public abstract class OwnerDaoTestBase {
() -> ownerDao.findOneById(0L)); () -> ownerDao.findOneById(0L));
} }
@Test
@DisplayName("Getting horses of owner with one horse should return the Horse")
public void gettingHorsesOfOwner_oneHorseAssigned_shouldReturnHorse() {
Owner savedOwner = ownerDao.addOwner(new Owner("Brad"));
// Create the horse
Horse newHorse = new Horse("Zephyr", "Nice horse", (short) 4, Date.valueOf("2020-01-01"), ERace.APPALOOSA, "files/test.png", savedOwner.getId());
Horse savedHorse = horseDao.addHorse(newHorse);
// Temporary, until the database mapping is fixed
savedHorse.setOwner(null);
assertTrue(ownerDao.getOwnedHorses(savedOwner.getId()).contains(newHorse));
}
@Test
@DisplayName("Getting horses of owner without horses should throw NotFoundException")
public void gettingHorsesOfOwner_noHorsesAssigned_shouldThrowNotFound() {
Owner savedOwner = ownerDao.addOwner(new Owner("Brad"));
assertThrows(NotFoundException.class, () -> ownerDao.getOwnedHorses(savedOwner.getId()));
}
@Test @Test
@DisplayName("Adding a new owner with the correct parameters should return the owner") @DisplayName("Adding a new owner with the correct parameters should return the owner")
public void addingNewOwner_correctParameters_shouldReturnOwner() { public void addingNewOwner_correctParameters_shouldReturnOwner() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment