/**
* Render tests for the AMS Filament Backup modal (#1762).
*
* Modal now renders one SVG ring per backup pair (BambuStudio Auto Refill
* style); lone slots are intentionally suppressed.
*/
import { describe, it, expect, vi } from 'vitest';
import { screen, fireEvent } from '@testing-library/react';
import { render } from '../utils';
import { AmsBackupModal } from '../../components/AmsBackupModal';
function makeAmsUnits() {
return [
{
id: 0,
tray: [
{ id: 0, tray_type: 'PLA', tray_sub_brands: 'PLA Basic', tray_color: '#000000', tray_info_idx: 'GFA00' },
{ id: 1, tray_type: 'PETG', tray_sub_brands: 'PETG HF', tray_color: '#0000FF', tray_info_idx: 'GFG99' },
],
},
{
id: 1,
tray: [
{ id: 0, tray_type: 'PLA', tray_sub_brands: 'PLA Basic', tray_color: '#000000', tray_info_idx: 'GFA00' },
],
},
];
}
describe('AmsBackupModal', () => {
it('returns null when isOpen=false', () => {
const { container } = render(
,
);
expect(container.querySelector('[data-testid="ams-backup-modal"]')).toBeNull();
});
it('renders a backup ring for each pair and OMITS lone slots', async () => {
render(
,
);
// PLA Basic — pair: rendered in centre of its ring
expect(await screen.findByText('PLA Basic')).toBeInTheDocument();
// PETG HF — lone, must NOT appear (no longer listed)
expect(screen.queryByText('PETG HF')).not.toBeInTheDocument();
});
it('closes on Escape keypress while open', async () => {
const onClose = vi.fn();
render(
,
);
fireEvent.keyDown(window, { key: 'Escape' });
expect(onClose).toHaveBeenCalledTimes(1);
});
it('does NOT fire onClose on Escape when closed (listener unmounts)', () => {
const onClose = vi.fn();
const { rerender } = render(
,
);
rerender(
,
);
fireEvent.keyDown(window, { key: 'Escape' });
expect(onClose).not.toHaveBeenCalled();
});
it('toggle reflects the ON state and fires onToggle(false) when clicked', async () => {
const onToggle = vi.fn();
render(
,
);
const toggle = await screen.findByRole('switch');
expect(toggle).toHaveAttribute('aria-checked', 'true');
fireEvent.click(toggle);
expect(onToggle).toHaveBeenCalledWith(false);
});
it('toggle is disabled when state is unknown (A1 family)', async () => {
render(
,
);
const toggle = await screen.findByRole('switch');
expect(toggle).toBeDisabled();
expect(screen.getByText(/Unsupported/i)).toBeInTheDocument();
});
it('toggle is disabled when the user lacks printers:control', async () => {
render(
,
);
const toggle = await screen.findByRole('switch');
expect(toggle).toBeDisabled();
});
it('shows a no-pairs empty state when AMS has no backup pair', async () => {
render(
,
);
expect(await screen.findByText(/No backup pairs/i)).toBeInTheDocument();
});
it('on dual-extruder with distinct map values, renders R / L badges on each ring', async () => {
render(
,
);
// Both rings should be present (PLA Basic and PETG HF in the centres).
expect(await screen.findByText('PLA Basic')).toBeInTheDocument();
expect(screen.getByText('PETG HF')).toBeInTheDocument();
// Both extruder badges visible.
expect(screen.getByText('R')).toBeInTheDocument();
expect(screen.getByText('L')).toBeInTheDocument();
});
it('collapses to single section (no R/L badges) when isDualNozzle=true but map has one distinct value', async () => {
render(
,
);
expect(screen.queryByText('R')).not.toBeInTheDocument();
expect(screen.queryByText('L')).not.toBeInTheDocument();
});
});