actingAs($user); $backupSet = \App\Models\BackupSet::factory()->create([ 'tenant_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'queued', 'started_at' => null, 'completed_at' => null, ]); // Observer should create the adapter OperationRun row on create. $operationRun = OperationRun::query() ->where('tenant_id', $tenant->id) ->where('type', 'restore.execute') ->where('context->restore_run_id', $restoreRun->id) ->first(); expect($operationRun)->not->toBeNull(); expect($operationRun?->status)->toBe('queued'); // Simulate downstream code updating RestoreRun status via query builder (no model events). $this->mock(RestoreService::class, function ($mock) use ($restoreRun): void { $mock->shouldReceive('executeForRun') ->once() ->andReturnUsing(function () use ($restoreRun): RestoreRun { RestoreRun::query()->whereKey($restoreRun->id)->update([ 'status' => 'completed', 'completed_at' => now(), ]); return RestoreRun::query()->findOrFail($restoreRun->id); }); }); $job = new ExecuteRestoreRunJob($restoreRun->id); $job->handle( app(RestoreService::class), app(AuditLogger::class), ); $operationRun = $operationRun?->fresh(); expect($operationRun)->not->toBeNull(); expect($operationRun?->status)->toBe('completed'); expect($operationRun?->outcome)->toBe('succeeded'); expect($operationRun?->completed_at)->not->toBeNull(); })->group('ops-ux');