mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-04-24 19:32:48 +00:00
parent
25ba1621a9
commit
8ad9c05f74
27 changed files with 323 additions and 192 deletions
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object with an id property. Used as a base class for objects
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Set;
|
|||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.Digits;
|
||||
|
@ -59,7 +60,7 @@ public class Owner extends Person {
|
|||
@Digits(fraction = 0, integer = 10)
|
||||
private String telephone;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch = FetchType.EAGER)
|
||||
private Set<Pet> pets;
|
||||
|
||||
public String getAddress() {
|
||||
|
|
|
@ -15,6 +15,14 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
|
@ -24,12 +32,9 @@ 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.RequestParam;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Ken Krebs
|
||||
|
@ -43,7 +48,7 @@ class OwnerController {
|
|||
|
||||
private final OwnerRepository owners;
|
||||
|
||||
private VisitRepository visits;
|
||||
private final VisitRepository visits;
|
||||
|
||||
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
|
||||
this.owners = clinicService;
|
||||
|
@ -80,7 +85,8 @@ class OwnerController {
|
|||
}
|
||||
|
||||
@GetMapping("/owners")
|
||||
public String processFindForm(Owner owner, BindingResult result, Map<String, Object> model) {
|
||||
public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result,
|
||||
Model model) {
|
||||
|
||||
// allow parameterless GET request for /owners to return all records
|
||||
if (owner.getLastName() == null) {
|
||||
|
@ -88,22 +94,41 @@ class OwnerController {
|
|||
}
|
||||
|
||||
// find owners by last name
|
||||
Collection<Owner> results = this.owners.findByLastName(owner.getLastName());
|
||||
if (results.isEmpty()) {
|
||||
String lastName = owner.getLastName();
|
||||
Page<Owner> ownersResults = findPaginatedForOwnersLastName(page, lastName);
|
||||
if (ownersResults.isEmpty()) {
|
||||
// no owners found
|
||||
result.rejectValue("lastName", "notFound", "not found");
|
||||
return "owners/findOwners";
|
||||
}
|
||||
else if (results.size() == 1) {
|
||||
else if (ownersResults.getTotalElements() == 1) {
|
||||
// 1 owner found
|
||||
owner = results.iterator().next();
|
||||
owner = ownersResults.iterator().next();
|
||||
return "redirect:/owners/" + owner.getId();
|
||||
}
|
||||
else {
|
||||
// multiple owners found
|
||||
model.put("selections", results);
|
||||
lastName = owner.getLastName();
|
||||
return addPaginationModel(page, model, lastName, ownersResults);
|
||||
}
|
||||
}
|
||||
|
||||
private String addPaginationModel(int page, Model model, String lastName, Page<Owner> paginated) {
|
||||
model.addAttribute("listOwners", paginated);
|
||||
List<Owner> listOwners = paginated.getContent();
|
||||
model.addAttribute("currentPage", page);
|
||||
model.addAttribute("totalPages", paginated.getTotalPages());
|
||||
model.addAttribute("totalItems", paginated.getTotalElements());
|
||||
model.addAttribute("listOwners", listOwners);
|
||||
return "owners/ownersList";
|
||||
}
|
||||
|
||||
private Page<Owner> findPaginatedForOwnersLastName(int page, String lastname) {
|
||||
|
||||
int pageSize = 5;
|
||||
Pageable pageable = PageRequest.of(page - 1, pageSize);
|
||||
return owners.findByLastName(lastname, pageable);
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/owners/{ownerId}/edit")
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
@ -42,9 +42,10 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
|
|||
* @return a Collection of matching {@link Owner}s (or an empty Collection if none
|
||||
* found)
|
||||
*/
|
||||
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
|
||||
|
||||
@Query("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.lastName LIKE :lastName% ")
|
||||
@Transactional(readOnly = true)
|
||||
Collection<Owner> findByLastName(@Param("lastName") String lastName);
|
||||
Page<Owner> findByLastName(@Param("lastName") String lastName, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Retrieve an {@link Owner} from the data store by id.
|
||||
|
@ -61,4 +62,11 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
|
|||
*/
|
||||
void save(Owner owner);
|
||||
|
||||
/**
|
||||
* Returnes all the owners from data store
|
||||
**/
|
||||
@Query("SELECT owner FROM Owner owner")
|
||||
@Transactional(readOnly = true)
|
||||
Page<Owner> findAll(Pageable pageable);
|
||||
|
||||
}
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Repository class for <code>Pet</code> domain objects All method names are compliant
|
||||
* with Spring Data naming conventions so this interface can easily be extended for Spring
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
|
||||
*/
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
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.stereotype.Component;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting
|
||||
* from Spring 3.0, Formatters have come as an improvement in comparison to legacy
|
||||
|
|
|
@ -15,20 +15,15 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
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;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
|
||||
package org.springframework.samples.petclinic.system;
|
||||
|
||||
import javax.cache.configuration.MutableConfiguration;
|
||||
|
||||
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.cache.configuration.MutableConfiguration;
|
||||
|
||||
/**
|
||||
* Cache configuration intended for caches providing the JCache API. This configuration
|
||||
* creates the used cache for the application and enables statistics that become
|
||||
|
|
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Models a {@link Vet Vet's} specialty (for example, dentistry).
|
||||
|
|
|
@ -15,24 +15,14 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
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;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing a veterinarian.
|
||||
*
|
||||
|
|
|
@ -15,11 +15,17 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
|
@ -37,15 +43,31 @@ class VetController {
|
|||
}
|
||||
|
||||
@GetMapping("/vets.html")
|
||||
public String showVetList(Map<String, Object> model) {
|
||||
public String showVetList(@RequestParam(defaultValue = "1") int page, Model 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());
|
||||
model.put("vets", vets);
|
||||
Page<Vet> paginated = findPaginated(page);
|
||||
vets.getVetList().addAll(paginated.toList());
|
||||
return addPaginationModel(page, paginated, model);
|
||||
|
||||
}
|
||||
|
||||
private String addPaginationModel(int page, Page<Vet> paginated, Model model) {
|
||||
List<Vet> listVets = paginated.getContent();
|
||||
model.addAttribute("currentPage", page);
|
||||
model.addAttribute("totalPages", paginated.getTotalPages());
|
||||
model.addAttribute("totalItems", paginated.getTotalElements());
|
||||
model.addAttribute("listVets", listVets);
|
||||
return "vets/vetList";
|
||||
}
|
||||
|
||||
private Page<Vet> findPaginated(int page) {
|
||||
int pageSize = 5;
|
||||
Pageable pageable = PageRequest.of(page - 1, pageSize);
|
||||
return vets.findAll(pageable);
|
||||
}
|
||||
|
||||
@GetMapping({ "/vets" })
|
||||
public @ResponseBody Vets showResourcesVetList() {
|
||||
// Here we are returning an object of type 'Vets' rather than a collection of Vet
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Repository class for <code>Vet</code> domain objects All method names are compliant
|
||||
* with Spring Data naming conventions so this interface can easily be extended for Spring
|
||||
|
@ -43,4 +45,16 @@ public interface VetRepository extends Repository<Vet, Integer> {
|
|||
@Cacheable("vets")
|
||||
Collection<Vet> findAll() throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Retrieve all <code>Vet</code>s from data store in Pages
|
||||
* @param pageable
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
@Cacheable("vets")
|
||||
Page<Vet> findAll(Pageable pageable) throws DataAccessException;
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
|
|
|
@ -15,11 +15,10 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Simple domain object representing a list of veterinarians. Mostly here to be used for
|
||||
|
|
|
@ -15,15 +15,14 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.visit;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing a visit.
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.visit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Repository class for <code>Visit</code> domain objects All method names are compliant
|
||||
* with Spring Data naming conventions so this interface can easily be extended for Spring
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="owner : ${selections}">
|
||||
<tr th:each="owner : ${listOwners}">
|
||||
<td>
|
||||
<a th:href="@{/owners/__${owner.id}__}" th:text="${owner.firstName + ' ' + owner.lastName}"/></a>
|
||||
</td>
|
||||
|
@ -28,6 +28,35 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div th:if="${totalPages > 1}">
|
||||
<span>Pages:</span>
|
||||
<span>[</span>
|
||||
<span th:each="i: ${#numbers.sequence(1, totalPages)}">
|
||||
<a th:if="${currentPage != i}" th:href="@{'/owners/' + ${i}}">[[${i}]]</a>
|
||||
<span th:unless="${currentPage != i}">[[${i}]]</span>
|
||||
</span>
|
||||
<span>] </span>
|
||||
<span>
|
||||
<a th:if="${currentPage > 1}" th:href="@{'/owners/?page=1'}" title="First"
|
||||
class="glyphicon glyphicon-backward"></a>
|
||||
<span th:unless="${currentPage > 1}" title="First" class="glyphicon glyphicon-backward"></span>
|
||||
</span>
|
||||
<span>
|
||||
<a th:if="${currentPage > 1}" th:href="@{'/owners/?page=' + ${currentPage - 1}}" title="Previous"
|
||||
class="glyphicon glyphicon-triangle-left"></a>
|
||||
<span th:unless="${currentPage > 1}" title="Previous" class="glyphicon glyphicon-triangle-left"></span>
|
||||
</span>
|
||||
<span>
|
||||
<a th:if="${currentPage < totalPages}" th:href="@{'/owners/?page=' + ${currentPage + 1}}" title="Next"
|
||||
class="glyphicon glyphicon-triangle-right"></a>
|
||||
<span th:unless="${currentPage < totalPages}" title="Next" class="glyphicon glyphicon-triangle-right"></span>
|
||||
</span>
|
||||
<span>
|
||||
<a th:if="${currentPage < totalPages}" th:href="@{'/owners/?page=' + ${totalPages}}" title="Last"
|
||||
class="glyphicon glyphicon-forward"></a>
|
||||
<span th:unless="${currentPage < totalPages}" title="Last" class="glyphicon glyphicon-forward"></span>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="vet : ${vets.vetList}">
|
||||
<tr th:each="vet : ${listVets}">
|
||||
<td th:text="${vet.firstName + ' ' + vet.lastName}"></td>
|
||||
<td><span th:each="specialty : ${vet.specialties}"
|
||||
th:text="${specialty.name + ' '}"/> <span
|
||||
|
@ -23,5 +23,35 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div th:if="${totalPages > 1}">
|
||||
<span>Pages:</span>
|
||||
<span>[</span>
|
||||
<span th:each="i: ${#numbers.sequence(1, totalPages)}">
|
||||
<a th:if="${currentPage != i}" th:href="@{'/vets/' + ${i}}">[[${i}]]</a>
|
||||
<span th:unless="${currentPage != i}">[[${i}]]</span>
|
||||
</span>
|
||||
<span>] </span>
|
||||
<span>
|
||||
<a th:if="${currentPage > 1}" th:href="@{'/vets.html/?page=1'}" title="First"
|
||||
class="glyphicon glyphicon-backward"></a>
|
||||
<span th:unless="${currentPage > 1}" title="First" class="glyphicon glyphicon-backward"></span>
|
||||
</span>
|
||||
<span>
|
||||
<a th:if="${currentPage > 1}" th:href="@{'/vets.html/?page=' + ${currentPage - 1}}" title="Previous"
|
||||
class="glyphicon glyphicon-triangle-left"></a>
|
||||
<span th:unless="${currentPage > 1}" title="Previous" class="glyphicon glyphicon-triangle-left"></span>
|
||||
</span>
|
||||
<span>
|
||||
<a th:if="${currentPage < totalPages}" th:href="@{'/vets.html/?page=' + ${currentPage + 1}}" title="Next"
|
||||
class="glyphicon glyphicon-triangle-right"></a>
|
||||
<span th:unless="${currentPage < totalPages}" title="Next" class="glyphicon glyphicon-triangle-right"></span>
|
||||
</span>
|
||||
<span>
|
||||
<a th:if="${currentPage < totalPages}" th:href="@{'/vets.html/?page=' + ${totalPages}}" title="Last"
|
||||
class="glyphicon glyphicon-forward"></a>
|
||||
<span th:unless="${currentPage < totalPages}" title="Last" class="glyphicon glyphicon-forward"></span>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
|
||||
package org.springframework.samples.petclinic.model;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validator;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validator;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,32 +16,34 @@
|
|||
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
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.Test;
|
||||
import org.mockito.Mockito;
|
||||
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.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.samples.petclinic.visit.Visit;
|
||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasProperty;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
* Test class for {@link OwnerController}
|
||||
|
@ -81,10 +83,17 @@ class OwnerControllerTests {
|
|||
max.setName("Max");
|
||||
max.setBirthDate(LocalDate.now());
|
||||
george.setPetsInternal(Collections.singleton(max));
|
||||
|
||||
given(this.owners.findByLastName(eq("Franklin"), any(Pageable.class)))
|
||||
.willReturn(new PageImpl<Owner>(Lists.newArrayList(george)));
|
||||
|
||||
given(this.owners.findAll(any(Pageable.class))).willReturn(new PageImpl<Owner>(Lists.newArrayList(george)));
|
||||
|
||||
given(this.owners.findById(TEST_OWNER_ID)).willReturn(george);
|
||||
Visit visit = new Visit();
|
||||
visit.setDate(LocalDate.now());
|
||||
given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -118,23 +127,35 @@ class OwnerControllerTests {
|
|||
|
||||
@Test
|
||||
void testProcessFindFormSuccess() throws Exception {
|
||||
given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner()));
|
||||
mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList"));
|
||||
Page<Owner> tasks = Mockito.mock(Page.class);
|
||||
Mockito.when(this.owners.findByLastName(anyString(), org.mockito.Matchers.isA(Pageable.class)))
|
||||
.thenReturn(tasks);
|
||||
mockMvc.perform(get("/owners?page=1")).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())
|
||||
|
||||
Page<Owner> tasks = new PageImpl<Owner>(Lists.newArrayList(george));
|
||||
String lastName = george.getLastName();
|
||||
Mockito.when(this.owners.findByLastName(eq("Franklin"), any(Pageable.class))).thenReturn(tasks);
|
||||
mockMvc.perform(get("/owners?page=1").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())
|
||||
int pageNumber = 0;
|
||||
int pageSize = 1, size = 0;
|
||||
Pageable pageable = PageRequest.of(pageNumber, pageSize);
|
||||
Page<Owner> tasks = new PageImpl<Owner>(Lists.newArrayList());
|
||||
Mockito.when(this.owners.findByLastName(eq("Unknown Surname"), org.mockito.Matchers.isA(Pageable.class)))
|
||||
.thenReturn(tasks);
|
||||
mockMvc.perform(get("/owners?page=1").param("lastName", "Unknown Surname")).andExpect(status().isOk())
|
||||
.andExpect(model().attributeHasFieldErrors("owner", "lastName"))
|
||||
.andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound"))
|
||||
.andExpect(view().name("owners/findOwners"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -16,13 +16,6 @@
|
|||
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -33,6 +26,11 @@ import org.springframework.context.annotation.ComponentScan;
|
|||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
* Test class for the {@link PetController}
|
||||
*
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -29,6 +23,12 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -16,13 +16,6 @@
|
|||
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -31,6 +24,11 @@ import org.springframework.boot.test.mock.mockito.MockBean;
|
|||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
* Test class for {@link VisitController}
|
||||
*
|
||||
|
|
|
@ -16,20 +16,13 @@
|
|||
|
||||
package org.springframework.samples.petclinic.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
|
||||
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.owner.OwnerRepository;
|
||||
import org.springframework.samples.petclinic.owner.Pet;
|
||||
import org.springframework.samples.petclinic.owner.PetRepository;
|
||||
import org.springframework.samples.petclinic.owner.PetType;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.samples.petclinic.owner.*;
|
||||
import org.springframework.samples.petclinic.vet.Vet;
|
||||
import org.springframework.samples.petclinic.vet.VetRepository;
|
||||
import org.springframework.samples.petclinic.visit.Visit;
|
||||
|
@ -37,6 +30,11 @@ import org.springframework.samples.petclinic.visit.VisitRepository;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration test of the Service and the Repository layer.
|
||||
* <p>
|
||||
|
@ -48,8 +46,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* time between test execution.</li>
|
||||
* <li><strong>Dependency Injection</strong> of test fixture instances, meaning that we
|
||||
* don't need to perform application context lookups. See the use of
|
||||
* {@link Autowired @Autowired} on the <code>{@link
|
||||
* ClinicServiceTests#clinicService clinicService}</code> instance variable, which uses
|
||||
* {@link Autowired @Autowired} on the <code> </code> instance variable, which uses
|
||||
* autowiring <em>by type</em>.
|
||||
* <li><strong>Transaction management</strong>, meaning each test method is executed in
|
||||
* its own transaction, which is automatically rolled back by default. Thus, even if tests
|
||||
|
@ -81,12 +78,14 @@ class ClinicServiceTests {
|
|||
@Autowired
|
||||
protected VetRepository vets;
|
||||
|
||||
Pageable pageable;
|
||||
|
||||
@Test
|
||||
void shouldFindOwnersByLastName() {
|
||||
Collection<Owner> owners = this.owners.findByLastName("Davis");
|
||||
Page<Owner> owners = this.owners.findByLastName("Davis", pageable);
|
||||
assertThat(owners).hasSize(2);
|
||||
|
||||
owners = this.owners.findByLastName("Daviss");
|
||||
owners = this.owners.findByLastName("Daviss", pageable);
|
||||
assertThat(owners).isEmpty();
|
||||
}
|
||||
|
||||
|
@ -102,8 +101,8 @@ class ClinicServiceTests {
|
|||
@Test
|
||||
@Transactional
|
||||
void shouldInsertOwner() {
|
||||
Collection<Owner> owners = this.owners.findByLastName("Schultz");
|
||||
int found = owners.size();
|
||||
Page<Owner> owners = this.owners.findByLastName("Schultz", pageable);
|
||||
int found = (int) owners.getTotalElements();
|
||||
|
||||
Owner owner = new Owner();
|
||||
owner.setFirstName("Sam");
|
||||
|
@ -114,8 +113,8 @@ class ClinicServiceTests {
|
|||
this.owners.save(owner);
|
||||
assertThat(owner.getId().longValue()).isNotEqualTo(0);
|
||||
|
||||
owners = this.owners.findByLastName("Schultz");
|
||||
assertThat(owners.size()).isEqualTo(found + 1);
|
||||
owners = this.owners.findByLastName("Schultz", pageable);
|
||||
assertThat(owners.getTotalElements()).isEqualTo(found + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
package org.springframework.samples.petclinic.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.orm.ObjectRetrievalFailureException;
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Utility methods for handling entities. Separate from the BaseEntity class mainly
|
||||
* because of dependency on the ORM-associated ObjectRetrievalFailureException.
|
||||
|
|
|
@ -23,10 +23,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
* Test class for {@link CrashController}
|
||||
|
|
|
@ -16,27 +16,28 @@
|
|||
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
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.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
* Test class for the {@link VetController}
|
||||
*/
|
||||
|
||||
@WebMvcTest(VetController.class)
|
||||
class VetControllerTests {
|
||||
|
||||
|
@ -46,13 +47,17 @@ class VetControllerTests {
|
|||
@MockBean
|
||||
private VetRepository vets;
|
||||
|
||||
private Vet james;
|
||||
|
||||
private Vet helen;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
Vet james = new Vet();
|
||||
james = new Vet();
|
||||
james.setFirstName("James");
|
||||
james.setLastName("Carter");
|
||||
james.setId(1);
|
||||
Vet helen = new Vet();
|
||||
helen = new Vet();
|
||||
helen.setFirstName("Helen");
|
||||
helen.setLastName("Leary");
|
||||
helen.setId(2);
|
||||
|
@ -61,12 +66,16 @@ class VetControllerTests {
|
|||
radiology.setName("radiology");
|
||||
helen.addSpecialty(radiology);
|
||||
given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen));
|
||||
given(this.vets.findAll(any(Pageable.class))).willReturn(new PageImpl<Vet>(Lists.newArrayList(james, helen)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShowVetListHtml() throws Exception {
|
||||
mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets"))
|
||||
.andExpect(view().name("vets/vetList"));
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/vets.html?page=1")).andExpect(status().isOk())
|
||||
.andExpect(model().attributeExists("listVets")).andExpect(view().name("vets/vetList"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in a new issue