diff --git a/pom.xml b/pom.xml index f522069..c15391d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,10 +9,10 @@ com.learning - SpringSecurity + YasMiniShop 1.0.0 - SpringSecurity - SpringSecurity + YasMini + YasMini CarShop 21 1.18.30 @@ -198,10 +198,9 @@ + **/common/** **/dto/** - **/entity/** **/mapper/** - **/configs/** diff --git a/src/main/java/com/learning/yasminishop/common/entity/Notification.java b/src/main/java/com/learning/yasminishop/common/entity/Notification.java index 4d1552e..6b6df63 100644 --- a/src/main/java/com/learning/yasminishop/common/entity/Notification.java +++ b/src/main/java/com/learning/yasminishop/common/entity/Notification.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import lombok.*; +import lombok.experimental.FieldDefaults; @Entity @Table(name = "t_notification") @@ -10,6 +11,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE) public class Notification extends AuditEntity{ @Id @GeneratedValue(strategy = GenerationType.UUID) diff --git a/src/test/java/com/learning/yasminishop/controller/AuthenticationControllerTest.java b/src/test/java/com/learning/yasminishop/controller/AuthenticationControllerTest.java index 578fac3..f65f4a4 100644 --- a/src/test/java/com/learning/yasminishop/controller/AuthenticationControllerTest.java +++ b/src/test/java/com/learning/yasminishop/controller/AuthenticationControllerTest.java @@ -10,6 +10,7 @@ import com.learning.yasminishop.auth.dto.response.TokenResponse; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -77,192 +78,200 @@ void setUp() { } - @Test - void register_validRequest_success() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - String registerRequestJson = objectMapper.writeValueAsString(registerRequest); + @Nested + class HappyCase { + @Test + void register_validRequest_success() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + String registerRequestJson = objectMapper.writeValueAsString(registerRequest); + + when(authenticationService.register(any(RegisterRequest.class))) + .thenReturn(authenticationResponse); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .content(registerRequestJson)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.tokens.access_token").value("accessToken")) + .andExpect(jsonPath("result.tokens.refresh_token").value("refreshToken")); + + } + + @Test + void authenticate_validRequest_success() throws Exception { + + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); + + when(authenticationService.authenticate(any(AuthenticationRequest.class))) + .thenReturn(authenticationResponse); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(authenticationRequestJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.tokens.access_token").value("accessToken")) + .andExpect(jsonPath("result.tokens.refresh_token").value("refreshToken")); + + } + + @Test + void refresh_validRequest_success() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + String refreshRequestJson = objectMapper.writeValueAsString(refreshRequest); + + when(authenticationService.refresh(any(RefreshRequest.class))) + .thenReturn(authenticationResponse); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/refresh") + .contentType(MediaType.APPLICATION_JSON) + .content(refreshRequestJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.tokens.access_token").value("accessToken")) + .andExpect(jsonPath("result.tokens.refresh_token").value("refreshToken")); + + } + + @Test + void logout_validRequest_success() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + String logoutRequestJson = objectMapper.writeValueAsString(logoutRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/logout") + .contentType(MediaType.APPLICATION_JSON) + .content(logoutRequestJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result").value("Logout successful")); + } - when(authenticationService.register(any(RegisterRequest.class))) - .thenReturn(authenticationResponse); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/register") - .contentType(MediaType.APPLICATION_JSON) - .content(registerRequestJson)) - .andExpect(status().isCreated()) - .andExpect(jsonPath("internalCode").value(1000)) - .andExpect(jsonPath("result.tokens.access_token").value("accessToken")) - .andExpect(jsonPath("result.tokens.refresh_token").value("refreshToken")); - - } - - @Test - void register_invalidEmail_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - registerRequest.setEmail("invalidEmail"); - String registerRequestJson = objectMapper.writeValueAsString(registerRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/register") - .contentType(MediaType.APPLICATION_JSON) - .content(registerRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2002)) - .andExpect(jsonPath("message").value("Invalid email")); - } - - @Test - void authenticate_validRequest_success() throws Exception { - - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); - - when(authenticationService.authenticate(any(AuthenticationRequest.class))) - .thenReturn(authenticationResponse); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") - .contentType(MediaType.APPLICATION_JSON) - .content(authenticationRequestJson)) - .andExpect(status().isOk()) - .andExpect(jsonPath("internalCode").value(1000)) - .andExpect(jsonPath("result.tokens.access_token").value("accessToken")) - .andExpect(jsonPath("result.tokens.refresh_token").value("refreshToken")); - - } - - @Test - void authenticate_invalidEmail_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - authenticationRequest.setEmail("invalidEmail"); - String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") - .contentType(MediaType.APPLICATION_JSON) - .content(authenticationRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2002)) - .andExpect(jsonPath("message").value("Invalid email")); - } - - @Test - void authenticate_invalidPassword_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - authenticationRequest.setPassword("123"); - String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") - .contentType(MediaType.APPLICATION_JSON) - .content(authenticationRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2001)) - .andExpect(jsonPath("message").value("Password must be at least 6 characters")); - } - - @Test - void authenticate_nullPassword_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - authenticationRequest.setPassword(null); - String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") - .contentType(MediaType.APPLICATION_JSON) - .content(authenticationRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2004)) - .andExpect(jsonPath("message").value("\"password\" must not be null")); } - @Test - void authenticate_nullEmail_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - authenticationRequest.setEmail(null); - String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") - .contentType(MediaType.APPLICATION_JSON) - .content(authenticationRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2004)) - .andExpect(jsonPath("message").value("\"email\" must not be null")); + @Nested + class UnHappyCase { + @Test + void register_invalidEmail_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + registerRequest.setEmail("invalidEmail"); + String registerRequestJson = objectMapper.writeValueAsString(registerRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .content(registerRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2002)) + .andExpect(jsonPath("message").value("Invalid email")); + } + + @Test + void authenticate_invalidEmail_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + authenticationRequest.setEmail("invalidEmail"); + String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(authenticationRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2002)) + .andExpect(jsonPath("message").value("Invalid email")); + } + + @Test + void authenticate_invalidPassword_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + authenticationRequest.setPassword("123"); + String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(authenticationRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2001)) + .andExpect(jsonPath("message").value("Password must be at least 6 characters")); + } + + @Test + void authenticate_nullPassword_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + authenticationRequest.setPassword(null); + String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(authenticationRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2004)) + .andExpect(jsonPath("message").value("\"password\" must not be null")); + } + + @Test + void authenticate_nullEmail_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + authenticationRequest.setEmail(null); + String authenticationRequestJson = objectMapper.writeValueAsString(authenticationRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(authenticationRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2004)) + .andExpect(jsonPath("message").value("\"email\" must not be null")); + } + + @Test + void refresh_nullToken_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + refreshRequest.setRefreshToken(null); + String refreshRequestJson = objectMapper.writeValueAsString(refreshRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/refresh") + .contentType(MediaType.APPLICATION_JSON) + .content(refreshRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2004)) + .andExpect(jsonPath("message").value("\"refreshToken\" must not be null")); + } + + @Test + void logout_nullToken_fail() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + logoutRequest.setToken(null); + String logoutRequestJson = objectMapper.writeValueAsString(logoutRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/auth/logout") + .contentType(MediaType.APPLICATION_JSON) + .content(logoutRequestJson)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("internalCode").value(2004)) + .andExpect(jsonPath("message").value("\"token\" must not be null")); + } } - @Test - void refresh_validRequest_success() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - String refreshRequestJson = objectMapper.writeValueAsString(refreshRequest); - - when(authenticationService.refresh(any(RefreshRequest.class))) - .thenReturn(authenticationResponse); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/refresh") - .contentType(MediaType.APPLICATION_JSON) - .content(refreshRequestJson)) - .andExpect(status().isOk()) - .andExpect(jsonPath("internalCode").value(1000)) - .andExpect(jsonPath("result.tokens.access_token").value("accessToken")) - .andExpect(jsonPath("result.tokens.refresh_token").value("refreshToken")); - - } - - @Test - void refresh_nullToken_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - refreshRequest.setRefreshToken(null); - String refreshRequestJson = objectMapper.writeValueAsString(refreshRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/refresh") - .contentType(MediaType.APPLICATION_JSON) - .content(refreshRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2004)) - .andExpect(jsonPath("message").value("\"refreshToken\" must not be null")); - } - - @Test - void logout_validRequest_success() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - String logoutRequestJson = objectMapper.writeValueAsString(logoutRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/logout") - .contentType(MediaType.APPLICATION_JSON) - .content(logoutRequestJson)) - .andExpect(status().isOk()) - .andExpect(jsonPath("internalCode").value(1000)) - .andExpect(jsonPath("result").value("Logout successful")); - } - - @Test - void logout_nullToken_fail() throws Exception { - // GIVEN - ObjectMapper objectMapper = new ObjectMapper(); - logoutRequest.setToken(null); - String logoutRequestJson = objectMapper.writeValueAsString(logoutRequest); - - // WHEN THEN - mockMvc.perform(MockMvcRequestBuilders.post("/auth/logout") - .contentType(MediaType.APPLICATION_JSON) - .content(logoutRequestJson)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("internalCode").value(2004)) - .andExpect(jsonPath("message").value("\"token\" must not be null")); - } } diff --git a/src/test/java/com/learning/yasminishop/controller/CartControllerTest.java b/src/test/java/com/learning/yasminishop/controller/CartControllerTest.java new file mode 100644 index 0000000..c8db9a7 --- /dev/null +++ b/src/test/java/com/learning/yasminishop/controller/CartControllerTest.java @@ -0,0 +1,179 @@ +package com.learning.yasminishop.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.learning.yasminishop.cart.CartItemRepository; +import com.learning.yasminishop.cart.dto.request.CartItemRequest; +import com.learning.yasminishop.common.entity.CartItem; +import com.learning.yasminishop.common.entity.Product; +import com.learning.yasminishop.common.entity.User; +import com.learning.yasminishop.product.ProductRepository; +import com.learning.yasminishop.user.UserRepository; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.math.BigDecimal; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@Slf4j +@AutoConfigureMockMvc +@TestPropertySource("/test.properties") +class CartControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ProductRepository productRepository; + + @Autowired + private CartItemRepository cartItemRepository; + + @Autowired + private UserRepository userRepository; + + private CartItemRequest cartItemRequest; + private Product product; + private User user; + private CartItem cartItem; + + @BeforeEach + void setUp() { + cartItemRequest = CartItemRequest.builder() + .productId("product-1") + .quantity(2) + .build(); + product = Product.builder() + .name("Product 1") + .description("Product 1 description") + .price(BigDecimal.valueOf(100)) + .quantity(10L) + .slug("product-1") + .sku("sku-1") + .isFeatured(true) + .isAvailable(true) + .build(); + user = User.builder() + .email("user@gmail.com") + .password("password") + .build(); + cartItem = CartItem.builder() + .product(product) + .quantity(2) + .price(BigDecimal.valueOf(200)) + .build(); + } + + @Test + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @WithMockUser(username = "user@gmail.com") + void createCart_validRequest_success() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + Product savedProduct = productRepository.save(product); + userRepository.save(user); + cartItemRequest.setProductId(savedProduct.getId()); + String requestJson = objectMapper.writeValueAsString(cartItemRequest); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/carts") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.product.name").value("Product 1")); + } + + @Test + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @WithMockUser(username = "user@gmail.com") + void getAllCarts_validRequest_success() throws Exception { + // GIVEN + Product savedProduct = productRepository.save(product); + User savedUser = userRepository.save(user); + cartItem.setProduct(savedProduct); + cartItem.setUser(savedUser); + cartItemRepository.save(cartItem); + + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/carts")) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result[0].product.name").value("Product 1")); + } + + @Test + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @WithMockUser(username = "user@gmail.com") + void updateCart_validRequest_success() throws Exception { + // GIVEN + Product savedProduct = productRepository.save(product); + User savedUser = userRepository.save(user); + cartItem.setProduct(savedProduct); + cartItem.setUser(savedUser); + CartItem savedCartItem = cartItemRepository.save(cartItem); + String requestJson = "{\"quantity\": 5}"; + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.put("/carts/" + savedCartItem.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.quantity").value(5)); + } + + @Test + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @WithMockUser(username = "user@gmail.com") + void deleteCart_validRequest_success() throws Exception { + // GIVEN + Product savedProduct = productRepository.save(product); + User savedUser = userRepository.save(user); + cartItem.setProduct(savedProduct); + cartItem.setUser(savedUser); + CartItem savedCartItem = cartItemRepository.save(cartItem); + String requestJson = "{\"ids\": [\"" + savedCartItem.getId() + "\"]}"; + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.delete("/carts") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("message").value("Cart items deleted successfully")); + } + + @Test + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + @WithMockUser(username = "user@gmail.com") + void getCartItemsByIds_validRequest_success() throws Exception { + // GIVEN + Product savedProduct = productRepository.save(product); + User savedUser = userRepository.save(user); + cartItem.setProduct(savedProduct); + cartItem.setUser(savedUser); + CartItem savedCartItem = cartItemRepository.save(cartItem); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/carts/get-by-ids") + .param("ids", savedCartItem.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result[0].product.name").value("Product 1")); + } + +} diff --git a/src/test/java/com/learning/yasminishop/controller/CategoryControllerTest.java b/src/test/java/com/learning/yasminishop/controller/CategoryControllerTest.java new file mode 100644 index 0000000..cbb1104 --- /dev/null +++ b/src/test/java/com/learning/yasminishop/controller/CategoryControllerTest.java @@ -0,0 +1,193 @@ +package com.learning.yasminishop.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.learning.yasminishop.category.CategoryRepository; +import com.learning.yasminishop.category.dto.request.CategoryCreation; +import com.learning.yasminishop.category.dto.request.CategoryIds; +import com.learning.yasminishop.common.entity.Category; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.util.List; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@Slf4j +@AutoConfigureMockMvc +@TestPropertySource("/test.properties") +class CategoryControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private CategoryRepository categoryRepository; + + private CategoryCreation categoryCreation; + private Category category; + private CategoryIds categoryIds; + + @BeforeEach + void setUp() { + + categoryCreation = CategoryCreation.builder() + .name("Category Create") + .description("Category create description") + .slug("category-create") + .build(); + category = Category.builder() + .name("Category 1") + .description("Category 1 description") + .slug("category-1") + .isAvailable(true) + .build(); + + categoryIds = CategoryIds.builder() + .ids(List.of("category-1")) + .build(); + + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void createCategory_validRequest_success() throws Exception { + + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + String categoryCreationJson = objectMapper.writeValueAsString(categoryCreation); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.post("/categories") + .contentType(MediaType.APPLICATION_JSON) + .content(categoryCreationJson)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.name").value("Category Create")) + .andExpect(jsonPath("result.description").value("Category create description")) + .andExpect(jsonPath("result.slug").value("category-create")); + } + + @Test + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getAllCategories_validRequest_success() throws Exception { + // GIVEN + categoryRepository.save(category); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/categories")) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result").isArray()); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getCategoryBySlug_validRequest_success() throws Exception { + // GIVEN + categoryRepository.save(category); + + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/categories/slug/category-1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.name").value("Category 1")) + .andExpect(jsonPath("result.description").value("Category 1 description")) + .andExpect(jsonPath("result.slug").value("category-1")); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getCategoryById_validRequest_success() throws Exception { + // GIVEN + Category saved = categoryRepository.save(category); + String id = saved.getId(); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/categories/" + id)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.id").value(id)) + .andExpect(jsonPath("result.name").value("Category 1")) + .andExpect(jsonPath("result.description").value("Category 1 description")) + .andExpect(jsonPath("result.slug").value("category-1")); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void toggleAvailability_validRequest_success() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + Category saved = categoryRepository.save(category); + + categoryIds.setIds(List.of(saved.getId())); + String idsJson = objectMapper.writeValueAsString(categoryIds); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.patch("/categories/toggle-availability") + .contentType(MediaType.APPLICATION_JSON) + .content(idsJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("message").value("Categories availability toggled successfully")); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void deleteCategories_validRequest_success() throws Exception { + // GIVEN + ObjectMapper objectMapper = new ObjectMapper(); + Category saved = categoryRepository.save(category); + + categoryIds.setIds(List.of(saved.getId())); + String idsJson = objectMapper.writeValueAsString(categoryIds); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.delete("/categories") + .contentType(MediaType.APPLICATION_JSON) + .content(idsJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("message").value("Category deleted successfully")); + } + + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getAllCategoriesForAdmin_validRequest_success() throws Exception { + // GIVEN + String name = "Category"; + boolean isAvailable = true; + int page = 1; + int itemsPerPage = 10; + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/categories/admin") + .param("name", name) + .param("isAvailable", Boolean.toString(isAvailable)) + .param("page", Integer.toString(page)) + .param("itemsPerPage", Integer.toString(itemsPerPage))) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result").exists()); + } + + +} diff --git a/src/test/java/com/learning/yasminishop/controller/OrderControllerTest.java b/src/test/java/com/learning/yasminishop/controller/OrderControllerTest.java new file mode 100644 index 0000000..f49d2fd --- /dev/null +++ b/src/test/java/com/learning/yasminishop/controller/OrderControllerTest.java @@ -0,0 +1,158 @@ +package com.learning.yasminishop.controller; + +import com.learning.yasminishop.common.entity.Order; +import com.learning.yasminishop.common.entity.OrderItem; +import com.learning.yasminishop.common.entity.Product; +import com.learning.yasminishop.common.entity.User; +import com.learning.yasminishop.order.OrderRepository; +import com.learning.yasminishop.product.ProductRepository; +import com.learning.yasminishop.user.UserRepository; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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.security.test.context.support.WithMockUser; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.math.BigDecimal; +import java.util.Set; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@Slf4j +@AutoConfigureMockMvc +@TestPropertySource("/test.properties") +class OrderControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private OrderRepository orderRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ProductRepository productRepository; + + private Order order; + private User user; + private Product product; + + @BeforeEach + void setUp() { + + product = Product.builder() + .name("Product 1") + .description("Product 1 description") + .price(BigDecimal.valueOf(100)) + .quantity(10L) + .slug("product-1") + .sku("sku-1") + .isFeatured(true) + .isAvailable(true) + .build(); + + OrderItem orderItem = OrderItem.builder() + .product(product) + .quantity(2) + .price(BigDecimal.valueOf(200)) + .build(); + + user = User.builder() + .email("user@test.com") + .password("password") + .build(); + order = Order.builder() + .id("order-1") + .totalQuantity(4) + .totalPrice(BigDecimal.valueOf(400)) + .orderItems(Set.of(orderItem)) + .user(user) + .build(); + + } + + @Test + @WithMockUser(username = "user@test.com") + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getAllOrders_validRequest_success() throws Exception { + // GIVEN + User savedUser = userRepository.save(user); + Product savedProduct = productRepository.save(product); + order.setUser(savedUser); + order.getOrderItems().forEach(orderItem -> orderItem.setProduct(savedProduct)); + orderRepository.save(order); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/orders")) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result").isArray()); + } + + @Test + @WithMockUser(username = "user@test.com") + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getOrderById_validRequest_success() throws Exception { + // GIVEN + User savedUser = userRepository.save(user); + Product savedProduct = productRepository.save(product); + order.setUser(savedUser); + order.getOrderItems().forEach(orderItem -> orderItem.setProduct(savedProduct)); + Order savedOrder = orderRepository.save(order); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/orders/" + savedOrder.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.id").value(savedOrder.getId())); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getAllOrdersForAdmin_validRequest_success() throws Exception { + // GIVEN + User savedUser = userRepository.save(user); + Product savedProduct = productRepository.save(product); + order.setUser(savedUser); + order.getOrderItems().forEach(orderItem -> orderItem.setProduct(savedProduct)); + orderRepository.save(order); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/orders/admin")) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.total").value(1)) + .andExpect(jsonPath("result.page").value(1)) + .andExpect(jsonPath("result.data").isArray()); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) + void getOrderByIdForAdmin_validRequest_success() throws Exception { + // GIVEN + User savedUser = userRepository.save(user); + Product savedProduct = productRepository.save(product); + order.setUser(savedUser); + order.getOrderItems().forEach(orderItem -> orderItem.setProduct(savedProduct)); + Order savedOrder = orderRepository.save(order); + + // WHEN THEN + mockMvc.perform(MockMvcRequestBuilders.get("/orders/" + savedOrder.getId() + "/admin")) + .andExpect(status().isOk()) + .andExpect(jsonPath("internalCode").value(1000)) + .andExpect(jsonPath("result.id").value(savedOrder.getId())); + } + +} diff --git a/src/test/java/com/learning/yasminishop/service/AuthenticationServiceTest.java b/src/test/java/com/learning/yasminishop/service/AuthenticationServiceTest.java index 6ab24b8..6c8477a 100644 --- a/src/test/java/com/learning/yasminishop/service/AuthenticationServiceTest.java +++ b/src/test/java/com/learning/yasminishop/service/AuthenticationServiceTest.java @@ -14,6 +14,7 @@ import com.learning.yasminishop.user.UserRepository; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -83,204 +84,216 @@ void setUp() { .build(); } - @Test - void register_validRequest_success() { + @Nested + class HappyCase { + @Test + void register_validRequest_success() { + + // GIVEN + when(userRepository.existsByEmail(anyString())).thenReturn(false); + when(roleRepository.findById(anyString())) + .thenReturn(Optional.of(Role.builder() + .name("USER") + .description("User role") + .build())); + + when(userRepository.save(any())) + .thenReturn(new User()); + + when(jwtService.generateAccessToken(any())) + .thenReturn("accessToken"); + + when(jwtService.generateRefreshToken(any())) + .thenReturn("refreshToken"); + + // WHEN + var response = authenticationService.register(registerRequest); + + // THEN + verify(userRepository, times(1)).save(any()); + assertThat(response.getTokens().getAccessToken()).isEqualTo("accessToken"); + assertThat(response.getTokens().getRefreshToken()).isEqualTo("refreshToken"); + } + + @Test + void authenticate_validRequest_success() { + // GIVEN + + when(userRepository.findByEmail(anyString())) + .thenReturn(Optional.of(User.builder() + .id("abc-123") + .email("duongminhhieu@gmail.com") + .password("123456") + .isActive(true) + .build())); + when(jwtService.generateAccessToken(any())) + .thenReturn("accessToken"); + when(jwtService.generateRefreshToken(any())) + .thenReturn("refreshToken"); + + when(passwordEncoder.matches(anyString(), anyString())) + .thenReturn(true); + + // WHEN + var response = authenticationService.authenticate(authenticationRequest); + + // THEN + assertThat(response.getTokens().getAccessToken()).isEqualTo("accessToken"); + assertThat(response.getTokens().getRefreshToken()).isEqualTo("refreshToken"); + } + + @Test + void refresh_validRequest_success() { + // GIVEN + when(jwtService.isTokenValid(anyString())).thenReturn(true); + when(jwtService.extractUserEmail(anyString())).thenReturn("duongminhhieu@gmail.com"); + when(userRepository.findByEmail(anyString())) + .thenReturn(Optional.of(User.builder() + .id("abc-123") + .email("duongminhhieu@gmail.com") + .password("123456") + .build())); + when(jwtService.extractIdToken(anyString())).thenReturn("idToken"); + when(jwtService.extractExpiration(anyString())) + .thenReturn(Date.from(new Date().toInstant().plusSeconds(3600))); + when(jwtService.generateAccessToken(any())) + .thenReturn("accessToken"); + when(jwtService.generateRefreshToken(any())) + .thenReturn("refreshToken"); + + // WHEN + var response = authenticationService.refresh(refreshRequest); + + // THEN + assertThat(response.getTokens().getAccessToken()).isEqualTo("accessToken"); + assertThat(response.getTokens().getRefreshToken()).isEqualTo("refreshToken"); + verify(invalidTokenRepository, times(1)).save(any()); + } + + @Test + void logout_validRequest_success() { + // GIVEN + when(jwtService.isTokenValid(anyString())).thenReturn(true); + when(jwtService.extractIdToken(anyString())).thenReturn("idToken"); + + // WHEN + authenticationService.logout(logoutRequest); + // THEN + verify(invalidTokenRepository, times(1)).save(any()); + } - // GIVEN - when(userRepository.existsByEmail(anyString())).thenReturn(false); - when(roleRepository.findById(anyString())) - .thenReturn(Optional.of(Role.builder() - .name("USER") - .description("User role") - .build())); - - when(userRepository.save(any())) - .thenReturn(new User()); - - when(jwtService.generateAccessToken(any())) - .thenReturn("accessToken"); - - when(jwtService.generateRefreshToken(any())) - .thenReturn("refreshToken"); - - // WHEN - var response = authenticationService.register(registerRequest); - - // THEN - verify(userRepository, times(1)).save(any()); - assertThat(response.getTokens().getAccessToken()).isEqualTo("accessToken"); - assertThat(response.getTokens().getRefreshToken()).isEqualTo("refreshToken"); - } - - @Test - void register_emailAlreadyExists_throwException() { - - // GIVEN - when(userRepository.existsByEmail(anyString())).thenReturn(true); - - // WHEN - var exception = assertThrows(AppException.class, () -> authenticationService.register(registerRequest) - ); - - // THEN - assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1002); - assertThat(exception.getErrorCode().getMessage()).isEqualTo("Email already exists"); } - @Test - void authenticate_validRequest_success() { - // GIVEN - - when(userRepository.findByEmail(anyString())) - .thenReturn(Optional.of(User.builder() - .id("abc-123") - .email("duongminhhieu@gmail.com") - .password("123456") - .isActive(true) - .build())); - when(jwtService.generateAccessToken(any())) - .thenReturn("accessToken"); - when(jwtService.generateRefreshToken(any())) - .thenReturn("refreshToken"); - - when(passwordEncoder.matches(anyString(), anyString())) - .thenReturn(true); - - // WHEN - var response = authenticationService.authenticate(authenticationRequest); - - // THEN - assertThat(response.getTokens().getAccessToken()).isEqualTo("accessToken"); - assertThat(response.getTokens().getRefreshToken()).isEqualTo("refreshToken"); + @Nested + class UnHappyCase { + @Test + void register_emailAlreadyExists_throwException() { + + // GIVEN + when(userRepository.existsByEmail(anyString())).thenReturn(true); + + // WHEN + var exception = assertThrows(AppException.class, () -> authenticationService.register(registerRequest) + ); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1002); + assertThat(exception.getErrorCode().getMessage()).isEqualTo("Email already exists"); + } + + + @Test + void authenticate_invalidPassword_throwException() { + // GIVEN + when(userRepository.findByEmail(anyString())) + .thenReturn(Optional.of(User.builder() + .id("abc-123") + .email("duongminhhieu@gmail.com") + .password("123456") + .build())); + when(passwordEncoder.matches(anyString(), anyString())) + .thenReturn(false); + + // WHEN + var exception = assertThrows(AppException.class, () -> authenticationService.authenticate(authenticationRequest) + ); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1013); + assertThat(exception.getErrorCode().getMessage()).isEqualTo("Email or password is incorrect"); + verify(passwordEncoder, times(1)).matches(anyString(), anyString()); + verify(jwtService, never()).generateAccessToken(any()); + verify(jwtService, never()).generateRefreshToken(any()); + } + + @Test + void authenticate_userNotFound_throwException() { + // GIVEN + when(userRepository.findByEmail(anyString())) + .thenReturn(Optional.empty()); + + // WHEN + var exception = assertThrows(AppException.class, () -> authenticationService.authenticate(authenticationRequest) + ); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1013); + assertThat(exception.getErrorCode().getMessage()).isEqualTo("Email or password is incorrect"); + verify(passwordEncoder, never()).matches(anyString(), anyString()); + verify(jwtService, never()).generateAccessToken(any()); + verify(jwtService, never()).generateRefreshToken(any()); + } + + + @Test + void refresh_invalidToken_throwException() { + // GIVEN + when(jwtService.isTokenValid(anyString())).thenReturn(false); + + // WHEN + var exception = assertThrows(AppException.class, () -> authenticationService.refresh(refreshRequest) + ); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1001); + assertThat(exception.getErrorCode().getMessage()).isEqualTo("Invalid token"); + verify(userRepository, never()).findByEmail(anyString()); + verify(jwtService, never()).generateAccessToken(any()); + verify(jwtService, never()).generateRefreshToken(any()); + verify(invalidTokenRepository, never()).save(any()); + } + + @Test + void refresh_userNotFound_throwException() { + // GIVEN + when(jwtService.isTokenValid(anyString())).thenReturn(true); + when(jwtService.extractUserEmail(anyString())).thenReturn("hehe@gmail.com"); + + // WHEN + var exception = assertThrows(AppException.class, () -> authenticationService.refresh(refreshRequest) + ); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1001); + assertThat(exception.getErrorCode().getMessage()).isEqualTo("Invalid token"); + } + + + @Test + void logout_invalidToken_throwException() { + // GIVEN + when(jwtService.isTokenValid(anyString())).thenReturn(false); + + // WHEN + var exception = assertThrows(AppException.class, () -> authenticationService.logout(logoutRequest) + ); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1001); + assertThat(exception.getErrorCode().getMessage()).isEqualTo("Invalid token"); + verify(invalidTokenRepository, never()).save(any()); + } } - @Test - void authenticate_invalidPassword_throwException() { - // GIVEN - when(userRepository.findByEmail(anyString())) - .thenReturn(Optional.of(User.builder() - .id("abc-123") - .email("duongminhhieu@gmail.com") - .password("123456") - .build())); - when(passwordEncoder.matches(anyString(), anyString())) - .thenReturn(false); - - // WHEN - var exception = assertThrows(AppException.class, () -> authenticationService.authenticate(authenticationRequest) - ); - - // THEN - assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1013); - assertThat(exception.getErrorCode().getMessage()).isEqualTo("Email or password is incorrect"); - verify(passwordEncoder, times(1)).matches(anyString(), anyString()); - verify(jwtService, never()).generateAccessToken(any()); - verify(jwtService, never()).generateRefreshToken(any()); - } - @Test - void authenticate_userNotFound_throwException() { - // GIVEN - when(userRepository.findByEmail(anyString())) - .thenReturn(Optional.empty()); - - // WHEN - var exception = assertThrows(AppException.class, () -> authenticationService.authenticate(authenticationRequest) - ); - - // THEN - assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1013); - assertThat(exception.getErrorCode().getMessage()).isEqualTo("Email or password is incorrect"); - verify(passwordEncoder, never()).matches(anyString(), anyString()); - verify(jwtService, never()).generateAccessToken(any()); - verify(jwtService, never()).generateRefreshToken(any()); - } - - @Test - void refresh_validRequest_success() { - // GIVEN - when(jwtService.isTokenValid(anyString())).thenReturn(true); - when(jwtService.extractUserEmail(anyString())).thenReturn("duongminhhieu@gmail.com"); - when(userRepository.findByEmail(anyString())) - .thenReturn(Optional.of(User.builder() - .id("abc-123") - .email("duongminhhieu@gmail.com") - .password("123456") - .build())); - when(jwtService.extractIdToken(anyString())).thenReturn("idToken"); - when(jwtService.extractExpiration(anyString())) - .thenReturn(Date.from(new Date().toInstant().plusSeconds(3600))); - when(jwtService.generateAccessToken(any())) - .thenReturn("accessToken"); - when(jwtService.generateRefreshToken(any())) - .thenReturn("refreshToken"); - - // WHEN - var response = authenticationService.refresh(refreshRequest); - - // THEN - assertThat(response.getTokens().getAccessToken()).isEqualTo("accessToken"); - assertThat(response.getTokens().getRefreshToken()).isEqualTo("refreshToken"); - verify(invalidTokenRepository, times(1)).save(any()); - } - - @Test - void refresh_invalidToken_throwException() { - // GIVEN - when(jwtService.isTokenValid(anyString())).thenReturn(false); - - // WHEN - var exception = assertThrows(AppException.class, () -> authenticationService.refresh(refreshRequest) - ); - - // THEN - assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1001); - assertThat(exception.getErrorCode().getMessage()).isEqualTo("Invalid token"); - verify(userRepository, never()).findByEmail(anyString()); - verify(jwtService, never()).generateAccessToken(any()); - verify(jwtService, never()).generateRefreshToken(any()); - verify(invalidTokenRepository, never()).save(any()); - } - - @Test - void refresh_userNotFound_throwException() { - // GIVEN - when(jwtService.isTokenValid(anyString())).thenReturn(true); - when(jwtService.extractUserEmail(anyString())).thenReturn("hehe@gmail.com"); - - // WHEN - var exception = assertThrows(AppException.class, () -> authenticationService.refresh(refreshRequest) - ); - - // THEN - assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1001); - assertThat(exception.getErrorCode().getMessage()).isEqualTo("Invalid token"); - } - - @Test - void logout_validRequest_success() { - // GIVEN - when(jwtService.isTokenValid(anyString())).thenReturn(true); - when(jwtService.extractIdToken(anyString())).thenReturn("idToken"); - - // WHEN - authenticationService.logout(logoutRequest); - // THEN - verify(invalidTokenRepository, times(1)).save(any()); - } - - @Test - void logout_invalidToken_throwException() { - // GIVEN - when(jwtService.isTokenValid(anyString())).thenReturn(false); - - // WHEN - var exception = assertThrows(AppException.class, () -> authenticationService.logout(logoutRequest) - ); - - // THEN - assertThat(exception.getErrorCode().getInternalCode()).isEqualTo(1001); - assertThat(exception.getErrorCode().getMessage()).isEqualTo("Invalid token"); - verify(invalidTokenRepository, never()).save(any()); - } } diff --git a/src/test/java/com/learning/yasminishop/service/CartServiceTest.java b/src/test/java/com/learning/yasminishop/service/CartServiceTest.java new file mode 100644 index 0000000..8a2231e --- /dev/null +++ b/src/test/java/com/learning/yasminishop/service/CartServiceTest.java @@ -0,0 +1,221 @@ +package com.learning.yasminishop.service; + +import com.learning.yasminishop.cart.CartItemRepository; +import com.learning.yasminishop.cart.CartItemService; +import com.learning.yasminishop.cart.dto.request.CartItemRequest; +import com.learning.yasminishop.cart.dto.request.CartItemUpdate; +import com.learning.yasminishop.cart.dto.response.CartItemResponse; +import com.learning.yasminishop.common.entity.CartItem; +import com.learning.yasminishop.common.entity.Product; +import com.learning.yasminishop.common.entity.User; +import com.learning.yasminishop.common.exception.AppException; +import com.learning.yasminishop.product.ProductRepository; +import com.learning.yasminishop.user.UserRepository; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.TestPropertySource; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import static org.assertj.core.api.Assertions.assertThat; + + +@SpringBootTest +@Slf4j +@TestPropertySource("/test.properties") +class CartServiceTest { + + @MockBean + private CartItemRepository cartItemRepository; + + @MockBean + private ProductRepository productRepository; + + @MockBean + private UserRepository userRepository; + + @Autowired + private CartItemService cartItemService; + + + private CartItemRequest cartItemRequest; + private Product product; + private User user; + private CartItem cartItem; + private CartItemUpdate cartItemUpdate; + private List cartIds; + private List cartItems; + + @BeforeEach + void setUp() { + + cartItemRequest = CartItemRequest.builder() + .productId("product-1") + .quantity(2) + .build(); + + product = Product.builder() + .name("Product 1") + .description("Product 1 description") + .price(BigDecimal.valueOf(100)) + .quantity(10L) + .slug("product-1") + .sku("sku-1") + .isFeatured(true) + .isAvailable(true) + .build(); + user = User.builder() + .email("user@test.com") + .password("password") + .build(); + cartItem = CartItem.builder() + .product(product) + .quantity(2) + .user(user) + .price(BigDecimal.valueOf(200)) + .build(); + + cartItemUpdate = CartItemUpdate.builder() + .quantity(3) + .build(); + cartIds = List.of("cart-1", "cart-2"); + cartItems = List.of(CartItem.builder() + .id("cart-1") + .product(product) + .quantity(2) + .user(user) + .price(BigDecimal.valueOf(200)) + .build(), + CartItem.builder() + .id("cart-2") + .product(product) + .quantity(2) + .user(user) + .price(BigDecimal.valueOf(200)) + .build()); + } + + @Nested + class HappyCase { + + @Test + @WithMockUser(username = "user@test.com") + void create_validRequest_success() { + // GIVEN + when(productRepository.findById(cartItemRequest.getProductId())).thenReturn(Optional.of(product)); + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(cartItemRepository.findByProductAndUser(product, user)).thenReturn(Optional.empty()); + when(cartItemRepository.save(any(CartItem.class))).thenReturn(cartItem); + + // WHEN + CartItemResponse result = cartItemService.create(cartItemRequest); + + // THEN + assertEquals(cartItem.getQuantity(), result.getQuantity()); + assertEquals(cartItem.getPrice(), result.getPrice()); + assertEquals(cartItem.getProduct().getId(), result.getProduct().getId()); + } + + @Test + @WithMockUser(username = "user@test.com") + void getAll_validRequest_success() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(cartItemRepository.findAllByUserOrderByLastModifiedDateDesc(user)).thenReturn(java.util.List.of(cartItem)); + + // WHEN + var result = cartItemService.getAll(); + + // THEN + assertThat(result).isNotNull() + .hasSize(1) + .first() + .hasFieldOrPropertyWithValue("quantity", 2) + .hasFieldOrPropertyWithValue("price", BigDecimal.valueOf(200)); + } + + @Test + @WithMockUser(username = "user@test.com") + void update_validRequest_success() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(cartItemRepository.findById(cartItem.getId())).thenReturn(Optional.of(cartItem)); + when(cartItemRepository.save(any(CartItem.class))).thenReturn(cartItem); + + // WHEN + var result = cartItemService.update(cartItem.getId(), cartItemUpdate); + + // THEN + assertEquals(cartItemUpdate.getQuantity(), result.getQuantity()); + } + + @Test + @WithMockUser(username = "user@test.com") + void delete_validRequest_success() { + // GIVEN + when(cartItemRepository.findAllById(cartIds)).thenReturn(cartItems); + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + + // WHEN + cartItemService.delete(cartIds); + + // THEN + verify(cartItemRepository).deleteAll(cartItems); + } + + @Test + @WithMockUser(username = "user@test.com") + void getCartByIds_validRequest_success() { + // GIVEN + when(cartItemRepository.findAllById(cartIds)).thenReturn(cartItems); + + // WHEN + var result = cartItemService.getCartByIds(cartIds); + + // THEN + assertThat(result).isNotNull() + .hasSize(2) + .first() + .hasFieldOrPropertyWithValue("id", "cart-1") + .hasFieldOrPropertyWithValue("quantity", 2); + } + + } + + @Nested + class UnhappyCase { + + @Test + @WithMockUser(username = "user@test.com") + void create_productNotFound_throwException() { + // GIVEN + when(productRepository.findById(cartItemRequest.getProductId())).thenReturn(Optional.empty()); + + // WHEN + var exception = assertThrows(AppException.class, () -> cartItemService.create(cartItemRequest)); + + // THEN + assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1009); + assertThat(exception.getErrorCode().getMessage()) + .isEqualTo("Product not found"); + } + + } + + +} diff --git a/src/test/java/com/learning/yasminishop/service/CategoryServiceTest.java b/src/test/java/com/learning/yasminishop/service/CategoryServiceTest.java new file mode 100644 index 0000000..fecff2e --- /dev/null +++ b/src/test/java/com/learning/yasminishop/service/CategoryServiceTest.java @@ -0,0 +1,182 @@ +package com.learning.yasminishop.service; + +import com.learning.yasminishop.category.CategoryRepository; +import com.learning.yasminishop.category.CategoryService; +import com.learning.yasminishop.category.dto.request.CategoryCreation; +import com.learning.yasminishop.category.dto.request.CategoryUpdate; +import com.learning.yasminishop.category.dto.response.CategoryResponse; +import com.learning.yasminishop.common.entity.Category; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.TestPropertySource; + +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +@Slf4j +@TestPropertySource("/test.properties") +class CategoryServiceTest { + + @Autowired + private CategoryService categoryService; + + @MockBean + private CategoryRepository categoryRepository; + + private CategoryCreation categoryCreation; + + private Category category; + private CategoryUpdate categoryUpdate; + + @BeforeEach + void setUp() { + + categoryCreation = CategoryCreation.builder() + .name("Category Create") + .description("Category create description") + .slug("category-create") + .build(); + + category = Category.builder() + .id("cate1") + .name("Category 1") + .description("Category 1 description") + .slug("category-1") + .isAvailable(true) + .products(Set.of()) + .build(); + + categoryUpdate = CategoryUpdate.builder() + .name("Category update") + .description("Category 1 update description") + .slug("category-1") + .isAvailable(true) + .build(); + + } + + @Nested + class HappyCase { + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void createCategory_validRequest_success() { + // GIVEN + when(categoryRepository.existsBySlug(categoryCreation.getSlug())).thenReturn(false); + when(categoryRepository.save(any(Category.class))).thenReturn(category); + + // WHEN + CategoryResponse response = categoryService.create(categoryCreation); + + // THEN + assertThat(response).isNotNull() + .hasFieldOrPropertyWithValue("name", "Category 1") + .hasFieldOrPropertyWithValue("description", "Category 1 description") + .hasFieldOrPropertyWithValue("slug", "category-1"); + } + + @Test + void getAllCategories_validRequest_success() { + // GIVEN + when(categoryRepository.findAllByIsAvailable(true)).thenReturn(List.of(category)); + + // WHEN + List response = categoryService.getAllCategories(); + + // THEN + assertThat(response).isNotNull() + .hasSize(1) + .first() + .hasFieldOrPropertyWithValue("name", "Category 1") + .hasFieldOrPropertyWithValue("description", "Category 1 description") + .hasFieldOrPropertyWithValue("slug", "category-1"); + } + + @Test + void getBySlug_validRequest_success() { + // GIVEN + when(categoryRepository.findBySlug("category-1")).thenReturn(Optional.of(category)); + + // WHEN + CategoryResponse response = categoryService.getBySlug("category-1"); + + // THEN + assertThat(response).isNotNull() + .hasFieldOrPropertyWithValue("name", "Category 1") + .hasFieldOrPropertyWithValue("description", "Category 1 description") + .hasFieldOrPropertyWithValue("slug", "category-1"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getCategory_validRequest_success() { + // GIVEN + when(categoryRepository.findById("cate1")).thenReturn(Optional.of(category)); + + // WHEN + var response = categoryService.getCategory("cate1"); + + // THEN + assertThat(response).isNotNull() + .hasFieldOrPropertyWithValue("name", "Category 1") + .hasFieldOrPropertyWithValue("description", "Category 1 description") + .hasFieldOrPropertyWithValue("slug", "category-1"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void delete_validRequest_success() { + // GIVEN + when(categoryRepository.findAllById(List.of("cate1"))).thenReturn(List.of(category)); + + // WHEN + categoryService.delete(List.of("cate1")); + + // THEN + verify(categoryRepository).deleteAll(List.of(category)); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void toggleAvailability_validRequest_success() { + // GIVEN + when(categoryRepository.findAllById(List.of("cate1"))).thenReturn(List.of(category)); + + // WHEN + categoryService.toggleAvailability(List.of("cate1")); + + // THEN + verify(categoryRepository).saveAll(List.of(category)); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void update_validRequest_success() { + // GIVEN + when(categoryRepository.findById("cate1")).thenReturn(Optional.of(category)); + when(categoryRepository.save(any(Category.class))).thenReturn(category); + + // WHEN + var response = categoryService.update("cate1", categoryUpdate); + + // THEN + assertThat(response).isNotNull() + .hasFieldOrPropertyWithValue("name", "Category update"); + } + } +} + + diff --git a/src/test/java/com/learning/yasminishop/service/OrderServiceTest.java b/src/test/java/com/learning/yasminishop/service/OrderServiceTest.java new file mode 100644 index 0000000..7f068c7 --- /dev/null +++ b/src/test/java/com/learning/yasminishop/service/OrderServiceTest.java @@ -0,0 +1,263 @@ +package com.learning.yasminishop.service; + + +import com.learning.yasminishop.cart.CartItemRepository; +import com.learning.yasminishop.common.dto.PaginationResponse; +import com.learning.yasminishop.common.entity.*; +import com.learning.yasminishop.common.enumeration.EOrderStatus; +import com.learning.yasminishop.common.exception.AppException; +import com.learning.yasminishop.notification.NotificationRepository; +import com.learning.yasminishop.order.OrderRepository; +import com.learning.yasminishop.order.OrderService; +import com.learning.yasminishop.order.dto.filter.OrderFilter; +import com.learning.yasminishop.order.dto.request.OrderAddressRequest; +import com.learning.yasminishop.order.dto.request.OrderRequest; +import com.learning.yasminishop.order.dto.response.OrderAdminResponse; +import com.learning.yasminishop.order.dto.response.OrderResponse; +import com.learning.yasminishop.user.UserRepository; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.TestPropertySource; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +@SpringBootTest +@Slf4j +@TestPropertySource("/test.properties") +class OrderServiceTest { + + @Autowired + private OrderService orderService; + + @MockBean + private UserRepository userRepository; + + @MockBean + private CartItemRepository cartItemRepository; + + @MockBean + private OrderRepository orderRepository; + + @MockBean + private NotificationRepository notificationRepository; + + private OrderRequest orderRequest; + private User user; + private Order order; + + @BeforeEach + void setUp() { + + Set cartItemIds = Set.of("cart-1"); + + OrderAddressRequest orderAddressRequest = OrderAddressRequest.builder() + .contactName("Hieu Duong") + .phone("0933444555") + .addressLine1("addressLine1") + .addressLine2("addressLine2") + .build(); + + orderRequest = OrderRequest.builder() + .cartItemIds(cartItemIds) + .orderAddress(orderAddressRequest) + .build(); + user = User.builder() + .email("user@test.com") + .password("password") + .build(); + Product product = Product.builder() + .name("Product 1") + .description("Product 1 description") + .price(BigDecimal.valueOf(100)) + .quantity(10L) + .slug("product-1") + .sku("sku-1") + .isFeatured(true) + .isAvailable(true) + .build(); + + OrderItem orderItem = OrderItem.builder() + .product(product) + .quantity(2) + .price(BigDecimal.valueOf(200)) + .build(); + order = Order.builder() + .id("order-1") + .totalQuantity(4) + .totalPrice(BigDecimal.valueOf(400)) + .orderItems(Set.of(orderItem)) + .user(user) + .build(); + } + + + @Nested + class HappyCase { + + @Test + @WithMockUser(username = "user@test.com") + void getAllOrderByUser_validRequest_success() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(orderRepository.findAllByUserOrderByLastModifiedDateDesc(any())).thenReturn(List.of(Order.builder().id("order-1").build())); + + // WHEN + List orderResponses = orderService.getAllOrderByUser(); + + // THEN + assertThat(orderResponses.getFirst()).isNotNull() + .hasFieldOrPropertyWithValue("id", "order-1"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getAllOrders_validRequest_success() { + // GIVEN + OrderFilter orderFilter = new OrderFilter(); + orderFilter.setStatus(EOrderStatus.PENDING); + + Pageable pageable = PageRequest.of(0, 5); + + Order order = new Order(); + order.setId("order-1"); + + Page orders = new PageImpl<>(List.of(order)); + when(orderRepository.findAll(any(Specification.class), eq(pageable))).thenReturn(orders); + + // WHEN + PaginationResponse result = orderService.getAllOrders(orderFilter, pageable); + + // THEN + assertThat(result).isNotNull() + .hasFieldOrPropertyWithValue("page", 1) + .hasFieldOrPropertyWithValue("total", 1L) + .hasFieldOrPropertyWithValue("itemsPerPage", 5) + .hasFieldOrPropertyWithValue("data", List.of(OrderAdminResponse.builder().id("order-1").build())); + } + + @Test + @WithMockUser(username = "user@test.com") + void getOrderById_validRequest_success() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(orderRepository.findByIdAndUser(any(), any())).thenReturn(Optional.of(Order.builder().id("order-1").build())); + + // WHEN + OrderResponse result = orderService.getOrderById("order-1"); + + // THEN + assertThat(result).isNotNull() + .hasFieldOrPropertyWithValue("id", "order-1"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getOrderByIdForAdmin_validRequest_success() { + // GIVEN + when(orderRepository.findById(any())).thenReturn(Optional.of(Order.builder().id("order-1").build())); + + // WHEN + OrderAdminResponse result = orderService.getOrderByIdForAdmin("order-1"); + + // THEN + assertThat(result).isNotNull() + .hasFieldOrPropertyWithValue("id", "order-1"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void updateOrderStatus_validRequest_success() { + // GIVEN + when(orderRepository.findById(any())).thenReturn(Optional.of(order)); + when(notificationRepository.save(any())).thenReturn(Notification.builder().id("notification-1").build()); + + // WHEN + orderService.updateOrderStatus("order-1", EOrderStatus.COMPLETED.name()); + + // THEN + verify(orderRepository, times(1)).save(any(Order.class)); + } + + } + + @Nested + class UnHappyCase { + @Test + @WithMockUser(username = "user@test.com") + void create_userNotFound_throwException() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.empty()); + + // WHEN + var exception = assertThrows(AppException.class, () -> orderService.create(orderRequest)); + + // THEN + assertThat(exception).isInstanceOf(AppException.class); + Assertions.assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1006); + + Assertions.assertThat(exception.getErrorCode().getMessage()) + .isEqualTo("User not found"); + } + + @Test + @WithMockUser(username = "user@test.com") + void create_cartItemNotFound_throwException() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(cartItemRepository.findAllByUserOrderByLastModifiedDateDesc(any())).thenReturn(List.of()); + + // WHEN + var exception = assertThrows(AppException.class, () -> orderService.create(orderRequest)); + + // THEN + assertThat(exception).isInstanceOf(AppException.class); + Assertions.assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1022); + + Assertions.assertThat(exception.getErrorCode().getMessage()) + .isEqualTo("Cart item not found"); + } + + @Test + @WithMockUser(username = "user@test.com") + void getOrderById_orderNotFound_throwException() { + // GIVEN + when(userRepository.findByEmail(any())).thenReturn(Optional.of(user)); + when(orderRepository.findByIdAndUser(any(), any())).thenReturn(Optional.empty()); + + // WHEN + var exception = assertThrows(AppException.class, () -> orderService.getOrderById("order-1")); + + // THEN + assertThat(exception).isInstanceOf(AppException.class); + Assertions.assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1023); + + Assertions.assertThat(exception.getErrorCode().getMessage()) + .isEqualTo("Order not found"); + } + } + +} diff --git a/src/test/java/com/learning/yasminishop/service/PermissionServiceTest.java b/src/test/java/com/learning/yasminishop/service/PermissionServiceTest.java index 70eea8f..fe60af6 100644 --- a/src/test/java/com/learning/yasminishop/service/PermissionServiceTest.java +++ b/src/test/java/com/learning/yasminishop/service/PermissionServiceTest.java @@ -8,6 +8,7 @@ import com.learning.yasminishop.permission.dto.response.PermissionResponse; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -50,50 +51,51 @@ void setUp() { } - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void createPermission_validRequest_success() { - // given - when(permissionRepository.save(any(Permission.class))).thenReturn(permission); - - // when - PermissionResponse response = permissionService.createPermission(permissionRequest); - - // then - assertThat(response).isNotNull(); - assertThat(response.getName()).isEqualTo("READ"); - assertThat(response.getDescription()).isEqualTo("Read permission"); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void getAllPermissions_validRequest_success() { - // given - when(permissionRepository.findAll()).thenReturn(List.of(permission)); - - // when - List response = permissionService.getALlPermissions(); - - // then - assertThat(response).isNotNull() - .isNotEmpty() - .hasSize(1); - + @Nested + class HappyCase { + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void createPermission_validRequest_success() { + // given + when(permissionRepository.save(any(Permission.class))).thenReturn(permission); + + // when + PermissionResponse response = permissionService.createPermission(permissionRequest); + + // then + assertThat(response).isNotNull(); + assertThat(response.getName()).isEqualTo("READ"); + assertThat(response.getDescription()).isEqualTo("Read permission"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getAllPermissions_validRequest_success() { + // given + when(permissionRepository.findAll()).thenReturn(List.of(permission)); + + // when + List response = permissionService.getALlPermissions(); + + // then + assertThat(response).isNotNull() + .isNotEmpty() + .hasSize(1); + + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void deletePermission_validRequest_success() { + // given + String permissionName = "READ"; + doNothing().when(permissionRepository).deleteById(permissionName); + + // when + permissionService.deletePermission(permissionName); + + // then + verify(permissionRepository, times(1)).deleteById(permissionName); + } } - - @Test -@WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) -void deletePermission_validRequest_success() { - // given - String permissionName = "READ"; - doNothing().when(permissionRepository).deleteById(permissionName); - - // when - permissionService.deletePermission(permissionName); - - // then - verify(permissionRepository, times(1)).deleteById(permissionName); -} - - } diff --git a/src/test/java/com/learning/yasminishop/service/ProductServiceTest.java b/src/test/java/com/learning/yasminishop/service/ProductServiceTest.java index 0ed514f..f8f08bc 100644 --- a/src/test/java/com/learning/yasminishop/service/ProductServiceTest.java +++ b/src/test/java/com/learning/yasminishop/service/ProductServiceTest.java @@ -16,6 +16,7 @@ import com.learning.yasminishop.storage.dto.response.StorageResponse; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -214,192 +215,195 @@ void setUp() { } + @Nested + class HappyCase { + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void createProduct_validRequest_success() { + // GIVEN + when(productRepository.existsBySlug(any())).thenReturn(false); + when(productRepository.existsBySku(any())).thenReturn(false); + when(categoryRepository.findAllById(Set.of("category1", "category2"))).thenReturn(List.of(category1, category2)); + when(storageRepository.findAllById(Set.of("image1", "image2"))).thenReturn(List.of(image1, image2)); + when(productMapper.toProduct(any())).thenReturn(product); + when(productRepository.save(product)).thenReturn(product); + when(productMapper.toProductAdminResponse(product)).thenReturn(productAdminResponse); + + // WHEN + ProductAdminResponse response = productService.create(productCreation); + + // THEN + assertThat(response).isNotNull() + .hasFieldOrPropertyWithValue("id", "product-1"); + + verify(categoryRepository).findAllById(Set.of("category1", "category2")); + verify(storageRepository).findAllById(Set.of("image1", "image2")); + verify(productRepository).save(product); + } + + @Test + void getBySlug_validSlug_success() { + // GIVEN + when(productRepository.findBySlug("product-1")).thenReturn(Optional.of(product)); + when(productMapper.toProductResponse(any())).thenReturn(productResponse); + + // WHEN + ProductResponse response = productService.getBySlug("product-1"); + + // THEN + assertThat(response).isNotNull() + .hasFieldOrPropertyWithValue("id", "product-1"); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getById_validId_success() { + // GIVEN + when(productRepository.findById(any())).thenReturn(Optional.of(product)); + when(productMapper.toProductAdminResponse(any())).thenReturn(productAdminResponse); + + // WHEN + ProductAdminResponse productAdminResponse1 = productService.getById("product-1"); + + // THEN + assertThat(productAdminResponse1).isNotNull() + .hasFieldOrPropertyWithValue("id", "product-1"); + + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getAllProductsForAdmin_validRequest_success() { + // GIVEN + + Pageable pageable = PageRequest.of(0, 5); + Page productPage = new PageImpl<>(List.of(product)); + + + when(categoryRepository.findAllById(anyList())).thenReturn(List.of(category1, category2)); + when(productRepository.findAll(any(Specification.class), eq(pageable))).thenReturn(productPage); + when(productMapper.toProductAdminResponse(any(Product.class))).thenReturn(productAdminResponse); + + // WHEN + PaginationResponse response = productService.getAllProductsForAdmin(productFilter, pageable); + + // THEN + assertThat(response).isNotNull(); + assertThat(response.getData().getFirst().getId()).isEqualTo("product-1"); + + verify(categoryRepository).findAllById(anyList()); + verify(productRepository).findAll(any(Specification.class), eq(pageable)); + verify(productMapper, times(1)).toProductAdminResponse(any(Product.class)); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void toggleAvailability_validRequest_success() { + // GIVEN + List ids = List.of("product-1", "product-2"); + + Product product1 = new Product(); + product1.setId("product-1"); + product1.setIsAvailable(true); + + Product product2 = new Product(); + product2.setId("product-2"); + product2.setIsAvailable(false); + + List products = List.of(product1, product2); + + when(productRepository.findAllById(ids)).thenReturn(products); + + // WHEN + productService.toggleAvailability(ids); + + // THEN + verify(productRepository).findAllById(ids); + verify(productRepository).saveAll(products); + + // Check that the availability of the products has been toggled + assertThat(product1.getIsAvailable()).isFalse(); + assertThat(product2.getIsAvailable()).isTrue(); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void update_validRequest_success() { + // GIVEN + String id = "product-1"; + + when(productRepository.findById(id)).thenReturn(Optional.of(product)); + when(categoryRepository.existsBySlug(productUpdate.getSlug())).thenReturn(false); + when(categoryRepository.existsBySlug(productUpdate.getSku())).thenReturn(false); + when(categoryRepository.findAllById(anySet())).thenReturn(categories); + when(storageRepository.findAllById(anySet())).thenReturn(images); + when(productRepository.save(any(Product.class))).thenReturn(product); + when(productMapper.toProductAdminResponse(any(Product.class))).thenReturn(productAdminResponse); + + // WHEN + ProductAdminResponse response = productService.update(id, productUpdate); + + // THEN + assertThat(response).isNotNull(); + assertThat(response.getId()).isEqualTo("product-1"); + + verify(productRepository).findById(id); + verify(categoryRepository).findAllById(anySet()); + verify(storageRepository).findAllById(anySet()); + verify(productRepository).save(any(Product.class)); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void delete_allProductIdsExistAndNoneInOrderOrCart_success() { + // GIVEN + List ids = List.of("product-1"); + product.setOrderItems(Set.of()); + product.setCartItems(Set.of()); + List products = List.of(product); - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void createProduct_validRequest_success() { - // GIVEN - when(productRepository.existsBySlug(any())).thenReturn(false); - when(productRepository.existsBySku(any())).thenReturn(false); - when(categoryRepository.findAllById(Set.of("category1", "category2"))).thenReturn(List.of(category1, category2)); - when(storageRepository.findAllById(Set.of("image1", "image2"))).thenReturn(List.of(image1, image2)); - when(productMapper.toProduct(any())).thenReturn(product); - when(productRepository.save(product)).thenReturn(product); - when(productMapper.toProductAdminResponse(product)).thenReturn(productAdminResponse); - - // WHEN - ProductAdminResponse response = productService.create(productCreation); - - // THEN - assertThat(response).isNotNull() - .hasFieldOrPropertyWithValue("id", "product-1"); - - verify(categoryRepository).findAllById(Set.of("category1", "category2")); - verify(storageRepository).findAllById(Set.of("image1", "image2")); - verify(productRepository).save(product); + when(productRepository.findAllById(ids)).thenReturn(products); + + // WHEN + productService.delete(ids); + + // THEN + verify(productRepository).findAllById(ids); + verify(productRepository).deleteAll(products); + } } - @Test - void getBySlug_validSlug_success() { - // GIVEN - when(productRepository.findBySlug("product-1")).thenReturn(Optional.of(product)); - when(productMapper.toProductResponse(any())).thenReturn(productResponse); - - // WHEN - ProductResponse response = productService.getBySlug("product-1"); - - // THEN - assertThat(response).isNotNull() - .hasFieldOrPropertyWithValue("id", "product-1"); + @Nested + class UnhappyCase { + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void delete_someProductIdsDoNotExist_throwsException() { + // GIVEN + List ids = List.of("product-1", "product-2"); + Product product1 = new Product(); + product1.setId("product-1"); + List products = List.of(product1); + + when(productRepository.findAllById(ids)).thenReturn(products); + + // THEN + assertThrows(AppException.class, () -> productService.delete(ids)); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void delete_productInOrderOrCart_throwsException() { + // GIVEN + List ids = List.of("product-1"); + Product product1 = new Product(); + product1.setId("product-1"); + product1.setOrderItems(Set.of(new OrderItem())); // product is in an order + List products = List.of(product1); + + when(productRepository.findAllById(ids)).thenReturn(products); + + // THEN + assertThrows(AppException.class, () -> productService.delete(ids)); + } } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void getById_validId_success() { - // GIVEN - when(productRepository.findById(any())).thenReturn(Optional.of(product)); - when(productMapper.toProductAdminResponse(any())).thenReturn(productAdminResponse); - - // WHEN - ProductAdminResponse productAdminResponse1 = productService.getById("product-1"); - - // THEN - assertThat(productAdminResponse1).isNotNull() - .hasFieldOrPropertyWithValue("id", "product-1"); - - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void getAllProductsForAdmin_validRequest_success() { - // GIVEN - - Pageable pageable = PageRequest.of(0, 5); - Page productPage = new PageImpl<>(List.of(product)); - - - when(categoryRepository.findAllById(anyList())).thenReturn(List.of(category1, category2)); - when(productRepository.findAll(any(Specification.class), eq(pageable))).thenReturn(productPage); - when(productMapper.toProductAdminResponse(any(Product.class))).thenReturn(productAdminResponse); - - // WHEN - PaginationResponse response = productService.getAllProductsForAdmin(productFilter, pageable); - - // THEN - assertThat(response).isNotNull(); - assertThat(response.getData().getFirst().getId()).isEqualTo("product-1"); - - verify(categoryRepository).findAllById(anyList()); - verify(productRepository).findAll(any(Specification.class), eq(pageable)); - verify(productMapper, times(1)).toProductAdminResponse(any(Product.class)); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void toggleAvailability_validRequest_success() { - // GIVEN - List ids = List.of("product-1", "product-2"); - - Product product1 = new Product(); - product1.setId("product-1"); - product1.setIsAvailable(true); - - Product product2 = new Product(); - product2.setId("product-2"); - product2.setIsAvailable(false); - - List products = List.of(product1, product2); - - when(productRepository.findAllById(ids)).thenReturn(products); - - // WHEN - productService.toggleAvailability(ids); - - // THEN - verify(productRepository).findAllById(ids); - verify(productRepository).saveAll(products); - - // Check that the availability of the products has been toggled - assertThat(product1.getIsAvailable()).isFalse(); - assertThat(product2.getIsAvailable()).isTrue(); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void update_validRequest_success() { - // GIVEN - String id = "product-1"; - - when(productRepository.findById(id)).thenReturn(Optional.of(product)); - when(categoryRepository.existsBySlug(productUpdate.getSlug())).thenReturn(false); - when(categoryRepository.existsBySlug(productUpdate.getSku())).thenReturn(false); - when(categoryRepository.findAllById(anySet())).thenReturn(categories); - when(storageRepository.findAllById(anySet())).thenReturn(images); - when(productRepository.save(any(Product.class))).thenReturn(product); - when(productMapper.toProductAdminResponse(any(Product.class))).thenReturn(productAdminResponse); - - // WHEN - ProductAdminResponse response = productService.update(id, productUpdate); - - // THEN - assertThat(response).isNotNull(); - assertThat(response.getId()).isEqualTo("product-1"); - - verify(productRepository).findById(id); - verify(categoryRepository).findAllById(anySet()); - verify(storageRepository).findAllById(anySet()); - verify(productRepository).save(any(Product.class)); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void delete_allProductIdsExistAndNoneInOrderOrCart_success() { - // GIVEN - List ids = List.of("product-1"); - product.setOrderItems(Set.of()); - product.setCartItems(Set.of()); - List products = List.of(product); - - when(productRepository.findAllById(ids)).thenReturn(products); - - // WHEN - productService.delete(ids); - - // THEN - verify(productRepository).findAllById(ids); - verify(productRepository).deleteAll(products); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void delete_someProductIdsDoNotExist_throwsException() { - // GIVEN - List ids = List.of("product-1", "product-2"); - Product product1 = new Product(); - product1.setId("product-1"); - List products = List.of(product1); - - when(productRepository.findAllById(ids)).thenReturn(products); - - // THEN - assertThrows(AppException.class, () -> productService.delete(ids)); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void delete_productInOrderOrCart_throwsException() { - // GIVEN - List ids = List.of("product-1"); - Product product1 = new Product(); - product1.setId("product-1"); - product1.setOrderItems(Set.of(new OrderItem())); // product is in an order - List products = List.of(product1); - - when(productRepository.findAllById(ids)).thenReturn(products); - - // THEN - assertThrows(AppException.class, () -> productService.delete(ids)); - } - - } diff --git a/src/test/java/com/learning/yasminishop/service/RatingServiceTest.java b/src/test/java/com/learning/yasminishop/service/RatingServiceTest.java new file mode 100644 index 0000000..6830b6e --- /dev/null +++ b/src/test/java/com/learning/yasminishop/service/RatingServiceTest.java @@ -0,0 +1,179 @@ +package com.learning.yasminishop.service; + +import com.learning.yasminishop.common.dto.PaginationResponse; +import com.learning.yasminishop.common.entity.Product; +import com.learning.yasminishop.common.entity.Rating; +import com.learning.yasminishop.common.entity.User; +import com.learning.yasminishop.common.exception.AppException; +import com.learning.yasminishop.product.ProductRepository; +import com.learning.yasminishop.rating.RatingRepository; +import com.learning.yasminishop.rating.RatingService; +import com.learning.yasminishop.rating.dto.request.RatingRequest; +import com.learning.yasminishop.rating.dto.response.RatingResponse; +import com.learning.yasminishop.user.UserRepository; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.TestPropertySource; + +import java.math.BigDecimal; +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertThrows; + + +@SpringBootTest +@Slf4j +@TestPropertySource("/test.properties") +class RatingServiceTest { + + @Autowired + private RatingService ratingService; + + @MockBean + private ProductRepository productRepository; + + @MockBean + private RatingRepository ratingRepository; + + @MockBean + private UserRepository userRepository; + + private RatingRequest ratingRequest; + private Product product; + private User user; + private Rating rating; + private Pageable pageable; + + @BeforeEach + void setUp() { + pageable = PageRequest.of(0, 5); + + ratingRequest = RatingRequest.builder() + .productId("product-1") + .star(5) + .comment("Review") + .build(); + + product = Product.builder() + .id("product-1") + .name("Product 1") + .description("Product 1 description") + .price(BigDecimal.valueOf(100)) + .quantity(10L) + .slug("product-1") + .sku("sku-1") + .isFeatured(true) + .isAvailable(true) + .build(); + user = User.builder() + .email("user@test.com") + .password("password") + .build(); + + rating = Rating.builder() + .id("rating-1") + .star(5) + .comment("Review") + .product(product) + .user(user) + .build(); + + } + + @Nested + class HappyCase { + + @Test + @WithMockUser(username = "user@test.com") + void create_validRequest_success() { + // GIVEN + when(productRepository.findById(anyString())).thenReturn(java.util.Optional.of(product)); + when(userRepository.findByEmail(anyString())).thenReturn(java.util.Optional.of(user)); + when(ratingRepository.existsByProductAndUser(any(), any())).thenReturn(false); + when(ratingRepository.save(any())).thenAnswer(invocation -> invocation.getArgument(0)); + + // WHEN + var result = ratingService.create(ratingRequest); + + // THEN + assertThat(result).isNotNull(); + assertThat(result.getStar()).isEqualTo(ratingRequest.getStar()); + assertThat(result.getComment()).isEqualTo(ratingRequest.getComment()); + } + + @Test + @WithMockUser(username = "user@test.com") + void getRatings_validRequest_success() { + // GIVEN + List ratings = List.of(rating); + Page ratingPage = new PageImpl<>(ratings, pageable, ratings.size()); + when(ratingRepository.findByProductOrderByCreatedDateDesc(any(), any())).thenReturn(ratingPage); + when(productRepository.findById(anyString())).thenReturn(java.util.Optional.of(product)); + + // WHEN + PaginationResponse result = ratingService.getRatings("product-1", pageable); + + // THEN + Assertions.assertThat(result).isNotNull(); + Assertions.assertThat(result.getData()).isNotEmpty(); + Assertions.assertThat(result.getData().getFirst().getStar()).isEqualTo(rating.getStar()); + Assertions.assertThat(result.getData().getFirst().getComment()).isEqualTo(rating.getComment()); + } + + } + + @Nested + class UnHappyCase { + @Test + @WithMockUser(username = "user@test.com") + void create_ratingAlreadyExists_exception() { + // GIVEN + when(productRepository.findById(anyString())).thenReturn(java.util.Optional.of(product)); + when(userRepository.findByEmail(anyString())).thenReturn(java.util.Optional.of(user)); + when(ratingRepository.existsByProductAndUser(any(), any())).thenReturn(true); + + // WHEN + var exception = assertThrows(AppException.class, () -> ratingService.create(ratingRequest)); + + + // THEN + assertThat(exception).isInstanceOf(AppException.class); + Assertions.assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1017); + + } + + @Test + @WithMockUser(username = "user@test.com") + void create_productNotFound_throwException() { + // GIVEN + when(productRepository.findById(anyString())).thenReturn(java.util.Optional.empty()); + + // WHEN + var exception = assertThrows(AppException.class, () -> ratingService.create(ratingRequest)); + + // THEN + assertThat(exception).isInstanceOf(AppException.class); + Assertions.assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1009); + } + + + } + + +} diff --git a/src/test/java/com/learning/yasminishop/service/RoleServiceTest.java b/src/test/java/com/learning/yasminishop/service/RoleServiceTest.java index cc3b7b6..8c17d81 100644 --- a/src/test/java/com/learning/yasminishop/service/RoleServiceTest.java +++ b/src/test/java/com/learning/yasminishop/service/RoleServiceTest.java @@ -10,6 +10,7 @@ import com.learning.yasminishop.role.dto.response.RoleResponse; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -20,6 +21,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; @@ -69,59 +71,61 @@ void setUp() { .build()); } - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void create_validRequest_success() { - // GIVEN - when(permissionRepository.findAllById(any())).thenReturn(permissionList); - when(roleRepository.save(any())).thenReturn(Role.builder() - .name("USER") - .description("User role") - .permissions(new HashSet<>(permissionList)) - .build()); - - // WHEN - RoleResponse response = roleService.create(roleRequest); - - // THEN - assertThat(response).isNotNull(); - assertThat(response.getName()).isEqualTo("USER"); - assertThat(response.getDescription()).isEqualTo("User role"); - assertThat(response.getPermissions()).isNotEmpty(); - assertThat(response.getPermissions()).hasSize(1); + @Nested + class HappyCase { + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void create_validRequest_success() { + // GIVEN + when(permissionRepository.findAllById(any())).thenReturn(permissionList); + when(roleRepository.save(any())).thenReturn(Role.builder() + .name("USER") + .description("User role") + .permissions(new HashSet<>(permissionList)) + .build()); + + // WHEN + RoleResponse response = roleService.create(roleRequest); + + // THEN + assertThat(response).isNotNull(); + assertThat(response.getName()).isEqualTo("USER"); + assertThat(response.getDescription()).isEqualTo("User role"); + assertThat(response.getPermissions()).isNotEmpty(); + assertThat(response.getPermissions()).hasSize(1); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void getAll_validRequest_success() { + // GIVEN + when(roleRepository.findAll()).thenReturn(List.of(Role.builder() + .name("USER") + .description("User role") + .permissions(new HashSet<>(permissionList)) + .build())); + + // WHEN + List response = roleService.getAll(); + + // THEN + assertThat(response).isNotNull() + .isNotEmpty() + .hasSize(1); + } + + @Test + @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) + void delete_validRequest_success() { + // GIVEN + doNothing().when(roleRepository).deleteById(anyString()); + + // WHEN + roleService.delete("USER"); + + // THEN + verify(roleRepository, times(1)).deleteById("USER"); + } } - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void getAll_validRequest_success() { - // GIVEN - when(roleRepository.findAll()).thenReturn(List.of(Role.builder() - .name("USER") - .description("User role") - .permissions(new HashSet<>(permissionList)) - .build())); - - // WHEN - List response = roleService.getAll(); - - // THEN - assertThat(response).isNotNull() - .isNotEmpty() - .hasSize(1); - } - - @Test - @WithMockUser(username = "admin@test.com", roles = {"ADMIN"}) - void delete_validRequest_success() { - // GIVEN - doNothing().when(roleRepository).deleteById(anyString()); - - // WHEN - roleService.delete("USER"); - - // THEN - verify(roleRepository, times(1)).deleteById("USER"); - } - - } diff --git a/src/test/java/com/learning/yasminishop/service/UserServiceTest.java b/src/test/java/com/learning/yasminishop/service/UserServiceTest.java index 00a3e36..5a095c3 100644 --- a/src/test/java/com/learning/yasminishop/service/UserServiceTest.java +++ b/src/test/java/com/learning/yasminishop/service/UserServiceTest.java @@ -15,6 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -48,8 +49,6 @@ class UserServiceTest { private User user; private UserUpdateRequest userUpdateRequest; - - @BeforeEach void setUp() { @@ -78,133 +77,141 @@ void setUp() { .build(); - - } - - @Test - @WithMockUser(username = "duongminhhieu@gmail.com") - void getMyInfo_validRequest_success() { - // Given - - when(userRepository.findByEmail(anyString())) - .thenReturn(Optional.of(user)); - - // When - var userResponse = userService.getMyInfo(); - - // Then - assertThat(userResponse) - .isNotNull() - .hasFieldOrPropertyWithValue("id", "abc-123") - .hasFieldOrPropertyWithValue("email", "duongminhhieu@gmail.com") - .hasFieldOrPropertyWithValue("firstName", "Hieu") - .hasFieldOrPropertyWithValue("lastName", "Duong") - .hasFieldOrPropertyWithValue("dob", LocalDate.of(1999, 1, 1)); - } - - @Test - @WithMockUser(username = "abc@gmail.com") - void getMyInfo_userNotFound_error() { - // Given - when(userRepository.findByEmail(anyString())) - .thenReturn(Optional.empty()); - - // When - var exception = assertThrows(AppException.class, () -> userService.getMyInfo()); - - // Then - assertThat(exception.getErrorCode().getInternalCode()) - .isEqualTo(1006); - assertThat(exception.getErrorCode().getMessage()) - .isEqualTo("User not found"); } - - @Test - @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) - void updateUser_validRequest_success() { - // Given - when(userRepository.findById(anyString())) - .thenReturn(Optional.of(user)); - - when(userRepository.save(user)) - .thenReturn(user); - - // When - var userResponse = userService.updateUser("abc-123", userUpdateRequest); - - // Then - assertThat(userResponse) - .isNotNull() - .hasFieldOrPropertyWithValue("id", "abc-123") - .hasFieldOrPropertyWithValue("firstName", "Hieu") - .hasFieldOrPropertyWithValue("lastName", "Duong") - - ; - assertThat(userResponse.getRoles()) - .containsExactlyInAnyOrder( - RoleResponse.builder() - .name("USER") - .description("User role") - .permissions(Set.of()) - .build(), - RoleResponse.builder() - .name("ADMIN") - .description("Admin role") - .permissions(Set.of()) - .build() - ); + @Nested + class HappyCase { + @Test + @WithMockUser(username = "duongminhhieu@gmail.com") + void getMyInfo_validRequest_success() { + // Given + + when(userRepository.findByEmail(anyString())) + .thenReturn(Optional.of(user)); + + // When + var userResponse = userService.getMyInfo(); + + // Then + assertThat(userResponse) + .isNotNull() + .hasFieldOrPropertyWithValue("id", "abc-123") + .hasFieldOrPropertyWithValue("email", "duongminhhieu@gmail.com") + .hasFieldOrPropertyWithValue("firstName", "Hieu") + .hasFieldOrPropertyWithValue("lastName", "Duong") + .hasFieldOrPropertyWithValue("dob", LocalDate.of(1999, 1, 1)); + } + + @Test + @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) + void updateUser_validRequest_success() { + // Given + when(userRepository.findById(anyString())) + .thenReturn(Optional.of(user)); + + when(userRepository.save(user)) + .thenReturn(user); + + // When + var userResponse = userService.updateUser("abc-123", userUpdateRequest); + + // Then + assertThat(userResponse) + .isNotNull() + .hasFieldOrPropertyWithValue("id", "abc-123") + .hasFieldOrPropertyWithValue("firstName", "Hieu") + .hasFieldOrPropertyWithValue("lastName", "Duong") + + ; + assertThat(userResponse.getRoles()) + .containsExactlyInAnyOrder( + RoleResponse.builder() + .name("USER") + .description("User role") + .permissions(Set.of()) + .build(), + RoleResponse.builder() + .name("ADMIN") + .description("Admin role") + .permissions(Set.of()) + .build() + ); + + } + + @Test + @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) + void deleteUser_valid_success() { + // Given + when(userRepository.existsById(anyString())) + .thenReturn(true); + // When + userService.deleteUser("abc-123"); + // Then + verify(userRepository, times(1)).deleteById("abc-123"); + } + + + @Test + @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) + void getUserById_valid_success() { + // Given + when(userRepository.findById(anyString())) + .thenReturn(Optional.of(user)); + // When + var response = userService.getUserById("abc-123"); + // Then + assertThat(response) + .isNotNull() + .hasFieldOrPropertyWithValue("id", "abc-123") + .hasFieldOrPropertyWithValue("email", "duongminhhieu@gmail.com") + .hasFieldOrPropertyWithValue("firstName", "Hieu") + .hasFieldOrPropertyWithValue("lastName", "Duong") + .hasFieldOrPropertyWithValue("dob", LocalDate.of(1999, 1, 1)); + + } } - @Test - @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) - void updateUser_notFoundUser_error() { - // Given - when(userRepository.findById(anyString())) - .thenReturn(Optional.empty()); - - // When - var exception = assertThrows(AppException.class, () -> userService.updateUser("abc-123", userUpdateRequest)); - - // Then - assertThat(exception.getErrorCode().getInternalCode()) - .isEqualTo(1006); - - assertThat(exception.getErrorCode().getMessage()) - .isEqualTo("User not found"); - } + @Nested + class UnHappyCase { + @Test + @WithMockUser(username = "abc@gmail.com") + void getMyInfo_userNotFound_error() { + // Given + when(userRepository.findByEmail(anyString())) + .thenReturn(Optional.empty()); + + // When + var exception = assertThrows(AppException.class, () -> userService.getMyInfo()); + + // Then + assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1006); + assertThat(exception.getErrorCode().getMessage()) + .isEqualTo("User not found"); + } + + @Test + @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) + void updateUser_notFoundUser_error() { + // Given + when(userRepository.findById(anyString())) + .thenReturn(Optional.empty()); + + // When + var exception = assertThrows(AppException.class, () -> userService.updateUser("abc-123", userUpdateRequest)); + + // Then + assertThat(exception.getErrorCode().getInternalCode()) + .isEqualTo(1006); + + assertThat(exception.getErrorCode().getMessage()) + .isEqualTo("User not found"); + } - @Test - @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) - void deleteUser_valid_success() { - // Given - when(userRepository.existsById(anyString())) - .thenReturn(true); - // When - userService.deleteUser("abc-123"); - // Then - verify(userRepository, times(1)).deleteById("abc-123"); } - @Test - @WithMockUser(username = "admin@spring.com", roles = {"ADMIN"}) - void getUserById_valid_success() { - // Given - when(userRepository.findById(anyString())) - .thenReturn(Optional.of(user)); - // When - var response = userService.getUserById("abc-123"); - // Then - assertThat(response) - .isNotNull() - .hasFieldOrPropertyWithValue("id", "abc-123") - .hasFieldOrPropertyWithValue("email", "duongminhhieu@gmail.com") - .hasFieldOrPropertyWithValue("firstName", "Hieu") - .hasFieldOrPropertyWithValue("lastName", "Duong") - .hasFieldOrPropertyWithValue("dob", LocalDate.of(1999, 1, 1)); - - } }