import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import type { MouseEventHandler, ReactElement, ReactNode } from 'react' import { describe, expect, it, vi } from 'vitest' import { LocalDropdown } from './LocalDropdown' const { mockRouter, mockSetTheme, mockSetLastRoute, mockToggleFeaturePreviewModal } = vi.hoisted( () => ({ mockRouter: { pathname: '/project/[ref]/editor', asPath: '/project/default/editor', }, mockSetTheme: vi.fn(), mockSetLastRoute: vi.fn(), mockToggleFeaturePreviewModal: vi.fn(), }) ) vi.mock('next/router', () => ({ useRouter: () => mockRouter, })) vi.mock('next/link', () => ({ default: ({ href, children, onClick, }: { href: string children: ReactNode onClick?: MouseEventHandler }) => ( {children} ), })) vi.mock('next-themes', () => ({ useTheme: () => ({ theme: 'dark', setTheme: mockSetTheme, }), })) vi.mock('@/state/app-state', () => ({ useAppStateSnapshot: () => ({ setLastRouteBeforeVisitingAccountPage: mockSetLastRoute, }), })) vi.mock('@/components/ui/ProfileImage', () => ({ ProfileImage: () =>
Avatar
, })) vi.mock('./App/FeaturePreview/FeaturePreviewContext', () => ({ useFeaturePreviewModal: () => ({ toggleFeaturePreviewModal: mockToggleFeaturePreviewModal, }), })) vi.mock('@/lib/telemetry/track', () => ({ useTrack: () => vi.fn() })) vi.mock('ui', async () => { const React = await import('react') return { Button: ({ children, ...props }: React.ButtonHTMLAttributes & { children?: ReactNode }) => ( ), cn: (...classes: Array) => classes.filter(Boolean).join(' '), DropdownMenu: ({ children }: { children: ReactNode }) =>
{children}
, DropdownMenuTrigger: ({ children }: { children: ReactNode }) =>
{children}
, DropdownMenuContent: ({ children }: { children: ReactNode }) =>
{children}
, DropdownMenuGroup: ({ children }: { children: ReactNode }) =>
{children}
, DropdownMenuItem: ({ children, asChild, onClick, onSelect, }: { children: ReactNode asChild?: boolean onClick?: () => void onSelect?: () => void }) => asChild ? (
{children}
) : ( ), DropdownMenuLabel: ({ children }: { children: ReactNode }) =>
{children}
, DropdownMenuSeparator: () =>
, DropdownMenuRadioGroup: ({ children, onValueChange, }: { children: ReactNode onValueChange: (value: string) => void }) => (
{React.Children.map(children, (child: ReactNode) => React.isValidElement<{ value: string; onClick?: () => void }>(child) ? React.cloneElement(child, { onClick: () => onValueChange(child.props.value), }) : (child as ReactElement) )}
), DropdownMenuRadioItem: ({ children, onClick, }: { children: ReactNode onClick?: () => void }) => , Tooltip: ({ children }: { children: ReactNode }) =>
{children}
, TooltipContent: ({ children }: { children: ReactNode }) =>
{children}
, TooltipTrigger: ({ children }: { children: ReactNode }) =>
{children}
, singleThemes: [ { value: 'dark', name: 'Dark' }, { value: 'light', name: 'Light' }, ], } }) describe('LocalDropdown', () => { it('shows Preferences, removes Command menu, and keeps theme controls wired', async () => { const user = userEvent.setup() render() expect(screen.getByText('Preferences')).toBeInTheDocument() expect(screen.queryByText('Command menu')).not.toBeInTheDocument() expect(screen.getByText('Theme')).toBeInTheDocument() await user.click(screen.getByText('Preferences')) expect(mockSetLastRoute).toHaveBeenCalledWith('/project/default/editor') await user.click(screen.getByText('Feature previews')) expect(mockToggleFeaturePreviewModal).toHaveBeenCalledWith(true) await user.click(screen.getByText('Light')) expect(mockSetTheme).toHaveBeenCalledWith('light') }) })