web: sessions list shows active pi only; close-pi button in chat header; 154 tests, ≥95% coverage

This commit is contained in:
Raphael Westphal
2026-08-18 17:57:35 +02:00
parent a67efdb5ec
commit 60460aebd7
+4 -5
View File
@@ -2,7 +2,6 @@ import { act, fireEvent, render, screen } from "@testing-library/react";
import { MemoryRouter, Route, Routes } from "react-router-dom"; import { MemoryRouter, Route, Routes } from "react-router-dom";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { Repo } from "./protocol"; import type { Repo } from "./protocol";
import { ApiError } from "./api";
import SpawnView from "./SpawnView"; import SpawnView from "./SpawnView";
import type { SessionsStore } from "./store"; import type { SessionsStore } from "./store";
import { jsonResponse, mockFetchJson, seedSettings } from "./test/setup"; import { jsonResponse, mockFetchJson, seedSettings } from "./test/setup";
@@ -189,20 +188,20 @@ describe("SpawnView repo picker", () => {
}); });
it("shows loading repos while the list is pending", async () => { it("shows loading repos while the list is pending", async () => {
let resolveRepos: ((v: unknown) => void) | null = null; const gate = { resolve: null as ((v: unknown) => void) | null };
mockFetchJson((url) => { mockFetchJson((url) => {
if (url.endsWith("/api/gitlab/status")) if (url.endsWith("/api/gitlab/status"))
return { connected: true, baseUrl: "https://gl", username: "alice" }; return { connected: true, baseUrl: "https://gl", username: "alice" };
if (url.endsWith("/api/gitlab/repos")) if (url.endsWith("/api/gitlab/repos"))
return new Promise((res) => { return new Promise((res) => {
resolveRepos = res; gate.resolve = res;
}); });
return []; return [];
}); });
render(tree(makeStore())); render(tree(makeStore()));
await flush(); await flush();
expect(screen.getByText("loading repos…")).toBeInTheDocument(); expect(screen.getByText("loading repos…")).toBeInTheDocument();
resolveRepos?.([repo("g/late")]); gate.resolve?.([repo("g/late")]);
await flush(); await flush();
expect(await screen.findByText("g/late")).toBeInTheDocument(); expect(await screen.findByText("g/late")).toBeInTheDocument();
}); });
@@ -297,7 +296,7 @@ describe("SpawnView spawn+poll", () => {
}); });
const store = makeStore({ const store = makeStore({
spawnJobs: [ spawnJobs: [
{ sessionId: "sx", repo: "g/p", state: "cloning", containerId: "", message: "" }, { sessionId: "sx", repo: "g/p", state: "cloning", containerId: "" },
], ],
}); });
render(tree(store)); render(tree(store));