Commit 65f2dd55 authored by Ashok Kumar K's avatar Ashok Kumar K

Added few test cases for CustomerController

parent 73d1aaa6
...@@ -4,7 +4,6 @@ import org.springframework.beans.factory.annotation.Value; ...@@ -4,7 +4,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.config.EnableMongoAuditing; import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import static com.nisum.ecomcustomer.config.mongodb.CustomMongoConverters.*; import static com.nisum.ecomcustomer.config.mongodb.CustomMongoConverters.*;
...@@ -23,21 +22,6 @@ public class MongoConfig extends AbstractMongoClientConfiguration { ...@@ -23,21 +22,6 @@ public class MongoConfig extends AbstractMongoClientConfiguration {
return databaseName; return databaseName;
} }
//TODO - know about the good practices.
// @Bean
// @Override
// public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory databaseFactory, MongoCustomConversions customConversions, MongoMappingContext mappingContext) {
// MappingMongoConverter mmc = super.mappingMongoConverter(databaseFactory, customConversions, mappingContext);
// mmc.setTypeMapper(getTypeMapper());
// return mmc;
// }
//
// @Bean
// public MongoTypeMapper getTypeMapper() {
// return new CustomMongoTypeMapper();
// }
@Override @Override
protected void configureConverters(MongoConverterConfigurationAdapter adapter) { protected void configureConverters(MongoConverterConfigurationAdapter adapter) {
adapter.registerConverter(new CustomerTypeToIntegerConverter()); adapter.registerConverter(new CustomerTypeToIntegerConverter());
...@@ -47,13 +31,6 @@ public class MongoConfig extends AbstractMongoClientConfiguration { ...@@ -47,13 +31,6 @@ public class MongoConfig extends AbstractMongoClientConfiguration {
} }
} }
class CustomMongoTypeMapper extends DefaultMongoTypeMapper {
CustomMongoTypeMapper() {
super(null);
}
}
...@@ -23,6 +23,7 @@ public class CustomerDbOpsEventListener extends AbstractMongoEventListener<Custo ...@@ -23,6 +23,7 @@ public class CustomerDbOpsEventListener extends AbstractMongoEventListener<Custo
if (source.getId() == null) { if (source.getId() == null) {
DbSequence dbSequence = dbSequenceRepository.findBySequenceName(Customer.SEQUENCE_NAME).orElse(new DbSequence(Customer.SEQUENCE_NAME)); DbSequence dbSequence = dbSequenceRepository.findBySequenceName(Customer.SEQUENCE_NAME).orElse(new DbSequence(Customer.SEQUENCE_NAME));
source.setId(dbSequence.incrementLastId()); source.setId(dbSequence.incrementLastId());
source.setEmail(source.getEmail().toLowerCase());
source.setCreatedDate(LocalDate.now()); source.setCreatedDate(LocalDate.now());
dbSequenceRepository.save(dbSequence); dbSequenceRepository.save(dbSequence);
} }
......
...@@ -46,9 +46,7 @@ public class CustomerController { ...@@ -46,9 +46,7 @@ public class CustomerController {
return ResponseEntity.ok(customerService.getCustomerById(id)); return ResponseEntity.ok(customerService.getCustomerById(id));
} }
//TODO - make email field unique @GetMapping("/email/{email}")
// @GetMapping("/email/{email}")
public ResponseEntity<Customer> getCustomerByEmail(@PathVariable @Email String email) { public ResponseEntity<Customer> getCustomerByEmail(@PathVariable @Email String email) {
return ResponseEntity.ok(customerService.getCustomerByEmail(email)); return ResponseEntity.ok(customerService.getCustomerByEmail(email));
} }
......
...@@ -26,6 +26,11 @@ public class CustomerServiceExceptionHandler { ...@@ -26,6 +26,11 @@ public class CustomerServiceExceptionHandler {
return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.NOT_FOUND, httpServletRequest); return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.NOT_FOUND, httpServletRequest);
} }
@ExceptionHandler(EmailAlreadyRegisteredException.class)
public ResponseEntity<ErrorResponse> handleEmailAlreadyRegisteredException(EmailAlreadyRegisteredException ex, HttpServletRequest httpServletRequest) {
return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.CONFLICT, httpServletRequest);
}
@ExceptionHandler(MethodArgumentNotValidException.class) @ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest httpServletRequest) { public ResponseEntity<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest httpServletRequest) {
ErrorResponse errorResponse = buildErrorResponse("Invalid payload or params", HttpStatus.BAD_REQUEST, httpServletRequest); ErrorResponse errorResponse = buildErrorResponse("Invalid payload or params", HttpStatus.BAD_REQUEST, httpServletRequest);
......
package com.nisum.ecomcustomer.exceptions;
public class EmailAlreadyRegisteredException extends RuntimeException {
public EmailAlreadyRegisteredException() {
super("email already registered");
}
public EmailAlreadyRegisteredException(String message) {
super(message);
}
public EmailAlreadyRegisteredException(String message, Throwable cause) {
super(message, cause);
}
}
...@@ -5,14 +5,19 @@ import org.springframework.data.mongodb.repository.MongoRepository; ...@@ -5,14 +5,19 @@ import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query; import org.springframework.data.mongodb.repository.Query;
import java.util.List; import java.util.List;
import java.util.Optional;
public interface CustomerRepository extends MongoRepository<Customer, Long> { public interface CustomerRepository extends MongoRepository<Customer, Long> {
Customer findByEmailIgnoreCase(String email); Optional<Customer> findByEmailIgnoreCase(String email);
@Query(value = "{'firstName': {$regex : ?0, $options: 'i'}}") @Query(value = "{'firstName': {$regex : ?0, $options: 'i'}}")
List<Customer> findByFirstName(String fName); List<Customer> findByFirstName(String fName);
List<Customer> findByLastNameIgnoreCase(String lName); List<Customer> findByLastNameIgnoreCase(String lName);
boolean existsByEmail(String email);
boolean existsByEmailIn(List<String> emails);
} }
package com.nisum.ecomcustomer.service.impl; package com.nisum.ecomcustomer.service.impl;
import com.nisum.ecomcustomer.exceptions.CustomerNotFoundException; import com.nisum.ecomcustomer.exceptions.CustomerNotFoundException;
import com.nisum.ecomcustomer.exceptions.EmailAlreadyRegisteredException;
import com.nisum.ecomcustomer.model.Customer; import com.nisum.ecomcustomer.model.Customer;
import com.nisum.ecomcustomer.repository.CustomerRepository; import com.nisum.ecomcustomer.repository.CustomerRepository;
import com.nisum.ecomcustomer.service.CustomerService; import com.nisum.ecomcustomer.service.CustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service @Service
public class CustomerServiceImpl implements CustomerService { public class CustomerServiceImpl implements CustomerService {
...@@ -22,11 +26,17 @@ public class CustomerServiceImpl implements CustomerService { ...@@ -22,11 +26,17 @@ public class CustomerServiceImpl implements CustomerService {
@Override @Override
public Customer register(Customer customer) { public Customer register(Customer customer) {
customer.setId(null); // auto-generated customer.setId(null); // auto-generated
if (customerRepository.existsByEmail(customer.getEmail())) {
throw new EmailAlreadyRegisteredException();
}
return customerRepository.save(customer); return customerRepository.save(customer);
} }
@Override @Override
public List<Customer> registerAll(List<Customer> customers) { public List<Customer> registerAll(List<Customer> customers) {
List<String> emails = customers.stream().map(Customer::getEmail).collect(Collectors.toList());
if (customerRepository.existsByEmailIn(emails))
throw new EmailAlreadyRegisteredException("one of the emails is already registered");
return customerRepository.saveAll(customers); return customerRepository.saveAll(customers);
} }
...@@ -54,7 +64,7 @@ public class CustomerServiceImpl implements CustomerService { ...@@ -54,7 +64,7 @@ public class CustomerServiceImpl implements CustomerService {
@Override @Override
public Customer getCustomerByEmail(String email) { public Customer getCustomerByEmail(String email) {
return customerRepository.findByEmailIgnoreCase(email); return customerRepository.findByEmailIgnoreCase(email).orElseThrow(CustomerNotFoundException::new);
} }
@Override @Override
......
server:
port: 8181
spring:
data:
mongodb:
host: localhost
port: 27017
database: ecom-test
logging:
level:
web: debug
\ No newline at end of file
package com.nisum.ecomcustomer.controller;
import com.nisum.ecomcustomer.model.Customer;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
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.boot.web.server.LocalServerPort;
import org.springframework.test.context.ActiveProfiles;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.TestInstance.Lifecycle;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@TestInstance(Lifecycle.PER_CLASS)
@ActiveProfiles("test")
public class CustomerControllerIntegrationTest {
@LocalServerPort
private int port;
private String url;
@Autowired
TestRestTemplate testRestTemplate;
@BeforeAll
public void setUp() {
url = "http://localhost:" + port + "/customer";
}
@Test
public void testGetById() {
Customer responseObject = testRestTemplate.getForObject(url + "/id/2", Customer.class);
assertEquals("Ashokk", responseObject.getFirstName());
}
}
package com.nisum.ecomcustomer.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nisum.ecomcustomer.exceptions.CustomerNotFoundException;
import com.nisum.ecomcustomer.exceptions.CustomerServiceExceptionHandler;
import com.nisum.ecomcustomer.exceptions.EmailAlreadyRegisteredException;
import com.nisum.ecomcustomer.model.Address;
import com.nisum.ecomcustomer.model.AddressType;
import com.nisum.ecomcustomer.model.Customer;
import com.nisum.ecomcustomer.model.CustomerType;
import com.nisum.ecomcustomer.service.CustomerService;
import org.junit.jupiter.api.Test;
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.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(value = {CustomerController.class, CustomerServiceExceptionHandler.class})
class CustomerControllerTest {
@MockBean
CustomerService customerService;
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@Test
void registerCustomer_returnsCustomer_201() throws Exception {
Customer customerRequestObj = getCustomerRequestObject();
Customer customerResponseObj = getCustomerResponseObject();
when(customerService.register(customerRequestObj)).thenReturn(customerResponseObj);
MvcResult result = mockMvc.perform(post("/customer/register")
.content(objectMapper.writeValueAsString(customerRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andReturn();
Customer response = getObjectFromResponse(result, Customer.class);
assertEquals("Ashok", response.getFirstName());
assertEquals(3, response.getAddresses().size());
assertNotNull(response.getId());
assertEquals(LocalDate.now(), response.getCreatedDate());
}
@Test
void registerCustomer_throwsEmailAlreadyRegisteredException_409() throws Exception {
Customer customerRequestObject = getCustomerRequestObject();
when(customerService.register(customerRequestObject)).thenThrow(new EmailAlreadyRegisteredException());
mockMvc.perform(post("/customer/register")
.content(objectMapper.writeValueAsString(customerRequestObject))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isConflict())
.andReturn();
}
@Test
void registerCustomers_returnsCustomers_201() throws Exception {
List<Customer> customersRequestObj = getCustomerRequestObjectsList();
List<Customer> customersResponseObj = getCustomerResponseObjectsList();
when(customerService.registerAll(customersRequestObj)).thenReturn(customersResponseObj);
mockMvc.perform(post("/customer/registerAll")
.content(objectMapper.writeValueAsString(customersRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", hasSize(2)))
.andReturn();
}
@Test
void registerCustomers_throwsEmailAlreadyRegisteredException_409() throws Exception {
List<Customer> customersRequestObj = getCustomerRequestObjectsList();
when(customerService.registerAll(customersRequestObj)).thenThrow(new EmailAlreadyRegisteredException());
MvcResult result = mockMvc.perform(post("/customer/registerAll")
.content(objectMapper.writeValueAsString(customersRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isConflict())
.andReturn();
}
@Test
void updateCustomer_returnsCustomer_201() throws Exception {
Customer customerRequestObj = getCustomerRequestObject();
customerRequestObj.setId(1L);
customerRequestObj.setEmail(customerRequestObj.getEmail().toLowerCase());
customerRequestObj.setCreatedDate(LocalDate.now());
customerRequestObj.setModifiedDate(LocalDateTime.now());
Customer customerResponseObj = getCustomerResponseObject();
when(customerService.update(customerRequestObj)).thenReturn(customerResponseObj);
MvcResult result = mockMvc.perform(put("/customer/update")
.content(objectMapper.writeValueAsString(customerRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andReturn();
Customer response = getObjectFromResponse(result, Customer.class);
assertEquals("Ashok", response.getFirstName());
assertEquals(3, response.getAddresses().size());
assertNotNull(response.getId());
assertEquals(LocalDate.now(), response.getCreatedDate());
assertNotEquals(customerRequestObj.getModifiedDate(), response.getModifiedDate());
}
@Test
void updateCustomer_throwsCustomerNotFoundException_404() throws Exception {
Customer customerRequestObj = getCustomerRequestObject();
customerRequestObj.setId(null);
when(customerService.update(customerRequestObj)).thenThrow(new CustomerNotFoundException());
mockMvc.perform(put("/customer/update")
.content(objectMapper.writeValueAsString(customerRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound())
.andReturn();
}
@Test
void getAllCustomers_returnsCustomers_200() throws Exception {
when(customerService.getAllCustomers()).thenReturn(getCustomerResponseObjectsList());
mockMvc.perform(get("/customer/"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andReturn();
}
@Test
void getCustomerById_returnsCustomer_200() throws Exception {
when(customerService.getCustomerById(1L)).thenReturn(getCustomerResponseObject());
mockMvc.perform(get("/customer/id/" + 1))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is(1)))
.andReturn();
}
@Test
void getCustomerById_throwsCustomerNotFoundException_404() throws Exception {
when(customerService.getCustomerById(1L)).thenThrow(new CustomerNotFoundException());
mockMvc.perform(get("/customer/id/" + 1))
.andExpect(status().isNotFound())
.andReturn();
}
@Test
void getCustomerByEmail_returnsCustomer_200() throws Exception {
String email = "ashokk@nisum.com";
when(customerService.getCustomerByEmail(email)).thenReturn(getCustomerResponseObjectsList().stream().filter(customer -> customer.getEmail().equals(email)).findFirst().get());
mockMvc.perform(get("/customer/email/" + email))
.andExpect(status().isOk())
.andExpect(jsonPath("$.email", is(email)))
.andReturn();
}
@Test
void getCustomerByEmail_throwsCustomerNotFoundException_404() throws Exception {
String email = "ashokk@nisum.com";
when(customerService.getCustomerByEmail(email)).thenThrow(new CustomerNotFoundException());
mockMvc.perform(get("/customer/email/" + email))
.andExpect(status().isNotFound())
.andReturn();
}
@Test
void getCustomersByFirstName() {
}
@Test
void getCustomersByLastName() {
}
@Test
void deleteById_returnsNoContent_204() throws Exception {
doNothing().when(customerService).deleteById(1L);
mockMvc.perform(delete("/customer/id/" + 1))
.andExpect(status().isNoContent());
}
@Test
void deleteById_throwsCustomerNotFoundException_404() throws Exception {
doThrow(new CustomerNotFoundException()).when(customerService).deleteById(1L);
mockMvc.perform(delete("/customer/id/" + 1))
.andExpect(status().isNotFound());
}
private Customer getCustomerRequestObject() {
Customer customer = new Customer();
customer.setId(null);
customer.setFirstName("Ashok");
customer.setLastName("Kumar");
customer.setEmail("ashokk@nisum.com");
customer.setDayPhone("8989898989");
customer.setCustomerType(CustomerType.LOYAL);
Address billingAddress = new Address();
billingAddress.setAddressLine1("Srinagar colony");
billingAddress.setAddressLine2("Ameerpet");
billingAddress.setAddressType(AddressType.BILLING);
billingAddress.setDefault(true);
billingAddress.setZipCode("500000");
billingAddress.setCity("Hyderabad");
billingAddress.setState("TS");
billingAddress.setCountry("IND");
Address shippingAddress1 = new Address();
shippingAddress1.setAddressLine1("Jawaharnagar colony");
shippingAddress1.setAddressLine2("Ameerpet");
shippingAddress1.setAddressType(AddressType.SHIPPING);
shippingAddress1.setDefault(true);
shippingAddress1.setZipCode("500001");
shippingAddress1.setCity("Hyderabad");
shippingAddress1.setState("TS");
shippingAddress1.setCountry("IND");
Address shippingAddress2 = new Address();
shippingAddress2.setAddressLine1("Krishnanagar colony");
shippingAddress2.setAddressLine2("Ameerpet");
shippingAddress2.setAddressType(AddressType.SHIPPING);
shippingAddress2.setDefault(false);
shippingAddress2.setZipCode("500002");
shippingAddress2.setCity("Hyderabad");
shippingAddress2.setState("TS");
shippingAddress2.setCountry("IND");
List<Address> addresses = Arrays.asList(billingAddress, shippingAddress1, shippingAddress2);
customer.setAddresses(addresses);
return customer;
}
private Customer getCustomerResponseObject() {
Customer customer = getCustomerRequestObject();
customer.setId(1L);
customer.setEmail(customer.getEmail().toLowerCase());
customer.setCreatedDate(LocalDate.now());
customer.setModifiedDate(LocalDateTime.now().plusSeconds(2));
return customer;
}
private List<Customer> getCustomerRequestObjectsList() {
Customer customer1 = getCustomerRequestObject();
Customer customer2 = getCustomerRequestObject();
customer2.setEmail("anandk@nisum.com");
return Arrays.asList(customer1, customer2);
}
private List<Customer> getCustomerResponseObjectsList() {
List<Customer> customers = getCustomerRequestObjectsList();
Long id = 1L;
for (Customer customer : customers) {
customer.setId(id++);
customer.setEmail(customer.getEmail().toLowerCase());
customer.setCreatedDate(LocalDate.now());
customer.setModifiedDate(LocalDateTime.now());
}
return customers;
}
private <T> T getObjectFromResponse(MvcResult result, Class<T> targetClass) throws Exception {
String responseAsString = result.getResponse().getContentAsString();
return objectMapper.readValue(responseAsString, targetClass);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment