totalFailedJobs)->toBe(0); expect($state->failedJobs)->toBe([]); expect($state->statistics)->toBe([]); expect($state->lastUpdated)->toBeString(); }); it('creates state from array', function () { $data = [ 'totalFailedJobs' => 15, 'failedJobs' => [ [ 'id' => 'job-1', 'queue' => 'default', 'error' => 'Connection timeout', ], ], 'statistics' => [ 'total_retries' => 42, 'avg_failure_time' => 123.45, ], 'lastUpdated' => '2024-01-15 12:00:00', ]; $state = FailedJobsState::fromArray($data); expect($state->totalFailedJobs)->toBe(15); expect($state->failedJobs)->toHaveCount(1); expect($state->statistics)->toHaveKey('total_retries'); }); it('converts state to array', function () { $failedJobs = [ [ 'id' => 'job-1', 'queue' => 'default', 'job_type' => 'EmailJob', 'error' => 'SMTP connection failed', 'failed_at' => '2024-01-15 12:00:00', 'attempts' => 3, ], ]; $statistics = [ 'total_retries' => 10, 'successful_retries' => 8, ]; $state = new FailedJobsState( totalFailedJobs: 1, failedJobs: $failedJobs, statistics: $statistics, lastUpdated: '2024-01-15 12:00:00' ); $array = $state->toArray(); expect($array)->toHaveKey('totalFailedJobs'); expect($array)->toHaveKey('failedJobs'); expect($array)->toHaveKey('statistics'); expect($array['failedJobs'])->toHaveCount(1); }); it('creates new state with updated failed jobs', function () { $state = FailedJobsState::empty(); $failedJobs = [ [ 'id' => 'job-1', 'error' => 'Database connection lost', 'attempts' => 5, ], ]; $statistics = [ 'most_common_error' => 'Database connection lost', 'total_failures_today' => 10, ]; $updatedState = $state->withFailedJobs( totalFailedJobs: 1, failedJobs: $failedJobs, statistics: $statistics ); // Original unchanged expect($state->totalFailedJobs)->toBe(0); expect($state->failedJobs)->toBe([]); // New state updated expect($updatedState->totalFailedJobs)->toBe(1); expect($updatedState->failedJobs)->toHaveCount(1); expect($updatedState->statistics)->toHaveKey('most_common_error'); expect($updatedState->lastUpdated)->not->toBe($state->lastUpdated); }); it('is immutable', function () { $state = new FailedJobsState( totalFailedJobs: 5, failedJobs: [], statistics: [], lastUpdated: '2024-01-15 12:00:00' ); $newState = $state->withFailedJobs( totalFailedJobs: 10, failedJobs: [], statistics: [] ); // Original unchanged expect($state->totalFailedJobs)->toBe(5); // New instance expect($newState)->not->toBe($state); expect($newState->totalFailedJobs)->toBe(10); }); it('handles empty failed jobs list', function () { $state = FailedJobsState::empty()->withFailedJobs( totalFailedJobs: 0, failedJobs: [], statistics: [] ); expect($state->failedJobs)->toBe([]); expect($state->totalFailedJobs)->toBe(0); expect($state->statistics)->toBe([]); }); });