test: the gate's output carries no noise to hide a real warning in
- Home tests mocked the api without downloadIndex, so every card's download button logged a missing-queryFn error (64 stderr blocks per run). - QueryState rendered without an i18n instance; Modal.fullscreen awaited a synchronous act, which React reports as an act environment it does not support. - pytest: Starlette 1.x's TestClient is built on httpx2 and warned on every run without it (pinned in requirements-dev); alembic.ini declares its path separator.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
[alembic]
|
||||
script_location = alembic
|
||||
prepend_sys_path = .
|
||||
# Split the path list the way the OS does (alembic's legacy space/comma/colon split is deprecated).
|
||||
path_separator = os
|
||||
|
||||
[loggers]
|
||||
keys = root,sqlalchemy,alembic
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Test + lint tooling — NEVER in the prod image. Installed only by backend/Dockerfile.test (the
|
||||
# throwaway test image), which the prod build (root Dockerfile) never references. Pinned so the
|
||||
# suite is reproducible: pytest for the pure-logic tests, and ruff at the SAME version the gate's
|
||||
# backend lint lane currently runs on the host (see the run_lint note in siftlode.sh). httpx is
|
||||
# already an app dependency (requirements.txt), so its TestClient needs nothing extra here.
|
||||
# backend lint lane runs on the host (the gate fails when the host's ruff is not this one). httpx2:
|
||||
# Starlette 1.x's TestClient is built on it (`import httpx2 as httpx`) and only falls back to the
|
||||
# app's own httpx with a deprecation warning on every run.
|
||||
pytest==8.4.2
|
||||
ruff==0.15.21
|
||||
httpx2==2.13.0
|
||||
|
||||
@@ -49,6 +49,7 @@ vi.mock("../lib/api", () => ({
|
||||
setState: () => Promise.resolve(),
|
||||
watchLaterAdd: () => Promise.resolve(),
|
||||
watchLaterRemove: () => Promise.resolve(),
|
||||
downloadIndex: () => Promise.resolve({}), // the cards' download buttons read it
|
||||
},
|
||||
DISCOVER_BUDGETS: ["short", "medium", "long", "any"],
|
||||
discoverCardKey: (c: { source: string; id: string }) => `${c.source}:${c.id}`,
|
||||
|
||||
@@ -53,6 +53,7 @@ vi.mock("../lib/api", () => ({
|
||||
setState: () => Promise.resolve(),
|
||||
watchLaterAdd: () => Promise.resolve(),
|
||||
watchLaterRemove: () => Promise.resolve(),
|
||||
downloadIndex: () => Promise.resolve({}), // the cards' download buttons read it
|
||||
comfortPins: (...a: unknown[]) => comfortPins(...a),
|
||||
addComfortPin: (...a: unknown[]) => addComfortPin(...a),
|
||||
removeComfortPin: (...a: unknown[]) => removeComfortPin(...a),
|
||||
|
||||
@@ -31,7 +31,7 @@ describe("a dialog open while fullscreen is left", () => {
|
||||
it("keeps what the viewer had typed in it, and the focus inside it", async () => {
|
||||
const stage = document.createElement("div");
|
||||
document.body.appendChild(stage);
|
||||
await setFullscreen(stage);
|
||||
setFullscreen(stage);
|
||||
render(
|
||||
<Modal title="Download" onClose={() => {}}>
|
||||
<input aria-label="name" defaultValue="" />
|
||||
@@ -42,7 +42,7 @@ describe("a dialog open while fullscreen is left", () => {
|
||||
field.focus();
|
||||
expect(stage.contains(field)).toBe(true);
|
||||
|
||||
await setFullscreen(null); // the browser's own Esc leaves fullscreen; the dialog stays open
|
||||
setFullscreen(null); // the browser's own Esc leaves fullscreen; the dialog stays open
|
||||
|
||||
const after = screen.getByLabelText("name") as HTMLInputElement;
|
||||
expect(after.value).toBe("my cut");
|
||||
@@ -78,7 +78,7 @@ describe("a dialog with an autoFocus child", () => {
|
||||
const field = screen.getByLabelText("query");
|
||||
expect(document.activeElement).toBe(field);
|
||||
|
||||
await setFullscreen(stage); // the player goes fullscreen under the open dialog
|
||||
setFullscreen(stage); // the player goes fullscreen under the open dialog
|
||||
|
||||
expect(stage.contains(field)).toBe(true);
|
||||
expect(document.activeElement).toBe(field);
|
||||
|
||||
@@ -8,6 +8,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { render, cleanup } from "@testing-library/react";
|
||||
import { LoadingState } from "./QueryState";
|
||||
|
||||
// The label is not under test; without an i18n instance react-i18next warns on every render.
|
||||
vi.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key: string) => key }) }));
|
||||
|
||||
let now = 0;
|
||||
beforeEach(() => {
|
||||
vi.spyOn(performance, "now").mockImplementation(() => now);
|
||||
|
||||
Reference in New Issue
Block a user