create(); $role = Role::firstOrCreate(['slug' => 'admin'], ['name' => 'Admin']); $user->roles()->sync([$role->id]); $this->actingAs($user); // Build a simple DOCX containing nested tokens $tmp = tempnam(sys_get_temp_dir(), 'doc'); $zip = new \ZipArchive; $zip->open($tmp, \ZipArchive::OVERWRITE); $zip->addFromString('[Content_Types].xml', ''); $zip->addFromString('word/document.xml', '{{client.person.full_name}}|{{person.person_address.address}},{{person.person_address.post_code}} {{person.person_address.city}}'); $zip->close(); $bytes = file_get_contents($tmp); $upload = UploadedFile::fake()->createWithContent('nested.docx', $bytes); $resp = $this->post(route('admin.document-templates.store'), [ 'name' => 'Nested', 'slug' => 'nested', 'file' => $upload, ]); $resp->assertRedirect(); $template = DocumentTemplate::where('slug', 'nested')->orderByDesc('version')->firstOrFail(); // Create models $person = Person::factory()->create(['full_name' => 'Jane Doe']); $type = \App\Models\Person\AddressType::factory()->create(); PersonAddress::create([ 'person_id' => $person->id, 'address' => 'Main 1', 'post_code' => '1000', 'city' => 'Ljubljana', 'type_id' => $type->id, 'active' => 1, ]); $client = Client::factory()->create(['person_id' => $person->id]); $case = ClientCase::factory()->create(['client_id' => $client->id, 'person_id' => $person->id]); $contract = Contract::factory()->create(['client_case_id' => $case->id]); $gen = $this->postJson(route('contracts.generate-document', ['contract' => $contract->uuid]), [ 'template_slug' => 'nested', ]); $gen->assertOk()->assertJson(['status' => 'ok']); $doc = \App\Models\Document::latest('id')->first(); $this->assertTrue(Storage::disk('public')->exists($doc->path)); // Inspect XML $path = Storage::disk('public')->path($doc->path); $z = new \ZipArchive; $this->assertTrue($z->open($path) === true); $xml = $z->getFromName('word/document.xml'); $z->close(); $this->assertIsString($xml); $this->assertStringContainsString('Jane Doe', $xml); $this->assertStringContainsString('Main 1,1000 Ljubljana', $xml); } }