diff --git a/src/main/java/com/cabin/plat/domain/member/entity/Member.java b/src/main/java/com/cabin/plat/domain/member/entity/Member.java index 362d23c..f7e5517 100644 --- a/src/main/java/com/cabin/plat/domain/member/entity/Member.java +++ b/src/main/java/com/cabin/plat/domain/member/entity/Member.java @@ -1,14 +1,21 @@ package com.cabin.plat.domain.member.entity; import com.cabin.plat.global.common.BaseEntity; -import jakarta.persistence.*; -import java.time.LocalDateTime; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import java.util.Objects; -import lombok.*; -import org.hibernate.annotations.SQLDelete; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.hibernate.annotations.SQLRestriction; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; @Getter @Builder @@ -56,8 +63,12 @@ public class Member extends BaseEntity { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Member)) return false; + if (this == o) { + return true; + } + if (!(o instanceof Member)) { + return false; + } Member member = (Member) o; return id.equals(member.id) && clientId.equals(member.clientId); } diff --git a/src/main/java/com/cabin/plat/domain/member/service/MemberService.java b/src/main/java/com/cabin/plat/domain/member/service/MemberService.java index 0ebfa08..4532fc5 100644 --- a/src/main/java/com/cabin/plat/domain/member/service/MemberService.java +++ b/src/main/java/com/cabin/plat/domain/member/service/MemberService.java @@ -24,4 +24,6 @@ public interface MemberService { MemberResponse.MemberId resign(Member member); MemberResponse.MemberId updateNickname(Member member, String nickname); + + Member findMemberById(Long id); } diff --git a/src/main/java/com/cabin/plat/domain/member/service/MemberServiceImpl.java b/src/main/java/com/cabin/plat/domain/member/service/MemberServiceImpl.java index 782c37a..e64892c 100644 --- a/src/main/java/com/cabin/plat/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/cabin/plat/domain/member/service/MemberServiceImpl.java @@ -1,27 +1,33 @@ package com.cabin.plat.domain.member.service; -import com.cabin.plat.domain.member.dto.MemberResponse; -import com.cabin.plat.domain.member.dto.MemberResponse.*; -import com.cabin.plat.domain.member.entity.Member; -import com.cabin.plat.domain.member.entity.StreamType; -import com.cabin.plat.domain.member.mapper.MemberMapper; -import com.cabin.plat.domain.member.repository.MemberRepository; -import com.cabin.plat.global.exception.RestApiException; -import com.cabin.plat.global.exception.errorCode.MemberErrorCode; import com.cabin.plat.config.jwt.dto.TokenInfo; import com.cabin.plat.config.jwt.service.JwtUtil; import com.cabin.plat.domain.member.dto.MemberRequest; +import com.cabin.plat.domain.member.dto.MemberResponse; +import com.cabin.plat.domain.member.dto.MemberResponse.MemberId; +import com.cabin.plat.domain.member.dto.MemberResponse.ProfileInfo; +import com.cabin.plat.domain.member.dto.MemberResponse.ProfileStreamType; +import com.cabin.plat.domain.member.entity.Member; import com.cabin.plat.domain.member.entity.PermissionRole; import com.cabin.plat.domain.member.entity.RefreshToken; import com.cabin.plat.domain.member.entity.SocialType; +import com.cabin.plat.domain.member.entity.StreamType; import com.cabin.plat.domain.member.mapper.AuthenticationMapper; +import com.cabin.plat.domain.member.mapper.MemberMapper; +import com.cabin.plat.domain.member.repository.MemberRepository; import com.cabin.plat.domain.member.repository.RefreshTokenRepository; +import com.cabin.plat.domain.playlist.entity.PlaylistTrack; +import com.cabin.plat.domain.playlist.repository.PlaylistRepository; +import com.cabin.plat.domain.playlist.repository.PlaylistTrackRepository; +import com.cabin.plat.domain.track.entity.Track; +import com.cabin.plat.domain.track.repository.TrackRepository; +import com.cabin.plat.global.exception.RestApiException; +import com.cabin.plat.global.exception.errorCode.MemberErrorCode; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - @Service @RequiredArgsConstructor @@ -33,6 +39,9 @@ public class MemberServiceImpl implements MemberService { private final AuthenticationMapper authenticationMapper; private final RefreshTokenRepository refreshTokenRepository; private final MemberMapper memberMapper; + private final TrackRepository trackRepository; + private final PlaylistTrackRepository playlistTrackRepository; + private final PlaylistRepository playlistRepository; @Override public MemberResponse.MemberSignIn appleSocialSignIn( @@ -75,17 +84,16 @@ public MemberResponse.MemberSignIn signIn(MemberRequest.MemberSignInByEncryptedU if (jwtUtil.isExpired(refreshToken)) { return generateNewToken(member, isServiced); } - String newAccessToken = jwtUtil.createAccessToken(member.getId(), member.getClientId(), member.getPermissionRole()); + String newAccessToken = jwtUtil.createAccessToken(member.getId(), member.getClientId(), + member.getPermissionRole()); TokenInfo tokenInfo = authenticationMapper.toTokenInfo(newAccessToken, refreshToken); - refreshTokenRepository.save(new RefreshToken(member.getId(), refreshToken, newAccessToken)); return memberMapper.toMemberSignIn(member, tokenInfo, isServiced); } TokenInfo tokenInfo = authenticationMapper.toTokenInfo(accessToken, refreshToken); return memberMapper.toMemberSignIn(member, tokenInfo, isServiced); - } @Override @@ -116,7 +124,8 @@ public MemberId updateAvatarUrl(Member member, String avatar) { return memberMapper.toMemberId(updateMember.getId()); } - private Member findMemberById(Long id) { + @Override + public Member findMemberById(Long id) { return memberRepository.findById(id).orElseThrow(() -> new RestApiException(MemberErrorCode.MEMBER_NOT_FOUND)); } @@ -134,7 +143,8 @@ private MemberResponse.MemberSignIn generateNewToken(Member member, Boolean isSe MemberResponse.MemberTokens memberTokens = jwtUtil.refreshTokens(memberId, clientId, permissionRole); - TokenInfo tokenInfo = authenticationMapper.toTokenInfo(memberTokens.getAccessToken(), memberTokens.getRefreshToken()); + TokenInfo tokenInfo = authenticationMapper.toTokenInfo(memberTokens.getAccessToken(), + memberTokens.getRefreshToken()); return memberMapper.toMemberSignIn(member, tokenInfo, isServiced); } @@ -143,6 +153,11 @@ private MemberResponse.MemberSignIn generateNewToken(Member member, Boolean isSe @Transactional public MemberResponse.MemberId resign(Member member) { Member deleteMember = findMemberById(member.getId()); + playlistRepository.findAllByMember(deleteMember).forEach(playlist -> { + playlistTrackRepository.findAllByPlaylistIs(playlist).forEach(PlaylistTrack::delete); + playlist.delete(); + }); + trackRepository.findAllByMember(deleteMember).forEach(Track::delete); deleteMember.delete(); memberRepository.save(deleteMember); return memberMapper.toMemberId(deleteMember.getId()); diff --git a/src/main/java/com/cabin/plat/domain/playlist/mapper/PlaylistMapper.java b/src/main/java/com/cabin/plat/domain/playlist/mapper/PlaylistMapper.java index 8b0b1cb..e8b37d8 100644 --- a/src/main/java/com/cabin/plat/domain/playlist/mapper/PlaylistMapper.java +++ b/src/main/java/com/cabin/plat/domain/playlist/mapper/PlaylistMapper.java @@ -1,6 +1,5 @@ package com.cabin.plat.domain.playlist.mapper; -import com.cabin.plat.domain.member.dto.MemberResponse; import com.cabin.plat.domain.member.entity.Member; import com.cabin.plat.domain.playlist.dto.PlaylistRequest.PlaylistUpload; import com.cabin.plat.domain.playlist.dto.PlaylistResponse; @@ -52,7 +51,8 @@ public PlaylistResponse.Playlists toPlaylists(List playlistInfos) .build(); } - public PlaylistResponse.Playlists.PlaylistInfo toPlaylistInfo(Playlist playlist, List playlistTracks) { + public PlaylistResponse.Playlists.PlaylistInfo toPlaylistInfo(Playlist playlist, + List playlistTracks) { return PlaylistInfo.builder() .playlistId(playlist.getId()) .title(playlist.getTitle()) @@ -60,19 +60,26 @@ public PlaylistResponse.Playlists.PlaylistInfo toPlaylistInfo(Playlist playlist, .createdAt(playlist.getCreatedAt()) .uploaderNicknames(playlistTracks.stream() .map(PlaylistTrack::getTrack) - .map(track -> track.getMember().getNickname()) + .map(track -> { + if (track.getMember() == null) { + return "알수없음"; + } + return track.getMember().getNickname(); + }) .collect(Collectors.toUnmodifiableSet())) .build(); } - public PlaylistResponse.TrackDetailOrder toTrackDetailOrder(PlaylistTrack playlistTrack, TrackResponse.TrackDetail trackDetail) { + public PlaylistResponse.TrackDetailOrder toTrackDetailOrder(PlaylistTrack playlistTrack, + TrackResponse.TrackDetail trackDetail) { return PlaylistResponse.TrackDetailOrder.builder() .orderIndex(playlistTrack.getOrderIndex()) .trackDetail(trackDetail) .build(); } - public PlaylistResponse.PlaylistDetail toPlaylistDetail(Playlist playlist, List trackDetailOrders) { + public PlaylistResponse.PlaylistDetail toPlaylistDetail(Playlist playlist, + List trackDetailOrders) { return PlaylistResponse.PlaylistDetail.builder() .playlistId(playlist.getId()) .title(playlist.getTitle()) diff --git a/src/main/java/com/cabin/plat/domain/playlist/repository/PlaylistRepository.java b/src/main/java/com/cabin/plat/domain/playlist/repository/PlaylistRepository.java index aac1a42..ff8fb1c 100644 --- a/src/main/java/com/cabin/plat/domain/playlist/repository/PlaylistRepository.java +++ b/src/main/java/com/cabin/plat/domain/playlist/repository/PlaylistRepository.java @@ -9,5 +9,6 @@ public interface PlaylistRepository extends JpaRepository { Page findAllByMember(Member member, Pageable pageable); + List findAllByMember(Member member); Page findAllByMemberAndTitleContainingIgnoreCase(Member member, String title, Pageable pageable); } diff --git a/src/main/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImpl.java b/src/main/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImpl.java index 445b6cc..0a1d207 100644 --- a/src/main/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImpl.java +++ b/src/main/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImpl.java @@ -19,9 +19,13 @@ import com.cabin.plat.global.exception.RestApiException; import com.cabin.plat.global.exception.errorCode.PlaylistErrorCode; import com.cabin.plat.global.exception.errorCode.TrackErrorCode; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -101,6 +105,7 @@ public PlaylistResponse.Playlists getSearchedPlaylists(Member member, String tit @Override public PlaylistResponse.PlayListId deletePlaylist(Member member, Long playlistId) { Playlist playlist = findPlaylistByIdWithValidation(playlistId, member); + playlistTrackRepository.findAllByPlaylistIs(playlist).forEach(PlaylistTrack::delete); playlist.delete(); return playlistMapper.toPlaylistId(playlistId); } @@ -113,7 +118,8 @@ public PlaylistResponse.PlaylistDetail getPlaylistDetail(Member member, Long pla playlist); List trackDetailOrders = playlistTracks.stream() .map(playlistTrack -> { - TrackResponse.TrackDetail trackDetail = trackService.getTrackById(member, playlistTrack.getTrack().getId()); + TrackResponse.TrackDetail trackDetail = trackService.getTrackById(member, + playlistTrack.getTrack().getId()); return playlistMapper.toTrackDetailOrder(playlistTrack, trackDetail); }) .sorted(Comparator.comparingInt(PlaylistResponse.TrackDetailOrder::getOrderIndex)) @@ -123,7 +129,8 @@ public PlaylistResponse.PlaylistDetail getPlaylistDetail(Member member, Long pla @Transactional @Override - public PlaylistResponse.PlayListId updatePlaylistTitleAndImage(Member member, Long playlistId, PlaylistRequest.PlaylistEdit playlistEdit) { + public PlaylistResponse.PlayListId updatePlaylistTitleAndImage(Member member, Long playlistId, + PlaylistRequest.PlaylistEdit playlistEdit) { Playlist playlist = findPlaylistByIdWithValidation(playlistId, member); // 제목 및 이미지 변경 @@ -134,7 +141,8 @@ public PlaylistResponse.PlayListId updatePlaylistTitleAndImage(Member member, Lo @Transactional @Override - public PlaylistResponse.PlayListId addTrackToPlaylist(Member member, Long playlistId, PlaylistRequest.TrackId trackId) { + public PlaylistResponse.PlayListId addTrackToPlaylist(Member member, Long playlistId, + PlaylistRequest.TrackId trackId) { Playlist playlist = findPlaylistByIdWithValidation(playlistId, member); Track track = findTrackById(trackId.getTrackId()); @@ -169,7 +177,7 @@ public PlayListId updateTrackOrders(Member member, Long playlistId, PlaylistOrde validateTrackOrderCount(playlistOrders, playlistTracks); validateTrackIds(playlistOrders, playlistTracks); - for (PlaylistTrack playlistTrack: playlistTracks) { + for (PlaylistTrack playlistTrack : playlistTracks) { Long trackId = playlistTrack.getTrack().getId(); int newOrder = trackOrderMap.get(trackId); playlistTrack.setOrderIndex(newOrder); @@ -202,7 +210,8 @@ private List findPlaylistTracksInPlaylist(Playlist playlist) { } private static void validateTrackDuplicateInPlaylist(TrackId trackId, List playlistTracks) { - if (playlistTracks.stream().anyMatch(playlistTrack -> playlistTrack.getTrack().getId().equals(trackId.getTrackId()))) { + if (playlistTracks.stream() + .anyMatch(playlistTrack -> playlistTrack.getTrack().getId().equals(trackId.getTrackId()))) { throw new RestApiException(PlaylistErrorCode.PLAYLIST_TRACK_DUPLICATE); } } diff --git a/src/main/java/com/cabin/plat/domain/track/dto/TrackResponse.java b/src/main/java/com/cabin/plat/domain/track/dto/TrackResponse.java index 484eb35..8ec64e4 100644 --- a/src/main/java/com/cabin/plat/domain/track/dto/TrackResponse.java +++ b/src/main/java/com/cabin/plat/domain/track/dto/TrackResponse.java @@ -3,9 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; - public class TrackResponse { +public class TrackResponse { @Getter @Builder diff --git a/src/main/java/com/cabin/plat/domain/track/entity/Location.java b/src/main/java/com/cabin/plat/domain/track/entity/Location.java index 5ba6278..8a8a95f 100644 --- a/src/main/java/com/cabin/plat/domain/track/entity/Location.java +++ b/src/main/java/com/cabin/plat/domain/track/entity/Location.java @@ -1,8 +1,17 @@ package com.cabin.plat.domain.track.entity; import com.cabin.plat.global.common.BaseEntity; -import jakarta.persistence.*; -import lombok.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.SQLRestriction; @Getter @@ -10,6 +19,7 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor +@SQLRestriction("deleted_at is null") public class Location extends BaseEntity { @Id diff --git a/src/main/java/com/cabin/plat/domain/track/entity/Track.java b/src/main/java/com/cabin/plat/domain/track/entity/Track.java index 8fad225..0365c80 100644 --- a/src/main/java/com/cabin/plat/domain/track/entity/Track.java +++ b/src/main/java/com/cabin/plat/domain/track/entity/Track.java @@ -2,16 +2,25 @@ import com.cabin.plat.domain.member.entity.Member; import com.cabin.plat.global.common.BaseEntity; -import jakarta.persistence.*; -import lombok.*; -import org.hibernate.annotations.SQLRestriction; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @Builder @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor -@SQLRestriction("deleted_at is null") public class Track extends BaseEntity { @Id @@ -20,11 +29,11 @@ public class Track extends BaseEntity { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id", nullable = false) + @JoinColumn(name = "member_id") private Member member; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "location_id", nullable = false) + @JoinColumn(name = "location_id") private Location location; @Column(nullable = false) @@ -35,4 +44,14 @@ public class Track extends BaseEntity { @Column(name = "image_url") private String imageUrl; + + @Override + public void delete() { + super.delete(); + this.member = null; + this.content = "삭제된 게시글 입니다"; + this.imageUrl = ""; + this.location.delete(); + this.location = null; + } } \ No newline at end of file diff --git a/src/main/java/com/cabin/plat/domain/track/repository/TrackRepository.java b/src/main/java/com/cabin/plat/domain/track/repository/TrackRepository.java index c283d64..ac5935b 100644 --- a/src/main/java/com/cabin/plat/domain/track/repository/TrackRepository.java +++ b/src/main/java/com/cabin/plat/domain/track/repository/TrackRepository.java @@ -1,5 +1,6 @@ package com.cabin.plat.domain.track.repository; +import com.cabin.plat.domain.member.entity.Member; import com.cabin.plat.domain.track.entity.Track; import io.lettuce.core.dynamic.annotation.Param; import java.util.List; @@ -22,4 +23,5 @@ List findAllTracksWithinBounds( @Param("minLongitude") double minLongitude, @Param("maxLongitude") double maxLongitude); Page findAll(Pageable pageable); + List findAllByMember(Member member); } \ No newline at end of file diff --git a/src/main/java/com/cabin/plat/domain/track/service/TrackServiceImpl.java b/src/main/java/com/cabin/plat/domain/track/service/TrackServiceImpl.java index 7a01cf3..db37397 100644 --- a/src/main/java/com/cabin/plat/domain/track/service/TrackServiceImpl.java +++ b/src/main/java/com/cabin/plat/domain/track/service/TrackServiceImpl.java @@ -5,9 +5,15 @@ import com.cabin.plat.domain.track.dto.TrackResponse; import com.cabin.plat.domain.track.dto.TrackResponse.TrackDetail; import com.cabin.plat.domain.track.dto.TrackResponse.TrackId; -import com.cabin.plat.domain.track.entity.*; +import com.cabin.plat.domain.track.entity.Location; +import com.cabin.plat.domain.track.entity.Track; +import com.cabin.plat.domain.track.entity.TrackLike; +import com.cabin.plat.domain.track.entity.TrackReport; import com.cabin.plat.domain.track.mapper.TrackMapper; -import com.cabin.plat.domain.track.repository.*; +import com.cabin.plat.domain.track.repository.LocationRepository; +import com.cabin.plat.domain.track.repository.TrackLikeRepository; +import com.cabin.plat.domain.track.repository.TrackReportRepository; +import com.cabin.plat.domain.track.repository.TrackRepository; import com.cabin.plat.global.exception.RestApiException; import com.cabin.plat.global.exception.errorCode.TrackErrorCode; import com.cabin.plat.global.util.geocoding.AddressInfo; @@ -47,10 +53,12 @@ public TrackResponse.TrackMapList getTracksByLocation( double maxLongitude = Math.max(startLongitude, endLongitude); List tracks = trackRepository.findAllTracksWithinBounds( - minLatitude, - maxLatitude, - minLongitude, - maxLongitude); + minLatitude, + maxLatitude, + minLongitude, + maxLongitude).stream() + .filter(track -> track.getDeletedAt() == null) + .toList(); List trackMaps = tracks.stream() .map(track -> trackMapper.toTrackMap( @@ -118,6 +126,7 @@ public TrackResponse.TrackDetailList getTrackFeeds(Member member, int page, int List tracks = trackRepository.findAll(pageable).getContent(); List trackDetails = tracks.stream() + .filter(track -> track.getDeletedAt() == null) .map(track -> getTrackDetail(member, track)) .toList(); @@ -148,24 +157,52 @@ public TrackResponse.ReportId reportTrack(Member member, Long trackId) { } private TrackDetail getTrackDetail(Member member, Track track) { - TrackResponse.MemberInfo memberInfo = trackMapper.toMemberInfo( - track.getMember().getId(), - track.getMember().getNickname(), - track.getMember().getAvatar() - ); + TrackResponse.MemberInfo memberInfo; + Double latitude; + Double longitude; + String buildingName; + String address; + int likeCount; + boolean isLiked; + + if (track.getDeletedAt() != null) { + memberInfo = trackMapper.toMemberInfo( + null, + "알수없음", + "" + ); + latitude = 0.0; + longitude = 0.0; + buildingName = ""; + address = ""; + likeCount = 0; + isLiked = false; + } else { + memberInfo = trackMapper.toMemberInfo( + track.getMember().getId(), + track.getMember().getNickname(), + track.getMember().getAvatar() + ); + latitude = track.getLocation().getLatitude(); + longitude = track.getLocation().getLongitude(); + buildingName = track.getLocation().getBuildingName(); + address = track.getLocation().getAddress(); + likeCount = trackLikeRepository.countByTrack(track); + isLiked = trackLikeRepository.existsByMemberAndTrack(member, track); + } return trackMapper.toTrackDetail( track.getId(), track.getIsrc(), track.getCreatedAt(), - track.getLocation().getLatitude(), - track.getLocation().getLongitude(), - track.getLocation().getBuildingName(), - track.getLocation().getAddress(), + latitude, + longitude, + buildingName, + address, track.getImageUrl(), track.getContent(), - trackLikeRepository.countByTrack(track), - trackLikeRepository.existsByMemberAndTrack(member, track), + likeCount, + isLiked, memberInfo ); } diff --git a/src/test/java/com/cabin/plat/domain/member/service/MemberServiceImplTest.java b/src/test/java/com/cabin/plat/domain/member/service/MemberServiceImplTest.java new file mode 100644 index 0000000..37f2c07 --- /dev/null +++ b/src/test/java/com/cabin/plat/domain/member/service/MemberServiceImplTest.java @@ -0,0 +1,116 @@ +package com.cabin.plat.domain.member.service; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import com.cabin.plat.domain.member.entity.Member; +import com.cabin.plat.domain.member.entity.PermissionRole; +import com.cabin.plat.domain.member.entity.SocialType; +import com.cabin.plat.domain.member.entity.StreamType; +import com.cabin.plat.domain.member.repository.MemberRepository; +import com.cabin.plat.domain.member.repository.RefreshTokenRepository; +import com.cabin.plat.domain.test.service.TestService; +import com.cabin.plat.global.exception.RestApiException; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class MemberServiceImplTest { + + @Autowired + private MemberService memberService; + + @Autowired + private TestService testService; + + @Autowired + private RefreshTokenRepository refreshTokenRepository; + + private List members; + @Autowired + private MemberRepository memberRepository; + + @BeforeEach + void setUp() { + members = createTestMembers(); + testService.addMockData(members.get(0)); + testService.addMockData(members.get(1)); + testService.addMockData(members.get(2)); + } + + private List createTestMembers() { + List members = List.of( + Member.builder() + .permissionRole(PermissionRole.CLIENT) + .clientId("0") + .name("이름0") + .email("이메일0") + .nickname("닉네임0") + .avatar("https://testimage1.avatar0/") + .streamType(StreamType.APPLE_MUSIC) + .socialType(SocialType.APPLE) + .build(), + Member.builder() + .permissionRole(PermissionRole.CLIENT) + .clientId("1") + .name("이름1") + .email("이메일1") + .nickname("닉네임1") + .avatar("https://testimage1.avatar1/") + .streamType(StreamType.APPLE_MUSIC) + .socialType(SocialType.APPLE) + .build(), + Member.builder() + .permissionRole(PermissionRole.CLIENT) + .clientId("2") + .name("이름2") + .email("이메일2") + .nickname("닉네임2") + .avatar("https://testimage1.avatar2/") + .streamType(StreamType.APPLE_MUSIC) + .socialType(SocialType.APPLE) + .build() + ); + + return memberRepository.saveAll(members); + } + + @Nested + class ResignTest { + + @Test + @Disabled + void 회원_탈퇴시_프로필_정보_삭제() { + // given + Member member = members.get(0); + + // when + memberService.resign(member); + + // then + assertThatThrownBy(() -> memberService.findMemberById(member.getId())) + .isInstanceOf(RestApiException.class); + } + + @Test + @Disabled + void 회원_탈퇴시_리프레시토큰_삭제() { + // given + Member member = members.get(0); + + // when + assertThat(refreshTokenRepository.findById(member.getId())).isNotEmpty(); + memberService.resign(member); + + // then + assertThat(refreshTokenRepository.findById(member.getId())).isEmpty(); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImplTest.java b/src/test/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImplTest.java index 1693491..31a0812 100644 --- a/src/test/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImplTest.java +++ b/src/test/java/com/cabin/plat/domain/playlist/service/PlaylistServiceImplTest.java @@ -1,9 +1,14 @@ package com.cabin.plat.domain.playlist.service; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; -import com.cabin.plat.domain.member.entity.*; +import com.cabin.plat.domain.member.entity.Member; +import com.cabin.plat.domain.member.entity.PermissionRole; +import com.cabin.plat.domain.member.entity.SocialType; +import com.cabin.plat.domain.member.entity.StreamType; import com.cabin.plat.domain.member.repository.MemberRepository; +import com.cabin.plat.domain.member.service.MemberService; import com.cabin.plat.domain.playlist.dto.PlaylistRequest; import com.cabin.plat.domain.playlist.dto.PlaylistRequest.PlaylistUpload; import com.cabin.plat.domain.playlist.dto.PlaylistRequest.TrackOrder; @@ -13,16 +18,27 @@ import com.cabin.plat.domain.playlist.entity.PlaylistTrack; import com.cabin.plat.domain.playlist.repository.PlaylistRepository; import com.cabin.plat.domain.playlist.repository.PlaylistTrackRepository; +import com.cabin.plat.domain.track.dto.TrackResponse.TrackDetail; import com.cabin.plat.domain.track.entity.Location; import com.cabin.plat.domain.track.entity.Track; import com.cabin.plat.domain.track.repository.LocationRepository; import com.cabin.plat.domain.track.repository.TrackRepository; +import com.cabin.plat.domain.track.service.TrackService; import com.cabin.plat.global.exception.RestApiException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.stream.IntStream; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; @SpringBootTest @@ -32,6 +48,12 @@ class PlaylistServiceImplTest { @Autowired private PlaylistService playlistService; + @Autowired + private TrackService trackService; + + @Autowired + private MemberService memberService; + @Autowired private PlaylistRepository playlistRepository; @@ -64,9 +86,12 @@ void setUp() { private List createTestMembers() { List members = new ArrayList<>(); - Member member1 = new Member(null, PermissionRole.CLIENT, "1", "이름1", "이메일1", "닉네임1", "https://testimage1.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); - Member member2 = new Member(null, PermissionRole.CLIENT, "2", "이름2", "이메일2", "닉네임2", "https://testimage2.avatar/", StreamType.SPOTIFY, SocialType.APPLE); - Member member3 = new Member(null, PermissionRole.CLIENT, "3", "이름3", "이메일3", "닉네임3", "https://testimage3.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); + Member member1 = new Member(null, PermissionRole.CLIENT, "1", "이름1", "이메일1", "닉네임1", + "https://testimage1.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); + Member member2 = new Member(null, PermissionRole.CLIENT, "2", "이름2", "이메일2", "닉네임2", + "https://testimage2.avatar/", StreamType.SPOTIFY, SocialType.APPLE); + Member member3 = new Member(null, PermissionRole.CLIENT, "3", "이름3", "이메일3", "닉네임3", + "https://testimage3.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); members.add(memberRepository.save(member1)); members.add(memberRepository.save(member2)); @@ -80,7 +105,8 @@ private List createTestLocations() { Location domitory18 = new Location(null, "Dormitory 16 (DICE)", "경상북도 포항시 남구 지곡동 287", 36.017062, 129.321993); Location burgerKing = new Location(null, "버거킹 포항공대점", "경상북도 포항시 남구 청암로 77", 36.015733, 129.322700); - Location c5 = new Location(null, "Apple Developer Academy @ POSTECH(애플 디벨로퍼 아카데미)", "경상북도 포항시 남구 청암로 77", 36.014335, 129.325951); + Location c5 = new Location(null, "Apple Developer Academy @ POSTECH(애플 디벨로퍼 아카데미)", "경상북도 포항시 남구 청암로 77", + 36.014335, 129.325951); Location liversAcademy = new Location(null, "", "경상북도 포항시 남구 효자동 222-24", 36.009002, 129.332852); Location young1Dae = new Location(null, "영일대 해수욕장", "경상북도 포항시 북구 두호동 1015", 36.056074, 129.378190); Location hwangLidanGil = new Location(null, "황리단길", "경상북도 경주시 황남동 포석로 일대", 35.837555, 129.209712); @@ -98,11 +124,16 @@ private List createTestLocations() { private List createTestTracks(List members, List locations) { List tracks = new ArrayList<>(); Track track0 = new Track(null, members.get(0), locations.get(0), "isrc1", "기숙사에서 한곡", "https://testimage1.com"); - Track track1 = new Track(null, members.get(0), locations.get(1), "isrc2", "버거킹마을 공연 최애 노래", "https://testimage2.com"); - Track track2 = new Track(null, members.get(1), locations.get(2), "isrc3", "아카데미는 이 노래지", "https://testimage3.com"); - Track track3 = new Track(null, members.get(1), locations.get(3), "isrc4", "리버스아카데미 노래", "https://testimage4.com"); - Track track4 = new Track(null, members.get(2), locations.get(4), "isrc5", "영일대는 이노래지", "https://testimage5.com"); - Track track5 = new Track(null, members.get(2), locations.get(5), "isrc6", "황리단길과 어울리는", "https://testimage5.com"); + Track track1 = new Track(null, members.get(0), locations.get(1), "isrc2", "버거킹마을 공연 최애 노래", + "https://testimage2.com"); + Track track2 = new Track(null, members.get(1), locations.get(2), "isrc3", "아카데미는 이 노래지", + "https://testimage3.com"); + Track track3 = new Track(null, members.get(1), locations.get(3), "isrc4", "리버스아카데미 노래", + "https://testimage4.com"); + Track track4 = new Track(null, members.get(2), locations.get(4), "isrc5", "영일대는 이노래지", + "https://testimage5.com"); + Track track5 = new Track(null, members.get(2), locations.get(5), "isrc6", "황리단길과 어울리는", + "https://testimage5.com"); tracks.add(trackRepository.save(track0)); tracks.add(trackRepository.save(track1)); @@ -122,11 +153,11 @@ private List createTestPlaylistUpload() { .trackId(tracks.get(0).getId()) .orderIndex(0) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(1).getId()) .orderIndex(1) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(2).getId()) .orderIndex(2) .build() @@ -141,11 +172,11 @@ private List createTestPlaylistUpload() { .trackId(tracks.get(3).getId()) .orderIndex(0) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(4).getId()) .orderIndex(1) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(5).getId()) .orderIndex(2) .build() @@ -160,23 +191,23 @@ private List createTestPlaylistUpload() { .trackId(tracks.get(0).getId()) .orderIndex(0) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(1).getId()) .orderIndex(1) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(2).getId()) .orderIndex(2) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(3).getId()) .orderIndex(3) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(4).getId()) .orderIndex(4) .build() - ,TrackOrder.builder() + , TrackOrder.builder() .trackId(tracks.get(5).getId()) .orderIndex(5) .build() @@ -201,7 +232,7 @@ private List createTestPlaylists(List members, List uploaderNicknames = playlists0.getPlaylists().get(0).getUploaderNicknames(); + assertThat(title).isEqualTo("플레이리스트 제목0"); + assertThat(imageUrl).isEqualTo("https://test0.com"); + assertThat(uploaderNicknames).containsExactlyInAnyOrder(member0.getNickname(), "알수없음"); + } + + @Test + void 삭제된_트랙이_포함된_플레이리스트_조회시_삭제된_트랙은_uploaderNickname_닉네임_알수없음으로_가져오기() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + trackService.deleteTrack(member1, tracks.get(2).getId()); // 멤버 1이 업로드한 트랙2 삭제 (트랙2는 멤버0이 만든 플레이리스트0에 포함) + + // when + PlaylistResponse.Playlists playlists0 = playlistService.getPlaylists(member0, 0, 20); + + // then + String title = playlists0.getPlaylists().get(0).getTitle(); + String imageUrl = playlists0.getPlaylists().get(0).getPlaylistImageUrl(); + Set uploaderNicknames = playlists0.getPlaylists().get(0).getUploaderNicknames(); + assertThat(title).isEqualTo("플레이리스트 제목0"); + assertThat(imageUrl).isEqualTo("https://test0.com"); + assertThat(uploaderNicknames).containsExactlyInAnyOrder(member0.getNickname(), "알수없음"); + } + + @Test + void 회원_탈퇴시_해당_회원이_올린_플레이리스트_모두_소프트_삭제() { + // given + Member member = members.get(0); + List sorts = new ArrayList<>(); + sorts.add(Sort.Order.desc("createdAt")); + Pageable pageable = PageRequest.of(0, 20, Sort.by(sorts)); + + // when + memberService.resign(member); + + // then + playlistRepository.findAllByMember(member, pageable).forEach(playlist -> { + assertThat(playlist.getDeletedAt()).isNotNull(); + }); + } } @Nested - class GetSearchedPlaylistsTest { + class GetSearchedPlaylistsTests { @Test void 플레이리스트_제목_검색_2개_중에_하나만_검색_성공() { @@ -407,6 +493,44 @@ class GetSearchedPlaylistsTest { // then assertThat(playlists.getPlaylists()).isEmpty(); } + + @Test + void 회원_탈퇴한_멤버의_트랙이_포함된_플레이리스트_조회시_uploaderNickname_닉네임_알수없음으로_가져오기() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + memberService.resign(member1); // 멤버 1이 탈퇴 해서 멤버 1이 업로드한 트랙2가 삭제 (트랙2는 멤버0이 만든 플레이리스트0에 포함) + + // when + PlaylistResponse.Playlists playlists0 = playlistService.getSearchedPlaylists(member0, "플레이리스트", 0, 20); + + // then + String title = playlists0.getPlaylists().get(0).getTitle(); + String imageUrl = playlists0.getPlaylists().get(0).getPlaylistImageUrl(); + Set uploaderNicknames = playlists0.getPlaylists().get(0).getUploaderNicknames(); + assertThat(title).isEqualTo("플레이리스트 제목0"); + assertThat(imageUrl).isEqualTo("https://test0.com"); + assertThat(uploaderNicknames).containsExactlyInAnyOrder(member0.getNickname(), "알수없음"); + } + + @Test + void 삭제된_트랙이_포함된_플레이리스트_조회시_삭제된_트랙은_uploaderNickname_닉네임_알수없음으로_가져오기() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + trackService.deleteTrack(member1, tracks.get(2).getId()); // 멤버 1이 업로드한 트랙2 삭제 (트랙2는 멤버0이 만든 플레이리스트0에 포함) + + // when + PlaylistResponse.Playlists playlists0 = playlistService.getSearchedPlaylists(member0, "플레이리스트", 0, 20); + + // then + String title = playlists0.getPlaylists().get(0).getTitle(); + String imageUrl = playlists0.getPlaylists().get(0).getPlaylistImageUrl(); + Set uploaderNicknames = playlists0.getPlaylists().get(0).getUploaderNicknames(); + assertThat(title).isEqualTo("플레이리스트 제목0"); + assertThat(imageUrl).isEqualTo("https://test0.com"); + assertThat(uploaderNicknames).containsExactlyInAnyOrder(member0.getNickname(), "알수없음"); + } } @Nested @@ -469,10 +593,59 @@ class GetPlaylistDetailTests { PlaylistResponse.PlaylistDetail playlistDetail = playlistService.getPlaylistDetail(member, playlistId); // then - assertPlaylistTrackDetails(playlistDetail); } + @Test + void 회원_탈퇴한_멤버의_트랙이_포함된_플레이리스트_디테일_조회시_노래정보_제외_나머지_삭제처리() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + Long playlist0Id = playlistIds.get(0); + memberService.resign(member1); + + // when + TrackDetail trackDetail = playlistService.getPlaylistDetail(member0, playlist0Id).getTracks().get(2) + .getTrackDetail(); // 탈퇴한 멤버가 업로드한 트랙 + + // then + assertThat(trackDetail.getTrackId()).isNotNull(); + assertThat(trackDetail.getIsrc()).isNotBlank(); + assertThat(trackDetail.getCreatedAt()).isNotNull(); + assertThat(trackDetail.getLatitude()).isZero(); + assertThat(trackDetail.getLongitude()).isZero(); + assertThat(trackDetail.getBuildingName()).isBlank(); + assertThat(trackDetail.getAddress()).isBlank(); + assertThat(trackDetail.getImageUrl()).isEqualTo(""); + assertThat(trackDetail.getContent()).isEqualTo("삭제된 게시글 입니다"); + assertThat(trackDetail.getLikeCount()).isZero(); + assertThat(trackDetail.getIsLiked()).isFalse(); + assertThat(trackDetail.getMember().getMemberNickname()).isEqualTo("알수없음"); + assertThat(trackDetail.getMember().getAvatar()).isEqualTo(""); + } + + @Test + void 삭제한_트랙이_포함된_플레이리스트_디테일_조회시_노래정보_제외_나머지_삭제처리() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + Long playlist0Id = playlistIds.get(0); + + // when + trackService.deleteTrack(member1, tracks.get(2).getId()); + TrackDetail newTrackDetail = playlistService.getPlaylistDetail(member0, playlist0Id).getTracks().get(2) + .getTrackDetail(); // 탈퇴한 멤버가 업로드한 트랙 + + // then + assertThat(newTrackDetail.getIsrc()).isEqualTo("isrc3"); + assertThat(newTrackDetail.getLikeCount()).isEqualTo(0); + assertThat(newTrackDetail.getIsLiked()).isFalse(); + assertThat(newTrackDetail.getContent()).isEqualTo("삭제된 게시글 입니다"); + assertThat(newTrackDetail.getImageUrl()).isEqualTo(""); + assertThat(newTrackDetail.getMember().getMemberNickname()).isEqualTo("알수없음"); + assertThat(newTrackDetail.getMember().getAvatar()).isEqualTo(""); + } + private void assertPlaylistTrackDetails(PlaylistResponse.PlaylistDetail playlistDetail) { PlaylistResponse.TrackDetailOrder trackDetailOrder0 = playlistDetail.getTracks().get(0); PlaylistResponse.TrackDetailOrder trackDetailOrder1 = playlistDetail.getTracks().get(1); @@ -489,77 +662,50 @@ private void assertPlaylistTrackDetails(PlaylistResponse.PlaylistDetail playlist @Nested class UpdatePlaylistTests { -// private PlaylistRequest.PlaylistUpload newPlaylistUpload = PlaylistUpload.builder() -// .title("플레이리스트 제목2") -// .playlistImageUrl("https://test2.com") -// .tracks(List.of( -// TrackOrder.builder() -// .trackId(tracks.get(4).getId()) -// .orderIndex(0) -// .build() -// ,TrackOrder.builder() -// .trackId(tracks.get(5).getId()) -// .orderIndex(1) -// .build() -// )) -// .build(); -// -// @Test -// void 플레이리스트_수정_성공() { -// // given -// Member member = members.get(0); -// Long playlistId = playlistIds.get(0); -// -// // when -// playlistService.updatePlaylistTitleAndImage(member, playlistId, newPlaylistUpload); -// Optional optionalPlaylist = playlistRepository.findById(playlistId); -// -// // then -// assertThat(optionalPlaylist.isPresent()).isTrue(); -// Playlist playlist = optionalPlaylist.get(); -// -// // 변경된 정보 -// assertThat(playlist.getTitle()).isEqualTo("플레이리스트 제목2"); -// assertThat(playlist.getPlaylistImageUrl()).isEqualTo("https://test2.com"); -// assertThat(playlist.getPlaylistTracks().get(0).getId()).isEqualTo(tracks.get(4).getId()); -// assertThat(playlist.getPlaylistTracks().get(0).getOrderIndex()).isEqualTo(0); -// assertThat(playlist.getPlaylistTracks().get(1).getId()).isEqualTo(tracks.get(5).getId()); -// assertThat(playlist.getPlaylistTracks().get(1).getOrderIndex()).isEqualTo(1); -// } -// -// @Test -// void 플레이리스트_수정_실패_권한없음() { -// // given -// Member member = members.get(2); -// Long playlistId = playlistIds.get(0); -// -// // when -// playlistService.updatePlaylistTitleAndImage(member, playlistId, newPlaylistUpload); -// Optional optionalPlaylist = playlistRepository.findById(playlistId); -// -// // then -// assertThat(optionalPlaylist.isPresent()).isTrue(); -// Playlist playlist = optionalPlaylist.get(); -// -// // 변경안된 정보 -// assertThat(playlist.getTitle()).isEqualTo("플레이리스트 제목0"); -// assertThat(playlist.getPlaylistImageUrl()).isEqualTo("https://test0.com"); -// assertThat(playlist.getPlaylistTracks().get(0).getId()).isEqualTo(tracks.get(0).getId()); -// assertThat(playlist.getPlaylistTracks().get(0).getOrderIndex()).isEqualTo(0); -// assertThat(playlist.getPlaylistTracks().get(1).getId()).isEqualTo(tracks.get(1).getId()); -// assertThat(playlist.getPlaylistTracks().get(1).getOrderIndex()).isEqualTo(1); -// } -// -// @Test -// void 플레이리스트_수정_실패_권한없음_예외발생() { -// // given -// Member member = members.get(2); -// Long playlistId = playlistIds.get(0); -// -// // when then -// assertThatThrownBy(() -> playlistService.updatePlaylistTitleAndImage(member, playlistId, newPlaylistUpload)) -// .isInstanceOf(RestApiException.class); -// } + + private PlaylistRequest.PlaylistEdit playlistEdit = PlaylistRequest.PlaylistEdit.builder() + .title("플레이리스트 제목2") + .playlistImageUrl("https://test2.com") + .build(); + + @Test + void 플레이리스트_수정_성공() { + // given + Member member = members.get(0); + Long playlistId = playlistIds.get(0); + + // when + playlistService.updatePlaylistTitleAndImage(member, playlistId, playlistEdit); + Optional optionalPlaylist = playlistRepository.findById(playlistId); + + // then + assertThat(optionalPlaylist.isPresent()).isTrue(); + Playlist playlist = optionalPlaylist.get(); + + // 변경된 정보 + assertThat(playlist.getTitle()).isEqualTo("플레이리스트 제목2"); + assertThat(playlist.getPlaylistImageUrl()).isEqualTo("https://test2.com"); + } + + @Test + void 플레이리스트_수정_실패_권한없음_예외발생() { + // given + Member member = members.get(2); + Long playlistId = playlistIds.get(0); + + // when then + assertThatThrownBy(() -> playlistService.updatePlaylistTitleAndImage(member, playlistId, playlistEdit)) + .isInstanceOf(RestApiException.class); + + Optional optionalPlaylist = playlistRepository.findById(playlistId); + + // then + assertThat(optionalPlaylist.isPresent()).isTrue(); + Playlist playlist = optionalPlaylist.get(); + + assertThat(playlist.getTitle()).isEqualTo("플레이리스트 제목0"); + assertThat(playlist.getPlaylistImageUrl()).isEqualTo("https://test0.com"); + } } @Nested @@ -753,7 +899,8 @@ class DeleteTrackFromPlaylistTest { Long deleteTrackId = tracks.get(1).getId(); // when - PlaylistResponse.PlayListId responsePlaylistId = playlistService.deleteTrackFromPlaylist(member, playlistId, deleteTrackId); + PlaylistResponse.PlayListId responsePlaylistId = playlistService.deleteTrackFromPlaylist(member, playlistId, + deleteTrackId); // then assertThat(responsePlaylistId.getPlaylistId()).isEqualTo(playlistId); @@ -773,7 +920,8 @@ class DeleteTrackFromPlaylistTest { Long deleteTrackId = tracks.get(1).getId(); // when - PlaylistResponse.PlayListId responsePlaylistId = playlistService.deleteTrackFromPlaylist(member, playlistId, deleteTrackId); + PlaylistResponse.PlayListId responsePlaylistId = playlistService.deleteTrackFromPlaylist(member, playlistId, + deleteTrackId); // then Optional optionalPlaylist = playlistRepository.findById(playlistId); diff --git a/src/test/java/com/cabin/plat/domain/track/service/TrackServiceTest.java b/src/test/java/com/cabin/plat/domain/track/service/TrackServiceTest.java index 6dfb57d..f1788a7 100644 --- a/src/test/java/com/cabin/plat/domain/track/service/TrackServiceTest.java +++ b/src/test/java/com/cabin/plat/domain/track/service/TrackServiceTest.java @@ -1,16 +1,23 @@ package com.cabin.plat.domain.track.service; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; -import com.cabin.plat.domain.member.entity.*; +import com.cabin.plat.domain.member.entity.Member; +import com.cabin.plat.domain.member.entity.PermissionRole; +import com.cabin.plat.domain.member.entity.SocialType; +import com.cabin.plat.domain.member.entity.StreamType; import com.cabin.plat.domain.member.repository.MemberRepository; +import com.cabin.plat.domain.member.service.MemberService; import com.cabin.plat.domain.track.dto.TrackRequest; import com.cabin.plat.domain.track.dto.TrackResponse; import com.cabin.plat.domain.track.dto.TrackResponse.TrackDetail; +import com.cabin.plat.domain.track.dto.TrackResponse.TrackMap; import com.cabin.plat.domain.track.entity.Location; import com.cabin.plat.domain.track.entity.Track; import com.cabin.plat.domain.track.entity.TrackReport; import com.cabin.plat.domain.track.repository.LocationRepository; +import com.cabin.plat.domain.track.repository.TrackLikeRepository; import com.cabin.plat.domain.track.repository.TrackReportRepository; import com.cabin.plat.domain.track.repository.TrackRepository; import com.cabin.plat.global.exception.RestApiException; @@ -31,6 +38,9 @@ class TrackServiceTest { @Autowired private TrackService trackService; + @Autowired + private MemberService memberService; + @Autowired private TrackRepository trackRepository; @@ -43,6 +53,9 @@ class TrackServiceTest { @Autowired private TrackReportRepository trackReportRepository; + @Autowired + private TrackLikeRepository trackLikeRepository; + private List members; private List locations; private List tracks; @@ -59,9 +72,12 @@ void setUp() { private List createTestMembers() { List members = new ArrayList<>(); - Member member1 = new Member(null, PermissionRole.CLIENT, "1", "이름1", "이메일1", "닉네임1", "https://testimage1.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); - Member member2 = new Member(null, PermissionRole.CLIENT, "2", "이름2", "이메일2", "닉네임2", "https://testimage2.avatar/", StreamType.SPOTIFY, SocialType.APPLE); - Member member3 = new Member(null, PermissionRole.CLIENT, "3", "이름3", "이메일3", "닉네임3", "https://testimage3.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); + Member member1 = new Member(null, PermissionRole.CLIENT, "1", "이름1", "이메일1", "닉네임1", + "https://testimage1.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); + Member member2 = new Member(null, PermissionRole.CLIENT, "2", "이름2", "이메일2", "닉네임2", + "https://testimage2.avatar/", StreamType.SPOTIFY, SocialType.APPLE); + Member member3 = new Member(null, PermissionRole.CLIENT, "3", "이름3", "이메일3", "닉네임3", + "https://testimage3.avatar/", StreamType.APPLE_MUSIC, SocialType.APPLE); members.add(memberRepository.save(member1)); members.add(memberRepository.save(member2)); @@ -75,7 +91,8 @@ private List createTestLocations() { Location domitory18 = new Location(null, "Dormitory 16 (DICE)", "경상북도 포항시 남구 지곡동 287", 36.017062, 129.321993); Location burgerKing = new Location(null, "버거킹 포항공대점", "경상북도 포항시 남구 청암로 77", 36.015733, 129.322700); - Location c5 = new Location(null, "Apple Developer Academy @ POSTECH(애플 디벨로퍼 아카데미)", "경상북도 포항시 남구 청암로 77", 36.014335, 129.325951); + Location c5 = new Location(null, "Apple Developer Academy @ POSTECH(애플 디벨로퍼 아카데미)", "경상북도 포항시 남구 청암로 77", + 36.014335, 129.325951); Location liversAcademy = new Location(null, "", "경상북도 포항시 남구 효자동 222-24", 36.009002, 129.332852); Location young1Dae = new Location(null, "영일대 해수욕장", "경상북도 포항시 북구 두호동 1015", 36.056074, 129.378190); Location hwangLidanGil = new Location(null, "황리단길", "경상북도 경주시 황남동 포석로 일대", 35.837555, 129.209712); @@ -93,11 +110,16 @@ private List createTestLocations() { private List createTestTracks(List members, List locations) { List tracks = new ArrayList<>(); Track track1 = new Track(null, members.get(0), locations.get(0), "isrc1", "기숙사에서 한곡", "https://testimage1.com"); - Track track2 = new Track(null, members.get(0), locations.get(1), "isrc2", "버거킹마을 공연 최애 노래", "https://testimage2.com"); - Track track3 = new Track(null, members.get(1), locations.get(2), "isrc3", "아카데미는 이 노래지", "https://testimage3.com"); - Track track4 = new Track(null, members.get(1), locations.get(3), "isrc4", "리버스아카데미 노래", "https://testimage4.com"); - Track track5 = new Track(null, members.get(2), locations.get(4), "isrc5", "영일대는 이노래지", "https://testimage5.com"); - Track track6 = new Track(null, members.get(2), locations.get(5), "isrc6", "황리단길과 어울리는", "https://testimage5.com"); + Track track2 = new Track(null, members.get(0), locations.get(1), "isrc2", "버거킹마을 공연 최애 노래", + "https://testimage2.com"); + Track track3 = new Track(null, members.get(1), locations.get(2), "isrc3", "아카데미는 이 노래지", + "https://testimage3.com"); + Track track4 = new Track(null, members.get(1), locations.get(3), "isrc4", "리버스아카데미 노래", + "https://testimage4.com"); + Track track5 = new Track(null, members.get(2), locations.get(4), "isrc5", "영일대는 이노래지", + "https://testimage5.com"); + Track track6 = new Track(null, members.get(2), locations.get(5), "isrc6", "황리단길과 어울리는", + "https://testimage5.com"); tracks.add(trackRepository.save(track1)); tracks.add(trackRepository.save(track2)); @@ -124,60 +146,122 @@ private List createTestTracks(List members, List locati assertThat(location.getLongitude()).isEqualTo(retrievedLocation.get().getLongitude()); } - @Test - void getTracksByLocationTest() { - // given - TrackResponse.TrackMap expectedTrackMap1 = TrackResponse.TrackMap.builder() - .isrc("isrc2") - .isLiked(false) - .longitude(129.322700) - .latitude(36.015733) - .build(); + @Nested + class getTracksByLocationTests { - TrackResponse.TrackMap expectedTrackMap2 = TrackResponse.TrackMap.builder() - .isrc("isrc3") - .isLiked(false) - .longitude(129.325951) - .latitude(36.014335) - .build(); + @Test + void 트랙맵_조회_성공() { + // given + TrackResponse.TrackMap expectedTrackMap1 = TrackResponse.TrackMap.builder() + .isrc("isrc2") + .isLiked(false) + .longitude(129.322700) + .latitude(36.015733) + .build(); + + TrackResponse.TrackMap expectedTrackMap2 = TrackResponse.TrackMap.builder() + .isrc("isrc3") + .isLiked(false) + .longitude(129.325951) + .latitude(36.014335) + .build(); - // when - TrackResponse.TrackMapList trackMapList = trackService.getTracksByLocation(members.get(0), 36.016512, 129.321285, 36.012527, 129.328229); - List trackMaps = trackMapList.getTracks(); + // when + TrackResponse.TrackMapList trackMapList = trackService.getTracksByLocation(members.get(0), 36.016512, + 129.321285, 36.012527, 129.328229); + List trackMaps = trackMapList.getTracks(); - // then - assertThat(trackMaps.size()).isEqualTo(2); - assertThat(trackMaps.get(0)).usingRecursiveComparison() - .ignoringFields("trackId").isEqualTo(expectedTrackMap1); - assertThat(trackMaps.get(1)).usingRecursiveComparison() - .ignoringFields("trackId").isEqualTo(expectedTrackMap2); + // then + assertThat(trackMaps.size()).isEqualTo(2); + assertThat(trackMaps.get(0)).usingRecursiveComparison() + .ignoringFields("trackId").isEqualTo(expectedTrackMap1); + assertThat(trackMaps.get(1)).usingRecursiveComparison() + .ignoringFields("trackId").isEqualTo(expectedTrackMap2); + } + + @Test + void 트랙맵_조회_삭제된_트랙_안가져옴() { + // given + Member member0 = members.get(0); + trackService.deleteTrack(member0, tracks.get(0).getId()); + trackService.deleteTrack(member0, tracks.get(1).getId()); + + // when + TrackResponse.TrackMapList trackMapList = trackService.getTracksByLocation( + members.get(0), + 36, + 129, + 37, + 130 + ); + List trackMaps = trackMapList.getTracks(); + + // then + List getTrackLists = trackMaps.stream() + .map(TrackMap::getTrackId) + .toList(); + assertThat(getTrackLists).doesNotContain(tracks.get(0).getId(), tracks.get(1).getId()); + } } - @Test - void getTrackByIdTest() { - // given - Long trackId = tracks.get(0).getId(); - TrackResponse.MemberInfo memberInfo = TrackResponse.MemberInfo.builder() - .memberId(members.get(0).getId()) - .memberNickname(members.get(0).getNickname()) - .avatar(members.get(0).getAvatar()) - .build(); + @Nested + class getTrackByIdTests { - // when - TrackResponse.TrackDetail trackDetail = trackService.getTrackById(members.get(0), trackId); + @Test + void 트랙_조회_성공() { + // given + Long trackId = tracks.get(0).getId(); + TrackResponse.MemberInfo memberInfo = TrackResponse.MemberInfo.builder() + .memberId(members.get(0).getId()) + .memberNickname(members.get(0).getNickname()) + .avatar(members.get(0).getAvatar()) + .build(); - // then - assertThat(trackDetail).isNotNull(); - assertThat(trackDetail.getIsrc()).isEqualTo("isrc1"); - assertThat(trackDetail.getLatitude()).isEqualTo(36.017062); - assertThat(trackDetail.getLongitude()).isEqualTo(129.321993); - assertThat(trackDetail.getBuildingName()).isEqualTo("Dormitory 16 (DICE)"); - assertThat(trackDetail.getAddress()).isEqualTo("경상북도 포항시 남구 지곡동 287"); - assertThat(trackDetail.getImageUrl()).isEqualTo("https://testimage1.com"); - assertThat(trackDetail.getContent()).isEqualTo("기숙사에서 한곡"); - assertThat(trackDetail.getLikeCount()).isEqualTo(0); - assertThat(trackDetail.getIsLiked()).isEqualTo(false); - assertThat(trackDetail.getMember()).usingRecursiveComparison().isEqualTo(memberInfo); + // when + TrackResponse.TrackDetail trackDetail = trackService.getTrackById(members.get(0), trackId); + + // then + assertThat(trackDetail).isNotNull(); + assertThat(trackDetail.getIsrc()).isEqualTo("isrc1"); + assertThat(trackDetail.getLatitude()).isEqualTo(36.017062); + assertThat(trackDetail.getLongitude()).isEqualTo(129.321993); + assertThat(trackDetail.getBuildingName()).isEqualTo("Dormitory 16 (DICE)"); + assertThat(trackDetail.getAddress()).isEqualTo("경상북도 포항시 남구 지곡동 287"); + assertThat(trackDetail.getImageUrl()).isEqualTo("https://testimage1.com"); + assertThat(trackDetail.getContent()).isEqualTo("기숙사에서 한곡"); + assertThat(trackDetail.getLikeCount()).isEqualTo(0); + assertThat(trackDetail.getIsLiked()).isEqualTo(false); + assertThat(trackDetail.getMember()).usingRecursiveComparison().isEqualTo(memberInfo); + } + + @Test + void 회원탈퇴한_회원의_트랙정보는_노래만_남는다() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + memberService.resign(member0); + + // when + TrackDetail trackDetail1 = trackService.getTrackById(member1, tracks.get(0).getId()); + TrackDetail trackDetail2 = trackService.getTrackById(member1, tracks.get(1).getId()); + + // then + for (TrackDetail trackDetail : List.of(trackDetail1, trackDetail2)) { + assertThat(trackDetail.getTrackId()).isNotNull(); + assertThat(trackDetail.getIsrc()).isNotBlank(); + assertThat(trackDetail.getCreatedAt()).isNotNull(); + assertThat(trackDetail.getLatitude()).isZero(); + assertThat(trackDetail.getLongitude()).isZero(); + assertThat(trackDetail.getBuildingName()).isBlank(); + assertThat(trackDetail.getAddress()).isBlank(); + assertThat(trackDetail.getImageUrl()).isEqualTo(""); + assertThat(trackDetail.getContent()).isEqualTo("삭제된 게시글 입니다"); + assertThat(trackDetail.getLikeCount()).isZero(); + assertThat(trackDetail.getIsLiked()).isFalse(); + assertThat(trackDetail.getMember().getMemberNickname()).isEqualTo("알수없음"); + assertThat(trackDetail.getMember().getAvatar()).isEqualTo(""); + } + } } @Nested @@ -285,24 +369,48 @@ void addTrackTest() { assertThat(trackDetails).hasSize(6); } - @Test - void getTrackFeedsTest_페이지네이션() { - // given - Member member = members.get(0); + @Nested + class getTrackFeedsTests { - // when - List firstPageTracks = trackService.getTrackFeeds(member, 0, 4).getTrackDetails(); - List secondPageTracks = trackService.getTrackFeeds(member, 1, 4).getTrackDetails(); - List thirdPageTracks = trackService.getTrackFeeds(member, 2, 4).getTrackDetails(); + @Test + void getTrackFeedsTest_페이지네이션() { + // given + Member member = members.get(0); - // then - assertThat(firstPageTracks).hasSize(4); - assertThat(secondPageTracks).hasSize(2); - assertThat(thirdPageTracks).hasSize(0); + // when + List firstPageTracks = trackService.getTrackFeeds(member, 0, 4).getTrackDetails(); + List secondPageTracks = trackService.getTrackFeeds(member, 1, 4).getTrackDetails(); + List thirdPageTracks = trackService.getTrackFeeds(member, 2, 4).getTrackDetails(); + + // then + assertThat(firstPageTracks).hasSize(4); + assertThat(secondPageTracks).hasSize(2); + assertThat(thirdPageTracks).hasSize(0); + } + + @Test + void 회원탈퇴한_회원의_트랙은_트랙피드에_표시되지않는다() { + // given + Member member0 = members.get(0); + Member member1 = members.get(1); + // when + List member0Tracks1 = trackService.getTrackFeeds(member1, 0, 20).getTrackDetails(); + + // then + assertThat(member0Tracks1).hasSize(6); + memberService.resign(member0); + + // when + List member0Tracks = trackService.getTrackFeeds(member1, 0, 20).getTrackDetails(); + + // then + assertThat(member0Tracks).hasSize(4); + } } @Nested class DeleteTrackTest { + @Test void 트랙_삭제_성공() { // given @@ -329,6 +437,29 @@ class DeleteTrackTest { assertThatThrownBy(() -> trackService.deleteTrack(nonUploader, trackId)) .isInstanceOf(RestApiException.class); } + + @Test + void 트랙_삭제시_노래_제외_정보들_삭제처리() { + // given + Member uploader = members.get(0); + Long trackId = tracks.get(0).getId(); + + // when + TrackResponse.TrackId deletedTrackId = trackService.deleteTrack(uploader, trackId); + + // then + trackRepository.findById(deletedTrackId.getTrackId()).ifPresent(track -> + assertThat(track.getDeletedAt()).isNotNull() // deletedAt 값이 null 이 아님 + ); + TrackDetail trackDetail = trackService.getTrackById(uploader, deletedTrackId.getTrackId()); + assertThat(trackDetail.getIsrc()).isEqualTo("isrc1"); + assertThat(trackDetail.getLikeCount()).isEqualTo(0); // 모든 좋아요 삭제 + assertThat(trackDetail.getIsLiked()).isFalse(); // 모든 좋아요 삭제 + assertThat(trackDetail.getContent()).isEqualTo("삭제된 게시글 입니다"); // 본문 "삭제된 게시글 입니다" + assertThat(trackDetail.getImageUrl()).isEqualTo(""); // 트랙 이미지 "" + assertThat(trackDetail.getMember().getMemberNickname()).isEqualTo("알수없음"); // 업로드한 멤버 이름 "알수없음" + assertThat(trackDetail.getMember().getAvatar()).isEqualTo(""); // 업로드한 멤버 아바타 "" + } } @Test