root = "{$base}/platform"; $this->public = "{$base}/public"; File::makeDirectory("{$this->root}/public", 0755, true); File::makeDirectory($this->public, 0755, true); $this->originalPublic = public_path(); $this->app->usePublicPath($this->public); config(['app.platform_path' => $this->root]); // The layouts' @vite would look for the build manifest in the temporary public/ $this->withoutVite(); } protected function tearDown(): void { View::flushSections(); $this->app->usePublicPath($this->originalPublic); File::deleteDirectory(dirname($this->root)); parent::tearDown(); } private function renderHead(): string { return view('layouts.guest', ['slot' => new HtmlString('')])->render(); } public function test_open_graph_tags_use_property_and_the_title_is_escaped_once(): void { View::startSection('title', 'Terms & conditions'); $html = $this->renderHead(); $this->assertStringContainsString('Terms & conditions - ' . e(config('app.name')) . '', $html); $this->assertStringContainsString('', $html); $this->assertStringContainsString('assertStringContainsString('', $html); $this->assertStringNotContainsString('&', $html); $this->assertStringNotContainsString('name="og:', $html); $this->assertStringNotContainsString('og:image', $html, 'no preview image without a file'); } public function test_the_preview_image_comes_from_the_platform_folder_then_the_theme(): void { File::put("{$this->public}/theme-preview.png", 'png'); config(['themes.themes.' . theme_id() . '.logos.og_image' => 'theme-preview.png']); $this->assertStringContainsString('', $this->renderHead()); File::put("{$this->root}/public/og-image.png", 'png'); $this->artisan('platform:link')->assertExitCode(0); $html = $this->renderHead(); $this->assertStringContainsString('', $html); $this->assertStringContainsString('', $html); } public function test_optional_icons_are_linked_only_when_present(): void { $html = $this->renderHead(); $this->assertStringNotContainsString('favicon.svg', $html); $this->assertStringNotContainsString('rel="manifest"', $html); $this->assertStringContainsString('favicon-32x32.png', $html, 'the standard icons are always linked'); File::put("{$this->root}/public/favicon.svg", ''); File::put("{$this->root}/public/site.webmanifest", '{}'); File::put("{$this->public}/favicon-96x96.png", 'png'); $this->artisan('platform:link')->assertExitCode(0); $html = $this->renderHead(); $this->assertStringContainsString('', $html); $this->assertStringContainsString('', $html); $this->assertStringContainsString('', $html); } /** * Uuro's branch added onQueue('high') to this notification (2025-12-15), which is not a queued notification: * every admin or bank password reset then failed with "Call to undefined method ...::onQueue()". */ public function test_the_admin_and_bank_password_reset_mail_can_be_built(): void { $notification = new NonUserPasswordResetNotification('https://example.test/reset/abc', new Admin(['name' => 'admin-test'])); $this->assertStringContainsString('https://example.test/reset/abc', (string) $notification->toMail(new Admin(['name' => 'admin-test']))->render()); } }