Skip to content

Commit

Permalink
#893 Unit test Rating (#912)
Browse files Browse the repository at this point in the history
* #893 Add unit test file

* #893 remove println

* #893 Update Code for SonarCloud checks

* #893 Remove @author
  • Loading branch information
NhatTranMinh15 authored Aug 21, 2024
1 parent 7206d1a commit 3192b51
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 8 deletions.
14 changes: 14 additions & 0 deletions rating/src/test/java/com/yas/rating/RatingApplicationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.yas.rating;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.ALWAYS)
class RatingApplicationTest {

@Test
void contextLoads() {
// It is suppose to be empty
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package com.yas.rating.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.yas.rating.RatingApplication;
import com.yas.rating.exception.NotFoundException;
import com.yas.rating.service.RatingService;
import com.yas.rating.utils.Constants;
import com.yas.rating.viewmodel.RatingListVm;
import com.yas.rating.viewmodel.RatingPostVm;
import com.yas.rating.viewmodel.RatingVm;
import com.yas.rating.viewmodel.ResponeStatusVm;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = RatingController.class)
@ContextConfiguration(classes = RatingApplication.class)
@AutoConfigureMockMvc(addFilters = false)
class RatingControllerTest {

@MockBean
private RatingService ratingService;

@Autowired
private MockMvc mockMvc;

private ObjectWriter objectWriter;
private RatingVm ratingVm;

@BeforeEach
void setUp() {
objectWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
ratingVm = new RatingVm(1L, "rating1", 5, 1L, "product1", "nhat1", "Nhat", "Tran", ZonedDateTime.now());
}

@Test
void testGetRatingListWithFilter() throws Exception {
String productName = "product1";
String customerName = "Nhat Tran";
String message = "comment 1";
ZonedDateTime createdFrom = ZonedDateTime.of(
LocalDate.of(1970, 1, 1),
LocalTime.of(0, 0),
ZoneId.systemDefault());
ZonedDateTime createdTo = ZonedDateTime.now();

when(ratingService.getRatingListWithFilter(
anyString(),
anyString(),
anyString(),
any(ZonedDateTime.class),
any(ZonedDateTime.class),
anyInt(),
anyInt())).thenReturn(new RatingListVm(List.of(), 0, 0));

this.mockMvc.perform(get("/backoffice/ratings")
.contentType(MediaType.APPLICATION_JSON)
.param("productName", productName)
.param("customerName", customerName)
.param("message", message)
.param("createdFrom", createdFrom.toString())
.param("createdTo", createdTo.toString())
.param("pageNo", "0")
.param("pageSize", "10")
)
.andExpect(status().isOk());
}

@Test
void testDeleteRating_WhenValidId_ShouldReturn200() throws Exception {
when(ratingService.deleteRating(anyLong())).thenReturn(new ResponeStatusVm(
"Delete Rating",
Constants.Message.SUCCESS_MESSAGE,
HttpStatus.OK.toString())
);

this.mockMvc.perform(delete("/backoffice/ratings/{id}", 1)
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk());

verify(ratingService, times(1)).deleteRating(anyLong());
}

@Test
void testDeleteRating_WhenInvalidId_ShouldReturn404() throws Exception {
when(ratingService.deleteRating(1L))
.thenThrow(new NotFoundException(Constants.ErrorCode.RATING_NOT_FOUND, 1L));
this.mockMvc.perform(delete("/backoffice/ratings/{id}", 1)
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isNotFound())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.jsonPath("$.statusCode", Matchers.is("404 NOT_FOUND")))
.andExpect(MockMvcResultMatchers.jsonPath("$.title", Matchers.is("NotFound")))
.andExpect(MockMvcResultMatchers.jsonPath("$.detail", Matchers.is("RATING 1 is not found")));

verify(ratingService, times(1)).deleteRating(anyLong());
}

@Test
void testStorefrontGetRatingList_ShouldReturnList() throws Exception {
when(ratingService.getRatingListByProductId(anyLong(), anyInt(), anyInt()))
.thenReturn(new RatingListVm(List.of(), 0, 0));

this.mockMvc.perform(get("/storefront/ratings/products/{productId}", 1)
.contentType(MediaType.APPLICATION_JSON)
.param("pageNo", "0")
.param("pageSize", "10")
)
.andExpect(status().isOk());
}

@Test
void TestCreateRating_WhenValid_ShouldSuccess() throws Exception {
RatingPostVm vm = new RatingPostVm("rating1", 5, 1L, "product1");

when(ratingService.createRating(any(RatingPostVm.class))).thenReturn(ratingVm);

this.mockMvc.perform(post("/storefront/ratings")
.contentType(MediaType.APPLICATION_JSON)
.content(objectWriter.writeValueAsString(vm))
)
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.is(1)));
}

@Test
void TestGetAverageStarOfProduct_ShouldReturnSuccess() throws Exception {
when(ratingService.calculateAverageStar(anyLong())).thenReturn(0.0D);
this.mockMvc.perform(get("/storefront/ratings/product/{productId}/average-star", 1L)
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(content().string("0.0"));
}

}
79 changes: 71 additions & 8 deletions rating/src/test/java/com/yas/rating/service/RatingServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.yas.rating.service;

import com.yas.rating.RatingApplication;
import com.yas.rating.exception.AccessDeniedException;
import com.yas.rating.exception.NotFoundException;
import com.yas.rating.exception.ResourceExistedException;
import com.yas.rating.model.Rating;
import com.yas.rating.repository.RatingRepository;
import com.yas.rating.viewmodel.CustomerVm;
import com.yas.rating.viewmodel.OrderExistsByProductAndUserGetVm;
import com.yas.rating.viewmodel.RatingListVm;
import com.yas.rating.viewmodel.RatingPostVm;
import com.yas.rating.viewmodel.RatingVm;
import com.yas.rating.viewmodel.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -24,12 +23,15 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@SpringBootTest(classes = RatingApplication.class)
class RatingServiceTest {

private final String userId = "user1";
@Autowired
private RatingRepository ratingRepository;
@MockBean
Expand All @@ -39,7 +41,6 @@ class RatingServiceTest {
@Autowired
private RatingService ratingService;
private List<Rating> ratingList;
private String userId = "user1";

@BeforeEach
void setUp() {
Expand Down Expand Up @@ -70,12 +71,12 @@ void setUp() {
.build()
);
ratingRepository.saveAll(ratingList);

}

@AfterEach
void tearDown() {
ratingRepository.deleteAll();
SecurityContextHolder.clearContext();
}

@Test
Expand All @@ -90,6 +91,17 @@ void getRatingList_ValidProductId_ShouldSuccess() {
assertEquals(2, actualResponse.ratingList().size());
}

@Test
void getRatingList_NotExistedProductId_ShouldReturnEmptyList() {
int pageNo = 0;
int pageSize = 10;

RatingListVm actualResponse = ratingService.getRatingListByProductId(0L, pageNo, pageSize);
assertEquals(0, actualResponse.ratingList().size());
assertEquals(0, actualResponse.totalPages());
assertEquals(0, actualResponse.totalElements());
}

@Test
void getRatingListWithFilter_ValidFilterData_ShouldReturnSuccess() {
String proName = "product2";
Expand Down Expand Up @@ -119,7 +131,8 @@ void createRating_ValidRatingData_ShouldSuccess() {
when(authentication.getToken()).thenReturn(jwt);
when(authentication.getName()).thenReturn(userId);
when(jwt.getSubject()).thenReturn(userId);
when(orderService.checkOrderExistsByProductAndUserWithStatus(anyLong())).thenReturn(new OrderExistsByProductAndUserGetVm(true));
when(orderService.checkOrderExistsByProductAndUserWithStatus(anyLong())).
thenReturn(new OrderExistsByProductAndUserGetVm(true));
when(customerService.getCustomer()).thenReturn(new CustomerVm(userId, null, "Cuong", "Tran"));

RatingPostVm ratingPostVm = RatingPostVm.builder().content("comment 4").productName("product3").star(4).productId(3L).build();
Expand All @@ -129,6 +142,43 @@ void createRating_ValidRatingData_ShouldSuccess() {
assertEquals(ratingPostVm.star(), ratingVm.star());
}

@Test
void createRating_InvalidAuthorization_ShouldThrowAccessDeniedException() {
RatingPostVm ratingPostVm = RatingPostVm.builder().content("comment 4").productName("product3").star(4).productId(3L).build();

Jwt jwt = mock(Jwt.class);
JwtAuthenticationToken authentication = mock(JwtAuthenticationToken.class);
SecurityContextHolder.getContext().setAuthentication(authentication);
when(authentication.getToken()).thenReturn(jwt);
when(authentication.getName()).thenReturn(userId);
when(jwt.getSubject()).thenReturn(userId);
when(orderService.checkOrderExistsByProductAndUserWithStatus(anyLong())).thenReturn(new OrderExistsByProductAndUserGetVm(false));

AccessDeniedException exception = assertThrows(AccessDeniedException.class,
() -> ratingService.createRating(ratingPostVm));

assertEquals("ACCESS_DENIED", exception.getMessage());
}

@Test
void createRating_ExistedRating_ShouldThrowResourceExistedException() {
RatingPostVm ratingPostVm = RatingPostVm.builder().productId(1L).content("comment 4").productName("product3").star(4).build();

Jwt jwt = mock(Jwt.class);
JwtAuthenticationToken authentication = mock(JwtAuthenticationToken.class);
SecurityContextHolder.getContext().setAuthentication(authentication);
when(authentication.getToken()).thenReturn(jwt);
when(authentication.getName()).thenReturn("");
when(jwt.getSubject()).thenReturn("");

when(orderService.checkOrderExistsByProductAndUserWithStatus(anyLong())).thenReturn(new OrderExistsByProductAndUserGetVm(true));

ResourceExistedException exception = assertThrows(ResourceExistedException.class,
() -> ratingService.createRating(ratingPostVm));

assertEquals("Resource already existed", exception.getMessage());
}

@Test
void deleteRating_ValidRatingId_ShouldSuccess() {
Long id = ratingRepository.findAll().getFirst().getId();
Expand All @@ -137,9 +187,22 @@ void deleteRating_ValidRatingId_ShouldSuccess() {
assertFalse(rating.isPresent());
}

@Test
void deleteRating_InvalidRatingId_ShouldThrowNotFoundException() {
NotFoundException exception = assertThrows(NotFoundException.class,
() -> ratingService.deleteRating(0L));
assertEquals("RATING 0 is not found", exception.getMessage());
}

@Test
void calculateAverageStar_ValidProductId_ShouldSuccess() {
Double averageStar = ratingService.calculateAverageStar(1L);
assertEquals(3, averageStar);
}

@Test
void calculateAverageStar_InvalidProductId_ShouldReturnZero() {
Double averageStar = ratingService.calculateAverageStar(0L);
assertEquals(0, averageStar);
}
}

0 comments on commit 3192b51

Please sign in to comment.