87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { BoxUserCard } from '../../src/components/machine/box-user-card';
|
|
|
|
const { mockUseQuery, fetchSpy } = vi.hoisted(() => ({
|
|
mockUseQuery: vi.fn(),
|
|
fetchSpy: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('convex/react', () => ({
|
|
useQuery: mockUseQuery,
|
|
}));
|
|
|
|
vi.mock('sonner', () => ({
|
|
toast: { error: vi.fn(), success: vi.fn() },
|
|
}));
|
|
|
|
describe('BoxUserCard', () => {
|
|
beforeEach(() => {
|
|
vi.stubGlobal('fetch', fetchSpy);
|
|
fetchSpy.mockResolvedValue(
|
|
new Response(JSON.stringify({ hasPassword: true, applied: true })),
|
|
);
|
|
});
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.unstubAllGlobals();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('shows the identity line and not-set state', () => {
|
|
mockUseQuery.mockReturnValue({ hasPassword: false });
|
|
render(<BoxUserCard username='Gabriel' />);
|
|
expect(screen.getByText('gabriel@gabriel-box')).toBeInTheDocument();
|
|
expect(screen.getByText('Not set')).toBeInTheDocument();
|
|
expect(screen.getByText('Set password')).toBeInTheDocument();
|
|
expect(screen.queryByText('Remove password')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('offers change/remove when a password is set', () => {
|
|
mockUseQuery.mockReturnValue({ hasPassword: true });
|
|
render(<BoxUserCard username='gabriel' />);
|
|
expect(screen.getByText('Set')).toBeInTheDocument();
|
|
expect(screen.getByText('Change password')).toBeInTheDocument();
|
|
expect(screen.getByText('Remove password')).toBeInTheDocument();
|
|
});
|
|
|
|
it('blocks submit on mismatched confirmation', () => {
|
|
mockUseQuery.mockReturnValue({ hasPassword: false });
|
|
render(<BoxUserCard username='gabriel' />);
|
|
fireEvent.change(screen.getByLabelText('New password'), {
|
|
target: { value: 'longenough' },
|
|
});
|
|
fireEvent.change(screen.getByLabelText('Confirm'), {
|
|
target: { value: 'different1' },
|
|
});
|
|
expect(screen.getByText('Passwords do not match.')).toBeInTheDocument();
|
|
expect(screen.getByText('Set password').closest('button')!.disabled).toBe(
|
|
true,
|
|
);
|
|
expect(fetchSpy).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('posts the password and shows the restart note when not applied live', async () => {
|
|
mockUseQuery.mockReturnValue({ hasPassword: false });
|
|
fetchSpy.mockResolvedValue(
|
|
new Response(JSON.stringify({ hasPassword: true, applied: false })),
|
|
);
|
|
render(<BoxUserCard username='gabriel' />);
|
|
fireEvent.change(screen.getByLabelText('New password'), {
|
|
target: { value: 'longenough' },
|
|
});
|
|
fireEvent.change(screen.getByLabelText('Confirm'), {
|
|
target: { value: 'longenough' },
|
|
});
|
|
fireEvent.click(screen.getByText('Set password'));
|
|
expect(
|
|
await screen.findByText(/takes effect the next time it starts/),
|
|
).toBeInTheDocument();
|
|
expect(fetchSpy).toHaveBeenCalledWith(
|
|
'/api/box/set-password',
|
|
expect.objectContaining({ method: 'POST' }),
|
|
);
|
|
});
|
|
});
|