diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index c06fe4f..0f2aece 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -9,9 +9,11 @@ import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.Notification; import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.domain.user.exception.UserNotFoundException; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -32,12 +34,12 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class BadgeServiceTest { @@ -343,44 +345,95 @@ void success_1(boolean hasBadge) { @DisplayName("배지 수동 등록") class saveManualBadge { - @ParameterizedTest - @ValueSource(booleans = {true, false}) - @DisplayName("정상 저장되었다면 true, 이미 저장된 배지였으면 false를 반환한다.") - void success_1(boolean hasBadge) { + @Test + @DisplayName("새롭게 정상 저장된 배지 개수를 반환한다.") + void success_1() { // given - User user = TestUtil.createUser(); + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + List emails = users.stream() + .map(User::getEmail) + .toList(); + when(userRepository.findByEmailIn(emails)) + .thenReturn(users); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; - when(userRepository.findByEmail(user.getEmail())) - .thenReturn(Optional.of(user)); - when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) - .thenReturn(hasBadge); + when(badgeRepository.existsByUserAndBadgeType(users.get(0), badgeType)) + .thenReturn(true); + when(badgeRepository.existsByUserAndBadgeType(users.get(1), badgeType)) + .thenReturn(false); + when(badgeRepository.existsByUserAndBadgeType(users.get(2), badgeType)) + .thenReturn(false); // when - boolean result = badgeService.saveManualBadge(user.getEmail(), badgeType, false); + int result = badgeService.saveManualBadge(emails, badgeType, false); // then - assertThat(result).isEqualTo(!hasBadge); - assertThat(user.getNotification()).isNull(); + assertThat(result).isEqualTo(2); + verify(badgeRepository, times(2)).save(any(Badge.class)); } @Test - @DisplayName("개인 메시지로 저장") + @DisplayName("registerMessage 값을 true로 설정하면 user.notification에 원소가 추가된다.") void success_2() { // given - User user = TestUtil.createUser(); + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + List emails = users.stream() + .map(User::getEmail) + .toList(); + when(userRepository.findByEmailIn(emails)) + .thenReturn(users); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; - when(userRepository.findByEmail(user.getEmail())) - .thenReturn(Optional.of(user)); - when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) + when(badgeRepository.existsByUserAndBadgeType(users.get(0), badgeType)) + .thenReturn(true); + when(badgeRepository.existsByUserAndBadgeType(users.get(1), badgeType)) + .thenReturn(false); + when(badgeRepository.existsByUserAndBadgeType(users.get(2), badgeType)) .thenReturn(false); // when - boolean result = badgeService.saveManualBadge(user.getEmail(), badgeType, true); + int result = badgeService.saveManualBadge(emails, badgeType, true); // then - assertThat(result).isTrue(); - assertThat(user.getNotification()) + assertThat(result).isEqualTo(2); + verify(badgeRepository, times(2)).save(any(Badge.class)); + + assertThat(users.get(0).getNotification()).isEmpty(); + assertThat(users.get(1).getNotification()) .containsOnly(new Notification(NotificationEnum.NEW_BADGE, badgeType.name())); + assertThat(users.get(2).getNotification()) + .containsOnly(new Notification(NotificationEnum.NEW_BADGE, badgeType.name())); + } + + @Test + @DisplayName("존재하지 않는 이메일이 하나라도 존재하면 예외를 던진다.") + void fail_1() { + // given + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + List emails = users.subList(1, users.size()).stream() + .map(User::getEmail) + .toList(); + when(userRepository.findByEmailIn(emails)) + .thenReturn(users); + + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + + // expected + assertThatThrownBy(() -> badgeService.saveManualBadge(emails, badgeType, false)) + .isInstanceOf(UserNotFoundException.class); + verify(badgeRepository, times(0)).save(any(Badge.class)); } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java index aa07143..221c944 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java @@ -9,6 +9,7 @@ import com.playkuround.playkuroundserver.domain.user.api.request.ManualBadgeSaveRequest; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.*; +import com.playkuround.playkuroundserver.global.error.ErrorCode; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; @@ -18,11 +19,13 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.Set; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; 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; @@ -50,110 +53,131 @@ void clean() { } @Nested + @WithMockCustomUser(role = Role.ROLE_ADMIN) @DisplayName("배지 수동 등록") class saveManualBadge { @Test - @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("정상 배지 수동 등록 : 개인 메시지 저장 안함") + @DisplayName("기존에 가지고 있지 않는 배지인 경우만 저장된다.") void success_1() throws Exception { // given - User user = TestUtil.createUser("aa@konkuk.ac.kr", "newNickname", Major.건축학부); - userRepository.save(user); - + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + userRepository.saveAll(users); + + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + badgeRepository.save(new Badge(users.get(0), BadgeType.MONTHLY_RANKING_1)); + + List emails = users.stream() + .map(User::getEmail) + .toList(); ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest(user.getEmail(), BadgeType.MONTHLY_RANKING_1.name(), false); + = new ManualBadgeSaveRequest(emails, badgeType.name(), false); String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); // expect mockMvc.perform(post("/api/admin/badges/manual") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.response").value(true)) + .andExpect(jsonPath("$.response").value(2)) .andDo(print()); - List badges = badgeRepository.findByUser(user); - assertThat(badges).hasSize(1); - assertThat(badges.get(0).getBadgeType()).isEqualTo(BadgeType.MONTHLY_RANKING_1); - assertThat(user.getNotification()).isNull(); + List badges = badgeRepository.findAll(); + assertThat(badges).hasSize(3) + .extracting("user.id", "badgeType") + .containsExactlyInAnyOrder( + tuple(users.get(0).getId(), badgeType), + tuple(users.get(1).getId(), badgeType), + tuple(users.get(2).getId(), badgeType) + ); } @Test - @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("정상 배지 수동 등록 : 개인 메시지 저장") + @DisplayName("개인 메시지 저장 설정이 true인 경우, 새롭게 배지가 저장된 유저에게 메시지가 저장된다") void success_2() throws Exception { // given - User user = TestUtil.createUser("aa@konkuk.ac.kr", "test", Major.건축학부); - userRepository.save(user); - + List existUsers = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.컴퓨터공학부), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.국제무역학과) + ); + List notExistUsers = List.of( + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.건축학부), + TestUtil.createUser("user4@konkuk.ac.kr", "user4", Major.국어국문학과) + ); + + List allUsers = Stream.concat(existUsers.stream(), notExistUsers.stream()).toList(); + userRepository.saveAll(allUsers); + + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + List badges = existUsers.stream() + .map(user -> new Badge(user, badgeType)) + .toList(); + badgeRepository.saveAll(badges); + + List emails = allUsers.stream() + .map(User::getEmail) + .toList(); ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest(user.getEmail(), BadgeType.MONTHLY_RANKING_1.name(), true); + = new ManualBadgeSaveRequest(emails, badgeType.name(), true); String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); // expect mockMvc.perform(post("/api/admin/badges/manual") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.response").value(true)) + .andExpect(jsonPath("$.response").value(notExistUsers.size())) .andDo(print()); - List badges = badgeRepository.findByUser(user); - assertThat(badges).hasSize(1); - assertThat(badges.get(0).getBadgeType()).isEqualTo(BadgeType.MONTHLY_RANKING_1); - - Optional optionalUser = userRepository.findByEmail(user.getEmail()); - Set notification = optionalUser.get().getNotification(); - assertThat(notification) - .containsOnly(new Notification(NotificationEnum.NEW_BADGE, BadgeType.MONTHLY_RANKING_1.name())); + List notExistUserEmails = notExistUsers.stream() + .map(User::getEmail) + .toList(); + notExistUsers = userRepository.findByEmailIn(notExistUserEmails); + assertThat(notExistUsers).hasSize(notExistUsers.size()) + .extracting("notification", Set.class) + .allMatch(notifications -> notifications.contains(new Notification(NotificationEnum.NEW_BADGE, badgeType.name()))); + + List existUserEmails = existUsers.stream() + .map(User::getEmail) + .toList(); + existUsers = userRepository.findByEmailIn(existUserEmails); + assertThat(existUsers).hasSize(existUsers.size()) + .extracting("notification", Set.class) + .allMatch(Set::isEmpty); } @Test - @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("이미 가지고 있는 배지면 false를 반환한다") + @DisplayName("존재하지 않는 이메일이 하나라도 존재하면 예외를 던진다.") void fail_1() throws Exception { // given - User user = TestUtil.createUser("aa@konkuk.ac.kr", "test", Major.건축학부); - userRepository.save(user); - badgeRepository.save(new Badge(user, BadgeType.MONTHLY_RANKING_1)); - + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부) + ); + userRepository.saveAll(users); + + List emails = new ArrayList<>(); + users.stream() + .map(User::getEmail) + .forEach(emails::add); + emails.add("notFoundUser@konkuk.ac.kr"); ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest(user.getEmail(), BadgeType.MONTHLY_RANKING_1.name(), true); + = new ManualBadgeSaveRequest(emails, BadgeType.MONTHLY_RANKING_1.name(), false); String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); // expect mockMvc.perform(post("/api/admin/badges/manual") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) - .andExpect(status().isCreated()) - .andExpect(jsonPath("$.response").value(false)) + .content(request)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.USER_NOT_FOUND.getCode())) + .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.USER_NOT_FOUND.getMessage())) .andDo(print()); - - List badges = badgeRepository.findByUser(user); - assertThat(badges).hasSize(1); - assertThat(user.getNotification()).isNull(); } - @Test - @WithMockCustomUser(role = Role.ROLE_USER) - @DisplayName("admin 권한이 없으면 권한 에러가 발생한다") - void fail_2() throws Exception { - // given - ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest("test@konkuk.ac.kr", BadgeType.MONTHLY_RANKING_1.name(), true); - String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); - - // expect - mockMvc.perform(post("/api/admin/badges/manual") - .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) - .andExpect(status().isForbidden()) - .andDo(print()); - } } } \ No newline at end of file