Merge branch 'refs/heads/24-fix-achievement-date' into sattelgeschichten
# Conflicts: # src/test/java/net/javahippie/fitpub/service/ActivitySummaryServiceTest.java
This commit is contained in:
commit
88ac213214
3 changed files with 128 additions and 10 deletions
|
|
@ -48,9 +48,15 @@ public interface ActivityRepository extends JpaRepository<Activity, UUID> {
|
||||||
* @return list of activities
|
* @return list of activities
|
||||||
*/
|
*/
|
||||||
List<Activity> findByUserIdAndStartedAtBetweenOrderByStartedAtDesc(
|
List<Activity> findByUserIdAndStartedAtBetweenOrderByStartedAtDesc(
|
||||||
UUID userId,
|
UUID userId,
|
||||||
LocalDateTime startDate,
|
LocalDateTime startDate,
|
||||||
LocalDateTime endDate
|
LocalDateTime endDate
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean existsByUserIdAndStartedAtBetween(
|
||||||
|
UUID userId,
|
||||||
|
LocalDateTime startDate,
|
||||||
|
LocalDateTime endDate
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -239,26 +239,67 @@ public class ActivitySummaryService {
|
||||||
/**
|
/**
|
||||||
* Get current week summary.
|
* Get current week summary.
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional
|
||||||
public ActivitySummary getCurrentWeekSummary(UUID userId) {
|
public ActivitySummary getCurrentWeekSummary(UUID userId) {
|
||||||
LocalDate weekStart = LocalDate.now().with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
|
LocalDate weekStart = LocalDate.now().with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
|
||||||
return activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
LocalDate weekEndExclusive = weekStart.plusDays(7);
|
||||||
|
return getOrBuildCurrentSummary(
|
||||||
userId,
|
userId,
|
||||||
ActivitySummary.PeriodType.WEEK,
|
ActivitySummary.PeriodType.WEEK,
|
||||||
weekStart
|
weekStart,
|
||||||
).orElse(null);
|
weekEndExclusive,
|
||||||
|
() -> updateWeeklySummary(userId, weekStart)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current month summary.
|
* Get current month summary.
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional
|
||||||
public ActivitySummary getCurrentMonthSummary(UUID userId) {
|
public ActivitySummary getCurrentMonthSummary(UUID userId) {
|
||||||
LocalDate monthStart = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
|
LocalDate monthStart = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
|
||||||
return activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
LocalDate monthEndExclusive = monthStart.plusMonths(1);
|
||||||
|
return getOrBuildCurrentSummary(
|
||||||
userId,
|
userId,
|
||||||
ActivitySummary.PeriodType.MONTH,
|
ActivitySummary.PeriodType.MONTH,
|
||||||
monthStart
|
monthStart,
|
||||||
|
monthEndExclusive,
|
||||||
|
() -> updateMonthlySummary(userId, monthStart)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActivitySummary getOrBuildCurrentSummary(
|
||||||
|
UUID userId,
|
||||||
|
ActivitySummary.PeriodType periodType,
|
||||||
|
LocalDate periodStart,
|
||||||
|
LocalDate periodEndExclusive,
|
||||||
|
Runnable rebuildAction
|
||||||
|
) {
|
||||||
|
ActivitySummary existingSummary = activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
||||||
|
userId,
|
||||||
|
periodType,
|
||||||
|
periodStart
|
||||||
|
).orElse(null);
|
||||||
|
|
||||||
|
if (existingSummary != null) {
|
||||||
|
return existingSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasActivitiesInPeriod = activityRepository.existsByUserIdAndStartedAtBetween(
|
||||||
|
userId,
|
||||||
|
periodStart.atStartOfDay(),
|
||||||
|
periodEndExclusive.atStartOfDay()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasActivitiesInPeriod) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
rebuildAction.run();
|
||||||
|
return activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
||||||
|
userId,
|
||||||
|
periodType,
|
||||||
|
periodStart
|
||||||
).orElse(null);
|
).orElse(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,9 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.argThat;
|
import static org.mockito.Mockito.argThat;
|
||||||
|
|
@ -144,4 +147,72 @@ class ActivitySummaryServiceTest {
|
||||||
summary.getActivityCount() == 1
|
summary.getActivityCount() == 1
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should rebuild current month summary on demand when activities exist but summary is missing")
|
||||||
|
void getCurrentMonthSummary_RebuildsMissingSummary() {
|
||||||
|
LocalDate monthStart = LocalDate.now().withDayOfMonth(1);
|
||||||
|
LocalDateTime startDateTime = monthStart.atStartOfDay();
|
||||||
|
LocalDateTime endDateTime = monthStart.plusMonths(1).atStartOfDay();
|
||||||
|
|
||||||
|
Activity activity = Activity.builder()
|
||||||
|
.id(UUID.randomUUID())
|
||||||
|
.userId(userId)
|
||||||
|
.activityType(Activity.ActivityType.RUN)
|
||||||
|
.startedAt(startDateTime.plusDays(2).plusHours(7))
|
||||||
|
.endedAt(startDateTime.plusDays(2).plusHours(8))
|
||||||
|
.totalDistance(BigDecimal.valueOf(10000))
|
||||||
|
.totalDurationSeconds(3600L)
|
||||||
|
.elevationGain(BigDecimal.valueOf(150))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ActivitySummary rebuiltSummary = ActivitySummary.builder()
|
||||||
|
.userId(userId)
|
||||||
|
.periodType(ActivitySummary.PeriodType.MONTH)
|
||||||
|
.periodStart(monthStart)
|
||||||
|
.periodEnd(monthStart.plusMonths(1).minusDays(1))
|
||||||
|
.activityCount(1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
when(activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
||||||
|
userId,
|
||||||
|
ActivitySummary.PeriodType.MONTH,
|
||||||
|
monthStart
|
||||||
|
)).thenReturn(Optional.empty(), Optional.of(rebuiltSummary));
|
||||||
|
when(activityRepository.existsByUserIdAndStartedAtBetween(userId, startDateTime, endDateTime))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(activityRepository.findByUserIdAndStartedAtBetweenOrderByStartedAtDesc(userId, startDateTime, endDateTime))
|
||||||
|
.thenReturn(List.of(activity));
|
||||||
|
when(personalRecordRepository.countByUserIdAndDateRange(userId, startDateTime, endDateTime)).thenReturn(0L);
|
||||||
|
when(achievementRepository.countByUserIdAndActivityStartedDateRange(userId, startDateTime, endDateTime)).thenReturn(0L);
|
||||||
|
when(activitySummaryRepository.save(org.mockito.ArgumentMatchers.any(ActivitySummary.class)))
|
||||||
|
.thenAnswer(invocation -> invocation.getArgument(0));
|
||||||
|
|
||||||
|
ActivitySummary result = activitySummaryService.getCurrentMonthSummary(userId);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.getActivityCount());
|
||||||
|
verify(activityRepository).existsByUserIdAndStartedAtBetween(userId, startDateTime, endDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should return null for current month summary when no activities exist in the period")
|
||||||
|
void getCurrentMonthSummary_ReturnsNullWhenNoActivitiesExist() {
|
||||||
|
LocalDate monthStart = LocalDate.now().withDayOfMonth(1);
|
||||||
|
LocalDateTime startDateTime = monthStart.atStartOfDay();
|
||||||
|
LocalDateTime endDateTime = monthStart.plusMonths(1).atStartOfDay();
|
||||||
|
|
||||||
|
when(activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
||||||
|
userId,
|
||||||
|
ActivitySummary.PeriodType.MONTH,
|
||||||
|
monthStart
|
||||||
|
)).thenReturn(Optional.empty());
|
||||||
|
when(activityRepository.existsByUserIdAndStartedAtBetween(userId, startDateTime, endDateTime))
|
||||||
|
.thenReturn(false);
|
||||||
|
|
||||||
|
ActivitySummary result = activitySummaryService.getCurrentMonthSummary(userId);
|
||||||
|
|
||||||
|
assertNull(result);
|
||||||
|
verify(activityRepository).existsByUserIdAndStartedAtBetween(userId, startDateTime, endDateTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue