Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public ResponseEntity<MemberBandResponse> memberLikeBand(
@GetMapping("/archive-band")
public ResponseEntity<MemberBandResponse> memberArchiveBand(
@Parameter(description = "사용자 ID") @RequestParam Long memberId) {
List<Long> bandIdListOfMember = emotionBandArchiveService.findEmotionBandIdListByCreator(memberId);
List<Long> bandIdListOfMember = emotionBandArchiveService.findArchivedEmotionBandIdsByMember(memberId);
List<EmotionBand> allByEmotionBandIdList = emotionBandService.findAllByEmotionBandIdListWithSongs(bandIdListOfMember);
List<MemberBandResponseDto> collect = allByEmotionBandIdList.stream().map(memberApiParser::mapToMemberBandResponse).collect(Collectors.toList());
return ResponseEntity.ok(new MemberBandResponse(collect));
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/team3/kummit/domain/EmotionBand.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@ public class EmotionBand {

public void incrementCommentCount() { this.commentCount++; }

public void incrementPeopleCount() {
this.peopleCount++;
}
public void decrementPeopleCount() {
this.peopleCount--;
}

}
3 changes: 3 additions & 0 deletions src/main/java/team3/kummit/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,8 @@ public void incrementLikeCount() {
public void incrementSongAddCount() {
this.songAddCount++;
}
public void decrementBandJoinCount() {
this.bandJoinCount--;
}

}
61 changes: 20 additions & 41 deletions src/main/java/team3/kummit/service/EmotionBandArchiveService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import team3.kummit.domain.EmotionBand;
import team3.kummit.domain.EmotionBandArchive;
import team3.kummit.domain.Member;
import team3.kummit.exception.ResourceNotFoundException;
import team3.kummit.repository.EmotionBandArchiveRepository;
import team3.kummit.repository.EmotionBandRepository;
import team3.kummit.repository.MemberRepository;
Expand All @@ -21,72 +20,52 @@ public class EmotionBandArchiveService {
private final EmotionBandArchiveRepository archiveRepository;
private final EmotionBandRepository emotionBandRepository;
private final MemberRepository memberRepository;
private final EntityValidator entityValidator;

@Transactional
public EmotionBandArchiveResponse toggleArchive(Long emotionBandId, Long memberId) {
// emotionBandId 검증
EmotionBand emotionBand = emotionBandRepository.findById(emotionBandId)
.orElseThrow(() -> new ResourceNotFoundException("감정밴드를 찾을 수 없습니다."));
EmotionBand emotionBand = emotionBandRepository.findById(emotionBandId).orElse(null);
Member member = memberRepository.findById(memberId).orElse(null);

// memberId 검증
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new ResourceNotFoundException("사용자를 찾을 수 없습니다."));
entityValidator.validateMember(member);
entityValidator.validateActiveEmotionBand(emotionBand);

// 보관 상태값
boolean isArchived = archiveRepository.existsByCreatorIdAndEmotionBandId(memberId, emotionBandId);

if (isArchived) {
// 보관 해제 toggle
archiveRepository.findByCreatorIdAndEmotionBandId(memberId, emotionBandId)
.ifPresent(archiveRepository::delete);

// peopleCount 감소, bandJoinCount 감소
Integer currentPeopleCount = emotionBand.getPeopleCount() != null ? emotionBand.getPeopleCount() : 0;
Integer currentBandJoinCount = member.getBandJoinCount() != null ? member.getBandJoinCount() : 0;

EmotionBand updatedEmotionBand = emotionBand.toBuilder()
.peopleCount(Math.max(0, currentPeopleCount - 1))
.build();
Member updatedMember = member.toBuilder()
.bandJoinCount(Math.max(0, currentBandJoinCount - 1))
.build();

emotionBandRepository.save(updatedEmotionBand);
memberRepository.save(updatedMember);

updateCounts(emotionBand, member, false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 봤는데, 이렇게 감정밴드 보관, 취소 로직을 한번에 태우는 흐름이 좋은 것 같습니다!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sudo-Terry 고생하셨습니다! 예전보다 훨씬 깔끔해진 것 같아요.

엇 동시성 문제는 조용히 넘어가려고 했는데, 좋습니다! 저도 후속 PR 날려볼게요

return EmotionBandArchiveResponse.of(false, "보관이 해제되었습니다.");
} else {
// 보관 추가 toggle
EmotionBandArchive archive = EmotionBandArchive.builder()
.creator(member)
.emotionBand(emotionBand)
.build();
archiveRepository.save(archive);

// peopleCount 증가, bandJoinCount 증가
Integer currentPeopleCount = emotionBand.getPeopleCount() != null ? emotionBand.getPeopleCount() : 0;
Integer currentBandJoinCount = member.getBandJoinCount() != null ? member.getBandJoinCount() : 0;

EmotionBand updatedEmotionBand = emotionBand.toBuilder()
.peopleCount(currentPeopleCount + 1)
.build();
Member updatedMember = member.toBuilder()
.bandJoinCount(currentBandJoinCount + 1)
.build();

emotionBandRepository.save(updatedEmotionBand);
memberRepository.save(updatedMember);

updateCounts(emotionBand, member, true);
return EmotionBandArchiveResponse.of(true, "보관되었습니다.");
}
}

private void updateCounts(EmotionBand emotionBand, Member member, boolean increment) {
if (increment) {
emotionBand.incrementPeopleCount();
member.incrementBandJoinCount();
} else {
emotionBand.decrementPeopleCount();
member.decrementBandJoinCount();
}
emotionBandRepository.save(emotionBand);
memberRepository.save(member);
}

@Transactional(readOnly = true)
public boolean isArchived(Long emotionBandId, Long memberId) {
return archiveRepository.existsByCreatorIdAndEmotionBandId(memberId, emotionBandId);
}

public List<Long> findEmotionBandIdListByCreator(Long memberId){
public List<Long> findArchivedEmotionBandIdsByMember(Long memberId){
return archiveRepository.findEmotionBandIdListByMemberId(memberId);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package team3.kummit.service;

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.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand All @@ -15,17 +15,19 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import team3.kummit.api.EmotionBandArchiveResponse;
import team3.kummit.domain.EmotionBand;
import team3.kummit.domain.EmotionBandArchive;
import team3.kummit.domain.Member;
import team3.kummit.exception.ResourceNotFoundException;
import team3.kummit.repository.EmotionBandArchiveRepository;
import team3.kummit.repository.EmotionBandRepository;
import team3.kummit.repository.MemberRepository;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class EmotionBandArchiveServiceTest {

@Mock
Expand All @@ -37,6 +39,9 @@ class EmotionBandArchiveServiceTest {
@Mock
private MemberRepository memberRepository;

@Mock
private EntityValidator entityValidator;

@InjectMocks
private EmotionBandArchiveService emotionBandArchiveService;

Expand All @@ -50,6 +55,7 @@ void setUp() {
.id(1L)
.name("테스트유저")
.email("test@test.com")
.bandJoinCount(0)
.build();

testEmotionBand = EmotionBand.builder()
Expand Down Expand Up @@ -92,6 +98,8 @@ void toggleArchive_AddArchive_Success() {
.thenReturn(testEmotionBand.toBuilder().peopleCount(1).build());
when(memberRepository.save(any(Member.class)))
.thenReturn(testMember.toBuilder().bandJoinCount(1).build());
doNothing().when(entityValidator).validateMember(any());
doNothing().when(entityValidator).validateActiveEmotionBand(any());

// when
EmotionBandArchiveResponse result = emotionBandArchiveService.toggleArchive(emotionBandId, memberId);
Expand Down Expand Up @@ -124,6 +132,8 @@ void toggleArchive_RemoveArchive_Success() {
.thenReturn(testEmotionBand.toBuilder().peopleCount(0).build());
when(memberRepository.save(any(Member.class)))
.thenReturn(testMember.toBuilder().bandJoinCount(0).build());
doNothing().when(entityValidator).validateMember(any());
doNothing().when(entityValidator).validateActiveEmotionBand(any());

// when
EmotionBandArchiveResponse result = emotionBandArchiveService.toggleArchive(emotionBandId, memberId);
Expand All @@ -137,40 +147,6 @@ void toggleArchive_RemoveArchive_Success() {
verify(memberRepository).save(any(Member.class));
}

@Test
@DisplayName("존재하지 않는 감정밴드 보관 시 예외 발생")
void toggleArchive_EmotionBandNotFound_ThrowsException() {
// given
Long emotionBandId = 999L;
Long memberId = 1L;

when(emotionBandRepository.findById(emotionBandId))
.thenReturn(java.util.Optional.empty());

// when & then
assertThatThrownBy(() -> emotionBandArchiveService.toggleArchive(emotionBandId, memberId))
.isInstanceOf(ResourceNotFoundException.class)
.hasMessage("감정밴드를 찾을 수 없습니다.");
}

@Test
@DisplayName("존재하지 않는 사용자로 보관 시 예외 발생")
void toggleArchive_MemberNotFound_ThrowsException() {
// given
Long emotionBandId = 1L;
Long memberId = 999L;

when(emotionBandRepository.findById(emotionBandId))
.thenReturn(java.util.Optional.of(testEmotionBand));
when(memberRepository.findById(memberId))
.thenReturn(java.util.Optional.empty());

// when & then
assertThatThrownBy(() -> emotionBandArchiveService.toggleArchive(emotionBandId, memberId))
.isInstanceOf(ResourceNotFoundException.class)
.hasMessage("사용자를 찾을 수 없습니다.");
}

@Test
@DisplayName("보관 여부 확인 - 보관된 경우")
void isArchived_WhenArchived_ReturnsTrue() {
Expand Down