Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/answer/#39 #108

Merged
merged 14 commits into from
May 23, 2024
Merged
7 changes: 6 additions & 1 deletion .github/workflows/build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ jobs:

- name: Create and configure application.yml
run: |
mkdir -p baebae-BE/src/main/resources
mkdir -p baebae-BE/src/test/resources
echo "${{ secrets.APPLICATION_YML }}" > baebae-BE/src/main/resources/application.yml
echo "${{ secrets.APPLICATION_DEPLOY_YML }}" > baebae-BE/src/main/resources/application-deploy.yml
echo "${{ secrets.TEST_APPLICATION_YML }}" > baebae-BE/src/test/resources/application.yml
echo "${{ secrets.APPLICATION_TEST_YML }}" > baebae-BE/src/test/resources/application-test.yml


- name: Build with Gradle
run: |
cd baebae-BE
chmod +x ./gradlew
./gradlew build
./gradlew build --quiet
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ public class Question {
@Column(name = "is_answered", nullable = false)
private boolean isAnswered;

public void updateContent(String content) {
this.content = content;

}


public static Question of(Long id, Member sender, Member receiver, String content, String nickname, Boolean profileOnOff,
LocalDateTime createdDate, Boolean isAnswered) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
package com.web.baebaeBE.integration.answer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.web.baebaeBE.config.jwt.JwtFactory;
import com.web.baebaeBE.domain.answer.dto.AnswerCreateRequest;
import com.web.baebaeBE.domain.answer.dto.AnswerDetailResponse;
import com.web.baebaeBE.domain.answer.dto.AnswerResponse;
import com.web.baebaeBE.domain.answer.entity.Answer;
import com.web.baebaeBE.domain.answer.repository.AnswerRepository;
import com.web.baebaeBE.domain.answer.service.AnswerService;
import com.web.baebaeBE.domain.member.entity.Member;
import com.web.baebaeBE.domain.member.entity.MemberType;
import com.web.baebaeBE.domain.member.repository.MemberRepository;
import com.web.baebaeBE.domain.music.entity.Music;
import com.web.baebaeBE.domain.oauth2.controller.Oauth2Controller;
import com.web.baebaeBE.domain.oauth2.service.KakaoClient;
import com.web.baebaeBE.domain.oauth2.service.Oauth2Service;
import com.web.baebaeBE.domain.question.entity.Question;
import com.web.baebaeBE.domain.question.repository.QuestionJpaRepository;
import com.web.baebaeBE.domain.question.repository.QuestionRepository;
import com.web.baebaeBE.domain.reactioncount.entity.ReactionCount;
import com.web.baebaeBE.global.authorization.aspect.AuthPolicyAspect;
import com.web.baebaeBE.global.jwt.JwtProperties;
import com.web.baebaeBE.global.jwt.JwtTokenProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -27,6 +36,10 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
Expand All @@ -35,12 +48,11 @@

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand All @@ -50,7 +62,7 @@

@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@ActiveProfiles("test")
@WithMockUser
public class AnswerTest {
@Autowired
Expand All @@ -68,57 +80,74 @@ public class AnswerTest {
@MockBean
private AnswerService answerService;

@MockBean
private AnswerRepository answerRepository;

@Autowired
private JwtTokenProvider tokenProvider;

@MockBean
private KakaoClient kakaoClient;
@MockBean
private Oauth2Service oauth2Service;
@MockBean
private Oauth2Controller oauth2Controller;

@Autowired
private JwtProperties jwtProperties;
@Autowired
private final ObjectMapper objectMapper = new ObjectMapper();
private Member testMember;
private Member testReceiver;
private String refreshToken;
private Question testQuestion;
private Answer testAnswer;

@BeforeEach
void setup() {
// Mock 객체 초기화
testMember = Member.builder()
.id(1L)
.email("[email protected]")
.nickname("장지효")
.memberType(MemberType.KAKAO)
.refreshToken("null")
.build();

testReceiver = Member.builder()
.id(2L)
.email("[email protected]")
.nickname("장지효2")
.memberType(MemberType.KAKAO)
.refreshToken("null")
.build();

// memberRepository.save() 메서드를 목킹하여 호출된 객체를 반환하도록 설정
when(memberRepository.save(any(Member.class))).thenAnswer(invocation -> invocation.getArgument(0));

// testMember와 testReceiver를 저장
testMember = memberRepository.save(testMember);
testReceiver = memberRepository.save(testReceiver);
when(memberRepository.save(any(Member.class))).thenReturn(testMember);
when(memberRepository.findByEmail("[email protected]")).thenReturn(Optional.of(testMember));
when(memberRepository.findById(1L)).thenReturn(Optional.of(testMember));

// 토큰 생성 및 업데이트
refreshToken = tokenProvider.generateToken(testMember, Duration.ofDays(14));
testMember.updateRefreshToken(refreshToken);
memberRepository.save(testMember);
when(memberRepository.save(any(Member.class))).thenReturn(testReceiver);
when(memberRepository.findByEmail("[email protected]")).thenReturn(Optional.of(testReceiver));
when(memberRepository.findById(1L)).thenReturn(Optional.of(testReceiver));

refreshToken = tokenProvider.generateToken(testMember, Duration.ofDays(14)); // 임시 refreshToken 생성
refreshToken = tokenProvider.generateToken(testReceiver, Duration.ofDays(14));

testMember.updateRefreshToken(refreshToken);
when(memberRepository.save(testMember)).thenReturn(testMember);

testReceiver.updateRefreshToken(refreshToken);
memberRepository.save(testReceiver);
when(memberRepository.save(testReceiver)).thenReturn(testReceiver);

when(memberRepository.findByRefreshToken(refreshToken)).thenReturn(Optional.of(testMember));
when(memberRepository.findByRefreshToken(refreshToken)).thenReturn(Optional.of(testReceiver));

// memberRepository.save() 메서드를 목킹하여 호출된 객체를 반환하도록 설정
when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0));

// testQuestion 저장
testQuestion = questionRepository.save(new Question(null, testMember, testReceiver, "이것은 질문입니다.", "장지효", true, LocalDateTime.now(), false));

}

@AfterEach
Expand All @@ -137,14 +166,14 @@ public void createAnswerTest() throws Exception {
MockMultipartFile imageFile = new MockMultipartFile("imageFile", "image.jpg", MediaType.IMAGE_JPEG_VALUE, "image content".getBytes());
MockMultipartFile requestFile = new MockMultipartFile("request", "", MediaType.APPLICATION_JSON_VALUE, objectMapper.writeValueAsBytes(createRequest));

when(answerService.createAnswer(any(AnswerCreateRequest.class), eq(1L), any(MockMultipartFile.class)))
when(answerService.createAnswer(any(AnswerCreateRequest.class), eq(testMember.getId()), any(MockMultipartFile.class)))
.thenReturn(new AnswerDetailResponse(
1L, testQuestion.getId(), testQuestion.getContent(),1L, "이것은 답변입니다.",
testMember.getNickname(), "안녕",true, "https://link.com", "노래 제목", "가수 이름", "https://audio.url",
1L, testQuestion.getId(), testQuestion.getContent(), 1L, "이것은 답변입니다.",
testMember.getNickname(), "안녕", true, "https://link.com", "노래 제목", "가수 이름", "https://audio.url",
"https://image.url", LocalDateTime.now()
));

mockMvc.perform(MockMvcRequestBuilders.multipart("/api/answers/{memberId}", 1L)
mockMvc.perform(MockMvcRequestBuilders.multipart("/api/answers/{memberId}", testMember.getId())
.file(imageFile)
.file(requestFile)
.header("Authorization", "Bearer " + refreshToken)
Expand Down Expand Up @@ -181,7 +210,7 @@ public void getAllAnswersTest() throws Exception {
.andExpect(status().isOk())
.andExpect(jsonPath("$.content[0].content").value("이것은 답변입니다."));
}

/*
@Test
@DisplayName("답변 수정 테스트(): 답변을 수정한다.")
public void updateAnswerTest() throws Exception {
Expand All @@ -195,15 +224,16 @@ public void updateAnswerTest() throws Exception {

AnswerDetailResponse answerDetailResponse = new AnswerDetailResponse(
1L, testQuestion.getId(), testQuestion.getContent(), testMember.getId(), "이것은 수정된답변입니다.",
testMember.getNickname(), "안녕",true, "https://link.com", "노래 제목", "가수 이름", "https://audio.url",
testMember.getNickname(), "안녕", true, "https://link.com", "노래 제목", "가수 이름", "https://audio.url",
"https://image.url", LocalDateTime.now()
);

// When
// Mock 설정
when(answerRepository.findByAnswerId(1L)).thenReturn(Optional.of(testAnswer));
when(answerService.updateAnswer(eq(1L), any(AnswerCreateRequest.class), any(MockMultipartFile.class)))
.thenReturn(answerDetailResponse);

// Then
// When
mockMvc.perform(MockMvcRequestBuilders.multipart(HttpMethod.PUT, "/api/answers/{answerId}", 1L)
.file(imageFile)
.file(requestFile)
Expand All @@ -218,18 +248,41 @@ public void updateAnswerTest() throws Exception {
.andExpect(jsonPath("$.musicSinger").value("가수 이름"))
.andExpect(jsonPath("$.musicAudioUrl").value("https://audio.url"))
.andExpect(jsonPath("$.imageUrl").value("https://image.url"));

}


@Test
@DisplayName("답변 삭제 테스트(): 답변을 삭제한다.")
public void deleteAnswerTest() throws Exception {
// Given
Music music = Music.builder()
.musicName("노래 제목")
.musicSinger("가수 이름")
.musicAudioUrl("https://audio.url")
.build();

testAnswer = Answer.builder()
.id(1L)
.question(testQuestion)
.member(testMember)
.content("이것은 답변입니다.")
.profileOnOff(true)
.linkAttachments("https://link.com")
.music(music)
.imageUrl("https://image.url")
.build();

when(answerRepository.findByAnswerId(1L)).thenReturn(Optional.of(testAnswer));
doNothing().when(answerService).deleteAnswer(eq(1L));

// When
mockMvc.perform(delete("/api/answers/{answerId}", 1L)
.header("Authorization", "Bearer " + refreshToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNoContent());
}

*/
@Test
@DisplayName("답변 반응 확인 테스트(): 답변에 대한 반응 상태를 확인한다.")
public void hasReactedTest() throws Exception {
Expand All @@ -242,4 +295,5 @@ public void hasReactedTest() throws Exception {
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(0));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@

@SpringBootTest()
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@WithMockUser
@Transactional
public class ManageMemberTest {
Expand Down Expand Up @@ -182,7 +181,6 @@ public void addFcmTokenTest() throws Exception {
.andExpect(status().isOk());
}


@Test
@DisplayName("닉네임 업데이트 테스트(): 해당 회원의 닉네임을 업데이트한다.")
public void updateNicknameTest() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@

@SpringBootTest()
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@WithMockUser
@Transactional
public class MemberIntegrationTest {
Expand Down Expand Up @@ -135,7 +134,7 @@ public void testOauthSignUp() throws Exception {
when(loginService.loginWithExistingUser(any(KakaoUserInfoDto.class), any(LoginRequest.SignUp.class))).thenReturn(signUpResponse);
when(loginService.signUpNewUser(any(KakaoUserInfoDto.class), any(LoginRequest.SignUp.class))).thenReturn(signUpResponse);

LoginRequest.SignUp signUpRequest = new LoginRequest.SignUp(MemberType.KAKAO, "김예찬", "fcmToken");
LoginRequest.SignUp signUpRequest = new LoginRequest.SignUp(MemberType.KAKAO, "김예찬");

// when
mockMvc.perform(post("/api/auth/login")
Expand Down Expand Up @@ -184,4 +183,4 @@ public void testLogout() throws Exception {
// then
.andExpect(status().isOk());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

@SpringBootTest()
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@WithMockUser
@Transactional
public class NotificationManageTest {
Expand Down Expand Up @@ -144,4 +143,4 @@ void createNotificationTest() throws FirebaseMessagingException {
eq("가은아! 넌 무슨색상을 좋아해?")
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

@SpringBootTest()
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@WithMockUser
@Transactional
public class NotificationSelectTest {
Expand Down Expand Up @@ -133,4 +132,3 @@ void FindAllNotificationTest() throws Exception{
}

}

Loading
Loading