CluPilotCloud/tests/Feature/SiteDesignSystemTest.php

92 lines
3.7 KiB
PHP

<?php
use Illuminate\Support\Facades\File;
/**
* The public website is one of the three surfaces the token file describes.
*
* It was the last one still speaking the old language: a 900-line page with its
* own design system inside a <style> block — warm paper, a serif headline, 3px
* corners, its own scale of greys — written before the tokens existed. A
* visitor who clicked "Anmelden" left one company and arrived at another.
*
* These tests are about drift, not about looks. Nothing stops someone pasting a
* hex value into a marketing page at four in the afternoon; what stops it
* becoming a second design system is noticing on the first one.
*/
/** Public pages that must draw from the shared stylesheet. */
function sitePages(): array
{
return [
'landing.blade.php',
'legal.blade.php',
'components/layouts/site.blade.php',
];
}
it('builds the public site from the shared tokens, not from its own palette', function (string $page) {
$source = File::get(resource_path('views/'.$page));
// Hex literals are the tell. One is a paste; a dozen is a second design
// system growing quietly beside the first.
preg_match_all('/#[0-9a-fA-F]{3,8}\b/', $source, $found);
expect($found[0])->toBeEmpty()
// The old page set its own type stack. The token file owns that now,
// and a serif headline is precisely the impression the redesign
// removed — every page read as a document.
->and($source)->not->toContain('font-family')
->and($source)->not->toContain('Georgia')
->and($source)->not->toContain('font-serif');
})->with(sitePages());
it('serves the website from the same stylesheet as the portal', function () {
// Not "a stylesheet exists" — the SAME one. Two builds would drift the
// moment a token changed in one of them.
$layout = File::get(resource_path('views/components/layouts/site.blade.php'));
expect($layout)->toContain('<x-shell.head');
$head = File::get(resource_path('views/components/shell/head.blade.php'));
expect($head)->toContain("@vite(['resources/css/app.css'");
});
it('keeps the two deliberately self-contained pages self-contained', function () {
// The exceptions, named rather than forgotten. Both are shown when the
// application may not be able to serve a built stylesheet at all — mid
// deploy, or freshly installed — and @vite would throw where the whole
// point is to render something reassuring.
foreach (['coming-soon.blade.php', 'status.blade.php'] as $page) {
$source = File::get(resource_path('views/'.$page));
// The CALL, not the word: coming-soon.blade.php explains in a comment
// why it does not use @vite, and a plain substring match reads that
// explanation as the offence it warns about.
expect($source)->not->toMatch('/@vite\s*\(/')
->and($source)->toContain('<style>');
}
});
it('does not leave the old marketing stylesheet behind anywhere', function () {
// The tell of the previous edition: warm paper and the 3px radius. Left in
// a partial nobody opened, it would come back the next time somebody
// copied a section.
foreach (File::allFiles(resource_path('views')) as $file) {
if (in_array($file->getFilename(), ['coming-soon.blade.php', 'status.blade.php'], true)) {
continue;
}
// The mail layout is deliberately inline-styled: an email client has no
// stylesheet of ours to load.
if (str_contains($file->getPathname(), '/mail/') || str_contains($file->getPathname(), '/pdf/')) {
continue;
}
expect(File::get($file->getPathname()))
->not->toContain('--paper')
->not->toContain('Plex Serif');
}
});