refactor(form-builder): drop legacy snapshot 'binding' (singular) key (WS-6)
Session 2 wrote both 'binding' (singular) and 'bindings' (plural) in form_submissions.schema_snapshot for backward compatibility. With no production data yet and dev seeders re-running every cycle, dual- key state has no upside. Snapshots now write 'bindings' only; all readers updated to match. FormFieldBindingService::snapshotShapesFor() simplified to return only ['bindings' => $all]. Pre-existing SchemaSnapshotEmbedsBindingFromRelationalTableTest updated to assert the applicator shape (with id, merge_strategy, trust_level, is_identity_key) on bindings[0]; new SnapshotOnlyContainsBindingsKeyTest enforces the no-legacy-key contract going forward. FormBuilderDevSeeder template snapshot embeds 'bindings' => [] for form-owned fields (Pattern B) instead of 'binding' => null. Other 'binding' string occurrences in the codebase (FormFieldResource, FormFieldService, request validation rules, BindingConflictResolver internal helper key) are unrelated to snapshot dual-state and remain untouched. Refs: WS-6 session 2 deviation #9 cleanup Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\FormBuilder\Schema;
|
||||
|
||||
use App\Enums\FormBuilder\FormFieldType;
|
||||
use App\Enums\FormBuilder\FormPurpose;
|
||||
use App\Enums\FormBuilder\FormSchemaSnapshotMode;
|
||||
use App\Models\FormBuilder\FormField;
|
||||
use App\Models\FormBuilder\FormFieldBinding;
|
||||
use App\Models\FormBuilder\FormSchema;
|
||||
use App\Models\FormBuilder\FormSubmission;
|
||||
use App\Models\Organisation;
|
||||
use App\Models\User;
|
||||
use App\Services\FormBuilder\FormSubmissionService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* RFC-WS-6 v1.1 / session 2.5 — schema_snapshot.fields[*] carries
|
||||
* `bindings` (plural) only. The legacy `binding` (singular) key was
|
||||
* dropped — no production data; dual-key state had no upside.
|
||||
*/
|
||||
final class SnapshotOnlyContainsBindingsKeyTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_snapshot_field_entries_have_bindings_plural_only(): void
|
||||
{
|
||||
$organisation = Organisation::factory()->create();
|
||||
$schema = FormSchema::factory()->create([
|
||||
'organisation_id' => $organisation->id,
|
||||
'purpose' => FormPurpose::USER_PROFILE->value,
|
||||
'snapshot_mode' => FormSchemaSnapshotMode::ALWAYS->value,
|
||||
]);
|
||||
|
||||
// Two fields: one with binding, one without (Pattern B).
|
||||
$boundField = FormField::factory()->create([
|
||||
'form_schema_id' => $schema->id,
|
||||
'field_type' => FormFieldType::EMAIL->value,
|
||||
'slug' => 'email',
|
||||
]);
|
||||
FormFieldBinding::factory()->forField($boundField)->entityOwned('user', 'email')->create();
|
||||
|
||||
FormField::factory()->create([
|
||||
'form_schema_id' => $schema->id,
|
||||
'field_type' => FormFieldType::TEXT->value,
|
||||
'slug' => 'note',
|
||||
]);
|
||||
|
||||
$user = User::factory()->create();
|
||||
$service = $this->app->make(FormSubmissionService::class);
|
||||
$draft = $service->createDraft($schema, $user, $user);
|
||||
/** @var FormSubmission $submitted */
|
||||
$submitted = $service->submit($draft, $user);
|
||||
|
||||
$snapshot = $submitted->fresh()->schema_snapshot;
|
||||
$this->assertIsArray($snapshot);
|
||||
|
||||
foreach ($snapshot['fields'] as $entry) {
|
||||
$this->assertArrayHasKey('bindings', $entry);
|
||||
$this->assertIsArray($entry['bindings']);
|
||||
$this->assertArrayNotHasKey(
|
||||
'binding',
|
||||
$entry,
|
||||
'Snapshot field entries must NOT contain the legacy `binding` (singular) key.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user