create(); $this->assertNotEmpty($failure->id); $this->assertSame(0, $failure->retry_count); $this->assertNull($failure->resolved_at); $this->assertNull($failure->dismissed_at); $this->assertNotEmpty($failure->context); } public function test_submission_relation_returns_parent(): void { $submission = FormSubmission::factory()->create(); $failure = FormSubmissionActionFailure::factory() ->for($submission, 'submission') ->create(); $this->assertSame($submission->id, $failure->submission->id); } public function test_binding_relation_is_nullable(): void { $failure = FormSubmissionActionFailure::factory()->create(); $this->assertNull($failure->binding); } public function test_open_scope_excludes_resolved_and_dismissed(): void { FormSubmissionActionFailure::factory()->create(); FormSubmissionActionFailure::factory()->resolved()->create(); FormSubmissionActionFailure::factory()->dismissed()->create(); $this->assertSame(1, FormSubmissionActionFailure::query()->open()->count()); $this->assertSame(1, FormSubmissionActionFailure::query()->resolved()->count()); $this->assertSame(1, FormSubmissionActionFailure::query()->dismissed()->count()); } public function test_dismissed_reason_type_round_trips_as_enum(): void { $failure = FormSubmissionActionFailure::factory()->create([ 'dismissed_reason_type' => DismissalReasonType::DATA_QUALITY_ISSUE, 'dismissed_at' => now(), ]); $reloaded = FormSubmissionActionFailure::query()->find($failure->id); $this->assertSame(DismissalReasonType::DATA_QUALITY_ISSUE, $reloaded->dismissed_reason_type); } public function test_context_round_trips_as_array(): void { $failure = FormSubmissionActionFailure::factory()->create([ 'context' => ['target_entity' => 'company', 'target_attribute' => 'kvk_number'], ]); $reloaded = FormSubmissionActionFailure::query()->find($failure->id); $this->assertSame('company', $reloaded->context['target_entity']); } public function test_can_be_retried_only_for_open_state(): void { // Sessie 3c (Q2 closure): both resolved AND dismissed block retry. // Open is the only retriable state. $open = FormSubmissionActionFailure::factory()->create(); $resolved = FormSubmissionActionFailure::factory()->resolved()->create(); $dismissed = FormSubmissionActionFailure::factory()->dismissed()->create(); $this->assertTrue($open->canBeRetried()); $this->assertFalse($resolved->canBeRetried()); $this->assertFalse($dismissed->canBeRetried()); } public function test_table_has_no_organisation_id_column_per_rfc_v3(): void { $this->assertFalse( Schema::hasColumn('form_submission_action_failures', 'organisation_id'), 'Tenant scope must flow via FK chain to form_submissions.organisation_id (RFC V3)', ); } }