feat: browse archived habit history and restore habits
This commit is contained in:
@@ -116,6 +116,24 @@ const buttonNamed = (name: string) => [...container.querySelectorAll<HTMLButtonE
|
||||
.find(button => button.textContent === name || button.getAttribute("aria-label") === name)!;
|
||||
|
||||
describe("homepage", () => {
|
||||
test("archived habits expose history and restore to the dashboard", async () => {
|
||||
const f = connectAccount();
|
||||
f.setTime("2026-09-03T12:00:00Z");
|
||||
const h = await f.json("/habits", "POST", { name: "Reading", method: "manual" }, 201);
|
||||
await f.json(`/habits/${h.id}/days/2026-09-03/progress`, "PUT", { done: true });
|
||||
f.setTime("2026-09-04T12:00:00Z");
|
||||
await f.request(`/habits/${h.id}`, "DELETE");
|
||||
await render("/");
|
||||
await act(async () => buttonNamed("Archived habits").click());
|
||||
expect(container.textContent).toContain("Restore Reading");
|
||||
await act(async () => buttonNamed("View history").click());
|
||||
expect(container.querySelector('[aria-label="2026-09-03: 1 of 1 completion · Complete"]')).not.toBeNull();
|
||||
await act(async () => buttonNamed("Restore Reading").click());
|
||||
expect(container.textContent).toContain("No archived habits.");
|
||||
expect((await f.json("/today")).habits[0].name).toBe("Reading");
|
||||
expect((await f.json(`/habits/${h.id}/days/2026-09-03`)).complete).toBe(true);
|
||||
});
|
||||
|
||||
test("historical check-ins use the selected date's tracking method and preserve today", async () => {
|
||||
const f = connectAccount();
|
||||
f.setTime("2026-09-03T12:00:00Z");
|
||||
@@ -240,12 +258,12 @@ describe("homepage", () => {
|
||||
expect(saved.target).toBe(10);
|
||||
expect(container.querySelector("form")).toBeNull();
|
||||
expect(container.querySelector("h3")?.textContent).toContain("Daily water");
|
||||
await act(async () => buttonNamed("Delete habit Daily water").click());
|
||||
await act(async () => buttonNamed("Archive habit Daily water").click());
|
||||
expect((await f.json("/habits")).habits).toHaveLength(1);
|
||||
await act(async () => buttonNamed("Cancel").click());
|
||||
expect((await f.json("/habits")).habits).toHaveLength(1);
|
||||
await act(async () => buttonNamed("Delete habit Daily water").click());
|
||||
await act(async () => buttonNamed("Delete habit").click());
|
||||
await act(async () => buttonNamed("Archive habit Daily water").click());
|
||||
await act(async () => buttonNamed("Archive habit").click());
|
||||
expect((await f.json("/habits")).habits).toHaveLength(0);
|
||||
expect(container.querySelector(".ds-habit-chart")).toBeNull();
|
||||
const previous = await f.json(`/habits/${habit.id}/days/2026-09-03`);
|
||||
@@ -398,15 +416,15 @@ describe("homepage", () => {
|
||||
const f = connectAccount();
|
||||
const habit = await f.json("/habits", "POST", { name: "Reading", method: "manual" }, 201);
|
||||
await render("/");
|
||||
await act(async () => buttonNamed("Delete habit Reading").click());
|
||||
await act(async () => buttonNamed("Archive habit Reading").click());
|
||||
fetchMock.mockImplementationOnce((async (input, init) => {
|
||||
return f.request(String(input).replace("/api", ""), init?.method);
|
||||
}) as typeof fetch);
|
||||
fetchMock.mockResolvedValueOnce(new Response(null, { status: 500 }));
|
||||
await act(async () => buttonNamed("Delete habit").click());
|
||||
await act(async () => buttonNamed("Archive habit").click());
|
||||
expect(container.querySelector("form")).toBeNull();
|
||||
expect(container.textContent).toContain("Your change was saved, but the dashboard could not refresh");
|
||||
expect(buttonNamed("Delete habit Reading").disabled).toBe(true);
|
||||
expect(buttonNamed("Archive habit Reading").disabled).toBe(true);
|
||||
expect((await f.json(`/habits/${habit.id}`)).archived).toBe(true);
|
||||
await act(async () => buttonNamed("Try again").click());
|
||||
expect(container.querySelector(".ds-habit-chart")).toBeNull();
|
||||
|
||||
Reference in New Issue
Block a user