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>
60 lines
1.9 KiB
PHP
60 lines
1.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\FormBuilder\Schema;
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* Migration rehearsal for WS-6 v1.3-delta D1:
|
|
* - 2026_05_08_000001_add_failure_response_code_to_form_submissions
|
|
*
|
|
* Verifies the column + index land per RFC-WS-6 §Q3 v1.3 addition 2 and
|
|
* ARCH-BINDINGS §7.1 v1.2.
|
|
*/
|
|
final class Ws6V13DeltaD1MigrationTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_form_submissions_has_failure_response_code_column(): void
|
|
{
|
|
$this->assertTrue(Schema::hasColumn('form_submissions', 'failure_response_code'));
|
|
}
|
|
|
|
public function test_failure_response_code_is_nullable_string_40(): void
|
|
{
|
|
$row = DB::selectOne(
|
|
'SELECT DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, COLUMN_DEFAULT
|
|
FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
AND TABLE_NAME = ?
|
|
AND COLUMN_NAME = ?',
|
|
['form_submissions', 'failure_response_code'],
|
|
);
|
|
|
|
$this->assertNotNull($row, 'failure_response_code column missing');
|
|
$this->assertSame('varchar', strtolower((string) $row->DATA_TYPE));
|
|
$this->assertSame(40, (int) $row->CHARACTER_MAXIMUM_LENGTH);
|
|
$this->assertSame('YES', $row->IS_NULLABLE);
|
|
$this->assertNull($row->COLUMN_DEFAULT);
|
|
}
|
|
|
|
public function test_failure_response_code_index_present(): void
|
|
{
|
|
$row = DB::selectOne(
|
|
'SELECT INDEX_NAME
|
|
FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
AND TABLE_NAME = ?
|
|
AND INDEX_NAME = ?',
|
|
['form_submissions', 'fs_failure_response_code_idx'],
|
|
);
|
|
|
|
$this->assertNotNull($row, 'fs_failure_response_code_idx missing');
|
|
}
|
|
}
|