diff --git a/backend/src/main/java/wooteco/prolog/studylog/application/PopularStudylogService.java b/backend/src/main/java/wooteco/prolog/studylog/application/PopularStudylogService.java index a03c93abc..ac01a7b67 100644 --- a/backend/src/main/java/wooteco/prolog/studylog/application/PopularStudylogService.java +++ b/backend/src/main/java/wooteco/prolog/studylog/application/PopularStudylogService.java @@ -1,5 +1,13 @@ package wooteco.prolog.studylog.application; +import static java.util.stream.Collectors.toList; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import lombok.AllArgsConstructor; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -20,15 +28,6 @@ import wooteco.prolog.studylog.domain.repository.PopularStudylogRepository; import wooteco.prolog.studylog.domain.repository.StudylogRepository; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.toList; - @Service @AllArgsConstructor @Transactional(readOnly = true) @@ -36,9 +35,6 @@ public class PopularStudylogService { private static final int A_WEEK = 7; private static final int THREE_WEEK = 21; - private static final String BACKEND = "백엔드"; - private static final String FRONTEND = "프론트엔드"; - private static final String ANDROID = "안드로이드"; private final StudylogService studylogService; private final StudylogRepository studylogRepository; @@ -51,24 +47,23 @@ public void updatePopularStudylogs(Pageable pageable) { deleteAllLegacyPopularStudylogs(); List groupMembers = groupMemberRepository.findAll(); - Map> memberGroupsBygroupType = memberGroupRepository.findAll().stream() - .collect(Collectors.groupingBy(MemberGroup::getGroupType)); + Map> memberGroupsBygroupType = memberGroupRepository.findAll() + .stream().collect(Collectors.groupingBy(MemberGroup::getGroupType)); - final List recentStudylogs = findRecentStudylogs(LocalDateTime.now(), pageable.getPageSize()); + final List recentStudylogs = findRecentStudylogs(LocalDateTime.now(), + pageable.getPageSize()); List popularStudylogs = new ArrayList<>(); for (MemberGroupType groupType : MemberGroupType.values()) { - popularStudylogs.addAll(filterStudylogsByMemberGroups(recentStudylogs, new MemberGroups(memberGroupsBygroupType.get(groupType)), groupMembers) - .stream() + popularStudylogs.addAll(filterStudylogsByMemberGroups(recentStudylogs, + new MemberGroups(memberGroupsBygroupType.get(groupType)), groupMembers).stream() .sorted(Comparator.comparing(Studylog::getPopularScore).reversed()) - .limit(pageable.getPageSize()) - .collect(toList())); + .limit(pageable.getPageSize()).collect(toList())); } - popularStudylogRepository.saveAll(popularStudylogs.stream() - .map(it -> new PopularStudylog(it.getId())) - .collect(toList())); + popularStudylogRepository.saveAll( + popularStudylogs.stream().map(it -> new PopularStudylog(it.getId())).collect(toList())); } private void deleteAllLegacyPopularStudylogs() { @@ -79,7 +74,8 @@ private void deleteAllLegacyPopularStudylogs() { } } - private List findRecentStudylogs(final LocalDateTime dateTime, final int minStudylogsSize) { + private List findRecentStudylogs(final LocalDateTime dateTime, + final int minStudylogsSize) { int decreaseDays = A_WEEK; List recentStudylogs = new ArrayList<>(); while (decreaseDays <= THREE_WEEK) { @@ -92,61 +88,56 @@ private List findRecentStudylogs(final LocalDateTime dateTime, final i return recentStudylogs; } - private List filterStudylogsByMemberGroups(final List studylogs, final MemberGroups memberGroups, final List groupMembers) { - return studylogs.stream() - .filter(studylog -> checkMemberAssignedInMemberGroups(memberGroups, studylog.getMember(), - groupMembers)) - .collect(toList()); + private List filterStudylogsByMemberGroups(final List studylogs, + final MemberGroups memberGroups, + final List groupMembers) { + return studylogs.stream().filter( + studylog -> checkMemberAssignedInMemberGroups(memberGroups, studylog.getMember(), + groupMembers)).collect(toList()); } - private boolean checkMemberAssignedInMemberGroups(MemberGroups memberGroups, - Member member, + private boolean checkMemberAssignedInMemberGroups(MemberGroups memberGroups, Member member, List groupMembers) { - if (canJudgeMemberGroup(groupMembers, member)) { - return groupMembers.stream() - .anyMatch(memberGroups::isContainsMemberGroups); - } - - return false; - } - - private boolean canJudgeMemberGroup(final List groupMembers, final Member member) { - return groupMembers.stream() - .anyMatch(it -> it.getMember().equals(member)); + return groupMembers.stream().anyMatch( + it -> it.getMember().equals(member) && memberGroups.isContainsMemberGroups(it)); } - public PopularStudylogsResponse findPopularStudylogs(Pageable pageable, - Long memberId, + public PopularStudylogsResponse findPopularStudylogs(Pageable pageable, Long memberId, boolean isAnonymousMember) { List allPopularStudylogs = getSortedPopularStudyLogs(pageable); List groupedMembers = groupMemberRepository.findAll(); - Map> memberGroupsBygroupType = memberGroupRepository.findAll().stream() - .collect(Collectors.groupingBy(MemberGroup::getGroupType)); + Map> memberGroupsBygroupType = memberGroupRepository.findAll() + .stream().collect(Collectors.groupingBy(MemberGroup::getGroupType)); return PopularStudylogsResponse.of( studylogsResponse(allPopularStudylogs, pageable, memberId), - studylogsResponse(filterStudylogsByMemberGroups(allPopularStudylogs, new MemberGroups(memberGroupsBygroupType.get(MemberGroupType.FRONTEND)), groupedMembers), pageable, memberId), - studylogsResponse(filterStudylogsByMemberGroups(allPopularStudylogs, new MemberGroups(memberGroupsBygroupType.get(MemberGroupType.BACKEND)), groupedMembers), pageable, memberId), - studylogsResponse(filterStudylogsByMemberGroups(allPopularStudylogs, new MemberGroups(memberGroupsBygroupType.get(MemberGroupType.ANDROID)), groupedMembers), pageable, memberId) - ); + studylogsResponse( + filterStudylogsByMemberGroups(allPopularStudylogs, new MemberGroups(memberGroupsBygroupType.get(MemberGroupType.FRONTEND)), groupedMembers), + pageable, + memberId), + studylogsResponse( + filterStudylogsByMemberGroups(allPopularStudylogs, new MemberGroups(memberGroupsBygroupType.get(MemberGroupType.BACKEND)), groupedMembers), + pageable, + memberId), + studylogsResponse( + filterStudylogsByMemberGroups(allPopularStudylogs, new MemberGroups(memberGroupsBygroupType.get(MemberGroupType.ANDROID)), groupedMembers), + pageable, + memberId)); } private List getSortedPopularStudyLogs(Pageable pageable) { - return studylogRepository.findAllByIdIn(getPopularStudylogIds(), pageable) - .stream() - .sorted(Comparator.comparing(Studylog::getPopularScore).reversed()) - .collect(toList()); + return studylogRepository.findAllByIdIn(getPopularStudylogIds(), pageable).stream() + .sorted(Comparator.comparing(Studylog::getPopularScore).reversed()).collect(toList()); } private List getPopularStudylogIds() { - return popularStudylogRepository.findAllByDeletedFalse() - .stream() - .map(PopularStudylog::getStudylogId) - .collect(toList()); + return popularStudylogRepository.findAllByDeletedFalse().stream() + .map(PopularStudylog::getStudylogId).collect(toList()); } - private StudylogsResponse studylogsResponse(final List studylogs, final Pageable pageable, final Long memberId) { + private StudylogsResponse studylogsResponse(final List studylogs, + final Pageable pageable, final Long memberId) { final PageImpl page = new PageImpl<>(studylogs, pageable, studylogs.size()); if (memberId == null) { return StudylogsResponse.of(page); diff --git a/backend/src/test/java/wooteco/prolog/studylog/application/PopularStudylogServiceTest.java b/backend/src/test/java/wooteco/prolog/studylog/application/PopularStudylogServiceTest.java index 1c2ebd865..0dedf34bd 100644 --- a/backend/src/test/java/wooteco/prolog/studylog/application/PopularStudylogServiceTest.java +++ b/backend/src/test/java/wooteco/prolog/studylog/application/PopularStudylogServiceTest.java @@ -216,80 +216,162 @@ void findPopularStudylogs_IsAnonymousMemberTrue() { @DisplayName("로그인한 멤버일 경우 스크랩과 읽음 여부가 표시하여 학습로그를 조회한다.") @Test void findPopularStudylogs_IsAnonymousMemberFalse() { - //given - final MemberGroup frontend = setUpMemberGroup("5기 프론트엔드", "5기 프론트엔드 설명"); - final MemberGroup backend = setUpMemberGroup("5기 백엔드", "5기 백엔드 설명"); - final MemberGroup android = setUpMemberGroup("5기 안드로이드", "5기 안드로이드 설명"); - - final Member split = setUpMember(1L, "박상현", "스플릿", 1L); - final Member journey = setUpMember(2L, "이지원", "져니", 2L); - - final GroupMember splitGroupMember = setUpGroupMember(split, backend); - final GroupMember journeyGroupMember = setUpGroupMember(journey, backend); - - final Studylog splitStudylog = setUpStudyLog(split); - final Studylog journeyStudylog = setUpStudyLog(journey); - - final List studylogs = Arrays.asList(splitStudylog, journeyStudylog); - final PageRequest pageRequest = PageRequest.of(0, 1); - final Page pages = new PageImpl<>(studylogs, pageRequest, 2); - final List memberGroups = Arrays.asList(frontend, backend, android); - final List groupMembers = Arrays.asList(splitGroupMember, - journeyGroupMember); - - when(groupMemberRepository.findAll()).thenReturn(groupMembers); - when(memberGroupRepository.findAll()).thenReturn(memberGroups); - when(studylogRepository.findAllByIdIn(any(), any())).thenReturn(pages); - when(studylogService.findScrapIds(any())).thenReturn(Arrays.asList(1L, 2L)); - doNothing().when(studylogService).updateScrap(any(), any()); - when(studylogService.findReadIds(any())).thenReturn(Arrays.asList(1L, 2L)); - doNothing().when(studylogService).updateRead(any(), any()); - - //when - final PopularStudylogsResponse popularStudylogs = popularStudylogService.findPopularStudylogs( - pageRequest, - split.getId(), - false - ); - - //then - final StudylogsResponse frontEndResponse = popularStudylogs.getFrontResponse(); - final StudylogsResponse backEndResponse = popularStudylogs.getBackResponse(); - final StudylogsResponse androidResponse = popularStudylogs.getAndroidResponse(); - final StudylogsResponse allResponse = popularStudylogs.getAllResponse(); - - verify(studylogService, times(4)).updateRead(any(), any()); - verify(studylogService, times(4)).updateScrap(any(), any()); - - assertAll( - () -> assertThat(frontEndResponse.getData()).isEmpty(), - () -> assertThat(frontEndResponse.getTotalPage()).isZero(), - () -> assertThat(frontEndResponse.getCurrPage()).isOne(), - () -> assertThat(frontEndResponse.getTotalSize()).isZero(), - - () -> assertThat(backEndResponse.getData()).hasSize(2), - () -> assertThat(backEndResponse.getTotalPage()).isEqualTo(2), - () -> assertThat(backEndResponse.getCurrPage()).isOne(), - () -> assertThat(backEndResponse.getTotalSize()).isEqualTo(2), - - () -> assertThat(androidResponse.getData()).isEmpty(), - () -> assertThat(androidResponse.getTotalPage()).isZero(), - () -> assertThat(androidResponse.getCurrPage()).isOne(), - () -> assertThat(androidResponse.getTotalSize()).isZero(), + { + //given + final MemberGroup frontend = setUpMemberGroup("5기 프론트엔드", "5기 프론트엔드 설명"); + final MemberGroup backend = setUpMemberGroup("5기 백엔드", "5기 백엔드 설명"); + final MemberGroup android = setUpMemberGroup("5기 안드로이드", "5기 안드로이드 설명"); + + final Member split = setUpMember(1L, "박상현", "스플릿", 1L); + final Member journey = setUpMember(2L, "이지원", "져니", 2L); + + final GroupMember splitGroupMember = setUpGroupMember(split, backend); + final GroupMember journeyGroupMember = setUpGroupMember(journey, backend); + + final Studylog splitStudylog = setUpStudyLog(split); + final Studylog journeyStudylog = setUpStudyLog(journey); + + final List studylogs = Arrays.asList(splitStudylog, journeyStudylog); + final PageRequest pageRequest = PageRequest.of(0, 1); + final Page pages = new PageImpl<>(studylogs, pageRequest, 2); + final List memberGroups = Arrays.asList(frontend, backend, android); + final List groupMembers = Arrays.asList(splitGroupMember, + journeyGroupMember); + + when(groupMemberRepository.findAll()).thenReturn(groupMembers); + when(memberGroupRepository.findAll()).thenReturn(memberGroups); + when(studylogRepository.findAllByIdIn(any(), any())).thenReturn(pages); + when(studylogService.findScrapIds(any())).thenReturn(Arrays.asList(1L, 2L)); + doNothing().when(studylogService).updateScrap(any(), any()); + when(studylogService.findReadIds(any())).thenReturn(Arrays.asList(1L, 2L)); + doNothing().when(studylogService).updateRead(any(), any()); + + //when + final PopularStudylogsResponse popularStudylogs = popularStudylogService.findPopularStudylogs( + pageRequest, + split.getId(), + false + ); + + //then + final StudylogsResponse frontEndResponse = popularStudylogs.getFrontResponse(); + final StudylogsResponse backEndResponse = popularStudylogs.getBackResponse(); + final StudylogsResponse androidResponse = popularStudylogs.getAndroidResponse(); + final StudylogsResponse allResponse = popularStudylogs.getAllResponse(); + + verify(studylogService, times(4)).updateRead(any(), any()); + verify(studylogService, times(4)).updateScrap(any(), any()); + + assertAll( + () -> assertThat(frontEndResponse.getData()).isEmpty(), + () -> assertThat(frontEndResponse.getTotalPage()).isZero(), + () -> assertThat(frontEndResponse.getCurrPage()).isOne(), + () -> assertThat(frontEndResponse.getTotalSize()).isZero(), + + () -> assertThat(backEndResponse.getData()).hasSize(2), + () -> assertThat(backEndResponse.getTotalPage()).isEqualTo(2), + () -> assertThat(backEndResponse.getCurrPage()).isOne(), + () -> assertThat(backEndResponse.getTotalSize()).isEqualTo(2), + + () -> assertThat(androidResponse.getData()).isEmpty(), + () -> assertThat(androidResponse.getTotalPage()).isZero(), + () -> assertThat(androidResponse.getCurrPage()).isOne(), + () -> assertThat(androidResponse.getTotalSize()).isZero(), + + () -> assertThat(allResponse.getData()).hasSize(2), + () -> assertThat(allResponse.getTotalPage()).isEqualTo(2), + () -> assertThat(allResponse.getCurrPage()).isOne(), + () -> assertThat(allResponse.getTotalSize()).isEqualTo(2) + ); + } + } - () -> assertThat(allResponse.getData()).hasSize(2), - () -> assertThat(allResponse.getTotalPage()).isEqualTo(2), - () -> assertThat(allResponse.getCurrPage()).isOne(), - () -> assertThat(allResponse.getTotalSize()).isEqualTo(2) - ); + @DisplayName("인기학습 로그를 분야별로 나누어서 반한한다.") + @Test + void findPopularStudylogs_filterGroupType() { + { + //given + final MemberGroup frontend = setUpMemberGroup("5기 프론트엔드", "5기 프론트엔드 설명"); + final MemberGroup backend = setUpMemberGroup("5기 백엔드", "5기 백엔드 설명"); + final MemberGroup android = setUpMemberGroup("5기 안드로이드", "5기 안드로이드 설명"); + + final Member split = setUpMember(1L, "박상현", "스플릿", 1L); + final Member journey = setUpMember(2L, "이지원", "져니", 2L); + final Member pooh = setUpMember(3L, "백승준", "푸우", 3L); + + final GroupMember splitGroupMember = setUpGroupMember(split, frontend); + final GroupMember journeyGroupMember = setUpGroupMember(journey, backend); + final GroupMember poohGroupMember = setUpGroupMember(pooh, android); + + final Studylog splitStudylog = setUpStudyLog(split); + final Studylog journeyStudylog = setUpStudyLog(journey); + final Studylog poohStudylog = setUpStudyLog(pooh); + + final List studylogs = Arrays.asList(splitStudylog, journeyStudylog, poohStudylog); + final PageRequest pageRequest = PageRequest.of(0, 3); + final Page pages = new PageImpl<>(studylogs, pageRequest, 1); + final List memberGroups = Arrays.asList(frontend, backend, android); + final List groupMembers = Arrays.asList(splitGroupMember, journeyGroupMember, poohGroupMember); + + final PopularStudylog splitPopularStudylog = setUpPopularStudylog(1L, + splitStudylog.getId()); + final PopularStudylog journeyPopularStudylog = setUpPopularStudylog(2L, + journeyStudylog.getId()); + final PopularStudylog poohPopularStudylog = setUpPopularStudylog(3L, + poohStudylog.getId()); + + final List popularStudylogs = Arrays.asList(splitPopularStudylog, + journeyPopularStudylog, poohPopularStudylog); + + when(popularStudylogRepository.findAllByDeletedFalse()).thenReturn(popularStudylogs); + when(groupMemberRepository.findAll()).thenReturn(groupMembers); + when(memberGroupRepository.findAll()).thenReturn(memberGroups); + when(studylogRepository.findAllByIdIn(any(), any())).thenReturn(pages); + + //when + final PopularStudylogsResponse popularStudylogsResponse = popularStudylogService.findPopularStudylogs( + pageRequest, + null, + true + ); + + //then + final StudylogsResponse frontEndResponse = popularStudylogsResponse.getFrontResponse(); + final StudylogsResponse backEndResponse = popularStudylogsResponse.getBackResponse(); + final StudylogsResponse androidResponse = popularStudylogsResponse.getAndroidResponse(); + final StudylogsResponse allResponse = popularStudylogsResponse.getAllResponse(); + + assertAll( + () -> assertThat(frontEndResponse.getData()).hasSize(1), + () -> assertThat(frontEndResponse.getTotalPage()).isEqualTo(1), + () -> assertThat(frontEndResponse.getCurrPage()).isOne(), + () -> assertThat(frontEndResponse.getTotalSize()).isEqualTo(1), + + () -> assertThat(backEndResponse.getData()).hasSize(1), + () -> assertThat(backEndResponse.getTotalPage()).isEqualTo(1), + () -> assertThat(backEndResponse.getCurrPage()).isOne(), + () -> assertThat(backEndResponse.getTotalSize()).isEqualTo(1), + + () -> assertThat(androidResponse.getData()).hasSize(1), + () -> assertThat(androidResponse.getTotalPage()).isEqualTo(1), + () -> assertThat(androidResponse.getCurrPage()).isOne(), + () -> assertThat(androidResponse.getTotalSize()).isEqualTo(1), + + () -> assertThat(allResponse.getData()).hasSize(3), + () -> assertThat(allResponse.getTotalPage()).isEqualTo(1), + () -> assertThat(allResponse.getCurrPage()).isOne(), + () -> assertThat(allResponse.getTotalSize()).isEqualTo(3) + ); + } } + private MemberGroup setUpMemberGroup(final String name, final String description) { return new MemberGroup(null, name, description); } private Member setUpMember(final Long id, final String userName, - final String nickname, final Long githubId) { + final String nickname, final Long githubId) { return new Member(id, userName, nickname, Role.CREW, githubId, "image url"); }