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>
54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { describeChatError } from "./error-message";
|
|
|
|
// Identity translator: assert on the raw English key so the tests do not depend
|
|
// on the i18n catalog.
|
|
const t = (key: string) => key;
|
|
|
|
describe("describeChatError", () => {
|
|
it('surfaces a provider "402: ..." stream error verbatim', () => {
|
|
expect(describeChatError("402: Insufficient credits", t)).toBe(
|
|
"402: Insufficient credits",
|
|
);
|
|
});
|
|
|
|
it('does NOT misclassify a body that merely contains "403" (no "statusCode":403)', () => {
|
|
// A provider message mentioning the number 403 must be surfaced verbatim,
|
|
// never folded into the "AI chat is disabled" gating message.
|
|
const msg = "429: rate limited after 403 attempts";
|
|
expect(describeChatError(msg, t)).toBe(msg);
|
|
});
|
|
|
|
it('maps a {"statusCode":403} body to the disabled message', () => {
|
|
const body = '{"statusCode":403,"message":"Forbidden"}';
|
|
expect(describeChatError(body, t)).toBe(
|
|
"AI chat is disabled for this workspace.",
|
|
);
|
|
});
|
|
|
|
it('maps a {"statusCode":503} body to the not-configured message', () => {
|
|
const body = '{"statusCode":503,"message":"Service Unavailable"}';
|
|
expect(describeChatError(body, t)).toBe(
|
|
"The AI provider is not configured. Ask an administrator to set it up.",
|
|
);
|
|
});
|
|
|
|
it('falls back to the generic message for "An error occurred."', () => {
|
|
expect(describeChatError("An error occurred.", t)).toBe(
|
|
"The AI agent could not respond. Please try again.",
|
|
);
|
|
});
|
|
|
|
it('falls back to the generic message for "Internal server error"', () => {
|
|
expect(describeChatError("Internal server error", t)).toBe(
|
|
"The AI agent could not respond. Please try again.",
|
|
);
|
|
});
|
|
|
|
it("falls back to the generic message for empty input", () => {
|
|
expect(describeChatError("", t)).toBe(
|
|
"The AI agent could not respond. Please try again.",
|
|
);
|
|
});
|
|
});
|