create(); $schema = FormSchema::factory()->create([ 'organisation_id' => $org->id, 'purpose' => FormPurpose::ARTIST_ADVANCE->value, ]); $submission = FormSubmission::factory()->create([ 'form_schema_id' => $schema->id, 'subject_type' => null, 'subject_id' => null, ]); $submission->schema_snapshot = ['fields' => []]; $submission->save(); try { DB::transaction(fn () => resolve(FormBindingApplicator::class)->apply($submission->fresh())); $this->fail('Expected PurposeSubjectResolutionException'); } catch (PurposeSubjectResolutionException $e) { $this->assertSame('artist_advance', $e->purposeSlug); $this->assertSame('no_portal_token', $e->reasonCode); } } /* * test_subject_claims_artist_but_record_gone — REMOVED until BACKLOG * ARCH-09 lands the Artist model. Hitting subject_type='artist' would * reach the resolver's `$submission->subject` morph access, which * Laravel's HasRelationships::newRelatedInstance instantiates as * `new App\Models\Artist`. The class doesn't exist yet (only the * morph alias is registered as a string), so the test crashes with * "Class not found" before reaching the subject_not_found branch. * * Once the Artist model + factory land, this case becomes testable: * just create an Artist subject row, link the submission to it, and * proceed with happy-path + conflict resolution patterns. The other * five purposes here exercise the full pattern; artist_advance is * limited to the no_portal_token branch above. */ }