- Changed error message styling in ICalImportModal to use new color classes. - Updated task completion styling in TaskListView to use new success color classes. - Modified selected styling in ContactListItem tests to reflect new background class. - Adjusted duplicate warning styling in ContactImportDialog to use new warning color classes. - Refactored background and border colors in CalendarInvitationBanner for various statuses. - Updated email list item and viewer components to use new warning and success color classes. - Refined styling for unread indicators in email components. - Enhanced error fallback styling in error components to use new warning color classes. - Updated filter rule modal button hover styles to use new destructive color classes. - Added experimental feature descriptions in Plugins and Themes settings. - Refined vacation settings validation warning styling to use new warning color classes. - Updated toast component styles to use new color classes for different states. - Introduced a new built-in theme 'Qui' with specific color variables. - Adjusted email security status colors to use new warning color classes.
86 lines
3.1 KiB
TypeScript
86 lines
3.1 KiB
TypeScript
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
import { ContactListItem } from '../contact-list-item';
|
|
import type { ContactCard } from '@/lib/jmap/types';
|
|
|
|
const contact: ContactCard = {
|
|
id: '1',
|
|
addressBookIds: {},
|
|
name: { components: [{ kind: 'given', value: 'Alice' }, { kind: 'surname', value: 'Smith' }], isOrdered: true },
|
|
emails: { e0: { address: 'alice@example.com' } },
|
|
organizations: { o0: { name: 'Acme Corp' } },
|
|
};
|
|
|
|
const noNameContact: ContactCard = {
|
|
id: '2',
|
|
addressBookIds: {},
|
|
emails: { e0: { address: 'nobody@example.com' } },
|
|
};
|
|
|
|
const _emptyContact: ContactCard = {
|
|
id: '3',
|
|
addressBookIds: {},
|
|
};
|
|
|
|
describe('ContactListItem', () => {
|
|
const baseProps = {
|
|
isSelected: false,
|
|
isChecked: false,
|
|
hasSelection: false,
|
|
density: 'regular' as const,
|
|
onClick: vi.fn(),
|
|
onCheckboxClick: vi.fn(),
|
|
selectedContactIds: new Set<string>(),
|
|
};
|
|
|
|
it('renders contact name and email', () => {
|
|
render(<ContactListItem contact={contact} {...baseProps} />);
|
|
expect(screen.getByText('Alice Smith')).toBeInTheDocument();
|
|
expect(screen.getByText('alice@example.com')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders organization in comfortable density', () => {
|
|
render(<ContactListItem contact={contact} {...baseProps} density="comfortable" />);
|
|
expect(screen.getByText('Acme Corp')).toBeInTheDocument();
|
|
});
|
|
|
|
it('hides organization in regular density', () => {
|
|
render(<ContactListItem contact={contact} {...baseProps} density="regular" />);
|
|
expect(screen.queryByText('Acme Corp')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('applies selected styling', () => {
|
|
const { container } = render(<ContactListItem contact={contact} {...baseProps} isSelected={true} />);
|
|
const div = container.firstElementChild;
|
|
expect(div?.className).toContain('bg-selection');
|
|
});
|
|
|
|
it('shows email as display name when no name exists', () => {
|
|
render(<ContactListItem contact={noNameContact} {...baseProps} />);
|
|
const matches = screen.getAllByText('nobody@example.com');
|
|
expect(matches.length).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it('calls onClick when clicked', () => {
|
|
const onClick = vi.fn();
|
|
render(<ContactListItem contact={contact} {...baseProps} onClick={onClick} />);
|
|
fireEvent.click(screen.getByText('Alice Smith'));
|
|
expect(onClick).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it('does not show checkbox when hasSelection is false', () => {
|
|
const { container } = render(<ContactListItem contact={contact} {...baseProps} hasSelection={false} />);
|
|
expect(container.querySelector('button')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('shows checkbox when hasSelection is true', () => {
|
|
const { container } = render(<ContactListItem contact={contact} {...baseProps} hasSelection={true} />);
|
|
expect(container.querySelector('button')).toBeInTheDocument();
|
|
});
|
|
|
|
it('hides avatar in extra-compact density', () => {
|
|
const { container } = render(<ContactListItem contact={contact} {...baseProps} density="extra-compact" />);
|
|
expect(container.querySelector('[data-testid="avatar"]') || container.querySelector('.rounded-full')).toBeNull();
|
|
});
|
|
});
|