test: cover features since 053a9c0d + repair test tooling #49

Merged
Ghost merged 2 commits from test/feature-coverage into develop 2026-06-21 00:20:16 +03:00

Что это

Тесты для всех основных фич gitmost, добавленных с коммита 053a9c0d (AI-чат, AI-роли, публичный share-ассистент, MCP per-user auth, HTML-embed, page-templates/embed, realtime-дерево, expand/collapse, AI-settings UI), плюс починка тест-инструментария, без которой часть покрытия была фиктивной.

Итог: +~330 тестов, все зелёные — server (Jest) 587, client (Vitest) 185, editor-ext (Vitest) 56, packages/mcp (node:test) 247. Новых падений нет.

Починка тест-инструментария (предусловие)

  • FIX-0 — 3 спека page-templates (page-template-access, page-template-lookup, transclusion-unsync-html-embed) не компилировались (TS2554: конструктор TransclusionService стал 11-аргументным). Покрытие контроля доступа / утечки контента / strip htmlEmbed на unsync было фиктивным — теперь спеки исполняются.
  • BUILD-0 — серверные тесты импортируют @docmost/editor-ext через dist/; добавлен pretest-хук, собирающий пакет (устаревший dist не содержал экспортов HtmlEmbed/PageEmbedTS2305).
  • INFRA-0 — jest не резолвил .tsx email-шаблоны (@docmost/transactional/emails/*): добавлен tsx в moduleFileExtensions, transform-regex расширен до (t|j)sx?.

Рефакторы (поведение сохранено, подтверждено code-review)

Извлечение чистых ядер ради дешёвых unit-тестов:

  • server: resolveShareAssistantRequest + uiMessageTextLength (public-share controller), decideBasicGate + mapAuthResultToResponse (mcp), buildErrorAssistantRecord (ai-chat), экспорт jsonbObject (roles).
  • client: render-raw-html + shouldExecute/canEdit, decide-embed-state, page-embed picker utils, tree-socket reducers, openBranches/closeIds, isEndpointConfigured/resolveKeyField. buildTreeWithChildren теперь трактует orphan (обрезанного правами родителя) как корень, а не падает.

Покрытые классы дефектов (примеры)

  • public-share: порядок воронки и cost-cap ДО hijack (429 раньше стрима), fail-closed на нерезолвимой странице, 404 на restricted-потомке.
  • mcp: SSO/MFA-гейт (реальная логика, а не заглушка), маппинг 401/403/500 без утечки заголовков/пароля.
  • html-embed: strip глубоко вложенного embed; контракт — прямой <div data-type="htmlEmbed"> детектируется и снимается (bypass нет).
  • transclusion: AND-порядок space-visibility + page-permission (анти-leak), delete-ветка ссылок, cross-workspace bulk.
  • realtime-дерево: идемпотентность reducer-арм, fallback при незагруженном родителе (анти-stale-node), партиционирование move/delete для restricted.

Отложено (нужен тестовый Postgres / HTTP-харнес; помечено в спеках)

repo-уровневые DB-интеграции (изоляция по workspace, jsonb-merge настроек) и E2E про XFF-обход публичного ассистента. Предсуществующие падения DI / lib0-ESM сьютов не трогались — вне scope.

🤖 Generated with Claude Code

## Что это Тесты для всех основных фич gitmost, добавленных **с коммита `053a9c0d`** (AI-чат, AI-роли, публичный share-ассистент, MCP per-user auth, HTML-embed, page-templates/embed, realtime-дерево, expand/collapse, AI-settings UI), плюс починка тест-инструментария, без которой часть покрытия была фиктивной. Итог: **+~330 тестов**, все зелёные — server (Jest) **587**, client (Vitest) **185**, editor-ext (Vitest) **56**, packages/mcp (node:test) **247**. Новых падений нет. ## Починка тест-инструментария (предусловие) - **FIX-0** — 3 спека page-templates (`page-template-access`, `page-template-lookup`, `transclusion-unsync-html-embed`) **не компилировались** (`TS2554`: конструктор `TransclusionService` стал 11-аргументным). Покрытие контроля доступа / утечки контента / strip htmlEmbed на unsync было фиктивным — теперь спеки исполняются. - **BUILD-0** — серверные тесты импортируют `@docmost/editor-ext` через `dist/`; добавлен `pretest`-хук, собирающий пакет (устаревший dist не содержал экспортов `HtmlEmbed`/`PageEmbed` → `TS2305`). - **INFRA-0** — jest не резолвил `.tsx` email-шаблоны (`@docmost/transactional/emails/*`): добавлен `tsx` в `moduleFileExtensions`, transform-regex расширен до `(t|j)sx?`. ## Рефакторы (поведение сохранено, подтверждено code-review) Извлечение чистых ядер ради дешёвых unit-тестов: - **server**: `resolveShareAssistantRequest` + `uiMessageTextLength` (public-share controller), `decideBasicGate` + `mapAuthResultToResponse` (mcp), `buildErrorAssistantRecord` (ai-chat), экспорт `jsonbObject` (roles). - **client**: `render-raw-html` + `shouldExecute`/`canEdit`, `decide-embed-state`, page-embed picker utils, tree-socket reducers, `openBranches`/`closeIds`, `isEndpointConfigured`/`resolveKeyField`. `buildTreeWithChildren` теперь трактует orphan (обрезанного правами родителя) как корень, а не падает. ## Покрытые классы дефектов (примеры) - **public-share**: порядок воронки и cost-cap **ДО** hijack (429 раньше стрима), fail-closed на нерезолвимой странице, 404 на restricted-потомке. - **mcp**: SSO/MFA-гейт (реальная логика, а не заглушка), маппинг 401/403/500 без утечки заголовков/пароля. - **html-embed**: strip глубоко вложенного embed; контракт — прямой `<div data-type="htmlEmbed">` детектируется и снимается (bypass нет). - **transclusion**: AND-порядок space-visibility + page-permission (анти-leak), delete-ветка ссылок, cross-workspace bulk. - **realtime-дерево**: идемпотентность reducer-арм, fallback при незагруженном родителе (анти-stale-node), партиционирование move/delete для restricted. ## Отложено (нужен тестовый Postgres / HTTP-харнес; помечено в спеках) repo-уровневые DB-интеграции (изоляция по workspace, jsonb-merge настроек) и E2E про XFF-обход публичного ассистента. Предсуществующие падения DI / lib0-ESM сьютов не трогались — вне scope. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Ghost added 1 commit 2026-06-20 23:45:40 +03:00
Add ~330 tests across server (Jest), client (Vitest), editor-ext (Vitest)
and packages/mcp (node:test) for the gitmost features added since
053a9c0d: AI chat, AI agent roles, public-share assistant, MCP per-user
auth, HTML embed, page templates/embed, realtime tree, tree
expand/collapse, and the AI-settings UI.

Test-tooling fixes (prerequisite, were silently hiding coverage):
- Repair 3 page-template specs broken by the 11-arg TransclusionService
  constructor; they never compiled, so template access-control / content
  -leak / unsync-strip coverage was fictitious.
- Build @docmost/editor-ext before server tests via a `pretest` hook;
  the stale dist omitted the new HtmlEmbed/PageEmbed exports (TS2305).
- Let jest resolve the .tsx email templates: add `tsx` to
  moduleFileExtensions and widen the ts-jest transform to (t|j)sx?.

Behaviour-preserving "extract pure core" refactors that the tests drive:
- server: resolveShareAssistantRequest + uiMessageTextLength
  (public-share controller), decideBasicGate + mapAuthResultToResponse
  (mcp), buildErrorAssistantRecord (ai-chat), jsonbObject export (roles).
- client: render-raw-html + shouldExecute/canEdit, decide-embed-state,
  page-embed picker utils, tree-socket reducers, open/close branch maps,
  isEndpointConfigured/resolveKeyField; buildTreeWithChildren now treats
  a permission-trimmed orphan as a root instead of crashing.

Deferred (need a test DB or HTTP harness, documented in the specs):
repo-level Postgres integration tests and the public-share XFF E2E.
Pre-existing DI/lib0-ESM suite failures are untouched and out of scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vvzvlad added 1 commit 2026-06-21 00:19:52 +03:00
Captures what PR #49 intentionally left out: DB-integration tests (need a
test Postgres), the public-share XFF e2e + real-Redis Lua check (need an
HTTP/Redis harness), the full AiChatService.stream integration (R1-stream
seam), and the related non-test findings (no server-side model allow-list,
unreferenced restriction-cache invalidation, client-only embed recursion
cap, missing cycle guard, and the pre-existing jest DI/lib0-ESM debt).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ghost merged commit 4348608ee4 into develop 2026-06-21 00:20:16 +03:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#49