Commit 67bff2ac authored by Ashok Kumar K's avatar Ashok Kumar K

Added 3 date related apis and few component and integration test cases

parent 65f2dd55
package com.nisum.ecomcustomer.controller;
import com.nisum.ecomcustomer.model.Customer;
import com.nisum.ecomcustomer.model.CustomerType;
import com.nisum.ecomcustomer.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
......@@ -11,6 +13,7 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.util.List;
@RestController
......@@ -61,6 +64,23 @@ public class CustomerController {
return ResponseEntity.ok(customerService.getCustomerByLastName(lName));
}
@GetMapping("/type/{type}")
public ResponseEntity<List<Customer>> getCustomersByCustomerType(@PathVariable("type") int type) {
CustomerType customerType = CustomerType.of(type);
return ResponseEntity.ok(customerService.getCustomersByCustomerType(customerType));
}
@GetMapping("/registered/on")
public ResponseEntity<List<Customer>> getRegisteredCustomersOnDate(@RequestParam("onDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate onDate) {
return ResponseEntity.ok(customerService.getRegisteredCustomersOnDate(onDate));
}
@GetMapping("/registered/between")
public ResponseEntity<List<Customer>> getRegisteredCustomersBetweenDates(@RequestParam("fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate,
@RequestParam("toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) {
return ResponseEntity.ok(customerService.getRegisteredCustomersBetweenDates(fromDate, toDate));
}
@DeleteMapping("/id/{id}")
public ResponseEntity<Void> deleteById(@PathVariable Long id) {
customerService.deleteById(id);
......
......@@ -31,6 +31,11 @@ public class CustomerServiceExceptionHandler {
return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.CONFLICT, httpServletRequest);
}
@ExceptionHandler(InvalidDateRangeException.class)
public ResponseEntity<ErrorResponse> handleInvalidDateRangeException(InvalidDateRangeException ex, HttpServletRequest httpServletRequest) {
return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.BAD_REQUEST, httpServletRequest);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest httpServletRequest) {
ErrorResponse errorResponse = buildErrorResponse("Invalid payload or params", HttpStatus.BAD_REQUEST, httpServletRequest);
......@@ -52,6 +57,11 @@ public class CustomerServiceExceptionHandler {
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex, HttpServletRequest httpServletRequest) {
return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.BAD_REQUEST, httpServletRequest);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception ex, HttpServletRequest httpServletRequest) {
return buildErrorResponseEntity(ex.getLocalizedMessage(), HttpStatus.INTERNAL_SERVER_ERROR, httpServletRequest);
......
package com.nisum.ecomcustomer.exceptions;
public class InvalidDateRangeException extends RuntimeException {
public InvalidDateRangeException() {
super("invalid date range");
}
public InvalidDateRangeException(String message) {
super(message);
}
public InvalidDateRangeException(String message, Throwable cause) {
super(message, cause);
}
}
......@@ -27,7 +27,7 @@ public enum AddressType {
case "bill":
return AddressType.BILLING;
default:
throw new IllegalArgumentException(value +" can't be converted to type AddressType");
throw new IllegalArgumentException(value +" isn't mapped to any AddressType");
}
}
}
......@@ -27,7 +27,7 @@ public enum CustomerType {
case 1:
return CustomerType.LOYAL;
default:
throw new IllegalArgumentException(value + " can't be converted to type CustomerType");
throw new IllegalArgumentException(value + " isn't mapped to any CustomerType");
}
}
}
package com.nisum.ecomcustomer.repository;
import com.nisum.ecomcustomer.model.Customer;
import com.nisum.ecomcustomer.model.CustomerType;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
......@@ -16,8 +18,12 @@ public interface CustomerRepository extends MongoRepository<Customer, Long> {
List<Customer> findByLastNameIgnoreCase(String lName);
List<Customer> findByCustomerType(CustomerType customerType);
boolean existsByEmail(String email);
boolean existsByEmailIn(List<String> emails);
List<Customer> findByCreatedDate(LocalDate date);
}
package com.nisum.ecomcustomer.service;
import com.nisum.ecomcustomer.model.Customer;
import com.nisum.ecomcustomer.model.CustomerType;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
@Service
......@@ -24,4 +26,10 @@ public interface CustomerService {
List<Customer> getCustomerByFirstName(String fName);
List<Customer> getCustomerByLastName(String lName);
List<Customer> getRegisteredCustomersOnDate(LocalDate onDate);
List<Customer> getRegisteredCustomersBetweenDates(LocalDate fromDate, LocalDate toDate);
List<Customer> getCustomersByCustomerType(CustomerType customerType);
}
......@@ -2,17 +2,23 @@ package com.nisum.ecomcustomer.service.impl;
import com.nisum.ecomcustomer.exceptions.CustomerNotFoundException;
import com.nisum.ecomcustomer.exceptions.EmailAlreadyRegisteredException;
import com.nisum.ecomcustomer.exceptions.InvalidDateRangeException;
import com.nisum.ecomcustomer.model.Customer;
import com.nisum.ecomcustomer.model.CustomerType;
import com.nisum.ecomcustomer.repository.CustomerRepository;
import com.nisum.ecomcustomer.service.CustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@Slf4j
@Service
public class CustomerServiceImpl implements CustomerService {
......@@ -77,6 +83,23 @@ public class CustomerServiceImpl implements CustomerService {
return customerRepository.findByLastNameIgnoreCase(lName);
}
@Override
public List<Customer> getCustomersByCustomerType(CustomerType customerType) {
return customerRepository.findByCustomerType(customerType);
}
@Override
public List<Customer> getRegisteredCustomersOnDate(LocalDate onDate) {
return customerRepository.findByCreatedDate(onDate);
}
@Override
public List<Customer> getRegisteredCustomersBetweenDates(LocalDate fromDate, LocalDate toDate) {
if (fromDate.isAfter(toDate)) throw new InvalidDateRangeException("invalid date range: fromDate can't be greater than toDate");
Query query = new Query(where("createdDate").gte(fromDate).lte(toDate));
return mongoTemplate.find(query, Customer.class);
}
@Override
public void deleteById(Long id) {
if (customerRepository.existsById(id)) customerRepository.deleteById(id);
......
package com.nisum.ecomcustomer.controller;
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.repository.CustomerRepository;
import com.nisum.ecomcustomer.repository.DbSequenceRepository;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
......@@ -8,9 +13,19 @@ 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.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.TestInstance.Lifecycle;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
......@@ -27,15 +42,202 @@ public class CustomerControllerIntegrationTest {
@Autowired
TestRestTemplate testRestTemplate;
@Autowired
CustomerRepository customerRepository;
@Autowired
DbSequenceRepository sequenceRepository;
@BeforeAll
public void setUp() {
initializeDb();
url = "http://localhost:" + port + "/customer";
}
@Test
public void testGetById() {
Customer responseObject = testRestTemplate.getForObject(url + "/id/2", Customer.class);
assertEquals("Ashokk", responseObject.getFirstName());
void registerCustomer_returnsCustomer_201() {
Customer requestObject = getCustomerRequestObject();
requestObject.setEmail("ashokk101@nisum.com");
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.postForEntity(url + "/register", requestObject, Customer.class);
Customer customer = customerResponseEntity.getBody();
assertEquals(HttpStatus.CREATED, customerResponseEntity.getStatusCode());
assertNotNull(customer);
assertNotNull(customer.getId());
assertEquals(LocalDate.now(), customer.getCreatedDate());
}
@Test
void registerCustomer_withExistingEmail_throwsEmailAlreadyRegisteredException_409() {
Customer requestObject = getCustomerRequestObject();
requestObject.setEmail("ashokk101@nisum.com");
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.postForEntity(url + "/register", requestObject, Customer.class);
assertEquals(HttpStatus.CONFLICT, customerResponseEntity.getStatusCode());
}
@Test
void registerCustomer_withMultipleDefaultShippingAddresses_throwsMethodArgumentNotValidException_404() {
Customer requestObject = getCustomerRequestObject();
requestObject.setEmail("ashokk101@nisum.com");
requestObject.getAddresses().forEach(address -> address.setDefault(true));
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.postForEntity(url + "/register", requestObject, Customer.class);
assertEquals(HttpStatus.BAD_REQUEST, customerResponseEntity.getStatusCode());
}
@Test
void registerCustomer_withMultipleBillingAddresses_throwsMethodArgumentNotValidException_404() {
Customer requestObject = getCustomerRequestObject();
requestObject.setEmail("ashokk101@nisum.com");
requestObject.getAddresses().forEach(address -> address.setAddressType(AddressType.BILLING));
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.postForEntity(url + "/register", requestObject, Customer.class);
assertEquals(HttpStatus.BAD_REQUEST, customerResponseEntity.getStatusCode());
}
@Test
void updateCustomer_returnsCustomer_201() {
Customer requestObject = customerRepository.findById(1L).get();
requestObject.setCustomerType(CustomerType.REGULAR);
HttpEntity<Customer> httpEntity = new HttpEntity<>(requestObject);
ResponseEntity<Customer> customerUpdatedResponseEntity = testRestTemplate.exchange(url + "/update", HttpMethod.PUT, httpEntity, Customer.class, new HashMap<>());
Customer updatedCustomer = customerUpdatedResponseEntity.getBody();
assertEquals(HttpStatus.CREATED, customerUpdatedResponseEntity.getStatusCode());
assertNotNull(updatedCustomer);
assertEquals(1L, updatedCustomer.getId());
assertEquals(CustomerType.REGULAR, updatedCustomer.getCustomerType());
}
@Test
void updateCustomer_throwsCustomerNotFoundException_404() {
Customer requestObject = getCustomerRequestObject();
requestObject.setId(2000L);
requestObject.setCustomerType(CustomerType.REGULAR);
HttpEntity<Customer> httpEntity = new HttpEntity<>(requestObject);
ResponseEntity<Customer> customerUpdatedResponseEntity = testRestTemplate.exchange(url + "/update", HttpMethod.PUT, httpEntity, Customer.class, new HashMap<>());
assertEquals(HttpStatus.NOT_FOUND, customerUpdatedResponseEntity.getStatusCode());
}
@Test
public void getById_returnsCustomer_200() {
Long id = 1L;
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.getForEntity(url + "/id/" + id, Customer.class);
assertEquals(HttpStatus.OK, customerResponseEntity.getStatusCode());
Customer customerResponse = customerResponseEntity.getBody();
assertNotNull(customerResponse);
assertEquals(id, customerResponse.getId());
assertEquals("ashokk1@nisum.com", customerResponse.getEmail());
}
@Test
public void getById_throwsCustomerNotFoundException_404() {
Long id = 2000L;
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.getForEntity(url + "/id/" + id, Customer.class);
assertEquals(HttpStatus.NOT_FOUND, customerResponseEntity.getStatusCode());
}
@Test
public void getByEmail_returnsCustomer_200() {
String email = "ashokk1@nisum.com";
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.getForEntity(url + "/email/" + email, Customer.class);
assertEquals(HttpStatus.OK, customerResponseEntity.getStatusCode());
Customer customerResponse = customerResponseEntity.getBody();
assertNotNull(customerResponse);
assertEquals(email, customerResponse.getEmail());
}
@Test
public void getByEmail_throwsCustomerNotFoundException_404() {
String email = "ashokk_random@nisum.com";
ResponseEntity<Customer> customerResponseEntity = testRestTemplate.getForEntity(url + "/email/" + email, Customer.class);
assertEquals(HttpStatus.NOT_FOUND, customerResponseEntity.getStatusCode());
}
private void initializeDb() {
customerRepository.deleteAll();
sequenceRepository.deleteAll();
Customer customer1 = getCustomerRequestObject();
customer1.setEmail("ashokk1@nisum.com");
Customer customer2 = getCustomerRequestObject();
customer2.setEmail("ashokk2@nisum.com");
customer2.setCustomerType(CustomerType.REGULAR);
Customer customer3 = getCustomerRequestObject();
customer3.setEmail("ashokk3@nisum.com");
customer3.setCustomerType(CustomerType.LOYAL);
Customer customer4 = getCustomerRequestObject();
customer4.setEmail("ashokk4@nisum.com");
Customer customer5 = getCustomerRequestObject();
customer5.setEmail("ashokk5@nisum.com");
List<Customer> customers = Arrays.asList(customer1, customer2, customer3, customer4, customer5);
customerRepository.saveAll(customers);
}
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 List<Customer> getCustomerRequestObjectsList() {
Customer customer1 = getCustomerRequestObject();
Customer customer2 = getCustomerRequestObject();
customer2.setEmail("anandk@nisum.com");
return Arrays.asList(customer1, customer2);
}
}
......@@ -21,6 +21,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
......@@ -79,7 +80,7 @@ class CustomerControllerTest {
.content(objectMapper.writeValueAsString(customersRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$", hasSize(3)))
.andReturn();
}
......@@ -87,7 +88,7 @@ class CustomerControllerTest {
void registerCustomers_throwsEmailAlreadyRegisteredException_409() throws Exception {
List<Customer> customersRequestObj = getCustomerRequestObjectsList();
when(customerService.registerAll(customersRequestObj)).thenThrow(new EmailAlreadyRegisteredException());
MvcResult result = mockMvc.perform(post("/customer/registerAll")
mockMvc.perform(post("/customer/registerAll")
.content(objectMapper.writeValueAsString(customersRequestObj))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isConflict())
......@@ -133,7 +134,7 @@ class CustomerControllerTest {
when(customerService.getAllCustomers()).thenReturn(getCustomerResponseObjectsList());
mockMvc.perform(get("/customer/"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$", hasSize(3)))
.andReturn();
}
......@@ -181,6 +182,38 @@ class CustomerControllerTest {
void getCustomersByLastName() {
}
@Test
void getCustomersByCustomerType_returnsCustomers_200() throws Exception {
int loyalValue = CustomerType.LOYAL.getValue();
when(customerService.getCustomersByCustomerType(CustomerType.LOYAL)).
thenReturn(getCustomerResponseObjectsList().stream()
.filter(customer -> customer.getCustomerType().getValue() == loyalValue)
.collect(Collectors.toList()));
mockMvc.perform(get("/customer/type/" + loyalValue))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].customerType", is(loyalValue)))
.andExpect(jsonPath("$[1].customerType", is(loyalValue)))
.andReturn();
}
@Test
void getCustomersByCustomerType_throwsIllegalArgumentException_400() throws Exception {
int typeValue = 3;
mockMvc.perform(get("/customer/type/" + typeValue))
.andExpect(status().isBadRequest())
.andReturn();
}
@Test
void getRegisteredCustomersOnDate() {
}
@Test
void getRegisteredCustomersBetweenDates() {
}
@Test
void deleteById_returnsNoContent_204() throws Exception {
doNothing().when(customerService).deleteById(1L);
......@@ -254,7 +287,10 @@ class CustomerControllerTest {
Customer customer1 = getCustomerRequestObject();
Customer customer2 = getCustomerRequestObject();
customer2.setEmail("anandk@nisum.com");
return Arrays.asList(customer1, customer2);
Customer customer3 = getCustomerRequestObject();
customer3.setEmail("anandk1@nisum.com");
customer3.setCustomerType(CustomerType.REGULAR);
return Arrays.asList(customer1, customer2, customer3);
}
private List<Customer> getCustomerResponseObjectsList() {
......@@ -273,4 +309,5 @@ class CustomerControllerTest {
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