Skip to content

Commit e276a99

Browse files
committed
add tests
1 parent 6bef315 commit e276a99

File tree

2 files changed

+189
-2
lines changed

2 files changed

+189
-2
lines changed

app/Http/Resources/Models/Utils/TimelineData.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use App\Http\Resources\Models\PhotoResource;
1717
use App\Http\Resources\Models\ThumbAlbumResource;
1818
use Carbon\Carbon;
19+
use Carbon\Exceptions\InvalidFormatException;
1920
use Illuminate\Support\Collection;
2021
use Safe\Exceptions\PcreException;
2122
use function Safe\preg_match;
@@ -64,7 +65,7 @@ public static function fromPhoto(PhotoResource $photo, TimelinePhotoGranularity
6465
*
6566
* @return ?Carbon The parsed Carbon date object or null if parsing fails
6667
*/
67-
private static function parseDateFromTitle(string $title): ?Carbon
68+
public static function parseDateFromTitle(string $title): ?Carbon
6869
{
6970
// A title is expected to be in one of the following formats:
7071
// "YYYY something"
@@ -83,7 +84,7 @@ private static function parseDateFromTitle(string $title): ?Carbon
8384
}
8485

8586
return null;
86-
} catch (PcreException $e) {
87+
} catch (PcreException|InvalidFormatException $e) {
8788
// fail silently.
8889
return null;
8990
}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2025 LycheeOrg.
7+
*/
8+
9+
/**
10+
* We don't care for unhandled exceptions in tests.
11+
* It is the nature of a test to throw an exception.
12+
* Without this suppression we had 100+ Linter warning in this file which
13+
* don't help anything.
14+
*
15+
* @noinspection PhpDocMissingThrowsInspection
16+
* @noinspection PhpUnhandledExceptionInspection
17+
*/
18+
19+
namespace Tests\Unit\Http\Resources;
20+
21+
use App\Http\Resources\Models\Utils\TimelineData;
22+
use Tests\AbstractTestCase;
23+
24+
class TimelineDataTest extends AbstractTestCase
25+
{
26+
public function testParseDateFromTitleWithFullDate(): void
27+
{
28+
$result = TimelineData::parseDateFromTitle('2023-12-25 Christmas Day');
29+
30+
self::assertNotNull($result);
31+
self::assertEquals(2023, $result->year);
32+
self::assertEquals(12, $result->month);
33+
self::assertEquals(25, $result->day);
34+
}
35+
36+
public function testParseDateFromTitleWithYearAndMonth(): void
37+
{
38+
$result = TimelineData::parseDateFromTitle('2023-12 December');
39+
40+
self::assertNotNull($result);
41+
self::assertEquals(2023, $result->year);
42+
self::assertEquals(12, $result->month);
43+
self::assertEquals(1, $result->day); // Should default to day 1
44+
}
45+
46+
public function testParseDateFromTitleWithYearOnly(): void
47+
{
48+
$result = TimelineData::parseDateFromTitle('2023 A Great Year');
49+
50+
self::assertNotNull($result);
51+
self::assertEquals(2023, $result->year);
52+
self::assertEquals(1, $result->month); // Should default to month 1
53+
self::assertEquals(1, $result->day); // Should default to day 1
54+
}
55+
56+
public function testParseDateFromTitleWithNoText(): void
57+
{
58+
$result = TimelineData::parseDateFromTitle('2023-06-15');
59+
60+
self::assertNotNull($result);
61+
self::assertEquals(2023, $result->year);
62+
self::assertEquals(6, $result->month);
63+
self::assertEquals(15, $result->day);
64+
}
65+
66+
public function testParseDateFromTitleWithInvalidFormat(): void
67+
{
68+
$result = TimelineData::parseDateFromTitle('December 25, 2023');
69+
70+
self::assertNull($result);
71+
}
72+
73+
public function testParseDateFromTitleWithNoDate(): void
74+
{
75+
$result = TimelineData::parseDateFromTitle('Just a regular title');
76+
77+
self::assertNull($result);
78+
}
79+
80+
public function testParseDateFromTitleWithEmptyString(): void
81+
{
82+
$result = TimelineData::parseDateFromTitle('');
83+
84+
self::assertNull($result);
85+
}
86+
87+
public function testParseDateFromTitleWithDateInMiddle(): void
88+
{
89+
// Should not match - date must be at the beginning
90+
$result = TimelineData::parseDateFromTitle('Some text 2023-12-25 more text');
91+
92+
self::assertNull($result);
93+
}
94+
95+
public function testParseDateFromTitleWithLeadingZeros(): void
96+
{
97+
$result = TimelineData::parseDateFromTitle('2023-01-05 New Year');
98+
99+
self::assertNotNull($result);
100+
self::assertEquals(2023, $result->year);
101+
self::assertEquals(1, $result->month);
102+
self::assertEquals(5, $result->day);
103+
}
104+
105+
public function testParseDateFromTitleWithInvalidMonth(): void
106+
{
107+
// Invalid month (13) - Carbon will overflow to next year
108+
$result = TimelineData::parseDateFromTitle('2023-13-01 Invalid Month');
109+
110+
self::assertNotNull($result);
111+
// Month 13 overflows to January of 2024
112+
self::assertEquals(2024, $result->year);
113+
self::assertEquals(1, $result->month);
114+
self::assertEquals(1, $result->day);
115+
}
116+
117+
public function testParseDateFromTitleWithInvalidDay(): void
118+
{
119+
// Invalid day (32) - Carbon will overflow to next month
120+
$result = TimelineData::parseDateFromTitle('2023-12-32 Invalid Day');
121+
122+
self::assertNotNull($result);
123+
// Day 32 of December overflows to January 1 of 2024
124+
self::assertEquals(2024, $result->year);
125+
self::assertEquals(1, $result->month);
126+
self::assertEquals(1, $result->day);
127+
}
128+
129+
public function testParseDateFromTitleWithShortYear(): void
130+
{
131+
// Year must be 4 digits
132+
$result = TimelineData::parseDateFromTitle('23-12-25 Short Year');
133+
134+
self::assertNull($result);
135+
}
136+
137+
public function testParseDateFromTitleWithExtraHyphens(): void
138+
{
139+
$result = TimelineData::parseDateFromTitle('2023-12-25-something');
140+
141+
self::assertNotNull($result);
142+
self::assertEquals(2023, $result->year);
143+
self::assertEquals(12, $result->month);
144+
self::assertEquals(25, $result->day);
145+
}
146+
147+
public function testParseDateFromTitleWithWhitespace(): void
148+
{
149+
$result = TimelineData::parseDateFromTitle('2023-12-25 Multiple Spaces');
150+
151+
self::assertNotNull($result);
152+
self::assertEquals(2023, $result->year);
153+
self::assertEquals(12, $result->month);
154+
self::assertEquals(25, $result->day);
155+
}
156+
157+
public function testParseDateFromTitleWithLeapYear(): void
158+
{
159+
$result = TimelineData::parseDateFromTitle('2024-02-29 Leap Day');
160+
161+
self::assertNotNull($result);
162+
self::assertEquals(2024, $result->year);
163+
self::assertEquals(2, $result->month);
164+
self::assertEquals(29, $result->day);
165+
}
166+
167+
public function testParseDateFromTitleWithHistoricalDate(): void
168+
{
169+
$result = TimelineData::parseDateFromTitle('1900-01-01 Turn of Century');
170+
171+
self::assertNotNull($result);
172+
self::assertEquals(1900, $result->year);
173+
self::assertEquals(1, $result->month);
174+
self::assertEquals(1, $result->day);
175+
}
176+
177+
public function testParseDateFromTitleWithFutureDate(): void
178+
{
179+
$result = TimelineData::parseDateFromTitle('2099-12-31 Future Date');
180+
181+
self::assertNotNull($result);
182+
self::assertEquals(2099, $result->year);
183+
self::assertEquals(12, $result->month);
184+
self::assertEquals(31, $result->day);
185+
}
186+
}

0 commit comments

Comments
 (0)