Merge pull request #8687 from rdevarakonda/BAEL-3324
BAEL-3324 | Using JSON Patch in Spring REST APIs
This commit is contained in:
		
						commit
						c012b831f1
					
				| @ -41,12 +41,18 @@ | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.github.java-json-tools</groupId> | ||||
|             <artifactId>json-patch</artifactId> | ||||
|             <version>${jsonpatch.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|     </dependencies> | ||||
| 
 | ||||
| 
 | ||||
|     <properties> | ||||
|         <xstream.version>1.4.9</xstream.version> | ||||
|         <jsonpatch.version>1.12</jsonpatch.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
|  | ||||
| @ -0,0 +1,12 @@ | ||||
| package com.baeldung; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class CustomerSpringBootRestApplication { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(CustomerSpringBootRestApplication.class, args); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,79 @@ | ||||
| package com.baeldung.model; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| public class Customer { | ||||
|     private String id; | ||||
|     private String telephone; | ||||
|     private List<String> favorites; | ||||
|     private Map<String, Boolean> communicationPreferences; | ||||
| 
 | ||||
|     public Customer() { | ||||
|     } | ||||
| 
 | ||||
|     public Customer(String id, String telephone, List<String> favorites, Map<String, Boolean> communicationPreferences) { | ||||
|         this(telephone, favorites, communicationPreferences); | ||||
|         this.id = id; | ||||
|     } | ||||
| 
 | ||||
|     public Customer(String telephone, List<String> favorites, Map<String, Boolean> communicationPreferences) { | ||||
|         this.telephone = telephone; | ||||
|         this.favorites = favorites; | ||||
|         this.communicationPreferences = communicationPreferences; | ||||
|     } | ||||
| 
 | ||||
|     public static Customer fromCustomer(Customer customer) { | ||||
|         return new Customer(customer.getId(), customer.getTelephone(), customer.getFavorites(), customer.getCommunicationPreferences()); | ||||
|     } | ||||
| 
 | ||||
|     public String getId() { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
|     public void setId(String id) { | ||||
|         this.id = id; | ||||
|     } | ||||
| 
 | ||||
|     public String getTelephone() { | ||||
|         return telephone; | ||||
|     } | ||||
| 
 | ||||
|     public void setTelephone(String telephone) { | ||||
|         this.telephone = telephone; | ||||
|     } | ||||
| 
 | ||||
|     public Map<String, Boolean> getCommunicationPreferences() { | ||||
|         return communicationPreferences; | ||||
|     } | ||||
| 
 | ||||
|     public void setCommunicationPreferences(Map<String, Boolean> communicationPreferences) { | ||||
|         this.communicationPreferences = communicationPreferences; | ||||
|     } | ||||
| 
 | ||||
|     public List<String> getFavorites() { | ||||
|         return favorites; | ||||
|     } | ||||
| 
 | ||||
|     public void setFavorites(List<String> favorites) { | ||||
|         this.favorites = favorites; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object o) { | ||||
|         if (this == o) { | ||||
|             return true; | ||||
|         } | ||||
|         if (!(o instanceof Customer)) { | ||||
|             return false; | ||||
|         } | ||||
|         Customer customer = (Customer) o; | ||||
|         return Objects.equals(id, customer.id); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         return Objects.hash(id); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| package com.baeldung.service; | ||||
| 
 | ||||
| public interface CustomerIdGenerator { | ||||
|     int generateNextId(); | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,14 @@ | ||||
| package com.baeldung.service; | ||||
| 
 | ||||
| import com.baeldung.model.Customer; | ||||
| 
 | ||||
| import java.util.Optional; | ||||
| 
 | ||||
| public interface CustomerService { | ||||
| 
 | ||||
|     Customer createCustomer(Customer customer); | ||||
| 
 | ||||
|     Optional<Customer> findCustomer(String id); | ||||
| 
 | ||||
|     void updateCustomer(Customer customer); | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package com.baeldung.service.impl; | ||||
| 
 | ||||
| import com.baeldung.service.CustomerIdGenerator; | ||||
| 
 | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import java.util.concurrent.atomic.AtomicInteger; | ||||
| 
 | ||||
| @Component | ||||
| public class CustomerIdGeneratorImpl implements CustomerIdGenerator { | ||||
|     private static final AtomicInteger SEQUENCE = new AtomicInteger(); | ||||
| 
 | ||||
|     @Override | ||||
|     public int generateNextId() { | ||||
|         return SEQUENCE.incrementAndGet(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,42 @@ | ||||
| package com.baeldung.service.impl; | ||||
| 
 | ||||
| import com.baeldung.model.Customer; | ||||
| import com.baeldung.service.CustomerIdGenerator; | ||||
| import com.baeldung.service.CustomerService; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
| 
 | ||||
| @Service | ||||
| public class CustomerServiceImpl implements CustomerService { | ||||
|     private CustomerIdGenerator customerIdGenerator; | ||||
|     private List<Customer> customers = new ArrayList<>(); | ||||
| 
 | ||||
|     @Autowired | ||||
|     public CustomerServiceImpl(CustomerIdGenerator customerIdGenerator) { | ||||
|         this.customerIdGenerator = customerIdGenerator; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Customer createCustomer(Customer customer) { | ||||
|         customer.setId(Integer.toString(customerIdGenerator.generateNextId())); | ||||
|         customers.add(customer); | ||||
|         return customer; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Optional<Customer> findCustomer(String id) { | ||||
|         return customers.stream() | ||||
|                         .filter(customer -> customer.getId().equals(id)) | ||||
|                         .findFirst(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void updateCustomer(Customer customer) { | ||||
|         customers.set(customers.indexOf(customer), customer); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,69 @@ | ||||
| package com.baeldung.web.controller; | ||||
| 
 | ||||
| import com.baeldung.model.Customer; | ||||
| import com.baeldung.service.CustomerService; | ||||
| import com.baeldung.web.exception.CustomerNotFoundException; | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.JsonNode; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import com.github.fge.jsonpatch.JsonPatch; | ||||
| import com.github.fge.jsonpatch.JsonPatchException; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.PatchMapping; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.bind.annotation.PostMapping; | ||||
| import org.springframework.web.bind.annotation.RequestBody; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||||
| 
 | ||||
| import java.net.URI; | ||||
| 
 | ||||
| import javax.validation.Valid; | ||||
| 
 | ||||
| @RestController | ||||
| @RequestMapping(value = "/customers") | ||||
| public class CustomerRestController { | ||||
|     private CustomerService customerService; | ||||
|     private ObjectMapper objectMapper = new ObjectMapper(); | ||||
| 
 | ||||
|     @Autowired | ||||
|     public CustomerRestController(CustomerService customerService) { | ||||
|         this.customerService = customerService; | ||||
|     } | ||||
| 
 | ||||
|     @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) | ||||
|     public ResponseEntity<Customer> createCustomer(@RequestBody Customer customer) { | ||||
|         Customer customerCreated = customerService.createCustomer(customer); | ||||
|         URI location = ServletUriComponentsBuilder.fromCurrentRequest() | ||||
|                                                   .path("/{id}") | ||||
|                                                   .buildAndExpand(customerCreated.getId()) | ||||
|                                                   .toUri(); | ||||
|         return ResponseEntity.created(location).build(); | ||||
|     } | ||||
| 
 | ||||
|     @PatchMapping(path = "/{id}", consumes = "application/json-patch+json") | ||||
|     public ResponseEntity<Customer> updateCustomer(@PathVariable String id, | ||||
|                                                    @RequestBody JsonPatch patch) { | ||||
|         try { | ||||
|             Customer customer = customerService.findCustomer(id).orElseThrow(CustomerNotFoundException::new); | ||||
|             Customer customerPatched = applyPatchToCustomer(patch, customer); | ||||
|             customerService.updateCustomer(customerPatched); | ||||
| 
 | ||||
|             return ResponseEntity.ok(customerPatched); | ||||
|         } catch (CustomerNotFoundException e) { | ||||
|             return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); | ||||
|         } catch (JsonPatchException | JsonProcessingException e) { | ||||
|             return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private Customer applyPatchToCustomer(JsonPatch patch, Customer targetCustomer) throws JsonPatchException, JsonProcessingException { | ||||
|         JsonNode patched = patch.apply(objectMapper.convertValue(targetCustomer, JsonNode.class)); | ||||
|         return objectMapper.treeToValue(patched, Customer.class); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.baeldung.web.exception; | ||||
| 
 | ||||
| public class CustomerNotFoundException extends RuntimeException { | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package com.baeldung.service.impl; | ||||
| 
 | ||||
| import com.baeldung.service.CustomerIdGenerator; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| public class CustomerIdGeneratorImplUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenIdGeneratedPreviously_whenGenerated_thenIdIsIncremented(){ | ||||
|         CustomerIdGenerator customerIdGenerator = new CustomerIdGeneratorImpl(); | ||||
|         int firstId = customerIdGenerator.generateNextId(); | ||||
|         assertThat(customerIdGenerator.generateNextId()).isEqualTo(++firstId); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,94 @@ | ||||
| package com.baeldung.service.impl; | ||||
| 
 | ||||
| 
 | ||||
| import com.baeldung.model.Customer; | ||||
| import com.baeldung.service.CustomerIdGenerator; | ||||
| import com.baeldung.service.CustomerService; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.mockito.Mock; | ||||
| import org.mockito.junit.MockitoJUnitRunner; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| 
 | ||||
| import static com.baeldung.model.Customer.fromCustomer; | ||||
| import static java.util.Arrays.asList; | ||||
| import static java.util.Optional.empty; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| import static org.mockito.BDDMockito.given; | ||||
| 
 | ||||
| @RunWith(MockitoJUnitRunner.class) | ||||
| public class CustomerServiceImplUnitTest { | ||||
| 
 | ||||
|     @Mock | ||||
|     private CustomerIdGenerator mockCustomerIdGenerator; | ||||
| 
 | ||||
|     private CustomerService customerService; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setup() { | ||||
|         customerService = new CustomerServiceImpl(mockCustomerIdGenerator); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCustomerIsCreated_thenNewCustomerDetailsAreCorrect() { | ||||
|         Map<String, Boolean> communicationPreferences = new HashMap<>(); | ||||
|         communicationPreferences.put("post", true); | ||||
|         communicationPreferences.put("email", true); | ||||
|         Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); | ||||
|         given(mockCustomerIdGenerator.generateNextId()).willReturn(1); | ||||
| 
 | ||||
|         Customer newCustomer = customerService.createCustomer(customer); | ||||
| 
 | ||||
|         assertThat(newCustomer.getId()).isEqualTo("1"); | ||||
|         assertThat(newCustomer.getTelephone()).isEqualTo("001-555-1234"); | ||||
|         assertThat(newCustomer.getFavorites()).containsExactly("Milk", "Eggs"); | ||||
|         assertThat(newCustomer.getCommunicationPreferences()).isEqualTo(communicationPreferences); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenNonExistentCustomer_whenCustomerIsLookedUp_thenCustomerCanNotBeFound() { | ||||
|         assertThat(customerService.findCustomer("CUST12345")).isEqualTo(empty()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCustomerIsCreated_thenCustomerCanBeFound() { | ||||
|         Map<String, Boolean> communicationPreferences = new HashMap<>(); | ||||
|         communicationPreferences.put("post", true); | ||||
|         communicationPreferences.put("email", true); | ||||
|         Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); | ||||
|         given(mockCustomerIdGenerator.generateNextId()).willReturn(7890); | ||||
| 
 | ||||
|         customerService.createCustomer(customer); | ||||
|         Customer lookedUpCustomer = customerService.findCustomer("7890").get(); | ||||
| 
 | ||||
|         assertThat(lookedUpCustomer.getId()).isEqualTo("7890"); | ||||
|         assertThat(lookedUpCustomer.getTelephone()).isEqualTo("001-555-1234"); | ||||
|         assertThat(lookedUpCustomer.getFavorites()).containsExactly("Milk", "Eggs"); | ||||
|         assertThat(lookedUpCustomer.getCommunicationPreferences()).isEqualTo(communicationPreferences); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCustomerUpdated_thenDetailsUpdatedCorrectly() { | ||||
|         given(mockCustomerIdGenerator.generateNextId()).willReturn(7890); | ||||
|         Map<String, Boolean> communicationPreferences = new HashMap<>(); | ||||
|         communicationPreferences.put("post", true); | ||||
|         communicationPreferences.put("email", true); | ||||
|         Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); | ||||
|         Customer newCustomer = customerService.createCustomer(customer); | ||||
| 
 | ||||
|         Customer customerWithUpdates = fromCustomer(newCustomer); | ||||
|         customerWithUpdates.setTelephone("001-555-6789"); | ||||
|         customerService.updateCustomer(customerWithUpdates); | ||||
|         Customer lookedUpCustomer = customerService.findCustomer("7890").get(); | ||||
| 
 | ||||
|         assertThat(lookedUpCustomer.getId()).isEqualTo("7890"); | ||||
|         assertThat(lookedUpCustomer.getTelephone()).isEqualTo("001-555-6789"); | ||||
|         assertThat(lookedUpCustomer.getFavorites()).containsExactly("Milk", "Eggs"); | ||||
|         assertThat(lookedUpCustomer.getCommunicationPreferences()).isEqualTo(communicationPreferences); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,72 @@ | ||||
| package com.baeldung.web.controller; | ||||
| 
 | ||||
| import com.baeldung.model.Customer; | ||||
| import com.baeldung.service.CustomerService; | ||||
| 
 | ||||
| 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.context.SpringBootTest; | ||||
| import org.springframework.boot.test.web.client.TestRestTemplate; | ||||
| import org.springframework.http.HttpEntity; | ||||
| import org.springframework.http.HttpHeaders; | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import static java.util.Collections.emptyList; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | ||||
| public class CustomerRestControllerIntegrationTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private CustomerService customerService; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private TestRestTemplate testRestTemplate; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setup() { | ||||
|         testRestTemplate.getRestTemplate().setRequestFactory(new HttpComponentsClientHttpRequestFactory()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenExistingCustomer_whenPatched_thenOnlyPatchedFieldsUpdated() { | ||||
|         Map<String, Boolean> communicationPreferences = new HashMap<>(); | ||||
|         communicationPreferences.put("post", true); | ||||
|         communicationPreferences.put("email", true); | ||||
|         Customer newCustomer = new Customer("001-555-1234", Arrays.asList("Milk", "Eggs"), | ||||
|                                           communicationPreferences); | ||||
|         Customer customer = customerService.createCustomer(newCustomer); | ||||
| 
 | ||||
| 
 | ||||
|         String patchBody = "[ { \"op\": \"replace\", \"path\": \"/telephone\", \"value\": \"001-555-5678\" },\n" | ||||
|                            + "{\"op\": \"add\", \"path\": \"/favorites/0\", \"value\": \"Bread\" }]"; | ||||
|         HttpHeaders headers = new HttpHeaders(); | ||||
|         headers.setContentType(MediaType.valueOf("application/json-patch+json")); | ||||
|         ResponseEntity<Customer> patchResponse | ||||
|                 = testRestTemplate.exchange("/customers/{id}", | ||||
|                                             HttpMethod.PATCH, | ||||
|                                             new HttpEntity<>(patchBody, headers), | ||||
|                                             Customer.class, | ||||
|                                             customer.getId()); | ||||
| 
 | ||||
|         Customer customerPatched = patchResponse.getBody(); | ||||
|         assertThat(patchResponse.getStatusCode()).isEqualTo(HttpStatus.OK); | ||||
|         assertThat(customerPatched.getId()).isEqualTo(customer.getId()); | ||||
|         assertThat(customerPatched.getTelephone()).isEqualTo("001-555-5678"); | ||||
|         assertThat(customerPatched.getCommunicationPreferences().get("post")).isTrue(); | ||||
|         assertThat(customerPatched.getCommunicationPreferences().get("email")).isTrue(); | ||||
|         assertThat(customerPatched.getFavorites()).containsExactly("Bread", "Milk", "Eggs"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,101 @@ | ||||
| package com.baeldung.web.controller; | ||||
| 
 | ||||
| import com.baeldung.model.Customer; | ||||
| import com.baeldung.service.CustomerService; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.boot.test.mock.mockito.MockBean; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| import org.springframework.test.web.servlet.MockMvc; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import static java.util.Arrays.asList; | ||||
| import static java.util.Optional.empty; | ||||
| import static java.util.Optional.of; | ||||
| import static org.hamcrest.CoreMatchers.is; | ||||
| import static org.mockito.BDDMockito.given; | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; | ||||
| import static org.springframework.http.MediaType.APPLICATION_JSON; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | ||||
| @AutoConfigureMockMvc | ||||
| public class CustomerRestControllerUnitTest { | ||||
| 
 | ||||
|     private static final String APPLICATION_JSON_PATCH_JSON = "application/json-patch+json"; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private MockMvc mvc; | ||||
| 
 | ||||
|     @MockBean | ||||
|     private CustomerService mockCustomerService; | ||||
| 
 | ||||
|     @Autowired | ||||
|     ApplicationContext context; | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCustomerCreated_then201ReturnedWithNewCustomerLocation() throws Exception { | ||||
|         Map<String, Boolean> communicationPreferences = new HashMap<>(); | ||||
|         communicationPreferences.put("post", true); | ||||
|         communicationPreferences.put("email", true); | ||||
|         Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); | ||||
| 
 | ||||
|         Customer persistedCustomer = Customer.fromCustomer(customer); | ||||
|         persistedCustomer.setId("1"); | ||||
| 
 | ||||
|         given(mockCustomerService.createCustomer(customer)).willReturn(persistedCustomer); | ||||
| 
 | ||||
|         String createCustomerRequestBody = "{" | ||||
|                                            + "\"telephone\": \"001-555-1234\",\n" | ||||
|                                            + "\"favorites\": [\"Milk\", \"Eggs\"],\n" | ||||
|                                            + "\"communicationPreferences\": {\"post\":true, \"email\":true}\n" | ||||
|                                            + "}"; | ||||
|         mvc.perform(post("/customers") | ||||
|                             .contentType(APPLICATION_JSON) | ||||
|                             .content(createCustomerRequestBody)) | ||||
|            .andExpect(status().isCreated()) | ||||
|            .andExpect(redirectedUrlPattern("http://*/customers/1")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenNonExistentCustomer_whenPatched_then404Returned() throws Exception { | ||||
|         given(mockCustomerService.findCustomer("1")).willReturn(empty()); | ||||
| 
 | ||||
|         String patchInstructions = "[{\"op\":\"replace\",\"path\": \"/telephone\",\"value\":\"001-555-5678\"}]"; | ||||
|         mvc.perform(patch("/customers/1") | ||||
|                             .contentType(APPLICATION_JSON_PATCH_JSON) | ||||
|                             .content(patchInstructions)) | ||||
|            .andExpect(status().isNotFound()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenExistingCustomer_whenPatched_thenReturnPatchedCustomer() throws Exception { | ||||
|         Map<String, Boolean> communicationPreferences = new HashMap<>(); | ||||
|         communicationPreferences.put("post", true); | ||||
|         communicationPreferences.put("email", true); | ||||
|         Customer customer = new Customer("1", "001-555-1234", asList("Milk", "Eggs"), communicationPreferences); | ||||
| 
 | ||||
|         given(mockCustomerService.findCustomer("1")).willReturn(of(customer)); | ||||
| 
 | ||||
|         String patchInstructions = "[{\"op\":\"replace\",\"path\": \"/telephone\",\"value\":\"001-555-5678\"}]"; | ||||
|         mvc.perform(patch("/customers/1") | ||||
|                             .contentType(APPLICATION_JSON_PATCH_JSON) | ||||
|                             .content(patchInstructions)) | ||||
|            .andExpect(status().isOk()) | ||||
|            .andExpect(jsonPath("$.id", is("1"))) | ||||
|            .andExpect(jsonPath("$.telephone", is("001-555-5678"))) | ||||
|            .andExpect(jsonPath("$.favorites", is(asList("Milk", "Eggs")))) | ||||
|            .andExpect(jsonPath("$.communicationPreferences", is(communicationPreferences))); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user