updates: Urteil und Paketliste sichtbar, ehrliche Lade- und Fehlerzustaende, Rueckfragen, Auftraege aller Gruppen
- Update-Details zeigen jetzt das Urteil des Hirns ("Nichts zu tun" / "Du musst
etwas tun" samt Text), die Zusammenfassung ist aufklappbar statt auf drei Zeilen
gekappt, das Betriebssystem zeigt seine Paketliste (und was Ubuntu zurueckhaelt).
- Scheitert eine Pruefung (z. B. git fetch bei Hermes), steht "Konnte nicht pruefen: ..."
statt "- -> neu"; waehrend des Ladens ein Platzhalter statt "..." und kein voreiliges "neu".
- Einzel-Update und Freigeben fragen vorher nach; der Ja-Knopf sperrt gegen Doppelklick.
- Neue Job-Karte (Fortschritt, Abbrechen mit Rueckfrage, letzte Meldung, Protokoll) fuer
alle laufenden Auftraege, egal welche Gruppe. Updates lassen sich bewusst nicht abbrechen.
- Job-Typen an jobengine.py angeglichen ("canceled", group, started_at/finished_at):
abgebrochene Auftraege erschienen bisher als "Laeuft".
- Fehler aus "Jetzt sichern" (Feld error) und "Es laeuft schon ein Update" (status busy)
werden gemeldet; ist ein Auftrag fertig, lesen Versionen, Modelle und Sicherungen neu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c8718fcde0
commit
5ddc952ecd
@@ -0,0 +1,82 @@
|
||||
import { fireEvent, render, screen } from "@testing-library/react"
|
||||
import { sichtbareJobs } from "@/lib/anzeige"
|
||||
import type { Job } from "@/lib/typen"
|
||||
import { JobKarte } from "./JobKarte"
|
||||
|
||||
const JETZT = 1_790_000_000 // Unix-Sekunden, fester Bezugspunkt
|
||||
|
||||
function job(teil: Partial<Job>): Job {
|
||||
return {
|
||||
id: "j1", label: "Nach Updates suchen", state: "running", group: null,
|
||||
log: ["$ bash -c 'sudo apt-get update'"], returncode: null,
|
||||
started_at: JETZT - 120, finished_at: null, ...teil,
|
||||
}
|
||||
}
|
||||
|
||||
describe("JobKarte", () => {
|
||||
it("zeigt bei einem Download Fortschritt und fragt vor dem Abbrechen nach", () => {
|
||||
const onAbbrechen = vi.fn()
|
||||
render(
|
||||
<JobKarte
|
||||
job={job({
|
||||
label: "download unsloth/Qwen3.8-27B-GGUF", progress: 42,
|
||||
done_bytes: 12 * 1024 ** 3, total_bytes: 29 * 1024 ** 3, eta_s: 360,
|
||||
})}
|
||||
onAbbrechen={onAbbrechen}
|
||||
/>,
|
||||
)
|
||||
expect(screen.getByText("Download unsloth/Qwen3.8-27B-GGUF")).toBeInTheDocument()
|
||||
expect(screen.getByRole("progressbar")).toHaveAttribute("aria-valuenow", "42")
|
||||
expect(screen.getByText("42 % · 12,0 GB von 29,0 GB · noch etwa 6 min")).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Abbrechen" }))
|
||||
expect(screen.getByRole("dialog", { name: "Auftrag abbrechen?" })).toBeInTheDocument()
|
||||
expect(onAbbrechen).not.toHaveBeenCalled()
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Ja, abbrechen" }))
|
||||
expect(onAbbrechen).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("nennt einen abgebrochenen Auftrag „Abgebrochen“ und nicht „Läuft“", () => {
|
||||
render(<JobKarte job={job({ state: "canceled", finished_at: JETZT })} onAbbrechen={() => {}} />)
|
||||
expect(screen.getByText("Abgebrochen")).toBeInTheDocument()
|
||||
expect(screen.queryByText("Läuft")).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole("button", { name: "Abbrechen" })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("bietet bei Updates kein Abbrechen an und zeigt bei Fehlern die letzte Meldung", () => {
|
||||
const { rerender } = render(
|
||||
<JobKarte job={job({ label: "Hermes-Agent-Update", group: "maintenance" })} onAbbrechen={() => {}} />,
|
||||
)
|
||||
expect(screen.queryByRole("button", { name: "Abbrechen" })).not.toBeInTheDocument()
|
||||
|
||||
rerender(
|
||||
<JobKarte
|
||||
job={job({
|
||||
label: "Hermes-Agent-Update", group: "maintenance", state: "failed", finished_at: JETZT,
|
||||
log: ["$ bash -c …", "✗ HERMES-UPDATE FEHLGESCHLAGEN (Dienste laufen wieder, aber alter Stand)", ""],
|
||||
})}
|
||||
/>,
|
||||
)
|
||||
expect(screen.getByText("Fehler")).toBeInTheDocument()
|
||||
expect(screen.getByText(/Letzte Meldung: ✗ HERMES-UPDATE FEHLGESCHLAGEN/)).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe("sichtbareJobs", () => {
|
||||
it("zeigt alle laufenden Aufträge jeder Gruppe und die drei zuletzt beendeten", () => {
|
||||
const liste = sichtbareJobs(
|
||||
[
|
||||
job({ id: "alt", state: "done", finished_at: JETZT - 2 * 86_400 }),
|
||||
job({ id: "f1", state: "done", finished_at: JETZT - 50 }),
|
||||
job({ id: "f2", state: "failed", finished_at: JETZT - 40 }),
|
||||
job({ id: "f3", state: "canceled", finished_at: JETZT - 30 }),
|
||||
job({ id: "f4", state: "done", finished_at: JETZT - 20 }),
|
||||
job({ id: "download", label: "download a/b", state: "running", group: null }),
|
||||
job({ id: "update", group: "maintenance", state: "queued", started_at: JETZT - 10 }),
|
||||
],
|
||||
JETZT,
|
||||
)
|
||||
expect(liste.map((j) => j.id)).toEqual(["download", "update", "f4", "f3", "f2"])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user