Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public record CocktailCommentResponseDto(
Long commentId,
Long postId,
Long cocktailId,
String userNickName,
LocalDateTime createdAt,
LocalDateTime updatedAt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public RsData<List<CocktailSearchResponseDto>> searchAndFilter(
// ์„œ๋น„์Šค ํ˜ธ์ถœ
List<CocktailSearchResponseDto> searchResults = cocktailService.searchAndFilter(cocktailSearchRequestDto);

// RsData๋กœ ํ†ต์ผ๋œ ์‘๋‹ต ๋ฐ˜ํ™˜
return RsData.successOf(searchResults);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public ResponseEntity<RsData<Map<String, String>>> getShareLink(@PathVariable Lo
.map(cocktail -> {
Map<String, String> response = Map.of(
// ๊ณต์œ  URL
"url", "https://www.ssoul.o-r.kr/cocktails/" + cocktail.getId(),
"url", "https://www.ssoul.life/cocktails/" + cocktail.getId(),
// ๊ณต์œ  ์ œ๋ชฉ
"title", cocktail.getCocktailName(),
// ๊ณต์œ  ์ด๋ฏธ์ง€ (์„ ํƒ)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package com.back.domain.cocktail.comment.controller;

import com.back.domain.cocktail.comment.dto.CocktailCommentCreateRequestDto;
import com.back.domain.cocktail.comment.dto.CocktailCommentResponseDto;
import com.back.domain.cocktail.comment.dto.CocktailCommentUpdateRequestDto;
import com.back.domain.cocktail.comment.service.CocktailCommentService;
import com.back.domain.post.comment.enums.CommentStatus;
import com.back.global.jwt.JwtUtil;
import com.back.global.rq.Rq;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
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.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willDoNothing;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(CocktailCommentController.class)
@AutoConfigureMockMvc(addFilters = false)
public class CocktailCommentControllerTest {

@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockitoBean
private CocktailCommentService cocktailCommentService;
@MockitoBean
private JwtUtil jwtUtil;
@MockitoBean
private Rq rq;

private CocktailCommentResponseDto createSampleResponseDto(Long id) {
return new CocktailCommentResponseDto(
id,
1L,
"ํ…Œ์ŠคํŠธ์œ ์ €" + id,
LocalDateTime.now(),
LocalDateTime.now(),
CommentStatus.PUBLIC,
"ํ…Œ์ŠคํŠธ ๋‚ด์šฉ" + id
);
}

@Test
@DisplayName("์นตํ…Œ์ผ ๋Œ“๊ธ€ ์ž‘์„ฑ API ํ…Œ์ŠคํŠธ")
void t1() throws Exception {
// given
CocktailCommentCreateRequestDto requestDto = new CocktailCommentCreateRequestDto(
CommentStatus.PUBLIC,
"ํ…Œ์ŠคํŠธ ๋‚ด์šฉ1"
);
CocktailCommentResponseDto responseDto = createSampleResponseDto(1L);
given(cocktailCommentService.createCocktailComment(anyLong(), any(CocktailCommentCreateRequestDto.class))).willReturn(responseDto);

// when & then
mockMvc.perform(post("/cocktails/{cocktailId}/comments", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.commentId").value(1L))
.andExpect(jsonPath("$.data.cocktailId").value(1L))
.andExpect(jsonPath("$.data.userNickName").value("ํ…Œ์ŠคํŠธ์œ ์ €1"))
.andExpect(jsonPath("$.data.status").value("PUBLIC"))
.andExpect(jsonPath("$.data.content").value("ํ…Œ์ŠคํŠธ ๋‚ด์šฉ1"))
.andDo(print());
}

@Test
@DisplayName("์นตํ…Œ์ผ ๋Œ“๊ธ€ ๋‹ค๊ฑด ์กฐํšŒ API ํ…Œ์ŠคํŠธ")
void t2() throws Exception {
// given
List<CocktailCommentResponseDto> firstPage = new ArrayList<>();
for (long i = 30; i >= 21; i--) {
firstPage.add(createSampleResponseDto(i));
}

List<CocktailCommentResponseDto> secondPage = new ArrayList<>();
for (long i = 20; i >= 11; i--) {
secondPage.add(createSampleResponseDto(i));
}

given(cocktailCommentService.getCocktailComments(1L, null)).willReturn(firstPage); // ์ฒซ ํ˜ธ์ถœ(lastId ์—†์Œ)
given(cocktailCommentService.getCocktailComments(1L, 21L)).willReturn(secondPage);

// when & then
mockMvc.perform(get("/cocktails/{cocktailId}/comments", 1L))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data", hasSize(10)))
.andExpect(jsonPath("$.data[0].commentId").value(30))
.andExpect(jsonPath("$.data[0].cocktailId").value(1L))
.andExpect(jsonPath("$.data[0].userNickName").value("ํ…Œ์ŠคํŠธ์œ ์ €30"))
.andExpect(jsonPath("$.data[0].status").value("PUBLIC"))
.andExpect(jsonPath("$.data[0].content").value("ํ…Œ์ŠคํŠธ ๋‚ด์šฉ30"))
.andDo(print());

mockMvc.perform(get("/cocktails/{cocktailId}/comments", 1L).param("lastId", "21"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data", hasSize(10)))
.andExpect(jsonPath("$.data[0].commentId").value(20))
.andExpect(jsonPath("$.data[0].cocktailId").value(1L))
.andExpect(jsonPath("$.data[0].userNickName").value("ํ…Œ์ŠคํŠธ์œ ์ €20"))
.andExpect(jsonPath("$.data[0].status").value("PUBLIC"))
.andExpect(jsonPath("$.data[0].content").value("ํ…Œ์ŠคํŠธ ๋‚ด์šฉ20"))
.andDo(print());
}

@Test
@DisplayName("์นตํ…Œ์ผ ๋Œ“๊ธ€ ๋‹จ๊ฑด ์กฐํšŒ API ํ…Œ์ŠคํŠธ")
void t3() throws Exception {
// given
Long cocktailId = 1L;
Long cocktailCommentId = 1L;
CocktailCommentResponseDto responseDto = createSampleResponseDto(cocktailCommentId);
given(cocktailCommentService.getCocktailComment(cocktailId, cocktailCommentId)).willReturn(responseDto);

// when & then
mockMvc.perform(get("/cocktails/{cocktailId}/comments/{cocktailCommentId}", cocktailId, cocktailCommentId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.commentId").value(cocktailCommentId))
.andExpect(jsonPath("$.data.cocktailId").value(cocktailId))
.andExpect(jsonPath("$.data.userNickName").value("ํ…Œ์ŠคํŠธ์œ ์ €1"))
.andExpect(jsonPath("$.data.status").value("PUBLIC"))
.andExpect(jsonPath("$.data.content").value("ํ…Œ์ŠคํŠธ ๋‚ด์šฉ1"))
.andDo(print());
}

@Test
@DisplayName("์นตํ…Œ์ผ ๋Œ“๊ธ€ ์ˆ˜์ • API ํ…Œ์ŠคํŠธ")
void t4() throws Exception {
// given
Long cocktailId = 1L;
Long cocktailCommentId = 1L;

CocktailCommentUpdateRequestDto requestDto = new CocktailCommentUpdateRequestDto(
CommentStatus.PUBLIC,
"์ˆ˜์ •๋œ ๋‚ด์šฉ" + cocktailCommentId
);

CocktailCommentResponseDto responseDto = new CocktailCommentResponseDto(
cocktailCommentId,
cocktailId,
"ํ…Œ์ŠคํŠธ์œ ์ €" + cocktailCommentId,
LocalDateTime.now(),
LocalDateTime.now(),
CommentStatus.PUBLIC,
"์ˆ˜์ •๋œ ๋‚ด์šฉ" + cocktailCommentId
);

given(cocktailCommentService.updateCocktailComment(eq(cocktailId), eq(cocktailCommentId), any(CocktailCommentUpdateRequestDto.class)))
.willReturn(responseDto);

// when & then
mockMvc.perform(patch("/cocktails/{cocktailId}/comments/{cocktailCommentId}", cocktailId, cocktailCommentId)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.commentId").value(cocktailCommentId))
.andExpect(jsonPath("$.data.cocktailId").value(cocktailId))
.andExpect(jsonPath("$.data.userNickName").value("ํ…Œ์ŠคํŠธ์œ ์ €" + cocktailCommentId))
.andExpect(jsonPath("$.data.status").value("PUBLIC"))
.andExpect(jsonPath("$.data.content").value("์ˆ˜์ •๋œ ๋‚ด์šฉ" + cocktailCommentId))
.andDo(print());
}

@Test
@DisplayName("์นตํ…Œ์ผ ๋Œ“๊ธ€ ์‚ญ์ œ API ํ…Œ์ŠคํŠธ")
void t5() throws Exception {
// given
Long cocktailId = 1L;
Long cocktailCommentId = 1L;

willDoNothing().given(cocktailCommentService).deleteCocktailComment(cocktailId, cocktailCommentId);

// when & then
mockMvc.perform(delete("/cocktails/{cocktailId}/comments/{cocktailCommentId}", cocktailId, cocktailCommentId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("success"))
.andExpect(jsonPath("$.data").value(nullValue())) // null ์ด๋ฏ€๋กœ empty ์ฒดํฌ ๊ฐ€๋Šฅ
.andDo(print());

// ์ถ”๊ฐ€ ๊ฒ€์ฆ: ์„œ๋น„์Šค ๋ฉ”์†Œ๋“œ๊ฐ€ ์ •ํ™•ํžˆ ํ˜ธ์ถœ๋๋Š”์ง€ ํ™•์ธ
verify(cocktailCommentService).deleteCocktailComment(cocktailId, cocktailCommentId);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.back.domain.cocktail.controller;

import com.back.domain.cocktail.dto.CocktailSearchRequestDto;
import com.back.domain.cocktail.entity.Cocktail;
import com.back.domain.cocktail.enums.AlcoholBaseType;
import com.back.domain.cocktail.enums.AlcoholStrength;
import com.back.domain.cocktail.enums.CocktailType;
import com.back.domain.cocktail.repository.CocktailRepository;
import com.back.domain.user.service.UserService;
import com.back.global.rq.Rq;
import com.back.global.standard.util.Ut;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -27,6 +29,7 @@
import java.time.LocalDateTime;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
Expand Down Expand Up @@ -138,6 +141,47 @@ void t4() throws Exception {
.andExpect(jsonPath("$.data").isArray());
}

@Test
@DisplayName("์นตํ…Œ์ผ ๊ฒ€์ƒ‰ ๋ฐ ํ•„ํ„ฐ๋ง")
void t5() throws Exception {
// given: DB์— ์นตํ…Œ์ผ ์ €์žฅ
Cocktail savedCocktail = cocktailRepository.save(
Cocktail.builder()
.cocktailName("๋ชจํžˆํ† ")
.alcoholStrength(AlcoholStrength.WEAK)
.cocktailType(CocktailType.SHORT)
.alcoholBaseType(AlcoholBaseType.RUM)
.cocktailImgUrl("https://example.com/image.jpg")
.cocktailStory("์ƒ์พŒํ•œ ๋ผ์ž„๊ณผ ๋ฏผํŠธ")
.ingredient("๋ผ์ž„, ๋ฏผํŠธ, ๋Ÿผ, ์„คํƒ•, ํƒ„์‚ฐ์ˆ˜")
.recipe("๋ผ์ž„๊ณผ ๋ฏผํŠธ๋ฅผ ์„ž๊ณ  ๋Ÿผ์„ ๋„ฃ๊ณ  ํƒ„์‚ฐ์ˆ˜๋กœ ์™„์„ฑ")
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build()
);

// ๊ฒ€์ƒ‰ ์กฐ๊ฑด (ํ‚ค์›Œ๋“œ: "๋ชจํžˆํ† ")
CocktailSearchRequestDto requestDto = new CocktailSearchRequestDto();
requestDto.setKeyword("๋ชจํžˆํ† ");

// when: POST ์š”์ฒญ
ResultActions resultActions = mvc.perform(
post("/cocktails/search")
.contentType(MediaType.APPLICATION_JSON)
.content(Ut.json.toString(requestDto))
).andDo(print());

// then: ์ƒํƒœ์ฝ”๋“œ, JSON ๊ตฌ์กฐ ๊ฒ€์ฆ
resultActions
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.message").value("success"))
.andExpect(jsonPath("$.data[0].cocktailName").value("๋ชจํžˆํ† "))
.andExpect(jsonPath("$.data[0].alcoholStrength").value("WEAK"))
.andExpect(jsonPath("$.data[0].cocktailType").value("SHORT"))
.andExpect(jsonPath("$.data[0].alcoholBaseType").value("RUM"));
}

@TestConfiguration
static class TestConfig {
@Bean
Expand All @@ -149,5 +193,4 @@ public Rq rq() {
return new Rq(req, resp, userService);
}
}

}