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