aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/app/components/BorderedContainer.test.tsx33
-rw-r--r--frontend/app/config.test.ts16
-rw-r--r--frontend/justfile9
-rw-r--r--frontend/package.json6
-rw-r--r--frontend/vitest.config.ts10
5 files changed, 70 insertions, 4 deletions
diff --git a/frontend/app/components/BorderedContainer.test.tsx b/frontend/app/components/BorderedContainer.test.tsx
new file mode 100644
index 0000000..2d1b663
--- /dev/null
+++ b/frontend/app/components/BorderedContainer.test.tsx
@@ -0,0 +1,33 @@
+/**
+ * @vitest-environment jsdom
+ */
+import { cleanup, render, screen } from "@testing-library/react";
+import { afterEach, describe, expect, test } from "vitest";
+import BorderedContainer from "./BorderedContainer";
+
+afterEach(() => {
+ cleanup();
+});
+
+describe("BorderedContainer", () => {
+ test("renders children", () => {
+ render(<BorderedContainer>Hello World</BorderedContainer>);
+ expect(screen.getByText("Hello World")).toBeDefined();
+ });
+
+ test("applies custom className", () => {
+ render(
+ <BorderedContainer className="custom-class">Content</BorderedContainer>,
+ );
+ const container = screen.getByText("Content").closest("div");
+ expect(container?.className).toContain("custom-class");
+ });
+
+ test("has default border styling", () => {
+ render(<BorderedContainer>Styled</BorderedContainer>);
+ const container = screen.getByText("Styled").closest("div");
+ expect(container?.className).toContain("border-2");
+ expect(container?.className).toContain("border-blue-600");
+ expect(container?.className).toContain("rounded-xl");
+ });
+});
diff --git a/frontend/app/config.test.ts b/frontend/app/config.test.ts
new file mode 100644
index 0000000..6989635
--- /dev/null
+++ b/frontend/app/config.test.ts
@@ -0,0 +1,16 @@
+import { describe, expect, test } from "vitest";
+import { API_BASE_PATH, APP_NAME, BASE_PATH } from "./config";
+
+describe("config", () => {
+ test("BASE_PATH defaults to /", () => {
+ expect(BASE_PATH).toBe("/");
+ });
+
+ test("API_BASE_PATH is based on BASE_PATH", () => {
+ expect(API_BASE_PATH).toBe(`${BASE_PATH}api/`);
+ });
+
+ test("APP_NAME is defined", () => {
+ expect(APP_NAME).toBeTruthy();
+ });
+});
diff --git a/frontend/justfile b/frontend/justfile
index beba8b3..6d8082e 100644
--- a/frontend/justfile
+++ b/frontend/justfile
@@ -1,7 +1,10 @@
check:
npm run check
-ci:
+test:
+ npm run test
+
+ci: test
npx biome ci .
- npx tsc --noEmit
- npx eslint .
+ npm run check:ts
+ npm run check:eslint
diff --git a/frontend/package.json b/frontend/package.json
index dfbaa55..62c8547 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,6 +10,7 @@
"check:eslint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
"check:ts": "tsc --noEmit",
"dev": "vite",
+ "test": "vitest run",
"openapi-typescript": "openapi-typescript --output ./app/api/schema.d.ts ../openapi/api-server.yaml",
"shiki-codegen": "shiki-codegen --langs php,swift --themes github-light --engine javascript ./app/shiki.bundle.ts"
},
@@ -33,6 +34,7 @@
"@eslint/js": "^9.39.2",
"@tailwindcss/postcss": "^4.1.18",
"@tailwindcss/vite": "^4.1.18",
+ "@testing-library/react": "^16.3.2",
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
@@ -42,6 +44,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^17.3.0",
+ "jsdom": "^28.1.0",
"openapi-typescript": "^7.13.0",
"rollup-plugin-visualizer": "^6.0.5",
"shiki-codegen": "^3.22.0",
@@ -49,7 +52,8 @@
"typescript": "^5.9.3",
"typescript-eslint": "^8.55.0",
"vite": "^7.3.1",
- "vite-tsconfig-paths": "^6.1.1"
+ "vite-tsconfig-paths": "^6.1.1",
+ "vitest": "^4.0.18"
},
"engines": {
"node": ">=22.0.0"
diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts
new file mode 100644
index 0000000..ab1f2c3
--- /dev/null
+++ b/frontend/vitest.config.ts
@@ -0,0 +1,10 @@
+import react from "@vitejs/plugin-react";
+import tsconfigPaths from "vite-tsconfig-paths";
+import { defineConfig } from "vitest/config";
+
+export default defineConfig({
+ plugins: [react(), tsconfigPaths()],
+ test: {
+ include: ["app/**/*.test.{ts,tsx}"],
+ },
+});