UNPKG

@trieb.work/nextjs-turbo-redis-cache

Version:

Designed for speed, scalability, and optimized performance, nextjs-turbo-redis-cache is your custom cache handler for demanding production environments.

180 lines (130 loc) 10.7 kB
# Test Structure ``` test/ ├── playwright/ # E2E tests — browser automation (Playwright) ├── vitest/ # Unit + Integration tests (Vitest) │ ├── unit/ # Pure unit tests (no external deps) │ └── integration/ # Integration tests (Redis + Next.js server) │ └── cache-components/ # Cache Components integration (Next.js 16+) └── nextjs-test-projects/ # Next.js app fixtures (shared across test types) ``` ## Overview | Layer | Runner | What it validates | Needs Redis? | Needs Next.js app? | | --------------- | ---------- | ----------------------------------------------------------------------- | ------------ | ------------------ | | **Unit** | Vitest | Logic in isolation (serializer, prefix resolution, reconnect handling) | No | No | | **Integration** | Vitest | Cache handler ↔ Redis ↔ Next.js HTTP responses (server-side plumbing) | Yes | Yes | | **E2E** | Playwright | User-facing behavior in a real browser (Cache Components / `use cache`) | Yes | Yes | --- ## Unit Tests (`test/vitest/unit/`) **Runner:** Vitest **Command:** `pnpm test:unit` **Config:** `vite.config.ts` Fast tests with no external dependencies. Mocks are used where needed. | File | What it tests | | ----------------------------------------- | -------------------------------------------------------------------------------- | | `serializer.test.ts` | `CacheValueSerializer` interface, JSON round-trips, singleton stability | | `index.test.ts` | `RedisStringsHandler` constructor options, default behaviors | | `utils/prefix.test.ts` | `resolveKeyPrefix` logic (BUILD_ID fallback, env var precedence) | | `reconnect-socket-already-opened.test.ts` | Regression: reconnect logic doesn't call `connect()` when socket is already open | ```bash pnpm test:unit # single run pnpm test:unit:watch # watch mode pnpm test:unit:coverage # with coverage report (used in CI) ``` --- ## Integration Tests (`test/vitest/integration/`) **Runner:** Vitest **Command:** `pnpm test:integration` **Config:** `vite.config.ts` **Requires:** Redis on localhost:6379, pre-built Next.js test app These tests spawn a real Next.js server as a child process, make `fetch()` requests against it, and verify both HTTP responses and Redis state directly. ### Standard Integration (`nextjs-cache-handler.integration.test.ts`) Full cache lifecycle: static pages, fetch caching, revalidation, tag invalidation, TTL behavior. In CI this runs against a matrix of Next.js versions (15.4–16.2). ```bash pnpm test:integration ``` ### BUILD_ID Prefix (`build-id-prefix.integration.test.ts`) Verifies that when neither `KEY_PREFIX` nor `VERCEL_URL` is set, the handler falls back to `.next/BUILD_ID` as the Redis key prefix. Runs in its own CI job because it needs a clean environment without those env vars. ```bash pnpm test:integration:build-id-prefix ``` ### Cache Components (`cache-components/`) Integration tests specific to Next.js 16 Cache Components (`use cache`). Uses `next-app-16-2-6-cache-components` as the test app. | File | What it tests | | -------------------------------------- | ------------------------------------------------------------------------------------------------------ | | `cache-components.integration.test.ts` | `use cache` lifecycle: store, retrieve, tag invalidation, `cacheLife` expiry | | `redis-kill-reconnect.test.ts` | Graceful recovery when Redis drops and reconnects (main client ping only) | | `redis-subscriber-outage.test.ts` | Issue #86: subscriber PubSub does not recover after Redis outage (expected to fail until bug is fixed) | | `redis-quit-vs-disconnect.test.ts` | `quit()` does not reliably close a subscriber during an outage; `disconnect()` does | `redis-kill-reconnect.test.ts` uses a container runtime and auto-detects `podman` first, then `docker`. You can force runtime selection with `CONTAINER_RUNTIME=podman` or `CONTAINER_RUNTIME=docker`. ```bash pnpm test:integration:cache-components ``` **Prerequisites for all integration tests:** ```bash cd test/nextjs-test-projects/<app-name> pnpm install && pnpm build ``` --- ## E2E Tests (`test/playwright/`) **Runner:** Playwright **Command:** `pnpm test:e2e` **Config:** `playwright.config.ts` **Requires:** Redis on localhost:6379 (Playwright auto-starts `next-app-16-2-6-cache-components` via `webServer`) Browser-based tests that validate Cache Components behavior from the user's perspective. Playwright was introduced because the Cache Components (`use cache`) feature in Next.js 16 relies on interactions that `fetch()` alone cannot reproduce: - **Server Actions** are triggered by form submissions / button clicks — requires a real browser context - `**updateTag`\*\* must be called from within a Server Action — needs actual UI interaction to verify - **Cookie-based cache keys** depend on the browser sending cookies during navigation - **Stale-while-revalidate** effects are only observable through page reloads and DOM diffing The Vitest cache-components integration tests verify the server-side plumbing (Redis state, HTTP responses). Playwright closes the gap by testing the full user-facing flow. | File | What it tests | | -------------------- | -------------------------------------------------------------------------------------------------------------------- | | `cache-lab.spec.ts` | `use cache` stability, tag invalidation (`updateTag`/`revalidateTag`), runtime cookie-based cache keys, SWR behavior | | `update-tag.spec.ts` | `updateTag` via Server Actions (button click → action → UI update) | ```bash pnpm test:e2e # Test against a specific Next.js version: PLAYWRIGHT_TEST_APP=next-app-16-0-11-cache-components pnpm test:e2e # Or point at an already-running server: PLAYWRIGHT_BASE_URL=http://localhost:3001 pnpm test:e2e ``` --- ## Next.js Test Projects (`test/nextjs-test-projects/`) Minimal Next.js applications used as fixtures. They are not test runners — they provide the server that tests run against. | App | Next.js | Used by | | ----------------------------------- | ------- | -------------------------------------------------------------- | | `next-app-15-4-11` | 15.4.11 | Integration (matrix, default for local), build-id-prefix | | `next-app-16-0-11` | 16.0.11 | Integration (matrix) | | `next-app-16-2-6` | 16.2.6 | Integration (matrix) | | `next-app-16-0-11-cache-components` | 16.0.11 | Integration (cache-components matrix), E2E (Playwright matrix) | | `next-app-16-2-6-cache-components` | 16.2.6 | Integration (cache-components matrix), E2E (Playwright matrix) | | `next-app-customized` | — | Example of custom config (referenced in project README) | --- ## CI Jobs The CI workflow (`.github/workflows/ci.yml`) is structured as: ``` lint-and-unit → Lint + Unit Tests + Coverage ├── integration → Matrix: 3 Next.js versions (15.4–16.2) ├── integration-build-id-prefix → Isolated BUILD_ID prefix test ├── integration-cache-components → Matrix: 16.0.11 + 16.2.6 cache-components └── e2e → Matrix: Playwright against 16.0.11 + 16.2.6 ``` `lint-and-unit` runs first as a gate. All other jobs run in parallel after it passes. | CI Job | Test App(s) | What runs | | ------------------------------ | --------------------------------------------------------- | --------------------------------------------------------------- | | `lint-and-unit` | — | `pnpm lint` + `pnpm test:unit:coverage` | | `integration` | `next-app-15-4-11`, `next-app-16-0-11`, `next-app-16-2-6` | `pnpm test:integration` (per matrix entry) | | `integration-build-id-prefix` | `next-app-15-4-11` | `pnpm test:integration:build-id-prefix` | | `integration-cache-components` | `next-app-16-{0-3,2-3}-cache-components` | `pnpm test:integration:cache-components` + Redis kill/reconnect | | `e2e` | `next-app-16-{0-3,2-3}-cache-components` | `pnpm test:e2e` (Playwright) | --- ## Environment Variables | Variable | Used by | Description | | ----------------------- | ------------------------------ | ------------------------------------------------------------------------- | | `NEXT_TEST_APP` | Integration | Which test app to use (default: `next-app-15-4-11`) | | `CACHE_COMPONENTS_APP` | Integration (cache-components) | Which cache-components app (default: `next-app-16-2-6-cache-components`) | | `PLAYWRIGHT_TEST_APP` | E2E | Which app Playwright starts (default: `next-app-16-2-6-cache-components`) | | `PLAYWRIGHT_BASE_URL` | E2E | Override base URL (skips `webServer` auto-start) | | `SKIP_BUILD` | Integration | Skip Next.js build if app is pre-built | | `DEBUG_INTEGRATION` | Integration | Print child process stdout/stderr | | `CACHE_COMPONENTS_PORT` | Integration (cache-components) | Port for the server (default: 3065) |