molecule-mcp-claude-channel/server.test.ts
Hongming Wang 53e4ac329d feat(channel): surface 410 Gone with re-onboard hint instead of HTTP-410 (#2429)
Follow-up to molecule-core#2449 (which taught the platform to return
410 Gone for status='removed'). Without this branch the operator sees
`get_workspace_info failed: HTTP 410 — workspace removed` and has to
guess what to do — exactly the 2026-04-30 silent-fail UX hit on the
hongmingwang tenant.

The new code path:
  1. Detect resp.status === 410 explicitly
  2. Best-effort parse the body for id / removed_at / hint
  3. Throw `Workspace <id> was deleted on the platform at <ts>. <hint>`

The 410-message-formatting is extracted into a pure
`formatRemovedWorkspaceError` helper so it can be unit-tested
without mocking fetch + resolveWatching. Four new bun:test cases:

  - prefers platform-supplied id, removed_at, hint
  - falls back to local workspaceId + default hint when body is empty
  - tolerates null/undefined body (unparseable response)
  - omits ' at <ts>' clause when removed_at is missing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 22:10:00 -07:00

50 lines
1.9 KiB
TypeScript

// Regression tests for getWorkspaceInfo's 410-handling — pinned via
// the formatRemovedWorkspaceError pure helper so the test doesn't
// need to mock fetch + resolveWatching just to read one string.
//
// molecule-core#2429 — without these tests, the "your workspace was
// deleted, re-onboard" message is a 4-line code path that an
// inattentive refactor could collapse back into the generic
// "HTTP 410" error we used to surface.
import { describe, expect, it } from 'bun:test'
import { formatRemovedWorkspaceError } from './server.ts'
describe('formatRemovedWorkspaceError — 410 Gone handling (#2429)', () => {
it('prefers the platform-supplied id, removed_at, and hint when present', () => {
const msg = formatRemovedWorkspaceError('local-fallback-id', {
id: 'real-uuid',
removed_at: '2026-04-30T12:00:00Z',
hint: 'Custom hint from the platform.',
})
expect(msg).toBe(
'Workspace real-uuid was deleted on the platform at 2026-04-30T12:00:00Z. Custom hint from the platform.',
)
})
it('falls back to the local workspaceId + default hint when body is empty', () => {
const msg = formatRemovedWorkspaceError('fallback-uuid', {})
expect(msg).toBe(
'Workspace fallback-uuid was deleted on the platform. Regenerate workspace + token from the canvas → Tokens tab.',
)
})
it('tolerates a null/undefined body (unparseable response)', () => {
expect(formatRemovedWorkspaceError('uuid', null)).toContain(
'Workspace uuid was deleted',
)
expect(formatRemovedWorkspaceError('uuid', undefined)).toContain(
'Regenerate workspace + token',
)
})
it('omits the timestamp clause when removed_at is missing', () => {
const msg = formatRemovedWorkspaceError('uuid', {
id: 'uuid',
hint: 'h',
})
expect(msg).not.toContain(' at ')
expect(msg).toBe('Workspace uuid was deleted on the platform. h')
})
})