diff --git a/README.md b/README.md index 87de421a..18bc8439 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -# SFG Beer Works - Brewery Microservice \ No newline at end of file +# SFG Beer Works - Brewery Microservice + +Source code in this repository is to support my on line courses: +* [Spring Boot Microservices with Spring Cloud](https://www.udemy.com/spring-boot-microservices-with-spring-cloud-beginner-to-guru/?couponCode=GIT_HUB2) diff --git a/pom.xml b/pom.xml index 9ca39714..3318f7b4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.4.RELEASE + 2.1.5.RELEASE @@ -17,6 +17,8 @@ 11 + 1.4.2.Final + 1.18.18 @@ -37,8 +39,14 @@ org.projectlombok lombok + ${org.lombok.version} true + + org.mapstruct + mapstruct + ${mapstruct.version} + org.springframework.boot spring-boot-starter-test @@ -52,6 +60,33 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.projectlombok + lombok + ${org.lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + -Amapstruct.defaultComponentModel=spring + + + diff --git a/src/main/java/guru/springframework/msscbrewery/domain/Beer.java b/src/main/java/guru/springframework/msscbrewery/domain/Beer.java new file mode 100644 index 00000000..e467748a --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/domain/Beer.java @@ -0,0 +1,23 @@ +package guru.springframework.msscbrewery.domain; + +import guru.springframework.msscbrewery.web.model.v2.BeerStyleEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +/** + * Created by jt on 2019-05-25. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Beer { + private UUID id; + private String beerName; + private BeerStyleEnum beerStyle; + private Long upc; +} diff --git a/src/main/java/guru/springframework/msscbrewery/domain/Customer.java b/src/main/java/guru/springframework/msscbrewery/domain/Customer.java new file mode 100644 index 00000000..ce11230a --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/domain/Customer.java @@ -0,0 +1,20 @@ +package guru.springframework.msscbrewery.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +/** + * Created by jt on 2019-05-25. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Customer { + private UUID id; + private String name; +} diff --git a/src/main/java/guru/springframework/msscbrewery/services/BeerService.java b/src/main/java/guru/springframework/msscbrewery/services/BeerService.java index c24ff2bf..ea830e94 100644 --- a/src/main/java/guru/springframework/msscbrewery/services/BeerService.java +++ b/src/main/java/guru/springframework/msscbrewery/services/BeerService.java @@ -9,4 +9,10 @@ */ public interface BeerService { BeerDto getBeerById(UUID beerId); + + BeerDto saveNewBeer(BeerDto beerDto); + + void updateBeer(UUID beerId, BeerDto beerDto); + + void deleteById(UUID beerId); } diff --git a/src/main/java/guru/springframework/msscbrewery/services/BeerServiceImpl.java b/src/main/java/guru/springframework/msscbrewery/services/BeerServiceImpl.java index 1b6505f0..15856c77 100644 --- a/src/main/java/guru/springframework/msscbrewery/services/BeerServiceImpl.java +++ b/src/main/java/guru/springframework/msscbrewery/services/BeerServiceImpl.java @@ -1,6 +1,7 @@ package guru.springframework.msscbrewery.services; import guru.springframework.msscbrewery.web.model.BeerDto; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.UUID; @@ -8,6 +9,7 @@ /** * Created by jt on 2019-04-20. */ +@Slf4j @Service public class BeerServiceImpl implements BeerService { @Override @@ -17,4 +19,21 @@ public BeerDto getBeerById(UUID beerId) { .beerStyle("Pale Ale") .build(); } + + @Override + public BeerDto saveNewBeer(BeerDto beerDto) { + return BeerDto.builder() + .id(UUID.randomUUID()) + .build(); + } + + @Override + public void updateBeer(UUID beerId, BeerDto beerDto) { + //todo impl - would add a real impl to update beer + } + + @Override + public void deleteById(UUID beerId) { + log.debug("Deleting a beer..."); + } } diff --git a/src/main/java/guru/springframework/msscbrewery/services/CustomerService.java b/src/main/java/guru/springframework/msscbrewery/services/CustomerService.java new file mode 100644 index 00000000..6c2f9416 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/services/CustomerService.java @@ -0,0 +1,18 @@ +package guru.springframework.msscbrewery.services; + +import guru.springframework.msscbrewery.web.model.CustomerDto; + +import java.util.UUID; + +/** + * Created by jt on 2019-04-21. + */ +public interface CustomerService { + CustomerDto getCustomerById(UUID customerId); + + CustomerDto saveNewCustomer(CustomerDto customerDto); + + void updateCustomer(UUID customerId, CustomerDto customerDto); + + void deleteById(UUID customerId); +} diff --git a/src/main/java/guru/springframework/msscbrewery/services/CustomerServiceImpl.java b/src/main/java/guru/springframework/msscbrewery/services/CustomerServiceImpl.java new file mode 100644 index 00000000..7362b553 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/services/CustomerServiceImpl.java @@ -0,0 +1,40 @@ +package guru.springframework.msscbrewery.services; + +import guru.springframework.msscbrewery.web.model.CustomerDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +/** + * Created by jt on 2019-04-21. + */ +@Slf4j +@Service +public class CustomerServiceImpl implements CustomerService { + @Override + public CustomerDto getCustomerById(UUID customerId) { + return CustomerDto.builder() + .id(UUID.randomUUID()) + .name("Joe Buck") + .build(); + } + + @Override + public CustomerDto saveNewCustomer(CustomerDto customerDto) { + return CustomerDto.builder() + .id(UUID.randomUUID()) + .build(); + } + + @Override + public void updateCustomer(UUID customerId, CustomerDto customerDto) { + //todo impl + log.debug("Updating...."); + } + + @Override + public void deleteById(UUID customerId) { + log.debug("Deleting.... "); + } +} diff --git a/src/main/java/guru/springframework/msscbrewery/services/v2/BeerServiceV2.java b/src/main/java/guru/springframework/msscbrewery/services/v2/BeerServiceV2.java new file mode 100644 index 00000000..0392a508 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/services/v2/BeerServiceV2.java @@ -0,0 +1,18 @@ +package guru.springframework.msscbrewery.services.v2; + +import guru.springframework.msscbrewery.web.model.v2.BeerDtoV2; + +import java.util.UUID; + +/** + * Created by jt on 2019-04-23. + */ +public interface BeerServiceV2 { + BeerDtoV2 getBeerById(UUID beerId); + + BeerDtoV2 saveNewBeer(BeerDtoV2 beerDto); + + void updateBeer(UUID beerId, BeerDtoV2 beerDto); + + void deleteById(UUID beerId); +} diff --git a/src/main/java/guru/springframework/msscbrewery/services/v2/BeerServiceV2Impl.java b/src/main/java/guru/springframework/msscbrewery/services/v2/BeerServiceV2Impl.java new file mode 100644 index 00000000..fad00604 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/services/v2/BeerServiceV2Impl.java @@ -0,0 +1,32 @@ +package guru.springframework.msscbrewery.services.v2; + +import guru.springframework.msscbrewery.web.model.v2.BeerDtoV2; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +/** + * Created by jt on 2019-04-23. + */ +@Service +public class BeerServiceV2Impl implements BeerServiceV2 { + @Override + public BeerDtoV2 getBeerById(UUID beerId) { + return null; + } + + @Override + public BeerDtoV2 saveNewBeer(BeerDtoV2 beerDto) { + return null; + } + + @Override + public void updateBeer(UUID beerId, BeerDtoV2 beerDto) { + + } + + @Override + public void deleteById(UUID beerId) { + + } +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/controller/BeerController.java b/src/main/java/guru/springframework/msscbrewery/web/controller/BeerController.java index 49670652..6db632c3 100644 --- a/src/main/java/guru/springframework/msscbrewery/web/controller/BeerController.java +++ b/src/main/java/guru/springframework/msscbrewery/web/controller/BeerController.java @@ -2,18 +2,18 @@ import guru.springframework.msscbrewery.services.BeerService; import guru.springframework.msscbrewery.web.model.BeerDto; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import javax.validation.Valid; import java.util.UUID; /** * Created by jt on 2019-04-20. */ +@Deprecated @RequestMapping("/api/v1/beer") @RestController public class BeerController { @@ -30,4 +30,30 @@ public ResponseEntity getBeer(@PathVariable("beerId") UUID beerId){ return new ResponseEntity<>(beerService.getBeerById(beerId), HttpStatus.OK); } + @PostMapping // POST - create new beer + public ResponseEntity handlePost(@Valid @RequestBody BeerDto beerDto){ + + BeerDto savedDto = beerService.saveNewBeer(beerDto); + + HttpHeaders headers = new HttpHeaders(); + //todo add hostname to url + headers.add("Location", "/api/v1/beer/" + savedDto.getId().toString()); + + return new ResponseEntity(headers, HttpStatus.CREATED); + } + + @PutMapping({"/{beerId}"}) + public ResponseEntity handleUpdate(@PathVariable("beerId") UUID beerId, @Valid @RequestBody BeerDto beerDto){ + + beerService.updateBeer(beerId, beerDto); + + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @DeleteMapping({"/{beerId}"}) + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteBeer(@PathVariable("beerId") UUID beerId){ + beerService.deleteById(beerId); + } + } diff --git a/src/main/java/guru/springframework/msscbrewery/web/controller/CustomerController.java b/src/main/java/guru/springframework/msscbrewery/web/controller/CustomerController.java new file mode 100644 index 00000000..c4d4224d --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/controller/CustomerController.java @@ -0,0 +1,54 @@ +package guru.springframework.msscbrewery.web.controller; + +import guru.springframework.msscbrewery.services.CustomerService; +import guru.springframework.msscbrewery.web.model.CustomerDto; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.UUID; + +/** + * Created by jt on 2019-04-21. + */ + +@RequestMapping("api/v1/customer") +@RestController +public class CustomerController { + + private CustomerService customerService; + + public CustomerController(CustomerService customerService) { + this.customerService = customerService; + } + + @GetMapping("/{customerId}") + public ResponseEntity getCustomer(@PathVariable("customerId") UUID customerId){ + + return new ResponseEntity<>(customerService.getCustomerById(customerId), HttpStatus.OK); + } + + @PostMapping + public ResponseEntity handlePost(@RequestBody @Validated CustomerDto customerDto){ + CustomerDto savedDto = customerService.saveNewCustomer(customerDto); + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("Location", "/api/v1/customer/" + savedDto.getId().toString()); + + return new ResponseEntity(httpHeaders, HttpStatus.CREATED); + } + + @PutMapping("/{customerId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void handleUpdate(@PathVariable("customerId") UUID customerId, @Validated @RequestBody CustomerDto customerDto){ + customerService.updateCustomer(customerId, customerDto); + } + + @DeleteMapping("/{customerId}") + public void deleteById(@PathVariable("customerId") UUID customerId){ + customerService.deleteById(customerId); + } + +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/controller/MvcExceptionHandler.java b/src/main/java/guru/springframework/msscbrewery/web/controller/MvcExceptionHandler.java new file mode 100644 index 00000000..ce4bd52f --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/controller/MvcExceptionHandler.java @@ -0,0 +1,34 @@ +package guru.springframework.msscbrewery.web.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import javax.validation.ConstraintViolationException; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by jt on 2019-05-25. + */ +@ControllerAdvice +public class MvcExceptionHandler { + + @ExceptionHandler(ConstraintViolationException.class) + public ResponseEntity validationErrorHandler(ConstraintViolationException e){ + List errors = new ArrayList<>(e.getConstraintViolations().size()); + + e.getConstraintViolations().forEach(constraintViolation -> { + errors.add(constraintViolation.getPropertyPath() + " : " + constraintViolation.getMessage()); + }); + + return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(BindException.class) + public ResponseEntity handleBindException(BindException ex){ + return new ResponseEntity(ex.getAllErrors(), HttpStatus.BAD_REQUEST); + } +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/controller/v2/BeerControllerV2.java b/src/main/java/guru/springframework/msscbrewery/web/controller/v2/BeerControllerV2.java new file mode 100644 index 00000000..33906917 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/controller/v2/BeerControllerV2.java @@ -0,0 +1,60 @@ +package guru.springframework.msscbrewery.web.controller.v2; + +import guru.springframework.msscbrewery.services.v2.BeerServiceV2; +import guru.springframework.msscbrewery.web.model.v2.BeerDtoV2; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.UUID; + +/** + * Created by jt on 2019-04-23. + */ +@Slf4j +@RequiredArgsConstructor +@RequestMapping("/api/v2/beer") +@RestController +public class BeerControllerV2 { + private final BeerServiceV2 beerServiceV2; + + @GetMapping({"/{beerId}"}) + public ResponseEntity getBeer(@PathVariable("beerId") UUID beerId){ + + return new ResponseEntity<>(beerServiceV2.getBeerById(beerId), HttpStatus.OK); + } + + @PostMapping // POST - create new beer + public ResponseEntity handlePost(@Valid @RequestBody BeerDtoV2 beerDto){ + + log.debug("in handle post..."); + + val savedDto = beerServiceV2.saveNewBeer(beerDto); + + var headers = new HttpHeaders(); + //todo add hostname to url + headers.add("Location", "/api/v1/beer/" + savedDto.getId().toString()); + + return new ResponseEntity(headers, HttpStatus.CREATED); + } + + @PutMapping({"/{beerId}"}) + public ResponseEntity handleUpdate(@PathVariable("beerId") UUID beerId, @Valid @RequestBody BeerDtoV2 beerDto){ + + beerServiceV2.updateBeer(beerId, beerDto); + + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @DeleteMapping({"/{beerId}"}) + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteBeer(@PathVariable("beerId") UUID beerId){ + beerServiceV2.deleteById(beerId); + } + +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/mappers/BeerMapper.java b/src/main/java/guru/springframework/msscbrewery/web/mappers/BeerMapper.java new file mode 100644 index 00000000..516ce3d2 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/mappers/BeerMapper.java @@ -0,0 +1,16 @@ +package guru.springframework.msscbrewery.web.mappers; + +import guru.springframework.msscbrewery.domain.Beer; +import guru.springframework.msscbrewery.web.model.BeerDto; +import org.mapstruct.Mapper; + +/** + * Created by jt on 2019-05-25. + */ +@Mapper +public interface BeerMapper { + + BeerDto beerToBeerDto(Beer beer); + + Beer beerDtoToBeer(BeerDto dto); +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/mappers/CustomerMapper.java b/src/main/java/guru/springframework/msscbrewery/web/mappers/CustomerMapper.java new file mode 100644 index 00000000..4cef4ca2 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/mappers/CustomerMapper.java @@ -0,0 +1,16 @@ +package guru.springframework.msscbrewery.web.mappers; + +import guru.springframework.msscbrewery.domain.Customer; +import guru.springframework.msscbrewery.web.model.CustomerDto; +import org.mapstruct.Mapper; + +/** + * Created by jt on 2019-05-25. + */ +@Mapper +public interface CustomerMapper { + + Customer customerDtoToCustomer(CustomerDto dto); + + CustomerDto customerToCustomerDto(Customer customer); +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/model/BeerDto.java b/src/main/java/guru/springframework/msscbrewery/web/model/BeerDto.java index 34605262..83b32611 100644 --- a/src/main/java/guru/springframework/msscbrewery/web/model/BeerDto.java +++ b/src/main/java/guru/springframework/msscbrewery/web/model/BeerDto.java @@ -5,6 +5,9 @@ import lombok.Data; import lombok.NoArgsConstructor; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Null; +import javax.validation.constraints.Positive; import java.util.UUID; /** @@ -16,8 +19,15 @@ @Builder public class BeerDto { + @Null private UUID id; + + @NotBlank private String beerName; + + @NotBlank private String beerStyle; + + @Positive private Long upc; } diff --git a/src/main/java/guru/springframework/msscbrewery/web/model/CustomerDto.java b/src/main/java/guru/springframework/msscbrewery/web/model/CustomerDto.java new file mode 100644 index 00000000..cab5ab60 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/model/CustomerDto.java @@ -0,0 +1,26 @@ +package guru.springframework.msscbrewery.web.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.UUID; + +/** + * Created by jt on 2019-04-21. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CustomerDto { + + private UUID id; + + @NotBlank + @Size(min = 3, max = 100) + private String name; +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/model/v2/BeerDtoV2.java b/src/main/java/guru/springframework/msscbrewery/web/model/v2/BeerDtoV2.java new file mode 100644 index 00000000..2790c00f --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/model/v2/BeerDtoV2.java @@ -0,0 +1,22 @@ +package guru.springframework.msscbrewery.web.model.v2; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +/** + * Created by jt on 2019-04-23. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class BeerDtoV2 { + private UUID id; + private String beerName; + private BeerStyleEnum beerStyle; + private Long upc; +} diff --git a/src/main/java/guru/springframework/msscbrewery/web/model/v2/BeerStyleEnum.java b/src/main/java/guru/springframework/msscbrewery/web/model/v2/BeerStyleEnum.java new file mode 100644 index 00000000..c4d34d33 --- /dev/null +++ b/src/main/java/guru/springframework/msscbrewery/web/model/v2/BeerStyleEnum.java @@ -0,0 +1,9 @@ +package guru.springframework.msscbrewery.web.model.v2; + +/** + * Created by jt on 2019-04-23. + */ +public enum BeerStyleEnum { + + LAGER, PISLSNER, ALE, STOUT, GOSE, IPA +} diff --git a/src/test/java/guru/springframework/msscbrewery/web/controller/BeerControllerTest.java b/src/test/java/guru/springframework/msscbrewery/web/controller/BeerControllerTest.java new file mode 100644 index 00000000..5073cef7 --- /dev/null +++ b/src/test/java/guru/springframework/msscbrewery/web/controller/BeerControllerTest.java @@ -0,0 +1,93 @@ +package guru.springframework.msscbrewery.web.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import guru.springframework.msscbrewery.services.BeerService; +import guru.springframework.msscbrewery.web.model.BeerDto; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +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.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.UUID; + +import static org.hamcrest.core.Is.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@RunWith(SpringRunner.class) +@WebMvcTest(BeerController.class) +public class BeerControllerTest { + + @MockBean + BeerService beerService; + + @Autowired + MockMvc mockMvc; + + @Autowired + ObjectMapper objectMapper; + + BeerDto validBeer; + + @Before + public void setUp() { + validBeer = BeerDto.builder().id(UUID.randomUUID()) + .beerName("Beer1") + .beerStyle("PALE_ALE") + .upc(123456789012L) + .build(); + } + + @Test + public void getBeer() throws Exception { + given(beerService.getBeerById(any(UUID.class))).willReturn(validBeer); + + mockMvc.perform(get("/api/v1/beer/" + validBeer.getId().toString()).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(jsonPath("$.id", is(validBeer.getId().toString()))) + .andExpect(jsonPath("$.beerName", is("Beer1"))); + } + + @Test + public void handlePost() throws Exception { + //given + BeerDto beerDto = validBeer; + beerDto.setId(null); + BeerDto savedDto = BeerDto.builder().id(UUID.randomUUID()).beerName("New Beer").build(); + String beerDtoJson = objectMapper.writeValueAsString(beerDto); + + given(beerService.saveNewBeer(any())).willReturn(savedDto); + + mockMvc.perform(post("/api/v1/beer/") + .contentType(MediaType.APPLICATION_JSON) + .content(beerDtoJson)) + .andExpect(status().isCreated()); + + } + + @Test + public void handleUpdate() throws Exception { + //given + BeerDto beerDto = validBeer; + beerDto.setId(null); + String beerDtoJson = objectMapper.writeValueAsString(beerDto); + + //when + mockMvc.perform(put("/api/v1/beer/" + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(beerDtoJson)) + .andExpect(status().isNoContent()); + + then(beerService).should().updateBeer(any(), any()); + + } +} \ No newline at end of file