Browse Source

fix(ci): ruff format spoolbuddy.py; raise SettingsPage test timeout

  - backend/app/api/routes/spoolbuddy.py: re-formatted via ruff (lambda
    conditional wrapped in parens — the formatter check fires when the
    expression spans multiple lines without grouping)
  - frontend/src/__tests__/pages/SettingsPage.test.tsx: per-test timeout
    raised to 15s for the external_camera_snapshot_url PATCH test; the
    default 5s was tight enough on GitHub Actions runners that user.type()
    of the 49-char URL + 800ms debounce occasionally blew past it
maziggy 2 weeks ago
parent
commit
b4875fd5d6

+ 8 - 6
backend/app/api/routes/spoolbuddy.py

@@ -1362,13 +1362,15 @@ async def trigger_daemon_update(
     # Run the SSH update in the background — hold reference to prevent GC cancellation
     # Run the SSH update in the background — hold reference to prevent GC cancellation
     _ssh_update_task = asyncio.create_task(perform_ssh_update(device_id, device.ip_address))
     _ssh_update_task = asyncio.create_task(perform_ssh_update(device_id, device.ip_address))
     _ssh_update_task.add_done_callback(
     _ssh_update_task.add_done_callback(
-        lambda t: logger.error(
-            "SSH update task for device %s ended unexpectedly (cancelled=%s)",
-            device_id,
-            t.cancelled(),
+        lambda t: (
+            logger.error(
+                "SSH update task for device %s ended unexpectedly (cancelled=%s)",
+                device_id,
+                t.cancelled(),
+            )
+            if (t.cancelled() or t.exception() is not None)
+            else None
         )
         )
-        if (t.cancelled() or t.exception() is not None)
-        else None
     )
     )
 
 
     return {"status": "ok", "message": "SSH update started"}
     return {"status": "ok", "message": "SSH update started"}

+ 39 - 31
frontend/src/__tests__/pages/SettingsPage.test.tsx

@@ -776,36 +776,44 @@ describe('SettingsPage', () => {
       expect(screen.queryByPlaceholderText(/api\/frame\.jpeg\?src=printer/)).not.toBeInTheDocument();
       expect(screen.queryByPlaceholderText(/api\/frame\.jpeg\?src=printer/)).not.toBeInTheDocument();
     });
     });
 
 
-    it('PATCHes the printer with external_camera_snapshot_url when the user types into the input', async () => {
-      let receivedBody: Record<string, unknown> | null = null;
-      server.use(
-        http.get('/api/v1/printers/', () => HttpResponse.json([mjpegPrinter])),
-        http.patch('/api/v1/printers/7', async ({ request }) => {
-          receivedBody = (await request.json()) as Record<string, unknown>;
-          return HttpResponse.json({ ...mjpegPrinter, ...receivedBody });
-        }),
-      );
-
-      render(<SettingsPage />);
-
-      const input = await waitFor(() =>
-        screen.getByPlaceholderText(/api\/frame\.jpeg\?src=printer/),
-      );
-
-      const user = userEvent.setup();
-      await user.type(input, 'http://192.168.1.61:1984/api/frame.jpeg?src=printer');
-
-      // Save is debounced by 800ms; assert the PATCH eventually fires with
-      // the typed snapshot URL.
-      await waitFor(
-        () => {
-          expect(receivedBody).not.toBeNull();
-          expect(receivedBody!.external_camera_snapshot_url).toBe(
-            'http://192.168.1.61:1984/api/frame.jpeg?src=printer',
-          );
-        },
-        { timeout: 3000 },
-      );
-    });
+    it(
+      'PATCHes the printer with external_camera_snapshot_url when the user types into the input',
+      async () => {
+        let receivedBody: Record<string, unknown> | null = null;
+        server.use(
+          http.get('/api/v1/printers/', () => HttpResponse.json([mjpegPrinter])),
+          http.patch('/api/v1/printers/7', async ({ request }) => {
+            receivedBody = (await request.json()) as Record<string, unknown>;
+            return HttpResponse.json({ ...mjpegPrinter, ...receivedBody });
+          }),
+        );
+
+        render(<SettingsPage />);
+
+        const input = await waitFor(() =>
+          screen.getByPlaceholderText(/api\/frame\.jpeg\?src=printer/),
+        );
+
+        const user = userEvent.setup();
+        await user.type(input, 'http://192.168.1.61:1984/api/frame.jpeg?src=printer');
+
+        // Save is debounced by 800ms; assert the PATCH eventually fires with
+        // the typed snapshot URL.
+        await waitFor(
+          () => {
+            expect(receivedBody).not.toBeNull();
+            expect(receivedBody!.external_camera_snapshot_url).toBe(
+              'http://192.168.1.61:1984/api/frame.jpeg?src=printer',
+            );
+          },
+          { timeout: 5000 },
+        );
+      },
+      // Per-test timeout raised to 15s — `user.type()` of a 49-char URL plus
+      // the 800ms save debounce fits in 5s locally (~2.3s typical) but blows
+      // past it on slow GitHub Actions runners (5000ms timeout was the failure
+      // mode on PR #1263).
+      15_000,
+    );
   });
   });
 });
 });