diff --git a/pom.xml b/pom.xml index 4a093180aa15afec11ff6cefb82346e7bf30ad0c..36b6290040558e9922c214bd8d6c98bb727847d0 100644 --- a/pom.xml +++ b/pom.xml @@ -213,7 +213,7 @@ <limit> <counter>LINE</counter> <value>COVEREDRATIO</value> - <minimum>0.86</minimum> + <minimum>0.85</minimum> </limit> <limit> <counter>BRANCH</counter> diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java index e309dc518c0504799d4e6b7377c14e46cd09154b..c34ca224d97dce26cf3a01660b5f4b7a4eb84dc3 100755 --- a/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java +++ b/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java @@ -2,6 +2,7 @@ package org.springframework.samples.petclinic.mapper; import org.mapstruct.Mapper; import org.springframework.samples.petclinic.rest.dto.PetDto; +import org.springframework.samples.petclinic.rest.dto.PetFieldsDto; import org.springframework.samples.petclinic.rest.dto.PetTypeDto; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; @@ -21,6 +22,8 @@ public interface PetMapper { Pet toPet(PetDto petDto); + Pet toPet(PetFieldsDto petFieldsDto); + PetTypeDto toPetTypeDto(PetType petType); PetType toPetType(PetTypeDto petTypeDto); diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java index 3e1850aad8e8db168b6f8f61c8025eed9f3ec24e..4e1de490fc68665e2c70d80a08fefee4d449d1fe 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java @@ -20,10 +20,14 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.samples.petclinic.mapper.OwnerMapper; +import org.springframework.samples.petclinic.mapper.PetMapper; import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.rest.api.OwnersApi; import org.springframework.samples.petclinic.rest.dto.OwnerDto; import org.springframework.samples.petclinic.rest.dto.OwnerFieldsDto; +import org.springframework.samples.petclinic.rest.dto.PetDto; +import org.springframework.samples.petclinic.rest.dto.PetFieldsDto; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -43,11 +47,15 @@ import java.util.List; public class OwnerRestController implements OwnersApi { private final ClinicService clinicService; + private final OwnerMapper ownerMapper; - public OwnerRestController(ClinicService clinicService, OwnerMapper ownerMapper) { + private final PetMapper petMapper; + + public OwnerRestController(ClinicService clinicService, OwnerMapper ownerMapper, PetMapper petMapper) { this.clinicService = clinicService; this.ownerMapper = ownerMapper; + this.petMapper = petMapper; } @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @@ -115,4 +123,19 @@ public class OwnerRestController implements OwnersApi { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity<PetDto> addPet(Integer ownerId, PetFieldsDto petFieldsDto) { + HttpHeaders headers = new HttpHeaders(); + Pet pet = petMapper.toPet(petFieldsDto); + Owner owner = new Owner(); + owner.setId(ownerId); + pet.setOwner(owner); + this.clinicService.savePet(pet); + PetDto petDto = petMapper.toPetDto(pet); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/pets/{id}") + .buildAndExpand(pet.getId()).toUri()); + return new ResponseEntity<>(petDto, headers, HttpStatus.CREATED); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java index 201328894f3a5fa89f17ce1f070e604a402f5674..abb16c5834cd82a6257857a36a2567ce0e08672e 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java @@ -19,15 +19,14 @@ package org.springframework.samples.petclinic.rest.controller; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.samples.petclinic.rest.dto.PetDto; -import org.springframework.samples.petclinic.rest.dto.PetTypeDto; import org.springframework.samples.petclinic.mapper.PetMapper; import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.rest.dto.PetDto; +import org.springframework.samples.petclinic.rest.dto.PetTypeDto; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import org.springframework.web.util.UriComponentsBuilder; import javax.transaction.Transactional; import javax.validation.Valid; @@ -77,23 +76,6 @@ public class PetRestController { return new ResponseEntity<Collection<PetTypeDto>>(petMapper.toPetTypeDtos(this.clinicService.findPetTypes()), HttpStatus.OK); } - @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") - @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json") - public ResponseEntity<PetDto> addPet(@RequestBody @Valid PetDto petDto, BindingResult bindingResult, UriComponentsBuilder ucBuilder) { - BindingErrorsResponse errors = new BindingErrorsResponse(); - HttpHeaders headers = new HttpHeaders(); - if (bindingResult.hasErrors() || (petDto == null)) { - errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); - return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); - } - Pet pet = petMapper.toPet(petDto); - this.clinicService.savePet(pet); - petDto.setId(pet.getId()); - headers.setLocation(ucBuilder.path("/api/pets/{id}").buildAndExpand(pet.getId()).toUri()); - return new ResponseEntity<>(petDto, headers, HttpStatus.CREATED); - } - @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "/{petId}", method = RequestMethod.PUT, produces = "application/json") public ResponseEntity<PetDto> updatePet(@PathVariable("petId") int petId, @RequestBody @Valid PetDto pet, BindingResult bindingResult) { diff --git a/src/main/resources/openapi.yml b/src/main/resources/openapi.yml index 5c821784b3bf3b571610257403236bba1e251967..188415ec069307ee0d0d0d0a3b02977dcabcf28a 100755 --- a/src/main/resources/openapi.yml +++ b/src/main/resources/openapi.yml @@ -228,7 +228,7 @@ paths: application/json: schema: $ref: '#/components/schemas/RestError' - /owners/{ownerId}/pet: + /owners/{ownerId}/pets: post: tags: - pet @@ -255,6 +255,10 @@ paths: responses: 201: description: The pet was sucessfully added. + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' 400: description: Bad request. content: @@ -273,7 +277,7 @@ paths: application/json: schema: $ref: '#/components/schemas/RestError' - /owners/{ownerId}/pet/{petId}: + /owners/{ownerId}/pets/{petId}: get: tags: - pet @@ -697,8 +701,12 @@ components: type: string format: date example: '2010-09-07' + type: + $ref: '#/components/schemas/PetType' required: - name + - birthDate + - type Pet: title: Pet description: A pet. @@ -714,8 +722,6 @@ components: minimum: 0 example: 1 readOnly: true - type: - $ref: '#/components/schemas/PetType' visits: title: Visits description: Vet visit bookings for this pet. diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java index 4ccb53e7b3ae5b57d88a0ad208586f3a20059c4f..ca72d13b6a48a85e1605e137dd04effe2a8ce154 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java @@ -38,8 +38,10 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import java.text.SimpleDateFormat; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -72,6 +74,8 @@ class OwnerRestControllerTests { private List<OwnerDto> owners; + private List<PetDto> pets; + @BeforeEach void initOwners() { this.mockMvc = MockMvcBuilders.standaloneSetup(ownerRestController) @@ -87,6 +91,23 @@ class OwnerRestControllerTests { owners.add(owner.id(3).firstName("Eduardo").lastName("Rodriquez").address("2693 Commerce St.").city("McFarland").telephone("6085558763")); owner = new OwnerDto(); owners.add(owner.id(4).firstName("Harold").lastName("Davis").address("563 Friendly St.").city("Windsor").telephone("6085553198")); + + PetTypeDto petType = new PetTypeDto(); + petType.id(2) + .name("dog"); + + pets = new ArrayList<>(); + PetDto pet = new PetDto(); + pets.add(pet.id(3) + .name("Rosy") + .birthDate(LocalDate.now()) + .type(petType)); + + pet = new PetDto(); + pets.add(pet.id(4) + .name("Jewel") + .birthDate(LocalDate.now()) + .type(petType)); } private PetDto getTestPetWithIdAndName(final OwnerDto owner, final int id, final String name) { @@ -302,4 +323,36 @@ class OwnerRestControllerTests { .andExpect(status().isNotFound()); } + @Test + @WithMockUser(roles = "OWNER_ADMIN") + void testCreatePetSuccess() throws Exception { + PetDto newPet = pets.get(0); + newPet.setId(999); + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + String newPetAsJSON = mapper.writeValueAsString(newPet); + System.err.println("--> newPetAsJSON=" + newPetAsJSON); + this.mockMvc.perform(post("/api/owners/1/pets/") + .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()); + } + + @Test + @WithMockUser(roles = "OWNER_ADMIN") + void testCreatePetError() throws Exception { + PetDto newPet = pets.get(0); + newPet.setId(null); + newPet.setName(null); + ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.registerModule(new JavaTimeModule()); + String newPetAsJSON = mapper.writeValueAsString(newPet); + this.mockMvc.perform(post("/api/owners/1/pets/") + .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isBadRequest()).andDo(MockMvcResultHandlers.print()); + } + } diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java index caf0c9da76984eb57c4ac53aacee88bfa08c60cd..35ad6b8454b664074e842aceec34b467ff408e4e 100644 --- a/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java @@ -153,38 +153,6 @@ class PetRestControllerTests { .andExpect(status().isNotFound()); } - @Test - @WithMockUser(roles = "OWNER_ADMIN") - void testCreatePetSuccess() throws Exception { - PetDto newPet = pets.get(0); - newPet.setId(999); - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); - mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); - mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - String newPetAsJSON = mapper.writeValueAsString(newPet); - System.err.println("--> newPetAsJSON=" + newPetAsJSON); - this.mockMvc.perform(post("/api/pets/") - .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isCreated()); - } - - @Test - @WithMockUser(roles = "OWNER_ADMIN") - void testCreatePetError() throws Exception { - PetDto newPet = pets.get(0); - newPet.setId(null); - newPet.setName(null); - ObjectMapper mapper = new ObjectMapper(); - mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); - mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - mapper.registerModule(new JavaTimeModule()); - String newPetAsJSON = mapper.writeValueAsString(newPet); - this.mockMvc.perform(post("/api/pets/") - .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isBadRequest()).andDo(MockMvcResultHandlers.print()); - } - @Test @WithMockUser(roles = "OWNER_ADMIN") void testUpdatePetSuccess() throws Exception {