|
|
@@ -719,7 +719,7 @@ describe('QueuePage', () => {
|
|
|
});
|
|
|
|
|
|
describe('stored mapping on the live printer (#3132)', () => {
|
|
|
- const mappedItem = (amsMapping: number[]) => ({
|
|
|
+ const mappedItem = (amsMapping: number[], extra: Record<string, unknown> = {}) => ({
|
|
|
...mockQueueItems[0],
|
|
|
id: 88,
|
|
|
printer_id: 1,
|
|
|
@@ -739,11 +739,16 @@ describe('QueuePage', () => {
|
|
|
force_color_match: false,
|
|
|
},
|
|
|
],
|
|
|
+ ...extra,
|
|
|
});
|
|
|
|
|
|
- const useMappedPrinter = (amsMapping: number[], status: Record<string, unknown>) => {
|
|
|
+ const useMappedPrinter = (
|
|
|
+ amsMapping: number[],
|
|
|
+ status: Record<string, unknown>,
|
|
|
+ item: Record<string, unknown> = {},
|
|
|
+ ) => {
|
|
|
server.use(
|
|
|
- http.get('/api/v1/queue/', () => HttpResponse.json([mappedItem(amsMapping)])),
|
|
|
+ http.get('/api/v1/queue/', () => HttpResponse.json([mappedItem(amsMapping, item)])),
|
|
|
http.get('/api/v1/library/files/19/plates', () =>
|
|
|
HttpResponse.json({
|
|
|
file_id: 19,
|
|
|
@@ -827,6 +832,74 @@ describe('QueuePage', () => {
|
|
|
expect(within(row).getByTestId('filament-swatch')).toHaveAttribute('title', '#8E351B');
|
|
|
});
|
|
|
|
|
|
+ describe('AMS Filament Backup during the print', () => {
|
|
|
+ const printing = { status: 'printing', started_at: '2024-01-01T10:00:00Z' };
|
|
|
+
|
|
|
+ it('shows the backup spool the printer switched to', async () => {
|
|
|
+ // A3 ran out at layer 350 and the printer carried on from A2.
|
|
|
+ useMappedPrinter(
|
|
|
+ [2],
|
|
|
+ { connected: true, state: 'RUNNING', ams: amsWithEmptyA3, vt_tray: [], tray_change_log: [[2, 0], [1, 350]] },
|
|
|
+ printing,
|
|
|
+ );
|
|
|
+ const row = await mappedRow();
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(within(row).getByText(/^A2 · PLA · /)).toBeInTheDocument();
|
|
|
+ });
|
|
|
+ expect(within(row).queryByText(/Empty/)).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('follows a backup that ran out in turn', async () => {
|
|
|
+ useMappedPrinter(
|
|
|
+ [2],
|
|
|
+ {
|
|
|
+ connected: true,
|
|
|
+ state: 'RUNNING',
|
|
|
+ ams: amsWithEmptyA3,
|
|
|
+ vt_tray: [],
|
|
|
+ tray_change_log: [[2, 0], [1, 120], [0, 400]],
|
|
|
+ },
|
|
|
+ printing,
|
|
|
+ );
|
|
|
+ const row = await mappedRow();
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(within(row).getByText(/^A1 · PLA · /)).toBeInTheDocument();
|
|
|
+ });
|
|
|
+ expect(within(row).queryByText(/^A2 · /)).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('does not take a change to another mapped slot for a backup', async () => {
|
|
|
+ // Slot 2 of the job feeds from A2: switching there is a colour change.
|
|
|
+ useMappedPrinter(
|
|
|
+ [2, 1],
|
|
|
+ { connected: true, state: 'RUNNING', ams: amsWithEmptyA3, vt_tray: [], tray_change_log: [[2, 0], [1, 30]] },
|
|
|
+ printing,
|
|
|
+ );
|
|
|
+ const row = await mappedRow();
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(within(row).getByText('A3 · Empty · Caramel')).toBeInTheDocument();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('leaves a queued job pointed at its mapped slot', async () => {
|
|
|
+ // The log belongs to whatever the printer prints now, not this job.
|
|
|
+ useMappedPrinter([2], {
|
|
|
+ connected: true,
|
|
|
+ ams: amsWithEmptyA3,
|
|
|
+ vt_tray: [],
|
|
|
+ tray_change_log: [[2, 0], [1, 350]],
|
|
|
+ });
|
|
|
+ const row = await mappedRow();
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(within(row).getByText('A3 · Empty · Caramel')).toBeInTheDocument();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
it('never calls the external spool empty, having no presence signal', async () => {
|
|
|
// Shape the status route really sends: an external tray carries no
|
|
|
// state / exists, so an unconfigured spool and no spool look the same.
|