import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { Command } from 'cmdk' import type { PropsWithChildren } from 'react' import { afterEach, describe, expect, it, vi } from 'vitest' import { CommandPaletteSearchInput } from './CommandPaletteSearchInput' const mockSetMode = vi.fn() const wrapper = (props: PropsWithChildren) => ( {props.children} ) afterEach(() => { vi.clearAllMocks() }) describe('in case input mode is "default"', () => { describe('when the user pressed > key', () => { it('should switch to "command" mode when value is empty', async () => { const user = userEvent.setup() render( , { wrapper }, ) await user.keyboard('>') expect(mockSetMode).toHaveBeenCalledWith({ type: 'command' }) }) it('should not switch input mode when value is not empty', async () => { const user = userEvent.setup() render( , { wrapper }, ) // make the input not empty await user.keyboard('hello') await user.keyboard('>') expect(mockSetMode).not.toHaveBeenCalled() }) }) describe('when the user pressed Tab key', () => { it('should switch to "table" mode and make the input empty when a table is suggested', async () => { const user = userEvent.setup() render( , { wrapper }, ) const input = screen.getByRole('combobox') // make the input not empty await user.keyboard('user') await user.keyboard('{Tab}') expect(mockSetMode).toHaveBeenCalledWith({ type: 'table', tableName: 'users', }) expect(input).toHaveValue('') }) it('should complete input value with suggested text but should not switch the input mode when suggestion is other than "table" option', async () => { const user = userEvent.setup() render( , { wrapper }, ) const input = screen.getByRole('combobox') await user.keyboard('{Tab}') expect(mockSetMode).not.toHaveBeenCalled() expect(input).toHaveValue('Copy Link') }) }) }) describe('in case input mode is "command"', () => { describe('when the user pressed Backspace key', () => { it('should switch to "default" mode when value is empty', async () => { const user = userEvent.setup() render( , { wrapper }, ) await user.keyboard('{backspace}') expect(mockSetMode).toHaveBeenCalledWith({ type: 'default' }) }) it('should not switch input mode when value is not empty', async () => { const user = userEvent.setup() render( , { wrapper }, ) // make the input not empty await user.keyboard('hello') await user.keyboard('{backspace}') expect(mockSetMode).not.toHaveBeenCalled() }) }) describe('when the user pressed Tab key', () => { it('should complete input value with suggested text', async () => { const user = userEvent.setup() render( , { wrapper }, ) const input = screen.getByRole('combobox') await user.keyboard('{Tab}') expect(mockSetMode).not.toHaveBeenCalled() expect(input).toHaveValue('Copy Link') }) }) }) describe('in case input mode is "table"', () => { describe('when the user pressed Backspace key', () => { it('should switch to "default" mode when value is empty', async () => { const user = userEvent.setup() render( , { wrapper }, ) await user.keyboard('{backspace}') expect(mockSetMode).toHaveBeenCalledWith({ type: 'default' }) }) it('should not switch input mode when value is not empty', async () => { const user = userEvent.setup() render( , { wrapper }, ) // make the input not empty await user.keyboard('hello') await user.keyboard('{backspace}') expect(mockSetMode).not.toHaveBeenCalled() }) }) describe('when the user pressed Tab key', () => { it('should complete input value with suggested text', async () => { const user = userEvent.setup() render( , { wrapper }, ) const input = screen.getByRole('combobox') await user.keyboard('{Tab}') expect(mockSetMode).not.toHaveBeenCalled() expect(input).toHaveValue('created_at') }) it('should not complete input value when a table is suggested', async () => { const user = userEvent.setup() render( , { wrapper }, ) const input = screen.getByRole('combobox') await user.keyboard('{Tab}') expect(mockSetMode).not.toHaveBeenCalled() expect(input).toHaveValue('') }) }) }) describe('displays a suggestion to complete the input', () => { it('displays the remaining text when the input matches the beginning of a suggestion', async () => { const user = userEvent.setup() render( , { wrapper }, ) await user.type(screen.getByRole('combobox'), 'user-s') expect( screen.getByTestId('command-palette-search-input-suggestion-suffix'), ).toHaveTextContent(/^ettings$/) }) it('display the whole text when the input does not match the beginning of a suggestion', async () => { const user = userEvent.setup() render( , { wrapper }, ) await user.type(screen.getByRole('combobox'), 'setting') expect( screen.getByTestId('command-palette-search-input-suggestion-suffix'), ).toHaveTextContent(/^- user-settings$/) }) })