create([ 'resource' => 'drift', 'action' => 'generate', ]); expect($run->runType())->toBe('drift.generate'); }); test('bulk operation statusBucket maps pending and running', function () { $pending = BulkOperationRun::factory()->create(['status' => 'pending']); $running = BulkOperationRun::factory()->create(['status' => 'running']); expect($pending->statusBucket())->toBe('queued') ->and($running->statusBucket())->toBe('running'); }); test('bulk operation statusBucket maps terminal outcomes using counts', function () { $succeeded = BulkOperationRun::factory()->create([ 'status' => 'completed', 'succeeded' => 3, 'failed' => 0, ]); $partial = BulkOperationRun::factory()->create([ 'status' => 'completed_with_errors', 'succeeded' => 2, 'failed' => 1, ]); $failedWithErrors = BulkOperationRun::factory()->create([ 'status' => 'completed_with_errors', 'succeeded' => 0, 'failed' => 4, ]); $failedAfterProgress = BulkOperationRun::factory()->create([ 'status' => 'failed', 'succeeded' => 1, 'failed' => 1, ]); $partialWithNonCountedFailures = BulkOperationRun::factory()->create([ 'status' => 'completed_with_errors', 'succeeded' => 1, 'failed' => 0, 'failures' => [ [ 'type' => 'foundation', 'item_id' => 'foundation', 'reason' => 'Forbidden', 'reason_code' => 'graph_forbidden', 'timestamp' => now()->toIso8601String(), ], ], ]); expect($succeeded->statusBucket())->toBe('succeeded') ->and($partial->statusBucket())->toBe('partially succeeded') ->and($failedWithErrors->statusBucket())->toBe('failed') ->and($failedAfterProgress->statusBucket())->toBe('partially succeeded') ->and($partialWithNonCountedFailures->statusBucket())->toBe('partially succeeded'); });