From 45e0b07d6ff25d3236e0ca6dcd99a9025fd0803c Mon Sep 17 00:00:00 2001 From: PEDSF Date: Wed, 7 Oct 2020 19:12:37 +0200 Subject: [PATCH 01/16] Implements DTOs and Services --- pom.xml | 7 + .../OwnerController.java | 46 ++++--- .../{owner => controller}/PetController.java | 50 ++++--- .../{vet => controller}/VetController.java | 23 ++-- .../VisitController.java | 32 +++-- .../samples/petclinic/dto/BaseDTO.java | 41 ++++++ .../samples/petclinic/dto/NamedDTO.java | 42 ++++++ .../samples/petclinic/dto/OwnerDTO.java | 130 ++++++++++++++++++ .../samples/petclinic/dto/PersonDTO.java | 47 +++++++ .../samples/petclinic/dto/PetDTO.java | 88 ++++++++++++ .../samples/petclinic/dto/PetTypeDTO.java | 10 ++ .../samples/petclinic/dto/SpecialtyDTO.java | 12 ++ .../samples/petclinic/dto/VetDTO.java | 60 ++++++++ .../samples/petclinic/dto/VetsDTO.java | 37 +++++ .../samples/petclinic/dto/VisitDTO.java | 68 +++++++++ .../petclinic/owner/PetTypeFormatter.java | 1 + .../OwnerRepository.java | 3 +- .../{owner => repository}/PetRepository.java | 4 +- .../{vet => repository}/VetRepository.java | 3 +- .../VisitRepository.java | 3 +- .../petclinic/service/BaseService.java | 10 ++ .../petclinic/service/OwnerService.java | 68 +++++++++ .../samples/petclinic/service/PetService.java | 63 +++++++++ .../petclinic/service/PetTypeService.java | 59 ++++++++ .../petclinic/service/SpecialityService.java | 46 +++++++ .../samples/petclinic/service/VetService.java | 60 ++++++++ .../petclinic/service/VisitService.java | 68 +++++++++ .../petclinic/PetclinicIntegrationTests.java | 2 +- .../petclinic/owner/OwnerControllerTests.java | 4 +- .../petclinic/owner/PetControllerTests.java | 3 + .../owner/PetTypeFormatterTests.java | 1 + .../petclinic/owner/VisitControllerTests.java | 4 +- .../petclinic/service/ClinicServiceTests.java | 8 +- .../petclinic/vet/VetControllerTests.java | 2 + 34 files changed, 1030 insertions(+), 75 deletions(-) rename src/main/java/org/springframework/samples/petclinic/{owner => controller}/OwnerController.java (73%) rename src/main/java/org/springframework/samples/petclinic/{owner => controller}/PetController.java (60%) rename src/main/java/org/springframework/samples/petclinic/{vet => controller}/VetController.java (69%) rename src/main/java/org/springframework/samples/petclinic/{owner => controller}/VisitController.java (72%) create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java create mode 100644 src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java rename src/main/java/org/springframework/samples/petclinic/{owner => repository}/OwnerRepository.java (95%) rename src/main/java/org/springframework/samples/petclinic/{owner => repository}/PetRepository.java (91%) rename src/main/java/org/springframework/samples/petclinic/{vet => repository}/VetRepository.java (93%) rename src/main/java/org/springframework/samples/petclinic/{visit => repository}/VisitRepository.java (93%) create mode 100644 src/main/java/org/springframework/samples/petclinic/service/BaseService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/OwnerService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/PetService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/VetService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/VisitService.java diff --git a/pom.xml b/pom.xml index e4e74747a..ed213a1ef 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,13 @@ + + + org.modelmapper.extensions + modelmapper-spring + 2.3.0 + + com.h2database diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java similarity index 73% rename from src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java rename to src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 79aa4cd9b..35ac779e1 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.controller; -import org.springframework.samples.petclinic.visit.VisitRepository; +import org.springframework.samples.petclinic.dto.*; +import org.springframework.samples.petclinic.service.OwnerService; +import org.springframework.samples.petclinic.service.VisitService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -35,19 +37,19 @@ import java.util.Map; * @author Ken Krebs * @author Arjen Poutsma * @author Michael Isvy + * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller class OwnerController { private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; - private final OwnerRepository owners; + private final OwnerService ownerService; + private final VisitService visitService; - private VisitRepository visits; - - public OwnerController(OwnerRepository clinicService, VisitRepository visits) { - this.owners = clinicService; - this.visits = visits; + OwnerController(OwnerService ownerService, VisitService visitService) { + this.ownerService = ownerService; + this.visitService = visitService; } @InitBinder @@ -57,30 +59,30 @@ class OwnerController { @GetMapping("/owners/new") public String initCreationForm(Map model) { - Owner owner = new Owner(); + OwnerDTO owner = new OwnerDTO(); model.put("owner", owner); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } @PostMapping("/owners/new") - public String processCreationForm(@Valid Owner owner, BindingResult result) { + public String processCreationForm(@Valid OwnerDTO owner, BindingResult result) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } else { - this.owners.save(owner); + this.ownerService.save(owner); return "redirect:/owners/" + owner.getId(); } } @GetMapping("/owners/find") public String initFindForm(Map model) { - model.put("owner", new Owner()); + model.put("owner", new OwnerDTO()); return "owners/findOwners"; } @GetMapping("/owners") - public String processFindForm(Owner owner, BindingResult result, Map model) { + public String processFindForm(OwnerDTO owner, BindingResult result, Map model) { // allow parameterless GET request for /owners to return all records if (owner.getLastName() == null) { @@ -88,7 +90,7 @@ class OwnerController { } // find owners by last name - Collection results = this.owners.findByLastName(owner.getLastName()); + Collection results = this.ownerService.findByLastName(owner.getLastName()); if (results.isEmpty()) { // no owners found result.rejectValue("lastName", "notFound", "not found"); @@ -108,20 +110,20 @@ class OwnerController { @GetMapping("/owners/{ownerId}/edit") public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { - Owner owner = this.owners.findById(ownerId); - model.addAttribute(owner); + OwnerDTO ownerDTO = this.ownerService.findById(ownerId); + model.addAttribute(ownerDTO); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } @PostMapping("/owners/{ownerId}/edit") - public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, + public String processUpdateOwnerForm(@Valid OwnerDTO owner, BindingResult result, @PathVariable("ownerId") int ownerId) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } else { owner.setId(ownerId); - this.owners.save(owner); + this.ownerService.save(owner); return "redirect:/owners/{ownerId}"; } } @@ -134,10 +136,12 @@ class OwnerController { @GetMapping("/owners/{ownerId}") public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { ModelAndView mav = new ModelAndView("owners/ownerDetails"); - Owner owner = this.owners.findById(ownerId); - for (Pet pet : owner.getPets()) { - pet.setVisitsInternal(visits.findByPetId(pet.getId())); + OwnerDTO owner = this.ownerService.findById(ownerId); + + for (PetDTO petDTO : owner.getPets()) { + petDTO.setVisitsInternal(visitService.findByPetId(petDTO.getId())); } + mav.addObject(owner); return mav; } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java similarity index 60% rename from src/main/java/org/springframework/samples/petclinic/owner/PetController.java rename to src/main/java/org/springframework/samples/petclinic/controller/PetController.java index a55e599af..b8f6b945b 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -13,8 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.controller; +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.PetValidator; +import org.springframework.samples.petclinic.service.OwnerService; +import org.springframework.samples.petclinic.service.PetService; +import org.springframework.samples.petclinic.service.PetTypeService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; @@ -29,6 +36,7 @@ import java.util.Collection; * @author Juergen Hoeller * @author Ken Krebs * @author Arjen Poutsma + * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller @RequestMapping("/owners/{ownerId}") @@ -36,23 +44,25 @@ class PetController { private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - private final PetRepository pets; + private final OwnerService ownerService; + private final PetService petService; + private final PetTypeService petTypeService; - private final OwnerRepository owners; - - public PetController(PetRepository pets, OwnerRepository owners) { - this.pets = pets; - this.owners = owners; + PetController(OwnerService ownerService, PetService petService, PetTypeService petTypeService) { + this.ownerService = ownerService; + this.petService = petService; + this.petTypeService = petTypeService; } + @ModelAttribute("types") - public Collection populatePetTypes() { - return this.pets.findPetTypes(); + public Collection populatePetTypes() { + return this.petTypeService.findPetTypes(); } @ModelAttribute("owner") - public Owner findOwner(@PathVariable("ownerId") int ownerId) { - return this.owners.findById(ownerId); + public OwnerDTO findOwner(@PathVariable("ownerId") int ownerId) { + return this.ownerService.findById(ownerId); } @InitBinder("owner") @@ -66,38 +76,38 @@ class PetController { } @GetMapping("/pets/new") - public String initCreationForm(Owner owner, ModelMap model) { - Pet pet = new Pet(); + public String initCreationForm(OwnerDTO owner, ModelMap model) { + PetDTO pet = new PetDTO(); owner.addPet(pet); model.put("pet", pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } @PostMapping("/pets/new") - public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { - if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { + public String processCreationForm(OwnerDTO ownerDTO, @Valid PetDTO pet, BindingResult result, ModelMap model) { + if (StringUtils.hasLength(pet.getName()) && pet.isNew() && ownerDTO.getPet(pet.getName(), true) != null) { result.rejectValue("name", "duplicate", "already exists"); } - owner.addPet(pet); + ownerDTO.addPet(pet); if (result.hasErrors()) { model.put("pet", pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } else { - this.pets.save(pet); + this.petService.save(pet); return "redirect:/owners/{ownerId}"; } } @GetMapping("/pets/{petId}/edit") public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { - Pet pet = this.pets.findById(petId); + PetDTO pet = this.petService.findById(petId); model.put("pet", pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } @PostMapping("/pets/{petId}/edit") - public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { + public String processUpdateForm(@Valid PetDTO pet, BindingResult result, OwnerDTO owner, ModelMap model) { if (result.hasErrors()) { pet.setOwner(owner); model.put("pet", pet); @@ -105,7 +115,7 @@ class PetController { } else { owner.addPet(pet); - this.pets.save(pet); + this.petService.save(pet); return "redirect:/owners/{ownerId}"; } } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java similarity index 69% rename from src/main/java/org/springframework/samples/petclinic/vet/VetController.java rename to src/main/java/org/springframework/samples/petclinic/controller/VetController.java index fb5e321ba..9ace51d26 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java @@ -13,8 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.vet; +package org.springframework.samples.petclinic.controller; +import org.springframework.samples.petclinic.dto.VetsDTO; +import org.springframework.samples.petclinic.service.VetService; +import org.springframework.samples.petclinic.vet.Vets; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -26,32 +29,34 @@ import java.util.Map; * @author Mark Fisher * @author Ken Krebs * @author Arjen Poutsma + * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller class VetController { - private final VetRepository vets; + private final VetService vetService; - public VetController(VetRepository clinicService) { - this.vets = clinicService; + VetController(VetService vetService) { + this.vetService = vetService; } + @GetMapping("/vets.html") public String showVetList(Map model) { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for Object-Xml mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.vets.findAll()); + VetsDTO vets = new VetsDTO(); + vets.getVetList().addAll(this.vetService.findAll()); model.put("vets", vets); return "vets/vetList"; } @GetMapping({ "/vets" }) - public @ResponseBody Vets showResourcesVetList() { + public @ResponseBody VetsDTO showResourcesVetList() { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for JSon/Object mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.vets.findAll()); + VetsDTO vets = new VetsDTO(); + vets.getVetList().addAll(this.vetService.findAll()); return vets; } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java similarity index 72% rename from src/main/java/org/springframework/samples/petclinic/owner/VisitController.java rename to src/main/java/org/springframework/samples/petclinic/controller/VisitController.java index 375980312..dd8bc1330 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java @@ -13,14 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.controller; import java.util.Map; import javax.validation.Valid; +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.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; @@ -36,19 +39,20 @@ import org.springframework.web.bind.annotation.PostMapping; * @author Arjen Poutsma * @author Michael Isvy * @author Dave Syer + * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller class VisitController { - private final VisitRepository visits; + private final VisitService visitService; + private final PetService petService; - private final PetRepository pets; - - public VisitController(VisitRepository visits, PetRepository pets) { - this.visits = visits; - this.pets = pets; + VisitController(VisitService visitService, PetService petService) { + this.visitService = visitService; + this.petService = petService; } + @InitBinder public void setAllowedFields(WebDataBinder dataBinder) { dataBinder.setDisallowedFields("id"); @@ -62,11 +66,11 @@ class VisitController { * @return Pet */ @ModelAttribute("visit") - public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) { - Pet pet = this.pets.findById(petId); - pet.setVisitsInternal(this.visits.findByPetId(petId)); + public VisitDTO loadPetWithVisit(@PathVariable("petId") int petId, Map model) { + PetDTO pet = this.petService.findById(petId); + pet.setVisitsInternal(this.visitService.findByPetId(petId)); model.put("pet", pet); - Visit visit = new Visit(); + VisitDTO visit = new VisitDTO(); pet.addVisit(visit); return visit; } @@ -79,12 +83,12 @@ class VisitController { // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") - public String processNewVisitForm(@Valid Visit visit, BindingResult result) { + public String processNewVisitForm(@Valid VisitDTO visit, BindingResult result) { if (result.hasErrors()) { return "pets/createOrUpdateVisitForm"; } else { - this.visits.save(visit); + this.visitService.save(visit); return "redirect:/owners/{ownerId}"; } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java new file mode 100644 index 000000000..1aa04af7a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class BaseDTO implements Serializable { + + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public boolean isNew() { + return this.id == null; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java new file mode 100644 index 000000000..345a192e2 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.dto; + + +/** + * Simple Data Transfert Object with a name property to BaseDTO. Used as + * a base class for DTOs needing these properties. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class NamedDTO extends BaseDTO { + + private String name; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.getName(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java new file mode 100644 index 000000000..c6bd4225e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -0,0 +1,130 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.dto; + +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; +import org.springframework.core.style.ToStringCreator; + +import javax.validation.constraints.Digits; +import javax.validation.constraints.NotEmpty; +import java.util.*; + +/** + * Simple Data Transfert Object representing a owner. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class OwnerDTO extends PersonDTO { + + @NotEmpty + private String address; + + @NotEmpty + private String city; + + @NotEmpty + @Digits(fraction = 0, integer = 10) + private String telephone; + + private Set pets; + + public String getAddress() { + return this.address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return this.city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getTelephone() { + return this.telephone; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + protected Set getPetsInternal() { + if (this.pets == null) { + this.pets = new HashSet<>(); + } + return this.pets; + } + + protected void setPetsInternal(Set pets) { + this.pets = pets; + } + + public List getPets() { + List sortedPets = new ArrayList<>(getPetsInternal()); + PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedPets); + } + + public void addPet(PetDTO pet) { + if (pet.isNew()) { + getPetsInternal().add(pet); + } + pet.setOwner(this); + } + + /** + * Return the Pet with the given name, or null if none found for this Owner. + * @param name to test + * @return true if pet name is already in use + */ + public PetDTO getPet(String name) { + return getPet(name, false); + } + + /** + * Return the Pet with the given name, or null if none found for this Owner. + * @param name to test + * @return true if pet name is already in use + */ + public PetDTO getPet(String name, boolean ignoreNew) { + name = name.toLowerCase(); + for (PetDTO pet : getPetsInternal()) { + if (!ignoreNew || !pet.isNew()) { + String compName = pet.getName(); + compName = compName.toLowerCase(); + if (compName.equals(name)) { + return pet; + } + } + } + return null; + } + + @Override + public String toString() { + return new ToStringCreator(this) + + .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName()) + .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city) + .append("telephone", this.telephone).toString(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java new file mode 100644 index 000000000..44d4f1faf --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.dto; + +import javax.validation.constraints.NotEmpty; + +/** + * Simple Data Transfert Object representing a person. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class PersonDTO extends BaseDTO { + + @NotEmpty + private String firstName; + @NotEmpty + private String lastName; + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return this.lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java new file mode 100644 index 000000000..a5000e27a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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.*; + +/** + * Simple Data Transfert Object representing a pet. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class PetDTO extends NamedDTO { + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate birthDate; + + private PetType type; + + private OwnerDTO owner; + + private Set visits = new LinkedHashSet<>(); + + public void setBirthDate(LocalDate birthDate) { + this.birthDate = birthDate; + } + + public LocalDate getBirthDate() { + return this.birthDate; + } + + public PetType getType() { + return this.type; + } + + public void setType(PetType type) { + this.type = type; + } + + public OwnerDTO getOwnerDTO() { + return owner; + } + + public void setOwner(OwnerDTO owner) { + this.owner = owner; + } + + protected Set getVisitsInternal() { + if (this.visits == null) { + this.visits = new HashSet<>(); + } + return this.visits; + } + + public void setVisitsInternal(Collection visits) { + this.visits = new LinkedHashSet<>(visits); + } + + public List getVisits() { + List sortedVisits = new ArrayList<>(getVisitsInternal()); + PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false)); + return Collections.unmodifiableList(sortedVisits); + } + + public void addVisit(VisitDTO visit) { + getVisitsInternal().add(visit); + visit.setPetId(this.getId()); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java new file mode 100644 index 000000000..54d771c7f --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.dto; + +/** + * Simple Data Transfert Object representing PetType. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class PetTypeDTO extends NamedDTO { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java new file mode 100644 index 000000000..d209a511a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java @@ -0,0 +1,12 @@ +package org.springframework.samples.petclinic.dto; + +import java.io.Serializable; + +/** + * Simple Data Transfert Object representing a list of specialities. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class SpecialtyDTO extends NamedDTO implements Serializable { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java new file mode 100644 index 000000000..048598218 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.dto; + +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; +import org.springframework.samples.petclinic.vet.Specialty; + +import javax.xml.bind.annotation.XmlElement; +import java.util.*; + +/** + * Simple Data Transfert Object representing a vet. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class VetDTO extends PersonDTO { + + private Set specialties; + + protected Set getSpecialtiesInternal() { + if (this.specialties == null) { + this.specialties = new HashSet<>(); + } + return this.specialties; + } + + protected void setSpecialtiesInternal(Set specialties) { + this.specialties = specialties; + } + + @XmlElement + public List getSpecialties() { + List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); + PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedSpecs); + } + + public int getNrOfSpecialties() { + return getSpecialtiesInternal().size(); + } + + public void addSpecialty(Specialty specialty) { + getSpecialtiesInternal().add(specialty); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java new file mode 100644 index 000000000..aea942f58 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * Simple Data Transfert Object representing a list of veterinarians. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class VetsDTO { + + private List vets; + + public List getVetList() { + if (vets == null) { + vets = new ArrayList<>(); + } + return vets; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java new file mode 100644 index 000000000..835b0dd75 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.dto; + +import org.springframework.format.annotation.DateTimeFormat; +import javax.validation.constraints.NotEmpty; +import java.time.LocalDate; + +/** + * Simple Data Transfert Object representing a visit. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public class VisitDTO extends BaseDTO { + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate date; + + @NotEmpty + private String description; + + private Integer petId; + + /** + * Creates a new instance of Visit for the current date + */ + public VisitDTO() { + this.date = LocalDate.now(); + } + + public LocalDate getDate() { + return this.date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Integer getPetId() { + return this.petId; + } + + public void setPetId(Integer petId) { + this.petId = petId; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java index 4940bcb38..d96062c49 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java @@ -21,6 +21,7 @@ import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.Formatter; +import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.stereotype.Component; /** diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java similarity index 95% rename from src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java rename to src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java index 0613e928a..16ac813d8 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.repository; import java.util.Collection; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; +import org.springframework.samples.petclinic.owner.Owner; import org.springframework.transaction.annotation.Transactional; /** diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java similarity index 91% rename from src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java rename to src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java index 9d25b095b..74a4ab140 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.repository; import java.util.List; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.owner.Pet; +import org.springframework.samples.petclinic.owner.PetType; import org.springframework.transaction.annotation.Transactional; /** diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java similarity index 93% rename from src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java rename to src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java index 549b1c229..a6eb67935 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.vet; +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; /** diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java similarity index 93% rename from src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java rename to src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java index d5a3334c6..5b680916f 100644 --- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.visit; +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; /** * Repository class for Visit domain objects All method names are compliant diff --git a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java new file mode 100644 index 000000000..93e3a2db8 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.service; + +import java.util.Collection; + +public interface BaseService { + public E dtoToEntity(D dto); + public D entityToDTO(E entity); + public Collection entitiesToDTOS(Collection entities); + public Collection dtosToEntities(Collection dtos); +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java new file mode 100644 index 000000000..fb3837b6a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -0,0 +1,68 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.OwnerDTO; +import org.springframework.samples.petclinic.owner.Owner; +import org.springframework.samples.petclinic.repository.OwnerRepository; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; + +@Service("OwnerService") +public class OwnerService implements BaseService{ + + private final OwnerRepository ownerRepository; + private final ModelMapper modelMapper = new ModelMapper(); + + public OwnerService(OwnerRepository ownerRepository) { + this.ownerRepository = ownerRepository; + } + + @Override + public Owner dtoToEntity(OwnerDTO dto) { + return modelMapper.map(dto, Owner.class); + } + + @Override + public OwnerDTO entityToDTO(Owner entity) { + return modelMapper.map(entity, OwnerDTO.class); + } + + @Override + public Collection entitiesToDTOS(Collection entities) { + Collection dtos = new HashSet<>(); + + for(Owner entity: entities) { + dtos.add(entityToDTO(entity)); + } + + return dtos; + } + + @Override + public Collection dtosToEntities(Collection dtos) { + Collection entities = new HashSet<>(); + + for(OwnerDTO dto: dtos) { + entities.add(dtoToEntity(dto)); + } + + return entities; + } + + public void save(OwnerDTO ownerDTO) { + Owner owner = dtoToEntity(ownerDTO); + ownerRepository.save(owner); + } + + public Collection findByLastName(String lastName) { + Collection owners = ownerRepository.findByLastName(lastName); + return entitiesToDTOS(owners); + } + + public OwnerDTO findById(int ownerId) { + Owner owner = ownerRepository.findById(ownerId); + return entityToDTO(owner); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java new file mode 100644 index 000000000..117e60752 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -0,0 +1,63 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.PetDTO; +import org.springframework.samples.petclinic.owner.Pet; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; + +@Service("PetService") +public class PetService implements BaseService{ + private final PetRepository petRepository; + private final ModelMapper modelMapper = new ModelMapper(); + + public PetService(PetRepository petRepository) { + this.petRepository = petRepository; + } + + @Override + public Pet dtoToEntity(PetDTO dto) { + return modelMapper.map(dto, Pet.class); + } + + @Override + public PetDTO entityToDTO(Pet entity) { + return modelMapper.map(entity, PetDTO.class); + } + + @Override + public Collection entitiesToDTOS(Collection entities) { + Collection dtos = new HashSet<>(); + + for(Pet entity:entities) { + dtos.add(entityToDTO(entity)); + } + return dtos; + } + + @Override + public Collection dtosToEntities(Collection dtos) { + Collection entities = new HashSet<>(); + + for(PetDTO dto: dtos) { + entities.add(dtoToEntity(dto)); + } + + return entities; + } + + public void save(PetDTO petDTO) { + Pet pet = dtoToEntity(petDTO); + petRepository.save(pet); + } + + public PetDTO findById(int petId) { + Pet pet = petRepository.findById(petId); + return entityToDTO(pet); + } + +} + diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java new file mode 100644 index 000000000..7623d6cab --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java @@ -0,0 +1,59 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.PetTypeDTO; +import org.springframework.samples.petclinic.owner.PetType; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; + +@Service("PerTypeService") +public class PetTypeService implements BaseService{ + private final PetRepository petRepository; + private final ModelMapper modelMapper = new ModelMapper(); + + public PetTypeService(PetRepository petRepository) { + this.petRepository = petRepository; + } + + @Override + public PetType dtoToEntity(PetTypeDTO dto) { + return modelMapper.map(dto, PetType.class); + } + + @Override + public PetTypeDTO entityToDTO(PetType entity) { + return modelMapper.map(entity, PetTypeDTO.class); + } + + @Override + public Collection entitiesToDTOS(Collection entities) { + Collection dtos = new HashSet<>(); + + for(PetType entity : entities) { + dtos.add(entityToDTO(entity)); + } + + return dtos; + } + + @Override + public Collection dtosToEntities(Collection dtos) { + Collection entities = new HashSet<>(); + + for(PetTypeDTO dto: dtos) { + entities.add(dtoToEntity(dto)); + } + + return entities; + } + + + public Collection findPetTypes() { + Collection petTypes = petRepository.findPetTypes(); + return entitiesToDTOS(petTypes); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java new file mode 100644 index 000000000..ec6810e6c --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java @@ -0,0 +1,46 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.SpecialtyDTO; +import org.springframework.samples.petclinic.vet.Specialty; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; + +@Service("SpecialityService") +public class SpecialityService implements BaseService { + private final ModelMapper modelMapper = new ModelMapper(); + + @Override + public Specialty dtoToEntity(SpecialtyDTO dto) { + return modelMapper.map(dto, Specialty.class); + } + + @Override + public SpecialtyDTO entityToDTO(Specialty entity) { + return modelMapper.map(entity, SpecialtyDTO.class); + } + + @Override + public Collection entitiesToDTOS(Collection entities) { + Collection dtos = new HashSet<>(); + + for(Specialty entity:entities) { + dtos.add(entityToDTO(entity)); + } + + return dtos; + } + + @Override + public Collection dtosToEntities(Collection dtos) { + Collection entities = new HashSet<>(); + + for(SpecialtyDTO dto: dtos) { + entities.add(dtoToEntity(dto)); + } + + return entities; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java new file mode 100644 index 000000000..75dcf53ba --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java @@ -0,0 +1,60 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.VetDTO; +import org.springframework.samples.petclinic.repository.VetRepository; +import org.springframework.samples.petclinic.vet.Vet; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; + +@Service("VetService") +public class VetService implements BaseService{ + + private final VetRepository vetRepository; + private final ModelMapper modelMapper = new ModelMapper(); + + public VetService(VetRepository vetRepository) { + this.vetRepository = vetRepository; + } + + @Override + public Vet dtoToEntity(VetDTO dto) { + return modelMapper.map(dto, Vet.class); + } + + @Override + public VetDTO entityToDTO(Vet entity) { + return modelMapper.map(entity, VetDTO.class); + } + + @Override + public Collection entitiesToDTOS(Collection entities) { + Collection dtos = new HashSet<>(); + + for(Vet entity: entities) { + dtos.add(entityToDTO(entity)); + } + + return dtos; + } + + @Override + public Collection dtosToEntities(Collection dtos) { + Collection entities = new HashSet<>(); + + for(VetDTO dto: dtos) { + entities.add(dtoToEntity(dto)); + } + + return entities; + } + + + public Collection findAll() { + Collection vets = vetRepository.findAll(); + return entitiesToDTOS(vets); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java new file mode 100644 index 000000000..f2e173a52 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java @@ -0,0 +1,68 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.VisitDTO; +import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.repository.VisitRepository; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; + +@Service("VisitService") +public class VisitService implements BaseService{ + + private final VisitRepository visitRepository; + private final ModelMapper modelMapper = new ModelMapper(); + + public VisitService(VisitRepository visitRepository) { + this.visitRepository = visitRepository; + } + + @Override + public Visit dtoToEntity(VisitDTO dto) { + return modelMapper.map(dto, Visit.class); + } + + @Override + public VisitDTO entityToDTO(Visit entity) { + return modelMapper.map(entity, VisitDTO.class); + } + + @Override + public Collection entitiesToDTOS(Collection entities) { + Collection dtos = new HashSet<>(); + + for(Visit entity: entities) { + dtos.add(entityToDTO(entity)); + } + return dtos; + } + + @Override + public Collection dtosToEntities(Collection dtos) { + Collection entities = new HashSet<>(); + + for(VisitDTO dto: dtos) { + entities.add(dtoToEntity(dto)); + } + + return entities; + } + + public void save(VisitDTO visitDTO) { + Visit visit = dtoToEntity(visitDTO); + visitRepository.save(visit); + } + + public Collection findByPetId(Integer petId) { + Collection visits = visitRepository.findByPetId(petId); + Collection visitDTOS = new HashSet<>(); + + for (Visit visit: visits) { + visitDTOS.add(entityToDTO(visit)); + } + + return visitDTOS; + } +} diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java index 226db01fe..90736badb 100644 --- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -19,7 +19,7 @@ package org.springframework.samples.petclinic; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.samples.petclinic.vet.VetRepository; +import org.springframework.samples.petclinic.repository.VetRepository; @SpringBootTest class PetclinicIntegrationTests { diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index 1d6249c5d..a41e16fc3 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -28,8 +28,10 @@ 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.visit.VisitRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.test.web.servlet.MockMvc; import static org.hamcrest.Matchers.empty; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index 47c444a78..2523e6101 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -31,6 +31,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 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.repository.OwnerRepository; +import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.test.web.servlet.MockMvc; /** diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index adb96b69d..44c051119 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -28,6 +28,7 @@ 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.samples.petclinic.repository.PetRepository; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index 84bee72df..86355cb4f 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -28,7 +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.visit.VisitRepository; +import org.springframework.samples.petclinic.controller.VisitController; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.test.web.servlet.MockMvc; /** diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index a7f3d9d24..a5849fb44 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -26,14 +26,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.samples.petclinic.owner.Owner; -import org.springframework.samples.petclinic.owner.OwnerRepository; +import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.owner.Pet; -import org.springframework.samples.petclinic.owner.PetRepository; +import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.samples.petclinic.owner.PetType; import org.springframework.samples.petclinic.vet.Vet; -import org.springframework.samples.petclinic.vet.VetRepository; +import org.springframework.samples.petclinic.repository.VetRepository; import org.springframework.samples.petclinic.visit.Visit; -import org.springframework.samples.petclinic.visit.VisitRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index fd537bee2..1488ff611 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -31,6 +31,8 @@ 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.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; From 6d5b55fc1030504cdefb38337c3187c9e1726a12 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Wed, 7 Oct 2020 19:40:58 +0200 Subject: [PATCH 02/16] Implements DTOs and Services --- .../petclinic/controller/OwnerController.java | 1 + .../petclinic/controller/PetController.java | 3 +- .../petclinic/controller/VetController.java | 1 - .../petclinic/controller/VisitController.java | 5 ++- .../samples/petclinic/dto/BaseDTO.java | 5 +-- .../samples/petclinic/dto/NamedDTO.java | 5 ++- .../samples/petclinic/dto/OwnerDTO.java | 2 +- .../samples/petclinic/dto/PersonDTO.java | 2 ++ .../samples/petclinic/dto/PetDTO.java | 7 ++-- .../petclinic/repository/VetRepository.java | 3 +- .../petclinic/repository/VisitRepository.java | 3 +- .../petclinic/service/BaseService.java | 7 +++- .../petclinic/service/OwnerService.java | 8 +++-- .../samples/petclinic/service/PetService.java | 9 ++--- .../petclinic/service/PetTypeService.java | 11 +++--- .../petclinic/service/SpecialityService.java | 6 ++-- .../samples/petclinic/service/VetService.java | 8 ++--- .../petclinic/service/VisitService.java | 10 +++--- .../OwnerControllerTests.java | 34 ++++++++++--------- .../PetControllerTests.java | 27 +++++++++++---- .../VetControllerTests.java | 15 ++++---- .../VisitControllerTests.java | 14 ++++---- .../petclinic/service/ClinicServiceTests.java | 8 ++--- 23 files changed, 111 insertions(+), 83 deletions(-) rename src/test/java/org/springframework/samples/petclinic/{owner => controller}/OwnerControllerTests.java (90%) rename src/test/java/org/springframework/samples/petclinic/{owner => controller}/PetControllerTests.java (80%) mode change 100755 => 100644 rename src/test/java/org/springframework/samples/petclinic/{vet => controller}/VetControllerTests.java (86%) rename src/test/java/org/springframework/samples/petclinic/{owner => controller}/VisitControllerTests.java (86%) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 35ac779e1..47ab04ad2 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -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) { diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index b8f6b945b..64f3f5512 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -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 populatePetTypes() { return this.petTypeService.findPetTypes(); diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VetController.java b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java index 9ace51d26..d3ae53e29 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java @@ -40,7 +40,6 @@ class VetController { this.vetService = vetService; } - @GetMapping("/vets.html") public String showVetList(Map model) { // Here we are returning an object of type 'Vets' rather than a collection of Vet diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java index dd8bc1330..c7dc9dc9f 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java @@ -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") diff --git a/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java index 1aa04af7a..eb08fa003 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java @@ -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; } + } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java index 345a192e2..29ce3830e 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java @@ -15,10 +15,9 @@ */ package org.springframework.samples.petclinic.dto; - /** - * Simple Data Transfert Object with a name property to BaseDTO. Used as - * a base class for DTOs needing these properties. + * Simple Data Transfert Object with a name property to BaseDTO. Used as a + * base class for DTOs needing these properties. * * @author Paul-Emmanuel DOS SANTOS FACAO */ diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index c6bd4225e..79ad5b660 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -73,7 +73,7 @@ public class OwnerDTO extends PersonDTO { return this.pets; } - protected void setPetsInternal(Set pets) { + public void setPetsInternal(Set pets) { this.pets = pets; } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java index 44d4f1faf..963341601 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java @@ -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; } + } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java index a5000e27a..af838e665 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -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; } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java index a6eb67935..4d35b2428 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java @@ -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 { */ @Transactional(readOnly = true) @Cacheable("vets") - Collection findAll() throws DataAccessException; + Collection findAll(); } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java index 5b680916f..e1b5fe7d5 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java @@ -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 { * @param visit the Visit to save * @see BaseEntity#isNew */ - void save(Visit visit) throws DataAccessException; + void save(Visit visit); List findByPetId(Integer petId); diff --git a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java index 93e3a2db8..40e0cc1f5 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java @@ -2,9 +2,14 @@ package org.springframework.samples.petclinic.service; import java.util.Collection; -public interface BaseService { +public interface BaseService { + public E dtoToEntity(D dto); + public D entityToDTO(E entity); + public Collection entitiesToDTOS(Collection entities); + public Collection dtosToEntities(Collection dtos); + } diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java index fb3837b6a..12af7346c 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -10,9 +10,10 @@ import java.util.Collection; import java.util.HashSet; @Service("OwnerService") -public class OwnerService implements BaseService{ +public class OwnerService implements BaseService { private final OwnerRepository ownerRepository; + private final ModelMapper modelMapper = new ModelMapper(); public OwnerService(OwnerRepository ownerRepository) { @@ -33,7 +34,7 @@ public class OwnerService implements BaseService{ public Collection entitiesToDTOS(Collection entities) { Collection dtos = new HashSet<>(); - for(Owner entity: entities) { + for (Owner entity : entities) { dtos.add(entityToDTO(entity)); } @@ -44,7 +45,7 @@ public class OwnerService implements BaseService{ public Collection dtosToEntities(Collection dtos) { Collection entities = new HashSet<>(); - for(OwnerDTO dto: dtos) { + for (OwnerDTO dto : dtos) { entities.add(dtoToEntity(dto)); } @@ -65,4 +66,5 @@ public class OwnerService implements BaseService{ Owner owner = ownerRepository.findById(ownerId); return entityToDTO(owner); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java index 117e60752..f64e13c42 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -10,8 +10,10 @@ import java.util.Collection; import java.util.HashSet; @Service("PetService") -public class PetService implements BaseService{ +public class PetService implements BaseService { + private final PetRepository petRepository; + private final ModelMapper modelMapper = new ModelMapper(); public PetService(PetRepository petRepository) { @@ -32,7 +34,7 @@ public class PetService implements BaseService{ public Collection entitiesToDTOS(Collection entities) { Collection dtos = new HashSet<>(); - for(Pet entity:entities) { + for (Pet entity : entities) { dtos.add(entityToDTO(entity)); } return dtos; @@ -42,7 +44,7 @@ public class PetService implements BaseService{ public Collection dtosToEntities(Collection dtos) { Collection entities = new HashSet<>(); - for(PetDTO dto: dtos) { + for (PetDTO dto : dtos) { entities.add(dtoToEntity(dto)); } @@ -60,4 +62,3 @@ public class PetService implements BaseService{ } } - diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java index 7623d6cab..63ebbb1e4 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java @@ -10,8 +10,10 @@ import java.util.Collection; import java.util.HashSet; @Service("PerTypeService") -public class PetTypeService implements BaseService{ +public class PetTypeService implements BaseService { + private final PetRepository petRepository; + private final ModelMapper modelMapper = new ModelMapper(); public PetTypeService(PetRepository petRepository) { @@ -32,7 +34,7 @@ public class PetTypeService implements BaseService{ public Collection entitiesToDTOS(Collection entities) { Collection dtos = new HashSet<>(); - for(PetType entity : entities) { + for (PetType entity : entities) { dtos.add(entityToDTO(entity)); } @@ -43,16 +45,15 @@ public class PetTypeService implements BaseService{ public Collection dtosToEntities(Collection dtos) { Collection entities = new HashSet<>(); - for(PetTypeDTO dto: dtos) { + for (PetTypeDTO dto : dtos) { entities.add(dtoToEntity(dto)); } return entities; } - public Collection findPetTypes() { - Collection petTypes = petRepository.findPetTypes(); + Collection petTypes = petRepository.findPetTypes(); return entitiesToDTOS(petTypes); } diff --git a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java index ec6810e6c..e4cb35291 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java @@ -10,6 +10,7 @@ import java.util.HashSet; @Service("SpecialityService") public class SpecialityService implements BaseService { + private final ModelMapper modelMapper = new ModelMapper(); @Override @@ -26,7 +27,7 @@ public class SpecialityService implements BaseService { public Collection entitiesToDTOS(Collection entities) { Collection dtos = new HashSet<>(); - for(Specialty entity:entities) { + for (Specialty entity : entities) { dtos.add(entityToDTO(entity)); } @@ -37,10 +38,11 @@ public class SpecialityService implements BaseService { public Collection dtosToEntities(Collection dtos) { Collection entities = new HashSet<>(); - for(SpecialtyDTO dto: dtos) { + for (SpecialtyDTO dto : dtos) { entities.add(dtoToEntity(dto)); } return entities; } + } diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java index 75dcf53ba..18f6aac47 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java @@ -10,9 +10,10 @@ import java.util.Collection; import java.util.HashSet; @Service("VetService") -public class VetService implements BaseService{ +public class VetService implements BaseService { private final VetRepository vetRepository; + private final ModelMapper modelMapper = new ModelMapper(); public VetService(VetRepository vetRepository) { @@ -33,7 +34,7 @@ public class VetService implements BaseService{ public Collection entitiesToDTOS(Collection entities) { Collection dtos = new HashSet<>(); - for(Vet entity: entities) { + for (Vet entity : entities) { dtos.add(entityToDTO(entity)); } @@ -44,14 +45,13 @@ public class VetService implements BaseService{ public Collection dtosToEntities(Collection dtos) { Collection entities = new HashSet<>(); - for(VetDTO dto: dtos) { + for (VetDTO dto : dtos) { entities.add(dtoToEntity(dto)); } return entities; } - public Collection findAll() { Collection vets = vetRepository.findAll(); return entitiesToDTOS(vets); diff --git a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java index f2e173a52..54ce4c6a5 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java @@ -10,9 +10,10 @@ import java.util.Collection; import java.util.HashSet; @Service("VisitService") -public class VisitService implements BaseService{ +public class VisitService implements BaseService { private final VisitRepository visitRepository; + private final ModelMapper modelMapper = new ModelMapper(); public VisitService(VisitRepository visitRepository) { @@ -33,7 +34,7 @@ public class VisitService implements BaseService{ public Collection entitiesToDTOS(Collection entities) { Collection dtos = new HashSet<>(); - for(Visit entity: entities) { + for (Visit entity : entities) { dtos.add(entityToDTO(entity)); } return dtos; @@ -43,7 +44,7 @@ public class VisitService implements BaseService{ public Collection dtosToEntities(Collection dtos) { Collection entities = new HashSet<>(); - for(VisitDTO dto: dtos) { + for (VisitDTO dto : dtos) { entities.add(dtoToEntity(dto)); } @@ -59,10 +60,11 @@ public class VisitService implements BaseService{ Collection visits = visitRepository.findByPetId(petId); Collection visitDTOS = new HashSet<>(); - for (Visit visit: visits) { + for (Visit visit : visits) { visitDTOS.add(entityToDTO(visit)); } return visitDTOS; } + } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java similarity index 90% rename from src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java rename to src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java index a41e16fc3..82fda30c4 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java @@ -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>() { + .andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher>() { @Override public boolean matches(Object item) { @SuppressWarnings("unchecked") - List pets = (List) item; - Pet pet = pets.get(0); + List pets = (List) item; + PetDTO pet = pets.get(0); if (pet.getVisits().isEmpty()) { return false; } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java old mode 100755 new mode 100644 similarity index 80% rename from src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java rename to src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java index 2523e6101..5594d7ec7 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java @@ -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()); } diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java similarity index 86% rename from src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java rename to src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java index 1488ff611..e1bdd5ad0 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java @@ -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 diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java similarity index 86% rename from src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java rename to src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java index 86355cb4f..eec30afb8 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java @@ -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 diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index a5849fb44..c2cf0742c 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -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 visits = this.visits.findByPetId(7); assertThat(visits).hasSize(2); Visit[] visitArr = visits.toArray(new Visit[visits.size()]); From 4dd08b9c5bc9535ab533675bf527dc5f5ef15eb8 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 09:12:52 +0200 Subject: [PATCH 03/16] Change PetTypeFormatter and Validator to use DTO --- pom.xml | 1 - .../petclinic/controller/PetController.java | 13 ++++------- .../petclinic/owner/PetTypeFormatter.java | 21 +++++++++-------- .../petclinic/service/BaseService.java | 20 ++++++++++++++++ .../{owner => validator}/PetValidator.java | 6 +++-- src/main/wro/wro.xml | 5 ++-- .../controller/PetControllerTests.java | 18 ++++++--------- .../owner/PetTypeFormatterTests.java | 23 +++++++++++-------- 8 files changed, 62 insertions(+), 45 deletions(-) rename src/main/java/org/springframework/samples/petclinic/{owner => validator}/PetValidator.java (89%) diff --git a/pom.xml b/pom.xml index ed213a1ef..3636c8154 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,6 @@ petclinic - 1.8 UTF-8 diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index 64f3f5512..2bd6eb9a3 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -15,13 +15,9 @@ */ package org.springframework.samples.petclinic.controller; -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.PetValidator; -import org.springframework.samples.petclinic.service.OwnerService; -import org.springframework.samples.petclinic.service.PetService; -import org.springframework.samples.petclinic.service.PetTypeService; +import org.springframework.samples.petclinic.dto.*; +import org.springframework.samples.petclinic.validator.PetValidator; +import org.springframework.samples.petclinic.service.*; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; @@ -93,8 +89,7 @@ class PetController { if (result.hasErrors()) { model.put("pet", pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } - else { + } else { this.petService.save(pet); return "redirect:/owners/{ownerId}"; } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java index d96062c49..f2ab9b542 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java @@ -21,7 +21,8 @@ import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.Formatter; -import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.dto.PetTypeDTO; +import org.springframework.samples.petclinic.service.PetTypeService; import org.springframework.stereotype.Component; /** @@ -35,24 +36,24 @@ import org.springframework.stereotype.Component; * @author Michael Isvy */ @Component -public class PetTypeFormatter implements Formatter { +public class PetTypeFormatter implements Formatter { - private final PetRepository pets; + // private final PetRepository pets; + private final PetTypeService petTypeService; - @Autowired - public PetTypeFormatter(PetRepository pets) { - this.pets = pets; + public PetTypeFormatter(PetTypeService petTypeService) { + this.petTypeService = petTypeService; } @Override - public String print(PetType petType, Locale locale) { + public String print(PetTypeDTO petType, Locale locale) { return petType.getName(); } @Override - public PetType parse(String text, Locale locale) throws ParseException { - Collection findPetTypes = this.pets.findPetTypes(); - for (PetType type : findPetTypes) { + public PetTypeDTO parse(String text, Locale locale) throws ParseException { + Collection findPetTypes = this.petTypeService.findPetTypes(); + for (PetTypeDTO type : findPetTypes) { if (type.getName().equals(text)) { return type; } diff --git a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java index 40e0cc1f5..1f97e4d0b 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java @@ -4,12 +4,32 @@ import java.util.Collection; public interface BaseService { + /** + * Convert Data Transfert Object to Entity Model + * @param dto DTO + * @return Entity Model + */ public E dtoToEntity(D dto); + /** + * Convert Entity Model to Data Transfert Object + * @param entity Entity Model + * @return DTO + */ public D entityToDTO(E entity); + /** + * Convert Entities Models Collection to Data Transfert Object Collection + * @param entities Collection of Entity Model + * @return Collection of DTO + */ public Collection entitiesToDTOS(Collection entities); + /** + * Convert Entities Models Collection to Data Transfert Object Collection + * @param dtos Collection of DTO + * @return Collection of Entity Model + */ public Collection dtosToEntities(Collection dtos); } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java similarity index 89% rename from src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java rename to src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java index e1370b428..6c96f217d 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.validator; +import org.springframework.samples.petclinic.dto.PetDTO; +import org.springframework.samples.petclinic.owner.Pet; import org.springframework.util.StringUtils; import org.springframework.validation.Errors; import org.springframework.validation.Validator; @@ -35,7 +37,7 @@ public class PetValidator implements Validator { @Override public void validate(Object obj, Errors errors) { - Pet pet = (Pet) obj; + PetDTO pet = (PetDTO) obj; String name = pet.getName(); // name validation if (!StringUtils.hasLength(name)) { diff --git a/src/main/wro/wro.xml b/src/main/wro/wro.xml index 590156d7e..d4f23be37 100644 --- a/src/main/wro/wro.xml +++ b/src/main/wro/wro.xml @@ -1,6 +1,7 @@ - + classpath:META-INF/resources/webjars/bootstrap/3.3.6/less/bootstrap.less /petclinic.less - + diff --git a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java index 5594d7ec7..011842c87 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java @@ -31,16 +31,10 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 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; @@ -97,11 +91,13 @@ class PetControllerTests { @Test void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate", - "2015-02-12")).andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type")) - .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) + .param("name", "Betty") + .param("birthDate","2015-02-12")) + .andExpect(model().attributeHasNoErrors("owner")) + .andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type")) + .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")); } @Test diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index 44c051119..284955710 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -28,7 +28,10 @@ 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.samples.petclinic.dto.PetTypeDTO; import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.service.PetService; +import org.springframework.samples.petclinic.service.PetTypeService; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -42,18 +45,18 @@ import static org.mockito.BDDMockito.given; class PetTypeFormatterTests { @Mock - private PetRepository pets; + private PetTypeService petTypeService; private PetTypeFormatter petTypeFormatter; @BeforeEach void setup() { - this.petTypeFormatter = new PetTypeFormatter(pets); + this.petTypeFormatter = new PetTypeFormatter(petTypeService); } @Test void testPrint() { - PetType petType = new PetType(); + PetTypeDTO petType = new PetTypeDTO(); petType.setName("Hamster"); String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); assertThat(petTypeName).isEqualTo("Hamster"); @@ -61,14 +64,14 @@ class PetTypeFormatterTests { @Test void shouldParse() throws ParseException { - given(this.pets.findPetTypes()).willReturn(makePetTypes()); - PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); + given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); + PetTypeDTO petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); assertThat(petType.getName()).isEqualTo("Bird"); } @Test void shouldThrowParseException() throws ParseException { - given(this.pets.findPetTypes()).willReturn(makePetTypes()); + given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); Assertions.assertThrows(ParseException.class, () -> { petTypeFormatter.parse("Fish", Locale.ENGLISH); }); @@ -78,14 +81,14 @@ class PetTypeFormatterTests { * Helper method to produce some sample pet types just for test purpose * @return {@link Collection} of {@link PetType} */ - private List makePetTypes() { - List petTypes = new ArrayList<>(); - petTypes.add(new PetType() { + private List makePetTypes() { + List petTypes = new ArrayList<>(); + petTypes.add(new PetTypeDTO() { { setName("Dog"); } }); - petTypes.add(new PetType() { + petTypes.add(new PetTypeDTO() { { setName("Bird"); } From 66c486891a524dabbf74eacbcae9ea1560ce9526 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 12:22:17 +0200 Subject: [PATCH 04/16] Change PetTypeFormatter and Validator to use DTO --- .../petclinic/controller/OwnerController.java | 9 +- .../petclinic/controller/PetController.java | 11 +- .../petclinic/validator/PetDTOValidator.java | 65 ++++++++ .../petclinic/validator/PetValidator.java | 2 +- .../controller/OwnerControllerTests.java | 152 +++++++++++------- .../owner/PetTypeDTOFormatterTests.java | 97 +++++++++++ 6 files changed, 263 insertions(+), 73 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java create mode 100644 src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 47ab04ad2..8993161d9 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -22,10 +22,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; @@ -53,7 +50,7 @@ class OwnerController { this.visitService = visitService; } - @InitBinder + @InitBinder("owner") public void setAllowedFields(WebDataBinder dataBinder) { dataBinder.setDisallowedFields("id"); } @@ -66,7 +63,7 @@ class OwnerController { } @PostMapping("/owners/new") - public String processCreationForm(@Valid OwnerDTO owner, BindingResult result) { + public String processCreationForm(@ModelAttribute("owner") @Valid OwnerDTO owner, BindingResult result) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index 2bd6eb9a3..198b83923 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -16,7 +16,7 @@ package org.springframework.samples.petclinic.controller; import org.springframework.samples.petclinic.dto.*; -import org.springframework.samples.petclinic.validator.PetValidator; +import org.springframework.samples.petclinic.validator.PetDTOValidator; import org.springframework.samples.petclinic.service.*; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; @@ -69,7 +69,7 @@ class PetController { @InitBinder("pet") public void initPetBinder(WebDataBinder dataBinder) { - dataBinder.setValidator(new PetValidator()); + dataBinder.setValidator(new PetDTOValidator()); } @GetMapping("/pets/new") @@ -81,11 +81,12 @@ class PetController { } @PostMapping("/pets/new") - public String processCreationForm(OwnerDTO ownerDTO, @Valid PetDTO pet, BindingResult result, ModelMap model) { - if (StringUtils.hasLength(pet.getName()) && pet.isNew() && ownerDTO.getPet(pet.getName(), true) != null) { + public String processCreationForm(@ModelAttribute("owner") OwnerDTO owner, + @ModelAttribute("pet") @Valid PetDTO pet, BindingResult result, ModelMap model) { + if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { result.rejectValue("name", "duplicate", "already exists"); } - ownerDTO.addPet(pet); + owner.addPet(pet); if (result.hasErrors()) { model.put("pet", pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; diff --git a/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java b/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java new file mode 100644 index 000000000..90333ff6b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.validator; + +import org.springframework.samples.petclinic.dto.PetDTO; +import org.springframework.util.StringUtils; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +/** + * Validator for PetDTO forms. + *

+ * We're not using Bean Validation annotations here because it is easier to define such + * validation rule in Java. + *

+ * + * @author Ken Krebs + * @author Juergen Hoeller + */ +public class PetDTOValidator implements Validator { + + private static final String REQUIRED = "required"; + + @Override + public void validate(Object obj, Errors errors) { + PetDTO pet = (PetDTO) obj; + String name = pet.getName(); + // name validation + if (!StringUtils.hasLength(name)) { + errors.rejectValue("name", REQUIRED, REQUIRED); + } + + // type validation + if (pet.isNew() && pet.getType() == null) { + errors.rejectValue("type", REQUIRED, REQUIRED); + } + + // birth date validation + if (pet.getBirthDate() == null) { + errors.rejectValue("birthDate", REQUIRED, REQUIRED); + } + } + + /** + * This Validator validates *just* Pet instances + */ + @Override + public boolean supports(Class clazz) { + return PetDTO.class.isAssignableFrom(clazz); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java index 6c96f217d..c85c4113e 100644 --- a/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java @@ -37,7 +37,7 @@ public class PetValidator implements Validator { @Override public void validate(Object obj, Errors errors) { - PetDTO pet = (PetDTO) obj; + Pet pet = (Pet) obj; String name = pet.getName(); // name validation if (!StringUtils.hasLength(name)) { diff --git a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java index 82fda30c4..eff339087 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java @@ -93,111 +93,141 @@ class OwnerControllerTests { @Test void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/new")).andExpect(status().isOk()).andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + mockMvc.perform(get("/owners/new")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @Test void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs") - .param("address", "123 Caramel Street").param("city", "London").param("telephone", "01316761638")) - .andExpect(status().is3xxRedirection()); + mockMvc.perform(post("/owners/new") + .param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("address", "123 Caramel Street") + .param("city", "London") + .param("telephone", "01316761638")) + .andExpect(status().is3xxRedirection()); } @Test void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform( - post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London")) - .andExpect(status().isOk()).andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + mockMvc.perform(post("/owners/new") + .param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("city", "London")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @Test void testInitFindForm() throws Exception { - mockMvc.perform(get("/owners/find")).andExpect(status().isOk()).andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/findOwners")); + mockMvc.perform(get("/owners/find")) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/findOwners")); } @Test void testProcessFindFormSuccess() throws Exception { given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new OwnerDTO())); - mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList")); + + mockMvc.perform(get("/owners")) + .andExpect(status().isOk()) + .andExpect(view().name("owners/ownersList")); } @Test void testProcessFindFormByLastName() throws Exception { given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); - mockMvc.perform(get("/owners").param("lastName", "Franklin")).andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); + + mockMvc.perform(get("/owners") + .param("lastName", "Franklin")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); } @Test void testProcessFindFormNoOwnersFound() throws Exception { - mockMvc.perform(get("/owners").param("lastName", "Unknown Surname")).andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors("owner", "lastName")) - .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) - .andExpect(view().name("owners/findOwners")); + mockMvc.perform(get("/owners") + .param("lastName", "Unknown Surname")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasFieldErrors("owner", "lastName")) + .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) + .andExpect(view().name("owners/findOwners")); } @Test void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)).andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) + .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) + .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @Test void testProcessUpdateOwnerFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") - .param("lastName", "Bloggs").param("address", "123 Caramel Street").param("city", "London") - .param("telephone", "01616291589")).andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) + .param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("address", "123 Caramel Street") + .param("city", "London") + .param("telephone", "01616291589")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); } @Test void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") - .param("lastName", "Bloggs").param("city", "London")).andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) + .param("firstName", "Joe") + .param("lastName", "Bloggs") + .param("city", "London")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @Test void testShowOwner() throws Exception { - mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)).andExpect(status().isOk()) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .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>() { + mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) + .andExpect(status().isOk()) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) + .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>() { - @Override - public boolean matches(Object item) { - @SuppressWarnings("unchecked") - List pets = (List) item; - PetDTO pet = pets.get(0); - if (pet.getVisits().isEmpty()) { - return false; - } - return true; - } + @Override + public boolean matches(Object item) { + @SuppressWarnings("unchecked") + List pets = (List) item; + PetDTO pet = pets.get(0); + if (pet.getVisits().isEmpty()) { + return false; + } - @Override - public void describeTo(Description description) { - description.appendText("Max did not have any visits"); - } - }))).andExpect(view().name("owners/ownerDetails")); + return true; + } + + @Override + public void describeTo(Description description) { + description.appendText("Max did not have any visits"); + } + }))) + .andExpect(view().name("owners/ownerDetails")); } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java new file mode 100644 index 000000000..f66381753 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java @@ -0,0 +1,97 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.owner; + +import org.junit.jupiter.api.Assertions; +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.samples.petclinic.dto.PetTypeDTO; +import org.springframework.samples.petclinic.service.PetTypeService; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +/** + * Test class for {@link PetTypeFormatter} + * + * @author Colin But + */ +@ExtendWith(MockitoExtension.class) +class PetTypeDTOFormatterTests { + + @Mock + private PetTypeService petTypeService; + + private PetTypeFormatter petTypeFormatter; + + @BeforeEach + void setup() { + this.petTypeFormatter = new PetTypeFormatter(petTypeService); + } + + @Test + void testPrint() { + PetTypeDTO petType = new PetTypeDTO(); + petType.setName("Hamster"); + String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); + assertThat(petTypeName).isEqualTo("Hamster"); + } + + @Test + void shouldParse() throws ParseException { + given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); + PetTypeDTO petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); + assertThat(petType.getName()).isEqualTo("Bird"); + } + + @Test + void shouldThrowParseException() throws ParseException { + given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); + Assertions.assertThrows(ParseException.class, () -> { + petTypeFormatter.parse("Fish", Locale.ENGLISH); + }); + } + + /** + * Helper method to produce some sample pet types just for test purpose + * @return {@link Collection} of {@link PetType} + */ + private List makePetTypes() { + List petTypes = new ArrayList<>(); + petTypes.add(new PetTypeDTO() { + { + setName("Dog"); + } + }); + petTypes.add(new PetTypeDTO() { + { + setName("Bird"); + } + }); + return petTypes; + } + +} From e77795d7f145adc5d3d1caeb43a2fc0449dae00a Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 15:15:09 +0200 Subject: [PATCH 05/16] solver @ModelAttributes in OwnerController Implement CommonAttribute for owner attributes names constants --- .../petclinic/common/CommonAttribute.java | 17 ++++ .../petclinic/controller/OwnerController.java | 19 ++--- .../controller/OwnerControllerTests.java | 79 ++++++++++--------- 3 files changed, 67 insertions(+), 48 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java b/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java new file mode 100644 index 000000000..5b312df20 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java @@ -0,0 +1,17 @@ +package org.springframework.samples.petclinic.common; + +public final class CommonAttribute { + public static String NAME = "name"; + + public static String OWNER = "owner"; + public static String OWNER_LAST_NAME = "lastName"; + public static String OWNER_FIRST_NAME = "firstName"; + public static String OWNER_PHONE = "telephone"; + public static String OWNER_ADDRESS = "address"; + public static String OWNER_CITY = "city"; + public static String OWNER_PETS = "pets"; + + private CommonAttribute() { + throw new IllegalStateException("Utility class"); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 8993161d9..7198334ef 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -15,6 +15,7 @@ */ package org.springframework.samples.petclinic.controller; +import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.dto.*; import org.springframework.samples.petclinic.service.OwnerService; import org.springframework.samples.petclinic.service.VisitService; @@ -58,7 +59,7 @@ class OwnerController { @GetMapping("/owners/new") public String initCreationForm(Map model) { OwnerDTO owner = new OwnerDTO(); - model.put("owner", owner); + model.put(CommonAttribute.OWNER, owner); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } @@ -75,12 +76,12 @@ class OwnerController { @GetMapping("/owners/find") public String initFindForm(Map model) { - model.put("owner", new OwnerDTO()); + model.put(CommonAttribute.OWNER, new OwnerDTO()); return "owners/findOwners"; } @GetMapping("/owners") - public String processFindForm(OwnerDTO owner, BindingResult result, Map model) { + public String processFindForm(@ModelAttribute("owner") OwnerDTO owner, BindingResult result, Map model) { // allow parameterless GET request for /owners to return all records if (owner.getLastName() == null) { @@ -91,7 +92,7 @@ class OwnerController { Collection results = this.ownerService.findByLastName(owner.getLastName()); if (results.isEmpty()) { // no owners found - result.rejectValue("lastName", "notFound", "not found"); + result.rejectValue(CommonAttribute.OWNER_LAST_NAME, "notFound", "not found"); return "owners/findOwners"; } else if (results.size() == 1) { @@ -109,12 +110,12 @@ class OwnerController { @GetMapping("/owners/{ownerId}/edit") public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { OwnerDTO ownerDTO = this.ownerService.findById(ownerId); - model.addAttribute(ownerDTO); + model.addAttribute(CommonAttribute.OWNER, ownerDTO); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } @PostMapping("/owners/{ownerId}/edit") - public String processUpdateOwnerForm(@Valid OwnerDTO owner, BindingResult result, + public String processUpdateOwnerForm(@ModelAttribute("owner") @Valid OwnerDTO owner, BindingResult result, @PathVariable("ownerId") int ownerId) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; @@ -133,15 +134,15 @@ class OwnerController { */ @GetMapping("/owners/{ownerId}") public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { - ModelAndView mav = new ModelAndView("owners/ownerDetails"); + ModelAndView modelAndView = new ModelAndView("owners/ownerDetails"); OwnerDTO owner = this.ownerService.findById(ownerId); for (PetDTO petDTO : owner.getPets()) { petDTO.setVisitsInternal(visitService.findByPetId(petDTO.getId())); } - mav.addObject(owner); - return mav; + modelAndView.addObject(CommonAttribute.OWNER, owner); + return modelAndView; } } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java index eff339087..f7c02d931 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java @@ -28,6 +28,7 @@ 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.common.CommonAttribute; import org.springframework.samples.petclinic.dto.OwnerDTO; import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.dto.PetTypeDTO; @@ -95,7 +96,7 @@ class OwnerControllerTests { void testInitCreationForm() throws Exception { mockMvc.perform(get("/owners/new")) .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) + .andExpect(model().attributeExists(CommonAttribute.OWNER)) .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @@ -103,10 +104,10 @@ class OwnerControllerTests { void testProcessCreationFormSuccess() throws Exception { mockMvc.perform(post("/owners/new") .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01316761638")) + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") + .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street") + .param(CommonAttribute.OWNER_CITY, "London") + .param(CommonAttribute.OWNER_PHONE, "01316761638")) .andExpect(status().is3xxRedirection()); } @@ -114,12 +115,12 @@ class OwnerControllerTests { void testProcessCreationFormHasErrors() throws Exception { mockMvc.perform(post("/owners/new") .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London")) + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") + .param(CommonAttribute.OWNER_CITY, "London")) .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @@ -127,7 +128,7 @@ class OwnerControllerTests { void testInitFindForm() throws Exception { mockMvc.perform(get("/owners/find")) .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) + .andExpect(model().attributeExists(CommonAttribute.OWNER)) .andExpect(view().name("owners/findOwners")); } @@ -145,7 +146,7 @@ class OwnerControllerTests { given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); mockMvc.perform(get("/owners") - .param("lastName", "Franklin")) + .param(CommonAttribute.OWNER_LAST_NAME, "Franklin")) .andExpect(status().is3xxRedirection()) .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); } @@ -153,10 +154,10 @@ class OwnerControllerTests { @Test void testProcessFindFormNoOwnersFound() throws Exception { mockMvc.perform(get("/owners") - .param("lastName", "Unknown Surname")) + .param(CommonAttribute.OWNER_LAST_NAME,"Unknown Surname")) .andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors("owner", "lastName")) - .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME)) + .andExpect(model().attributeHasFieldErrorCode(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME, "notFound")) .andExpect(view().name("owners/findOwners")); } @@ -164,23 +165,23 @@ class OwnerControllerTests { void testInitUpdateOwnerForm() throws Exception { mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(model().attributeExists(CommonAttribute.OWNER)) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @Test void testProcessUpdateOwnerFormSuccess() throws Exception { mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01616291589")) + .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") + .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street") + .param(CommonAttribute.OWNER_CITY, "London") + .param(CommonAttribute.OWNER_PHONE, "01616291589")) .andExpect(status().is3xxRedirection()) .andExpect(view().name("redirect:/owners/{ownerId}")); } @@ -188,13 +189,13 @@ class OwnerControllerTests { @Test void testProcessUpdateOwnerFormHasErrors() throws Exception { mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London")) + .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") + .param(CommonAttribute.OWNER_CITY, "London")) .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) .andExpect(view().name("owners/createOrUpdateOwnerForm")); } @@ -202,13 +203,13 @@ class OwnerControllerTests { void testShowOwner() throws Exception { mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) .andExpect(status().isOk()) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .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>() { + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PETS, not(empty())))) + .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PETS, new BaseMatcher>() { @Override public boolean matches(Object item) { From da3666f1aa9f1cd270cd0fa4a80b2a90da401cc2 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 16:24:19 +0200 Subject: [PATCH 06/16] solver @ModelAttributes in OwnerController Implement CommonAttribute for owner attributes names constants --- .../petclinic/common/CommonAttribute.java | 25 +++++--- .../petclinic/common/CommonEndPoint.java | 18 ++++++ .../samples/petclinic/common/CommonError.java | 17 ++++++ .../samples/petclinic/common/CommonView.java | 19 +++++++ .../petclinic/controller/OwnerController.java | 57 ++++++++++--------- .../petclinic/controller/PetController.java | 23 ++++---- .../controller/OwnerControllerTests.java | 47 ++++++++------- .../controller/PetControllerTests.java | 48 ++++++++++------ 8 files changed, 169 insertions(+), 85 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java create mode 100644 src/main/java/org/springframework/samples/petclinic/common/CommonError.java create mode 100644 src/main/java/org/springframework/samples/petclinic/common/CommonView.java diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java b/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java index 5b312df20..eb2bc444b 100644 --- a/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java @@ -1,15 +1,24 @@ package org.springframework.samples.petclinic.common; +/** + * Class for const attributes names to prevent error with attributes names + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ public final class CommonAttribute { - public static String NAME = "name"; + public static final String NAME = "name"; + public static final String SELECTIONS = "selections"; - public static String OWNER = "owner"; - public static String OWNER_LAST_NAME = "lastName"; - public static String OWNER_FIRST_NAME = "firstName"; - public static String OWNER_PHONE = "telephone"; - public static String OWNER_ADDRESS = "address"; - public static String OWNER_CITY = "city"; - public static String OWNER_PETS = "pets"; + public static final String OWNER = "owner"; + public static final String OWNER_ID = "id"; + public static final String OWNER_LAST_NAME = "lastName"; + public static final String OWNER_FIRST_NAME = "firstName"; + public static final String OWNER_PHONE = "telephone"; + public static final String OWNER_ADDRESS = "address"; + public static final String OWNER_CITY = "city"; + public static final String OWNER_PETS = "pets"; + + public static final String PET = "pet"; private CommonAttribute() { throw new IllegalStateException("Utility class"); diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java b/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java new file mode 100644 index 000000000..923a607ab --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java @@ -0,0 +1,18 @@ +package org.springframework.samples.petclinic.common; + +/** + * Class for const endpoint names to prevent error with endpoint names + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public final class CommonEndPoint { + public static final String OWNERS = "/owners"; + public static final String OWNERS_FIND = "/owners/find"; + public static final String OWNERS_ID = "/owners/{ownerId}"; + public static final String OWNERS_ID_EDIT = "/owners/{ownerId}/edit"; + public static final String OWNERS_NEW = "/owners/new"; + + private CommonEndPoint() { + throw new IllegalStateException("Utility class"); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonError.java b/src/main/java/org/springframework/samples/petclinic/common/CommonError.java new file mode 100644 index 000000000..7778b2a00 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonError.java @@ -0,0 +1,17 @@ +package org.springframework.samples.petclinic.common; + +/** + * Class for const error names to prevent errors + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public final class CommonError { + public static final String DUPLICATE_ARGS = "duplicate"; + public static final String DUPLICATE_MESSAGE = "already exists"; + public static final String NOT_FOUND_ARGS = "notFound"; + public static final String NOT_FOUND_MESSAGE = "notFound"; + + private CommonError() { + throw new IllegalStateException("Utility class"); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonView.java b/src/main/java/org/springframework/samples/petclinic/common/CommonView.java new file mode 100644 index 000000000..caeb76164 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonView.java @@ -0,0 +1,19 @@ +package org.springframework.samples.petclinic.common; + +/** + * Class for const view names to prevent error with view names + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public final class CommonView { + public static final String OWNER_OWNERS_R = "redirect:/owners/"; + public static final String OWNER_OWNERS_ID_R = "redirect:/owners/{ownerId}"; + public static final String OWNER_CREATE_OR_UPDATE = "owners/createOrUpdateOwnerForm"; + public static final String OWNER_FIND_OWNERS = "owners/findOwners"; + public static final String OWNER_OWNERS_LIST = "owners/ownersList"; + public static final String OWNER_DETAILS = "owners/ownerDetails"; + + private CommonView() { + throw new IllegalStateException("Utility class"); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 7198334ef..35807aac5 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -15,7 +15,11 @@ */ package org.springframework.samples.petclinic.controller; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonError; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.*; import org.springframework.samples.petclinic.service.OwnerService; import org.springframework.samples.petclinic.service.VisitService; @@ -39,13 +43,10 @@ import java.util.Map; */ @Controller class OwnerController { - - private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; - private final OwnerService ownerService; - private final VisitService visitService; + @Autowired OwnerController(OwnerService ownerService, VisitService visitService) { this.ownerService = ownerService; this.visitService = visitService; @@ -53,35 +54,35 @@ class OwnerController { @InitBinder("owner") public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); + dataBinder.setDisallowedFields(CommonAttribute.OWNER_ID); } - @GetMapping("/owners/new") + @GetMapping(CommonEndPoint.OWNERS_NEW) public String initCreationForm(Map model) { OwnerDTO owner = new OwnerDTO(); model.put(CommonAttribute.OWNER, owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + return CommonView.OWNER_CREATE_OR_UPDATE; } - @PostMapping("/owners/new") - public String processCreationForm(@ModelAttribute("owner") @Valid OwnerDTO owner, BindingResult result) { + @PostMapping(CommonEndPoint.OWNERS_NEW) + public String processCreationForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, BindingResult result) { if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + return CommonView.OWNER_CREATE_OR_UPDATE; } else { this.ownerService.save(owner); - return "redirect:/owners/" + owner.getId(); + return CommonView.OWNER_OWNERS_R + owner.getId(); } } - @GetMapping("/owners/find") + @GetMapping(CommonEndPoint.OWNERS_FIND) public String initFindForm(Map model) { model.put(CommonAttribute.OWNER, new OwnerDTO()); - return "owners/findOwners"; + return CommonView.OWNER_FIND_OWNERS; } - @GetMapping("/owners") - public String processFindForm(@ModelAttribute("owner") OwnerDTO owner, BindingResult result, Map model) { + @GetMapping(CommonEndPoint.OWNERS) + public String processFindForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, BindingResult result, Map model) { // allow parameterless GET request for /owners to return all records if (owner.getLastName() == null) { @@ -92,38 +93,38 @@ class OwnerController { Collection results = this.ownerService.findByLastName(owner.getLastName()); if (results.isEmpty()) { // no owners found - result.rejectValue(CommonAttribute.OWNER_LAST_NAME, "notFound", "not found"); - return "owners/findOwners"; + result.rejectValue(CommonAttribute.OWNER_LAST_NAME, CommonError.NOT_FOUND_ARGS, CommonError.NOT_FOUND_MESSAGE); + return CommonView.OWNER_FIND_OWNERS; } else if (results.size() == 1) { // 1 owner found owner = results.iterator().next(); - return "redirect:/owners/" + owner.getId(); + return CommonView.OWNER_OWNERS_R + owner.getId(); } else { // multiple owners found - model.put("selections", results); - return "owners/ownersList"; + model.put(CommonAttribute.SELECTIONS, results); + return CommonView.OWNER_OWNERS_LIST; } } - @GetMapping("/owners/{ownerId}/edit") + @GetMapping(CommonEndPoint.OWNERS_ID_EDIT) public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { OwnerDTO ownerDTO = this.ownerService.findById(ownerId); model.addAttribute(CommonAttribute.OWNER, ownerDTO); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + return CommonView.OWNER_CREATE_OR_UPDATE; } - @PostMapping("/owners/{ownerId}/edit") - public String processUpdateOwnerForm(@ModelAttribute("owner") @Valid OwnerDTO owner, BindingResult result, + @PostMapping(CommonEndPoint.OWNERS_ID_EDIT) + public String processUpdateOwnerForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, BindingResult result, @PathVariable("ownerId") int ownerId) { if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + return CommonView.OWNER_CREATE_OR_UPDATE; } else { owner.setId(ownerId); this.ownerService.save(owner); - return "redirect:/owners/{ownerId}"; + return CommonView.OWNER_OWNERS_ID_R; } } @@ -132,9 +133,9 @@ class OwnerController { * @param ownerId the ID of the owner to display * @return a ModelMap with the model attributes for the view */ - @GetMapping("/owners/{ownerId}") + @GetMapping(CommonEndPoint.OWNERS_ID) public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { - ModelAndView modelAndView = new ModelAndView("owners/ownerDetails"); + ModelAndView modelAndView = new ModelAndView(CommonView.OWNER_DETAILS); OwnerDTO owner = this.ownerService.findById(ownerId); for (PetDTO petDTO : owner.getPets()) { diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index 198b83923..eb9726b32 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -15,6 +15,9 @@ */ package org.springframework.samples.petclinic.controller; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonError; import org.springframework.samples.petclinic.dto.*; import org.springframework.samples.petclinic.validator.PetDTOValidator; import org.springframework.samples.petclinic.service.*; @@ -64,7 +67,7 @@ class PetController { @InitBinder("owner") public void initOwnerBinder(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); + dataBinder.setDisallowedFields(CommonAttribute.OWNER_ID); } @InitBinder("pet") @@ -73,22 +76,22 @@ class PetController { } @GetMapping("/pets/new") - public String initCreationForm(OwnerDTO owner, ModelMap model) { + public String initCreationForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, ModelMap model) { PetDTO pet = new PetDTO(); owner.addPet(pet); - model.put("pet", pet); + model.put(CommonAttribute.PET, pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } @PostMapping("/pets/new") - public String processCreationForm(@ModelAttribute("owner") OwnerDTO owner, - @ModelAttribute("pet") @Valid PetDTO pet, BindingResult result, ModelMap model) { + public String processCreationForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, + @ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, ModelMap model) { if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { - result.rejectValue("name", "duplicate", "already exists"); + result.rejectValue(CommonAttribute.NAME, CommonError.DUPLICATE_ARGS, CommonError.DUPLICATE_MESSAGE); } owner.addPet(pet); if (result.hasErrors()) { - model.put("pet", pet); + model.put(CommonAttribute.PET, pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } else { this.petService.save(pet); @@ -99,15 +102,15 @@ class PetController { @GetMapping("/pets/{petId}/edit") public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { PetDTO pet = this.petService.findById(petId); - model.put("pet", pet); + model.put(CommonAttribute.PET, pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } @PostMapping("/pets/{petId}/edit") - public String processUpdateForm(@Valid PetDTO pet, BindingResult result, OwnerDTO owner, ModelMap model) { + public String processUpdateForm(@ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, OwnerDTO owner, ModelMap model) { if (result.hasErrors()) { pet.setOwner(owner); - model.put("pet", pet); + model.put(CommonAttribute.PET, pet); return VIEWS_PETS_CREATE_OR_UPDATE_FORM; } else { diff --git a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java index f7c02d931..b429be5c4 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java @@ -29,6 +29,8 @@ 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.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.OwnerDTO; import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.dto.PetTypeDTO; @@ -52,6 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * Test class for {@link OwnerController} * * @author Colin But + * @author Paul-Emmanuel DOS SANTOS FACAO */ @WebMvcTest(OwnerController.class) class OwnerControllerTests { @@ -94,16 +97,16 @@ class OwnerControllerTests { @Test void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/new")) + mockMvc.perform(get(CommonEndPoint.OWNERS_NEW)) .andExpect(status().isOk()) .andExpect(model().attributeExists(CommonAttribute.OWNER)) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test void testProcessCreationFormSuccess() throws Exception { mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") + .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street") .param(CommonAttribute.OWNER_CITY, "London") @@ -113,57 +116,57 @@ class OwnerControllerTests { @Test void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") + mockMvc.perform(post(CommonEndPoint.OWNERS_NEW) + .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") .param(CommonAttribute.OWNER_CITY, "London")) .andExpect(status().isOk()) .andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test void testInitFindForm() throws Exception { - mockMvc.perform(get("/owners/find")) + mockMvc.perform(get(CommonEndPoint.OWNERS_FIND)) .andExpect(status().isOk()) .andExpect(model().attributeExists(CommonAttribute.OWNER)) - .andExpect(view().name("owners/findOwners")); + .andExpect(view().name(CommonView.OWNER_FIND_OWNERS)); } @Test void testProcessFindFormSuccess() throws Exception { given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new OwnerDTO())); - mockMvc.perform(get("/owners")) + mockMvc.perform(get(CommonEndPoint.OWNERS)) .andExpect(status().isOk()) - .andExpect(view().name("owners/ownersList")); + .andExpect(view().name(CommonView.OWNER_OWNERS_LIST)); } @Test void testProcessFindFormByLastName() throws Exception { given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); - mockMvc.perform(get("/owners") + mockMvc.perform(get(CommonEndPoint.OWNERS) .param(CommonAttribute.OWNER_LAST_NAME, "Franklin")) .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); + .andExpect(view().name(CommonView.OWNER_OWNERS_R + TEST_OWNER_ID)); } @Test void testProcessFindFormNoOwnersFound() throws Exception { - mockMvc.perform(get("/owners") + mockMvc.perform(get(CommonEndPoint.OWNERS) .param(CommonAttribute.OWNER_LAST_NAME,"Unknown Surname")) .andExpect(status().isOk()) .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME)) .andExpect(model().attributeHasFieldErrorCode(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME, "notFound")) - .andExpect(view().name("owners/findOwners")); + .andExpect(view().name(CommonView.OWNER_FIND_OWNERS)); } @Test void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) + mockMvc.perform(get(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID)) .andExpect(status().isOk()) .andExpect(model().attributeExists(CommonAttribute.OWNER)) .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) @@ -171,24 +174,24 @@ class OwnerControllerTests { .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test void testProcessUpdateOwnerFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) + mockMvc.perform(post(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID) .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street") .param(CommonAttribute.OWNER_CITY, "London") .param(CommonAttribute.OWNER_PHONE, "01616291589")) .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + .andExpect(view().name(CommonView.OWNER_OWNERS_ID_R)); } @Test void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) + mockMvc.perform(post(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID) .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") .param(CommonAttribute.OWNER_CITY, "London")) @@ -196,12 +199,12 @@ class OwnerControllerTests { .andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test void testShowOwner() throws Exception { - mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) + mockMvc.perform(get(CommonEndPoint.OWNERS_ID, TEST_OWNER_ID)) .andExpect(status().isOk()) .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) @@ -228,7 +231,7 @@ class OwnerControllerTests { description.appendText("Max did not have any visits"); } }))) - .andExpect(view().name("owners/ownerDetails")); + .andExpect(view().name(CommonView.OWNER_DETAILS)); } } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java index 011842c87..87008e6e5 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java @@ -70,23 +70,28 @@ class PetControllerTests { PetTypeDTO cat = new PetTypeDTO(); cat.setId(3); cat.setName("hamster"); + 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()); - } @Test void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet")); + mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)) + .andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")) + .andExpect(model().attributeExists("pet")); } @Test void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty") - .param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) + .param("name", "Betty") + .param("type", "hamster") + .param("birthDate", "2015-02-12")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); } @Test @@ -95,31 +100,40 @@ class PetControllerTests { .param("name", "Betty") .param("birthDate","2015-02-12")) .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type")) - .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("pet")) + .andExpect(model().attributeHasFieldErrors("pet", "type")) + .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")) + .andExpect(status().isOk()) .andExpect(view().name("pets/createOrUpdatePetForm")); } @Test void testInitUpdateForm() throws Exception { mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) - .andExpect(status().isOk()).andExpect(model().attributeExists("pet")) - .andExpect(view().name("pets/createOrUpdatePetForm")); + .andExpect(status().isOk()) + .andExpect(model().attributeExists("pet")) + .andExpect(view().name("pets/createOrUpdatePetForm")); } @Test void testProcessUpdateFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty") - .param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) + .param("name", "Betty") + .param("type", "hamster") + .param("birthDate", "2015-02-12")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); } @Test void testProcessUpdateFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty") - .param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); + mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) + .param("name", "Betty") + .param("birthDate", "2015/02/12")) + .andExpect(model().attributeHasNoErrors("owner")) + .andExpect(model().attributeHasErrors("pet")) + .andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")); } } From a564611681a996a2c1e05a1b1f775d32ab081791 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 17:24:50 +0200 Subject: [PATCH 07/16] solver @ModelAttributes in OwnerController Implement CommonAttribute for owner attributes names constants --- .../samples/petclinic/controller/OwnerController.java | 1 - .../samples/petclinic/controller/VisitController.java | 2 +- .../samples/petclinic/controller/PetControllerTests.java | 2 +- .../samples/petclinic/controller/VisitControllerTests.java | 5 +++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 35807aac5..b34261e56 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -46,7 +46,6 @@ class OwnerController { private final OwnerService ownerService; private final VisitService visitService; - @Autowired OwnerController(OwnerService ownerService, VisitService visitService) { this.ownerService = ownerService; this.visitService = visitService; diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java index c7dc9dc9f..1e0d411e8 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java @@ -82,7 +82,7 @@ class VisitController { // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") - public String processNewVisitForm(@Valid VisitDTO visit, BindingResult result) { + public String processNewVisitForm(@ModelAttribute("visit") @Valid VisitDTO visit, BindingResult result) { if (result.hasErrors()) { return "pets/createOrUpdateVisitForm"; } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java index 87008e6e5..5222af95b 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java @@ -71,9 +71,9 @@ class PetControllerTests { cat.setId(3); cat.setName("hamster"); - 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()); + given(this.petTypeService.findPetTypes()).willReturn(Lists.newArrayList(cat)); } @Test diff --git a/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java index eec30afb8..7bc0e5f4d 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java @@ -59,8 +59,9 @@ class VisitControllerTests { @Test void testInitNewVisitForm() throws Exception { - mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); + mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)) + .andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdateVisitForm")); } @Test From e041803e588f93f4ca6aafce298f61f34c7e2624 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 17:44:38 +0200 Subject: [PATCH 08/16] Solved getter bug in PetDTO --- .../samples/petclinic/controller/PetController.java | 1 + .../java/org/springframework/samples/petclinic/dto/PetDTO.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index eb9726b32..45f7c7b36 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -49,6 +49,7 @@ class PetController { private final PetTypeService petTypeService; + @Autowired PetController(OwnerService ownerService, PetService petService, PetTypeService petTypeService) { this.ownerService = ownerService; this.petService = petService; diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java index af838e665..5b5925adc 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -54,7 +54,7 @@ public class PetDTO extends NamedDTO { this.type = type; } - public OwnerDTO getOwnerDTO() { + public OwnerDTO getOwner() { return owner; } From 20cfa0a0785e9a0a348bb2279802754a51855b37 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 10 Oct 2020 19:05:15 +0200 Subject: [PATCH 09/16] Add @Tag and refactoring directories --- .../petclinic/common/CommonAttribute.java | 26 ++- .../petclinic/common/CommonEndPoint.java | 18 ++ .../samples/petclinic/common/CommonError.java | 9 + .../samples/petclinic/common/CommonView.java | 13 ++ .../petclinic/controller/OwnerController.java | 16 +- .../petclinic/controller/PetController.java | 34 ++-- .../petclinic/controller/VetController.java | 12 +- .../petclinic/controller/VisitController.java | 18 +- .../samples/petclinic/dto/OwnerDTO.java | 11 +- .../samples/petclinic/dto/VetDTO.java | 2 +- .../PetTypeFormatter.java | 4 +- .../petclinic/{owner => model}/Owner.java | 14 +- .../petclinic/{owner => model}/Pet.java | 4 +- .../petclinic/{owner => model}/PetType.java | 4 +- .../petclinic/{vet => model}/Specialty.java | 4 +- .../samples/petclinic/{vet => model}/Vet.java | 3 +- .../petclinic/{vet => model}/Vets.java | 2 +- .../petclinic/{visit => model}/Visit.java | 3 +- .../petclinic/repository/OwnerRepository.java | 2 +- .../petclinic/repository/PetRepository.java | 4 +- .../petclinic/repository/VetRepository.java | 2 +- .../petclinic/repository/VisitRepository.java | 2 +- .../petclinic/service/OwnerService.java | 2 +- .../samples/petclinic/service/PetService.java | 2 +- .../petclinic/service/PetTypeService.java | 2 +- .../petclinic/service/SpecialityService.java | 2 +- .../samples/petclinic/service/VetService.java | 2 +- .../petclinic/service/VisitService.java | 2 +- .../petclinic/system/CacheConfiguration.java | 4 +- .../petclinic/validator/PetDTOValidator.java | 11 +- .../petclinic/validator/PetValidator.java | 14 +- .../controller/OwnerControllerTests.java | 181 +++++++++--------- .../controller/PetControllerTests.java | 77 ++++---- .../controller/VetControllerTests.java | 18 +- .../controller/VisitControllerTests.java | 24 ++- .../PetTypeDTOFormatterTests.java | 4 +- .../PetTypeFormatterTests.java | 6 +- .../petclinic/{vet => model}/VetTests.java | 2 +- .../petclinic/service/ClinicServiceTests.java | 10 +- .../{model => validator}/ValidatorTests.java | 3 +- 40 files changed, 334 insertions(+), 239 deletions(-) rename src/main/java/org/springframework/samples/petclinic/{owner => formatter}/PetTypeFormatter.java (92%) rename src/main/java/org/springframework/samples/petclinic/{owner => model}/Owner.java (86%) rename src/main/java/org/springframework/samples/petclinic/{owner => model}/Pet.java (93%) mode change 100755 => 100644 rename src/main/java/org/springframework/samples/petclinic/{owner => model}/PetType.java (87%) rename src/main/java/org/springframework/samples/petclinic/{vet => model}/Specialty.java (88%) rename src/main/java/org/springframework/samples/petclinic/{vet => model}/Vet.java (95%) rename src/main/java/org/springframework/samples/petclinic/{vet => model}/Vets.java (95%) rename src/main/java/org/springframework/samples/petclinic/{visit => model}/Visit.java (93%) mode change 100755 => 100644 rename src/test/java/org/springframework/samples/petclinic/{owner => formater}/PetTypeDTOFormatterTests.java (93%) rename src/test/java/org/springframework/samples/petclinic/{owner => formater}/PetTypeFormatterTests.java (93%) rename src/test/java/org/springframework/samples/petclinic/{vet => model}/VetTests.java (95%) rename src/test/java/org/springframework/samples/petclinic/{model => validator}/ValidatorTests.java (94%) diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java b/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java index eb2bc444b..4fe322fd1 100644 --- a/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonAttribute.java @@ -6,21 +6,45 @@ package org.springframework.samples.petclinic.common; * @author Paul-Emmanuel DOS SANTOS FACAO */ public final class CommonAttribute { + + public static final String DESCRIPTION = "description"; + public static final String NAME = "name"; - public static final String SELECTIONS = "selections"; + + public static final String NEW = "new"; public static final String OWNER = "owner"; + public static final String OWNER_ID = "id"; + public static final String OWNER_LAST_NAME = "lastName"; + public static final String OWNER_FIRST_NAME = "firstName"; + public static final String OWNER_PHONE = "telephone"; + public static final String OWNER_ADDRESS = "address"; + public static final String OWNER_CITY = "city"; + public static final String OWNER_PETS = "pets"; public static final String PET = "pet"; + public static final String SELECTIONS = "selections"; + + public static final String PET_BIRTH_DATE = "birthDate"; + + public static final String PET_NAME = "name"; + + public static final String PET_TYPE = "type"; + + public static final String VETS = "vets"; + + public static final String VISIT = "visit"; + private CommonAttribute() { throw new IllegalStateException("Utility class"); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java b/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java index 923a607ab..fa4177eb1 100644 --- a/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonEndPoint.java @@ -6,13 +6,31 @@ package org.springframework.samples.petclinic.common; * @author Paul-Emmanuel DOS SANTOS FACAO */ public final class CommonEndPoint { + public static final String OWNERS = "/owners"; + public static final String OWNERS_FIND = "/owners/find"; + public static final String OWNERS_ID = "/owners/{ownerId}"; + public static final String OWNERS_ID_EDIT = "/owners/{ownerId}/edit"; + public static final String OWNERS_NEW = "/owners/new"; + public static final String PETS_NEW = "/pets/new"; + + public static final String PETS_ID_EDIT = "/pets/{petId}/edit"; + + public static final String VETS = "/vets"; + + public static final String VETS_HTML = "/vets.html"; + + public static final String VISITS_NEW = "/owners/*/pets/{petId}/visits/new"; + + public static final String VISITS_EDIT = "/owners/{ownerId}/pets/{petId}/visits/new"; + private CommonEndPoint() { throw new IllegalStateException("Utility class"); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonError.java b/src/main/java/org/springframework/samples/petclinic/common/CommonError.java index 7778b2a00..c7144975d 100644 --- a/src/main/java/org/springframework/samples/petclinic/common/CommonError.java +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonError.java @@ -6,12 +6,21 @@ package org.springframework.samples.petclinic.common; * @author Paul-Emmanuel DOS SANTOS FACAO */ public final class CommonError { + public static final String DUPLICATE_ARGS = "duplicate"; + public static final String DUPLICATE_MESSAGE = "already exists"; + public static final String NOT_FOUND_ARGS = "notFound"; + public static final String NOT_FOUND_MESSAGE = "notFound"; + public static final String REQUIRED_ARGS = "required"; + + public static final String REQUIRED_MESSAGE = "required"; + private CommonError() { throw new IllegalStateException("Utility class"); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/common/CommonView.java b/src/main/java/org/springframework/samples/petclinic/common/CommonView.java index caeb76164..ddde0c73b 100644 --- a/src/main/java/org/springframework/samples/petclinic/common/CommonView.java +++ b/src/main/java/org/springframework/samples/petclinic/common/CommonView.java @@ -6,14 +6,27 @@ package org.springframework.samples.petclinic.common; * @author Paul-Emmanuel DOS SANTOS FACAO */ public final class CommonView { + public static final String OWNER_OWNERS_R = "redirect:/owners/"; + public static final String OWNER_OWNERS_ID_R = "redirect:/owners/{ownerId}"; + public static final String OWNER_CREATE_OR_UPDATE = "owners/createOrUpdateOwnerForm"; + public static final String OWNER_FIND_OWNERS = "owners/findOwners"; + public static final String OWNER_OWNERS_LIST = "owners/ownersList"; + public static final String OWNER_DETAILS = "owners/ownerDetails"; + public static final String PET_CREATE_OR_UPDATE = "pets/createOrUpdatePetForm"; + + public static final String VET_VETS_LIST = "vets/vetList"; + + public static final String VISIT_CREATE_OR_UPDATE = "pets/createOrUpdateVisitForm"; + private CommonView() { throw new IllegalStateException("Utility class"); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index b34261e56..6cfcec4ef 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.controller; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonError; @@ -43,7 +42,9 @@ import java.util.Map; */ @Controller class OwnerController { + private final OwnerService ownerService; + private final VisitService visitService; OwnerController(OwnerService ownerService, VisitService visitService) { @@ -64,7 +65,8 @@ class OwnerController { } @PostMapping(CommonEndPoint.OWNERS_NEW) - public String processCreationForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, BindingResult result) { + public String processCreationForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, + BindingResult result) { if (result.hasErrors()) { return CommonView.OWNER_CREATE_OR_UPDATE; } @@ -81,7 +83,8 @@ class OwnerController { } @GetMapping(CommonEndPoint.OWNERS) - public String processFindForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, BindingResult result, Map model) { + public String processFindForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, BindingResult result, + Map model) { // allow parameterless GET request for /owners to return all records if (owner.getLastName() == null) { @@ -92,7 +95,8 @@ class OwnerController { Collection results = this.ownerService.findByLastName(owner.getLastName()); if (results.isEmpty()) { // no owners found - result.rejectValue(CommonAttribute.OWNER_LAST_NAME, CommonError.NOT_FOUND_ARGS, CommonError.NOT_FOUND_MESSAGE); + result.rejectValue(CommonAttribute.OWNER_LAST_NAME, CommonError.NOT_FOUND_ARGS, + CommonError.NOT_FOUND_MESSAGE); return CommonView.OWNER_FIND_OWNERS; } else if (results.size() == 1) { @@ -115,8 +119,8 @@ class OwnerController { } @PostMapping(CommonEndPoint.OWNERS_ID_EDIT) - public String processUpdateOwnerForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, BindingResult result, - @PathVariable("ownerId") int ownerId) { + public String processUpdateOwnerForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, + BindingResult result, @PathVariable("ownerId") int ownerId) { if (result.hasErrors()) { return CommonView.OWNER_CREATE_OR_UPDATE; } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index 45f7c7b36..134ef0fb1 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -17,7 +17,9 @@ package org.springframework.samples.petclinic.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonError; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.*; import org.springframework.samples.petclinic.validator.PetDTOValidator; import org.springframework.samples.petclinic.service.*; @@ -38,11 +40,9 @@ import java.util.Collection; * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller -@RequestMapping("/owners/{ownerId}") +@RequestMapping(CommonEndPoint.OWNERS_ID) class PetController { - private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - private final OwnerService ownerService; private final PetService petService; @@ -76,48 +76,50 @@ class PetController { dataBinder.setValidator(new PetDTOValidator()); } - @GetMapping("/pets/new") + @GetMapping(CommonEndPoint.PETS_NEW) public String initCreationForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, ModelMap model) { PetDTO pet = new PetDTO(); owner.addPet(pet); model.put(CommonAttribute.PET, pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + return CommonView.PET_CREATE_OR_UPDATE; } - @PostMapping("/pets/new") + @PostMapping(CommonEndPoint.PETS_NEW) public String processCreationForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, - @ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, ModelMap model) { + @ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, ModelMap model) { if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { result.rejectValue(CommonAttribute.NAME, CommonError.DUPLICATE_ARGS, CommonError.DUPLICATE_MESSAGE); } owner.addPet(pet); if (result.hasErrors()) { model.put(CommonAttribute.PET, pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { + return CommonView.PET_CREATE_OR_UPDATE; + } + else { this.petService.save(pet); - return "redirect:/owners/{ownerId}"; + return CommonView.OWNER_OWNERS_ID_R; } } - @GetMapping("/pets/{petId}/edit") + @GetMapping(CommonEndPoint.PETS_ID_EDIT) public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { PetDTO pet = this.petService.findById(petId); model.put(CommonAttribute.PET, pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + return CommonView.PET_CREATE_OR_UPDATE; } - @PostMapping("/pets/{petId}/edit") - public String processUpdateForm(@ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, OwnerDTO owner, ModelMap model) { + @PostMapping(CommonEndPoint.PETS_ID_EDIT) + public String processUpdateForm(@ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, + OwnerDTO owner, ModelMap model) { if (result.hasErrors()) { pet.setOwner(owner); model.put(CommonAttribute.PET, pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + return CommonView.PET_CREATE_OR_UPDATE; } else { owner.addPet(pet); this.petService.save(pet); - return "redirect:/owners/{ownerId}"; + return CommonView.OWNER_OWNERS_ID_R; } } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VetController.java b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java index d3ae53e29..64f00ca2f 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java @@ -15,9 +15,11 @@ */ package org.springframework.samples.petclinic.controller; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.VetsDTO; import org.springframework.samples.petclinic.service.VetService; -import org.springframework.samples.petclinic.vet.Vets; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -40,17 +42,17 @@ class VetController { this.vetService = vetService; } - @GetMapping("/vets.html") + @GetMapping(CommonEndPoint.VETS_HTML) public String showVetList(Map model) { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for Object-Xml mapping VetsDTO vets = new VetsDTO(); vets.getVetList().addAll(this.vetService.findAll()); - model.put("vets", vets); - return "vets/vetList"; + model.put(CommonAttribute.VETS, vets); + return CommonView.VET_VETS_LIST; } - @GetMapping({ "/vets" }) + @GetMapping({ CommonEndPoint.VETS }) public @ResponseBody VetsDTO showResourcesVetList() { // Here we are returning an object of type 'Vets' rather than a collection of Vet // objects so it is simpler for JSon/Object mapping diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java index 1e0d411e8..a3e67a073 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java @@ -19,6 +19,9 @@ import java.util.Map; import javax.validation.Valid; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.dto.VisitDTO; import org.springframework.samples.petclinic.service.PetService; @@ -68,27 +71,28 @@ class VisitController { public VisitDTO loadPetWithVisit(@PathVariable("petId") int petId, Map model) { PetDTO pet = this.petService.findById(petId); pet.setVisitsInternal(this.visitService.findByPetId(petId)); - model.put("pet", pet); + model.put(CommonAttribute.PET, pet); VisitDTO visit = new VisitDTO(); pet.addVisit(visit); return visit; } // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called - @GetMapping("/owners/*/pets/{petId}/visits/new") + @GetMapping(CommonEndPoint.VISITS_NEW) public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { - return "pets/createOrUpdateVisitForm"; + return CommonView.PET_CREATE_OR_UPDATE; } // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called - @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") - public String processNewVisitForm(@ModelAttribute("visit") @Valid VisitDTO visit, BindingResult result) { + @PostMapping(CommonEndPoint.VISITS_EDIT) + public String processNewVisitForm(@ModelAttribute(CommonAttribute.VISIT) @Valid VisitDTO visit, + BindingResult result) { if (result.hasErrors()) { - return "pets/createOrUpdateVisitForm"; + return CommonView.VISIT_CREATE_OR_UPDATE; } else { this.visitService.save(visit); - return "redirect:/owners/{ownerId}"; + return CommonView.OWNER_OWNERS_ID_R; } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index 79ad5b660..60ee8a05d 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.dto; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.core.style.ToStringCreator; +import org.springframework.samples.petclinic.common.CommonAttribute; import javax.validation.constraints.Digits; import javax.validation.constraints.NotEmpty; @@ -120,11 +121,11 @@ public class OwnerDTO extends PersonDTO { @Override public String toString() { - return new ToStringCreator(this) - - .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName()) - .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city) - .append("telephone", this.telephone).toString(); + return new ToStringCreator(this).append(CommonAttribute.OWNER_ID, this.getId()) + .append(CommonAttribute.NEW, this.isNew()).append(CommonAttribute.OWNER_LAST_NAME, this.getLastName()) + .append(CommonAttribute.OWNER_FIRST_NAME, this.getFirstName()) + .append(CommonAttribute.OWNER_ADDRESS, this.address).append(CommonAttribute.OWNER_CITY, this.city) + .append(CommonAttribute.OWNER_PHONE, this.telephone).toString(); } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java index 048598218..880589592 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java @@ -17,7 +17,7 @@ package org.springframework.samples.petclinic.dto; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; -import org.springframework.samples.petclinic.vet.Specialty; +import org.springframework.samples.petclinic.model.Specialty; import javax.xml.bind.annotation.XmlElement; import java.util.*; diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java similarity index 92% rename from src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java rename to src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java index f2ab9b542..28330c383 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.formatter; import java.text.ParseException; import java.util.Collection; import java.util.Locale; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.Formatter; import org.springframework.samples.petclinic.dto.PetTypeDTO; import org.springframework.samples.petclinic.service.PetTypeService; @@ -38,7 +37,6 @@ import org.springframework.stereotype.Component; @Component public class PetTypeFormatter implements Formatter { - // private final PetRepository pets; private final PetTypeService petTypeService; public PetTypeFormatter(PetTypeService petTypeService) { diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java similarity index 86% rename from src/main/java/org/springframework/samples/petclinic/owner/Owner.java rename to src/main/java/org/springframework/samples/petclinic/model/Owner.java index 61083bc8d..e5a4be5d5 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.model; import java.util.ArrayList; import java.util.Collections; @@ -32,7 +32,7 @@ import javax.validation.constraints.NotEmpty; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.core.style.ToStringCreator; -import org.springframework.samples.petclinic.model.Person; +import org.springframework.samples.petclinic.common.CommonAttribute; /** * Simple JavaBean domain object representing an owner. @@ -140,11 +140,11 @@ public class Owner extends Person { @Override public String toString() { - return new ToStringCreator(this) - - .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName()) - .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city) - .append("telephone", this.telephone).toString(); + return new ToStringCreator(this).append(CommonAttribute.OWNER_ID, this.getId()) + .append(CommonAttribute.NEW, this.isNew()).append(CommonAttribute.OWNER_LAST_NAME, this.getLastName()) + .append(CommonAttribute.OWNER_FIRST_NAME, this.getFirstName()) + .append(CommonAttribute.OWNER_ADDRESS, this.address).append(CommonAttribute.OWNER_CITY, this.city) + .append(CommonAttribute.OWNER_PHONE, this.telephone).toString(); } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java old mode 100755 new mode 100644 similarity index 93% rename from src/main/java/org/springframework/samples/petclinic/owner/Pet.java rename to src/main/java/org/springframework/samples/petclinic/model/Pet.java index 2b68005fd..c1db8010e --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.model; import java.time.LocalDate; import java.util.ArrayList; @@ -34,8 +34,6 @@ import javax.persistence.Transient; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.samples.petclinic.model.NamedEntity; -import org.springframework.samples.petclinic.visit.Visit; /** * Simple business object representing a pet. diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java b/src/main/java/org/springframework/samples/petclinic/model/PetType.java similarity index 87% rename from src/main/java/org/springframework/samples/petclinic/owner/PetType.java rename to src/main/java/org/springframework/samples/petclinic/model/PetType.java index 6f0aa58d3..ac554ac44 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java +++ b/src/main/java/org/springframework/samples/petclinic/model/PetType.java @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.model; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.samples.petclinic.model.NamedEntity; - /** * @author Juergen Hoeller Can be Cat, Dog, Hamster... */ diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java b/src/main/java/org/springframework/samples/petclinic/model/Specialty.java similarity index 88% rename from src/main/java/org/springframework/samples/petclinic/vet/Specialty.java rename to src/main/java/org/springframework/samples/petclinic/model/Specialty.java index ea8ec6ded..c6bcc0e0a 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Specialty.java @@ -13,15 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.vet; +package org.springframework.samples.petclinic.model; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.samples.petclinic.model.NamedEntity; - /** * Models a {@link Vet Vet's} specialty (for example, dentistry). * diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java b/src/main/java/org/springframework/samples/petclinic/model/Vet.java similarity index 95% rename from src/main/java/org/springframework/samples/petclinic/vet/Vet.java rename to src/main/java/org/springframework/samples/petclinic/model/Vet.java index 014becfce..dc45e5150 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Vet.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.vet; +package org.springframework.samples.petclinic.model; import java.util.ArrayList; import java.util.Collections; @@ -31,7 +31,6 @@ import javax.xml.bind.annotation.XmlElement; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; -import org.springframework.samples.petclinic.model.Person; /** * Simple JavaBean domain object representing a veterinarian. diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java b/src/main/java/org/springframework/samples/petclinic/model/Vets.java similarity index 95% rename from src/main/java/org/springframework/samples/petclinic/vet/Vets.java rename to src/main/java/org/springframework/samples/petclinic/model/Vets.java index cea665629..5ce52829f 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Vets.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.vet; +package org.springframework.samples.petclinic.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java old mode 100755 new mode 100644 similarity index 93% rename from src/main/java/org/springframework/samples/petclinic/visit/Visit.java rename to src/main/java/org/springframework/samples/petclinic/model/Visit.java index df9f25fe0..3ccbcfada --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.visit; +package org.springframework.samples.petclinic.model; import java.time.LocalDate; @@ -23,7 +23,6 @@ import javax.persistence.Table; import javax.validation.constraints.NotEmpty; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.samples.petclinic.model.BaseEntity; /** * Simple JavaBean domain object representing a visit. diff --git a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java index 16ac813d8..123fc4e3a 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java @@ -20,7 +20,7 @@ import java.util.Collection; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; -import org.springframework.samples.petclinic.owner.Owner; +import org.springframework.samples.petclinic.model.Owner; import org.springframework.transaction.annotation.Transactional; /** diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java index 74a4ab140..a46664df8 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java @@ -19,8 +19,8 @@ import java.util.List; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; -import org.springframework.samples.petclinic.owner.Pet; -import org.springframework.samples.petclinic.owner.PetType; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; import org.springframework.transaction.annotation.Transactional; /** diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java index 4d35b2428..bb54d107d 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java @@ -19,7 +19,7 @@ import java.util.Collection; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.repository.Repository; -import org.springframework.samples.petclinic.vet.Vet; +import org.springframework.samples.petclinic.model.Vet; import org.springframework.transaction.annotation.Transactional; /** diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java index e1b5fe7d5..0326d04b9 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java @@ -19,7 +19,7 @@ import java.util.List; import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; -import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.model.Visit; /** * Repository class for Visit domain objects All method names are compliant diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java index 12af7346c..404706c33 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -2,7 +2,7 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.OwnerDTO; -import org.springframework.samples.petclinic.owner.Owner; +import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java index f64e13c42..6c470dfa1 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -2,7 +2,7 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.PetDTO; -import org.springframework.samples.petclinic.owner.Pet; +import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java index 63ebbb1e4..2dfa4a464 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java @@ -2,7 +2,7 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.PetTypeDTO; -import org.springframework.samples.petclinic.owner.PetType; +import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java index e4cb35291..f0065f06d 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java @@ -2,7 +2,7 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.SpecialtyDTO; -import org.springframework.samples.petclinic.vet.Specialty; +import org.springframework.samples.petclinic.model.Specialty; import org.springframework.stereotype.Service; import java.util.Collection; diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java index 18f6aac47..d768fa3e7 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java @@ -3,7 +3,7 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.VetDTO; import org.springframework.samples.petclinic.repository.VetRepository; -import org.springframework.samples.petclinic.vet.Vet; +import org.springframework.samples.petclinic.model.Vet; import org.springframework.stereotype.Service; import java.util.Collection; diff --git a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java index 54ce4c6a5..a53c84182 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java @@ -2,7 +2,7 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.VisitDTO; -import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.model.Visit; import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index 0a96582c9..51ba24f22 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -34,9 +34,7 @@ class CacheConfiguration { @Bean public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { - return cm -> { - cm.createCache("vets", cacheConfiguration()); - }; + return cm -> cm.createCache("vets", cacheConfiguration()); } /** diff --git a/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java b/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java index 90333ff6b..ede0f9185 100644 --- a/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/validator/PetDTOValidator.java @@ -15,6 +15,8 @@ */ package org.springframework.samples.petclinic.validator; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonError; import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.util.StringUtils; import org.springframework.validation.Errors; @@ -29,28 +31,27 @@ import org.springframework.validation.Validator; * * @author Ken Krebs * @author Juergen Hoeller + * @author Paul-Emmanuel DOS SANTOS FACAO */ public class PetDTOValidator implements Validator { - private static final String REQUIRED = "required"; - @Override public void validate(Object obj, Errors errors) { PetDTO pet = (PetDTO) obj; String name = pet.getName(); // name validation if (!StringUtils.hasLength(name)) { - errors.rejectValue("name", REQUIRED, REQUIRED); + errors.rejectValue(CommonAttribute.PET_NAME, CommonError.REQUIRED_ARGS, CommonError.REQUIRED_MESSAGE); } // type validation if (pet.isNew() && pet.getType() == null) { - errors.rejectValue("type", REQUIRED, REQUIRED); + errors.rejectValue(CommonAttribute.PET_TYPE, CommonError.REQUIRED_ARGS, CommonError.REQUIRED_MESSAGE); } // birth date validation if (pet.getBirthDate() == null) { - errors.rejectValue("birthDate", REQUIRED, REQUIRED); + errors.rejectValue(CommonAttribute.PET_BIRTH_DATE, CommonError.REQUIRED_ARGS, CommonError.REQUIRED_MESSAGE); } } diff --git a/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java index c85c4113e..98f4ab025 100644 --- a/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/validator/PetValidator.java @@ -15,8 +15,9 @@ */ package org.springframework.samples.petclinic.validator; -import org.springframework.samples.petclinic.dto.PetDTO; -import org.springframework.samples.petclinic.owner.Pet; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonError; +import org.springframework.samples.petclinic.model.Pet; import org.springframework.util.StringUtils; import org.springframework.validation.Errors; import org.springframework.validation.Validator; @@ -30,28 +31,27 @@ import org.springframework.validation.Validator; * * @author Ken Krebs * @author Juergen Hoeller + * @author Paul-Emmanuel DOS SANTOS FACAO */ public class PetValidator implements Validator { - private static final String REQUIRED = "required"; - @Override public void validate(Object obj, Errors errors) { Pet pet = (Pet) obj; String name = pet.getName(); // name validation if (!StringUtils.hasLength(name)) { - errors.rejectValue("name", REQUIRED, REQUIRED); + errors.rejectValue(CommonAttribute.PET_NAME, CommonError.REQUIRED_ARGS, CommonError.REQUIRED_MESSAGE); } // type validation if (pet.isNew() && pet.getType() == null) { - errors.rejectValue("type", REQUIRED, REQUIRED); + errors.rejectValue(CommonAttribute.PET_TYPE, CommonError.REQUIRED_ARGS, CommonError.REQUIRED_MESSAGE); } // birth date validation if (pet.getBirthDate() == null) { - errors.rejectValue("birthDate", REQUIRED, REQUIRED); + errors.rejectValue(CommonAttribute.PET_BIRTH_DATE, CommonError.REQUIRED_ARGS, CommonError.REQUIRED_MESSAGE); } } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java index b429be5c4..ac1018907 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerTests.java @@ -24,6 +24,7 @@ import org.assertj.core.util.Lists; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -96,142 +97,148 @@ class OwnerControllerTests { } @Test + @Tag("initCreationForm") void testInitCreationForm() throws Exception { - mockMvc.perform(get(CommonEndPoint.OWNERS_NEW)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists(CommonAttribute.OWNER)) - .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); + mockMvc.perform(get(CommonEndPoint.OWNERS_NEW)).andExpect(status().isOk()) + .andExpect(model().attributeExists(CommonAttribute.OWNER)) + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test + @Tag("processCreationForm") void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/new") - .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") - .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") - .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street") - .param(CommonAttribute.OWNER_CITY, "London") - .param(CommonAttribute.OWNER_PHONE, "01316761638")) - .andExpect(status().is3xxRedirection()); + mockMvc.perform(post("/owners/new").param(CommonAttribute.OWNER_FIRST_NAME, "Joe") + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") + .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street").param(CommonAttribute.OWNER_CITY, "London") + .param(CommonAttribute.OWNER_PHONE, "01316761638")).andExpect(status().is3xxRedirection()); } @Test + @Tag("processCreationForm") void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post(CommonEndPoint.OWNERS_NEW) - .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") - .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") - .param(CommonAttribute.OWNER_CITY, "London")) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) - .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) - .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) - .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); + mockMvc.perform(post(CommonEndPoint.OWNERS_NEW).param(CommonAttribute.OWNER_FIRST_NAME, "Joe") + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs").param(CommonAttribute.OWNER_CITY, "London")) + .andExpect(status().isOk()).andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test + @Tag("initFindForm") void testInitFindForm() throws Exception { - mockMvc.perform(get(CommonEndPoint.OWNERS_FIND)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists(CommonAttribute.OWNER)) - .andExpect(view().name(CommonView.OWNER_FIND_OWNERS)); + mockMvc.perform(get(CommonEndPoint.OWNERS_FIND)).andExpect(status().isOk()) + .andExpect(model().attributeExists(CommonAttribute.OWNER)) + .andExpect(view().name(CommonView.OWNER_FIND_OWNERS)); } @Test + @Tag("processFindForm") void testProcessFindFormSuccess() throws Exception { given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new OwnerDTO())); - mockMvc.perform(get(CommonEndPoint.OWNERS)) - .andExpect(status().isOk()) - .andExpect(view().name(CommonView.OWNER_OWNERS_LIST)); + mockMvc.perform(get(CommonEndPoint.OWNERS)).andExpect(status().isOk()) + .andExpect(view().name(CommonView.OWNER_OWNERS_LIST)); } @Test + @Tag("processFindForm") void testProcessFindFormByLastName() throws Exception { given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); - mockMvc.perform(get(CommonEndPoint.OWNERS) - .param(CommonAttribute.OWNER_LAST_NAME, "Franklin")) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name(CommonView.OWNER_OWNERS_R + TEST_OWNER_ID)); + mockMvc.perform(get(CommonEndPoint.OWNERS).param(CommonAttribute.OWNER_LAST_NAME, "Franklin")) + .andExpect(status().is3xxRedirection()) + .andExpect(view().name(CommonView.OWNER_OWNERS_R + TEST_OWNER_ID)); } @Test + @Tag("processFindForm") void testProcessFindFormNoOwnersFound() throws Exception { - mockMvc.perform(get(CommonEndPoint.OWNERS) - .param(CommonAttribute.OWNER_LAST_NAME,"Unknown Surname")) - .andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME)) - .andExpect(model().attributeHasFieldErrorCode(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME, "notFound")) - .andExpect(view().name(CommonView.OWNER_FIND_OWNERS)); + mockMvc.perform(get(CommonEndPoint.OWNERS).param(CommonAttribute.OWNER_LAST_NAME, "Unknown Surname")) + .andExpect(status().isOk()) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME)) + .andExpect(model().attributeHasFieldErrorCode(CommonAttribute.OWNER, CommonAttribute.OWNER_LAST_NAME, + "notFound")) + .andExpect(view().name(CommonView.OWNER_FIND_OWNERS)); } @Test + @Tag("initUpdateOwnerForm") void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists(CommonAttribute.OWNER)) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) - .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); + mockMvc.perform(get(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(model().attributeExists(CommonAttribute.OWNER)) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test + @Tag("processUpdateOwnerForm") void testProcessUpdateOwnerFormSuccess() throws Exception { mockMvc.perform(post(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID) - .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") - .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") - .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street") - .param(CommonAttribute.OWNER_CITY, "London") - .param(CommonAttribute.OWNER_PHONE, "01616291589")) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name(CommonView.OWNER_OWNERS_ID_R)); + .param(CommonAttribute.OWNER_FIRST_NAME, "Joe").param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") + .param(CommonAttribute.OWNER_ADDRESS, "123 Caramel Street").param(CommonAttribute.OWNER_CITY, "London") + .param(CommonAttribute.OWNER_PHONE, "01616291589")).andExpect(status().is3xxRedirection()) + .andExpect(view().name(CommonView.OWNER_OWNERS_ID_R)); } @Test + @Tag("processUpdateOwnerForm") void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc.perform(post(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID) - .param(CommonAttribute.OWNER_FIRST_NAME, "Joe") - .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs") - .param(CommonAttribute.OWNER_CITY, "London")) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) - .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) - .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) - .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); + mockMvc.perform( + post(CommonEndPoint.OWNERS_ID_EDIT, TEST_OWNER_ID).param(CommonAttribute.OWNER_FIRST_NAME, "Joe") + .param(CommonAttribute.OWNER_LAST_NAME, "Bloggs").param(CommonAttribute.OWNER_CITY, "London")) + .andExpect(status().isOk()).andExpect(model().attributeHasErrors(CommonAttribute.OWNER)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_ADDRESS)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.OWNER, CommonAttribute.OWNER_PHONE)) + .andExpect(view().name(CommonView.OWNER_CREATE_OR_UPDATE)); } @Test + @Tag("processUpdateOwnerForm") void testShowOwner() throws Exception { - mockMvc.perform(get(CommonEndPoint.OWNERS_ID, TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PETS, not(empty())))) - .andExpect(model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PETS, new BaseMatcher>() { + mockMvc.perform(get(CommonEndPoint.OWNERS_ID, TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_LAST_NAME, is("Franklin")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_FIRST_NAME, is("George")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_ADDRESS, is("110 W. Liberty St.")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_CITY, is("Madison")))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_PHONE, is("6085551023")))) + .andExpect( + model().attribute(CommonAttribute.OWNER, hasProperty(CommonAttribute.OWNER_PETS, not(empty())))) + .andExpect(model().attribute(CommonAttribute.OWNER, + hasProperty(CommonAttribute.OWNER_PETS, new BaseMatcher>() { - @Override - public boolean matches(Object item) { - @SuppressWarnings("unchecked") - List pets = (List) item; - PetDTO pet = pets.get(0); - if (pet.getVisits().isEmpty()) { - return false; - } + @Override + public boolean matches(Object item) { + @SuppressWarnings("unchecked") + List pets = (List) item; + PetDTO pet = pets.get(0); + if (pet.getVisits().isEmpty()) { + return false; + } - return true; - } + return true; + } - @Override - public void describeTo(Description description) { - description.appendText("Max did not have any visits"); - } - }))) - .andExpect(view().name(CommonView.OWNER_DETAILS)); + @Override + public void describeTo(Description description) { + description.appendText("Max did not have any visits"); + } + }))) + .andExpect(view().name(CommonView.OWNER_DETAILS)); } } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java index 5222af95b..69f26dc19 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java @@ -25,16 +25,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import org.assertj.core.util.Lists; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; 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.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonError; +import org.springframework.samples.petclinic.common.CommonView; 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.PetTypeFormatter; +import org.springframework.samples.petclinic.formatter.PetTypeFormatter; import org.springframework.samples.petclinic.service.OwnerService; import org.springframework.samples.petclinic.service.PetService; import org.springframework.samples.petclinic.service.PetTypeService; @@ -44,6 +49,7 @@ import org.springframework.test.web.servlet.MockMvc; * Test class for the {@link PetController} * * @author Colin But + * @author Paul-Emmanuel DOS SANTOS FACAO */ @WebMvcTest(value = PetController.class, includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE)) @@ -77,63 +83,60 @@ class PetControllerTests { } @Test + @Tag("initCreationForm") void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")) - .andExpect(model().attributeExists("pet")); + mockMvc.perform(get(CommonEndPoint.OWNERS_ID + CommonEndPoint.PETS_NEW, TEST_OWNER_ID)) + .andExpect(status().isOk()).andExpect(view().name(CommonView.PET_CREATE_OR_UPDATE)) + .andExpect(model().attributeExists(CommonAttribute.PET)); } @Test + @Tag("processCreationForm") void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015-02-12")) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + mockMvc.perform(post(CommonEndPoint.OWNERS_ID + CommonEndPoint.PETS_NEW, TEST_OWNER_ID) + .param(CommonAttribute.PET_NAME, "Betty").param(CommonAttribute.PET_TYPE, "hamster") + .param(CommonAttribute.PET_BIRTH_DATE, "2015-02-12")).andExpect(status().is3xxRedirection()) + .andExpect(view().name(CommonView.OWNER_OWNERS_ID_R)); } @Test + @Tag("processCreationForm") void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("birthDate","2015-02-12")) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(model().attributeHasFieldErrors("pet", "type")) - .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); + mockMvc.perform(post(CommonEndPoint.OWNERS_ID + CommonEndPoint.PETS_NEW, TEST_OWNER_ID) + .param(CommonAttribute.PET_NAME, "Betty").param(CommonAttribute.PET_BIRTH_DATE, "2015-02-12")) + .andExpect(model().attributeHasNoErrors(CommonAttribute.OWNER)) + .andExpect(model().attributeHasErrors(CommonAttribute.PET)) + .andExpect(model().attributeHasFieldErrors(CommonAttribute.PET, CommonAttribute.PET_TYPE)) + .andExpect(model().attributeHasFieldErrorCode(CommonAttribute.PET, CommonAttribute.PET_TYPE, + CommonError.REQUIRED_ARGS)) + .andExpect(status().isOk()).andExpect(view().name(CommonView.PET_CREATE_OR_UPDATE)); } @Test + @Tag("initUpdateForm") void testInitUpdateForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("pet")) - .andExpect(view().name("pets/createOrUpdatePetForm")); + mockMvc.perform(get(CommonEndPoint.OWNERS_ID + CommonEndPoint.PETS_ID_EDIT, TEST_OWNER_ID, TEST_PET_ID)) + .andExpect(status().isOk()).andExpect(model().attributeExists(CommonAttribute.PET)) + .andExpect(view().name(CommonView.PET_CREATE_OR_UPDATE)); } @Test + @Tag("processUpdateForm") void testProcessUpdateFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015-02-12")) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + mockMvc.perform(post(CommonEndPoint.OWNERS_ID + CommonEndPoint.PETS_ID_EDIT, TEST_OWNER_ID, TEST_PET_ID) + .param(CommonAttribute.PET_NAME, "Betty").param(CommonAttribute.PET_TYPE, "hamster") + .param(CommonAttribute.PET_BIRTH_DATE, "2015-02-12")).andExpect(status().is3xxRedirection()) + .andExpect(view().name(CommonView.OWNER_OWNERS_ID_R)); } @Test + @Tag("processUpdateForm") void testProcessUpdateFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("birthDate", "2015/02/12")) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); + mockMvc.perform(post(CommonEndPoint.OWNERS_ID + CommonEndPoint.PETS_ID_EDIT, TEST_OWNER_ID, TEST_PET_ID) + .param(CommonAttribute.PET_NAME, "Betty").param(CommonAttribute.PET_BIRTH_DATE, "2015-02-12")) + .andExpect(model().attributeHasNoErrors(CommonAttribute.OWNER)) + .andExpect(model().attributeHasErrors(CommonAttribute.PET)).andExpect(status().isOk()) + .andExpect(view().name(CommonView.PET_CREATE_OR_UPDATE)); } } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java index e1bdd5ad0..003daa26e 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java @@ -26,19 +26,25 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import org.assertj.core.util.Lists; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; 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.http.MediaType; +import org.springframework.samples.petclinic.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.VetDTO; import org.springframework.samples.petclinic.service.VetService; -import org.springframework.samples.petclinic.vet.Specialty; +import org.springframework.samples.petclinic.model.Specialty; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; /** * Test class for the {@link VetController} + * + * @author Paul-Emmanuel DOS SANTOS FACAO */ @WebMvcTest(VetController.class) class VetControllerTests { @@ -67,15 +73,19 @@ class VetControllerTests { } @Test + @Tag("showVetList") void testShowVetListHtml() throws Exception { - mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets")) - .andExpect(view().name("vets/vetList")); + mockMvc.perform(get(CommonEndPoint.VETS_HTML)).andExpect(status().isOk()) + .andExpect(model().attributeExists(CommonAttribute.VETS)) + .andExpect(view().name(CommonView.VET_VETS_LIST)); } @Test + @Tag("showResourcesVetList") void testShowResourcesVetList() throws Exception { - ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON)) + ResultActions actions = mockMvc.perform(get(CommonEndPoint.VETS).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); + actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.vetList[0].id").value(1)); } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java index 7bc0e5f4d..f5cb862c4 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java @@ -24,10 +24,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; 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.common.CommonAttribute; +import org.springframework.samples.petclinic.common.CommonEndPoint; +import org.springframework.samples.petclinic.common.CommonView; import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.service.PetService; import org.springframework.samples.petclinic.service.VisitService; @@ -58,24 +62,26 @@ class VisitControllerTests { } @Test + @Tag("initNewVisitForm") void testInitNewVisitForm() throws Exception { - mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); + mockMvc.perform(get(CommonEndPoint.VISITS_NEW, TEST_PET_ID)).andExpect(status().isOk()) + .andExpect(view().name(CommonView.PET_CREATE_OR_UPDATE)); } @Test + @Tag("processNewVisitForm") void testProcessNewVisitFormSuccess() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George") - .param("description", "Visit Description")).andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); + mockMvc.perform(post(CommonEndPoint.VISITS_NEW, TEST_PET_ID).param(CommonAttribute.NAME, "George") + .param(CommonAttribute.DESCRIPTION, "Visit Description")).andExpect(status().is3xxRedirection()) + .andExpect(view().name(CommonView.OWNER_OWNERS_ID_R)); } @Test + @Tag("processNewVisitForm") void testProcessNewVisitFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")) - .andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); + mockMvc.perform(post(CommonEndPoint.VISITS_NEW, TEST_PET_ID).param(CommonAttribute.NAME, "George")) + .andExpect(model().attributeHasErrors(CommonAttribute.VISIT)).andExpect(status().isOk()) + .andExpect(view().name(CommonView.VISIT_CREATE_OR_UPDATE)); } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java similarity index 93% rename from src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java rename to src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java index f66381753..dab699990 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeDTOFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.formater; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -23,6 +23,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.samples.petclinic.dto.PetTypeDTO; +import org.springframework.samples.petclinic.formatter.PetTypeFormatter; +import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.service.PetTypeService; import java.text.ParseException; diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java similarity index 93% rename from src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java rename to src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java index 284955710..966a2348d 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.samples.petclinic.owner; +package org.springframework.samples.petclinic.formater; import java.text.ParseException; import java.util.ArrayList; @@ -29,8 +29,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.samples.petclinic.dto.PetTypeDTO; -import org.springframework.samples.petclinic.repository.PetRepository; -import org.springframework.samples.petclinic.service.PetService; +import org.springframework.samples.petclinic.formatter.PetTypeFormatter; +import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.service.PetTypeService; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java b/src/test/java/org/springframework/samples/petclinic/model/VetTests.java similarity index 95% rename from src/test/java/org/springframework/samples/petclinic/vet/VetTests.java rename to src/test/java/org/springframework/samples/petclinic/model/VetTests.java index d8df78b85..45066fe9c 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/VetTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.vet; +package org.springframework.samples.petclinic.model; import org.junit.jupiter.api.Test; import org.springframework.util.SerializationUtils; diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index c2cf0742c..6088c8ae0 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -25,14 +25,14 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; -import org.springframework.samples.petclinic.owner.Owner; +import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.repository.OwnerRepository; -import org.springframework.samples.petclinic.owner.Pet; +import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.repository.PetRepository; -import org.springframework.samples.petclinic.owner.PetType; -import org.springframework.samples.petclinic.vet.Vet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Vet; import org.springframework.samples.petclinic.repository.VetRepository; -import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.model.Visit; import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/validator/ValidatorTests.java similarity index 94% rename from src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java rename to src/test/java/org/springframework/samples/petclinic/validator/ValidatorTests.java index 8d754900d..f22b9d6b4 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/validator/ValidatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.samples.petclinic.model; +package org.springframework.samples.petclinic.validator; import java.util.Locale; import java.util.Set; @@ -24,6 +24,7 @@ import javax.validation.Validator; import org.junit.jupiter.api.Test; import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.samples.petclinic.model.Person; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import static org.assertj.core.api.Assertions.assertThat; From 4d62c09efbac4d8a772f94f6767b6ba130110e8f Mon Sep 17 00:00:00 2001 From: PEDSF Date: Wed, 14 Oct 2020 19:23:34 +0200 Subject: [PATCH 10/16] add equals and hashcode --- pom.xml | 17 ++ .../samples/petclinic/dto/OwnerDTO.java | 21 ++ .../samples/petclinic/dto/PersonDTO.java | 17 ++ .../samples/petclinic/dto/PetDTO.java | 21 ++ .../samples/petclinic/dto/VisitDTO.java | 19 ++ .../samples/petclinic/model/NamedEntity.java | 14 ++ .../samples/petclinic/model/Owner.java | 21 ++ .../samples/petclinic/model/Person.java | 17 ++ .../samples/petclinic/model/Pet.java | 23 +++ .../samples/petclinic/model/Visit.java | 19 ++ .../petclinic/service/OwnerService.java | 32 ++- .../samples/petclinic/service/PetService.java | 12 +- .../petclinic/service/OwnerServiceTest.java | 193 ++++++++++++++++++ 13 files changed, 420 insertions(+), 6 deletions(-) create mode 100644 src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java diff --git a/pom.xml b/pom.xml index 3636c8154..b48f5e05d 100644 --- a/pom.xml +++ b/pom.xml @@ -137,6 +137,23 @@ spring-boot-devtools true
+ + junit + junit + 4.13 + test + + + junit + junit + test + + + org.projectlombok + lombok + 1.18.12 + test + diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index 60ee8a05d..7f7cb1272 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -128,4 +128,25 @@ public class OwnerDTO extends PersonDTO { .append(CommonAttribute.OWNER_PHONE, this.telephone).toString(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof OwnerDTO)) return false; + + OwnerDTO ownerDTO = (OwnerDTO) o; + + if (!getAddress().equals(ownerDTO.getAddress())) return false; + if (!getCity().equals(ownerDTO.getCity())) return false; + if (!getTelephone().equals(ownerDTO.getTelephone())) return false; + return getPets() != null ? getPets().equals(ownerDTO.getPets()) : ownerDTO.getPets() == null; + } + + @Override + public int hashCode() { + int result = getAddress().hashCode(); + result = 31 * result + getCity().hashCode(); + result = 31 * result + getTelephone().hashCode(); + result = 31 * result + (getPets() != null ? getPets().hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java index 963341601..07565c8d0 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java @@ -46,4 +46,21 @@ public class PersonDTO extends BaseDTO { this.lastName = lastName; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PersonDTO)) return false; + + PersonDTO personDTO = (PersonDTO) o; + + if (!getFirstName().equals(personDTO.getFirstName())) return false; + return getLastName().equals(personDTO.getLastName()); + } + + @Override + public int hashCode() { + int result = getFirstName().hashCode(); + result = 31 * result + getLastName().hashCode(); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java index 5b5925adc..e88359a20 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -84,4 +84,25 @@ public class PetDTO extends NamedDTO { visit.setPetId(this.getId()); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PetDTO)) return false; + + PetDTO petDTO = (PetDTO) o; + + if (!getBirthDate().equals(petDTO.getBirthDate())) return false; + if (!getType().equals(petDTO.getType())) return false; + if (!getOwner().equals(petDTO.getOwner())) return false; + return getVisits() != null ? getVisits().equals(petDTO.getVisits()) : petDTO.getVisits() == null; + } + + @Override + public int hashCode() { + int result = getBirthDate().hashCode(); + result = 31 * result + getType().hashCode(); + result = 31 * result + getOwner().hashCode(); + result = 31 * result + (getVisits() != null ? getVisits().hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java index 835b0dd75..617dd4fbb 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java @@ -65,4 +65,23 @@ public class VisitDTO extends BaseDTO { this.petId = petId; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof VisitDTO)) return false; + + VisitDTO visitDTO = (VisitDTO) o; + + if (!getDate().equals(visitDTO.getDate())) return false; + if (!getDescription().equals(visitDTO.getDescription())) return false; + return getPetId().equals(visitDTO.getPetId()); + } + + @Override + public int hashCode() { + int result = getDate().hashCode(); + result = 31 * result + getDescription().hashCode(); + result = 31 * result + getPetId().hashCode(); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java index 088e52e81..7ac5aec0c 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java @@ -44,4 +44,18 @@ public class NamedEntity extends BaseEntity { return this.getName(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof NamedEntity)) return false; + + NamedEntity that = (NamedEntity) o; + + return getName().equals(that.getName()); + } + + @Override + public int hashCode() { + return getName().hashCode(); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java index e5a4be5d5..24815138f 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -147,4 +147,25 @@ public class Owner extends Person { .append(CommonAttribute.OWNER_PHONE, this.telephone).toString(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Owner)) return false; + + Owner owner = (Owner) o; + + if (!getAddress().equals(owner.getAddress())) return false; + if (!getCity().equals(owner.getCity())) return false; + if (!getTelephone().equals(owner.getTelephone())) return false; + return getPets() != null ? getPets().equals(owner.getPets()) : owner.getPets() == null; + } + + @Override + public int hashCode() { + int result = getAddress().hashCode(); + result = 31 * result + getCity().hashCode(); + result = 31 * result + getTelephone().hashCode(); + result = 31 * result + (getPets() != null ? getPets().hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index 15fabacc3..536deb548 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -51,4 +51,21 @@ public class Person extends BaseEntity { this.lastName = lastName; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Person)) return false; + + Person person = (Person) o; + + if (!getFirstName().equals(person.getFirstName())) return false; + return getLastName().equals(person.getLastName()); + } + + @Override + public int hashCode() { + int result = getFirstName().hashCode(); + result = 31 * result + getLastName().hashCode(); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java index c1db8010e..40683de7d 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -107,4 +107,27 @@ public class Pet extends NamedEntity { visit.setPetId(this.getId()); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pet)) return false; + if (!super.equals(o)) return false; + + Pet pet = (Pet) o; + + if (!getBirthDate().equals(pet.getBirthDate())) return false; + if (!getType().equals(pet.getType())) return false; + if (!getOwner().equals(pet.getOwner())) return false; + return getVisits() != null ? getVisits().equals(pet.getVisits()) : pet.getVisits() == null; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + getBirthDate().hashCode(); + result = 31 * result + getType().hashCode(); + result = 31 * result + getOwner().hashCode(); + result = 31 * result + (getVisits() != null ? getVisits().hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java index 3ccbcfada..f90594d4c 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java @@ -76,4 +76,23 @@ public class Visit extends BaseEntity { this.petId = petId; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Visit)) return false; + + Visit visit = (Visit) o; + + if (!getDate().equals(visit.getDate())) return false; + if (!getDescription().equals(visit.getDescription())) return false; + return getPetId().equals(visit.getPetId()); + } + + @Override + public int hashCode() { + int result = getDate().hashCode(); + result = 31 * result + getDescription().hashCode(); + result = 31 * result + getPetId().hashCode(); + return result; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java index 404706c33..1c75f8843 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -2,8 +2,11 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.OwnerDTO; +import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.repository.OwnerRepository; +import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.stereotype.Service; import java.util.Collection; @@ -13,21 +16,42 @@ import java.util.HashSet; public class OwnerService implements BaseService { private final OwnerRepository ownerRepository; - + private final PetRepository petRepository; private final ModelMapper modelMapper = new ModelMapper(); + private PetService petService; - public OwnerService(OwnerRepository ownerRepository) { + public OwnerService(OwnerRepository ownerRepository, PetRepository petRepository) { this.ownerRepository = ownerRepository; + this.petRepository = petRepository; + petService = new PetService(petRepository); } @Override public Owner dtoToEntity(OwnerDTO dto) { - return modelMapper.map(dto, Owner.class); + if(dto == null) { + return new Owner(); + } + Owner owner = modelMapper.map(dto, Owner.class); + + for(PetDTO petDTO: dto.getPets()) { + owner.addPet(petService.dtoToEntity(petDTO)); + } + + return owner; } @Override public OwnerDTO entityToDTO(Owner entity) { - return modelMapper.map(entity, OwnerDTO.class); + if(entity == null) { + return new OwnerDTO(); + } + OwnerDTO ownerDTO = modelMapper.map(entity, OwnerDTO.class); + + for(Pet pet : entity.getPets()) { + ownerDTO.addPet(petService.entityToDTO(pet)); + } + + return ownerDTO; } @Override diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java index 6c470dfa1..191eb558d 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -22,12 +22,20 @@ public class PetService implements BaseService { @Override public Pet dtoToEntity(PetDTO dto) { - return modelMapper.map(dto, Pet.class); + if(dto == null) { + return new Pet(); + } else { + return modelMapper.map(dto, Pet.class); + } } @Override public PetDTO entityToDTO(Pet entity) { - return modelMapper.map(entity, PetDTO.class); + if(entity == null) { + return new PetDTO(); + } else { + return modelMapper.map(entity, PetDTO.class); + } } @Override diff --git a/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java new file mode 100644 index 000000000..dc7d4c30a --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java @@ -0,0 +1,193 @@ +package org.springframework.samples.petclinic.service; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.samples.petclinic.dto.OwnerDTO; +import org.springframework.samples.petclinic.dto.PetDTO; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.repository.OwnerRepository; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.HashSet; + +import static org.assertj.core.api.Assertions.assertThat; + +@Slf4j +@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) +class OwnerServiceTest { + private final static Integer OWNER_ID = 55; + private final static String OWNER_FIRST_NAME = "Sam"; + private final static String OWNER_LAST_NAME = "Schultz"; + private final static String OWNER_ADDRESS = "4, Evans Street"; + private final static String OWNER_CITY = "Wollongong"; + private final static String OWNER_PHONE = "1234567890"; + + private final static Integer PET_ID = 11; + private final static String PET_NAME = "bowser"; + private final static String PET_BIRTH_DATE = "2020-07-11"; + + @Autowired + private OwnerRepository ownerRepository; + @Autowired + private PetRepository petRepository; + + private PetService petService; + private OwnerService ownerService; + private static Owner owner; + private static OwnerDTO ownerDTO; + private static Pet pet; + private static PetDTO petDTO; + + @BeforeEach + void beforeEach() { + petService = new PetService(petRepository); + ownerService = new OwnerService(ownerRepository, petRepository); + pet = new Pet(); + pet.setId(PET_ID); + pet.setName(PET_NAME); + pet.setBirthDate(LocalDate.parse(PET_BIRTH_DATE)); + petDTO = new PetDTO(); + petDTO.setId(PET_ID); + petDTO.setName(PET_NAME); + petDTO.setBirthDate(LocalDate.parse(PET_BIRTH_DATE)); + + owner = new Owner(); + owner.setId(OWNER_ID); + owner.setFirstName(OWNER_FIRST_NAME); + owner.setLastName(OWNER_LAST_NAME); + owner.setAddress(OWNER_ADDRESS); + owner.setCity(OWNER_CITY); + owner.setTelephone(OWNER_PHONE); + owner.addPet(pet); + ownerDTO = new OwnerDTO(); + ownerDTO.setId(OWNER_ID); + ownerDTO.setFirstName(OWNER_FIRST_NAME); + ownerDTO.setLastName(OWNER_LAST_NAME); + ownerDTO.setAddress(OWNER_ADDRESS); + ownerDTO.setCity(OWNER_CITY); + ownerDTO.setTelephone(OWNER_PHONE); + ownerDTO.addPet(petDTO); + } + + @Test + @Tag("dtoToEntity") + void dtoToEntity() { + Owner found = ownerService.dtoToEntity(ownerDTO); + assertThat(found.getFirstName()).isEqualTo(owner.getFirstName()); + assertThat(found.getLastName()).isEqualTo(owner.getLastName()); + assertThat(found.getAddress()).isEqualTo(owner.getAddress()); + assertThat(found.getCity()).isEqualTo(owner.getCity()); + assertThat(found.getTelephone()).isEqualTo(owner.getTelephone()); + + assertThat(found.getPets().size()).isEqualTo(owner.getPets().size()); + + for(Pet pet: found.getPets()) { + assertThat(owner.getPets()).contains(pet); + } + + } + + @Test + @Tag("entityToDTO") + void entityToDTO() { + OwnerDTO found = ownerService.entityToDTO(owner); + assertThat(found.getFirstName()).isEqualTo(ownerDTO.getFirstName()); + assertThat(found.getLastName()).isEqualTo(ownerDTO.getLastName()); + assertThat(found.getAddress()).isEqualTo(ownerDTO.getAddress()); + assertThat(found.getCity()).isEqualTo(ownerDTO.getCity()); + assertThat(found.getTelephone()).isEqualTo(ownerDTO.getTelephone()); + assertThat(found.getPets().size()).isEqualTo(ownerDTO.getPets().size()); + + for(PetDTO petDTO: found.getPets()) { + assertThat(ownerDTO.getPets()).contains(petDTO); + } + } + + @Test + @Tag("entitiesToDTOS") + void entitiesToDTOS() { + Collection owners = new HashSet<>(); + Collection expected = new HashSet<>(); + Collection found; + + for(int i =1 ; i<5; i++) { + OwnerDTO ownerDTO = ownerService.findById(i); + expected.add(ownerDTO); + owners.add(ownerService.dtoToEntity(ownerDTO)); + } + + found = ownerService.entitiesToDTOS(owners); + + assertThat(found).hasSameSizeAs(expected); + + for( int i=1; i<5; i++) { + assertThat(expected).contains(found.iterator().next()); + } + } + + @Test + @Tag("dtosToEntities") + void dtosToEntities() { + Collection ownerDTOS = new HashSet<>(); + Collection expected = new HashSet<>(); + Collection found; + + for(int i =1 ; i<5; i++) { + OwnerDTO ownerDTO = ownerService.findById(i); + expected.add(ownerService.dtoToEntity(ownerDTO)); + ownerDTOS.add(ownerDTO); + } + + found = ownerService.dtosToEntities(ownerDTOS); + + assertThat(found).hasSameSizeAs(expected); + + for( int i=1; i<5; i++) { + assertThat(expected).contains(found.iterator().next()); + } + } + + @Test + @Transactional + @Tag("save") + void save() { + Collection founds = ownerService.findByLastName(OWNER_LAST_NAME); + assertThat(founds).isEmpty(); + + ownerService.save(ownerDTO); + + OwnerDTO found = ownerService.findByLastName(OWNER_LAST_NAME).stream().findFirst().get(); + + assertThat(found).isEqualToIgnoringGivenFields(ownerDTO, "id"); + } + + @Test + @Tag("findByLastName") + void findByLastName() { + OwnerDTO expected = ownerService.findById(1); + OwnerDTO found = ownerService.findByLastName(expected.getLastName()).stream().findFirst().get(); + + assertThat(found).isEqualToComparingFieldByField(expected); + + } + + @Test + @Tag("findById") + void findById() { + ownerService.save(ownerDTO); + OwnerDTO expected = ownerService.findByLastName(OWNER_LAST_NAME).stream().findFirst().get(); + OwnerDTO found = ownerService.findById(expected.getId()); + + assertThat(found).isEqualToComparingFieldByField(expected); + } +} From f3e9c39681e458788cdc3bb44b54b7ed90edaef4 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 17 Oct 2020 16:20:31 +0200 Subject: [PATCH 11/16] Implemented unitary tests for services --- .../petclinic/controller/PetController.java | 2 +- .../samples/petclinic/dto/NamedDTO.java | 12 ++ .../samples/petclinic/dto/OwnerDTO.java | 23 +-- .../samples/petclinic/dto/PersonDTO.java | 15 +- .../samples/petclinic/dto/PetDTO.java | 23 +-- .../samples/petclinic/dto/PetTypeDTO.java | 5 + .../samples/petclinic/dto/VetDTO.java | 14 ++ .../samples/petclinic/dto/VisitDTO.java | 19 +- .../petclinic/formatter/PetTypeFormatter.java | 9 +- .../samples/petclinic/model/NamedEntity.java | 10 +- .../samples/petclinic/model/Owner.java | 21 --- .../samples/petclinic/model/Person.java | 15 +- .../samples/petclinic/model/Pet.java | 29 ++- .../samples/petclinic/model/PetType.java | 5 + .../samples/petclinic/model/Visit.java | 19 +- .../petclinic/repository/OwnerRepository.java | 8 + .../petclinic/repository/PetRepository.java | 9 +- .../repository/PetTypeRepository.java | 51 +++++ .../repository/SpecialtyRepository.java | 52 ++++++ .../petclinic/repository/VetRepository.java | 14 ++ .../petclinic/repository/VisitRepository.java | 15 ++ .../petclinic/service/BaseService.java | 33 +++- .../petclinic/service/OwnerService.java | 90 +++++---- .../samples/petclinic/service/PetService.java | 84 ++++++--- .../petclinic/service/PetTypeService.java | 61 +++--- .../petclinic/service/SpecialityService.java | 48 ----- .../petclinic/service/SpecialtyService.java | 81 ++++++++ .../samples/petclinic/service/VetService.java | 49 +++-- .../petclinic/service/VisitService.java | 47 +++-- .../controller/PetControllerTests.java | 2 +- .../formater/PetTypeDTOFormatterTests.java | 15 +- .../formater/PetTypeFormatterTests.java | 15 +- .../petclinic/service/OwnerServiceTest.java | 158 +++++++++------- .../petclinic/service/PetServiceTest.java | 176 ++++++++++++++++++ .../petclinic/service/VetServiceTest.java | 138 ++++++++++++++ 35 files changed, 1001 insertions(+), 366 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java create mode 100644 src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java create mode 100644 src/main/java/org/springframework/samples/petclinic/service/SpecialtyService.java create mode 100644 src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java create mode 100644 src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index 134ef0fb1..56989396d 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -58,7 +58,7 @@ class PetController { @ModelAttribute("types") public Collection populatePetTypes() { - return this.petTypeService.findPetTypes(); + return this.petService.findPetTypes(); } @ModelAttribute("owner") diff --git a/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java index 29ce3830e..1d3168628 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java @@ -38,4 +38,16 @@ public class NamedDTO extends BaseDTO { return this.getName(); } + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof NamedDTO)) + return false; + + NamedDTO namedDTO = (NamedDTO) o; + + return getName().equals(namedDTO.getName()); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index 7f7cb1272..83d2f8bac 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -130,23 +130,20 @@ public class OwnerDTO extends PersonDTO { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof OwnerDTO)) return false; + if (this == o) + return true; + if (!(o instanceof OwnerDTO)) + return false; OwnerDTO ownerDTO = (OwnerDTO) o; - if (!getAddress().equals(ownerDTO.getAddress())) return false; - if (!getCity().equals(ownerDTO.getCity())) return false; - if (!getTelephone().equals(ownerDTO.getTelephone())) return false; + if (!getAddress().equals(ownerDTO.getAddress())) + return false; + if (!getCity().equals(ownerDTO.getCity())) + return false; + if (!getTelephone().equals(ownerDTO.getTelephone())) + return false; return getPets() != null ? getPets().equals(ownerDTO.getPets()) : ownerDTO.getPets() == null; } - @Override - public int hashCode() { - int result = getAddress().hashCode(); - result = 31 * result + getCity().hashCode(); - result = 31 * result + getTelephone().hashCode(); - result = 31 * result + (getPets() != null ? getPets().hashCode() : 0); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java index 07565c8d0..f41818528 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java @@ -48,19 +48,16 @@ public class PersonDTO extends BaseDTO { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof PersonDTO)) return false; + if (this == o) + return true; + if (!(o instanceof PersonDTO)) + return false; PersonDTO personDTO = (PersonDTO) o; - if (!getFirstName().equals(personDTO.getFirstName())) return false; + if (!getFirstName().equals(personDTO.getFirstName())) + return false; return getLastName().equals(personDTO.getLastName()); } - @Override - public int hashCode() { - int result = getFirstName().hashCode(); - result = 31 * result + getLastName().hashCode(); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java index e88359a20..6a2875540 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -86,23 +86,20 @@ public class PetDTO extends NamedDTO { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof PetDTO)) return false; + if (this == o) + return true; + if (!(o instanceof PetDTO)) + return false; PetDTO petDTO = (PetDTO) o; - if (!getBirthDate().equals(petDTO.getBirthDate())) return false; - if (!getType().equals(petDTO.getType())) return false; - if (!getOwner().equals(petDTO.getOwner())) return false; + if (!getBirthDate().equals(petDTO.getBirthDate())) + return false; + if (!getType().equals(petDTO.getType())) + return false; + if (!getOwner().equals(petDTO.getOwner())) + return false; return getVisits() != null ? getVisits().equals(petDTO.getVisits()) : petDTO.getVisits() == null; } - @Override - public int hashCode() { - int result = getBirthDate().hashCode(); - result = 31 * result + getType().hashCode(); - result = 31 * result + getOwner().hashCode(); - result = 31 * result + (getVisits() != null ? getVisits().hashCode() : 0); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java index 54d771c7f..100c134bc 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java @@ -7,4 +7,9 @@ package org.springframework.samples.petclinic.dto; */ public class PetTypeDTO extends NamedDTO { + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java index 880589592..e41f87859 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java @@ -57,4 +57,18 @@ public class VetDTO extends PersonDTO { getSpecialtiesInternal().add(specialty); } + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof VetDTO)) + return false; + if (!super.equals(o)) + return false; + + VetDTO vetDTO = (VetDTO) o; + + return getSpecialties().equals(vetDTO.getSpecialties()); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java index 617dd4fbb..d976185b7 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java @@ -67,21 +67,18 @@ public class VisitDTO extends BaseDTO { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof VisitDTO)) return false; + if (this == o) + return true; + if (!(o instanceof VisitDTO)) + return false; VisitDTO visitDTO = (VisitDTO) o; - if (!getDate().equals(visitDTO.getDate())) return false; - if (!getDescription().equals(visitDTO.getDescription())) return false; + if (!getDate().equals(visitDTO.getDate())) + return false; + if (!getDescription().equals(visitDTO.getDescription())) + return false; return getPetId().equals(visitDTO.getPetId()); } - @Override - public int hashCode() { - int result = getDate().hashCode(); - result = 31 * result + getDescription().hashCode(); - result = 31 * result + getPetId().hashCode(); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java index 28330c383..a93537845 100644 --- a/src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/formatter/PetTypeFormatter.java @@ -21,6 +21,7 @@ import java.util.Locale; import org.springframework.format.Formatter; import org.springframework.samples.petclinic.dto.PetTypeDTO; +import org.springframework.samples.petclinic.service.PetService; import org.springframework.samples.petclinic.service.PetTypeService; import org.springframework.stereotype.Component; @@ -37,10 +38,10 @@ import org.springframework.stereotype.Component; @Component public class PetTypeFormatter implements Formatter { - private final PetTypeService petTypeService; + private final PetService petService; - public PetTypeFormatter(PetTypeService petTypeService) { - this.petTypeService = petTypeService; + public PetTypeFormatter(PetService petService) { + this.petService = petService; } @Override @@ -50,7 +51,7 @@ public class PetTypeFormatter implements Formatter { @Override public PetTypeDTO parse(String text, Locale locale) throws ParseException { - Collection findPetTypes = this.petTypeService.findPetTypes(); + Collection findPetTypes = this.petService.findPetTypes(); for (PetTypeDTO type : findPetTypes) { if (type.getName().equals(text)) { return type; diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java index 7ac5aec0c..cafe7e218 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java @@ -46,16 +46,14 @@ public class NamedEntity extends BaseEntity { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof NamedEntity)) return false; + if (this == o) + return true; + if (!(o instanceof NamedEntity)) + return false; NamedEntity that = (NamedEntity) o; return getName().equals(that.getName()); } - @Override - public int hashCode() { - return getName().hashCode(); - } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java index 24815138f..e5a4be5d5 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -147,25 +147,4 @@ public class Owner extends Person { .append(CommonAttribute.OWNER_PHONE, this.telephone).toString(); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Owner)) return false; - - Owner owner = (Owner) o; - - if (!getAddress().equals(owner.getAddress())) return false; - if (!getCity().equals(owner.getCity())) return false; - if (!getTelephone().equals(owner.getTelephone())) return false; - return getPets() != null ? getPets().equals(owner.getPets()) : owner.getPets() == null; - } - - @Override - public int hashCode() { - int result = getAddress().hashCode(); - result = 31 * result + getCity().hashCode(); - result = 31 * result + getTelephone().hashCode(); - result = 31 * result + (getPets() != null ? getPets().hashCode() : 0); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index 536deb548..709c3bec3 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -53,19 +53,16 @@ public class Person extends BaseEntity { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Person)) return false; + if (this == o) + return true; + if (!(o instanceof Person)) + return false; Person person = (Person) o; - if (!getFirstName().equals(person.getFirstName())) return false; + if (!getFirstName().equals(person.getFirstName())) + return false; return getLastName().equals(person.getLastName()); } - @Override - public int hashCode() { - int result = getFirstName().hashCode(); - result = 31 * result + getLastName().hashCode(); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java index 40683de7d..f6b0b26ed 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -81,7 +81,7 @@ public class Pet extends NamedEntity { return this.owner; } - protected void setOwner(Owner owner) { + public void setOwner(Owner owner) { this.owner = owner; } @@ -109,25 +109,22 @@ public class Pet extends NamedEntity { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Pet)) return false; - if (!super.equals(o)) return false; + if (this == o) + return true; + if (!(o instanceof Pet)) + return false; + if (!super.equals(o)) + return false; Pet pet = (Pet) o; - if (!getBirthDate().equals(pet.getBirthDate())) return false; - if (!getType().equals(pet.getType())) return false; - if (!getOwner().equals(pet.getOwner())) return false; + if (!getBirthDate().equals(pet.getBirthDate())) + return false; + if (!getType().equals(pet.getType())) + return false; + if (getOwner() != null ? !getOwner().equals(pet.getOwner()) : pet.getOwner() != null) + return false; return getVisits() != null ? getVisits().equals(pet.getVisits()) : pet.getVisits() == null; } - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + getBirthDate().hashCode(); - result = 31 * result + getType().hashCode(); - result = 31 * result + getOwner().hashCode(); - result = 31 * result + (getVisits() != null ? getVisits().hashCode() : 0); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/PetType.java b/src/main/java/org/springframework/samples/petclinic/model/PetType.java index ac554ac44..8453778e8 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/PetType.java +++ b/src/main/java/org/springframework/samples/petclinic/model/PetType.java @@ -25,4 +25,9 @@ import javax.persistence.Table; @Table(name = "types") public class PetType extends NamedEntity { + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java index f90594d4c..859ca61a0 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java @@ -78,21 +78,18 @@ public class Visit extends BaseEntity { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Visit)) return false; + if (this == o) + return true; + if (!(o instanceof Visit)) + return false; Visit visit = (Visit) o; - if (!getDate().equals(visit.getDate())) return false; - if (!getDescription().equals(visit.getDescription())) return false; + if (!getDate().equals(visit.getDate())) + return false; + if (!getDescription().equals(visit.getDescription())) + return false; return getPetId().equals(visit.getPetId()); } - @Override - public int hashCode() { - int result = getDate().hashCode(); - result = 31 * result + getDescription().hashCode(); - result = 31 * result + getPetId().hashCode(); - return result; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java index 123fc4e3a..14cc90528 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java @@ -16,6 +16,7 @@ package org.springframework.samples.petclinic.repository; import java.util.Collection; +import java.util.List; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; @@ -33,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional; * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Paul-Emmanuel DOS SANTOS FACAO */ public interface OwnerRepository extends Repository { @@ -56,6 +58,12 @@ public interface OwnerRepository extends Repository { @Transactional(readOnly = true) Owner findById(@Param("id") Integer id); + /** + * Retrieve all {@link Owner}s from the data store + * @return a Collection of {@link Owner}s (or an empty Collection if none + */ + List findAll(); + /** * Save an {@link Owner} to the data store, either inserting or updating it. * @param owner the {@link Owner} to save diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java index a46664df8..fa90093f3 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java @@ -15,6 +15,7 @@ */ package org.springframework.samples.petclinic.repository; +import java.util.Collection; import java.util.List; import org.springframework.data.jpa.repository.Query; @@ -33,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional; * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Paul-Emmanuel DOS SANTOS FACAO */ public interface PetRepository extends Repository { @@ -49,9 +51,14 @@ public interface PetRepository extends Repository { * @param id the id to search for * @return the {@link Pet} if found */ - @Transactional(readOnly = true) Pet findById(Integer id); + /** + * Retrieve all {@link Pet}s from the data store + * @return a Collection of {@link Pet}s (or an empty Collection if none + */ + List findAll(); + /** * Save a {@link Pet} to the data store, either inserting or updating it. * @param pet the {@link Pet} to save diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java new file mode 100644 index 000000000..77eb7e6b3 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository; + +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.PetType; + +import java.util.Collection; +import java.util.List; + +/** + * Repository class for PetType domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public interface PetTypeRepository extends Repository { + + /** + * Retrieve a {@link PetType} from the data store by id. + * @param id the id to search for + * @return the {@link PetType} if found + */ + PetType findById(Integer id); + + /** + * Retrieve all {@link PetType}s from the data store + * @return a Collection of {@link PetType}s (or an empty Collection if none + */ + List findAll(); + + /** + * Save a {@link PetType} to the data store, either inserting or updating it. + * @param petType the {@link PetType} to save + */ + void save(PetType petType); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java new file mode 100644 index 000000000..327161809 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository; + +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.Specialty; + +import java.util.Collection; +import java.util.List; + +/** + * Repository class for Speciality domain objects All method names are + * compliant with Spring Data naming conventions so this interface can easily be extended + * for Spring + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +public interface SpecialtyRepository extends Repository { + + /** + * Retrieve a {@link Specialty} from the data store by id. + * @param id the id to search for + * @return the {@link Specialty} if found + */ + Specialty findById(Integer id); + + /** + * Retrieve all {@link Specialty}s from the data store + * @return a Collection of {@link Specialty}s (or an empty Collection if none + */ + List findAll(); + + /** + * Save a {@link Specialty} to the data store, either inserting or updating it. + * @param specialty the {@link Specialty} to save + */ + void save(Specialty specialty); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java index bb54d107d..ae585f19f 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java @@ -32,9 +32,17 @@ import org.springframework.transaction.annotation.Transactional; * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Paul-Emmanuel DOS SANTOS FACAO */ public interface VetRepository extends Repository { + /** + * Retrieve a {@link Vet} from the data store by id. + * @param id the id to search for + * @return the {@link Vet} if found + */ + Vet findById(Integer id); + /** * Retrieve all Vets from the data store. * @return a Collection of Vets @@ -43,4 +51,10 @@ public interface VetRepository extends Repository { @Cacheable("vets") Collection findAll(); + /** + * Save a {@link Vet} to the data store, either inserting or updating it. + * @param vet the {@link Vet} to save + */ + void save(Vet vet); + } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java index 0326d04b9..06fe23dd8 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java @@ -15,6 +15,7 @@ */ package org.springframework.samples.petclinic.repository; +import java.util.Collection; import java.util.List; import org.springframework.data.repository.Repository; @@ -31,6 +32,7 @@ import org.springframework.samples.petclinic.model.Visit; * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Paul-Emmanuel DOS SANTOS FACAO */ public interface VisitRepository extends Repository { @@ -41,6 +43,19 @@ public interface VisitRepository extends Repository { */ void save(Visit visit); + /** + * Retrieve a {@link Visit} from the data store by id. + * @param id the id to search for + * @return the {@link Visit} if found + */ + Visit findById(Integer id); + List findByPetId(Integer petId); + /** + * Retrieve all {@link Visit}s from the data store + * @return a Collection of {@link Visit}s (or an empty Collection if none + */ + List findAll(); + } diff --git a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java index 1f97e4d0b..5b4cdf5de 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java @@ -1,7 +1,12 @@ package org.springframework.samples.petclinic.service; -import java.util.Collection; +import java.util.List; +/** + * Interface for all services + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ public interface BaseService { /** @@ -9,27 +14,45 @@ public interface BaseService { * @param dto DTO * @return Entity Model */ - public E dtoToEntity(D dto); + E dtoToEntity(D dto); /** * Convert Entity Model to Data Transfert Object * @param entity Entity Model * @return DTO */ - public D entityToDTO(E entity); + D entityToDTO(E entity); /** * Convert Entities Models Collection to Data Transfert Object Collection * @param entities Collection of Entity Model * @return Collection of DTO */ - public Collection entitiesToDTOS(Collection entities); + List entitiesToDTOS(List entities); /** * Convert Entities Models Collection to Data Transfert Object Collection * @param dtos Collection of DTO * @return Collection of Entity Model */ - public Collection dtosToEntities(Collection dtos); + List dtosToEntities(List dtos); + + /** + * Get DTO object from repository by his ID + * @param id identify object to be found + * @return + */ + D findById(int id); + + /** + * Get all DTO objects from repository + * @return + */ + List findAll(); + + /** + * Save DTO object to repository + */ + void save(D dto); } diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java index 1c75f8843..64b375f40 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -1,94 +1,102 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; +import org.modelmapper.internal.util.Lists; import org.springframework.samples.petclinic.dto.OwnerDTO; -import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; +import java.util.List; +/** + * Simple Service between Owner entity and OwnerDTO Data Transfert Object. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ @Service("OwnerService") public class OwnerService implements BaseService { private final OwnerRepository ownerRepository; + private final PetRepository petRepository; + private final ModelMapper modelMapper = new ModelMapper(); + private PetService petService; - public OwnerService(OwnerRepository ownerRepository, PetRepository petRepository) { + public OwnerService(OwnerRepository ownerRepository, PetRepository petRepository, + PetTypeRepository petTypeRepository, VisitRepository visitRepository) { this.ownerRepository = ownerRepository; this.petRepository = petRepository; - petService = new PetService(petRepository); + petService = new PetService(petRepository, petTypeRepository, visitRepository); } @Override public Owner dtoToEntity(OwnerDTO dto) { - if(dto == null) { - return new Owner(); - } - Owner owner = modelMapper.map(dto, Owner.class); - - for(PetDTO petDTO: dto.getPets()) { - owner.addPet(petService.dtoToEntity(petDTO)); + if (dto != null) { + Owner owner = modelMapper.map(dto, Owner.class); + dto.getPets().forEach(petDTO -> owner.addPet(petService.dtoToEntity(petDTO))); + return owner; } - return owner; + return new Owner(); } @Override public OwnerDTO entityToDTO(Owner entity) { - if(entity == null) { - return new OwnerDTO(); - } - OwnerDTO ownerDTO = modelMapper.map(entity, OwnerDTO.class); - - for(Pet pet : entity.getPets()) { - ownerDTO.addPet(petService.entityToDTO(pet)); + if (entity != null) { + OwnerDTO ownerDTO = modelMapper.map(entity, OwnerDTO.class); + entity.getPets().forEach(pet -> ownerDTO.addPet(petService.entityToDTO(pet))); + return ownerDTO; } - return ownerDTO; + return new OwnerDTO(); } @Override - public Collection entitiesToDTOS(Collection entities) { - Collection dtos = new HashSet<>(); + public List entitiesToDTOS(List entities) { + List dtos = new ArrayList<>(); - for (Owner entity : entities) { - dtos.add(entityToDTO(entity)); - } + entities.forEach(entity -> dtos.add(entityToDTO(entity))); return dtos; } @Override - public Collection dtosToEntities(Collection dtos) { - Collection entities = new HashSet<>(); + public List dtosToEntities(List dtos) { + List entities = new ArrayList<>(); - for (OwnerDTO dto : dtos) { - entities.add(dtoToEntity(dto)); - } + dtos.forEach(dto -> entities.add(dtoToEntity(dto))); return entities; } - public void save(OwnerDTO ownerDTO) { - Owner owner = dtoToEntity(ownerDTO); - ownerRepository.save(owner); - } - - public Collection findByLastName(String lastName) { - Collection owners = ownerRepository.findByLastName(lastName); - return entitiesToDTOS(owners); - } - + @Override public OwnerDTO findById(int ownerId) { Owner owner = ownerRepository.findById(ownerId); return entityToDTO(owner); } + @Override + public List findAll() { + return entitiesToDTOS(ownerRepository.findAll()); + } + + @Override + public void save(OwnerDTO ownerDTO) { + Owner owner = dtoToEntity(ownerDTO); + ownerRepository.save(owner); + } + + public List findByLastName(String lastName) { + Collection owners = ownerRepository.findByLastName(lastName); + return entitiesToDTOS(Lists.from(owners.iterator())); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java index 191eb558d..793f62706 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -2,71 +2,103 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.PetDTO; +import org.springframework.samples.petclinic.dto.PetTypeDTO; import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; -import java.util.Collection; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; +/** + * Simple Service between Pet entity and PetDTO Data Transfert Object. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ @Service("PetService") public class PetService implements BaseService { private final PetRepository petRepository; + private final PetTypeService petTypeService; + + private final PetTypeRepository petTypeRepository; + + private final VisitService visitService; + private final ModelMapper modelMapper = new ModelMapper(); - public PetService(PetRepository petRepository) { + public PetService(PetRepository petRepository, PetTypeRepository petTypeRepository, + VisitRepository visitRepository) { this.petRepository = petRepository; + this.petTypeRepository = petTypeRepository; + this.visitService = new VisitService(visitRepository); + this.petTypeService = new PetTypeService(petTypeRepository); } @Override public Pet dtoToEntity(PetDTO dto) { - if(dto == null) { - return new Pet(); - } else { - return modelMapper.map(dto, Pet.class); + if (dto != null) { + Pet pet = modelMapper.map(dto, Pet.class); + dto.getVisits().forEach(visitDTO -> pet.addVisit(visitService.dtoToEntity(visitDTO))); + return pet; } + + return new Pet(); } @Override public PetDTO entityToDTO(Pet entity) { - if(entity == null) { - return new PetDTO(); - } else { - return modelMapper.map(entity, PetDTO.class); + if (entity != null) { + PetDTO petDTO = modelMapper.map(entity, PetDTO.class); + entity.getVisits().forEach(visit -> petDTO.addVisit(visitService.entityToDTO(visit))); + return petDTO; } + + return new PetDTO(); } @Override - public Collection entitiesToDTOS(Collection entities) { - Collection dtos = new HashSet<>(); + public List entitiesToDTOS(List entities) { + List dtos = new ArrayList<>(); + + entities.forEach(entity -> dtos.add(entityToDTO(entity))); - for (Pet entity : entities) { - dtos.add(entityToDTO(entity)); - } return dtos; } @Override - public Collection dtosToEntities(Collection dtos) { - Collection entities = new HashSet<>(); + public List dtosToEntities(List dtos) { + List entities = new ArrayList<>(); - for (PetDTO dto : dtos) { - entities.add(dtoToEntity(dto)); - } + dtos.forEach(dto -> entities.add(dtoToEntity(dto))); return entities; } - public void save(PetDTO petDTO) { - Pet pet = dtoToEntity(petDTO); - petRepository.save(pet); - } - + @Override public PetDTO findById(int petId) { Pet pet = petRepository.findById(petId); return entityToDTO(pet); } + @Override + public List findAll() { + return entitiesToDTOS(petRepository.findAll()); + } + + @Override + public void save(PetDTO petDTO) { + petRepository.save(dtoToEntity(petDTO)); + } + + public List findPetTypes() { + List petTypes = petRepository.findPetTypes(); + + return petTypeService.entitiesToDTOS(petTypes); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java index 2dfa4a464..23c97f0a9 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java @@ -3,58 +3,77 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.springframework.samples.petclinic.dto.PetTypeDTO; import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.PetTypeRepository; import org.springframework.stereotype.Service; -import java.util.Collection; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; +/** + * Simple Service between PetType entity and PetTypeDTO Data Transfert Object. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ @Service("PerTypeService") public class PetTypeService implements BaseService { - private final PetRepository petRepository; + private final PetTypeRepository petTypeRepository; private final ModelMapper modelMapper = new ModelMapper(); - public PetTypeService(PetRepository petRepository) { - this.petRepository = petRepository; + public PetTypeService(PetTypeRepository petTypeRepository) { + this.petTypeRepository = petTypeRepository; } @Override public PetType dtoToEntity(PetTypeDTO dto) { - return modelMapper.map(dto, PetType.class); + if (dto != null) { + return modelMapper.map(dto, PetType.class); + } + + return new PetType(); } @Override public PetTypeDTO entityToDTO(PetType entity) { - return modelMapper.map(entity, PetTypeDTO.class); + if (entity != null) { + return modelMapper.map(entity, PetTypeDTO.class); + } + + return new PetTypeDTO(); } @Override - public Collection entitiesToDTOS(Collection entities) { - Collection dtos = new HashSet<>(); + public List entitiesToDTOS(List entities) { + List dtos = new ArrayList<>(); - for (PetType entity : entities) { - dtos.add(entityToDTO(entity)); - } + entities.forEach(entity -> dtos.add(entityToDTO(entity))); return dtos; } @Override - public Collection dtosToEntities(Collection dtos) { - Collection entities = new HashSet<>(); + public List dtosToEntities(List dtos) { + List entities = new ArrayList<>(); - for (PetTypeDTO dto : dtos) { - entities.add(dtoToEntity(dto)); - } + dtos.forEach(dto -> entities.add(dtoToEntity(dto))); return entities; } - public Collection findPetTypes() { - Collection petTypes = petRepository.findPetTypes(); - return entitiesToDTOS(petTypes); + @Override + public PetTypeDTO findById(int id) { + return entityToDTO(petTypeRepository.findById(id)); + } + + @Override + public List findAll() { + return entitiesToDTOS(petTypeRepository.findAll()); + } + + @Override + public void save(PetTypeDTO dto) { + petTypeRepository.save(dtoToEntity(dto)); } } diff --git a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java deleted file mode 100644 index f0065f06d..000000000 --- a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.springframework.samples.petclinic.service; - -import org.modelmapper.ModelMapper; -import org.springframework.samples.petclinic.dto.SpecialtyDTO; -import org.springframework.samples.petclinic.model.Specialty; -import org.springframework.stereotype.Service; - -import java.util.Collection; -import java.util.HashSet; - -@Service("SpecialityService") -public class SpecialityService implements BaseService { - - private final ModelMapper modelMapper = new ModelMapper(); - - @Override - public Specialty dtoToEntity(SpecialtyDTO dto) { - return modelMapper.map(dto, Specialty.class); - } - - @Override - public SpecialtyDTO entityToDTO(Specialty entity) { - return modelMapper.map(entity, SpecialtyDTO.class); - } - - @Override - public Collection entitiesToDTOS(Collection entities) { - Collection dtos = new HashSet<>(); - - for (Specialty entity : entities) { - dtos.add(entityToDTO(entity)); - } - - return dtos; - } - - @Override - public Collection dtosToEntities(Collection dtos) { - Collection entities = new HashSet<>(); - - for (SpecialtyDTO dto : dtos) { - entities.add(dtoToEntity(dto)); - } - - return entities; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/service/SpecialtyService.java b/src/main/java/org/springframework/samples/petclinic/service/SpecialtyService.java new file mode 100644 index 000000000..d4eb07cb8 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/SpecialtyService.java @@ -0,0 +1,81 @@ +package org.springframework.samples.petclinic.service; + +import org.modelmapper.ModelMapper; +import org.springframework.samples.petclinic.dto.SpecialtyDTO; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +/** + * Simple Service between Specialty entity and SpecialtyDTO Data Transfert Object. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +@Service("SpecialityService") +public class SpecialtyService implements BaseService { + + private final SpecialtyRepository specialtyRepository; + + private final ModelMapper modelMapper = new ModelMapper(); + + public SpecialtyService(SpecialtyRepository specialtyRepository) { + this.specialtyRepository = specialtyRepository; + } + + @Override + public Specialty dtoToEntity(SpecialtyDTO dto) { + if (dto != null) { + return modelMapper.map(dto, Specialty.class); + } + + return new Specialty(); + } + + @Override + public SpecialtyDTO entityToDTO(Specialty entity) { + if (entity != null) { + return modelMapper.map(entity, SpecialtyDTO.class); + } + + return new SpecialtyDTO(); + } + + @Override + public List entitiesToDTOS(List entities) { + List dtos = new ArrayList<>(); + + entities.forEach(entity -> dtos.add(entityToDTO(entity))); + + return dtos; + } + + @Override + public List dtosToEntities(List dtos) { + List entities = new ArrayList<>(); + + dtos.forEach(dto -> entities.add(dtoToEntity(dto))); + + return entities; + } + + @Override + public SpecialtyDTO findById(int id) { + return entityToDTO(specialtyRepository.findById(id)); + } + + @Override + public List findAll() { + return entitiesToDTOS(specialtyRepository.findAll()); + } + + @Override + public void save(SpecialtyDTO dto) { + specialtyRepository.save(dtoToEntity(dto)); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java index d768fa3e7..5f4775bd3 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java @@ -1,14 +1,22 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; +import org.modelmapper.internal.util.Lists; import org.springframework.samples.petclinic.dto.VetDTO; import org.springframework.samples.petclinic.repository.VetRepository; import org.springframework.samples.petclinic.model.Vet; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.List; +/** + * Simple Service between Vet entity and VetDTO Data Transfert Object. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ @Service("VetService") public class VetService implements BaseService { @@ -22,39 +30,52 @@ public class VetService implements BaseService { @Override public Vet dtoToEntity(VetDTO dto) { - return modelMapper.map(dto, Vet.class); + if (dto != null) { + return modelMapper.map(dto, Vet.class); + } + + return new Vet(); } @Override public VetDTO entityToDTO(Vet entity) { - return modelMapper.map(entity, VetDTO.class); + if (entity != null) { + return modelMapper.map(entity, VetDTO.class); + } + return new VetDTO(); } @Override - public Collection entitiesToDTOS(Collection entities) { - Collection dtos = new HashSet<>(); + public List entitiesToDTOS(List entities) { + List dtos = new ArrayList<>(); - for (Vet entity : entities) { - dtos.add(entityToDTO(entity)); - } + entities.forEach(entity -> dtos.add(entityToDTO(entity))); return dtos; } @Override - public Collection dtosToEntities(Collection dtos) { - Collection entities = new HashSet<>(); + public List dtosToEntities(List dtos) { + List entities = new ArrayList<>(); - for (VetDTO dto : dtos) { - entities.add(dtoToEntity(dto)); - } + dtos.forEach(dto -> entities.add(dtoToEntity(dto))); return entities; } - public Collection findAll() { + @Override + public VetDTO findById(int id) { + return entityToDTO(vetRepository.findById(id)); + } + + public List findAll() { Collection vets = vetRepository.findAll(); - return entitiesToDTOS(vets); + return entitiesToDTOS(Lists.from(vets.iterator())); + } + + @Override + public void save(VetDTO dto) { + vetRepository.save(dtoToEntity(dto)); } } diff --git a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java index a53c84182..8f627cf80 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java @@ -6,9 +6,16 @@ import org.springframework.samples.petclinic.model.Visit; import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.List; +/** + * Simple Service between Visit entity and VisitDTO Data Transfert Object. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ @Service("VisitService") public class VisitService implements BaseService { @@ -22,35 +29,51 @@ public class VisitService implements BaseService { @Override public Visit dtoToEntity(VisitDTO dto) { - return modelMapper.map(dto, Visit.class); + if (dto != null) { + return modelMapper.map(dto, Visit.class); + } + + return new Visit(); } @Override public VisitDTO entityToDTO(Visit entity) { - return modelMapper.map(entity, VisitDTO.class); + if (entity != null) { + return modelMapper.map(entity, VisitDTO.class); + } + + return new VisitDTO(); } @Override - public Collection entitiesToDTOS(Collection entities) { - Collection dtos = new HashSet<>(); + public List entitiesToDTOS(List entities) { + List dtos = new ArrayList<>(); + + entities.forEach(entity -> dtos.add(entityToDTO(entity))); - for (Visit entity : entities) { - dtos.add(entityToDTO(entity)); - } return dtos; } @Override - public Collection dtosToEntities(Collection dtos) { - Collection entities = new HashSet<>(); + public List dtosToEntities(List dtos) { + List entities = new ArrayList<>(); - for (VisitDTO dto : dtos) { - entities.add(dtoToEntity(dto)); - } + dtos.forEach(dto -> entities.add(dtoToEntity(dto))); return entities; } + @Override + public VisitDTO findById(int id) { + return entityToDTO(visitRepository.findById(id)); + } + + @Override + public List findAll() { + return entitiesToDTOS(visitRepository.findAll()); + } + + @Override public void save(VisitDTO visitDTO) { Visit visit = dtoToEntity(visitDTO); visitRepository.save(visit); diff --git a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java index 69f26dc19..717507c5b 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/PetControllerTests.java @@ -79,7 +79,7 @@ class PetControllerTests { given(this.ownerService.findById(TEST_OWNER_ID)).willReturn(new OwnerDTO()); given(this.petService.findById(TEST_PET_ID)).willReturn(new PetDTO()); - given(this.petTypeService.findPetTypes()).willReturn(Lists.newArrayList(cat)); + given(this.petService.findPetTypes()).willReturn(Lists.newArrayList(cat)); } @Test diff --git a/src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java index dab699990..a9e8f2e72 100644 --- a/src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeDTOFormatterTests.java @@ -25,6 +25,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.samples.petclinic.dto.PetTypeDTO; import org.springframework.samples.petclinic.formatter.PetTypeFormatter; import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.service.PetService; import org.springframework.samples.petclinic.service.PetTypeService; import java.text.ParseException; @@ -45,13 +46,13 @@ import static org.mockito.BDDMockito.given; class PetTypeDTOFormatterTests { @Mock - private PetTypeService petTypeService; + private PetService petService; private PetTypeFormatter petTypeFormatter; @BeforeEach void setup() { - this.petTypeFormatter = new PetTypeFormatter(petTypeService); + this.petTypeFormatter = new PetTypeFormatter(petService); } @Test @@ -64,17 +65,15 @@ class PetTypeDTOFormatterTests { @Test void shouldParse() throws ParseException { - given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); + given(this.petService.findPetTypes()).willReturn(makePetTypes()); PetTypeDTO petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); assertThat(petType.getName()).isEqualTo("Bird"); } @Test - void shouldThrowParseException() throws ParseException { - given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); - Assertions.assertThrows(ParseException.class, () -> { - petTypeFormatter.parse("Fish", Locale.ENGLISH); - }); + void shouldThrowParseException() { + given(this.petService.findPetTypes()).willReturn(makePetTypes()); + Assertions.assertThrows(ParseException.class, () -> petTypeFormatter.parse("Fish", Locale.ENGLISH)); } /** diff --git a/src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java index 966a2348d..902048f72 100644 --- a/src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/formater/PetTypeFormatterTests.java @@ -31,6 +31,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.samples.petclinic.dto.PetTypeDTO; import org.springframework.samples.petclinic.formatter.PetTypeFormatter; import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.service.PetService; import org.springframework.samples.petclinic.service.PetTypeService; import static org.assertj.core.api.Assertions.assertThat; @@ -45,13 +46,13 @@ import static org.mockito.BDDMockito.given; class PetTypeFormatterTests { @Mock - private PetTypeService petTypeService; + private PetService petService; private PetTypeFormatter petTypeFormatter; @BeforeEach void setup() { - this.petTypeFormatter = new PetTypeFormatter(petTypeService); + this.petTypeFormatter = new PetTypeFormatter(petService); } @Test @@ -64,17 +65,15 @@ class PetTypeFormatterTests { @Test void shouldParse() throws ParseException { - given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); + given(this.petService.findPetTypes()).willReturn(makePetTypes()); PetTypeDTO petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); assertThat(petType.getName()).isEqualTo("Bird"); } @Test - void shouldThrowParseException() throws ParseException { - given(this.petTypeService.findPetTypes()).willReturn(makePetTypes()); - Assertions.assertThrows(ParseException.class, () -> { - petTypeFormatter.parse("Fish", Locale.ENGLISH); - }); + void shouldThrowParseException() { + given(this.petService.findPetTypes()).willReturn(makePetTypes()); + Assertions.assertThrows(ParseException.class, () -> petTypeFormatter.parse("Fish", Locale.ENGLISH)); } /** diff --git a/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java index dc7d4c30a..7160140c4 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java +++ b/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java @@ -2,6 +2,7 @@ package org.springframework.samples.petclinic.service; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,45 +14,67 @@ import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; -import java.util.Collection; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @Slf4j @DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) class OwnerServiceTest { + private final static Integer OWNER_ID = 55; + private final static String OWNER_FIRST_NAME = "Sam"; + private final static String OWNER_LAST_NAME = "Schultz"; + private final static String OWNER_ADDRESS = "4, Evans Street"; + private final static String OWNER_CITY = "Wollongong"; + private final static String OWNER_PHONE = "1234567890"; private final static Integer PET_ID = 11; + private final static String PET_NAME = "bowser"; + private final static String PET_BIRTH_DATE = "2020-07-11"; @Autowired private OwnerRepository ownerRepository; + @Autowired private PetRepository petRepository; + @Autowired + private PetTypeRepository petTypeRepository; + + @Autowired + private VisitRepository visitRepository; + private PetService petService; + private OwnerService ownerService; + private static Owner owner; + private static OwnerDTO ownerDTO; + private static Pet pet; + private static PetDTO petDTO; @BeforeEach void beforeEach() { - petService = new PetService(petRepository); - ownerService = new OwnerService(ownerRepository, petRepository); + petService = new PetService(petRepository, petTypeRepository, visitRepository); + ownerService = new OwnerService(ownerRepository, petRepository, petTypeRepository, visitRepository); pet = new Pet(); pet.setId(PET_ID); pet.setName(PET_NAME); @@ -81,8 +104,11 @@ class OwnerServiceTest { @Test @Tag("dtoToEntity") + @DisplayName("Verify the convertion from DTO to Entity") void dtoToEntity() { Owner found = ownerService.dtoToEntity(ownerDTO); + + assertThat(found.getId()).isEqualTo(owner.getId()); assertThat(found.getFirstName()).isEqualTo(owner.getFirstName()); assertThat(found.getLastName()).isEqualTo(owner.getLastName()); assertThat(found.getAddress()).isEqualTo(owner.getAddress()); @@ -91,7 +117,7 @@ class OwnerServiceTest { assertThat(found.getPets().size()).isEqualTo(owner.getPets().size()); - for(Pet pet: found.getPets()) { + for (Pet pet : found.getPets()) { assertThat(owner.getPets()).contains(pet); } @@ -99,8 +125,11 @@ class OwnerServiceTest { @Test @Tag("entityToDTO") + @DisplayName("Verify the convertion from Entity to DTO") void entityToDTO() { OwnerDTO found = ownerService.entityToDTO(owner); + + assertThat(found.getId()).isEqualTo(ownerDTO.getId()); assertThat(found.getFirstName()).isEqualTo(ownerDTO.getFirstName()); assertThat(found.getLastName()).isEqualTo(ownerDTO.getLastName()); assertThat(found.getAddress()).isEqualTo(ownerDTO.getAddress()); @@ -108,86 +137,81 @@ class OwnerServiceTest { assertThat(found.getTelephone()).isEqualTo(ownerDTO.getTelephone()); assertThat(found.getPets().size()).isEqualTo(ownerDTO.getPets().size()); - for(PetDTO petDTO: found.getPets()) { + for (PetDTO petDTO : found.getPets()) { assertThat(ownerDTO.getPets()).contains(petDTO); } } - @Test - @Tag("entitiesToDTOS") - void entitiesToDTOS() { - Collection owners = new HashSet<>(); - Collection expected = new HashSet<>(); - Collection found; - - for(int i =1 ; i<5; i++) { - OwnerDTO ownerDTO = ownerService.findById(i); - expected.add(ownerDTO); - owners.add(ownerService.dtoToEntity(ownerDTO)); - } - - found = ownerService.entitiesToDTOS(owners); - - assertThat(found).hasSameSizeAs(expected); - - for( int i=1; i<5; i++) { - assertThat(expected).contains(found.iterator().next()); - } - } - @Test @Tag("dtosToEntities") + @DisplayName("Verify the convertion from DTOs list to Entities list") void dtosToEntities() { - Collection ownerDTOS = new HashSet<>(); - Collection expected = new HashSet<>(); - Collection found; + List ownerDTOS = ownerService.findAll(); + List expected = new ArrayList<>(); + ownerDTOS.forEach(dto -> expected.add(ownerService.dtoToEntity(dto))); - for(int i =1 ; i<5; i++) { - OwnerDTO ownerDTO = ownerService.findById(i); - expected.add(ownerService.dtoToEntity(ownerDTO)); - ownerDTOS.add(ownerDTO); - } + List found = ownerService.dtosToEntities(ownerDTOS); - found = ownerService.dtosToEntities(ownerDTOS); - - assertThat(found).hasSameSizeAs(expected); - - for( int i=1; i<5; i++) { - assertThat(expected).contains(found.iterator().next()); - } + assertThat(found).hasSameSizeAs(expected).containsAll(expected); } @Test - @Transactional - @Tag("save") - void save() { - Collection founds = ownerService.findByLastName(OWNER_LAST_NAME); - assertThat(founds).isEmpty(); + @Tag("entitiesToDTOS") + @DisplayName("Verify the convertion from Entities list to DTOs list") + void entitiesToDTOS() { + List expected = ownerService.findAll(); + List owners = new ArrayList<>(); + expected.forEach(dto -> owners.add(ownerService.dtoToEntity(dto))); - ownerService.save(ownerDTO); - - OwnerDTO found = ownerService.findByLastName(OWNER_LAST_NAME).stream().findFirst().get(); - - assertThat(found).isEqualToIgnoringGivenFields(ownerDTO, "id"); - } - - @Test - @Tag("findByLastName") - void findByLastName() { - OwnerDTO expected = ownerService.findById(1); - OwnerDTO found = ownerService.findByLastName(expected.getLastName()).stream().findFirst().get(); - - assertThat(found).isEqualToComparingFieldByField(expected); + List found = ownerService.entitiesToDTOS(owners); + assertThat(found).hasSameSizeAs(expected).containsAll(expected); } @Test @Tag("findById") + @DisplayName("Verify that we get OwnerDTO by his ID") void findById() { - ownerService.save(ownerDTO); - OwnerDTO expected = ownerService.findByLastName(OWNER_LAST_NAME).stream().findFirst().get(); - OwnerDTO found = ownerService.findById(expected.getId()); + List allDTO = ownerService.findAll(); + OwnerDTO expected = allDTO.get(2); - assertThat(found).isEqualToComparingFieldByField(expected); + assertThat(ownerService.findById(expected.getId())).isEqualTo(expected); } + + @Test + @Tag("findByLastName") + @DisplayName("Verify that we get OwnerDTO by his LastName") + void findByLastName() { + OwnerDTO expected = ownerService.findById(1); + + Optional found = ownerService.findByLastName(expected.getLastName()).stream().findFirst(); + + found.ifPresent(dto -> assertThat(dto).isEqualToComparingFieldByField(expected)); + } + + @Test + @Tag("findAll") + @DisplayName("Verify that the OwnerDTO list contain all previous elements and the new saved one") + void findAll() { + List expected = ownerService.findAll(); + + assertThat(expected).doesNotContain(ownerDTO); + ownerService.save(ownerDTO); + + List found = ownerService.findAll(); + + assertThat(found).contains(ownerDTO).containsAll(expected); + } + + @Test + @Tag("save") + @DisplayName("Verify that all OwnerDTO list contain the new saved one") + void save() { + assertThat(ownerService.findAll()).doesNotContain(ownerDTO); + + ownerService.save(ownerDTO); + + assertThat(ownerService.findAll()).contains(ownerDTO); + } + } diff --git a/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java new file mode 100644 index 000000000..0ecb9af6e --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java @@ -0,0 +1,176 @@ +package org.springframework.samples.petclinic.service; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +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.model.Owner; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.samples.petclinic.repository.VetRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@Slf4j +@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) +class PetServiceTest { + + private final static Integer OWNER_ID = 5; + + private final static Integer PET_ID = 14; + + private final static String PET_NAME = "bowser"; + + private final static String PET_BIRTH_DATE = "2020-07-11"; + + @Autowired + private OwnerService ownerService; + + @Autowired + private PetRepository petRepository; + + @Autowired + private PetTypeRepository petTypeRepository; + + @Autowired + private VisitRepository visitRepository; + + private PetService petService; + + private static Owner owner; + + private static Pet pet; + + private static PetDTO petDTO; + + @BeforeEach + void beforeEach() { + this.petService = new PetService(petRepository, petTypeRepository, visitRepository); + + PetTypeService petTypeService = new PetTypeService(petTypeRepository); + Collection petTypeDTOS = petService.findPetTypes(); + PetTypeDTO petTypeDTO = petTypeDTOS.stream().findFirst().get(); + PetType petType = petTypeService.dtoToEntity(petTypeDTO); + pet = new Pet(); + pet.setId(PET_ID); + pet.setName(PET_NAME); + pet.setType(petType); + pet.setBirthDate(LocalDate.parse(PET_BIRTH_DATE)); + petDTO = new PetDTO(); + petDTO.setId(PET_ID); + petDTO.setName(PET_NAME); + petDTO.setType(petTypeDTO); + petDTO.setBirthDate(LocalDate.parse(PET_BIRTH_DATE)); + + OwnerDTO ownerDTO = ownerService.findById(OWNER_ID); + ownerDTO.addPet(petDTO); + + pet.setOwner(ownerService.dtoToEntity(ownerDTO)); + petDTO.setOwner(ownerDTO); + } + + @Test + @Tag("dtoToEntity") + @DisplayName("Verify the convertion from DTO to Entity") + void dtoToEntity() { + Pet found = petService.dtoToEntity(petDTO); + + assertThat(found.getId()).isEqualTo(pet.getId()); + assertThat(found.getName()).isEqualTo(pet.getName()); + assertThat(found.getBirthDate()).isEqualTo(pet.getBirthDate()); + assertThat(found.getType()).isEqualTo(pet.getType()); + assertThat(found.getOwner()).isEqualTo(pet.getOwner()); + assertThat(found.getVisits()).isEqualTo(pet.getVisits()); + } + + @Test + @Tag("entityToDTO") + @DisplayName("Verify the convertion from Entity to DTO") + void entityToDTO() { + PetDTO found = petService.entityToDTO(pet); + + assertThat(found.getId()).isEqualTo(petDTO.getId()); + assertThat(found.getName()).isEqualTo(petDTO.getName()); + assertThat(found.getBirthDate()).isEqualTo(petDTO.getBirthDate()); + assertThat(found.getType()).isEqualTo(petDTO.getType()); + assertThat(found.getOwner()).isEqualTo(petDTO.getOwner()); + assertThat(found.getVisits()).isEqualTo(petDTO.getVisits()); + } + + @Test + @Tag("dtosToEntities") + @DisplayName("Verify the convertion from DTOs list to Entities list") + void dtosToEntities() { + List expected = petRepository.findAll(); + List allDTO = petService.findAll(); + + List found = petService.dtosToEntities(allDTO); + + assertThat(found).hasSameSizeAs(expected).isEqualTo(expected); + } + + @Test + @Tag("entitiesToDTOS") + @DisplayName("Verify the convertion from Entity to DTO") + void entitiesToDTOS() { + List allEntity = petRepository.findAll(); + List expected = petService.findAll(); + + List found = petService.entitiesToDTOS(allEntity); + + assertThat(found).hasSameSizeAs(expected).isEqualTo(expected); + } + + @Test + @Tag("findById") + @DisplayName("Verify that we get PetDTO by his ID") + void findById() { + List allDTO = petService.findAll(); + PetDTO expected = allDTO.get(2); + + assertThat(petService.findById(expected.getId())).isEqualTo(expected); + } + + @Test + @Tag("findAll") + @DisplayName("Verify that the PetDTO list contain all previous elements and the new saved one") + void findAll() { + List expected = petService.findAll(); + + assertThat(expected).doesNotContain(petDTO); + petService.save(petDTO); + + List found = petService.findAll(); + + assertThat(found).contains(petDTO).containsAll(expected); + + } + + @Test + @Tag("save") + @DisplayName("Verify that all PetDTO list contain the new saved one") + void save() { + assertThat(petService.findAll()).doesNotContain(petDTO); + + petService.save(petDTO); + + assertThat(petService.findAll()).contains(petDTO); + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java new file mode 100644 index 000000000..289a8c501 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java @@ -0,0 +1,138 @@ +package org.springframework.samples.petclinic.service; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.samples.petclinic.dto.VetDTO; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.repository.VetRepository; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@Slf4j +@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) +class VetServiceTest { + + private final static Integer VET_ID = 11; + + private final static String VET_FIRST_NAME = "Sam"; + + private final static String VET_LAST_NAME = "Schultz"; + + @Autowired + private VetRepository vetRepository; + + private VetService vetService; + + private static Vet vet; + + private static VetDTO vetDTO; + + @BeforeEach + void beforeEach() { + vetService = new VetService(vetRepository); + vet = new Vet(); + vet.setId(VET_ID); + vet.setFirstName(VET_FIRST_NAME); + vet.setLastName(VET_LAST_NAME); + vetDTO = new VetDTO(); + vetDTO.setId(VET_ID); + vetDTO.setFirstName(VET_FIRST_NAME); + vetDTO.setLastName(VET_LAST_NAME); + + } + + @Test + @Tag("dtoToEntity") + @DisplayName("Verify the convertion from DTO to Entity") + void dtoToEntity() { + Vet found = vetService.dtoToEntity(vetDTO); + + assertThat(found.getId()).isEqualTo(vet.getId()); + assertThat(found.getFirstName()).isEqualTo(vet.getFirstName()); + assertThat(found.getLastName()).isEqualTo(vet.getLastName()); + } + + @Test + @Tag("entityToDTO") + @DisplayName("Verify the convertion from Entity to DTO") + void entityToDTO() { + VetDTO found = vetService.entityToDTO(vet); + + assertThat(found.getId()).isEqualTo(vetDTO.getId()); + assertThat(found.getFirstName()).isEqualTo(vetDTO.getFirstName()); + assertThat(found.getLastName()).isEqualTo(vetDTO.getLastName()); + } + + @Test + @DisplayName("Verify the convertion from DTOs list to Entities list") + @Tag("dtosToEntities") + void dtosToEntities() { + List vetDTOS = vetService.findAll(); + List expected = new ArrayList<>(); + vetDTOS.forEach(dto -> expected.add(vetService.dtoToEntity(dto))); + + Collection found = vetService.dtosToEntities(vetDTOS); + + assertThat(found).hasSameSizeAs(expected).isEqualTo(expected); + } + + @Test + @Tag("entitiesToDTOS") + @DisplayName("Verify the convertion from Entities list to DTOs list") + void entitiesToDTOS() { + List expected = vetService.findAll(); + List vets = new ArrayList<>(); + expected.forEach(dto -> vets.add(vetService.dtoToEntity(dto))); + + List found = vetService.entitiesToDTOS(vets); + + assertThat(found).hasSameSizeAs(expected).isEqualTo(expected); + } + + @Test + @Tag("findById") + @DisplayName("Verify that we get VetDTO by his ID") + void findById() { + List allDTO = vetService.findAll(); + VetDTO expected = allDTO.get(2); + + assertThat(vetService.findById(expected.getId())).isEqualTo(expected); + } + + @Test + @Tag("findAll") + @DisplayName("Verify that the VetDTO list contain all previous elements and the new saved one") + void findAll() { + List expected = vetService.findAll(); + + assertThat(expected).doesNotContain(vetDTO); + vetService.save(vetDTO); + + List found = vetService.findAll(); + + assertThat(found).contains(vetDTO).containsAll(expected); + } + + @Test + @Tag("save") + @DisplayName("Verify that all VetDTO list contain the new saved one") + void save() { + assertThat(vetService.findAll()).doesNotContain(vetDTO); + + vetService.save(vetDTO); + + assertThat(vetService.findAll()).contains(vetDTO); + } + +} From cca4d45e002f8231b43a27ac1f7c3a8e3085d9d9 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 17 Oct 2020 17:11:39 +0200 Subject: [PATCH 12/16] Fix spetialty empty bug --- .../petclinic/controller/OwnerController.java | 1 - .../samples/petclinic/dto/OwnerDTO.java | 3 ++- .../samples/petclinic/dto/VetDTO.java | 12 +++++----- .../samples/petclinic/model/Owner.java | 2 +- .../petclinic/service/OwnerService.java | 10 ++++++++- .../samples/petclinic/service/VetService.java | 22 +++++++++++++++---- .../controller/VetControllerTests.java | 3 ++- .../petclinic/service/VetServiceTest.java | 5 ++++- 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 6cfcec4ef..dc9535e47 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -44,7 +44,6 @@ import java.util.Map; class OwnerController { private final OwnerService ownerService; - private final VisitService visitService; OwnerController(OwnerService ownerService, VisitService visitService) { diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index 83d2f8bac..0a05b6518 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -85,7 +85,8 @@ public class OwnerDTO extends PersonDTO { } public void addPet(PetDTO pet) { - if (pet.isNew()) { + + if(!this.getPets().contains(pet)) { getPetsInternal().add(pet); } pet.setOwner(this); diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java index e41f87859..0b1520b56 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java @@ -29,22 +29,22 @@ import java.util.*; */ public class VetDTO extends PersonDTO { - private Set specialties; + private Set specialties; - protected Set getSpecialtiesInternal() { + protected Set getSpecialtiesInternal() { if (this.specialties == null) { this.specialties = new HashSet<>(); } return this.specialties; } - protected void setSpecialtiesInternal(Set specialties) { + protected void setSpecialtiesInternal(Set specialties) { this.specialties = specialties; } @XmlElement - public List getSpecialties() { - List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); + public List getSpecialties() { + List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); return Collections.unmodifiableList(sortedSpecs); } @@ -53,7 +53,7 @@ public class VetDTO extends PersonDTO { return getSpecialtiesInternal().size(); } - public void addSpecialty(Specialty specialty) { + public void addSpecialty(SpecialtyDTO specialty) { getSpecialtiesInternal().add(specialty); } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java index e5a4be5d5..bc5f2df92 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -104,7 +104,7 @@ public class Owner extends Person { } public void addPet(Pet pet) { - if (pet.isNew()) { + if (!this.getPets().contains(pet)) { getPetsInternal().add(pet); } pet.setOwner(this); diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java index 64b375f40..fcb239be7 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -1,9 +1,12 @@ package org.springframework.samples.petclinic.service; +import net.bytebuddy.matcher.FilterableList; import org.modelmapper.ModelMapper; import org.modelmapper.internal.util.Lists; import org.springframework.samples.petclinic.dto.OwnerDTO; +import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.samples.petclinic.repository.PetTypeRepository; @@ -52,7 +55,12 @@ public class OwnerService implements BaseService { public OwnerDTO entityToDTO(Owner entity) { if (entity != null) { OwnerDTO ownerDTO = modelMapper.map(entity, OwnerDTO.class); - entity.getPets().forEach(pet -> ownerDTO.addPet(petService.entityToDTO(pet))); + + for( Pet pet : entity.getPets()) { + PetDTO petDTO = petService.entityToDTO(pet); + ownerDTO.addPet(petDTO); + } + return ownerDTO; } diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java index 5f4775bd3..1e0071d93 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java @@ -2,7 +2,10 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; import org.modelmapper.internal.util.Lists; +import org.springframework.samples.petclinic.dto.SpecialtyDTO; import org.springframework.samples.petclinic.dto.VetDTO; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; import org.springframework.samples.petclinic.repository.VetRepository; import org.springframework.samples.petclinic.model.Vet; import org.springframework.stereotype.Service; @@ -21,17 +24,23 @@ import java.util.List; public class VetService implements BaseService { private final VetRepository vetRepository; - + private final SpecialtyService specialtyService; private final ModelMapper modelMapper = new ModelMapper(); - public VetService(VetRepository vetRepository) { + public VetService(VetRepository vetRepository, SpecialtyRepository specialtyRepository) { this.vetRepository = vetRepository; + this.specialtyService = new SpecialtyService(specialtyRepository); } @Override public Vet dtoToEntity(VetDTO dto) { if (dto != null) { - return modelMapper.map(dto, Vet.class); + Vet vet = modelMapper.map(dto, Vet.class); + dto.getSpecialties().forEach(specialtyDTO -> { + Specialty specialty = specialtyService.dtoToEntity(specialtyDTO); + vet.addSpecialty(specialty); + }); + return vet; } return new Vet(); @@ -40,7 +49,12 @@ public class VetService implements BaseService { @Override public VetDTO entityToDTO(Vet entity) { if (entity != null) { - return modelMapper.map(entity, VetDTO.class); + VetDTO vetDTO = modelMapper.map(entity, VetDTO.class); + entity.getSpecialties().forEach(specialty -> { + SpecialtyDTO specialtyDTO = specialtyService.entityToDTO(specialty); + vetDTO.addSpecialty(specialtyDTO); + }); + return vetDTO; } return new VetDTO(); } diff --git a/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java index 003daa26e..c3eef01b1 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VetControllerTests.java @@ -35,6 +35,7 @@ import org.springframework.http.MediaType; import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonView; +import org.springframework.samples.petclinic.dto.SpecialtyDTO; import org.springframework.samples.petclinic.dto.VetDTO; import org.springframework.samples.petclinic.service.VetService; import org.springframework.samples.petclinic.model.Specialty; @@ -65,7 +66,7 @@ class VetControllerTests { helen.setFirstName("Helen"); helen.setLastName("Leary"); helen.setId(2); - Specialty radiology = new Specialty(); + SpecialtyDTO radiology = new SpecialtyDTO(); radiology.setId(1); radiology.setName("radiology"); helen.addSpecialty(radiology); diff --git a/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java index 289a8c501..3f11bf551 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java +++ b/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java @@ -10,6 +10,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.samples.petclinic.dto.VetDTO; import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; import org.springframework.samples.petclinic.repository.VetRepository; import org.springframework.stereotype.Service; @@ -31,6 +32,8 @@ class VetServiceTest { @Autowired private VetRepository vetRepository; + @Autowired + private SpecialtyRepository specialtyRepository; private VetService vetService; @@ -40,7 +43,7 @@ class VetServiceTest { @BeforeEach void beforeEach() { - vetService = new VetService(vetRepository); + vetService = new VetService(vetRepository, specialtyRepository); vet = new Vet(); vet.setId(VET_ID); vet.setFirstName(VET_FIRST_NAME); From bb2a8fa73a2d4be86735c9884a15a60144493018 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sat, 17 Oct 2020 17:21:20 +0200 Subject: [PATCH 13/16] Fix find owner bug --- .../samples/petclinic/controller/OwnerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index dc9535e47..da7a785e9 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -82,7 +82,7 @@ class OwnerController { } @GetMapping(CommonEndPoint.OWNERS) - public String processFindForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, BindingResult result, + public String processFindForm(OwnerDTO owner, BindingResult result, Map model) { // allow parameterless GET request for /owners to return all records From c6b54da5df2f18997f6369e960478dcdc848dc07 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Sun, 18 Oct 2020 09:44:02 +0200 Subject: [PATCH 14/16] Fix find owner testing --- .../petclinic/controller/OwnerController.java | 3 +- .../samples/petclinic/dto/OwnerDTO.java | 2 +- .../samples/petclinic/dto/PetDTO.java | 2 +- .../petclinic/service/OwnerService.java | 16 +++++----- .../samples/petclinic/service/PetService.java | 30 +++++++++++++++++++ .../samples/petclinic/service/VetService.java | 2 ++ .../petclinic/service/OwnerServiceTest.java | 24 +++++++++++---- .../petclinic/service/PetServiceTest.java | 8 ++--- .../petclinic/service/VetServiceTest.java | 1 + 9 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index da7a785e9..6cfcec4ef 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -44,6 +44,7 @@ import java.util.Map; class OwnerController { private final OwnerService ownerService; + private final VisitService visitService; OwnerController(OwnerService ownerService, VisitService visitService) { @@ -82,7 +83,7 @@ class OwnerController { } @GetMapping(CommonEndPoint.OWNERS) - public String processFindForm(OwnerDTO owner, BindingResult result, + public String processFindForm(@ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, BindingResult result, Map model) { // allow parameterless GET request for /owners to return all records diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index 0a05b6518..4da660d16 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -86,7 +86,7 @@ public class OwnerDTO extends PersonDTO { public void addPet(PetDTO pet) { - if(!this.getPets().contains(pet)) { + if (!this.getPets().contains(pet)) { getPetsInternal().add(pet); } pet.setOwner(this); diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java index 6a2875540..c5b0315cd 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -97,7 +97,7 @@ public class PetDTO extends NamedDTO { return false; if (!getType().equals(petDTO.getType())) return false; - if (!getOwner().equals(petDTO.getOwner())) + if (!getOwner().getId().equals(petDTO.getOwner().getId())) return false; return getVisits() != null ? getVisits().equals(petDTO.getVisits()) : petDTO.getVisits() == null; } diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java index fcb239be7..675b7b639 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java @@ -1,6 +1,5 @@ package org.springframework.samples.petclinic.service; -import net.bytebuddy.matcher.FilterableList; import org.modelmapper.ModelMapper; import org.modelmapper.internal.util.Lists; import org.springframework.samples.petclinic.dto.OwnerDTO; @@ -44,7 +43,11 @@ public class OwnerService implements BaseService { public Owner dtoToEntity(OwnerDTO dto) { if (dto != null) { Owner owner = modelMapper.map(dto, Owner.class); - dto.getPets().forEach(petDTO -> owner.addPet(petService.dtoToEntity(petDTO))); + dto.getPets().forEach(petDTO -> { + Pet pet = modelMapper.map(petDTO, Pet.class); + pet.setOwner(owner); + owner.addPet(pet); + }); return owner; } @@ -55,12 +58,11 @@ public class OwnerService implements BaseService { public OwnerDTO entityToDTO(Owner entity) { if (entity != null) { OwnerDTO ownerDTO = modelMapper.map(entity, OwnerDTO.class); - - for( Pet pet : entity.getPets()) { - PetDTO petDTO = petService.entityToDTO(pet); + entity.getPets().forEach(pet -> { + PetDTO petDTO = modelMapper.map(pet, PetDTO.class); + petDTO.setOwner(ownerDTO); ownerDTO.addPet(petDTO); - } - + }); return ownerDTO; } diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java index 793f62706..563f6b48b 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -1,8 +1,10 @@ package org.springframework.samples.petclinic.service; import org.modelmapper.ModelMapper; +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.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.repository.PetRepository; @@ -43,7 +45,21 @@ public class PetService implements BaseService { public Pet dtoToEntity(PetDTO dto) { if (dto != null) { Pet pet = modelMapper.map(dto, Pet.class); + Owner owner = modelMapper.map(dto.getOwner(), Owner.class); + dto.getVisits().forEach(visitDTO -> pet.addVisit(visitService.dtoToEntity(visitDTO))); + + dto.getOwner().getPets().forEach(petDTO -> { + if (petDTO.getId().equals(dto.getId())) { + owner.addPet(pet); + } + else { + Pet otherPet = modelMapper.map(petDTO, Pet.class); + otherPet.setOwner(owner); + owner.addPet(otherPet); + } + }); + pet.setOwner(owner); return pet; } @@ -54,7 +70,21 @@ public class PetService implements BaseService { public PetDTO entityToDTO(Pet entity) { if (entity != null) { PetDTO petDTO = modelMapper.map(entity, PetDTO.class); + OwnerDTO ownerDTO = modelMapper.map(entity.getOwner(), OwnerDTO.class); + entity.getVisits().forEach(visit -> petDTO.addVisit(visitService.entityToDTO(visit))); + + entity.getOwner().getPets().forEach(pet -> { + if (pet.getId().equals(entity.getId())) { + ownerDTO.addPet(petDTO); + } + else { + PetDTO otherPetDTO = modelMapper.map(pet, PetDTO.class); + otherPetDTO.setOwner(ownerDTO); + ownerDTO.addPet(otherPetDTO); + } + }); + petDTO.setOwner(ownerDTO); return petDTO; } diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java index 1e0071d93..cc1b59d62 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/VetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java @@ -24,7 +24,9 @@ import java.util.List; public class VetService implements BaseService { private final VetRepository vetRepository; + private final SpecialtyService specialtyService; + private final ModelMapper modelMapper = new ModelMapper(); public VetService(VetRepository vetRepository, SpecialtyRepository specialtyRepository) { diff --git a/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java index 7160140c4..0857538ab 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java +++ b/src/test/java/org/springframework/samples/petclinic/service/OwnerServiceTest.java @@ -10,8 +10,10 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.ComponentScan; 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.model.Owner; import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.repository.PetRepository; import org.springframework.samples.petclinic.repository.PetTypeRepository; @@ -20,6 +22,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Optional; @@ -29,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) class OwnerServiceTest { - private final static Integer OWNER_ID = 55; + private final static Integer OWNER_ID = 11; private final static String OWNER_FIRST_NAME = "Sam"; @@ -75,13 +78,19 @@ class OwnerServiceTest { void beforeEach() { petService = new PetService(petRepository, petTypeRepository, visitRepository); ownerService = new OwnerService(ownerRepository, petRepository, petTypeRepository, visitRepository); + PetTypeService petTypeService = new PetTypeService(petTypeRepository); + Collection petTypeDTOS = petService.findPetTypes(); + PetTypeDTO petTypeDTO = petTypeDTOS.stream().findFirst().get(); + PetType petType = petTypeService.dtoToEntity(petTypeDTO); pet = new Pet(); pet.setId(PET_ID); pet.setName(PET_NAME); + pet.setType(petType); pet.setBirthDate(LocalDate.parse(PET_BIRTH_DATE)); petDTO = new PetDTO(); petDTO.setId(PET_ID); petDTO.setName(PET_NAME); + petDTO.setType(petTypeDTO); petDTO.setBirthDate(LocalDate.parse(PET_BIRTH_DATE)); owner = new Owner(); @@ -118,7 +127,7 @@ class OwnerServiceTest { assertThat(found.getPets().size()).isEqualTo(owner.getPets().size()); for (Pet pet : found.getPets()) { - assertThat(owner.getPets()).contains(pet); + assertThat(owner.getPets()).extracting("id").contains(pet.getId()); } } @@ -138,7 +147,7 @@ class OwnerServiceTest { assertThat(found.getPets().size()).isEqualTo(ownerDTO.getPets().size()); for (PetDTO petDTO : found.getPets()) { - assertThat(ownerDTO.getPets()).contains(petDTO); + assertThat(ownerDTO.getPets()).extracting("id").contains(petDTO.getId()); } } @@ -200,7 +209,10 @@ class OwnerServiceTest { List found = ownerService.findAll(); - assertThat(found).contains(ownerDTO).containsAll(expected); + assertThat(found).hasSize(expected.size() + 1) + .usingElementComparatorOnFields("lastName", "firstName", "address", "city", "telephone") + .contains(ownerDTO).containsAnyElementsOf(expected); + } @Test @@ -210,8 +222,10 @@ class OwnerServiceTest { assertThat(ownerService.findAll()).doesNotContain(ownerDTO); ownerService.save(ownerDTO); + List found = ownerService.findAll(); - assertThat(ownerService.findAll()).contains(ownerDTO); + assertThat(found).usingElementComparatorOnFields("lastName", "firstName", "address", "city", "telephone") + .contains(ownerDTO); } } diff --git a/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java index 0ecb9af6e..1eab22b6f 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java +++ b/src/test/java/org/springframework/samples/petclinic/service/PetServiceTest.java @@ -95,7 +95,7 @@ class PetServiceTest { assertThat(found.getName()).isEqualTo(pet.getName()); assertThat(found.getBirthDate()).isEqualTo(pet.getBirthDate()); assertThat(found.getType()).isEqualTo(pet.getType()); - assertThat(found.getOwner()).isEqualTo(pet.getOwner()); + assertThat(found.getOwner().getId()).isEqualTo(pet.getOwner().getId()); assertThat(found.getVisits()).isEqualTo(pet.getVisits()); } @@ -109,7 +109,7 @@ class PetServiceTest { assertThat(found.getName()).isEqualTo(petDTO.getName()); assertThat(found.getBirthDate()).isEqualTo(petDTO.getBirthDate()); assertThat(found.getType()).isEqualTo(petDTO.getType()); - assertThat(found.getOwner()).isEqualTo(petDTO.getOwner()); + assertThat(found.getOwner().getId()).isEqualTo(petDTO.getOwner().getId()); assertThat(found.getVisits()).isEqualTo(petDTO.getVisits()); } @@ -158,7 +158,7 @@ class PetServiceTest { List found = petService.findAll(); - assertThat(found).contains(petDTO).containsAll(expected); + assertThat(found).hasSize(expected.size() + 1).contains(petDTO).containsAll(expected); } @@ -170,7 +170,7 @@ class PetServiceTest { petService.save(petDTO); - assertThat(petService.findAll()).contains(petDTO); + assertThat(petService.findAll()).containsAnyOf(petDTO); } } diff --git a/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java b/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java index 3f11bf551..f1c833820 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java +++ b/src/test/java/org/springframework/samples/petclinic/service/VetServiceTest.java @@ -32,6 +32,7 @@ class VetServiceTest { @Autowired private VetRepository vetRepository; + @Autowired private SpecialtyRepository specialtyRepository; From f7f07f42dd44851e133902e92bbece43c07e6268 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Mon, 19 Oct 2020 18:18:03 +0200 Subject: [PATCH 15/16] PetDTO fix loop in equal testing for OwnerDTO attribute --- .../petclinic/controller/PetController.java | 2 +- .../petclinic/controller/VisitController.java | 2 +- .../samples/petclinic/dto/OwnerDTO.java | 2 +- .../samples/petclinic/dto/PetDTO.java | 4 +++- .../petclinic/repository/PetRepository.java | 8 ++++++- .../samples/petclinic/service/PetService.java | 22 +++++++++---------- .../controller/VisitControllerTests.java | 2 +- 7 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index 56989396d..d0d8ca9d7 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -110,7 +110,7 @@ class PetController { @PostMapping(CommonEndPoint.PETS_ID_EDIT) public String processUpdateForm(@ModelAttribute(CommonAttribute.PET) @Valid PetDTO pet, BindingResult result, - OwnerDTO owner, ModelMap model) { + @ModelAttribute(CommonAttribute.OWNER) OwnerDTO owner, ModelMap model) { if (result.hasErrors()) { pet.setOwner(owner); model.put(CommonAttribute.PET, pet); diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java index a3e67a073..3fb9bfb4c 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java @@ -80,7 +80,7 @@ class VisitController { // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called @GetMapping(CommonEndPoint.VISITS_NEW) public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { - return CommonView.PET_CREATE_OR_UPDATE; + return CommonView.VISIT_CREATE_OR_UPDATE; } // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java index 4da660d16..938e095c9 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java @@ -86,7 +86,7 @@ public class OwnerDTO extends PersonDTO { public void addPet(PetDTO pet) { - if (!this.getPets().contains(pet)) { + if (pet.isNew() || this.getPets() == null || !this.getPets().contains(pet)) { getPetsInternal().add(pet); } pet.setOwner(this); diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java index c5b0315cd..c51587db9 100644 --- a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java +++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java @@ -90,6 +90,8 @@ public class PetDTO extends NamedDTO { return true; if (!(o instanceof PetDTO)) return false; + if (!super.equals(o)) + return false; PetDTO petDTO = (PetDTO) o; @@ -97,7 +99,7 @@ public class PetDTO extends NamedDTO { return false; if (!getType().equals(petDTO.getType())) return false; - if (!getOwner().getId().equals(petDTO.getOwner().getId())) + if (getOwner() != null ? !getOwner().getId().equals(petDTO.getOwner().getId()) : petDTO.getOwner() != null) return false; return getVisits() != null ? getVisits().equals(petDTO.getVisits()) : petDTO.getVisits() == null; } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java index fa90093f3..1d52108c9 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java @@ -15,7 +15,6 @@ */ package org.springframework.samples.petclinic.repository; -import java.util.Collection; import java.util.List; import org.springframework.data.jpa.repository.Query; @@ -53,6 +52,13 @@ public interface PetRepository extends Repository { */ Pet findById(Integer id); + /** + * Retrieve all {@link Pet}d from the data store by owner id. + * @param id the id of owner to search for + * @return a Collection of {@link Pet}s + */ + List findByOwnerId(Integer id); + /** * Retrieve all {@link Pet}s from the data store * @return a Collection of {@link Pet}s (or an empty Collection if none diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java index 563f6b48b..20c74b15d 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/PetService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java @@ -50,7 +50,7 @@ public class PetService implements BaseService { dto.getVisits().forEach(visitDTO -> pet.addVisit(visitService.dtoToEntity(visitDTO))); dto.getOwner().getPets().forEach(petDTO -> { - if (petDTO.getId().equals(dto.getId())) { + if (dto.getId() == null || petDTO.getId().equals(dto.getId())) { owner.addPet(pet); } else { @@ -72,18 +72,14 @@ public class PetService implements BaseService { PetDTO petDTO = modelMapper.map(entity, PetDTO.class); OwnerDTO ownerDTO = modelMapper.map(entity.getOwner(), OwnerDTO.class); + petRepository.findByOwnerId(ownerDTO.getId()).forEach(pet -> { + PetDTO otherPetDTO = modelMapper.map(pet, PetDTO.class); + otherPetDTO.setOwner(ownerDTO); + ownerDTO.addPet(otherPetDTO); + }); + entity.getVisits().forEach(visit -> petDTO.addVisit(visitService.entityToDTO(visit))); - entity.getOwner().getPets().forEach(pet -> { - if (pet.getId().equals(entity.getId())) { - ownerDTO.addPet(petDTO); - } - else { - PetDTO otherPetDTO = modelMapper.map(pet, PetDTO.class); - otherPetDTO.setOwner(ownerDTO); - ownerDTO.addPet(otherPetDTO); - } - }); petDTO.setOwner(ownerDTO); return petDTO; } @@ -125,6 +121,10 @@ public class PetService implements BaseService { petRepository.save(dtoToEntity(petDTO)); } + public List findByOwnerId(int id) { + return entitiesToDTOS(petRepository.findByOwnerId(id)); + } + public List findPetTypes() { List petTypes = petRepository.findPetTypes(); diff --git a/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java index f5cb862c4..718bab0f0 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/VisitControllerTests.java @@ -65,7 +65,7 @@ class VisitControllerTests { @Tag("initNewVisitForm") void testInitNewVisitForm() throws Exception { mockMvc.perform(get(CommonEndPoint.VISITS_NEW, TEST_PET_ID)).andExpect(status().isOk()) - .andExpect(view().name(CommonView.PET_CREATE_OR_UPDATE)); + .andExpect(view().name(CommonView.VISIT_CREATE_OR_UPDATE)); } @Test From 2d491434906ca54066fc2e2373edda15a9f203c2 Mon Sep 17 00:00:00 2001 From: PEDSF Date: Tue, 20 Oct 2020 17:59:24 +0200 Subject: [PATCH 16/16] Change modelmapper version --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b48f5e05d..4cc8bd611 100644 --- a/pom.xml +++ b/pom.xml @@ -71,9 +71,10 @@ - org.modelmapper.extensions - modelmapper-spring - 2.3.0 + org.modelmapper + modelmapper + 2.3.8 + compile