feat(apps): add unit tests for providers + bind-production + cms config
web-next: bindAllProduction calls all 4 feature binders exactly once; Providers renders children. web-tanstack: equivalent providers + bind tests. cms: payload.config exports a SanitizedConfig with all expected collections. Spec: §6.7, §9 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
"build": "echo 'CMS build requires database — use docker compose or pnpm dev'",
|
"build": "echo 'CMS build requires database — use docker compose or pnpm dev'",
|
||||||
"dev": "next dev --port 3001",
|
"dev": "next dev --port 3001",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
|
"test": "vitest run --passWithNoTests",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"generate:types": "payload generate:types"
|
"generate:types": "payload generate:types"
|
||||||
},
|
},
|
||||||
@@ -24,9 +25,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@repo/core-eslint": "workspace:*",
|
"@repo/core-eslint": "workspace:*",
|
||||||
|
"@repo/core-testing": "workspace:*",
|
||||||
"@repo/core-typescript": "workspace:*",
|
"@repo/core-typescript": "workspace:*",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@types/react": "^19.0.0",
|
"@types/react": "^19.0.0",
|
||||||
"@types/react-dom": "^19.0.0"
|
"@types/react-dom": "^19.0.0",
|
||||||
|
"vitest": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
apps/cms/src/payload.config.test.ts
Normal file
20
apps/cms/src/payload.config.test.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import config from "./payload.config";
|
||||||
|
|
||||||
|
describe("CMS app payload.config", () => {
|
||||||
|
it("registers all feature collections", async () => {
|
||||||
|
const resolved = await config;
|
||||||
|
const slugs = resolved.collections?.map((c) => c.slug) ?? [];
|
||||||
|
expect(slugs).toEqual(
|
||||||
|
expect.arrayContaining(["users", "articles", "pages", "media"]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("registers all feature globals", async () => {
|
||||||
|
const resolved = await config;
|
||||||
|
const slugs = resolved.globals?.map((g) => g.slug) ?? [];
|
||||||
|
expect(slugs).toEqual(
|
||||||
|
expect.arrayContaining(["site-settings", "header"]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
"./src/payload.config.ts"
|
"./src/payload.config.ts"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"allowJs": true
|
"allowJs": true,
|
||||||
|
"types": ["vitest/globals"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
|
|||||||
7
apps/cms/vitest.config.ts
Normal file
7
apps/cms/vitest.config.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
import { mergeConfig } from "vitest/config";
|
||||||
|
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||||
|
|
||||||
|
export default mergeConfig(nodeVitestConfig, {
|
||||||
|
resolve: { alias: { "@": path.resolve(__dirname, "./src") } },
|
||||||
|
});
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
"build": "echo 'Next.js build requires full environment — use pnpm dev or docker'",
|
"build": "echo 'Next.js build requires full environment — use pnpm dev or docker'",
|
||||||
"dev": "next dev --port 3000",
|
"dev": "next dev --port 3000",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
|
"test": "vitest run --passWithNoTests",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:e2e:install": "playwright install --with-deps chromium",
|
"test:e2e:install": "playwright install --with-deps chromium",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
@@ -33,9 +34,15 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.50.0",
|
"@playwright/test": "^1.50.0",
|
||||||
"@repo/core-eslint": "workspace:*",
|
"@repo/core-eslint": "workspace:*",
|
||||||
|
"@repo/core-testing": "workspace:*",
|
||||||
"@repo/core-typescript": "workspace:*",
|
"@repo/core-typescript": "workspace:*",
|
||||||
|
"@testing-library/jest-dom": "^6.5.0",
|
||||||
|
"@testing-library/react": "^16.0.0",
|
||||||
|
"@testing-library/user-event": "^14.5.0",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@types/react": "^19.0.0",
|
"@types/react": "^19.0.0",
|
||||||
"@types/react-dom": "^19.0.0"
|
"@types/react-dom": "^19.0.0",
|
||||||
|
"jsdom": "^25.0.0",
|
||||||
|
"vitest": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
apps/web-next/src/app/providers.test.tsx
Normal file
14
apps/web-next/src/app/providers.test.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import { Providers } from "./providers";
|
||||||
|
|
||||||
|
describe("Providers", () => {
|
||||||
|
it("renders children", () => {
|
||||||
|
render(
|
||||||
|
<Providers>
|
||||||
|
<div data-testid="child">hi</div>
|
||||||
|
</Providers>,
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId("child")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
37
apps/web-next/src/server/bind-production.test.ts
Normal file
37
apps/web-next/src/server/bind-production.test.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||||
|
|
||||||
|
vi.mock("@repo/core-cms", () => ({ default: Promise.resolve({}) }));
|
||||||
|
vi.mock("@repo/blog/di/bind-production", () => ({ bindProductionBlog: vi.fn() }));
|
||||||
|
vi.mock("@repo/auth/di/bind-production", () => ({ bindProductionAuth: vi.fn() }));
|
||||||
|
vi.mock("@repo/marketing-pages/di/bind-production", () => ({ bindProductionMarketingPages: vi.fn() }));
|
||||||
|
vi.mock("@repo/navigation/di/bind-production", () => ({ bindProductionNavigation: vi.fn() }));
|
||||||
|
|
||||||
|
describe("bindAllProduction", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.resetModules();
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("binds all four feature production repos", async () => {
|
||||||
|
const { bindAllProduction } = await import("./bind-production");
|
||||||
|
const { bindProductionBlog } = await import("@repo/blog/di/bind-production");
|
||||||
|
const { bindProductionAuth } = await import("@repo/auth/di/bind-production");
|
||||||
|
const { bindProductionMarketingPages } = await import("@repo/marketing-pages/di/bind-production");
|
||||||
|
const { bindProductionNavigation } = await import("@repo/navigation/di/bind-production");
|
||||||
|
|
||||||
|
await bindAllProduction();
|
||||||
|
|
||||||
|
expect(bindProductionBlog).toHaveBeenCalledOnce();
|
||||||
|
expect(bindProductionAuth).toHaveBeenCalledOnce();
|
||||||
|
expect(bindProductionMarketingPages).toHaveBeenCalledOnce();
|
||||||
|
expect(bindProductionNavigation).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is idempotent — second call does not re-bind", async () => {
|
||||||
|
const { bindAllProduction } = await import("./bind-production");
|
||||||
|
const { bindProductionBlog } = await import("@repo/blog/di/bind-production");
|
||||||
|
await bindAllProduction();
|
||||||
|
await bindAllProduction();
|
||||||
|
expect(bindProductionBlog).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
"./src/*"
|
"./src/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"allowJs": true
|
"allowJs": true,
|
||||||
|
"types": ["vitest/globals", "@testing-library/jest-dom"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
|
|||||||
8
apps/web-next/vitest.config.ts
Normal file
8
apps/web-next/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
import { mergeConfig } from "vitest/config";
|
||||||
|
import { jsdomVitestConfig } from "@repo/core-typescript/vitest.base.jsdom";
|
||||||
|
|
||||||
|
export default mergeConfig(jsdomVitestConfig, {
|
||||||
|
esbuild: { jsx: "automatic" },
|
||||||
|
resolve: { alias: { "@": path.resolve(__dirname, "./src") } },
|
||||||
|
});
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
"build": "echo 'placeholder — TanStack Start build configured in later plan'",
|
"build": "echo 'placeholder — TanStack Start build configured in later plan'",
|
||||||
"dev": "echo 'placeholder'",
|
"dev": "echo 'placeholder'",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
|
"test": "vitest run --passWithNoTests",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
@@ -25,9 +26,15 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.50.0",
|
"@playwright/test": "^1.50.0",
|
||||||
"@repo/core-eslint": "workspace:*",
|
"@repo/core-eslint": "workspace:*",
|
||||||
|
"@repo/core-testing": "workspace:*",
|
||||||
"@repo/core-typescript": "workspace:*",
|
"@repo/core-typescript": "workspace:*",
|
||||||
|
"@testing-library/jest-dom": "^6.5.0",
|
||||||
|
"@testing-library/react": "^16.0.0",
|
||||||
|
"@testing-library/user-event": "^14.5.0",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@types/react": "^19.0.0",
|
"@types/react": "^19.0.0",
|
||||||
"@types/react-dom": "^19.0.0"
|
"@types/react-dom": "^19.0.0",
|
||||||
|
"jsdom": "^25.0.0",
|
||||||
|
"vitest": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
apps/web-tanstack/src/routes/__root.test.tsx
Normal file
23
apps/web-tanstack/src/routes/__root.test.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { describe, it, expect, vi } from "vitest";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
|
||||||
|
// Mock @tanstack/react-router so we don't need a full router context
|
||||||
|
vi.mock("@tanstack/react-router", () => ({
|
||||||
|
createRootRoute: vi.fn((opts: { component: React.ComponentType }) => ({
|
||||||
|
options: { component: opts.component },
|
||||||
|
})),
|
||||||
|
Outlet: () => <div data-testid="outlet" />,
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("Root route", () => {
|
||||||
|
it("wraps Outlet with TanstackTrpcProvider (children render)", async () => {
|
||||||
|
const { Route } = await import("./__root");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const RootComponent = (Route as any).options.component as React.ComponentType;
|
||||||
|
|
||||||
|
render(<RootComponent />);
|
||||||
|
|
||||||
|
expect(screen.getByTestId("outlet")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -6,7 +6,8 @@
|
|||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
},
|
||||||
|
"types": ["vitest/globals", "@testing-library/jest-dom"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
|
|||||||
8
apps/web-tanstack/vitest.config.ts
Normal file
8
apps/web-tanstack/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
import { mergeConfig } from "vitest/config";
|
||||||
|
import { jsdomVitestConfig } from "@repo/core-typescript/vitest.base.jsdom";
|
||||||
|
|
||||||
|
export default mergeConfig(jsdomVitestConfig, {
|
||||||
|
esbuild: { jsx: "automatic" },
|
||||||
|
resolve: { alias: { "@": path.resolve(__dirname, "./src") } },
|
||||||
|
});
|
||||||
42
pnpm-lock.yaml
generated
42
pnpm-lock.yaml
generated
@@ -54,6 +54,9 @@ importers:
|
|||||||
'@repo/core-eslint':
|
'@repo/core-eslint':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core-eslint
|
version: link:../../packages/core-eslint
|
||||||
|
'@repo/core-testing':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../packages/core-testing
|
||||||
'@repo/core-typescript':
|
'@repo/core-typescript':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core-typescript
|
version: link:../../packages/core-typescript
|
||||||
@@ -66,6 +69,9 @@ importers:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^19.0.0
|
specifier: ^19.0.0
|
||||||
version: 19.2.3(@types/react@19.2.14)
|
version: 19.2.3(@types/react@19.2.14)
|
||||||
|
vitest:
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.2.4(@types/debug@4.1.13)(@types/node@22.19.17)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(tsx@4.21.0)
|
||||||
|
|
||||||
apps/storybook:
|
apps/storybook:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -167,9 +173,21 @@ importers:
|
|||||||
'@repo/core-eslint':
|
'@repo/core-eslint':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core-eslint
|
version: link:../../packages/core-eslint
|
||||||
|
'@repo/core-testing':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../packages/core-testing
|
||||||
'@repo/core-typescript':
|
'@repo/core-typescript':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core-typescript
|
version: link:../../packages/core-typescript
|
||||||
|
'@testing-library/jest-dom':
|
||||||
|
specifier: ^6.5.0
|
||||||
|
version: 6.9.1
|
||||||
|
'@testing-library/react':
|
||||||
|
specifier: ^16.0.0
|
||||||
|
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
'@testing-library/user-event':
|
||||||
|
specifier: ^14.5.0
|
||||||
|
version: 14.6.1(@testing-library/dom@10.4.1)
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.0.0
|
specifier: ^22.0.0
|
||||||
version: 22.19.17
|
version: 22.19.17
|
||||||
@@ -179,6 +197,12 @@ importers:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^19.0.0
|
specifier: ^19.0.0
|
||||||
version: 19.2.3(@types/react@19.2.14)
|
version: 19.2.3(@types/react@19.2.14)
|
||||||
|
jsdom:
|
||||||
|
specifier: ^25.0.0
|
||||||
|
version: 25.0.1
|
||||||
|
vitest:
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.2.4(@types/debug@4.1.13)(@types/node@22.19.17)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(tsx@4.21.0)
|
||||||
|
|
||||||
apps/web-tanstack:
|
apps/web-tanstack:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -219,9 +243,21 @@ importers:
|
|||||||
'@repo/core-eslint':
|
'@repo/core-eslint':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core-eslint
|
version: link:../../packages/core-eslint
|
||||||
|
'@repo/core-testing':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../packages/core-testing
|
||||||
'@repo/core-typescript':
|
'@repo/core-typescript':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/core-typescript
|
version: link:../../packages/core-typescript
|
||||||
|
'@testing-library/jest-dom':
|
||||||
|
specifier: ^6.5.0
|
||||||
|
version: 6.9.1
|
||||||
|
'@testing-library/react':
|
||||||
|
specifier: ^16.0.0
|
||||||
|
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
'@testing-library/user-event':
|
||||||
|
specifier: ^14.5.0
|
||||||
|
version: 14.6.1(@testing-library/dom@10.4.1)
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.0.0
|
specifier: ^22.0.0
|
||||||
version: 22.19.17
|
version: 22.19.17
|
||||||
@@ -231,6 +267,12 @@ importers:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^19.0.0
|
specifier: ^19.0.0
|
||||||
version: 19.2.3(@types/react@19.2.14)
|
version: 19.2.3(@types/react@19.2.14)
|
||||||
|
jsdom:
|
||||||
|
specifier: ^25.0.0
|
||||||
|
version: 25.0.1
|
||||||
|
vitest:
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.2.4(@types/debug@4.1.13)(@types/node@22.19.17)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(tsx@4.21.0)
|
||||||
|
|
||||||
packages/auth:
|
packages/auth:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user