root = "{$base}/platform"; $this->public = "{$base}/public"; File::makeDirectory($this->public, 0755, true); $this->originalPublic = public_path(); $this->app->usePublicPath($this->public); config(['app.platform_path' => $this->root]); } protected function tearDown(): void { $this->app->usePublicPath($this->originalPublic); File::deleteDirectory(dirname($this->root)); parent::tearDown(); } private function putFile(string $path, string $content): void { File::ensureDirectoryExists(dirname("{$this->root}/{$path}")); File::put("{$this->root}/{$path}", $content); } /** Load the folder as the app does at start, and drop what was already cached. */ private function loadPlatform(): void { $provider = new PlatformServiceProvider($this->app); $provider->register(); $provider->boot(); $this->app['translator']->setLoaded([]); View::getFinder()->flush(); $this->app->forgetInstance(Markdown::class); } public function test_without_a_folder_nothing_changes(): void { $name = config('app.timebank_config'); $before = [config($name), config('themes'), config('mail.markdown.paths'), __('Search'), View::getFinder()->getPaths()]; $this->loadPlatform(); $this->assertSame($before, [config($name), config('themes'), config('mail.markdown.paths'), __('Search'), View::getFinder()->getPaths()]); $this->assertSame(asset('favicon.ico'), theme_favicon('favicon.ico')); $this->assertSame(asset('storage/' . theme_email_logo()), theme_email_logo_url()); } public function test_its_config_is_the_platform_config(): void { $this->putFile('config.php', " 'from the folder', 'local_pages' => []];\n"); $this->loadPlatform(); $this->assertSame('from the folder', timebank_config('platform_folder_marker')); $this->assertNull(timebank_config('footer'), 'the folder replaces config/.php, it does not merge with it'); } public function test_its_theme_becomes_the_active_theme(): void { $this->putFile('theme.php', " 'acme', 'name' => 'Acme', 'colors' => ['brand' => '#123456']];\n"); $this->loadPlatform(); $this->assertSame('acme', theme_id()); $this->assertSame('Acme', theme_name()); $this->assertSame('#123456', theme_color('brand')); $this->assertStringContainsString('--color-brand: 18 52 86;', theme_css_vars()); } public function test_translations_are_overridden_key_by_key(): void { app()->setLocale('en'); $base = json_decode(File::get(lang_path('en.json')), true); [$changed, $kept] = array_slice(array_keys($base), 10, 2); $baseWirechat = trans('wirechat::chat.labels.you'); $this->putFile('lang/en.json', json_encode([$changed => 'Changed by the platform', 'Only on this platform' => 'Platform text'])); $this->putFile('lang/en/messages.php', " 'Group text'];\n"); $this->putFile('lang/vendor/wirechat/en/chat.php', " ['you' => 'Me']];\n"); $this->loadPlatform(); $this->assertSame('Changed by the platform', __($changed)); $this->assertSame($base[$kept], __($kept), 'keys the platform does not override keep their text'); $this->assertSame('Platform text', __('Only on this platform')); $this->assertSame('Group text', __('messages.platform_folder_marker')); $this->assertNotSame('messages.platform_folder_marker', __('messages.' . array_key_first(require lang_path('en/messages.php'))), 'the rest of the group stays'); $this->assertSame('Me', trans('wirechat::chat.labels.you')); $this->assertNotSame($baseWirechat, 'Me'); $this->assertSame(trans('wirechat::chat.labels.attachment'), 'Attachment', 'the rest of the package group stays'); } public function test_templates_are_overridden_as_whole_files(): void { $this->putFile('views/logos/timebank_cc.blade.php', 'PLATFORM LOGO'); $this->putFile('views/vendor/wirechat/components/divider.blade.php', 'PLATFORM DIVIDER'); $this->putFile('views/mail/html/panel.blade.php', '
PLATFORM PANEL {{ $slot }}
'); $this->putFile('views/platform-test-markdown.blade.php', "\nHello\n\n"); $this->loadPlatform(); $this->assertSame('PLATFORM LOGO', trim(view('logos.timebank_cc')->render())); $this->assertSame("{$this->root}/views/vendor/wirechat/components/divider.blade.php", View::getFinder()->find('wirechat::components.divider')); $this->assertStringContainsString('PLATFORM PANEL', (string) app(Markdown::class)->render('platform-test-markdown')); $this->assertStringContainsString('resources/views/emails', View::getFinder()->find('emails.layouts.html'), 'templates the platform does not override come from the code'); } public function test_public_files_are_served_from_the_folder_once_linked(): void { $this->putFile('public/favicon.ico', 'icon'); $this->putFile('public/mail-logo.png', 'logo'); $this->loadPlatform(); $this->assertSame(asset('favicon.ico'), theme_favicon('favicon.ico'), 'not served before the link exists'); $this->artisan('platform:link')->assertExitCode(0); $this->assertSame("{$this->root}/public", readlink("{$this->public}/platform")); $this->assertSame(asset('platform/favicon.ico'), theme_favicon('favicon.ico')); $this->assertSame(asset('favicon-32x32.png'), theme_favicon('favicon-32x32.png'), 'a file the platform lacks comes from the code'); $this->assertSame(asset('platform/mail-logo.png'), theme_email_logo_url()); $this->assertSame("{$this->public}/platform/mail-logo.png", theme_email_logo_file()); $this->assertSame(asset('storage/' . theme_email_logo(true)), theme_email_logo_url(true), 'no inverted logo in the folder'); } public function test_platform_link_is_idempotent_and_never_replaces_a_real_folder(): void { $this->artisan('platform:link')->expectsOutputToContain('nothing to link')->assertExitCode(0); $this->assertFalse(file_exists("{$this->public}/platform")); $this->putFile('public/favicon.ico', 'icon'); $this->artisan('platform:link')->assertExitCode(0); $this->artisan('platform:link')->expectsOutputToContain('already links')->assertExitCode(0); File::deleteDirectory("{$this->root}/public"); $this->artisan('platform:link')->expectsOutputToContain('Removed')->assertExitCode(0); $this->assertFalse(is_link("{$this->public}/platform")); File::makeDirectory("{$this->public}/platform"); $this->putFile('public/favicon.ico', 'icon'); $this->artisan('platform:link')->expectsOutputToContain('not a link')->assertExitCode(1); $this->assertTrue(is_dir("{$this->public}/platform") && !is_link("{$this->public}/platform")); } }