0]); $this->team = Team::factory()->create(); $this->user = User::factory()->create(); }); function renderNavbarAt(string $path, bool $mobile = false): string { app()->instance('request', Request::create($path)); return (string) test()->blade($mobile ? '' : ''); } function loginNavbarUser(string $role): void { test()->team->members()->attach(test()->user->id, ['role' => $role]); test()->actingAs(test()->user); session(['currentTeam' => test()->team]); } test('a submenu page opens its submenu with the current page active', function () { loginNavbarUser('owner'); $html = renderNavbarAt('/metrics'); expect($html) ->toContain('Back to the main menu') ->toMatch('#aria-current="page"[^>]*>\s*]*>.*?\s*]*>Metrics#s'); }); test('a page outside every submenu starts on the main menu', function () { loginNavbarUser('owner'); expect(renderNavbarAt('/servers'))->not->toContain('data-active-submenu="'); }); test('a submenu entry links to its first visible page', function () { loginNavbarUser('owner'); expect(renderNavbarAt('/servers'))->toContain('href="'.route('analytics').'"'); }); test('the registries page is hidden from members in the integrations submenu', function () { loginNavbarUser('member'); expect(renderNavbarAt('/sources')) ->toContain('Destinations') ->not->toContain('href="'.route('registries.index').'"'); }); test('the team submenu lists the team pages by role', function () { loginNavbarUser('owner'); expect(renderNavbarAt('/team/members')) ->toContain('href="'.route('team.member.index').'"') ->toContain('href="'.route('team.audit-log').'"') ->toContain('href="'.route('team.danger-zone').'"'); }); test('members do not see the audit log or danger zone in the team submenu', function () { loginNavbarUser('member'); expect(renderNavbarAt('/team')) ->toContain('href="'.route('team.member.index').'"') ->not->toContain('href="'.route('team.audit-log').'"') ->not->toContain('href="'.route('team.danger-zone').'"'); }); test('notifications and keys & tokens open their own submenus', function () { loginNavbarUser('owner'); expect(renderNavbarAt('/notifications/discord')) ->toContain('href="'.route('notifications.slack').'"') ->toMatch('#aria-current="page"[^>]*>.*?discord\.svg#s'); expect(renderNavbarAt('/security/api-tokens')) ->toContain('href="'.route('security.private-key.index').'"') ->toContain('Back to the main menu'); }); test('the admin link belongs to the main menu, not to submenus', function () { config()->set('app.env', 'local'); $root = User::factory()->create(['id' => 0]); test()->team->members()->attach($root->id, ['role' => 'owner']); test()->actingAs($root); session(['currentTeam' => test()->team]); expect(renderNavbarAt('/team')) ->toMatch('#]*>\s*toContain('Back to the main menu') ->toContain('href="'.route('shared-variables.team.index').'"') ->toMatch('#aria-current="page"[^>]*>\s*]*>.*?\s*]*>Servers#s'); }); test('instance settings open their own submenu for instance admins', function () { config()->set('app.env', 'local'); $root = User::factory()->create(['id' => 0]); test()->team->members()->attach($root->id, ['role' => 'owner']); test()->actingAs($root); session(['currentTeam' => test()->team]); expect(renderNavbarAt('/settings/email')) ->toContain('Back to the main menu') ->toContain('href="'.route('settings.oauth').'"') ->toMatch('#aria-current="page"[^>]*>\s*]*>.*?\s*]*>Email#s'); }); test('a parent entry opens its submenu in place on mobile and desktop', function () { loginNavbarUser('owner'); foreach ([renderNavbarAt('/servers', mobile: true), renderNavbarAt('/servers')] as $html) { expect($html) ->toContain('x-show="submenu === \'Monitoring\'"') ->toMatch('#