mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 17:46:06 +00:00
Second pass over the suite, driven by the inventory in the gaps document. Nine agents wrote suites in parallel against private databases, then a tenth read all of it adversarially and five of its findings were fixed. unit + component 2076 -> 2079 (+888 over the round) api 647 -> 1015 e2e 18 -> 29 What was closed: - lib/route-access.ts, the page-level authorization layer, went from zero tests to 48. Every API route was guarded and none of the pages were. - The five media proxy routes now have a real 2xx beside every 403. The blocker was the positive control, solved by stubbing r2Client.send() and leaving lib/r2-media-proxy.ts itself real. - Every remaining server-side lib module: invitations, email verification, the upload tokens, the logger, request origin, the whole R2 and Bunny lifecycle, notifications and admin stats. - Six video-page hooks, and the chunking arithmetic extracted out of lib/client/r2-video-upload.ts as a pure module. - Five end-to-end flows: workspace members, bulk operations, the admin area, player interaction and failure recovery. Three things about the harness itself turned out to be wrong: - Two @/lib/r2 stubs in tests/setup/api.ts had the wrong return shape, so every route reaching finalizeR2VideoUpload silently took the "not a valid video" branch and no test noticed. - The auth matrix asserted only "not 2xx", which two entries satisfied without their guard existing. It now requires 401 or 403, which makes both load-bearing, and all 60 routes pass the stricter form. - Both admin API routes had no positive control anywhere: replacing their guard with an unconditional refusal left the entire suite green. Found by the adversarial review, now covered. Process: - bun run test:mutation runs StrykerJS over the authorization and validation modules. Diagnostic, not a gate, weekly in CI rather than on a push. - playwright.config.ts gains an opt-in webkit project for the player spec. - AGENTS.md now requires a batch of new tests to be reviewed by somebody who did not write them. Only two production files change, both deliberate: lib/auth.ts loses a verbatim copy of its own permission formulas, and lib/client/r2-video-upload.ts calls the extracted arithmetic. No behaviour change in either.
39 lines
1.2 KiB
JavaScript
39 lines
1.2 KiB
JavaScript
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
import nextVitals from 'eslint-config-next/core-web-vitals';
|
|
import nextTs from 'eslint-config-next/typescript';
|
|
import prettier from 'eslint-config-prettier';
|
|
|
|
const eslintConfig = defineConfig([
|
|
...nextVitals,
|
|
...nextTs,
|
|
// Override default ignores of eslint-config-next.
|
|
globalIgnores([
|
|
// Default ignores of eslint-config-next:
|
|
'.next/**',
|
|
'out/**',
|
|
'build/**',
|
|
'next-env.d.ts',
|
|
// Generated test output. These are gitignored, but eslint keeps its own
|
|
// ignore list, and the v8 coverage reporter ships vendored JS that trips
|
|
// `--max-warnings=0`, so a coverage run would otherwise break `bun run lint`.
|
|
'coverage/**',
|
|
'playwright-report/**',
|
|
'test-results/**',
|
|
'reports/**',
|
|
'.stryker-tmp/**',
|
|
]),
|
|
prettier,
|
|
{
|
|
// Tests are allowed liberties that production code is not: `any` when
|
|
// shaping a fixture, and imports that reach past the `@/` aliases into
|
|
// test helpers. `--max-warnings=0` still applies to everything else.
|
|
files: ['tests/**/*.{ts,tsx}'],
|
|
rules: {
|
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
'no-restricted-imports': 'off',
|
|
},
|
|
},
|
|
]);
|
|
|
|
export default eslintConfig;
|