Files
SealShare/tests/Feature/AppToolbarTest.php
T
Andreas Reinhold / reiniandClaude Opus 5 accbc17c1c Move the navigation into a floating toolbar at the bottom
The top app bar repeated the site's name, which already heads the upload
and download pages, and spread its actions to the window's far edge. A
floating toolbar centred above the bottom edge, as wide as its buttons,
now holds them: Upload and the admin pages with the current one filled,
and the account menu; guests get Upload, the theme toggle and Log in,
without tooltips. On a phone the sign-in card no longer stretches to the
full height, and the admin dashboard's empty state sits outside the
scrolling table.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 11:12:12 +02:00

59 lines
2.4 KiB
PHP

<?php
use App\Models\User;
/**
* The page's main navigation, the floating toolbar at the bottom.
*/
function toolbar(string $html): string
{
preg_match('/<nav aria-label="Main">.*?<\/nav>/s', $html, $matches);
return $matches[0] ?? '';
}
/**
* The opening tag of the toolbar's link to a URL.
*/
function toolbarLink(string $html, string $url): string
{
preg_match('/<a\s[^>]*href="'.preg_quote($url, '/').'"[^>]*>/', toolbar($html), $matches);
return $matches[0] ?? '';
}
test('pages have a floating toolbar at the bottom instead of a top app bar', function () {
$html = $this->get(route('upload'))->assertOk()->getContent();
expect($html)->not->toContain('data-app-bar')
->and(toolbar($html))->toContain('role="toolbar"')->toContain('data-toolbar-place="bottom"');
});
test('a guest gets the upload page, the theme toggle and a way to log in, without tooltips', function () {
$html = $this->get(route('upload'))->getContent();
expect(toolbarLink($html, route('upload')))->toContain('aria-current="page"')->toContain('aria-label="Upload"')
->and(toolbarLink($html, route('login')))->not->toBe('')
->and(toolbar($html))->toContain('Log in')->toContain('data-theme-toggle')->not->toContain('popover')->not->toContain('data-account-menu');
expect(toolbar($this->get(route('login'))->getContent()))->not->toContain(route('login').'"');
});
test('an admin gets the admin pages and the account menu, the current page marked', function () {
$admin = User::query()->where('is_admin', true)->first();
$html = $this->actingAs($admin)->get(route('admin.dashboard'))->assertOk()->getContent();
expect(toolbarLink($html, route('admin.dashboard')))->toContain('aria-current="page"')
->and(toolbarLink($html, route('upload')))->not->toContain('aria-current')
->and(toolbarLink($html, route('admin.settings')))->not->toContain('aria-current')
->and(toolbar($html))->toContain('data-account-menu')->toContain('data-test="logout-button"')->not->toContain('Log in');
});
test('a user who is not an admin gets no admin pages', function () {
$html = $this->actingAs(User::factory()->create(['is_admin' => false]))->get(route('profile.edit'))->assertOk()->getContent();
expect(toolbarLink($html, route('upload')))->not->toBe('')
->and(toolbar($html))->not->toContain(route('admin.dashboard'))->not->toContain(route('admin.settings'));
});