yiekheng e38b9ac7b6 feat(web): RunEtaPill at the wizard review step
Renders an advisory ETA badge above the Schedule button:
* Green "Fits before deadline" when the projected finish lands
  before the chosen deadline hour.
* Amber "Likely to pause" with a "Push the deadline later or split
  into smaller runs" hint when it doesn't.

Pill is purely informational — the operator can still schedule a
run that's likely to pause; the pause/resume flow (Phase 3) covers
that case. The pill just removes the surprise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:11:53 +08:00

47 lines
1.5 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { renderToStaticMarkup } from "react-dom/server";
import { RunEtaPill } from "./run-eta-pill";
describe("RunEtaPill", () => {
it("renders nothing for zero targets", () => {
const html = renderToStaticMarkup(
<RunEtaPill
targetCount={0}
fireAt={new Date("2026-05-13T09:00:00.000+08:00")}
windowEndAt={new Date("2026-05-13T18:00:00.000+08:00")}
timezone="Asia/Kuala_Lumpur"
/>,
);
expect(html).toBe("");
});
it("shows green 'Fits before deadline' when ETA finishes within the window", () => {
const html = renderToStaticMarkup(
<RunEtaPill
targetCount={500}
fireAt={new Date("2026-05-13T09:00:00.000+08:00")}
windowEndAt={new Date("2026-05-13T18:00:00.000+08:00")}
timezone="Asia/Kuala_Lumpur"
/>,
);
expect(html).toMatch(/Fits before deadline/);
expect(html).toMatch(/min/);
expect(html).not.toMatch(/Likely to pause/);
expect(html).toContain("emerald");
});
it("shows amber 'Likely to pause' when ETA exceeds the window", () => {
const html = renderToStaticMarkup(
<RunEtaPill
targetCount={5000}
fireAt={new Date("2026-05-13T17:00:00.000+08:00")}
windowEndAt={new Date("2026-05-13T18:00:00.000+08:00")}
timezone="Asia/Kuala_Lumpur"
/>,
);
expect(html).toMatch(/Likely to pause/);
expect(html).toMatch(/Push the deadline later/);
expect(html).toContain("amber");
});
});