Skip to content

Commit

Permalink
Merge pull request #75 from SWM-KAWAI-MANS/develop
Browse files Browse the repository at this point in the history
프로덕션 환경에 반영
  • Loading branch information
seong-wooo authored Oct 14, 2023
2 parents d8e321e + c299049 commit 3be3256
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 4 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build-docker-image-prd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ jobs:
with:
java-version: '17'
distribution: 'temurin'

- name: Login to Docker Hub
uses: docker/[email protected]
with:
Expand Down
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ jacocoTestCoverageVerification {
'**.*Parser*',
'**.*Listener*',
'**.*Message*',
'**.*logging*.**'
'**.*logging*.**',
'**.*mypage*.**'
]
}

Expand All @@ -166,7 +167,7 @@ jacocoTestCoverageVerification {
limit {
counter = 'LINE'
value = 'TOTALCOUNT'
maximum = 20
maximum = 40
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ void addRunnerRecordsAndUpdateRunnerStatus(
Optional<Battle> findBattleByRunnerStatus(String runnerId, List<RunnerStatus> preRunnerStatus);

Optional<Battle> findByIdAndRunnersId(String battleId, String runnerId);

@Query(value = "{ 'runners.id': ?0 }", fields = "{'runners.runnerRecords': 0}")
List<Battle> findAllByRunnersIdExceptRunnerRecords(String runnerId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package online.partyrun.partyrunbattleservice.domain.mypage.controller;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import online.partyrun.partyrunbattleservice.domain.mypage.dto.MyPageHistoryResponse;
import online.partyrun.partyrunbattleservice.domain.mypage.dto.MyPageTotalResponse;
import online.partyrun.partyrunbattleservice.domain.mypage.service.MyPageService;
import online.partyrun.partyrunbattleservice.global.logging.Logging;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Logging
@RestController
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@RequestMapping("mypage")
public class MyPageController {

MyPageService myPageService;

@GetMapping("total")
public MyPageTotalResponse getMyPageTotalResponse(Authentication auth) {
return myPageService.getMyPageTotal(auth.getName());
}

@GetMapping("battles")
public MyPageHistoryResponse getMyPageBattleResponse(Authentication auth) {
return myPageService.getMyPageBattle(auth.getName());
}

@GetMapping("singles")
public MyPageHistoryResponse getMyPageSingleResponse(Authentication auth) {
return myPageService.getMyPageSingle(auth.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package online.partyrun.partyrunbattleservice.domain.mypage.dto;

import online.partyrun.partyrunbattleservice.domain.battle.entity.Battle;
import online.partyrun.partyrunbattleservice.domain.single.entity.Single;

import java.util.Collections;
import java.util.List;

public record MyPageHistoryResponse(List<MyPageRunningResponse> history) {
private static final MyPageHistoryResponse EMPTY_HISTORY = new MyPageHistoryResponse(Collections.emptyList());

public static MyPageHistoryResponse ofBattles(List<Battle> battles, String memberId) {
if (battles.isEmpty()) {
return EMPTY_HISTORY;
}

return new MyPageHistoryResponse(
battles.stream()
.map(battle -> MyPageRunningResponse.of(battle, memberId))
.toList()
);
}

public static MyPageHistoryResponse ofSingle(List<Single> singles) {
if (singles.isEmpty()) {
return EMPTY_HISTORY;
}
return new MyPageHistoryResponse(
singles.stream()
.map(MyPageRunningResponse::from)
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package online.partyrun.partyrunbattleservice.domain.mypage.dto;

import online.partyrun.partyrunbattleservice.domain.battle.entity.Battle;
import online.partyrun.partyrunbattleservice.domain.runner.entity.record.RunnerRecord;
import online.partyrun.partyrunbattleservice.domain.single.dto.RunningTimeResponse;
import online.partyrun.partyrunbattleservice.domain.single.entity.RunningTime;
import online.partyrun.partyrunbattleservice.domain.single.entity.Single;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

public record MyPageRunningResponse(String id,
LocalDateTime startTime,
RunningTimeResponse runningTime,
double distance) {

public static MyPageRunningResponse of(Battle battle, String memberId) {
final RunnerRecord runnerRecentRecord = battle.getRunnerRecentRecord(memberId);

final LocalDateTime startTime = battle.getStartTime();
final LocalDateTime endTime = runnerRecentRecord.getTime();
final Duration duration = Duration.between(startTime, endTime);

return new MyPageRunningResponse(
battle.getId(),
startTime,
new RunningTimeResponse(duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart()),
runnerRecentRecord.getDistance()
);
}

public static MyPageRunningResponse from(Single single) {
final RunningTime runningTime = single.getRunningTime();

final List<RunnerRecord> runnerRecords = single.getRunnerRecords();

return new MyPageRunningResponse(
single.getId(),
runnerRecords.get(0).getTime(),
new RunningTimeResponse(runningTime.getHours(), runningTime.getMinutes(), runningTime.getSeconds()),
runnerRecords.get(runnerRecords.size() - 1).getDistance()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package online.partyrun.partyrunbattleservice.domain.mypage.dto;

import online.partyrun.partyrunbattleservice.domain.battle.entity.Battle;
import online.partyrun.partyrunbattleservice.domain.runner.entity.record.RunnerRecord;
import online.partyrun.partyrunbattleservice.domain.runner.exception.InvalidRecentRunnerRecordException;
import online.partyrun.partyrunbattleservice.domain.single.dto.RunningTimeResponse;
import online.partyrun.partyrunbattleservice.domain.single.entity.Single;

import java.time.Duration;
import java.util.List;

public record MyPageTotalResponse(double totalDistance, double averagePace, RunningTimeResponse totalRunningTime) {

public static MyPageTotalResponse of(String memberId, List<Battle> battles, List<Single> singles) {
if (battles.isEmpty() && singles.isEmpty()) {
return new MyPageTotalResponse(0, 0, new RunningTimeResponse(0, 0, 0));
}

final double totalBattleDistance = battles.stream()
.mapToDouble(
battle -> {
try {
return battle.getRunnerRecentDistance(memberId);
} catch (InvalidRecentRunnerRecordException exception) {
return 0;
}
}
)
.sum();

final long totalBattleRunningTime = battles.stream()
.mapToLong(
battle -> {
try {
return Duration.between(battle.getCreatedAt(), battle.getRunnerRecentRecord(memberId).getTime()).toSeconds();
} catch (InvalidRecentRunnerRecordException exception) {
return 0;
}
}
)
.sum();

final double totalSingleDistance = singles.stream()
.mapToDouble(single -> {
final List<RunnerRecord> runnerRecords = single.getRunnerRecords();
return runnerRecords.get(runnerRecords.size() - 1).getDistance();
})
.sum();

final int totalSingleRunningTime = singles.stream()
.mapToInt(single -> single.getRunningTime().getTotalSeconds())
.sum();


final double totalDistance = totalBattleDistance + totalSingleDistance;
final long totalRunningTime = totalBattleRunningTime + totalSingleRunningTime;

int totalHour = (int) totalRunningTime / 3600;
int totalMinute = (int) (totalRunningTime % 3600) / 60;
int totalSecond = (int) totalRunningTime % 60;

return new MyPageTotalResponse(totalDistance, totalDistance / totalRunningTime, new RunningTimeResponse(totalHour, totalMinute, totalSecond));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package online.partyrun.partyrunbattleservice.domain.mypage.service;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import online.partyrun.partyrunbattleservice.domain.battle.entity.Battle;
import online.partyrun.partyrunbattleservice.domain.battle.repository.BattleRepository;
import online.partyrun.partyrunbattleservice.domain.mypage.dto.MyPageHistoryResponse;
import online.partyrun.partyrunbattleservice.domain.mypage.dto.MyPageTotalResponse;
import online.partyrun.partyrunbattleservice.domain.single.entity.Single;
import online.partyrun.partyrunbattleservice.domain.single.repository.SingleRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class MyPageService {

BattleRepository battleRepository;
SingleRepository singleRepository;

public MyPageTotalResponse getMyPageTotal(String memberId) {
final List<Battle> battles = battleRepository.findAllByRunnersIdExceptRunnerRecords(memberId);
final List<Single> singles = singleRepository.findAllByRunnerId(memberId);

return MyPageTotalResponse.of(memberId, battles, singles);
}

public MyPageHistoryResponse getMyPageBattle(String memberId) {
final List<Battle> battles = battleRepository.findAllByRunnersIdExceptRunnerRecords(memberId);

return MyPageHistoryResponse.ofBattles(battles, memberId);
}

public MyPageHistoryResponse getMyPageSingle(String memberId) {
final List<Single> singles = singleRepository.findAllByRunnerId(memberId);

return MyPageHistoryResponse.ofSingle(singles);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ private boolean isNotCorrectMinutes(int minutes) {
private boolean isNotCorrectSeconds(int seconds) {
return seconds < MIN_TIME || seconds > MAX_TIME;
}

public int getTotalSeconds() {
return hours * 60 * 60 + minutes * 60 + seconds;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@
import online.partyrun.partyrunbattleservice.domain.single.entity.Single;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface SingleRepository extends MongoRepository<Single, String> {

List<Single> findAllByRunnerId(String memberId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package online.partyrun.partyrunbattleservice.global.config;


import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
Expand All @@ -9,7 +10,6 @@

@Configuration
public class RedissonConfig {

@Bean
public RedissonClient singleRedissonClient(@Value("${spring.data.redis.url}") String redisUrl) {
Config config = new Config();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,22 @@ void returnNull() {
);
}
}

@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class findAllByRunnersIdExceptRunnerRecords는 {

@BeforeEach
void setUp() {
battleRepository.save(new Battle(1000, List.of(박성우, 박현준), now));
battleRepository.save(new Battle(1000, List.of(박성우, 노준혁), now));
}
@Test
@DisplayName("러너가 속한 모든 배틀을 반환한다.")
void returnResult() {
final List<Battle> battles = battleRepository.findAllByRunnersIdExceptRunnerRecords(박성우.getId());

assertThat(battles).hasSize(2);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package online.partyrun.partyrunbattleservice.domain.single.repository;

import online.partyrun.partyrunbattleservice.domain.runner.entity.record.GpsData;
import online.partyrun.partyrunbattleservice.domain.runner.entity.record.RunnerRecord;
import online.partyrun.partyrunbattleservice.domain.single.entity.RunningTime;
import online.partyrun.partyrunbattleservice.domain.single.entity.Single;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;

import java.time.LocalDateTime;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@DataMongoTest
@DisplayName("SingleRepository")
class SingleRepositoryTest {

@Autowired
SingleRepository singleRepository;

String runnerId = "박성우";
LocalDateTime now = LocalDateTime.now();

@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class findAllByRunnerId는 {

@Test
@DisplayName("모든 싱글 데이터를 조회한다.")
void returnSingles() {
final List<Single> singleData = List.of(
new Single(runnerId, new RunningTime(0, 0, 1), List.of(new RunnerRecord(GpsData.of(1, 1, 1, now), 0))),
new Single(runnerId, new RunningTime(0, 0, 1), List.of(new RunnerRecord(GpsData.of(1, 1, 1, now), 0)))
);

singleRepository.saveAll(singleData);

final List<Single> singleResult = singleRepository.findAllByRunnerId(runnerId);

assertThat(singleResult).hasSize(2);
}
}
}

0 comments on commit 3be3256

Please sign in to comment.