Skip to content

Commit 7f75743

Browse files
committed
created Streak service test
1 parent 6656752 commit 7f75743

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

tests/Unit/StreakServiceTest.php

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
use App\Models\CheckIn;
4+
use App\Models\User;
5+
use App\Models\WorkSession;
6+
use App\Services\StreakService;
7+
use Carbon\Carbon;
8+
9+
beforeEach(function () {
10+
Carbon::setTestNow();
11+
});
12+
13+
it('returns an empty array of active days when there is no activity', function () {
14+
$user = User::factory()->create();
15+
16+
$service = new StreakService();
17+
18+
expect($service->activeDaysForUser($user))->toBe([]);
19+
});
20+
21+
it('computes active days from both check-ins and completed work sessions', function () {
22+
$user = User::factory()->create();
23+
24+
Carbon::setTestNow('2026-03-10 10:00:00');
25+
26+
// Check-ins on two days.
27+
CheckIn::create([
28+
'user_id' => $user->id,
29+
'date' => Carbon::today()->subDays(2),
30+
'intention' => 'Earlier check-in',
31+
]);
32+
33+
CheckIn::create([
34+
'user_id' => $user->id,
35+
'date' => Carbon::today()->subDay(),
36+
'intention' => 'Yesterday check-in',
37+
]);
38+
39+
// Completed work session today.
40+
WorkSession::create([
41+
'user_id' => $user->id,
42+
'started_at' => Carbon::today()->setTime(8, 0),
43+
'ended_at' => Carbon::today()->setTime(9, 0),
44+
'planned_duration_minutes' => 60,
45+
]);
46+
47+
$service = new StreakService();
48+
49+
$days = $service->activeDaysForUser($user);
50+
51+
expect($days)->toEqualCanonicalizing([
52+
Carbon::today()->toDateString(),
53+
Carbon::today()->subDay()->toDateString(),
54+
Carbon::today()->subDays(2)->toDateString(),
55+
]);
56+
});
57+
58+
it('returns 0 streak when today is not active', function () {
59+
$user = User::factory()->create();
60+
61+
Carbon::setTestNow('2026-03-10 10:00:00');
62+
63+
// Activity only on previous days, not today.
64+
CheckIn::create([
65+
'user_id' => $user->id,
66+
'date' => Carbon::today()->subDay(),
67+
'intention' => 'Yesterday only',
68+
]);
69+
70+
$service = new StreakService();
71+
72+
expect($service->currentStreak($user))->toBe(0);
73+
});
74+
75+
it('counts consecutive active days ending today as the current streak', function () {
76+
$user = User::factory()->create();
77+
78+
Carbon::setTestNow('2026-03-10 10:00:00');
79+
80+
// Three consecutive days including today.
81+
foreach ([2, 1, 0] as $daysAgo) {
82+
CheckIn::create([
83+
'user_id' => $user->id,
84+
'date' => Carbon::today()->subDays($daysAgo),
85+
'intention' => 'Day-'.$daysAgo,
86+
]);
87+
}
88+
89+
$service = new StreakService();
90+
91+
expect($service->currentStreak($user))->toBe(3);
92+
});
93+
94+
it('breaks the streak when there is a gap day', function () {
95+
$user = User::factory()->create();
96+
97+
Carbon::setTestNow('2026-03-10 10:00:00');
98+
99+
// Activity 4 and 2 days ago, plus today. Gap at 1 day ago.
100+
foreach ([4, 2, 0] as $daysAgo) {
101+
CheckIn::create([
102+
'user_id' => $user->id,
103+
'date' => Carbon::today()->subDays($daysAgo),
104+
'intention' => 'Day-'.$daysAgo,
105+
]);
106+
}
107+
108+
$service = new StreakService();
109+
110+
// Only today is consecutive, yesterday is inactive so streak is 1.
111+
expect($service->currentStreak($user))->toBe(1);
112+
});
113+

0 commit comments

Comments
 (0)