| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- 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<HTMLAnchorElement>
- }) => (
- <a href={href} onClick={onClick}>
- {children}
- </a>
- ),
- }))
- vi.mock('next-themes', () => ({
- useTheme: () => ({
- theme: 'dark',
- setTheme: mockSetTheme,
- }),
- }))
- vi.mock('@/state/app-state', () => ({
- useAppStateSnapshot: () => ({
- setLastRouteBeforeVisitingAccountPage: mockSetLastRoute,
- }),
- }))
- vi.mock('@/components/ui/ProfileImage', () => ({
- ProfileImage: () => <div>Avatar</div>,
- }))
- 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<HTMLButtonElement> & { children?: ReactNode }) => (
- <button {...props}>{children}</button>
- ),
- cn: (...classes: Array<string | false | null | undefined>) => classes.filter(Boolean).join(' '),
- DropdownMenu: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- DropdownMenuTrigger: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- DropdownMenuContent: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- DropdownMenuGroup: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- DropdownMenuItem: ({
- children,
- asChild,
- onClick,
- onSelect,
- }: {
- children: ReactNode
- asChild?: boolean
- onClick?: () => void
- onSelect?: () => void
- }) =>
- asChild ? (
- <div>{children}</div>
- ) : (
- <button
- onClick={() => {
- onClick?.()
- onSelect?.()
- }}
- >
- {children}
- </button>
- ),
- DropdownMenuLabel: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- DropdownMenuSeparator: () => <hr />,
- DropdownMenuRadioGroup: ({
- children,
- onValueChange,
- }: {
- children: ReactNode
- onValueChange: (value: string) => void
- }) => (
- <div>
- {React.Children.map(children, (child: ReactNode) =>
- React.isValidElement<{ value: string; onClick?: () => void }>(child)
- ? React.cloneElement(child, {
- onClick: () => onValueChange(child.props.value),
- })
- : (child as ReactElement)
- )}
- </div>
- ),
- DropdownMenuRadioItem: ({
- children,
- onClick,
- }: {
- children: ReactNode
- onClick?: () => void
- }) => <button onClick={onClick}>{children}</button>,
- Tooltip: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- TooltipContent: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- TooltipTrigger: ({ children }: { children: ReactNode }) => <div>{children}</div>,
- 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(<LocalDropdown />)
- 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')
- })
- })
|