create(); $backupSet = BackupSet::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'policy_identifier' => 'policy-fetch-dedupe', 'metadata' => [], ]); Bus::fake(); $firstRun = FetchAssignmentsJob::dispatchTracked( backupItem: $backupItem, policyPayload: ['id' => 'policy-fetch-dedupe'], ); $secondRun = FetchAssignmentsJob::dispatchTracked( backupItem: $backupItem, policyPayload: ['id' => 'policy-fetch-dedupe'], ); expect((int) $firstRun->getKey())->toBe((int) $secondRun->getKey()); Bus::assertDispatched(FetchAssignmentsJob::class, 1); $assignmentBackupService = \Mockery::mock(AssignmentBackupService::class); $assignmentBackupService->shouldReceive('enrichWithAssignments') ->once() ->andReturnUsing(function (BackupItem $item): BackupItem { $metadata = is_array($item->metadata) ? $item->metadata : []; $metadata['assignments_fetch_failed'] = false; $item->update([ 'metadata' => $metadata, 'assignments' => [['id' => 'assignment-fetch-1']], ]); return $item->refresh(); }); $firstJob = new FetchAssignmentsJob( backupItemId: (int) $backupItem->getKey(), tenantExternalId: (string) $tenant->external_id, policyExternalId: (string) $backupItem->policy_identifier, policyPayload: ['id' => 'policy-fetch-dedupe'], operationRun: $firstRun, ); $duplicateJob = new FetchAssignmentsJob( backupItemId: (int) $backupItem->getKey(), tenantExternalId: (string) $tenant->external_id, policyExternalId: (string) $backupItem->policy_identifier, policyPayload: ['id' => 'policy-fetch-dedupe'], operationRun: $firstRun, ); $firstJob->handle($assignmentBackupService, app(OperationRunService::class)); $duplicateJob->handle($assignmentBackupService, app(OperationRunService::class)); Bus::fake(); $cooldownRun = FetchAssignmentsJob::dispatchTracked( backupItem: $backupItem, policyPayload: ['id' => 'policy-fetch-dedupe'], ); expect((int) $cooldownRun->getKey())->toBe((int) $firstRun->getKey()); Bus::assertNotDispatched(FetchAssignmentsJob::class); }); test('restore assignment job dedupes dispatch and execution, and reuses recent completion during cooldown', function (): void { $tenant = Tenant::factory()->create(); $backupSet = BackupSet::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), ]); $assignments = [ ['id' => 'assignment-1'], ['id' => 'assignment-2'], ]; Bus::fake(); $firstRun = RestoreAssignmentsJob::dispatchTracked( restoreRunId: (int) $restoreRun->getKey(), tenant: $tenant, policyType: 'settingsCatalogPolicy', policyId: 'policy-restore-dedupe', assignments: $assignments, groupMapping: [], ); $secondRun = RestoreAssignmentsJob::dispatchTracked( restoreRunId: (int) $restoreRun->getKey(), tenant: $tenant, policyType: 'settingsCatalogPolicy', policyId: 'policy-restore-dedupe', assignments: $assignments, groupMapping: [], ); expect((int) $firstRun->getKey())->toBe((int) $secondRun->getKey()); Bus::assertDispatched(RestoreAssignmentsJob::class, 1); $assignmentRestoreService = \Mockery::mock(AssignmentRestoreService::class); $assignmentRestoreService->shouldReceive('restore') ->once() ->andReturn([ 'outcomes' => [ ['status' => 'success'], ['status' => 'success'], ], 'summary' => [ 'success' => 2, 'failed' => 0, 'skipped' => 0, ], ]); $firstJob = new RestoreAssignmentsJob( restoreRunId: (int) $restoreRun->getKey(), tenantId: (int) $tenant->getKey(), policyType: 'settingsCatalogPolicy', policyId: 'policy-restore-dedupe', assignments: $assignments, groupMapping: [], foundationMapping: [], operationRun: $firstRun, ); $duplicateJob = new RestoreAssignmentsJob( restoreRunId: (int) $restoreRun->getKey(), tenantId: (int) $tenant->getKey(), policyType: 'settingsCatalogPolicy', policyId: 'policy-restore-dedupe', assignments: $assignments, groupMapping: [], foundationMapping: [], operationRun: $firstRun, ); $firstJob->handle($assignmentRestoreService, app(OperationRunService::class)); $duplicateJob->handle($assignmentRestoreService, app(OperationRunService::class)); Bus::fake(); $cooldownRun = RestoreAssignmentsJob::dispatchTracked( restoreRunId: (int) $restoreRun->getKey(), tenant: $tenant, policyType: 'settingsCatalogPolicy', policyId: 'policy-restore-dedupe', assignments: $assignments, groupMapping: [], ); expect((int) $cooldownRun->getKey())->toBe((int) $firstRun->getKey()); Bus::assertNotDispatched(RestoreAssignmentsJob::class); });