169 lines
7.8 KiB
PHP
169 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Providers\PlatformServiceProvider;
|
|
use Illuminate\Mail\Markdown;
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Facades\View;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* The platform folder (platform_path(), outside git) holds everything that makes an installation one platform.
|
|
* Every part is optional; without it the installation runs from the code as before. Each test builds its own
|
|
* folder, and a public/ of its own, so the real platform/ and public/platform are never touched.
|
|
*/
|
|
class PlatformFolderTest extends TestCase
|
|
{
|
|
private string $root;
|
|
private string $public;
|
|
private string $originalPublic;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$base = sys_get_temp_dir() . '/platform-folder-test-' . uniqid();
|
|
$this->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', "<?php\n\nreturn ['platform_folder_marker' => '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/<name>.php, it does not merge with it');
|
|
}
|
|
|
|
public function test_its_theme_becomes_the_active_theme(): void
|
|
{
|
|
$this->putFile('theme.php', "<?php\n\nreturn ['id' => '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', "<?php\n\nreturn ['platform_folder_marker' => 'Group text'];\n");
|
|
$this->putFile('lang/vendor/wirechat/en/chat.php', "<?php\n\nreturn ['labels' => ['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', '<div>PLATFORM PANEL {{ $slot }}</div>');
|
|
$this->putFile('views/platform-test-markdown.blade.php', "<x-mail::panel>\nHello\n</x-mail::panel>\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"));
|
|
}
|
|
}
|