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>
55 lines
1.9 KiB
PHP
55 lines
1.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Events\FormBuilder;
|
|
|
|
use App\Events\FormBuilder\FormSubmissionIdentityMatchResolved;
|
|
use Illuminate\Broadcasting\PrivateChannel;
|
|
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Per RFC-WS-6 §Q1 v1.3 addition 2.
|
|
*
|
|
* Class-only tests — D2 wires the dispatch from
|
|
* TriggerPersonIdentityMatchOnFormSubmit::handle, and tests covering
|
|
* that wiring will live alongside the listener tests.
|
|
*/
|
|
final class FormSubmissionIdentityMatchResolvedTest extends TestCase
|
|
{
|
|
public function test_implements_should_broadcast(): void
|
|
{
|
|
$event = new FormSubmissionIdentityMatchResolved('01HX', 'matched', 1);
|
|
$this->assertInstanceOf(ShouldBroadcast::class, $event);
|
|
}
|
|
|
|
public function test_broadcasts_on_private_submission_channel(): void
|
|
{
|
|
$event = new FormSubmissionIdentityMatchResolved('01HX1234567890', 'matched', 2);
|
|
$channels = $event->broadcastOn();
|
|
|
|
$this->assertCount(1, $channels);
|
|
$this->assertInstanceOf(PrivateChannel::class, $channels[0]);
|
|
// PrivateChannel prepends 'private-' to the name passed to its
|
|
// constructor; that's the wire-format the frontend Echo client
|
|
// subscribes to.
|
|
$this->assertSame('private-submission.01HX1234567890', $channels[0]->name);
|
|
}
|
|
|
|
public function test_broadcast_as(): void
|
|
{
|
|
$event = new FormSubmissionIdentityMatchResolved('01HX', 'matched', 1);
|
|
$this->assertSame('identity-match.resolved', $event->broadcastAs());
|
|
}
|
|
|
|
public function test_constructor_assigns_payload_readonly(): void
|
|
{
|
|
$event = new FormSubmissionIdentityMatchResolved('01HX', 'no_match', 0);
|
|
|
|
$this->assertSame('01HX', $event->submissionId);
|
|
$this->assertSame('no_match', $event->status);
|
|
$this->assertSame(0, $event->matchCount);
|
|
}
|
|
}
|