2f88e883b2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
105 lines
4.1 KiB
TypeScript
105 lines
4.1 KiB
TypeScript
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
import { AccountsList } from './AccountsList';
|
|
|
|
const mockAccounts = [
|
|
{ id: 'acc_1', jid: '111@s.whatsapp.net', displayName: 'Account One', status: 'ACTIVE', platform: 'whatsapp' },
|
|
{ id: 'acc_2', jid: '222@s.whatsapp.net', displayName: null, status: 'DISCONNECTED', platform: 'whatsapp' },
|
|
];
|
|
|
|
let fetchSpy: jest.SpyInstance;
|
|
|
|
beforeEach(() => {
|
|
fetchSpy = jest.spyOn(global, 'fetch');
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
describe('AccountsList', () => {
|
|
it('renders an AccountCard for each initial account', () => {
|
|
render(<AccountsList initialAccounts={mockAccounts} />);
|
|
expect(screen.getByText('Account One')).toBeInTheDocument();
|
|
expect(screen.getByText('222@s.whatsapp.net')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows empty state when no accounts', () => {
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
expect(screen.getByText(/no accounts yet/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders Add Account button', () => {
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
expect(screen.getByRole('button', { name: /add account/i })).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders display name input', () => {
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
expect(screen.getByPlaceholderText(/display name/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it('calls POST /api/accounts when Add Account is clicked', async () => {
|
|
fetchSpy.mockResolvedValue(
|
|
new Response(
|
|
JSON.stringify({ id: 'acc_new', jid: 'pending_x@placeholder', displayName: null, status: 'ACTIVE', platform: 'whatsapp' }),
|
|
{ status: 201, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
);
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
fireEvent.click(screen.getByRole('button', { name: /add account/i }));
|
|
await waitFor(() =>
|
|
expect(fetchSpy).toHaveBeenCalledWith('/api/accounts', expect.objectContaining({ method: 'POST' })),
|
|
);
|
|
});
|
|
|
|
it('adds new account to list after successful POST', async () => {
|
|
const newAccount = { id: 'acc_new', jid: 'pending_x@placeholder', displayName: 'New Device', status: 'ACTIVE', platform: 'whatsapp' };
|
|
fetchSpy.mockResolvedValue(
|
|
new Response(JSON.stringify(newAccount), {
|
|
status: 201,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
}),
|
|
);
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
const input = screen.getByPlaceholderText(/display name/i);
|
|
fireEvent.change(input, { target: { value: 'New Device' } });
|
|
fireEvent.click(screen.getByRole('button', { name: /add account/i }));
|
|
await waitFor(() => expect(screen.getByText('New Device')).toBeInTheDocument());
|
|
});
|
|
|
|
it('sends displayName in POST body when entered', async () => {
|
|
fetchSpy.mockResolvedValue(
|
|
new Response(
|
|
JSON.stringify({ id: 'acc_new', jid: 'pending_x@placeholder', displayName: 'Test Name', status: 'ACTIVE', platform: 'whatsapp' }),
|
|
{ status: 201, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
);
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
const input = screen.getByPlaceholderText(/display name/i);
|
|
fireEvent.change(input, { target: { value: 'Test Name' } });
|
|
fireEvent.click(screen.getByRole('button', { name: /add account/i }));
|
|
await waitFor(() =>
|
|
expect(fetchSpy).toHaveBeenCalledWith(
|
|
'/api/accounts',
|
|
expect.objectContaining({
|
|
body: JSON.stringify({ displayName: 'Test Name' }),
|
|
}),
|
|
),
|
|
);
|
|
});
|
|
|
|
it('clears the input after successful account creation', async () => {
|
|
fetchSpy.mockResolvedValue(
|
|
new Response(
|
|
JSON.stringify({ id: 'acc_new', jid: 'pending_x@placeholder', displayName: null, status: 'ACTIVE', platform: 'whatsapp' }),
|
|
{ status: 201, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
);
|
|
render(<AccountsList initialAccounts={[]} />);
|
|
const input = screen.getByPlaceholderText(/display name/i) as HTMLInputElement;
|
|
fireEvent.change(input, { target: { value: 'My Device' } });
|
|
fireEvent.click(screen.getByRole('button', { name: /add account/i }));
|
|
await waitFor(() => expect(input.value).toBe(''));
|
|
});
|
|
});
|