Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TNT-253] fix: 회원 탈퇴 시 식단 데이터 삭제, 기타 수정 #64

Merged
merged 7 commits into from
Feb 14, 2025
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
34 changes: 20 additions & 14 deletions src/main/java/com/tnt/application/member/WithdrawService.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.tnt.application.member;

import static com.tnt.domain.member.MemberType.TRAINEE;
import static com.tnt.domain.member.MemberType.TRAINER;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tnt.application.pt.PtService;
import com.tnt.application.trainee.DietService;
import com.tnt.application.trainee.PtGoalService;
import com.tnt.application.trainee.TraineeService;
import com.tnt.application.trainer.TrainerService;
import com.tnt.common.error.exception.NotFoundException;
import com.tnt.domain.member.Member;
import com.tnt.domain.member.MemberType;
import com.tnt.domain.pt.PtLesson;
import com.tnt.domain.pt.PtTrainerTrainee;
import com.tnt.domain.trainee.Diet;
import com.tnt.domain.trainee.PtGoal;
import com.tnt.domain.trainee.Trainee;
import com.tnt.domain.trainer.Trainer;
Expand All @@ -31,6 +35,7 @@ public class WithdrawService {
private final TrainerService trainerService;
private final TraineeService traineeService;
private final PtGoalService ptGoalService;
private final DietService dietService;
private final PtService ptService;

@Transactional
Expand All @@ -45,29 +50,28 @@ public WithdrawDto withdraw(Long memberId) {
}

private void deleteMemberData(Member member) {
if (member.getMemberType() == MemberType.TRAINER) {
if (member.getMemberType() == TRAINER) {
Trainer trainer = trainerService.getTrainerWithMemberId(member.getId());

if (ptService.isPtTrainerTraineeExistWithTrainerId(trainer.getId())) {
try {
List<PtTrainerTrainee> ptTrainerTrainee = ptService.getAllPtTrainerTraineeWithTrainerId(
trainer.getId());
List<PtTrainerTrainee> ptTrainerTrainee = ptService.getAllPtTrainerTraineeWithTrainerId(
trainer.getId());

List<PtLesson> ptLessons = ptTrainerTrainee.stream().map(ptService::getPtLessonWithPtTrainerTrainee)
.flatMap(List::stream)
.toList();
List<PtLesson> ptLessons = ptTrainerTrainee.stream().map(ptService::getPtLessonWithPtTrainerTrainee)
.flatMap(List::stream)
.toList();

ptLessons.forEach(PtLesson::softDelete);
ptTrainerTrainee.forEach(PtTrainerTrainee::softDelete);
} catch (NotFoundException e) {
// Do nothing
}
ptLessons.forEach(PtLesson::softDelete);
ptTrainerTrainee.forEach(PtTrainerTrainee::softDelete);
}

trainer.softDelete();
} else if (member.getMemberType() == MemberType.TRAINEE) {
}

if (member.getMemberType() == TRAINEE) {
Trainee trainee = traineeService.getTraineeWithMemberId(member.getId());
List<PtGoal> ptGoals = ptGoalService.getAllPtGoalsWithTraineeId(trainee.getId());
List<Diet> diets = dietService.getAllDietsWithTraineeId(trainee.getId());

if (ptService.isPtTrainerTraineeExistWithTraineeId(trainee.getId())) {
try {
Expand All @@ -83,6 +87,8 @@ private void deleteMemberData(Member member) {

ptGoals.forEach(PtGoal::softDelete);

diets.forEach(Diet::softDelete);

trainee.softDelete();
}

Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/tnt/application/pt/PtService.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,11 @@ public GetTraineeDailyRecordsResponse getDailyRecords(Long memberId, LocalDate d
date).orElse(new TraineeProjection.PtInfoDto(null, null, null, null, null));

// PT 정보 Mapping to PtInfo
GetTraineeDailyRecordsResponse.PtInfo ptInfo = new GetTraineeDailyRecordsResponse.PtInfo(ptResult.trainerName(),
ptResult.trainerProfileImage(), ptResult.session(), ptResult.lessonStart(), ptResult.lessonEnd());
GetTraineeDailyRecordsResponse.PtInfo ptInfo =
(ptResult.trainerName() == null && ptResult.trainerProfileImage() == null && ptResult.session() == null
&& ptResult.lessonStart() == null && ptResult.lessonEnd() == null) ? null :
new GetTraineeDailyRecordsResponse.PtInfo(ptResult.trainerName(), ptResult.trainerProfileImage(),
ptResult.session(), ptResult.lessonStart(), ptResult.lessonEnd());

// 식단 정보 조회
List<Diet> diets = dietService.getDietsWithTraineeIdForDaily(trainee.getId(), date);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/tnt/application/trainee/DietService.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public Diet getDietWithTraineeIdAndDietId(Long dietId, Long traineeId) {
.orElseThrow(() -> new NotFoundException(DIET_NOT_FOUND));
}

public List<Diet> getAllDietsWithTraineeId(Long traineeId) {
return dietRepository.findAllByTraineeIdAndDeletedAtIsNull(traineeId);
}

public List<Diet> getDietsWithTraineeIdForDaily(Long traineeId, LocalDate date) {
return dietSearchRepository.findAllByTraineeIdForDaily(traineeId, date);
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/tnt/domain/trainee/Diet.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,8 @@ private String validateMemo(String memo) {

return memo;
}

public void softDelete() {
this.deletedAt = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public record ConnectTraineeInfo(
@Schema(description = "트레이니 나이", example = "25", nullable = true)
Integer traineeAge,

@Schema(description = "트레이니 키", example = "178.6cm", nullable = false)
@Schema(description = "트레이니 키", example = "178.6cm", nullable = true)
Double height,

@Schema(description = "트레이니 몸무게", example = "70.2kg", nullable = false)
@Schema(description = "트레이니 몸무게", example = "70.2kg", nullable = true)
Double weight,

@Schema(description = "PT 목표", example = "체중 감량, 근력 향상, 건강 관리", nullable = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tnt.infrastructure.mysql.repository.trainee;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -9,4 +10,6 @@
public interface DietRepository extends JpaRepository<Diet, Long> {

Optional<Diet> findByIdAndTraineeIdAndDeletedAtIsNull(Long id, Long traineeId);

List<Diet> findAllByTraineeIdAndDeletedAtIsNull(Long traineeId);
}
12 changes: 12 additions & 0 deletions src/test/java/com/tnt/application/member/WithdrawServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@
import org.mockito.junit.jupiter.MockitoExtension;

import com.tnt.application.pt.PtService;
import com.tnt.application.trainee.DietService;
import com.tnt.application.trainee.PtGoalService;
import com.tnt.application.trainee.TraineeService;
import com.tnt.application.trainer.TrainerService;
import com.tnt.common.error.exception.NotFoundException;
import com.tnt.domain.member.Member;
import com.tnt.domain.pt.PtLesson;
import com.tnt.domain.pt.PtTrainerTrainee;
import com.tnt.domain.trainee.Diet;
import com.tnt.domain.trainee.PtGoal;
import com.tnt.domain.trainee.Trainee;
import com.tnt.domain.trainer.Trainer;
import com.tnt.fixture.DietFixture;
import com.tnt.fixture.MemberFixture;
import com.tnt.fixture.PtLessonsFixture;
import com.tnt.fixture.PtTrainerTraineeFixture;
Expand All @@ -48,6 +51,9 @@ class WithdrawServiceTest {
@Mock
private PtGoalService ptGoalService;

@Mock
private DietService dietService;

@Mock
private PtService ptService;

Expand Down Expand Up @@ -79,10 +85,12 @@ void withdraw_trainee_success() {
Trainee trainee = TraineeFixture.getTrainee1WithId(1L, traineeMember);

List<PtGoal> ptGoals = List.of(PtGoal.builder().id(1L).traineeId(trainee.getId()).content("test").build());
List<Diet> diets = List.of(DietFixture.getDiet1(trainee.getId()), DietFixture.getDiet2(trainee.getId()));

given(memberService.getMemberWithMemberId(traineeMember.getId())).willReturn(traineeMember);
given(traineeService.getTraineeWithMemberId(traineeMember.getId())).willReturn(trainee);
given(ptGoalService.getAllPtGoalsWithTraineeId(trainee.getId())).willReturn(ptGoals);
given(dietService.getAllDietsWithTraineeId(trainee.getId())).willReturn(diets);

// when
withdrawService.withdraw(traineeMember.getId());
Expand Down Expand Up @@ -131,13 +139,15 @@ void withdraw_trainee_with_pt_success() {
PtTrainerTrainee ptTrainerTrainee = PtTrainerTraineeFixture.getPtTrainerTrainee1(trainer, trainee);

List<PtGoal> ptGoals = List.of(PtGoal.builder().id(1L).traineeId(trainee.getId()).content("test").build());
List<Diet> diets = List.of(DietFixture.getDiet1(trainee.getId()), DietFixture.getDiet2(trainee.getId()));

List<PtLesson> ptLessons = PtLessonsFixture.getPtLessons1WithId(ptTrainerTrainee);

given(memberService.getMemberWithMemberId(traineeMember.getId())).willReturn(traineeMember);
given(traineeService.getTraineeWithMemberId(traineeMember.getId())).willReturn(trainee);
given(ptService.isPtTrainerTraineeExistWithTraineeId(trainee.getId())).willReturn(true);
given(ptGoalService.getAllPtGoalsWithTraineeId(trainee.getId())).willReturn(ptGoals);
given(dietService.getAllDietsWithTraineeId(trainee.getId())).willReturn(diets);
given(ptService.getPtTrainerTraineeWithTraineeId(trainee.getId())).willReturn(ptTrainerTrainee);
given(ptService.getPtLessonWithPtTrainerTrainee(ptTrainerTrainee)).willReturn(ptLessons);

Expand Down Expand Up @@ -176,11 +186,13 @@ void withdraw_trainee_without_pt_success() {
Trainee trainee = TraineeFixture.getTrainee1WithId(1L, traineeMember);

List<PtGoal> ptGoals = List.of(PtGoal.builder().id(1L).traineeId(trainee.getId()).content("test").build());
List<Diet> diets = List.of(DietFixture.getDiet1(trainee.getId()), DietFixture.getDiet2(trainee.getId()));

given(memberService.getMemberWithMemberId(traineeMember.getId())).willReturn(traineeMember);
given(traineeService.getTraineeWithMemberId(traineeMember.getId())).willReturn(trainee);
given(ptService.isPtTrainerTraineeExistWithTraineeId(trainee.getId())).willReturn(true);
given(ptGoalService.getAllPtGoalsWithTraineeId(trainee.getId())).willReturn(ptGoals);
given(dietService.getAllDietsWithTraineeId(trainee.getId())).willReturn(diets);
given(ptService.getPtTrainerTraineeWithTraineeId(trainee.getId())).willThrow(NotFoundException.class);

// when
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/tnt/fixture/PtLessonsFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public static List<PtLesson> getPtLessons1(PtTrainerTrainee ptTrainerTrainee) {
LocalDateTime startDate1 = LocalDateTime.parse("2025-02-01T11:30");
LocalDateTime endDate1 = LocalDateTime.parse("2025-02-01T13:00");

LocalDateTime startDate2 = LocalDateTime.parse("2025-02-02T11:30");
LocalDateTime endDate2 = LocalDateTime.parse("2025-02-02T13:00");
LocalDateTime startDate2 = LocalDateTime.parse("2025-02-05T11:30");
LocalDateTime endDate2 = LocalDateTime.parse("2025-02-05T13:00");

return List.of(PtLesson.builder()
.ptTrainerTrainee(ptTrainerTrainee)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ void get_calendar_daily_records_success() throws Exception {
.andExpect(status().isOk())
.andExpect(jsonPath("$.date").value(targetDate.format(dateFormatter)))
.andExpect(jsonPath("$.ptInfo.trainerName").value(trainer.getMember().getName()))
.andExpect(jsonPath("$.ptInfo.trainerProfileImage").value(trainer.getMember().getProfileImageUrl()))
.andExpect(jsonPath("$.ptInfo.session").value(ptLesson.getSession()))
.andExpect(jsonPath("$.ptInfo.lessonStart").value(ptLesson.getLessonStart().format(dateTimeFormatter)))
.andExpect(jsonPath("$.ptInfo.lessonEnd").value(ptLesson.getLessonEnd().format(dateTimeFormatter)))
Expand All @@ -444,4 +445,67 @@ void get_calendar_daily_records_success() throws Exception {
.andExpect(jsonPath("$.diets[1].dietType").value(diet2.getDietType().toString()))
.andDo(print());
}

@Test
@DisplayName("통합 테스트 - 트레이니 PT 수업 없는 날 특정 날짜 기록 조회 성공")
void get_calendar_daily_records_without_pt_info_success() throws Exception {
// given
Member trainerMember = MemberFixture.getTrainerMember1();
Member traineeMember = MemberFixture.getTraineeMember2();

trainerMember = memberRepository.save(trainerMember);
traineeMember = memberRepository.save(traineeMember);

CustomUserDetails traineeUserDetails = new CustomUserDetails(traineeMember.getId(),
traineeMember.getId().toString(),
authoritiesMapper.mapAuthorities(List.of(new SimpleGrantedAuthority("ROLE_USER"))));

Authentication authentication = new UsernamePasswordAuthenticationToken(traineeUserDetails, null,
authoritiesMapper.mapAuthorities(traineeUserDetails.getAuthorities()));

SecurityContextHolder.getContext().setAuthentication(authentication);

Trainer trainer = TrainerFixture.getTrainer2(trainerMember);
Trainee trainee = TraineeFixture.getTrainee1(traineeMember);

trainerRepository.save(trainer);
traineeRepository.save(trainee);

PtTrainerTrainee ptTrainerTrainee = PtTrainerTraineeFixture.getPtTrainerTrainee1(trainer, trainee);

ptTrainerTraineeRepository.save(ptTrainerTrainee);

PtLesson ptLesson = PtLessonsFixture.getPtLessons1(ptTrainerTrainee).getFirst();

ptLessonRepository.save(ptLesson);

Diet diet3 = DietFixture.getDiet3(trainee.getId());
Diet diet4 = DietFixture.getDiet4(trainee.getId());

List<Diet> diets = List.of(diet3, diet4);

dietRepository.saveAll(diets);

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
LocalDate targetDate = diet3.getDate().toLocalDate();

// when & then
mockMvc.perform(get("/trainees/calendar/{date}", targetDate))
.andExpect(status().isOk())
.andExpect(jsonPath("$.date").value(targetDate.format(dateFormatter)))
.andExpect(jsonPath("$.ptInfo").doesNotExist())
.andExpect(jsonPath("$.diets").isArray())
.andExpect(jsonPath("$.diets[0].dietId").value(diet3.getId()))
.andExpect(jsonPath("$.diets[0].date").value(diet3.getDate().format(dateTimeFormatter)))
.andExpect(jsonPath("$.diets[0].dietImageUrl").value(diet3.getDietImageUrl()))
.andExpect(jsonPath("$.diets[0].memo").value(diet3.getMemo()))
.andExpect(jsonPath("$.diets[0].dietType").value(diet3.getDietType().toString()))
.andExpect(jsonPath("$.diets[1].dietId").value(diet4.getId()))
.andExpect(jsonPath("$.diets[1].date").value(diet4.getDate().format(dateTimeFormatter)))
.andExpect(jsonPath("$.diets[1].dietImageUrl").value(diet4.getDietImageUrl()))
.andExpect(jsonPath("$.diets[1].memo").value(diet4.getMemo()))
.andExpect(jsonPath("$.diets[1].dietType").value(diet4.getDietType().toString()))
.andDo(print());
}
}