mirror of
https://github.com/portainer/portainer.git
synced 2025-07-18 21:09:40 +02:00
116 lines
3.1 KiB
TypeScript
116 lines
3.1 KiB
TypeScript
|
import { render, screen } from '@testing-library/react';
|
||
|
import userEvent from '@testing-library/user-event';
|
||
|
|
||
|
import { CodeEditor } from './CodeEditor';
|
||
|
|
||
|
vi.mock('yaml-schema', () => ({}));
|
||
|
|
||
|
const defaultProps = {
|
||
|
id: 'test-editor',
|
||
|
onChange: vi.fn(),
|
||
|
value: '',
|
||
|
'data-cy': 'test-editor',
|
||
|
};
|
||
|
|
||
|
beforeEach(() => {
|
||
|
vi.clearAllMocks();
|
||
|
});
|
||
|
|
||
|
test('should render with basic props', () => {
|
||
|
render(<CodeEditor {...defaultProps} />);
|
||
|
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
||
|
});
|
||
|
|
||
|
test('should display placeholder when provided', async () => {
|
||
|
const placeholder = 'Enter your code here';
|
||
|
const { findByText } = render(
|
||
|
<CodeEditor {...defaultProps} placeholder={placeholder} />
|
||
|
);
|
||
|
|
||
|
const placeholderText = await findByText(placeholder);
|
||
|
expect(placeholderText).toBeVisible();
|
||
|
});
|
||
|
|
||
|
test('should show copy button and copy content', async () => {
|
||
|
const testValue = 'test content';
|
||
|
const { findByText } = render(
|
||
|
<CodeEditor {...defaultProps} value={testValue} />
|
||
|
);
|
||
|
|
||
|
const mockClipboard = {
|
||
|
writeText: vi.fn(),
|
||
|
};
|
||
|
Object.assign(navigator, {
|
||
|
clipboard: mockClipboard,
|
||
|
});
|
||
|
|
||
|
const copyButton = await findByText('Copy to clipboard');
|
||
|
expect(copyButton).toBeVisible();
|
||
|
|
||
|
await userEvent.click(copyButton);
|
||
|
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(testValue);
|
||
|
});
|
||
|
|
||
|
test('should handle read-only mode', async () => {
|
||
|
const { findByRole } = render(<CodeEditor {...defaultProps} readonly />);
|
||
|
const editor = await findByRole('textbox');
|
||
|
// the editor should not editable
|
||
|
await userEvent.type(editor, 'test');
|
||
|
expect(editor).not.toHaveValue('test');
|
||
|
});
|
||
|
|
||
|
test('should show version selector when versions are provided', async () => {
|
||
|
const versions = [1, 2, 3];
|
||
|
const onVersionChange = vi.fn();
|
||
|
const { findByRole } = render(
|
||
|
<CodeEditor
|
||
|
{...defaultProps}
|
||
|
versions={versions}
|
||
|
onVersionChange={onVersionChange}
|
||
|
/>
|
||
|
);
|
||
|
|
||
|
const selector = await findByRole('combobox');
|
||
|
expect(selector).toBeVisible();
|
||
|
});
|
||
|
|
||
|
test('should handle YAML indentation correctly', async () => {
|
||
|
const onChange = vi.fn();
|
||
|
const yamlContent = 'services:';
|
||
|
|
||
|
const { findByRole } = render(
|
||
|
<CodeEditor
|
||
|
{...defaultProps}
|
||
|
value={yamlContent}
|
||
|
onChange={onChange}
|
||
|
type="yaml"
|
||
|
/>
|
||
|
);
|
||
|
|
||
|
const editor = await findByRole('textbox');
|
||
|
await userEvent.type(editor, '{enter}');
|
||
|
await userEvent.keyboard('database:');
|
||
|
await userEvent.keyboard('{enter}');
|
||
|
await userEvent.keyboard('image: nginx');
|
||
|
await userEvent.keyboard('{enter}');
|
||
|
await userEvent.keyboard('name: database');
|
||
|
|
||
|
// Wait for the debounced onChange to be called
|
||
|
setTimeout(() => {
|
||
|
expect(onChange).toHaveBeenCalledWith(
|
||
|
'services:\n database:\n image: nginx\n name: database'
|
||
|
);
|
||
|
// debounce timeout is 300ms, so 500ms is enough
|
||
|
}, 500);
|
||
|
});
|
||
|
|
||
|
test('should apply custom height', async () => {
|
||
|
const customHeight = '300px';
|
||
|
const { findByRole } = render(
|
||
|
<CodeEditor {...defaultProps} height={customHeight} />
|
||
|
);
|
||
|
|
||
|
const editor = (await findByRole('textbox')).parentElement?.parentElement;
|
||
|
expect(editor).toHaveStyle({ height: customHeight });
|
||
|
});
|