Implements DTOs and Services

This commit is contained in:
PEDSF 2020-10-07 19:40:58 +02:00
parent 45e0b07d6f
commit 6d5b55fc10
23 changed files with 111 additions and 83 deletions

View file

@ -45,6 +45,7 @@ class OwnerController {
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
private final OwnerService ownerService;
private final VisitService visitService;
OwnerController(OwnerService ownerService, VisitService visitService) {

View file

@ -45,7 +45,9 @@ class PetController {
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
private final OwnerService ownerService;
private final PetService petService;
private final PetTypeService petTypeService;
PetController(OwnerService ownerService, PetService petService, PetTypeService petTypeService) {
@ -54,7 +56,6 @@ class PetController {
this.petTypeService = petTypeService;
}
@ModelAttribute("types")
public Collection<PetTypeDTO> populatePetTypes() {
return this.petTypeService.findPetTypes();

View file

@ -40,7 +40,6 @@ class VetController {
this.vetService = vetService;
}
@GetMapping("/vets.html")
public String showVetList(Map<String, Object> model) {
// Here we are returning an object of type 'Vets' rather than a collection of Vet

View file

@ -23,7 +23,6 @@ import org.springframework.samples.petclinic.dto.PetDTO;
import org.springframework.samples.petclinic.dto.VisitDTO;
import org.springframework.samples.petclinic.service.PetService;
import org.springframework.samples.petclinic.service.VisitService;
import org.springframework.samples.petclinic.visit.Visit;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
@ -45,6 +44,7 @@ import org.springframework.web.bind.annotation.PostMapping;
class VisitController {
private final VisitService visitService;
private final PetService petService;
VisitController(VisitService visitService, PetService petService) {
@ -52,7 +52,6 @@ class VisitController {
this.petService = petService;
}
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
@ -62,7 +61,7 @@ class VisitController {
* Called before each and every @RequestMapping annotated method. 2 goals: - Make sure
* we always have fresh data - Since we do not use the session scope, make sure that
* Pet object always has an id (Even though id is not part of the form fields)
* @param petId
* @param petId Pet identification
* @return Pet
*/
@ModelAttribute("visit")

View file

@ -18,8 +18,8 @@ package org.springframework.samples.petclinic.dto;
import java.io.Serializable;
/**
* Simple Data Transfert Object with an id property. Used as a base class for DTO
* needing this property.
* Simple Data Transfert Object with an id property. Used as a base class for DTO needing
* this property.
*
* @author Paul-Emmanuel DOS SANTOS FACAO
*/
@ -38,4 +38,5 @@ public class BaseDTO implements Serializable {
public boolean isNew() {
return this.id == null;
}
}

View file

@ -15,10 +15,9 @@
*/
package org.springframework.samples.petclinic.dto;
/**
* Simple Data Transfert Object with a name property to <code>BaseDTO</code>. Used as
* a base class for DTOs needing these properties.
* Simple Data Transfert Object with a name property to <code>BaseDTO</code>. Used as a
* base class for DTOs needing these properties.
*
* @author Paul-Emmanuel DOS SANTOS FACAO
*/

View file

@ -73,7 +73,7 @@ public class OwnerDTO extends PersonDTO {
return this.pets;
}
protected void setPetsInternal(Set<PetDTO> pets) {
public void setPetsInternal(Set<PetDTO> pets) {
this.pets = pets;
}

View file

@ -26,6 +26,7 @@ public class PersonDTO extends BaseDTO {
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
@ -44,4 +45,5 @@ public class PersonDTO extends BaseDTO {
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

View file

@ -18,7 +18,6 @@ package org.springframework.samples.petclinic.dto;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.samples.petclinic.owner.PetType;
import java.time.LocalDate;
import java.util.*;
@ -33,7 +32,7 @@ public class PetDTO extends NamedDTO {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthDate;
private PetType type;
private PetTypeDTO type;
private OwnerDTO owner;
@ -47,11 +46,11 @@ public class PetDTO extends NamedDTO {
return this.birthDate;
}
public PetType getType() {
public PetTypeDTO getType() {
return this.type;
}
public void setType(PetType type) {
public void setType(PetTypeDTO type) {
this.type = type;
}

View file

@ -18,7 +18,6 @@ package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.vet.Vet;
import org.springframework.transaction.annotation.Transactional;
@ -42,6 +41,6 @@ public interface VetRepository extends Repository<Vet, Integer> {
*/
@Transactional(readOnly = true)
@Cacheable("vets")
Collection<Vet> findAll() throws DataAccessException;
Collection<Vet> findAll();
}

View file

@ -17,7 +17,6 @@ package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.visit.Visit;
@ -40,7 +39,7 @@ public interface VisitRepository extends Repository<Visit, Integer> {
* @param visit the <code>Visit</code> to save
* @see BaseEntity#isNew
*/
void save(Visit visit) throws DataAccessException;
void save(Visit visit);
List<Visit> findByPetId(Integer petId);

View file

@ -3,8 +3,13 @@ package org.springframework.samples.petclinic.service;
import java.util.Collection;
public interface BaseService<E, D> {
public E dtoToEntity(D dto);
public D entityToDTO(E entity);
public Collection<D> entitiesToDTOS(Collection<E> entities);
public Collection<E> dtosToEntities(Collection<D> dtos);
}

View file

@ -13,6 +13,7 @@ import java.util.HashSet;
public class OwnerService implements BaseService<Owner, OwnerDTO> {
private final OwnerRepository ownerRepository;
private final ModelMapper modelMapper = new ModelMapper();
public OwnerService(OwnerRepository ownerRepository) {
@ -65,4 +66,5 @@ public class OwnerService implements BaseService<Owner,OwnerDTO>{
Owner owner = ownerRepository.findById(ownerId);
return entityToDTO(owner);
}
}

View file

@ -11,7 +11,9 @@ import java.util.HashSet;
@Service("PetService")
public class PetService implements BaseService<Pet, PetDTO> {
private final PetRepository petRepository;
private final ModelMapper modelMapper = new ModelMapper();
public PetService(PetRepository petRepository) {
@ -60,4 +62,3 @@ public class PetService implements BaseService<Pet,PetDTO>{
}
}

View file

@ -11,7 +11,9 @@ import java.util.HashSet;
@Service("PerTypeService")
public class PetTypeService implements BaseService<PetType, PetTypeDTO> {
private final PetRepository petRepository;
private final ModelMapper modelMapper = new ModelMapper();
public PetTypeService(PetRepository petRepository) {
@ -50,7 +52,6 @@ public class PetTypeService implements BaseService<PetType, PetTypeDTO>{
return entities;
}
public Collection<PetTypeDTO> findPetTypes() {
Collection<PetType> petTypes = petRepository.findPetTypes();
return entitiesToDTOS(petTypes);

View file

@ -10,6 +10,7 @@ import java.util.HashSet;
@Service("SpecialityService")
public class SpecialityService implements BaseService<Specialty, SpecialtyDTO> {
private final ModelMapper modelMapper = new ModelMapper();
@Override
@ -43,4 +44,5 @@ public class SpecialityService implements BaseService<Specialty, SpecialtyDTO> {
return entities;
}
}

View file

@ -13,6 +13,7 @@ import java.util.HashSet;
public class VetService implements BaseService<Vet, VetDTO> {
private final VetRepository vetRepository;
private final ModelMapper modelMapper = new ModelMapper();
public VetService(VetRepository vetRepository) {
@ -51,7 +52,6 @@ public class VetService implements BaseService<Vet,VetDTO>{
return entities;
}
public Collection<VetDTO> findAll() {
Collection<Vet> vets = vetRepository.findAll();
return entitiesToDTOS(vets);

View file

@ -13,6 +13,7 @@ import java.util.HashSet;
public class VisitService implements BaseService<Visit, VisitDTO> {
private final VisitRepository visitRepository;
private final ModelMapper modelMapper = new ModelMapper();
public VisitService(VisitRepository visitRepository) {
@ -65,4 +66,5 @@ public class VisitService implements BaseService<Visit, VisitDTO>{
return visitDTOS;
}
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.samples.petclinic.owner;
package org.springframework.samples.petclinic.controller;
import java.time.LocalDate;
import java.util.Collections;
@ -28,10 +28,12 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.samples.petclinic.controller.OwnerController;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.visit.Visit;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.samples.petclinic.dto.OwnerDTO;
import org.springframework.samples.petclinic.dto.PetDTO;
import org.springframework.samples.petclinic.dto.PetTypeDTO;
import org.springframework.samples.petclinic.dto.VisitDTO;
import org.springframework.samples.petclinic.service.OwnerService;
import org.springframework.samples.petclinic.service.VisitService;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.empty;
@ -59,24 +61,24 @@ class OwnerControllerTests {
private MockMvc mockMvc;
@MockBean
private OwnerRepository owners;
private OwnerService owners;
@MockBean
private VisitRepository visits;
private VisitService visits;
private Owner george;
private OwnerDTO george;
@BeforeEach
void setup() {
george = new Owner();
george = new OwnerDTO();
george.setId(TEST_OWNER_ID);
george.setFirstName("George");
george.setLastName("Franklin");
george.setAddress("110 W. Liberty St.");
george.setCity("Madison");
george.setTelephone("6085551023");
Pet max = new Pet();
PetType dog = new PetType();
PetDTO max = new PetDTO();
PetTypeDTO dog = new PetTypeDTO();
dog.setName("dog");
max.setId(1);
max.setType(dog);
@ -84,7 +86,7 @@ class OwnerControllerTests {
max.setBirthDate(LocalDate.now());
george.setPetsInternal(Collections.singleton(max));
given(this.owners.findById(TEST_OWNER_ID)).willReturn(george);
Visit visit = new Visit();
VisitDTO visit = new VisitDTO();
visit.setDate(LocalDate.now());
given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit));
}
@ -120,7 +122,7 @@ class OwnerControllerTests {
@Test
void testProcessFindFormSuccess() throws Exception {
given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner()));
given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new OwnerDTO()));
mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList"));
}
@ -178,13 +180,13 @@ class OwnerControllerTests {
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
.andExpect(model().attribute("owner", hasProperty("pets", not(empty()))))
.andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher<List<Pet>>() {
.andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher<List<PetDTO>>() {
@Override
public boolean matches(Object item) {
@SuppressWarnings("unchecked")
List<Pet> pets = (List<Pet>) item;
Pet pet = pets.get(0);
List<PetDTO> pets = (List<PetDTO>) item;
PetDTO pet = pets.get(0);
if (pet.getVisits().isEmpty()) {
return false;
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.samples.petclinic.owner;
package org.springframework.samples.petclinic.controller;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@ -32,8 +32,18 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.samples.petclinic.controller.PetController;
import org.springframework.samples.petclinic.dto.OwnerDTO;
import org.springframework.samples.petclinic.dto.PetDTO;
import org.springframework.samples.petclinic.dto.PetTypeDTO;
import org.springframework.samples.petclinic.owner.Owner;
import org.springframework.samples.petclinic.owner.Pet;
import org.springframework.samples.petclinic.owner.PetType;
import org.springframework.samples.petclinic.owner.PetTypeFormatter;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.samples.petclinic.service.OwnerService;
import org.springframework.samples.petclinic.service.PetService;
import org.springframework.samples.petclinic.service.PetTypeService;
import org.springframework.test.web.servlet.MockMvc;
/**
@ -53,19 +63,22 @@ class PetControllerTests {
private MockMvc mockMvc;
@MockBean
private PetRepository pets;
private PetService petService;
@MockBean
private OwnerRepository owners;
private PetTypeService petTypeService;
@MockBean
private OwnerService ownerService;
@BeforeEach
void setup() {
PetType cat = new PetType();
PetTypeDTO cat = new PetTypeDTO();
cat.setId(3);
cat.setName("hamster");
given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat));
given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner());
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
given(this.petTypeService.findPetTypes()).willReturn(Lists.newArrayList(cat));
given(this.ownerService.findById(TEST_OWNER_ID)).willReturn(new OwnerDTO());
given(this.petService.findById(TEST_PET_ID)).willReturn(new PetDTO());
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.samples.petclinic.vet;
package org.springframework.samples.petclinic.controller;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@ -31,8 +31,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.samples.petclinic.controller.VetController;
import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.samples.petclinic.dto.VetDTO;
import org.springframework.samples.petclinic.service.VetService;
import org.springframework.samples.petclinic.vet.Specialty;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
@ -46,15 +47,15 @@ class VetControllerTests {
private MockMvc mockMvc;
@MockBean
private VetRepository vets;
private VetService vetService;
@BeforeEach
void setup() {
Vet james = new Vet();
VetDTO james = new VetDTO();
james.setFirstName("James");
james.setLastName("Carter");
james.setId(1);
Vet helen = new Vet();
VetDTO helen = new VetDTO();
helen.setFirstName("Helen");
helen.setLastName("Leary");
helen.setId(2);
@ -62,7 +63,7 @@ class VetControllerTests {
radiology.setId(1);
radiology.setName("radiology");
helen.addSpecialty(radiology);
given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen));
given(this.vetService.findAll()).willReturn(Lists.newArrayList(james, helen));
}
@Test

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.samples.petclinic.owner;
package org.springframework.samples.petclinic.controller;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@ -28,9 +28,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.samples.petclinic.controller.VisitController;
import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.samples.petclinic.dto.PetDTO;
import org.springframework.samples.petclinic.service.PetService;
import org.springframework.samples.petclinic.service.VisitService;
import org.springframework.test.web.servlet.MockMvc;
/**
@ -47,14 +47,14 @@ class VisitControllerTests {
private MockMvc mockMvc;
@MockBean
private VisitRepository visits;
private VisitService visitService;
@MockBean
private PetRepository pets;
private PetService petService;
@BeforeEach
void init() {
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
given(this.petService.findById(TEST_PET_ID)).willReturn(new PetDTO());
}
@Test

View file

@ -112,10 +112,10 @@ class ClinicServiceTests {
owner.setCity("Wollongong");
owner.setTelephone("4444444444");
this.owners.save(owner);
assertThat(owner.getId().longValue()).isNotEqualTo(0);
assertThat(owner.getId().longValue()).isNotZero();
owners = this.owners.findByLastName("Schultz");
assertThat(owners.size()).isEqualTo(found + 1);
assertThat(owners).hasSize(found + 1);
}
@Test
@ -176,7 +176,7 @@ class ClinicServiceTests {
@Test
@Transactional
void shouldUpdatePetName() throws Exception {
void shouldUpdatePetName() {
Pet pet7 = this.pets.findById(7);
String oldName = pet7.getName();
@ -216,7 +216,7 @@ class ClinicServiceTests {
}
@Test
void shouldFindVisitsByPetId() throws Exception {
void shouldFindVisitsByPetId() {
Collection<Visit> visits = this.visits.findByPetId(7);
assertThat(visits).hasSize(2);
Visit[] visitArr = visits.toArray(new Visit[visits.size()]);