mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
`Client/tests/unit/admin-static-channel-perms.test.ts` reads and executes
`Server/admin/static/index.html`. Filed under `tests/unit`, nothing about its
location or name said it locks a server-owned artifact, so a Go developer
editing the admin SPA got a red check called "Client Unit Tests" with no clue
why.
The register describes this as one file. It is not, and the measured set does
not match the description in either direction:
- Client -> Server: exactly ONE test crosses by filesystem read, not two.
`main-page.test.ts` was named in the plan but only carries a prose comment
citing `Server/admin/update_handlers.go:181` at line 1046 — no read, no
import, nothing to move.
- Server -> Client: the four tests the plan named do not cross.
`waf_test.go`/`waf_crs_test.go` set a `User-Agent: OwnCordClient/1.0`
literal that appears nowhere under `Client/`; `ws_integration_test.go:289`
and `sanitize_content_fuzz_test.go:46` are comments. The real crossing is
one the register never named: `Server/updater/updater_test.go:630` does
`os.ReadFile` on `Client/src-tauri/tauri.conf.json`.
The obvious fixes are both wrong. Moving the invariant "to the owning server
test" cannot work: `Server/go.mod` carries no JavaScript engine (no goja,
otto, v8go, quickjs, rogchap, duktape), so a Go port could only assert at the
text level like `admin/perm_grid_test.go` does — and that is not a
substitute. Flipping the guard at `admin/static/index.html:1182` to
`targetIsTouchedRole=false` reintroduces OC-0154 in full while leaving every
greppable identifier intact, so a text-level test passes on a broken file.
Relocating it to the e2e admin journey is worse: that job is
`continue-on-error: true` and deliberately unpinned ("requiring it is
theatre" — `docs/plans/b0-dev-branch-protection.sh`), so it would convert a
blocking, pinned gate into one that is green regardless. And the journey does
not cover the invariant today: `grep -Eic "perm|access|role|override|matrix"`
over its 142 lines returns 0, so the "if e2e already covers it, delete"
branch never fires.
Done — one tier, applied to the whole set, defined by artifact coupling and
placed by runtime capability:
- New `Client/tests/contract/`, holding
`server-admin-static-channel-perms.test.ts`. Same directory depth, so
`../../../Server/...` still resolves; the body is byte-identical apart from
a header naming the owner and the runner.
- `Server/updater/tauri_key_contract_test.go` splits the one cross-component
Go test out of `updater_test.go` verbatim, same `package updater`. It stays
in Go — placement follows capability, and Go parses JSON fine — so only the
file name has to declare the crossing. Without this the item would have
been "moved one file and declared the class closed".
- `npm run test:contract`, and the tier, the membership rule and a
blocking/non-blocking table in `docs/contributing.md#testing`, which
previously described no tiers at all.
- `Client/CLAUDE.md`'s tier list was missing `tests/e2e/admin` and
`tests/e2e/native` before this; it now lists all seven and states the rule.
`Server/CLAUDE.md` records why the SPA's execution-level invariant is
locked from the client tree, so nobody "fixes" it into a regex.
- Ledger `OC-0154.fix.test` re-pointed and `FINDINGS.md` re-rendered;
`.claude/workflows/bughunt.js` — the workflow that produced OC-0154 — no
longer describes the TS test surface as `tests/unit/*.test.ts` only.
- Three stale cross-stack pointers of exactly the class this item is about:
`tests/e2e/helpers.ts:348,351` and `tests/unit/types.test.ts:13` named
`docs/brain/06-Specs/PROTOCOL.md`, which does not exist (`docs/brain/` is a
gitignored path); all now name `docs/protocol.md`.
15 files, 125 insertions, 33 deletions. No CI job, workflow, vitest,
tsconfig, eslint, knip or stryker change, and no new pinned check —
`ci.yml`'s `npx vitest run --coverage` has no path filter and
`vitest.config.ts` includes `tests/**/*.test.ts`, so enforcement after the
move is bit-identical to enforcement before it. That is deliberate: `dev`
pins 11 contexts and a 12th is a branch-protection API write, not something a
PR can do, so any new job would be advisory until someone separately changed
repository settings — strictly less protection than today.
Verified: both directions, and the assertion was not weakened. Flipping
`admin/static/index.html:1182` to `const targetIsTouchedRole=false;` makes
the moved test fail (`AssertionError: expected 'DELETE' not to be 'DELETE'`);
`git checkout` of that file makes it pass again — so the invariant survived
the move intact rather than becoming a test that passes anywhere. The split
Go test's cross-boundary read is live too: with
`Client/src-tauri/tauri.conf.json` moved away, `go test ./updater/` fails
with `ReadFile(../../Client/src-tauri/tauri.conf.json): no such file or
directory` from `tauri_key_contract_test.go:20`, and passes once restored.
The full client suite is 192 files / 5257 tests passing, identical to the
count before the move; `npm run typecheck` passes, which proves
`tests/contract/` is inside the tsconfig graph and that `tests/types/jsdom.d.ts`
still resolves the moved test's `import { JSDOM }`. `npm run lint`,
`npx prettier --check .`, `go vet ./...` and `go test ./updater/` all pass.
`git grep "tests/unit/admin-static-channel-perms"` finds no survivor outside
the B1 plan itself.
Not included: nothing was deleted, because no e2e sibling covers OC-0154.
`Client/tests/types/jsdom.d.ts` was neither moved nor deleted — it is still
the only type source for the moved test's `jsdom` import. `capabilities-scope.test.ts`
and `tauri-conf-webview2-args.test.ts` read `src-tauri/` and stay in
`tests/unit`: `src-tauri` is inside the `Client` component, so they are not
contract tests, and the rule earns that rather than hand-waving it — moving
them would have forced repoints of ledger entry OC-0089 and
`docs/security.md:64` for no gain. Each gained a one-line header saying why.
`Server/admin/perm_grid_test.go` and `emoji_section_test.go` read their own
package's embedded asset and are unchanged; they are the text-level
complement to the execution-level test, not duplicates. No JS engine was
added to `go.mod`, no npm root was created under `Server/`, and no root-level
`tests/` tier was created — there is no runner for one and no way to make it
blocking from a PR. Separately noticed and NOT fixed here:
`docs/contributing.md:221` still says "All ten required checks" while
`docs/plans/b0-dev-branch-protection.sh` pins eleven since B1-3 added
`Repository Hygiene`, and `docs/plans/hp-0-scorecard-2026-08-25.md:109` is
stale the same way — that is the branch-protection item's to fix, not this
one's, and one register item per commit.
Refs RL-11, L-11
76 lines
2.4 KiB
JSON
76 lines
2.4 KiB
JSON
{
|
|
"name": "owncord-client",
|
|
"private": true,
|
|
"version": "1.2.0-alpha.3",
|
|
"type": "module",
|
|
"engines": {
|
|
"node": ">=24",
|
|
"npm": ">=10"
|
|
},
|
|
"scripts": {
|
|
"dev": "vite",
|
|
"build": "tsc -p tsconfig.build.json && vite build",
|
|
"preview": "vite preview",
|
|
"tauri": "tauri",
|
|
"test": "vitest run",
|
|
"test:unit": "vitest run tests/unit",
|
|
"test:integration": "vitest run tests/integration",
|
|
"test:contract": "vitest run tests/contract",
|
|
"test:e2e": "playwright test",
|
|
"test:e2e:prod": "npm run build && playwright test --config playwright.config.prod.ts",
|
|
"test:e2e:native": "playwright test --config playwright.config.native.ts",
|
|
"test:e2e:admin": "playwright test --config playwright.config.admin.ts",
|
|
"test:e2e:ui": "playwright test --ui",
|
|
"test:watch": "vitest",
|
|
"test:coverage": "vitest run --coverage",
|
|
"test:browser": "vitest run --config vitest.config.browser.ts",
|
|
"typecheck": "tsc --noEmit",
|
|
"typecheck:build": "tsc -p tsconfig.build.json --noEmit",
|
|
"typecheck:e2e": "tsc -p tsconfig.e2e.json --noEmit",
|
|
"lint": "oxlint src/ && eslint src/",
|
|
"lint:fix": "eslint src/ --fix",
|
|
"lint:ox": "oxlint src/",
|
|
"knip": "knip",
|
|
"test:mutate": "stryker run",
|
|
"test:mutate:dry": "stryker run --dryRunOnly"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/js": "^10.0.1",
|
|
"@playwright/test": "^1",
|
|
"@stryker-mutator/api": "^10.0.0",
|
|
"@stryker-mutator/core": "^10.0.0",
|
|
"@stryker-mutator/typescript-checker": "^10.0.0",
|
|
"@stryker-mutator/vitest-runner": "^10.0.0",
|
|
"@tauri-apps/cli": "^2",
|
|
"@types/node": "^24.13.3",
|
|
"@vitest/browser-playwright": "^4.1.11",
|
|
"@vitest/coverage-v8": "^4.1.11",
|
|
"eslint": "^10.9.0",
|
|
"fast-check": "^4.9.0",
|
|
"jsdom": "^30.0.1",
|
|
"knip": "^6.32.2",
|
|
"oxlint": "^1.79.0",
|
|
"typescript": "^6.0.3",
|
|
"typescript-eslint": "^8.67.0",
|
|
"vite": "^8.2.2",
|
|
"vitest": "^4.1.11"
|
|
},
|
|
"dependencies": {
|
|
"@jitsi/rnnoise-wasm": "^0.2.1",
|
|
"@tauri-apps/api": "^2.10.1",
|
|
"@tauri-apps/plugin-autostart": "^2",
|
|
"@tauri-apps/plugin-deep-link": "^2",
|
|
"@tauri-apps/plugin-dialog": "^2.7.2",
|
|
"@tauri-apps/plugin-fs": "^2.4.5",
|
|
"@tauri-apps/plugin-http": "^2.5.7",
|
|
"@tauri-apps/plugin-notification": "^2",
|
|
"@tauri-apps/plugin-opener": "^2.5.3",
|
|
"@tauri-apps/plugin-process": "^2.3.1",
|
|
"livekit-client": "^2.22.0"
|
|
},
|
|
"overrides": {
|
|
"qs": "^6.15.3",
|
|
"test-exclude": "^8.0.0"
|
|
}
|
|
}
|