with some tests

This commit is contained in:
counterweight 2025-12-18 21:48:41 +01:00
parent a764c92a0b
commit 0995e1cc77
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
18 changed files with 3020 additions and 16 deletions

View file

@ -0,0 +1,68 @@
import { render, screen, fireEvent, waitFor, cleanup } from "@testing-library/react";
import { expect, test, vi, beforeEach, afterEach } from "vitest";
import Home from "./page";
beforeEach(() => {
vi.restoreAllMocks();
});
afterEach(() => {
cleanup();
});
test("renders loading state initially", () => {
vi.spyOn(global, "fetch").mockImplementation(() => new Promise(() => {}));
render(<Home />);
expect(screen.getByText("...")).toBeDefined();
});
test("renders counter value after fetch", async () => {
vi.spyOn(global, "fetch").mockResolvedValue({
json: () => Promise.resolve({ value: 42 }),
} as Response);
render(<Home />);
await waitFor(() => {
expect(screen.getByText("42")).toBeDefined();
});
});
test("renders +1 button", async () => {
vi.spyOn(global, "fetch").mockResolvedValue({
json: () => Promise.resolve({ value: 0 }),
} as Response);
render(<Home />);
expect(screen.getByText("+1")).toBeDefined();
});
test("clicking button calls increment endpoint", async () => {
const fetchSpy = vi.spyOn(global, "fetch")
.mockResolvedValueOnce({ json: () => Promise.resolve({ value: 0 }) } as Response)
.mockResolvedValueOnce({ json: () => Promise.resolve({ value: 1 }) } as Response);
render(<Home />);
await waitFor(() => expect(screen.getByText("0")).toBeDefined());
fireEvent.click(screen.getByText("+1"));
await waitFor(() => {
expect(fetchSpy).toHaveBeenCalledWith(
"http://localhost:8000/api/counter/increment",
{ method: "POST" }
);
});
});
test("clicking button updates displayed count", async () => {
vi.spyOn(global, "fetch")
.mockResolvedValueOnce({ json: () => Promise.resolve({ value: 0 }) } as Response)
.mockResolvedValueOnce({ json: () => Promise.resolve({ value: 1 }) } as Response);
render(<Home />);
await waitFor(() => expect(screen.getByText("0")).toBeDefined());
fireEvent.click(screen.getByText("+1"));
await waitFor(() => expect(screen.getByText("1")).toBeDefined());
});

View file

@ -3,18 +3,37 @@
import { useEffect, useState } from "react";
export default function Home() {
const [message, setMessage] = useState("");
const [count, setCount] = useState<number | null>(null);
useEffect(() => {
fetch("http://localhost:8000/api/hello")
fetch("http://localhost:8000/api/counter")
.then((res) => res.json())
.then((data) => setMessage(data.message));
.then((data) => setCount(data.value));
}, []);
const increment = async () => {
const res = await fetch("http://localhost:8000/api/counter/increment", {
method: "POST",
});
const data = await res.json();
setCount(data.value);
};
return (
<main style={{ padding: "2rem", fontFamily: "system-ui" }}>
<h1>FastAPI + Next.js</h1>
<p>{message || "Loading..."}</p>
<main style={{ padding: "2rem", fontFamily: "system-ui", textAlign: "center" }}>
<h1 style={{ fontSize: "6rem", margin: "2rem 0" }}>
{count === null ? "..." : count}
</h1>
<button
onClick={increment}
style={{
fontSize: "1.5rem",
padding: "1rem 2rem",
cursor: "pointer",
}}
>
+1
</button>
</main>
);
}