fix(analytics): count summary achievements by activity period
Signed-off-by: Marcus Fihlon <marcus@fihlon.swiss>
This commit is contained in:
parent
6af484bcf7
commit
10037de043
3 changed files with 113 additions and 1 deletions
|
|
@ -60,6 +60,23 @@ public interface AchievementRepository extends JpaRepository<Achievement, UUID>
|
|||
@Param("endDate") LocalDateTime endDate
|
||||
);
|
||||
|
||||
/**
|
||||
* Count achievements whose triggering activity started within a date range.
|
||||
*/
|
||||
@Query(value = """
|
||||
SELECT COUNT(*)
|
||||
FROM achievements ach
|
||||
JOIN activities act ON act.id = ach.activity_id
|
||||
WHERE ach.user_id = :userId
|
||||
AND act.started_at >= :startDate
|
||||
AND act.started_at < :endDate
|
||||
""", nativeQuery = true)
|
||||
long countByUserIdAndActivityStartedDateRange(
|
||||
@Param("userId") UUID userId,
|
||||
@Param("startDate") LocalDateTime startDate,
|
||||
@Param("endDate") LocalDateTime endDate
|
||||
);
|
||||
|
||||
/**
|
||||
* Find recent achievements for a user.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ public class ActivitySummaryService {
|
|||
startDateTime,
|
||||
endDateTime
|
||||
);
|
||||
long achievementsEarned = achievementRepository.countByUserIdAndDateRange(
|
||||
long achievementsEarned = achievementRepository.countByUserIdAndActivityStartedDateRange(
|
||||
userId,
|
||||
startDateTime,
|
||||
endDateTime
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
package net.javahippie.fitpub.service;
|
||||
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.ActivitySummary;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.ActivitySummaryRepository;
|
||||
import net.javahippie.fitpub.repository.AchievementRepository;
|
||||
import net.javahippie.fitpub.repository.PersonalRecordRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ActivitySummaryServiceTest {
|
||||
|
||||
@Mock
|
||||
private ActivitySummaryRepository activitySummaryRepository;
|
||||
|
||||
@Mock
|
||||
private ActivityRepository activityRepository;
|
||||
|
||||
@Mock
|
||||
private PersonalRecordRepository personalRecordRepository;
|
||||
|
||||
@Mock
|
||||
private AchievementRepository achievementRepository;
|
||||
|
||||
@InjectMocks
|
||||
private ActivitySummaryService activitySummaryService;
|
||||
|
||||
private UUID userId;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
userId = UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should count achievements in summaries by triggering activity start date")
|
||||
void testUpdateWeeklySummary_CountsAchievementsByActivityStartDate() {
|
||||
LocalDate weekDate = LocalDate.of(2025, 12, 3);
|
||||
LocalDate weekStart = LocalDate.of(2025, 12, 1);
|
||||
LocalDateTime startDateTime = weekStart.atStartOfDay();
|
||||
LocalDateTime endDateTime = weekStart.plusDays(7).atStartOfDay();
|
||||
|
||||
Activity activity = Activity.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.userId(userId)
|
||||
.activityType(Activity.ActivityType.RUN)
|
||||
.startedAt(LocalDateTime.of(2025, 12, 3, 23, 30))
|
||||
.endedAt(LocalDateTime.of(2025, 12, 4, 0, 15))
|
||||
.totalDistance(BigDecimal.valueOf(5000))
|
||||
.totalDurationSeconds(2700L)
|
||||
.elevationGain(BigDecimal.valueOf(120))
|
||||
.build();
|
||||
|
||||
when(activitySummaryRepository.findByUserIdAndPeriodTypeAndPeriodStart(
|
||||
userId,
|
||||
ActivitySummary.PeriodType.WEEK,
|
||||
weekStart
|
||||
)).thenReturn(Optional.empty());
|
||||
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(1L);
|
||||
when(activitySummaryRepository.save(org.mockito.ArgumentMatchers.any(ActivitySummary.class)))
|
||||
.thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
activitySummaryService.updateWeeklySummary(userId, weekDate);
|
||||
|
||||
verify(achievementRepository).countByUserIdAndActivityStartedDateRange(userId, startDateTime, endDateTime);
|
||||
verify(activitySummaryRepository).save(org.mockito.ArgumentMatchers.argThat(summary ->
|
||||
summary.getAchievementsEarned() == 1 &&
|
||||
summary.getActivityCount() == 1
|
||||
));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue