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

Feat: 챌린지 및 목표 응답 DTO 통합 #326

Merged
merged 10 commits into from
Dec 26, 2024
Merged
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
@@ -3,7 +3,9 @@
import com.dnd.runus.application.running.dto.RunningResultDto;
import com.dnd.runus.application.running.event.RunningRecordAddedEvent;
import com.dnd.runus.domain.challenge.Challenge;
import com.dnd.runus.domain.challenge.ChallengeCondition;
import com.dnd.runus.domain.challenge.ChallengeRepository;
import com.dnd.runus.domain.challenge.ChallengeType;
import com.dnd.runus.domain.challenge.ChallengeWithCondition;
import com.dnd.runus.domain.challenge.GoalMetricType;
import com.dnd.runus.domain.challenge.achievement.ChallengeAchievement;
@@ -19,13 +21,15 @@
import com.dnd.runus.domain.running.DailyRunningRecordSummary;
import com.dnd.runus.domain.running.RunningRecord;
import com.dnd.runus.domain.running.RunningRecordRepository;
import com.dnd.runus.global.exception.BusinessException;
import com.dnd.runus.global.exception.NotFoundException;
import com.dnd.runus.global.exception.type.ErrorType;
import com.dnd.runus.presentation.v1.running.dto.WeeklyRunningRatingDto;
import com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode;
import com.dnd.runus.presentation.v1.running.dto.request.RunningRecordRequestV1;
import com.dnd.runus.presentation.v1.running.dto.request.RunningRecordWeeklySummaryType;
import com.dnd.runus.presentation.v1.running.dto.response.*;
import com.dnd.runus.presentation.v2.running.dto.request.RunningRecordRequestV2;
import com.dnd.runus.presentation.v2.running.dto.request.RunningRecordRequestV2.ChallengeAchievedDto;
import com.dnd.runus.presentation.v2.running.dto.request.RunningRecordRequestV2.GoalAchievedDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
@@ -79,7 +83,7 @@ public RunningRecordService(
}

@Transactional(readOnly = true)
public RunningRecordQueryResponse getRunningRecord(long memberId, long runningRecordId) {
public RunningResultDto getRunningRecord(long memberId, long runningRecordId) {
RunningRecord runningRecord = runningRecordRepository
.findById(runningRecordId)
.filter(r -> r.member().memberId() == memberId)
@@ -97,7 +101,27 @@ public RunningRecordQueryResponse getRunningRecord(long memberId, long runningRe
.orElse(null)
: null;

return RunningRecordQueryResponse.of(runningRecord, challengeAchievement, goalAchievement);
RunningAchievementMode runningAchievementMode = (challengeAchievement != null)
? RunningAchievementMode.CHALLENGE
: (goalAchievement != null) ? RunningAchievementMode.GOAL : RunningAchievementMode.NORMAL;

switch (runningAchievementMode) {
case CHALLENGE -> {
return RunningResultDto.of(
runningRecord,
challengeAchievement,
calChallengeAchievementPercentage(memberId, challengeAchievement));
}
case GOAL -> {
int achievedGoalValue = goalAchievement.goalMetricType().getActualValue(runningRecord);
return RunningResultDto.of(
runningRecord,
goalAchievement,
calPercentage(achievedGoalValue, goalAchievement.achievementValue()));
}
}

return RunningResultDto.from(runningRecord);
}

@Transactional(readOnly = true)
@@ -223,16 +247,22 @@ public RunningResultDto addRunningRecordV2(long memberId, RunningRecordRequestV2

switch (request.achievementMode()) {
case CHALLENGE -> {
ChallengeAchievedDto challengeAchievedForAdd = request.challengeValues();
Challenge challenge = challengeRepository
.findById(challengeAchievedForAdd.challengeId())
.orElseThrow(
() -> new NotFoundException(Challenge.class, challengeAchievedForAdd.challengeId()));
.findById(request.challengeValues().challengeId())
.orElseThrow(() -> new NotFoundException(
Challenge.class, request.challengeValues().challengeId()));
if (!challenge.isActive()) {
throw new BusinessException(ErrorType.CHALLENGE_NOT_ACTIVE);
}

ChallengeAchievement challengeAchievement = challengeAchievementRepository.save(
new ChallengeAchievement(challenge, record, challengeAchievedForAdd.isSuccess()));
ChallengeAchievement challengeAchievement =
challengeAchievementRepository.save(new ChallengeAchievement(
challenge, record, request.challengeValues().isSuccess()));

return RunningResultDto.of(record, challengeAchievement);
return RunningResultDto.of(
record,
challengeAchievement,
calChallengeAchievementPercentage(memberId, challengeAchievement));
}
case GOAL -> {
GoalAchievedDto goalAchievedForAdd = request.goalValues();
@@ -244,7 +274,10 @@ public RunningResultDto addRunningRecordV2(long memberId, RunningRecordRequestV2
: goalAchievedForAdd.goalTime(),
goalAchievedForAdd.isSuccess()));

return RunningResultDto.of(record, goalAchievement);
int achievedGoalValue = goalAchievement.goalMetricType().getActualValue(record);

return RunningResultDto.of(
record, goalAchievement, calPercentage(achievedGoalValue, goalAchievement.achievementValue()));
}
}
return RunningResultDto.from(record);
@@ -337,4 +370,54 @@ private GoalAchievement handleGoalMode(RunningRecord runningRecord, Integer goal
GoalAchievement goalAchievement = new GoalAchievement(runningRecord, goalMetricType, goalValue, isAchieved);
return goalAchievementRepository.save(goalAchievement);
}

/**
* 챌린지 퍼센테이지 계산(V2 이후에서 사용)
* 어제 러닝 기록 이기기 관련 챌린지면 챌린지 목표값 재등록(기본 목표 값 + 어제 러닝 기록)한 후 계산
* @return Double(퍼센테이지 계산하기 힘든, 2 이전에 저장된 챌린지같은 경우 null로 리턴)
*/
private Double calChallengeAchievementPercentage(long memberId, ChallengeAchievement challengeAchievement) {

Challenge challenge = challengeAchievement.challenge();
ChallengeWithCondition challengeWithCondition = challengeRepository
.findChallengeWithConditionsByChallengeId(challenge.challengeId())
.orElseThrow(() -> new NotFoundException(Challenge.class, challenge.challengeId()));

// DISTANCE_IN_TIME, PACE 챌린지인지 확인
// (v2이전에 퍼센테이지를 표현할 수 없는 애들일 경우, 퍼센테이지 null로 리턴함)
if (challenge.challengeType() == ChallengeType.DISTANCE_IN_TIME
|| challengeWithCondition.conditions().stream()
.anyMatch(condition -> !condition.goalMetricType().hasPercentage())) {
return null;
}

ChallengeCondition condition = challengeWithCondition.conditions().getFirst();
RunningRecord runningRecord = challengeAchievement.runningRecord();

if (challenge.isDefeatYesterdayChallenge()) {
// 어제 러닝 기록 이기기 관련 챌린지면, 챌린지 목표값 재등록(어제 기록 + 목표값)
OffsetDateTime runningDate = runningRecord
.startAt()
.toLocalDate()
.atStartOfDay(runningRecord.startAt().getZone())
.toOffsetDateTime();

RunningRecord preRunningRecord =
runningRecordRepository
.findByMemberIdAndStartAtBetween(memberId, runningDate.minusDays(1), runningDate)
.stream()
.findFirst()
.orElseThrow(() -> new NotFoundException("이전 러닝 기록을 가져올 수 없습니다."));
condition.registerComparisonValue(condition.goalMetricType().getActualValue(preRunningRecord));
}

int achievedValue = condition.goalMetricType().getActualValue(runningRecord);
return calPercentage(achievedValue, condition.comparisonValue());
}

private double calPercentage(double part, double total) {
if (total <= 0) return 0;
double percentage = part / total;
return percentage > 1 ? 1 : percentage;
}
}
Original file line number Diff line number Diff line change
@@ -9,33 +9,38 @@ public record RunningResultDto(
RunningRecord runningRecord,
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode runningAchievementMode,
ChallengeAchievement challengeAchievement,
GoalAchievement goalAchievement
GoalAchievement goalAchievement,
Double percentage
) {
public static RunningResultDto from(RunningRecord runningRecord) {
return new RunningResultDto(
runningRecord,
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.NORMAL,
null,
null,
null
);
}

public static RunningResultDto of(RunningRecord runningRecord,
ChallengeAchievement challengeAchievement) {
ChallengeAchievement challengeAchievement, Double percentage) {
return new RunningResultDto(
runningRecord,
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.CHALLENGE,
challengeAchievement,
null
null,
percentage
);
}

public static RunningResultDto of(RunningRecord runningRecord, GoalAchievement goalAchievement) {
public static RunningResultDto of(RunningRecord runningRecord,
GoalAchievement goalAchievement, Double percentage) {
return new RunningResultDto(
runningRecord,
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.GOAL,
null,
goalAchievement
goalAchievement,
percentage
);
}
}
Original file line number Diff line number Diff line change
@@ -50,6 +50,9 @@ public enum ErrorType {
GOAL_VALUES_REQUIRED_IN_GOAL_MODE(BAD_REQUEST, DEBUG, "RUNNING_005", "개인 목표 모드에서, 개인 목표 달성값은 필수 잆니다."),
CHALLENGE_VALUES_REQUIRED_IN_CHALLENGE_MODE(BAD_REQUEST, DEBUG, "RUNNING_006", "챌린지 모드에서, 챌린지 달성값은 필수 입니다."),

// ChallengeErrorType
CHALLENGE_NOT_ACTIVE(CONFLICT, DEBUG, "CHALLENGE_001", "해당 챌린지는 현재 활성화된 챌린지가 아닙니다."),

// WeatherErrorType
WEATHER_API_ERROR(SERVICE_UNAVAILABLE, WARN, "WEATHER_001", "날씨 API 호출 중 오류가 발생했습니다"),
;
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ public class RunningRecordController {
@GetMapping("/{runningRecordId}")
@Operation(summary = "러닝 기록 상세 조회", description = "RunngingRecord id로 러닝 상세 기록을 조회합니다.")
public RunningRecordQueryResponse getRunningRecord(@MemberId long memberId, @PathVariable long runningRecordId) {
return runningRecordService.getRunningRecord(memberId, runningRecordId);
return RunningRecordQueryResponse.from(runningRecordService.getRunningRecord(memberId, runningRecordId));
}

@GetMapping("monthly-dates")
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
package com.dnd.runus.presentation.v1.running.dto;

import com.dnd.runus.domain.challenge.achievement.ChallengeAchievement;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

public record ChallengeDto(
@Schema(description = "챌린지 ID")
long challengeId,
@NotBlank
@Schema(description = "챌린지 이름", example = "오늘 30분 동안 뛰기")
String title,
@NotBlank
@Schema(description = "챌린지 결과 문구", example = "성공했어요!")
String subTitle,
@NotBlank
@Schema(description = "챌린지 아이콘 이미지 URL")
String iconUrl,
@Schema(description = "챌린지 성공 여부")
boolean isSuccess
@Schema(description = "챌린지 ID")
long challengeId,
@NotBlank
@Schema(description = "챌린지 이름", example = "오늘 30분 동안 뛰기")
String title,
@NotBlank
@Schema(description = "챌린지 결과 문구", example = "성공했어요!")
String subTitle,
@NotBlank
@Schema(description = "챌린지 아이콘 이미지 URL")
String iconUrl,
@Schema(description = "챌린지 성공 여부")
boolean isSuccess
) {
public static ChallengeDto from(ChallengeAchievement achievement) {
return new ChallengeDto(
achievement.challenge().challengeId(),
achievement.challenge().name(),
achievement.description(),
achievement.challenge().imageUrl(),
achievement.isSuccess()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
package com.dnd.runus.presentation.v1.running.dto;

import com.dnd.runus.domain.goalAchievement.GoalAchievement;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

public record GoalResultDto(
@Schema(description = "설정된 목표 제목", example = "2.5km 달성")
String title,
@Schema(description = "설정된 목표 결과 문구", example = "성공했어요!")
String subTitle,
@NotBlank
@Schema(description = "챌린지 아이콘 이미지 URL")
String iconUrl,
@Schema(description = "설정된 목표 성공 여부")
boolean isSuccess
@Schema(description = "설정된 목표 제목", example = "2.5km 달성")
String title,
@Schema(description = "설정된 목표 결과 문구", example = "성공했어요!")
String subTitle,
@NotBlank
@Schema(description = "챌린지 아이콘 이미지 URL")
String iconUrl,
@Schema(description = "설정된 목표 성공 여부")
boolean isSuccess
) {
public static GoalResultDto from(GoalAchievement achievement) {
return new GoalResultDto(
achievement.getTitle(),
achievement.getDescription(),
achievement.getIconUrl(),
achievement.isAchieved()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.dnd.runus.presentation.v1.running.dto.response;

import com.dnd.runus.domain.challenge.achievement.ChallengeAchievement;
import com.dnd.runus.domain.goalAchievement.GoalAchievement;
import com.dnd.runus.application.running.dto.RunningResultDto;
import com.dnd.runus.domain.running.RunningRecord;
import com.dnd.runus.global.constant.RunningEmoji;
import com.dnd.runus.presentation.v1.running.dto.ChallengeDto;
@@ -32,45 +31,18 @@ public record RunningRecordQueryResponse(
@NotNull
RunningRecordMetricsDto runningData
) {
public static RunningRecordQueryResponse from(RunningRecord runningRecord) {
return buildResponse(runningRecord, null, null, RunningAchievementMode.NORMAL);
}

public static RunningRecordQueryResponse of(RunningRecord runningRecord, ChallengeAchievement achievement) {
return buildResponse(runningRecord,
new ChallengeDto(
achievement.challenge().challengeId(),
achievement.challenge().name(),
achievement.description(),
achievement.challenge().imageUrl(),
achievement.isSuccess()
),
null,
RunningAchievementMode.CHALLENGE
);
}

public static RunningRecordQueryResponse of(RunningRecord runningRecord, GoalAchievement achievement) {
return buildResponse(runningRecord,
null,
new GoalResultDto(
achievement.getTitle(),
achievement.getDescription(),
achievement.getIconUrl(),
achievement.isAchieved()
),
RunningAchievementMode.GOAL
public static RunningRecordQueryResponse from(RunningResultDto runningResult) {
return buildResponse(
runningResult.runningRecord(),
runningResult.challengeAchievement() == null ? null
: ChallengeDto.from(runningResult.challengeAchievement()),
runningResult.goalAchievement() == null ? null
: GoalResultDto.from(runningResult.goalAchievement()),
runningResult.runningAchievementMode()
);
}

public static RunningRecordQueryResponse of(RunningRecord runningRecord, ChallengeAchievement challengeAchievement, GoalAchievement goalAchievement) {
if (challengeAchievement != null) {
return of(runningRecord, challengeAchievement);
} else if (goalAchievement != null) {
return of(runningRecord, goalAchievement);
}
return from(runningRecord);
}

private static RunningRecordQueryResponse buildResponse(RunningRecord runningRecord, ChallengeDto challenge, GoalResultDto goal, RunningAchievementMode achievementMode) {
return new RunningRecordQueryResponse(
@@ -89,4 +61,5 @@ private static RunningRecordQueryResponse buildResponse(RunningRecord runningRec
)
);
}

}
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -27,6 +28,12 @@ public class RunningRecordControllerV2 {
private final RunningRecordServiceV2 runningRecordService2;
private final RunningRecordService runningRecordService;

@GetMapping("/{runningRecordId}")
@Operation(summary = "러닝 기록 상세 조회", description = "RunngingRecord id로 러닝 상세 기록을 조회합니다.")
public RunningRecordResultResponseV2 getRunningRecord(@MemberId long memberId, @PathVariable long runningRecordId) {
return RunningRecordResultResponseV2.from(runningRecordService.getRunningRecord(memberId, runningRecordId));
}

@Operation(summary = "이번 달 러닝 기록 조회(홈화면) V2", description = """
홈화면의 이번 달 러닝 기록을 조회 합니다.<br>
""")
@@ -47,9 +54,9 @@ public RunningRecordMonthlySummaryResponseV2 getMonthlyRunningSummary(@MemberId
"""
러닝 기록을 추가합니다.<br>
러닝 기록은 시작 시간, 종료 시간, 러닝 평가(emotion), 러닝 데이터 등으로 구성됩니다. <br>
챌린지 모드가 normal : challengeValues, goalValues 둘다 null <br>
챌린지 모드가 challenge : challengeValues 필수 값 <br>
챌린지 모드가 goal : goalValues 필수 값 <br>
normal : challengeValues, goalValues 둘다 null <br>
challenge : challengeValues 필수 값 <br>
goal : goalValues 필수 값 <br>
러닝 데이터는 위치, 거리, 시간, 칼로리, 평균 페이스, 러닝 경로로 구성됩니다. <br>
러닝 기록 추가에 성공하면 러닝 기록 ID, 기록 정보를 반환합니다. <br>
""")
@@ -58,7 +65,8 @@ public RunningRecordMonthlySummaryResponseV2 getMonthlyRunningSummary(@MemberId
ErrorType.CHALLENGE_VALUES_REQUIRED_IN_CHALLENGE_MODE,
ErrorType.GOAL_VALUES_REQUIRED_IN_GOAL_MODE,
ErrorType.GOAL_TIME_AND_DISTANCE_BOTH_EXIST,
ErrorType.ROUTE_MUST_HAVE_AT_LEAST_TWO_COORDINATES
ErrorType.ROUTE_MUST_HAVE_AT_LEAST_TWO_COORDINATES,
ErrorType.CHALLENGE_NOT_ACTIVE
})
@PostMapping
@ResponseStatus(HttpStatus.OK)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.dnd.runus.presentation.v2.running.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.lang.Nullable;

/**
* 챌린지, 목표 달성 결과 통합 DTO
*/
public record AchievementResultDto(
@Schema(description = "챌린지 이름 또는 설정된 목표 제목", examples = {"오늘 30분 동안 뛰기", "2.5km 달성"})
String title,
@Schema(description = "결과 문구", examples = {"정말 대단해요! 잘하셨어요", "아쉬워요. 내일 다시 도전해보세요!"})
String subTitle,
@Schema(description = "아이콘 이미지 URL")
String iconUrl,
@Schema(description = "성공 여부")
boolean isSuccess,
@Nullable
@Schema(description = "퍼센테이지 값, V2 이전에 퍼센테이지를 나타낼 수 없는 챌린지일 경우 null값을 리턴합니다.")
Double percentage
) {

}
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ public record RouteDtoV2(
) {
public record Point(double longitude, double latitude) {
public static Point from(CoordinatePoint point) {
return new Point(point.longitude(), point.longitude());
return new Point(point.longitude(), point.latitude());
}
}
}
Original file line number Diff line number Diff line change
@@ -31,7 +31,8 @@ public record RunningRecordRequestV2(
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode achievementMode,
@Schema(description = "챌린지 데이터, 챌린지를 하지 않은 경우 null이나 필드 없이 보내주세요")
ChallengeAchievedDto challengeValues,
@Schema(description = "목표 데이터, 목표를 설정하지 않은 경우 null이나 필드 없이 보내주세요")
@Schema(description = "목표 데이터, 목표를 설정하지 않은 경우 null이나 필드 없이 보내주세요. "
+ "goalDistance(거리) 또는 goalTime(시간)값 둘 중 하나는 null이어야 합니다.")
GoalAchievedDto goalValues,
@NotNull
RunningRecordMetrics runningData
@@ -52,7 +53,8 @@ public record RunningRecordRequestV2(
if(goalValues == null) {
throw new BusinessException(ErrorType.GOAL_VALUES_REQUIRED_IN_GOAL_MODE);
}
if (goalValues.goalDistance() == null && goalValues.goalTime() == null) {
if ((goalValues.goalDistance() == null && goalValues.goalTime() == null)
|| (goalValues.goalDistance() != null && goalValues.goalTime() != null)) {
throw new BusinessException(ErrorType.GOAL_TIME_AND_DISTANCE_BOTH_EXIST);
}
}
Original file line number Diff line number Diff line change
@@ -7,8 +7,8 @@
import com.dnd.runus.domain.goalAchievement.GoalAchievement;
import com.dnd.runus.domain.running.RunningRecord;
import com.dnd.runus.global.constant.RunningEmoji;
import com.dnd.runus.presentation.v1.running.dto.ChallengeDto;
import com.dnd.runus.presentation.v1.running.dto.GoalResultDto;
import com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode;
import com.dnd.runus.presentation.v2.running.dto.AchievementResultDto;
import com.dnd.runus.presentation.v2.running.dto.RouteDtoV2;
import com.dnd.runus.presentation.v2.running.dto.RouteDtoV2.Point;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -29,12 +29,9 @@ public record RunningRecordResultResponseV2(
RunningEmoji emotion,
@NotNull
@Schema(description = "달성 모드, normal: 일반(목표 설정 X), challenge: 챌린지, goal: 목표")
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode achievementMode,
//todo 챌린지, 및 goal 관련해서 다시 구성
@Schema(description = "챌린지 정보, achievementMode가 challenge인 경우에만 값이 존재합니다.")
ChallengeDto challenge,
@Schema(description = "목표 결과 정보, achievementMode가 goal인 경우에만 값이 존재합니다.")
GoalResultDto goal,
RunningAchievementMode achievementMode,
@Schema(description = "달성 값(챌린지 또는 목표), achievementMode가 challenge 또는 goal인 경우에만 값이 존재합니다.")
AchievementResultDto achievementResult,
@NotNull
RunningRecordMetrics runningData
) {
@@ -61,10 +58,7 @@ public static RunningRecordResultResponseV2 from(RunningResultDto runningRecordR
runningRecord.endAt().toLocalDateTime(),
runningRecord.emoji(),
runningRecordResult.runningAchievementMode(),
runningRecordResult.runningAchievementMode() != com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.CHALLENGE ? null
: buildChallengeDto(runningRecordResult.challengeAchievement()),
runningRecordResult.runningAchievementMode() != com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.GOAL ? null
: buildGoalResultDto(runningRecordResult.goalAchievement()),
buildAchievementResultOf(runningRecordResult),
new RunningRecordMetrics(
runningRecord.averagePace(),
runningRecord.duration(),
@@ -75,32 +69,38 @@ public static RunningRecordResultResponseV2 from(RunningResultDto runningRecordR
);
}

private static ChallengeDto buildChallengeDto(ChallengeAchievement achievement) {
if (achievement == null) {
return null;
}
return new ChallengeDto(
achievement.challenge().challengeId(),
achievement.challenge().name(),
achievement.description(),
achievement.challenge().imageUrl(),
achievement.isSuccess()
);
}
private static AchievementResultDto buildAchievementResultOf(RunningResultDto runningRecordResult) {
if (runningRecordResult.runningAchievementMode() == RunningAchievementMode.NORMAL) return null;
switch (runningRecordResult.runningAchievementMode()) {
case GOAL -> {
GoalAchievement goalAchievement = runningRecordResult.goalAchievement();
if (goalAchievement == null) return null;
return new AchievementResultDto(
goalAchievement.getTitle(),
goalAchievement.getDescription(),
goalAchievement.getIconUrl(),
goalAchievement.isAchieved(),
runningRecordResult.percentage()
);
}
case CHALLENGE -> {
ChallengeAchievement challengeAchievement = runningRecordResult.challengeAchievement();
if (challengeAchievement == null) return null;
return new AchievementResultDto(
challengeAchievement.challenge().name(),
challengeAchievement.description(),
challengeAchievement.challenge().imageUrl(),
challengeAchievement.isSuccess(),
runningRecordResult.percentage()
);

private static GoalResultDto buildGoalResultDto(GoalAchievement achievement) {
if (achievement == null) {
return null;
}
default -> {
return null;
}
}
return new GoalResultDto(
achievement.getTitle(),
achievement.getDescription(),
achievement.getIconUrl(),
achievement.isAchieved()
);
}


private static List<RouteDtoV2> convertRouteDtoListFrom(
List<CoordinatePoint> runningRecordRoute) {
// route가 null, empty, 또는 경로데이터를 사용하지 않았을 버전의 데이터 값 인경우 null를 리턴

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -110,6 +110,7 @@ void addRunningRecord_Normal_CheckRunningPath() throws Exception {
createRunningRecordFrom(request),
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.NORMAL,
null,
null,
null));

// when
@@ -121,8 +122,7 @@ void addRunningRecord_Normal_CheckRunningPath() throws Exception {
result.andExpect(status().isOk())
.andExpect(jsonPath("$.data.emotion").value("very-good"))
.andExpect(jsonPath("$.data.achievementMode").value("normal"))
.andExpect(jsonPath("$.data.challenge").doesNotExist())
.andExpect(jsonPath("$.data.goal").doesNotExist())
.andExpect(jsonPath("$.data.achievementResult").doesNotExist())
.andExpect(jsonPath("$.data.runningData.averagePace").value("5’30”"))
.andExpect(
jsonPath("$.data.runningData.route[0].start.longitude").value("1.0"))