test(form-builder): WS-6 v1.3-delta D1 tests

32 new tests covering D1 deliverables:

- Migration shape (3): failure_response_code column presence,
  type/length/nullability, index name. MySQL information_schema
  introspection.
- Exception hierarchy (11): abstract base, RuntimeException ancestor,
  per-subclass constructor + reasonCode (named-args asserting
  submissionId is preserved structurally), Timeout extends Infra and
  inherits temporary_error, all subclasses extend base, previous-throwable
  chaining works, IdentityMatchInvariantViolation is NOT in the
  binding-applicator hierarchy and IS a DomainException.
- FormBindingExceptionClassifier matrix (6): each subclass maps to its
  reason code; Timeout dispatches to inherited 'temporary_error';
  arbitrary RuntimeException -> 'unknown_error'; IdentityMatchInvariantViolation
  -> 'unknown_error' (intentional fallback per docstring).
- FormFieldBindingMergeStrategy::validForTargetType (4 tests covering
  the full 4 strategies x 3 target types matrix).
- FormSubmissionIdentityMatchResolved (4): ShouldBroadcast contract,
  private channel naming ('private-submission.{id}'), broadcast-as
  string, payload assignment.
- FormSubmission failure_response_code cast (4): persists as plain
  string, NULL by default, factory state composes with apply_status,
  round-trips for all four canonical codes.

Baseline regenerated to absorb new tautological-assertion entries (48
lines) — these are class-hierarchy regression guards that Larastan
correctly flags as statically known. The pattern is established in the
codebase per existing baseline entries for similar tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-08 02:09:48 +02:00
parent 01c5ff207a
commit c29ad75ecc
7 changed files with 484 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Enums\FormBuilder;
use App\Enums\FormBuilder\BindingTargetType;
use App\Enums\FormBuilder\FormFieldBindingMergeStrategy;
use PHPUnit\Framework\TestCase;
/**
* Per RFC-WS-6 §V1 + ARCH-BINDINGS §4.2.
*
* Locks the strategy x target-type validity matrix. Append is the only
* non-trivial case (collection-only). Future contributors who alter the
* matrix without RFC follow-through will see a structural test failure.
*/
final class FormFieldBindingMergeStrategyValidForTargetTypeTest extends TestCase
{
public function test_overwrite_valid_for_all_target_types(): void
{
$this->assertTrue(FormFieldBindingMergeStrategy::Overwrite->validForTargetType(BindingTargetType::SCALAR));
$this->assertTrue(FormFieldBindingMergeStrategy::Overwrite->validForTargetType(BindingTargetType::COLLECTION));
$this->assertTrue(FormFieldBindingMergeStrategy::Overwrite->validForTargetType(BindingTargetType::RELATION));
}
public function test_replace_valid_for_all_target_types(): void
{
$this->assertTrue(FormFieldBindingMergeStrategy::Replace->validForTargetType(BindingTargetType::SCALAR));
$this->assertTrue(FormFieldBindingMergeStrategy::Replace->validForTargetType(BindingTargetType::COLLECTION));
$this->assertTrue(FormFieldBindingMergeStrategy::Replace->validForTargetType(BindingTargetType::RELATION));
}
public function test_first_write_wins_valid_for_all_target_types(): void
{
$this->assertTrue(FormFieldBindingMergeStrategy::FirstWriteWins->validForTargetType(BindingTargetType::SCALAR));
$this->assertTrue(FormFieldBindingMergeStrategy::FirstWriteWins->validForTargetType(BindingTargetType::COLLECTION));
$this->assertTrue(FormFieldBindingMergeStrategy::FirstWriteWins->validForTargetType(BindingTargetType::RELATION));
}
public function test_append_valid_only_for_collection(): void
{
$this->assertFalse(FormFieldBindingMergeStrategy::Append->validForTargetType(BindingTargetType::SCALAR));
$this->assertTrue(FormFieldBindingMergeStrategy::Append->validForTargetType(BindingTargetType::COLLECTION));
$this->assertFalse(FormFieldBindingMergeStrategy::Append->validForTargetType(BindingTargetType::RELATION));
}
}