2026-04-26 13:06:22 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace Tests\Unit\Enums;
|
|
|
|
|
|
|
|
|
|
use App\Enums\CrawlOutcomeEnum;
|
2026-04-27 01:36:37 +02:00
|
|
|
use App\Enums\PageStatusEnum;
|
2026-04-26 13:06:22 +02:00
|
|
|
use Tests\TestCase;
|
|
|
|
|
|
|
|
|
|
class CrawlOutcomeEnumTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
public function test_all_expected_cases_exist_with_correct_backing_values(): void
|
|
|
|
|
{
|
|
|
|
|
$expected = [
|
|
|
|
|
'Success' => 'success',
|
|
|
|
|
'Failed' => 'failed',
|
|
|
|
|
'Timeout' => 'timeout',
|
|
|
|
|
'BlockedRobots' => 'blocked_robots',
|
|
|
|
|
'Blocked4xx' => 'blocked_4xx',
|
|
|
|
|
'Blocked5xx' => 'blocked_5xx',
|
2026-04-26 16:35:46 +02:00
|
|
|
'Rejected' => 'rejected',
|
2026-04-26 13:06:22 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
foreach ($expected as $caseName => $backingValue) {
|
|
|
|
|
$case = CrawlOutcomeEnum::from($backingValue);
|
|
|
|
|
|
|
|
|
|
$this->assertSame($caseName, $case->name, "Case name for '{$backingValue}' should be '{$caseName}'");
|
|
|
|
|
$this->assertSame($backingValue, $case->value, "Backing value for '{$caseName}' should be '{$backingValue}'");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-26 16:35:46 +02:00
|
|
|
public function test_enum_has_exactly_seven_cases(): void
|
2026-04-26 13:06:22 +02:00
|
|
|
{
|
2026-04-26 16:35:46 +02:00
|
|
|
$this->assertCount(7, CrawlOutcomeEnum::cases());
|
2026-04-26 13:06:22 +02:00
|
|
|
}
|
2026-04-27 01:36:37 +02:00
|
|
|
|
|
|
|
|
public function test_to_page_status_maps_each_outcome_correctly(): void
|
|
|
|
|
{
|
|
|
|
|
$this->assertSame(PageStatusEnum::Fetched, CrawlOutcomeEnum::Success->toPageStatus());
|
|
|
|
|
$this->assertSame(PageStatusEnum::Rejected, CrawlOutcomeEnum::Rejected->toPageStatus());
|
|
|
|
|
$this->assertSame(PageStatusEnum::Failed, CrawlOutcomeEnum::Failed->toPageStatus());
|
|
|
|
|
$this->assertSame(PageStatusEnum::Failed, CrawlOutcomeEnum::Timeout->toPageStatus());
|
|
|
|
|
$this->assertSame(PageStatusEnum::Failed, CrawlOutcomeEnum::Blocked4xx->toPageStatus());
|
|
|
|
|
$this->assertSame(PageStatusEnum::Failed, CrawlOutcomeEnum::Blocked5xx->toPageStatus());
|
|
|
|
|
$this->assertSame(PageStatusEnum::Failed, CrawlOutcomeEnum::BlockedRobots->toPageStatus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_is_retryable_returns_true_only_for_transient_failures(): void
|
|
|
|
|
{
|
|
|
|
|
// Retryable: transient network/server problems that may resolve later
|
|
|
|
|
$this->assertTrue(CrawlOutcomeEnum::Failed->isRetryable());
|
|
|
|
|
$this->assertTrue(CrawlOutcomeEnum::Timeout->isRetryable());
|
|
|
|
|
$this->assertTrue(CrawlOutcomeEnum::Blocked5xx->isRetryable());
|
|
|
|
|
|
|
|
|
|
// Not retryable: success (done), permanent failures, or policy decisions
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Success->isRetryable());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Rejected->isRetryable());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::BlockedRobots->isRetryable());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Blocked4xx->isRetryable());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_should_register_outbound_links_returns_true_only_for_success(): void
|
|
|
|
|
{
|
|
|
|
|
$this->assertTrue(CrawlOutcomeEnum::Success->shouldRegisterOutboundLinks());
|
|
|
|
|
|
|
|
|
|
// No links to register on any non-Success outcome
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Failed->shouldRegisterOutboundLinks());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Timeout->shouldRegisterOutboundLinks());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Rejected->shouldRegisterOutboundLinks());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::BlockedRobots->shouldRegisterOutboundLinks());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Blocked4xx->shouldRegisterOutboundLinks());
|
|
|
|
|
$this->assertFalse(CrawlOutcomeEnum::Blocked5xx->shouldRegisterOutboundLinks());
|
|
|
|
|
}
|
2026-04-26 13:06:22 +02:00
|
|
|
}
|