Skip to content

Commit

Permalink
Merge pull request #12 from alvinmarshall/5-endpoint-to-update-customer
Browse files Browse the repository at this point in the history
chore: update customer endpoint
  • Loading branch information
alvinmarshall authored Jul 28, 2024
2 parents 8a55340 + c847b89 commit e24b1f8
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/main/java/com/cheise_proj/auditing/Customer.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ static Customer of(CustomerDto.CreateCustomer customer) {
.build();
}

static Customer of(CustomerDto.UpdateCustomer customer) {
return Customer.builder()
.firstName(customer.firstName())
.lastName(customer.lastName())
.emailAddress(customer.emailAddress())
.build();
}

void setAddresses(Set<CustomerDto.CustomerAddress> customerAddresses, Customer customer) {
if (customerAddresses == null) return;
this.addresses = (this.addresses == null) ? new LinkedHashSet<>() : this.addresses;
this.addresses = (this.addresses == null) ? new LinkedHashSet<>() : new LinkedHashSet<>(this.addresses);
Set<Address> addressSet = customerAddresses.stream().map(customerAddress -> Address.of(customerAddress, customer)).collect(Collectors.toSet());
this.addresses.addAll(addressSet);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,10 @@ ResponseEntity<Object> getCustomer(@PathVariable("id") Long id) {
return ResponseEntity.ok(CustomerDto.toCustomer(customer));
}

@PutMapping("{id}")
ResponseEntity<Object> updateCustomer(@PathVariable("id") Long id, @RequestBody @Valid CustomerDto.UpdateCustomer input) {
Customer customer = customerService.updateCustomer(id, input);
return ResponseEntity.ok(CustomerDto.toCustomer(customer));
}

}
10 changes: 10 additions & 0 deletions src/main/java/com/cheise_proj/auditing/CustomerDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ record GetCustomer(
) implements CustomerDto {
}

@Builder
record UpdateCustomer(
@NotBlank @JsonProperty String firstName,
@NotBlank @JsonProperty String lastName,
@Email @JsonProperty("email") String emailAddress,
@JsonProperty Set<CustomerAddress> customerAddress
) implements CustomerDto {
}

static GetCustomer toGetCustomer(Customer customer) {
Set<CustomerAddress> customerAddresses = null;
if (customer.getAddresses() != null) {
Expand All @@ -55,6 +64,7 @@ static GetCustomer toGetCustomer(Customer customer) {
.customerAddress(customerAddresses)
.build();
}

static GetCustomer toCustomer(Customer customer) {
return GetCustomer.builder()
.firstName(customer.getFirstName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.Optional;

interface CustomerRepository extends JpaRepository<Customer, Long> {
@EntityGraph(attributePaths = "addresses")
@Override
Page<Customer> findAll(Pageable pageable);

@EntityGraph(attributePaths = "addresses")
@Query("select c from Customer c where c.id = :id")
Optional<Customer> findByIdWithAddress(Long id);
}
17 changes: 16 additions & 1 deletion src/main/java/com/cheise_proj/auditing/CustomerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,24 @@ Page<Customer> getCustomers(Pageable pageable) {
return customerRepository.findAll(pageable);
}

public Customer getCustomer(Long id) {
Customer getCustomer(Long id) {
return customerRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Customer with id %d not found".formatted(id)));
}

Customer getCustomerWithAddress(Long id) {
return customerRepository.findByIdWithAddress(id)
.orElseThrow(() -> new EntityNotFoundException("Customer with id %d not found".formatted(id)));
}

Customer updateCustomer(Long customerId, CustomerDto.UpdateCustomer updateCustomer) {
Customer customer = getCustomerWithAddress(customerId);
Customer newCustomer = Customer.of(updateCustomer);
customer.setFirstName(newCustomer.getFirstName());
customer.setLastName(newCustomer.getLastName());
customer.setEmailAddress(newCustomer.getEmailAddress());
customer.setAddresses(updateCustomer.customerAddress(), customer);
return customerRepository.save(customer);
}

}
55 changes: 55 additions & 0 deletions src/test/java/com/cheise_proj/auditing/CustomerControllerIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,59 @@ void getCustomer_by_id_returns_404() throws Exception {
).andExpectAll(MockMvcResultMatchers.status().isNotFound())
.andDo(result -> log.info("result: {}", result.getResponse().getContentAsString()));
}

@Test
void updateCustomer_returns_200() throws Exception {
String customerLocation = (String) mockMvc.perform(MockMvcRequestBuilders.post("/customers")
.contentType(MediaType.APPLICATION_JSON)
.content(CustomerFixture.createCustomerWithAddress(objectMapper))

).andExpectAll(MockMvcResultMatchers.status().isCreated())
.andDo(result -> log.info("result: {}", result.getResponse().getHeaderValue("location")))
.andReturn().getResponse().getHeaderValue("location");

assert customerLocation != null;
mockMvc.perform(MockMvcRequestBuilders.put(customerLocation)
.contentType(MediaType.APPLICATION_JSON)
.content(CustomerFixture.updateCustomer(objectMapper))

).andExpectAll(MockMvcResultMatchers.status().isOk())
.andDo(result -> log.info("result: {}", result.getResponse().getContentAsString()));
}

@Test
void updateCustomer_With_Address_returns_200() throws Exception {
String customerLocation = (String) mockMvc.perform(MockMvcRequestBuilders.post("/customers")
.contentType(MediaType.APPLICATION_JSON)
.content(CustomerFixture.createCustomerWithAddress(objectMapper))

).andExpectAll(MockMvcResultMatchers.status().isCreated())
.andDo(result -> log.info("result: {}", result.getResponse().getHeaderValue("location")))
.andReturn().getResponse().getHeaderValue("location");

assert customerLocation != null;
mockMvc.perform(MockMvcRequestBuilders.put(customerLocation)
.contentType(MediaType.APPLICATION_JSON)
.content(CustomerFixture.updateCustomerWithAddress(objectMapper))

).andExpectAll(MockMvcResultMatchers.status().isOk())
.andDo(result -> log.info("result: {}", result.getResponse().getContentAsString()));
}

@Test
void updateCustomer_returns_404() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/customers")
.contentType(MediaType.APPLICATION_JSON)
.content(CustomerFixture.createCustomerWithAddress(objectMapper))

).andExpectAll(MockMvcResultMatchers.status().isCreated())
.andDo(result -> log.info("result: {}", result.getResponse().getHeaderValue("location")));

mockMvc.perform(MockMvcRequestBuilders.put("/customers/10")
.contentType(MediaType.APPLICATION_JSON)
.content(CustomerFixture.updateCustomer(objectMapper))

).andExpectAll(MockMvcResultMatchers.status().isNotFound())
.andDo(result -> log.info("result: {}", result.getResponse().getContentAsString()));
}
}
25 changes: 25 additions & 0 deletions src/test/java/com/cheise_proj/auditing/CustomerFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,29 @@ static String createCustomerWithAddress(ObjectMapper mapper) throws JsonProcessi
.build();
return mapper.writeValueAsString(customerDto);
}

static String updateCustomer(ObjectMapper mapper) throws JsonProcessingException {
CustomerDto.CreateCustomer customerDto = CustomerDto.CreateCustomer.builder()
.firstName("Theresia")
.lastName("Macejkovic")
.emailAddress("thres.mac@gmail.com")
.build();
return mapper.writeValueAsString(customerDto);
}

static String updateCustomerWithAddress(ObjectMapper mapper) throws JsonProcessingException {
CustomerDto.CreateCustomer customerDto = CustomerDto.CreateCustomer.builder()
.firstName("Vito")
.lastName("Kovacek")
.emailAddress("vito.kov.hahn@gmail.com")
.customerAddress(Set.of(CustomerDto.CustomerAddress.builder()
.city("Phillipshire")
.country("USA")
.streetAddress("68578 Champlin Mill")
.stateCode("NJ")
.zipCode("28711")
.build()))
.build();
return mapper.writeValueAsString(customerDto);
}
}
79 changes: 79 additions & 0 deletions src/test/java/com/cheise_proj/auditing/CustomerServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,83 @@ void getCustomer_throw_if_customer_not_found() {
);
assertEquals("Customer with id 1 not found", exception.getMessage());
}

@Test
void updateCustomer() {
CustomerDto.UpdateCustomer updateCustomerDto = CustomerDto.UpdateCustomer.builder()
.firstName("Update Claribel")
.lastName("Update Zieme")
.emailAddress("Update claribel.zieme@gmail.com")
.build();

Mockito.when(customerRepository.findByIdWithAddress(ArgumentMatchers.anyLong()))
.thenReturn(Optional.of(Customer.builder().id(1L)
.firstName("Claribel")
.lastName("Zieme")
.emailAddress("claribel.zieme@gmail.com")
.build()));

sut.updateCustomer(1L, updateCustomerDto);
Mockito.verify(customerRepository, Mockito.atMostOnce()).save(customerArgumentCaptor.capture());
Customer customer = customerArgumentCaptor.getValue();
assertNotNull(customer);
assertEquals("Update Claribel", customer.getFirstName());
assertEquals("Update Zieme", customer.getLastName());
assertEquals("Update claribel.zieme@gmail.com", customer.getEmailAddress());
}

@Test
void updateCustomerWithAddress() {
CustomerDto.UpdateCustomer updateCustomerDto = CustomerDto.UpdateCustomer.builder()
.firstName("Update Claribel")
.lastName("Update Zieme")
.emailAddress("Update claribel.zieme@gmail.com")
.customerAddress(Set.of(CustomerDto.CustomerAddress.builder()
.city("Emmerichmouth")
.country("USA")
.streetAddress("Suite 290 6898 King Village")
.stateCode("PA")
.zipCode("29665")
.build()))
.build();

Mockito.when(customerRepository.findByIdWithAddress(ArgumentMatchers.anyLong()))
.thenReturn(Optional.of(Customer.builder().id(1L)
.firstName("Claribel")
.lastName("Zieme")
.emailAddress("claribel.zieme@gmail.com")
.addresses(Set.of(Address.builder()
.city("Risaberg")
.country("USA")
.streetAddress("942 Walker Street")
.stateCode("WV")
.zipCode("88742")
.build()))
.build()));

sut.updateCustomer(1L, updateCustomerDto);
Mockito.verify(customerRepository, Mockito.atMostOnce()).save(customerArgumentCaptor.capture());
Customer customer = customerArgumentCaptor.getValue();
assertNotNull(customer);
assertEquals("Update Claribel", customer.getFirstName());
assertEquals("Update Zieme", customer.getLastName());
assertEquals("Update claribel.zieme@gmail.com", customer.getEmailAddress());
assertEquals(2, customer.getAddresses().size());
}

@Test
void updateCustomer_throw_if_customer_not_found() {
CustomerDto.UpdateCustomer updateCustomerDto = CustomerDto.UpdateCustomer.builder()
.firstName("Update Claribel")
.lastName("Update Zieme")
.emailAddress("Update claribel.zieme@gmail.com")
.build();

EntityNotFoundException exception = Assertions.assertThrows(
EntityNotFoundException.class,
() -> sut.updateCustomer(1L, updateCustomerDto)
);
assertEquals("Customer with id 1 not found", exception.getMessage());
}

}

0 comments on commit e24b1f8

Please sign in to comment.