From eb81aae893de2b8233d8589e6c72e56545073374 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:50:01 +0900 Subject: [PATCH 01/10] [Fix] Remove tests Erase to make a new one later - ControllerAccessTest.java - FileServiceTest.java - MemberRepositoryTest.java - MemberServiceImplTest.java - MessageRepositoryTest.java - MessageServiceImplTest.java --- .../controller/ControllerAccessTest.java | 303 ------------------ .../repository/MemberRepositoryTest.java | 127 -------- .../repository/MessageRepositoryTest.java | 165 ---------- .../TIAB/timebox/service/FileServiceTest.java | 42 --- .../service/MemberServiceImplTest.java | 190 ----------- .../service/MessageServiceImplTest.java | 213 ------------ 6 files changed, 1040 deletions(-) delete mode 100644 src/test/java/TIAB/timebox/controller/ControllerAccessTest.java delete mode 100644 src/test/java/TIAB/timebox/repository/MemberRepositoryTest.java delete mode 100644 src/test/java/TIAB/timebox/repository/MessageRepositoryTest.java delete mode 100644 src/test/java/TIAB/timebox/service/FileServiceTest.java delete mode 100644 src/test/java/TIAB/timebox/service/MemberServiceImplTest.java delete mode 100644 src/test/java/TIAB/timebox/service/MessageServiceImplTest.java diff --git a/src/test/java/TIAB/timebox/controller/ControllerAccessTest.java b/src/test/java/TIAB/timebox/controller/ControllerAccessTest.java deleted file mode 100644 index d704ecc..0000000 --- a/src/test/java/TIAB/timebox/controller/ControllerAccessTest.java +++ /dev/null @@ -1,303 +0,0 @@ -package TIAB.timebox.controller; - -import TIAB.timebox.dto.MemberDtoReq; -import TIAB.timebox.dto.MemberDtoRes; -import TIAB.timebox.dto.MessageDtoReq; -import TIAB.timebox.dto.MessageDtoRes; -import TIAB.timebox.exception.CanNotAccessException; -import TIAB.timebox.exception.MessageNotFoundException; -import TIAB.timebox.exception.NotPassedDeadlineException; -import TIAB.timebox.exception.UserNotFoundException; -import TIAB.timebox.service.member.MemberService; -import TIAB.timebox.service.message.MessageService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -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; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.test.context.support.WithAnonymousUser; -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.transaction.annotation.Transactional; - -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login; -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.status; - -@SpringBootTest -@AutoConfigureMockMvc -@Transactional -public class ControllerAccessTest { - - @Autowired - private MockMvc mvc; - - @Autowired - private MemberService memberService; - @Autowired - private MessageService messageService; - - @Nested - @DisplayName("with Anonymous User") - class CanNotAccess { - @Test - @DisplayName("홈 접근불가") - @WithAnonymousUser - public void canNotAccessHome() throws Exception { - mvc.perform(get("/")) - .andDo(print()) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("로그인은 접근 가능") - @WithAnonymousUser - public void canAccessLogin() throws Exception { - mvc.perform(get("/auth/login")) - .andDo(print()) - .andExpect(status().isOk()); - } - - @Test - @DisplayName("메세지 작성 접근불가능") - @WithAnonymousUser - public void canNotAccessMake() throws Exception { - mvc.perform(get("/message")) - .andDo(print()) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("메세지 전송 불가능") - @WithAnonymousUser - public void canNotPostMessage() throws Exception { - mvc.perform(post("/message") - .param("deadline", String.valueOf(new Date()))) - .andDo(print()) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("메세지 조회 불가능") - @WithAnonymousUser - public void canNotGetMessage() throws Exception { - mvc.perform(get("/message/1")) - .andDo(print()) - .andExpect(status().is3xxRedirection()); - } - - } - - @Nested - @DisplayName("With OAuth2 User") - class CanAccess { - MemberDtoRes memberDtoRes1, memberDtoRes2; - MessageDtoReq messageDtoReq1, messageDtoReq2, messageDtoReq3; - MessageDtoRes messageDtoRes1, messageDtoRes2, messageDtoRes3; - SecurityMockMvcRequestPostProcessors.OAuth2LoginRequestPostProcessor user1, user2, undefinedUser; - - private MockMultipartFile getMockMultifile(String filename, String contentType, String path) { - return new MockMultipartFile(filename, filename + "." + contentType, contentType, path.getBytes()); - } - - @BeforeEach - public void init() throws IOException { - MockMultipartFile mockMultipartFile = getMockMultifile("test", "test", "testpath"); - //user1 생성 - MemberDtoReq memberDtoReq1 = MemberDtoReq.builder() - .kakaoId(123l) - .email("test123@naver.com") - .imgSrc(null) - .build(); - memberDtoRes1 = memberService.save(memberDtoReq1); - //user2 생성 - MemberDtoReq memberDtoReq2 = MemberDtoReq.builder() - .kakaoId(312l) - .email("test321@naver.com") - .imgSrc(null) - .build(); - memberDtoRes2 = memberService.save(memberDtoReq2); - - //user1의 message1 생성 - messageDtoReq1 = MessageDtoReq.builder() - .content(mockMultipartFile) - .deadline(new Date()) - .member(memberDtoRes1.getMember()) - .filename("123") - .fileUrl("123") - .height(15) - .width(15) - .build(); - - //user1의 message2 생성 - messageDtoReq2 = MessageDtoReq.builder() - .content(mockMultipartFile) - .deadline(new Date(new Date().getTime() + 6000)) - .member(memberDtoRes1.getMember()) - .filename("123") - .fileUrl("123") - .height(15) - .width(15) - .build(); - - //user2의 message1 생성 - messageDtoReq3 = MessageDtoReq.builder() - .content(mockMultipartFile) - .deadline(new Date()) - .member(memberDtoRes2.getMember()) - .filename("123") - .fileUrl("123") - .height(15) - .width(15) - .build(); - - messageDtoRes1 = messageService.save(memberDtoRes1.getId(), messageDtoReq1); - messageDtoRes2 = messageService.save(memberDtoRes1.getId(), messageDtoReq2); - messageDtoRes3 = messageService.save(memberDtoRes2.getId(), messageDtoReq3); - - - //user1 oauth2 생성 - user1 = oauth2Login() - .authorities(new SimpleGrantedAuthority("ROLE_USER")) - .attributes(attr -> { - attr.put("id", memberDtoRes1.getId()); - }); - //user2 oauth2 생성 - user2 = oauth2Login() - .authorities(new SimpleGrantedAuthority("ROLE_USER")) - .attributes(attr -> { - attr.put("id", memberDtoRes2.getId()); - }); - //없는 유저 생성 - undefinedUser = oauth2Login() - .authorities(new SimpleGrantedAuthority("ROLE_USER")) - .attributes(attr -> { - attr.put("id", 123123291l); - }); - - } - - @Test - @DisplayName("홈 접근 가능") - public void canAccess() throws Exception { - mvc.perform(get("/").with(user1)) - .andDo(print()) - .andExpect(status().isOk()); - } - - @Test - @DisplayName("메세지 작성 접근가능") - public void canAccessMake() throws Exception { - mvc.perform(get("/message").with(user1)) - .andDo(print()) - .andExpect(status().isOk()); - } - - @Test - @DisplayName("시간이 만료된 메세지 조회가능") - public void canGetMessageExpiredDeadline() throws Exception { - mvc.perform(get("/message/" + messageDtoRes1.getId()).with(user1)) - .andDo(print()) - .andExpect(status().isOk()); - } - - @Test - @DisplayName("시간이 만료되지 않은 메세지 조회 불가능") - public void canNotGetMessageNotExpiredDeadline() throws Exception { - mvc.perform(get("/message/" + messageDtoRes2.getId()).with(user1)) - .andDo(print()) - .andExpect(result -> { - assertThat(result.getResolvedException().getClass()).isAssignableFrom(NotPassedDeadlineException.class); - }) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("다른 사람의 메세지 조회 불가능") - public void canNotAccessOtherMessage() throws Exception { - mvc.perform(get("/message/" + messageDtoRes3.getId()).with(user1)) - .andDo(print()) - .andExpect(result -> { - assertThat(result.getResolvedException().getClass()).isAssignableFrom(CanNotAccessException.class); - }) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("없는 메세지 조회 불가능") - public void canNotAccessNotExistMessage() throws Exception { - mvc.perform(get("/message/" + (messageDtoRes3.getId() + 1)).with(user1)) - .andDo(print()) - .andExpect(result -> { - assertThat(result.getResolvedException().getClass()).isAssignableFrom(MessageNotFoundException.class); - }) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("유저가 메세지 전송") - public void userPostMessage() throws Exception { - String formatted = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); - mvc.perform( - multipart("/message") - .file("content", getMockMultifile("aa", "aa", "Aa").getBytes()) - .param("height", "15") - .param("width", "15") - .param("deadline", formatted) - .with(request -> { - request.setMethod("POST"); - return request; - }).with(user1) - ) - .andDo(print()) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("없는 유저가 메세지를 만들기위해 접근") - public void undefinedUserAccess() throws Exception { - String formatted = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); - mvc.perform( - multipart("/message") - .file("content", getMockMultifile("aa", "aa", "aa").getBytes()) - .param("width", "15") - .param("height", "15") - .param("deadline", formatted) - .with(request -> { - request.setMethod("POST"); - return request; - }).with(undefinedUser)) - .andDo(print()) - .andExpect(result -> { - assertThat(result.getResolvedException().getClass()).isAssignableFrom(UserNotFoundException.class); - }) - .andExpect(status().is3xxRedirection()); - } - - @Test - @DisplayName("데드라인을 입력안했을시에 redirect") - public void notInputDeadline() throws Exception { - mvc.perform( - multipart("/message") - .file("content", getMockMultifile("aa", "aa", "aa").getBytes()) - .param("width", "15") - .param("height", "15") - .with(request -> { - request.setMethod("POST"); - return request; - }).with(undefinedUser)) - .andDo(print()) - .andExpect(status().is3xxRedirection()); - } - } -} diff --git a/src/test/java/TIAB/timebox/repository/MemberRepositoryTest.java b/src/test/java/TIAB/timebox/repository/MemberRepositoryTest.java deleted file mode 100644 index 808b5f6..0000000 --- a/src/test/java/TIAB/timebox/repository/MemberRepositoryTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package TIAB.timebox.repository; - -import TIAB.timebox.entity.member.Member; -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.orm.jpa.DataJpaTest; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@DataJpaTest -//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -public class MemberRepositoryTest { - @Autowired - private UserRepository userRepository; - - Member member, member1, member2; - - @BeforeEach - public void setUp() { - member = Member.builder() - .email("test@naver.com") - .imgSrc("testImg") - .kakaoId(123l) - .build(); - member1 = Member.builder() - .email("test1@naver.com") - .imgSrc("testImg1") - .kakaoId(1231l) - .build(); - member2 = Member.builder() - .email("test2@naver.com") - .imgSrc("testImg2") - .kakaoId(1232l) - .build(); - - } - - @Test - public void saveUser() { - //given - - //when - userRepository.save(member); - - //then - assertThat(userRepository.findByEmail(member.getEmail()).isPresent()).isEqualTo(true); - } - - @Test - public void findUserById() { - //given - userRepository.save(member); - - //when - Member find = userRepository.findById(member.getId()).orElse(null); - - //then - assertThat(find).isEqualTo(member); - } - - @Test - public void findByEmail() { - //given - userRepository.save(member); - - //when - Member find = userRepository.findByEmail(member.getEmail()).orElse(null); - - //then - assertThat(find).isEqualTo(member); - } - - @Test - public void findByKakaoId() { - //given - userRepository.save(member); - - //when - Member find = userRepository.findByKakaoId(member.getKakaoId()).orElse(null); - - //then - assertThat(find).isEqualTo(member); - } - - @Test - public void findAll() { - int beforeSize = userRepository.findAll().size(); - - //given && when && then - userRepository.save(member); - List members = userRepository.findAll(); - System.out.println(members.size()); - assertThat(members.size()).isEqualTo(beforeSize + 1); - assertThat(members).contains(member); - - userRepository.save(member1); - List users1 = userRepository.findAll(); - System.out.println(members.size()); - assertThat(users1.size()).isEqualTo(beforeSize + 2); - assertThat(users1).contains(member); - assertThat(users1).contains(member1); - - userRepository.save(member2); - List users2 = userRepository.findAll(); - System.out.println(members.size()); - assertThat(users2.size()).isEqualTo(beforeSize + 3); - assertThat(users2).contains(member); - assertThat(users2).contains(member1); - assertThat(users2).contains(member2); - } - - @Test - public void updateEmail() { - //given - Member saved = userRepository.save(member); - - //when - saved.setEmail("changed@gmail.com"); - Member changedEmailMember = userRepository.save(saved); - - //then - assertThat(changedEmailMember).isEqualTo(saved); - } -} diff --git a/src/test/java/TIAB/timebox/repository/MessageRepositoryTest.java b/src/test/java/TIAB/timebox/repository/MessageRepositoryTest.java deleted file mode 100644 index 60fba03..0000000 --- a/src/test/java/TIAB/timebox/repository/MessageRepositoryTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package TIAB.timebox.repository; - -import TIAB.timebox.entity.member.Member; -import TIAB.timebox.entity.message.Message; -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.orm.jpa.DataJpaTest; - -import java.util.Date; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@DataJpaTest -//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -public class MessageRepositoryTest { - @Autowired - private UserRepository userRepository; - @Autowired - private MessageRepository messageRepository; - - Member member1, member2, member3; - Message yesterdayMessage, message1, message2, message3, message4, message5; - - @BeforeEach - public void setUp() { - member1 = Member.builder() - .imgSrc("testimg1") - .kakaoId(1l) - .email("test1@gmail.com") - .build(); - member2 = Member.builder() - .imgSrc("testimg2") - .kakaoId(2l) - .email("test2@gmail.com") - .build(); - member3 = Member.builder() - .imgSrc("testimg3") - .kakaoId(3l) - .email("test3@gmail.com") - .build(); - - yesterdayMessage = Message.builder() - .filename("message yesterday") - .width(1) - .height(1) - .deadline(new Date(new Date().getTime() - (1000 * 60 * 60 * 24 * 1))) - .build(); - - message1 = Message.builder() - .filename("message1") - .width(1) - .height(1) - .deadline(new Date()) - .build(); - - message2 = Message.builder() - .filename("message2") - .width(2) - .height(2) - .deadline(new Date()) - .build(); - - message3 = Message.builder() - .filename("message3") - .width(3) - .height(3) - .deadline(new Date()) - .build(); - - message4 = Message.builder() - .filename("message4") - .width(4) - .height(4) - .deadline(new Date()) - .build(); - - message5 = Message.builder() - .filename("message5") - .width(5) - .height(5) - .deadline(new Date()) - .build(); - } - - @Test - public void repositoryIsNotNull() { - assertThat(userRepository).isNotNull(); - assertThat(messageRepository).isNotNull(); - } - - @Test - public void save() { - //given - Member savedMember = userRepository.save(member1); - message1.setMember(savedMember); - savedMember.getMessages().add(message1); - - //when - Message savedMessage = messageRepository.save(message1); - Member findMember = userRepository.findById(savedMember.getId()).orElse(null); - - //then - assertThat(savedMessage).isEqualTo(message1); - assertThat(findMember.getMessages()).contains(message1); - } - - @Test - public void findById() { - //given - Message saved = messageRepository.save(message1); - - //when - Message findMessage = messageRepository.findById(saved.getId()).orElse(null); - - //then - assertThat(findMessage).isEqualTo(saved); - } - - @Test - public void findAllByMember() { - //given - userRepository.save(member1); - - message1.setMember(member1); - member1.getMessages().add(message1); - message2.setMember(member1); - member1.getMessages().add(message2); - message3.setMember(member1); - member1.getMessages().add(message3); - - messageRepository.save(message1); - messageRepository.save(message2); - messageRepository.save(message3); - - - //when - List messages = messageRepository.findAllByMember(member1); - //then - assertThat(messages.size()).isEqualTo(3); - } - - @Test - public void findAllByDeadline() { - //given - userRepository.save(member1); - message1.setMember(member1); - message2.setMember(member1); - yesterdayMessage.setMember(member1); - - messageRepository.save(message1); - messageRepository.save(message2); - messageRepository.save(yesterdayMessage); - - //when - List todayMessages = messageRepository.findAllByDeadline(new Date()); - List yesterdayMessages = messageRepository.findAllByDeadline(new Date(new Date().getTime() - (1000 * 60 * 60 * 24 * 1))); - Date yesterDay = new Date(new Date().getTime() - (1000 * 60 * 60 * 24 * 1)); - //then - assertThat(todayMessages).contains(message1); - assertThat(todayMessages).contains(message2); - assertThat(yesterdayMessages).contains(yesterdayMessage); - } -} \ No newline at end of file diff --git a/src/test/java/TIAB/timebox/service/FileServiceTest.java b/src/test/java/TIAB/timebox/service/FileServiceTest.java deleted file mode 100644 index d9a5449..0000000 --- a/src/test/java/TIAB/timebox/service/FileServiceTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package TIAB.timebox.service; - -import TIAB.timebox.dto.FileServiceDtoRes; -import TIAB.timebox.dto.MessageDtoReq; -import TIAB.timebox.service.file.FileServiceImpl; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.io.IOException; -import java.util.Date; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class FileServiceTest { - @Mock - private FileServiceImpl fileService; - - - @Test - @DisplayName("파일 저장 테스트") - public void success() throws IOException { - MessageDtoReq messageDtoReq = MessageDtoReq.builder() - .content(null) - .deadline(new Date()) - .height(15) - .width(15) - .build(); - FileServiceDtoRes res = FileServiceDtoRes.builder() - .filename("test") - .fileUrl("testurl") - .build(); - when(fileService.save(any())).thenReturn(res); - - assertThat(fileService.save(messageDtoReq)).isEqualTo(res); - } -} diff --git a/src/test/java/TIAB/timebox/service/MemberServiceImplTest.java b/src/test/java/TIAB/timebox/service/MemberServiceImplTest.java deleted file mode 100644 index 6f99eb1..0000000 --- a/src/test/java/TIAB/timebox/service/MemberServiceImplTest.java +++ /dev/null @@ -1,190 +0,0 @@ -package TIAB.timebox.service; - - -import TIAB.timebox.dto.MemberDtoReq; -import TIAB.timebox.dto.MemberDtoRes; -import TIAB.timebox.entity.member.Member; -import TIAB.timebox.exception.UserNotFoundException; -import TIAB.timebox.repository.UserRepository; -import TIAB.timebox.service.member.MemberServiceImpl; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.IntStream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class MemberServiceImplTest { - @InjectMocks - private MemberServiceImpl userService; // - - @Mock - private UserRepository userRepository; - - MemberDtoReq memberDtoReq1, memberDtoReq2; - MemberDtoRes memberDtoRes1, memberDtoRes2; - Member beforeEntity1, afterEntity1, beforeEntity2, afterEntity2; - - @BeforeEach - public void init() { - memberDtoReq1 = MemberDtoReq.builder() - .kakaoId(1l) - .imgSrc("imgsrc") - .email("test123@gmail.com") - .build(); - - memberDtoReq2 = MemberDtoReq.builder() - .kakaoId(2l) - .imgSrc("imgsrc1") - .email("test1234@gmail.com") - .build(); - - beforeEntity1 = userService.dtoToEntity(memberDtoReq1); - afterEntity1 = userService.dtoToEntity(memberDtoReq1); - afterEntity1.setId(1l); - - beforeEntity2 = userService.dtoToEntity(memberDtoReq2); - afterEntity2 = userService.dtoToEntity(memberDtoReq2); - afterEntity2.setId(2l); - - memberDtoRes1 = userService.entityToDto(afterEntity1); - memberDtoRes2 = userService.entityToDto(afterEntity2); - - } - - //객체 두개를 비교해주는 메소드 - public void assertThatDtoEqualToDto(MemberDtoRes dto1, MemberDtoRes dto2) { - assertThat(dto1.getKakaoId()).isEqualTo(dto2.getKakaoId()); - assertThat(dto1.getMember()).isEqualTo(dto2.getMember()); - assertThat(dto1.getId()).isEqualTo(dto2.getId()); - assertThat(dto1.getEmail()).isEqualTo(dto2.getEmail()); - } - - @Nested - @DisplayName("Success Case") - class Success { - @Test - public void mockUserRepository() { - //given - List members = new ArrayList<>(); - members.add(afterEntity1); - when(userRepository.findAll()).thenReturn(members); - - //when - List actual = userService.getAllMembers(); - - //then - assertThat(actual.size()).isEqualTo(1); - assertThatDtoEqualToDto(actual.get(0), memberDtoRes1); - } - - @Test - public void saveTest_새로운사용자() { - //given - when(userRepository.save(any(Member.class))).thenReturn(afterEntity1); - when(userRepository.findByKakaoId(anyLong())).thenReturn(Optional.ofNullable(afterEntity1)); - - //when - MemberDtoRes actual = userService.save(memberDtoReq1); - - //then - assertThatDtoEqualToDto(actual, memberDtoRes1); - } - - @Test - public void saveTest_기존사용자_이미지src변경() { - //given - String changedSrc = "changedSrc"; - memberDtoReq1.setImgSrc(changedSrc); - afterEntity1.setImgSrc(changedSrc); - memberDtoRes1.setMember(afterEntity1); - when(userRepository.save(any(Member.class))).thenReturn(afterEntity1); - - //when - MemberDtoRes actual = userService.save(memberDtoReq1); - - //then - assertThatDtoEqualToDto(actual, memberDtoRes1); - } - - @Test - public void findAllTest() { - //given - List memberList = new ArrayList<>(); - memberList.add(afterEntity1); - memberList.add(afterEntity2); - when(userRepository.findAll()).thenReturn(memberList); - List expects = new ArrayList<>(); - expects.add(memberDtoRes1); - expects.add(memberDtoRes2); - - //when - List actual = userService.getAllMembers(); - - //then - IntStream.range(0, actual.size()).forEach(i -> { - assertThatDtoEqualToDto(actual.get(i), expects.get(i)); - }); - } - - @Test - public void findByKakaoIdTest() { - //given - when(userRepository.findByKakaoId(anyLong())).thenReturn(Optional.ofNullable(afterEntity1)); - - //when - MemberDtoRes actual = userService.findByKakaoId(memberDtoReq1.getKakaoId()); - - //then - assertThatDtoEqualToDto(actual, memberDtoRes1); - } - - @Test - public void findByIdTest() { - //given - when(userRepository.findById(anyLong())).thenReturn(Optional.ofNullable(afterEntity1)); - - //when - MemberDtoRes actual = userService.getMember(1l); - - //then - assertThatDtoEqualToDto(actual, memberDtoRes1); - } - } - - @Nested - @DisplayName("Failed Case") - class Failed { - @Test - public void findByKakaoIdExceptionTest() { - //given - when(userRepository.findByKakaoId(anyLong())).thenReturn(Optional.ofNullable(null)); - - //when & then - assertThrows(UserNotFoundException.class, () -> userService.findByKakaoId(3l)); - } - - @Test - public void findByIdExceptionTest() { - //given - when(userRepository.findById(anyLong())).thenReturn(Optional.ofNullable(null)); - - //when & then - assertThrows(UserNotFoundException.class, () -> userService.getMember(1l)); - } - } -} diff --git a/src/test/java/TIAB/timebox/service/MessageServiceImplTest.java b/src/test/java/TIAB/timebox/service/MessageServiceImplTest.java deleted file mode 100644 index 07a59d7..0000000 --- a/src/test/java/TIAB/timebox/service/MessageServiceImplTest.java +++ /dev/null @@ -1,213 +0,0 @@ -package TIAB.timebox.service; - -import TIAB.timebox.dto.FileServiceDtoRes; -import TIAB.timebox.dto.MessageDtoReq; -import TIAB.timebox.dto.MessageDtoRes; -import TIAB.timebox.entity.member.Member; -import TIAB.timebox.entity.message.Message; -import TIAB.timebox.exception.MessageNotFoundException; -import TIAB.timebox.exception.UserNotFoundException; -import TIAB.timebox.repository.MessageRepository; -import TIAB.timebox.repository.UserRepository; -import TIAB.timebox.service.file.FileService; -import TIAB.timebox.service.message.MessageServiceImpl; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; -import org.springframework.mock.web.MockMultipartFile; - -import java.io.IOException; -import java.util.Date; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class MessageServiceImplTest { - - @InjectMocks - private MessageServiceImpl messageService; - @Mock - private UserRepository userRepository; - @Mock - private MessageRepository messageRepository; - @Mock - private FileService fileService; - - Member member1, member2; - - MessageDtoReq yesterdayDtoReq, todayDtoReq, tomorrowDtoReq; - Message yesterdayMessage, todayMessage, tomorrowMessage, yesterdayMessageAfter, todayMessageAfter, tomorrowMessageAfter; - MessageDtoRes yesterdayDtoRes, todayDtoRes, tomorrowDtoRes; - String filename1, filename2, filename3; - String filepath, filepath1, filepath2, filepath3, contentType; - Date yesterday, today, tomorrow; - - private MockMultipartFile getMockMultifile(String filename, String contentType, String path) { - return new MockMultipartFile(filename, filename + "." + contentType, contentType, path.getBytes()); - } - - @BeforeEach - public void init() { - filename1 = "file1"; - filename2 = "file2"; - filename3 = "file3"; - contentType = "png"; - filepath = "/messagebox"; - filepath1 = filepath + "/" + filename1 + "." + contentType; - filepath2 = filepath + "/" + filename2 + "." + contentType; - filepath3 = filepath + "/" + filename3 + "." + contentType; - - yesterday = new Date(new Date().getTime() - (1000 * 60 * 60 * 24 * 1)); - today = new Date(); - tomorrow = new Date(new Date().getTime() + (1000 * 60 * 60 * 24 * 1)); - - member1 = Member.builder() - .email("test1@gmail.com") - .kakaoId(1l) - .imgSrc("testImgSrc") - .build(); - member1.setId(1l); - - member2 = Member.builder() - .email("test2@gmail.com") - .kakaoId(2l) - .imgSrc("test2ImgSrc") - .build(); - member2.setId(2l); - - yesterdayDtoReq = MessageDtoReq.builder() - .member(member1) - .content(getMockMultifile(filename1, contentType, filepath1)) - .deadline(yesterday) - .height(10) - .width(10) - .build(); - - todayDtoReq = MessageDtoReq.builder() - .member(member1) - .content(getMockMultifile(filename2, contentType, filepath2)) - .deadline(today) - .height(20) - .width(20) - .build(); - - tomorrowDtoReq = MessageDtoReq.builder() - .member(member2) - .content(getMockMultifile(filename3, contentType, filepath3)) - .deadline(tomorrow) - .height(30) - .width(30) - .build(); - - yesterdayMessage = messageService.dtoToEntity(yesterdayDtoReq); - yesterdayMessageAfter = messageService.dtoToEntity(yesterdayDtoReq); - yesterdayMessageAfter.setId(1l); - yesterdayMessageAfter.setFilename(filename1); - yesterdayMessageAfter.setFileUrl(filepath + "/" + filename1 + "." + contentType); - - todayMessage = messageService.dtoToEntity(todayDtoReq); - todayMessageAfter = messageService.dtoToEntity(todayDtoReq); - todayMessageAfter.setId(2l); - todayMessageAfter.setFilename(filename2); - todayMessageAfter.setFileUrl(filepath + "/" + filename2 + "." + contentType); - - tomorrowMessage = messageService.dtoToEntity(tomorrowDtoReq); - tomorrowMessageAfter = messageService.dtoToEntity(tomorrowDtoReq); - tomorrowMessageAfter.setId(2l); - tomorrowMessageAfter.setFilename(filename3); - tomorrowMessageAfter.setFileUrl(filepath + "/" + filename3 + "." + contentType); - - yesterdayDtoRes = messageService.entityToDto(yesterdayMessageAfter); - yesterdayDtoRes.setFilename(filename1); - yesterdayDtoRes.setFileUrl(filepath1); - - todayDtoRes = messageService.entityToDto(todayMessageAfter); - todayDtoRes.setFilename(filename2); - todayDtoRes.setFileUrl(filepath2); - - tomorrowDtoRes = messageService.entityToDto(tomorrowMessageAfter); - tomorrowDtoRes.setFilename(filename3); - tomorrowDtoRes.setFileUrl(filepath3); - } - - private void assertEqualDtoRes(MessageDtoRes dto1, MessageDtoRes dto2) { - assertThat(dto1.getDeadline()).isEqualTo(dto2.getDeadline()); - assertThat(dto1.getFilename()).isEqualTo(dto2.getFilename()); - assertThat(dto1.getFileUrl()).isEqualTo(dto2.getFileUrl()); - assertThat(dto1.getHeight()).isEqualTo(dto2.getHeight()); - assertThat(dto1.getWidth()).isEqualTo(dto2.getWidth()); - } - - @Nested - @DisplayName("Success Case") - class Success { - @Test - public void getByMessageId() { - //given - when(messageRepository.findById(anyLong())).thenReturn(Optional.ofNullable(todayMessageAfter)); - - //when - MessageDtoRes actual = messageService.getByMessageId(todayMessageAfter.getId()); - - //then - assertEqualDtoRes(actual, todayDtoRes); - } - - @Test - public void save() throws IOException { - //given - System.out.println(new Date()); - when(userRepository.findById(anyLong())).thenReturn(Optional.ofNullable(member1)); - when(messageRepository.save(any())).thenReturn(todayMessageAfter); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - MessageDtoReq dto = (MessageDtoReq) invocation.getArgument(0); - return FileServiceDtoRes.builder() - .filename(dto.getFilename()) - .fileUrl(dto.getFileUrl()) - .build(); - } - }).when(fileService).save(any()); - - //when - MessageDtoRes actual = messageService.save(member1.getId(), todayDtoReq); - - //then - assertEqualDtoRes(actual, todayDtoRes); - } - } - - @Nested - @DisplayName("Failed case") - class Failed { - @Test - public void getByMessageIdFailed() { - //given - when(messageRepository.findById(1l)).thenThrow(MessageNotFoundException.class); - //when & then - assertThrows(MessageNotFoundException.class, () -> messageService.getByMessageId(1l)); - } - - @Test - public void saveFailed_사용자없음() { - //given - when(userRepository.findById(anyLong())).thenThrow(UserNotFoundException.class); - //when & then - assertThrows(UserNotFoundException.class, () -> messageService.save(member1.getId(), todayDtoReq)); - } - } -} From 10902eef73bfd9c8c705ae701454e83af7af6215 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:51:33 +0900 Subject: [PATCH 02/10] [Fix] Remove oauth service with strong dependency --- .../java/TIAB/timebox/dto/MemberDtoReq.java | 14 ---- .../java/TIAB/timebox/dto/MemberDtoRes.java | 16 ----- .../security/KakaoOAuth2UserService.java | 66 ------------------- .../service/security/KakaoProfile.java | 49 -------------- 4 files changed, 145 deletions(-) delete mode 100644 src/main/java/TIAB/timebox/dto/MemberDtoReq.java delete mode 100644 src/main/java/TIAB/timebox/dto/MemberDtoRes.java delete mode 100644 src/main/java/TIAB/timebox/service/security/KakaoOAuth2UserService.java delete mode 100644 src/main/java/TIAB/timebox/service/security/KakaoProfile.java diff --git a/src/main/java/TIAB/timebox/dto/MemberDtoReq.java b/src/main/java/TIAB/timebox/dto/MemberDtoReq.java deleted file mode 100644 index f216af6..0000000 --- a/src/main/java/TIAB/timebox/dto/MemberDtoReq.java +++ /dev/null @@ -1,14 +0,0 @@ -package TIAB.timebox.dto; - -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Builder -public class MemberDtoReq { - private Long kakaoId; - private String email; - private String imgSrc; -} diff --git a/src/main/java/TIAB/timebox/dto/MemberDtoRes.java b/src/main/java/TIAB/timebox/dto/MemberDtoRes.java deleted file mode 100644 index 3143245..0000000 --- a/src/main/java/TIAB/timebox/dto/MemberDtoRes.java +++ /dev/null @@ -1,16 +0,0 @@ -package TIAB.timebox.dto; - -import TIAB.timebox.entity.member.Member; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Builder -public class MemberDtoRes { - private Long id; - private String email; - private long kakaoId; - private Member member; -} diff --git a/src/main/java/TIAB/timebox/service/security/KakaoOAuth2UserService.java b/src/main/java/TIAB/timebox/service/security/KakaoOAuth2UserService.java deleted file mode 100644 index 17b2dde..0000000 --- a/src/main/java/TIAB/timebox/service/security/KakaoOAuth2UserService.java +++ /dev/null @@ -1,66 +0,0 @@ -package TIAB.timebox.service.security; - -import TIAB.timebox.entity.member.Member; -import TIAB.timebox.repository.UserRepository; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.DefaultOAuth2User; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -@Slf4j -@Service -@RequiredArgsConstructor -public class KakaoOAuth2UserService extends DefaultOAuth2UserService { - private final UserRepository userRepository; - - private final ObjectMapper objectMapper; - - @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { - OAuth2User oAuth2User = super.loadUser(userRequest); - Map attributes = oAuth2User.getAttributes(); - - KakaoProfile profile = objectMapper.convertValue(attributes, KakaoProfile.class); - long profileKakaoId = profile.getId(); - String profileEmail = profile.getKakao_account().getEmail(); - String profileImgSrc = profile.getKakao_account().getProfile().getProfile_image_url(); - -// UserDtoReq dtoReq=UserDtoReq.builder() -// .kakaoId(profileKakaoId) -// .email(profileEmail) -// .imgSrc(profileImgSrc) -// .build(); -// UserDtoRes savedUser=userService.save(dtoReq); -// -// Map verifyInfo=new HashMap<>(); -// verifyInfo.put("id",savedUser.getId()); - Optional byKakaoId = userRepository.findByKakaoId(profileKakaoId); - Member securityMember = null; - if (!byKakaoId.isPresent()) { - Member newMember = Member.builder() - .kakaoId(profileKakaoId) - .email(profileEmail) - .imgSrc(profileImgSrc) - .build(); - - securityMember = userRepository.save(newMember); - } else { - securityMember = byKakaoId.get(); - } - Map verifyInfo = new HashMap<>(); - verifyInfo.put("id", securityMember.getId()); - - return new DefaultOAuth2User(Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")), verifyInfo, "id"); - } -} \ No newline at end of file diff --git a/src/main/java/TIAB/timebox/service/security/KakaoProfile.java b/src/main/java/TIAB/timebox/service/security/KakaoProfile.java deleted file mode 100644 index 7a95c05..0000000 --- a/src/main/java/TIAB/timebox/service/security/KakaoProfile.java +++ /dev/null @@ -1,49 +0,0 @@ -package TIAB.timebox.service.security; - -import lombok.Getter; -import lombok.ToString; - -@Getter -@ToString -public class KakaoProfile { - private long id; - private String connected_at; - private Properties properties; - private KakaoAccount kakao_account; - - @Getter - @ToString - public static class Properties { - private String nickname; - private String profile_image; - private String thumbnail_image; - } - - @Getter - @ToString - public static class KakaoAccount { - private Boolean profile_nickname_needs_agreement; - private Boolean profile_image_needs_agreement; - private Profile profile; - private Boolean has_email; - private Boolean email_needs_agreement; - private Boolean is_email_valid; - private Boolean is_email_verified; - private String email; - private Boolean has_age_range; - private Boolean age_range_needs_agreement; - private Boolean has_birthday; - private Boolean birthday_needs_agreement; - private Boolean has_gender; - private Boolean gender_needs_agreement; - - @Getter - @ToString - public static class Profile { - private String nickname; - private String thumbnail_image_url; - private String profile_image_url; - private Boolean is_default_image; - } - } -} From e0710a4149f46f455248ec92e441cd9da294daf7 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:54:32 +0900 Subject: [PATCH 03/10] [Fix] Rename and add fields & methods because of removing dependency of kakao --- .../TIAB/timebox/entity/member/Member.java | 29 ++++++++++----- ...rRepository.java => MemberRepository.java} | 4 +- .../timebox/service/member/MemberService.java | 31 +--------------- .../service/member/MemberServiceImpl.java | 37 ++++--------------- 4 files changed, 30 insertions(+), 71 deletions(-) rename src/main/java/TIAB/timebox/repository/{UserRepository.java => MemberRepository.java} (64%) diff --git a/src/main/java/TIAB/timebox/entity/member/Member.java b/src/main/java/TIAB/timebox/entity/member/Member.java index fbedc5d..1afdfbb 100644 --- a/src/main/java/TIAB/timebox/entity/member/Member.java +++ b/src/main/java/TIAB/timebox/entity/member/Member.java @@ -2,14 +2,16 @@ import TIAB.timebox.entity.BaseEntity; import TIAB.timebox.entity.message.Message; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Getter -@Setter @Entity @AllArgsConstructor @NoArgsConstructor @@ -20,20 +22,27 @@ public class Member extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; - @Column(name = "kakao_id") - private Long kakaoId; + @Column(name = "social_id") + private String socialId; + @Column(name = "social_provider") + private String socialProvider; @Column(name = "email") private String email; - @Column(name = "img_src") - private String imgSrc; + @Column(name = "profile_img") + private String profileImg; @Builder - public Member(Long kakaoId, String email, String imgSrc) { - this.kakaoId = kakaoId; + public Member(String socialId, String socialProvider, String email, String profileImg) { + this.socialProvider = socialProvider; + this.socialId = socialId; this.email = email; - this.imgSrc = imgSrc; + this.profileImg = profileImg; } - @OneToMany(mappedBy = "member") + @OneToMany(mappedBy = "member", fetch = FetchType.LAZY) private List messages = new ArrayList<>(); + + public void updateProfileImg(String profileImg) { + this.profileImg = profileImg; + } } diff --git a/src/main/java/TIAB/timebox/repository/UserRepository.java b/src/main/java/TIAB/timebox/repository/MemberRepository.java similarity index 64% rename from src/main/java/TIAB/timebox/repository/UserRepository.java rename to src/main/java/TIAB/timebox/repository/MemberRepository.java index 9dea32b..ffc8087 100644 --- a/src/main/java/TIAB/timebox/repository/UserRepository.java +++ b/src/main/java/TIAB/timebox/repository/MemberRepository.java @@ -5,8 +5,6 @@ import java.util.Optional; -public interface UserRepository extends JpaRepository { +public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); - - Optional findByKakaoId(Long kakao_id); } diff --git a/src/main/java/TIAB/timebox/service/member/MemberService.java b/src/main/java/TIAB/timebox/service/member/MemberService.java index e8e3253..dbb57b2 100644 --- a/src/main/java/TIAB/timebox/service/member/MemberService.java +++ b/src/main/java/TIAB/timebox/service/member/MemberService.java @@ -1,34 +1,7 @@ package TIAB.timebox.service.member; -import TIAB.timebox.dto.MemberDtoReq; -import TIAB.timebox.dto.MemberDtoRes; -import TIAB.timebox.entity.member.Member; - -import java.util.List; +import TIAB.timebox.dto.MemberDTO; public interface MemberService { - MemberDtoRes save(MemberDtoReq dto); - - MemberDtoRes getMember(long id); - - MemberDtoRes findByKakaoId(long kakaoId); - - List getAllMembers(); - - default Member dtoToEntity(MemberDtoReq dto) { - return Member.builder() - .email(dto.getEmail()) - .kakaoId(dto.getKakaoId()) - .imgSrc(dto.getImgSrc()) - .build(); - } - - default MemberDtoRes entityToDto(Member entity) { - return MemberDtoRes.builder() - .email(entity.getEmail()) - .kakaoId(entity.getKakaoId()) - .id(entity.getId()) - .member(entity) - .build(); - } + MemberDTO.Response findById(MemberDTO.Request req); } diff --git a/src/main/java/TIAB/timebox/service/member/MemberServiceImpl.java b/src/main/java/TIAB/timebox/service/member/MemberServiceImpl.java index 3aed98e..11d1b16 100644 --- a/src/main/java/TIAB/timebox/service/member/MemberServiceImpl.java +++ b/src/main/java/TIAB/timebox/service/member/MemberServiceImpl.java @@ -1,42 +1,21 @@ package TIAB.timebox.service.member; -import TIAB.timebox.dto.MemberDtoReq; -import TIAB.timebox.dto.MemberDtoRes; -import TIAB.timebox.entity.member.Member; +import TIAB.timebox.dto.MemberDTO; import TIAB.timebox.exception.UserNotFoundException; -import TIAB.timebox.repository.UserRepository; +import TIAB.timebox.repository.MemberRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.stream.Collectors; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class MemberServiceImpl implements MemberService { - private final UserRepository userRepository; - - @Override - public MemberDtoRes save(MemberDtoReq dto) { - Member member = userRepository.findByKakaoId(dto.getKakaoId()).orElse(dtoToEntity(dto)); - return entityToDto(userRepository.save(member)); - } - - //Exception 처리하기 - @Override - public MemberDtoRes getMember(long id) { - Member member = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException()); - return entityToDto(member); - } - - @Override - public MemberDtoRes findByKakaoId(long kakaoId) { - Member member = userRepository.findByKakaoId(kakaoId).orElseThrow(() -> new UserNotFoundException()); - return entityToDto(member); - } + private final MemberRepository memberRepository; @Override - public List getAllMembers() { - return userRepository.findAll().stream().map(entity -> entityToDto(entity)).collect(Collectors.toList()); + @Transactional(readOnly = true) + public MemberDTO.Response findById(MemberDTO.Request req) { + return MemberDTO.entityToDto(memberRepository.findById(req.getId()) + .orElseThrow(() -> new UserNotFoundException())); } } From 5610dfff59912bcf929a76e7331bd6652aa13a12 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:55:16 +0900 Subject: [PATCH 04/10] [Feat] Add OAuthProvider Enum class --- .../service/security/OAuthProvider.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/main/java/TIAB/timebox/service/security/OAuthProvider.java diff --git a/src/main/java/TIAB/timebox/service/security/OAuthProvider.java b/src/main/java/TIAB/timebox/service/security/OAuthProvider.java new file mode 100644 index 0000000..2936e39 --- /dev/null +++ b/src/main/java/TIAB/timebox/service/security/OAuthProvider.java @@ -0,0 +1,49 @@ +package TIAB.timebox.service.security; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.oauth2.core.user.OAuth2User; + +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Getter +@RequiredArgsConstructor +@Slf4j +public enum OAuthProvider { + KAKAO("kakao") { + @Override + public OAuthUserInfo getUserInfo(OAuth2User user) { + Map attributes = user.getAttributes(); + Map properties = user.getAttribute("properties"); + Map account = user.getAttribute("kakao_account"); + + + return OAuthUserInfo.builder() + .socialProvider(KAKAO.provider) + .socialId(String.valueOf(attributes.get("id"))) + .email(String.valueOf(account.get("email"))) + .nickname(String.valueOf(properties.get("nickname"))) + .profileImageUrl(String.valueOf(properties.get("profile_image"))) + .build(); + } + }; + + private final String provider; + private static final Map PROVIDERS = + Collections.unmodifiableMap(Stream.of(values()) + .collect(Collectors.toMap(OAuthProvider::getProvider, Function.identity()))); + + public static OAuthProvider getOAuthProviderByName(String providerName) { + if (!PROVIDERS.containsKey(providerName)) { + throw new IllegalArgumentException("지원하지 않는 로그인입니다."); + } + return PROVIDERS.get(providerName); + } + + public abstract OAuthUserInfo getUserInfo(OAuth2User user); +} From 7a994f3cd13aa615c53b38648d7bbb0b39a51598 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:56:50 +0900 Subject: [PATCH 05/10] [Feat] Create OAuthUserInfo with required information --- .../timebox/service/security/OAuthUserInfo.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/TIAB/timebox/service/security/OAuthUserInfo.java diff --git a/src/main/java/TIAB/timebox/service/security/OAuthUserInfo.java b/src/main/java/TIAB/timebox/service/security/OAuthUserInfo.java new file mode 100644 index 0000000..8e7adb7 --- /dev/null +++ b/src/main/java/TIAB/timebox/service/security/OAuthUserInfo.java @@ -0,0 +1,14 @@ +package TIAB.timebox.service.security; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class OAuthUserInfo { + private String email; + private String nickname; + private String socialProvider; + private String socialId; + private String profileImageUrl; +} From 8205edbd5566ccaad58078fe28bfdc26baed1bb1 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:58:16 +0900 Subject: [PATCH 06/10] [Feat] Create MemberOAuthService interface - getOrRegistWithOAuthInfo method --- .../TIAB/timebox/service/member/MemberOAuthService.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/TIAB/timebox/service/member/MemberOAuthService.java diff --git a/src/main/java/TIAB/timebox/service/member/MemberOAuthService.java b/src/main/java/TIAB/timebox/service/member/MemberOAuthService.java new file mode 100644 index 0000000..bde6153 --- /dev/null +++ b/src/main/java/TIAB/timebox/service/member/MemberOAuthService.java @@ -0,0 +1,8 @@ +package TIAB.timebox.service.member; + +import TIAB.timebox.entity.member.Member; +import TIAB.timebox.service.security.OAuthUserInfo; + +public interface MemberOAuthService { + Member getOrRegistWithOAuthInfo(OAuthUserInfo userInfo); +} From 2cf620c1b2ca7baf9146bfddd5d1c43d44bb315f Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:58:32 +0900 Subject: [PATCH 07/10] [Feat] Implements MemberOAuthService - getOrRegistWithOAuthInfo method --- .../member/MemberOAuthServiceImpl.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/TIAB/timebox/service/member/MemberOAuthServiceImpl.java diff --git a/src/main/java/TIAB/timebox/service/member/MemberOAuthServiceImpl.java b/src/main/java/TIAB/timebox/service/member/MemberOAuthServiceImpl.java new file mode 100644 index 0000000..94707df --- /dev/null +++ b/src/main/java/TIAB/timebox/service/member/MemberOAuthServiceImpl.java @@ -0,0 +1,35 @@ +package TIAB.timebox.service.member; + +import TIAB.timebox.entity.member.Member; +import TIAB.timebox.repository.MemberRepository; +import TIAB.timebox.service.security.OAuthUserInfo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +@Slf4j +@Service +@RequiredArgsConstructor +public class MemberOAuthServiceImpl implements MemberOAuthService { + private final MemberRepository memberRepository; + + @Override + @Transactional + public Member getOrRegistWithOAuthInfo(OAuthUserInfo userInfo) { + String email = userInfo.getEmail(); + String socialId = userInfo.getSocialId(); + String socialProvider = userInfo.getSocialProvider(); + String profileImageUrl = userInfo.getProfileImageUrl(); + + Member member = memberRepository.findByEmail(email) + .orElse(Member.builder() + .socialProvider(socialProvider) + .socialId(socialId) + .email(email) + .build()); + member.updateProfileImg(profileImageUrl); + return memberRepository.save(member); + } +} From 3cb1aa4e0fb398da5da07e628964b70bce4a79cb Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 00:59:58 +0900 Subject: [PATCH 08/10] [Feat] Inherited and implemented DefaultOAuth2UserService for SpringSecurity --- .../service/security/CustomOAuth2User.java | 43 +++++++++++++++++++ .../security/CustomOAuth2UserService.java | 30 +++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/main/java/TIAB/timebox/service/security/CustomOAuth2User.java create mode 100644 src/main/java/TIAB/timebox/service/security/CustomOAuth2UserService.java diff --git a/src/main/java/TIAB/timebox/service/security/CustomOAuth2User.java b/src/main/java/TIAB/timebox/service/security/CustomOAuth2User.java new file mode 100644 index 0000000..4c9790c --- /dev/null +++ b/src/main/java/TIAB/timebox/service/security/CustomOAuth2User.java @@ -0,0 +1,43 @@ +package TIAB.timebox.service.security; + +import TIAB.timebox.entity.member.Member; +import lombok.Getter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.core.user.OAuth2User; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +@Getter +public class CustomOAuth2User implements OAuth2User { + private final Member member; + private final Long id; + private final String socialId; + private final String socialProvider; + private final Map attributes; + + public CustomOAuth2User(Member member, Map attributes) { + this.attributes = attributes; + this.member = member; + this.id = member.getId(); + this.socialProvider = member.getSocialProvider(); + this.socialId = member.getSocialId(); + } + + @Override + public Map getAttributes() { + return this.attributes; + } + + @Override + public Collection getAuthorities() { + return Set.of(new SimpleGrantedAuthority("MEMBER")); + } + + @Override + public String getName() { + return this.member.getEmail(); + } +} diff --git a/src/main/java/TIAB/timebox/service/security/CustomOAuth2UserService.java b/src/main/java/TIAB/timebox/service/security/CustomOAuth2UserService.java new file mode 100644 index 0000000..cc49968 --- /dev/null +++ b/src/main/java/TIAB/timebox/service/security/CustomOAuth2UserService.java @@ -0,0 +1,30 @@ +package TIAB.timebox.service.security; + +import TIAB.timebox.entity.member.Member; +import TIAB.timebox.service.member.MemberOAuthService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class CustomOAuth2UserService extends DefaultOAuth2UserService { + private final MemberOAuthService memberOAuthService; + + @Override + public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + OAuth2User oAuth2User = super.loadUser(userRequest); + String providerName = userRequest.getClientRegistration().getRegistrationId(); + + OAuthUserInfo userInfo = OAuthProvider.getOAuthProviderByName(providerName) + .getUserInfo(oAuth2User); + + Member member = memberOAuthService.getOrRegistWithOAuthInfo(userInfo); + return new CustomOAuth2User(member, oAuth2User.getAttributes()); + } +} From 64cc9ad962c6fc011dc77b208f7b04c5997e800a Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 01:01:22 +0900 Subject: [PATCH 09/10] [Feat] Inject OAuthService with Dependencies --- src/main/java/TIAB/timebox/config/SecurityConfig.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/TIAB/timebox/config/SecurityConfig.java b/src/main/java/TIAB/timebox/config/SecurityConfig.java index 6375427..cfdfa60 100644 --- a/src/main/java/TIAB/timebox/config/SecurityConfig.java +++ b/src/main/java/TIAB/timebox/config/SecurityConfig.java @@ -1,18 +1,19 @@ package TIAB.timebox.config; -import TIAB.timebox.service.security.KakaoOAuth2UserService; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; +import org.springframework.security.oauth2.core.user.OAuth2User; @Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig extends WebSecurityConfigurerAdapter { - - private final KakaoOAuth2UserService kakaoOauth2UserService; + private final OAuth2UserService oAuth2UserService; @Override protected void configure(HttpSecurity http) throws Exception { @@ -23,7 +24,7 @@ protected void configure(HttpSecurity http) throws Exception { .disable() .and() .authorizeRequests() - .antMatchers("/auth/kakao/**", "/css/**", "/images/**", "/fonts/**", "/auth/login").permitAll() + .antMatchers("/auth/**", "/css/**", "/images/**", "/fonts/**").permitAll() .anyRequest().authenticated() .and() .logout() @@ -34,6 +35,6 @@ protected void configure(HttpSecurity http) throws Exception { .oauth2Login() .loginPage("/auth/login") .userInfoEndpoint() - .userService(kakaoOauth2UserService); + .userService(oAuth2UserService); } } From b01f4153d862a439c0b4ed63a762ee7fdbbac6b8 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Sun, 10 Dec 2023 01:02:12 +0900 Subject: [PATCH 10/10] [Feat] Modify according to refactored code --- .../timebox/controller/HomeController.java | 13 ++++--- .../timebox/controller/MessageController.java | 12 +++--- src/main/java/TIAB/timebox/dto/MemberDTO.java | 37 +++++++++++++++++++ .../service/message/MessageServiceImpl.java | 6 +-- src/main/resources/templates/home.html | 4 +- 5 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 src/main/java/TIAB/timebox/dto/MemberDTO.java diff --git a/src/main/java/TIAB/timebox/controller/HomeController.java b/src/main/java/TIAB/timebox/controller/HomeController.java index b05e564..2626568 100644 --- a/src/main/java/TIAB/timebox/controller/HomeController.java +++ b/src/main/java/TIAB/timebox/controller/HomeController.java @@ -1,11 +1,11 @@ package TIAB.timebox.controller; -import TIAB.timebox.dto.MemberDtoRes; +import TIAB.timebox.dto.MemberDTO; import TIAB.timebox.service.member.MemberService; +import TIAB.timebox.service.security.CustomOAuth2User; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -18,10 +18,11 @@ public class HomeController { private final MemberService memberService; @GetMapping - public String home(@AuthenticationPrincipal OAuth2User oAuth2User, Model model) { - long id = oAuth2User.getAttribute("id"); - MemberDtoRes member = memberService.getMember(id); - model.addAttribute("memberDto", member); + public String home(@AuthenticationPrincipal CustomOAuth2User oAuth2User, Model model) { + MemberDTO.Response member = memberService.findById(MemberDTO.Request.builder() + .id(oAuth2User.getId()) + .build()); + model.addAttribute("member", member); return "home"; } } diff --git a/src/main/java/TIAB/timebox/controller/MessageController.java b/src/main/java/TIAB/timebox/controller/MessageController.java index 91e4358..5ff0733 100644 --- a/src/main/java/TIAB/timebox/controller/MessageController.java +++ b/src/main/java/TIAB/timebox/controller/MessageController.java @@ -5,10 +5,10 @@ import TIAB.timebox.exception.CanNotAccessException; import TIAB.timebox.exception.NotPassedDeadlineException; import TIAB.timebox.service.message.MessageService; +import TIAB.timebox.service.security.CustomOAuth2User; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -33,9 +33,9 @@ public String makeMessage() { } @PostMapping - public String sendMessage(@AuthenticationPrincipal OAuth2User oAuth2User, + public String sendMessage(@AuthenticationPrincipal CustomOAuth2User oAuth2User, MessageDtoReq messageDtoReq) throws IOException { - long memberId = oAuth2User.getAttribute("id"); + long memberId = oAuth2User.getId(); if (messageDtoReq.getDeadline() == null) { return "redirect:/message"; } @@ -45,15 +45,15 @@ public String sendMessage(@AuthenticationPrincipal OAuth2User oAuth2User, @GetMapping("/{id}") public String showMessage(@PathVariable("id") String id, - @AuthenticationPrincipal OAuth2User oAuth2User, Model model) { + @AuthenticationPrincipal CustomOAuth2User oAuth2User, Model model) { Date now = new Date(); - long userId = oAuth2User.getAttribute("id"); + long memberId = oAuth2User.getId(); MessageDtoRes messageDtoRes = messageService.getByMessageId(Long.parseLong(id)); if (now.getTime() < messageDtoRes.getDeadline().getTime()) { throw new NotPassedDeadlineException(); } - if (messageDtoRes.getMember().getId() != userId) { + if (messageDtoRes.getMember().getId() != memberId) { throw new CanNotAccessException(); } diff --git a/src/main/java/TIAB/timebox/dto/MemberDTO.java b/src/main/java/TIAB/timebox/dto/MemberDTO.java new file mode 100644 index 0000000..74cae90 --- /dev/null +++ b/src/main/java/TIAB/timebox/dto/MemberDTO.java @@ -0,0 +1,37 @@ +package TIAB.timebox.dto; + +import TIAB.timebox.entity.member.Member; +import TIAB.timebox.entity.message.Message; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +public class MemberDTO { + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class Request { + private Long id; + } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class Response { + private String profileImg; + @Builder.Default + private List messages = new ArrayList<>(); + } + + public static MemberDTO.Response entityToDto(Member entity) { + return Response.builder() + .profileImg(entity.getProfileImg()) + .messages(entity.getMessages()) + .build(); + } +} diff --git a/src/main/java/TIAB/timebox/service/message/MessageServiceImpl.java b/src/main/java/TIAB/timebox/service/message/MessageServiceImpl.java index 5978e85..fcaa4a3 100644 --- a/src/main/java/TIAB/timebox/service/message/MessageServiceImpl.java +++ b/src/main/java/TIAB/timebox/service/message/MessageServiceImpl.java @@ -7,8 +7,8 @@ import TIAB.timebox.entity.message.Message; import TIAB.timebox.exception.MessageNotFoundException; import TIAB.timebox.exception.UserNotFoundException; +import TIAB.timebox.repository.MemberRepository; import TIAB.timebox.repository.MessageRepository; -import TIAB.timebox.repository.UserRepository; import TIAB.timebox.service.file.FileService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -21,14 +21,14 @@ @Slf4j @RequiredArgsConstructor public class MessageServiceImpl implements MessageService { - private final UserRepository userRepository; + private final MemberRepository memberRepository; private final MessageRepository messageRepository; private final FileService fileService; @Override @Transactional public MessageDtoRes save(long id, MessageDtoReq messageDtoReq) throws IOException { - Member member = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException()); + Member member = memberRepository.findById(id).orElseThrow(() -> new UserNotFoundException()); FileServiceDtoRes fileServiceDtoRes = fileService.save(messageDtoReq); diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index 7fd7481..7e4a05f 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -23,12 +23,12 @@ 작성하러 가기
- +
error
-