fedi-feed-router/tests/Unit/Support/DateRangeTest.php

230 lines
7.2 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Tests\Unit\Support;
use App\Support\DateRange;
use Illuminate\Support\Carbon;
use InvalidArgumentException;
use Tests\TestCase;
class DateRangeTest extends TestCase
{
public function test_it_exposes_from_and_to(): void
{
$from = Carbon::parse('2026-07-01 00:00:00');
$to = Carbon::parse('2026-07-31 23:59:59');
$range = new DateRange($from, $to);
$this->assertTrue($from->equalTo($range->from));
$this->assertTrue($to->equalTo($range->to));
}
public function test_it_rejects_a_to_earlier_than_from(): void
{
$this->expectException(InvalidArgumentException::class);
new DateRange(
Carbon::parse('2026-07-31 00:00:00'),
Carbon::parse('2026-07-01 00:00:00'),
);
}
public function test_it_allows_a_range_covering_a_single_instant(): void
{
$instant = Carbon::parse('2026-07-01 12:00:00');
$range = new DateRange($instant, $instant);
$this->assertTrue($range->from->equalTo($range->to));
}
public function test_it_builds_today_as_the_current_day(): void
{
Carbon::setTestNow('2026-07-15 13:45:00');
$range = DateRange::preset('today');
$this->assertSame('2026-07-15 00:00:00', $range->from->toDateTimeString());
$this->assertSame('2026-07-15 23:59:59', $range->to->toDateTimeString());
}
public function test_it_builds_week_month_and_year_presets(): void
{
Carbon::setTestNow('2026-07-15 13:45:00');
$week = DateRange::preset('week');
$this->assertTrue($week->from->equalTo(Carbon::parse('2026-07-15')->startOfWeek()));
$this->assertTrue($week->to->equalTo(Carbon::parse('2026-07-15')->endOfWeek()));
$month = DateRange::preset('month');
$this->assertSame('2026-07-01 00:00:00', $month->from->toDateTimeString());
$this->assertSame('2026-07-31 23:59:59', $month->to->toDateTimeString());
$year = DateRange::preset('year');
$this->assertSame('2026-01-01 00:00:00', $year->from->toDateTimeString());
$this->assertSame('2026-12-31 23:59:59', $year->to->toDateTimeString());
}
public function test_it_builds_all_as_a_bounded_range_ending_now(): void
{
Carbon::setTestNow('2026-07-15 13:45:00');
$range = DateRange::preset('all');
$this->assertSame('2026-07-15 23:59:59', $range->to->toDateTimeString());
$this->assertTrue($range->from->lessThan(Carbon::parse('2000-01-01')));
}
public function test_it_rejects_an_unknown_preset(): void
{
$this->expectException(InvalidArgumentException::class);
DateRange::preset('fortnight');
}
public function test_it_lists_the_available_presets(): void
{
$presets = DateRange::presets();
$this->assertSame(
['today', 'week', 'month', 'year', 'all'],
array_keys($presets),
);
$this->assertSame('Today', $presets['today']);
$this->assertSame('All Time', $presets['all']);
}
public function test_it_lists_each_day_in_the_range(): void
{
$range = new DateRange(
Carbon::parse('2026-07-01 09:30:00'),
Carbon::parse('2026-07-04 18:00:00'),
);
$this->assertSame(
['2026-07-01', '2026-07-02', '2026-07-03', '2026-07-04'],
$range->days(),
);
}
public function test_it_lists_a_single_day_for_a_same_day_range(): void
{
$range = new DateRange(
Carbon::parse('2026-07-01 00:00:00'),
Carbon::parse('2026-07-01 23:59:59'),
);
$this->assertSame(['2026-07-01'], $range->days());
}
public function test_it_lists_days_across_a_month_boundary(): void
{
$range = new DateRange(
Carbon::parse('2026-01-30 00:00:00'),
Carbon::parse('2026-02-02 23:59:59'),
);
$this->assertSame(
['2026-01-30', '2026-01-31', '2026-02-01', '2026-02-02'],
$range->days(),
);
}
public function test_it_lists_days_across_a_year_boundary(): void
{
$range = new DateRange(
Carbon::parse('2025-12-30 00:00:00'),
Carbon::parse('2026-01-02 23:59:59'),
);
$this->assertSame(
['2025-12-30', '2025-12-31', '2026-01-01', '2026-01-02'],
$range->days(),
);
}
public function test_it_lists_every_day_of_a_leap_february(): void
{
$range = new DateRange(
Carbon::parse('2028-02-27 00:00:00'),
Carbon::parse('2028-03-01 23:59:59'),
);
$this->assertSame(
['2028-02-27', '2028-02-28', '2028-02-29', '2028-03-01'],
$range->days(),
);
}
public function test_it_lists_days_up_to_the_maximum_span(): void
{
$from = Carbon::parse('2026-01-01 00:00:00');
$range = new DateRange($from, $from->copy()->addDays(DateRange::MAX_DAYS - 1)->endOfDay());
$this->assertCount(DateRange::MAX_DAYS, $range->days());
}
public function test_it_refuses_to_list_days_for_a_range_wider_than_the_maximum(): void
{
$from = Carbon::parse('2026-01-01 00:00:00');
$range = new DateRange($from, $from->copy()->addDays(DateRange::MAX_DAYS)->endOfDay());
$this->expectException(InvalidArgumentException::class);
$range->days();
}
public function test_it_refuses_to_list_days_for_the_all_preset(): void
{
Carbon::setTestNow('2026-07-15 13:45:00');
$this->expectException(InvalidArgumentException::class);
DateRange::preset('all')->days();
}
public function test_it_is_bucketable_by_day_for_a_normal_range(): void
{
$this->assertTrue(DateRange::preset('week')->isBucketableByDay());
$this->assertTrue(DateRange::preset('month')->isBucketableByDay());
}
public function test_it_is_bucketable_by_day_at_the_maximum_span(): void
{
$from = Carbon::parse('2026-01-01 00:00:00');
$range = new DateRange($from, $from->copy()->addDays(DateRange::MAX_DAYS - 1)->endOfDay());
$this->assertTrue($range->isBucketableByDay());
}
public function test_it_is_not_bucketable_by_day_one_day_beyond_the_maximum_span(): void
{
$from = Carbon::parse('2026-01-01 00:00:00');
$range = new DateRange($from, $from->copy()->addDays(DateRange::MAX_DAYS)->endOfDay());
$this->assertFalse($range->isBucketableByDay());
}
public function test_it_is_not_bucketable_by_day_for_the_all_preset(): void
{
Carbon::setTestNow('2026-07-15 13:45:00');
$this->assertFalse(DateRange::preset('all')->isBucketableByDay());
}
public function test_is_bucketable_by_day_agrees_with_days_at_every_boundary(): void
{
$from = Carbon::parse('2026-01-01 00:00:00');
$withinBounds = new DateRange($from, $from->copy()->addDays(DateRange::MAX_DAYS - 1)->endOfDay());
$withinBounds->days();
$this->assertTrue($withinBounds->isBucketableByDay());
$beyondBounds = new DateRange($from, $from->copy()->addDays(DateRange::MAX_DAYS)->endOfDay());
$this->assertFalse($beyondBounds->isBucketableByDay());
$this->expectException(InvalidArgumentException::class);
$beyondBounds->days();
}
}