Add sidebar tests
This commit is contained in:
278
client/src/components/__tests__/Sidebar.test.tsx
Normal file
278
client/src/components/__tests__/Sidebar.test.tsx
Normal file
@@ -0,0 +1,278 @@
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { describe, it, beforeEach, jest } from '@jest/globals';
|
||||
import Sidebar from '../Sidebar';
|
||||
|
||||
// Mock theme hook
|
||||
jest.mock('../../lib/useTheme', () => ({
|
||||
__esModule: true,
|
||||
default: () => ['light', jest.fn()],
|
||||
}));
|
||||
|
||||
describe('Sidebar Environment Variables', () => {
|
||||
const defaultProps = {
|
||||
connectionStatus: 'disconnected' as const,
|
||||
transportType: 'stdio' as const,
|
||||
setTransportType: jest.fn(),
|
||||
command: '',
|
||||
setCommand: jest.fn(),
|
||||
args: '',
|
||||
setArgs: jest.fn(),
|
||||
sseUrl: '',
|
||||
setSseUrl: jest.fn(),
|
||||
env: {},
|
||||
setEnv: jest.fn(),
|
||||
bearerToken: '',
|
||||
setBearerToken: jest.fn(),
|
||||
onConnect: jest.fn(),
|
||||
stdErrNotifications: [],
|
||||
logLevel: 'info' as const,
|
||||
sendLogLevelRequest: jest.fn(),
|
||||
loggingSupported: true,
|
||||
};
|
||||
|
||||
const renderSidebar = (props = {}) => {
|
||||
return render(<Sidebar {...defaultProps} {...props} />);
|
||||
};
|
||||
|
||||
const openEnvVarsSection = () => {
|
||||
const button = screen.getByText('Environment Variables');
|
||||
fireEvent.click(button);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('Basic Operations', () => {
|
||||
it('should add a new environment variable', () => {
|
||||
const setEnv = jest.fn();
|
||||
renderSidebar({ env: {}, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const addButton = screen.getByText('Add Environment Variable');
|
||||
fireEvent.click(addButton);
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({ '': '' });
|
||||
});
|
||||
|
||||
it('should remove an environment variable', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const removeButton = screen.getByRole('button', { name: '×' });
|
||||
fireEvent.click(removeButton);
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({});
|
||||
});
|
||||
|
||||
it('should update environment variable value', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const valueInput = screen.getByDisplayValue('test_value');
|
||||
fireEvent.change(valueInput, { target: { value: 'new_value' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({ TEST_KEY: 'new_value' });
|
||||
});
|
||||
|
||||
it('should toggle value visibility', () => {
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const valueInput = screen.getByDisplayValue('test_value');
|
||||
expect(valueInput).toHaveProperty('type', 'password');
|
||||
|
||||
const toggleButton = screen.getByRole('button', { name: /show value/i });
|
||||
fireEvent.click(toggleButton);
|
||||
|
||||
expect(valueInput).toHaveProperty('type', 'text');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Key Editing', () => {
|
||||
it('should maintain order when editing first key', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = {
|
||||
FIRST_KEY: 'first_value',
|
||||
SECOND_KEY: 'second_value',
|
||||
THIRD_KEY: 'third_value',
|
||||
};
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const firstKeyInput = screen.getByDisplayValue('FIRST_KEY');
|
||||
fireEvent.change(firstKeyInput, { target: { value: 'NEW_FIRST_KEY' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({
|
||||
NEW_FIRST_KEY: 'first_value',
|
||||
SECOND_KEY: 'second_value',
|
||||
THIRD_KEY: 'third_value',
|
||||
});
|
||||
});
|
||||
|
||||
it('should maintain order when editing middle key', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = {
|
||||
FIRST_KEY: 'first_value',
|
||||
SECOND_KEY: 'second_value',
|
||||
THIRD_KEY: 'third_value',
|
||||
};
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const middleKeyInput = screen.getByDisplayValue('SECOND_KEY');
|
||||
fireEvent.change(middleKeyInput, { target: { value: 'NEW_SECOND_KEY' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({
|
||||
FIRST_KEY: 'first_value',
|
||||
NEW_SECOND_KEY: 'second_value',
|
||||
THIRD_KEY: 'third_value',
|
||||
});
|
||||
});
|
||||
|
||||
it('should maintain order when editing last key', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = {
|
||||
FIRST_KEY: 'first_value',
|
||||
SECOND_KEY: 'second_value',
|
||||
THIRD_KEY: 'third_value',
|
||||
};
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const lastKeyInput = screen.getByDisplayValue('THIRD_KEY');
|
||||
fireEvent.change(lastKeyInput, { target: { value: 'NEW_THIRD_KEY' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({
|
||||
FIRST_KEY: 'first_value',
|
||||
SECOND_KEY: 'second_value',
|
||||
NEW_THIRD_KEY: 'third_value',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Multiple Operations', () => {
|
||||
it('should maintain state after multiple key edits', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = {
|
||||
FIRST_KEY: 'first_value',
|
||||
SECOND_KEY: 'second_value',
|
||||
};
|
||||
const { rerender } = renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
// First key edit
|
||||
const firstKeyInput = screen.getByDisplayValue('FIRST_KEY');
|
||||
fireEvent.change(firstKeyInput, { target: { value: 'NEW_FIRST_KEY' } });
|
||||
|
||||
// Get the updated env from the first setEnv call
|
||||
const updatedEnv = (setEnv.mock.calls[0][0] as Record<string, string>);
|
||||
|
||||
// Rerender with the updated env
|
||||
rerender(<Sidebar {...defaultProps} env={updatedEnv} setEnv={setEnv} />);
|
||||
|
||||
// Second key edit
|
||||
const secondKeyInput = screen.getByDisplayValue('SECOND_KEY');
|
||||
fireEvent.change(secondKeyInput, { target: { value: 'NEW_SECOND_KEY' } });
|
||||
|
||||
// Verify the final state matches what we expect
|
||||
expect(setEnv).toHaveBeenLastCalledWith({
|
||||
NEW_FIRST_KEY: 'first_value',
|
||||
NEW_SECOND_KEY: 'second_value',
|
||||
});
|
||||
});
|
||||
|
||||
it('should maintain visibility state after key edit', () => {
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
const { rerender } = renderSidebar({ env: initialEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
// Show the value
|
||||
const toggleButton = screen.getByRole('button', { name: /show value/i });
|
||||
fireEvent.click(toggleButton);
|
||||
|
||||
const valueInput = screen.getByDisplayValue('test_value');
|
||||
expect(valueInput).toHaveProperty('type', 'text');
|
||||
|
||||
// Edit the key
|
||||
const keyInput = screen.getByDisplayValue('TEST_KEY');
|
||||
fireEvent.change(keyInput, { target: { value: 'NEW_KEY' } });
|
||||
|
||||
// Rerender with updated env
|
||||
rerender(<Sidebar {...defaultProps} env={{ NEW_KEY: 'test_value' }} />);
|
||||
|
||||
// Value should still be visible
|
||||
const updatedValueInput = screen.getByDisplayValue('test_value');
|
||||
expect(updatedValueInput).toHaveProperty('type', 'text');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
it('should handle empty key', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const keyInput = screen.getByDisplayValue('TEST_KEY');
|
||||
fireEvent.change(keyInput, { target: { value: '' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({ '': 'test_value' });
|
||||
});
|
||||
|
||||
it('should handle special characters in key', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const keyInput = screen.getByDisplayValue('TEST_KEY');
|
||||
fireEvent.change(keyInput, { target: { value: 'TEST-KEY@123' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({ 'TEST-KEY@123': 'test_value' });
|
||||
});
|
||||
|
||||
it('should handle unicode characters', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const keyInput = screen.getByDisplayValue('TEST_KEY');
|
||||
fireEvent.change(keyInput, { target: { value: 'TEST_🔑' } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({ 'TEST_🔑': 'test_value' });
|
||||
});
|
||||
|
||||
it('should handle very long key names', () => {
|
||||
const setEnv = jest.fn();
|
||||
const initialEnv = { TEST_KEY: 'test_value' };
|
||||
renderSidebar({ env: initialEnv, setEnv });
|
||||
|
||||
openEnvVarsSection();
|
||||
|
||||
const keyInput = screen.getByDisplayValue('TEST_KEY');
|
||||
const longKey = 'A'.repeat(100);
|
||||
fireEvent.change(keyInput, { target: { value: longKey } });
|
||||
|
||||
expect(setEnv).toHaveBeenCalledWith({ [longKey]: 'test_value' });
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user