import { describe, it, expect, mock } from 'bun:test'; mock.module('../../src/services/domain/ModeManager.js', () => ({ ModeManager: { getInstance: () => ({ getActiveMode: () => ({ observation_types: [{ id: 'bugfix' }, { id: 'discovery' }, { id: 'refactor' }], }), }), }, })); import { parseAgentXml } from '../../src/sdk/parser.js'; describe('parseAgentXml — summaries', () => { it('returns invalid when response is plain text (no XML)', () => { const result = parseAgentXml('Some plain text response without any XML tags'); expect(result.valid).toBe(false); }); it('returns invalid when has no sub-tags (false positive — was #1360)', () => { const result = parseAgentXml('done some content here'); expect(result.valid).toBe(false); }); it('returns invalid for bare with only plain text, no sub-tags', () => { const result = parseAgentXml('This session was productive.'); expect(result.valid).toBe(false); }); it('returns valid summary when at least one sub-tag is present', () => { const text = `Fix the bug`; const result = parseAgentXml(text); expect(result.valid).toBe(true); if (result.valid && result.kind === 'summary') { expect(result.data.request).toBe('Fix the bug'); expect(result.data.investigated).toBeNull(); expect(result.data.learned).toBeNull(); } }); it('returns full summary when all fields are present', () => { const text = ` Fix login bug Auth flow and JWT expiry Token was expiring too soon Extended token TTL to 24h Monitor error rates `; const result = parseAgentXml(text); expect(result.valid).toBe(true); if (result.valid && result.kind === 'summary') { expect(result.data.request).toBe('Fix login bug'); expect(result.data.investigated).toBe('Auth flow and JWT expiry'); expect(result.data.learned).toBe('Token was expiring too soon'); expect(result.data.completed).toBe('Extended token TTL to 24h'); expect(result.data.next_steps).toBe('Monitor error rates'); } }); it('treats as a first-class summary with skipped:true', () => { const result = parseAgentXml(''); expect(result.valid).toBe(true); if (result.valid && result.kind === 'summary') { expect(result.data.skipped).toBe(true); expect(result.data.skip_reason).toBe('no work done'); } }); it('does NOT coerce into a summary (former #1633 path deleted)', () => { const result = parseAgentXml('foo'); expect(result.valid).toBe(true); if (result.valid) { expect(result.kind).toBe('observation'); } }); it('prefers over when both present', () => { const text = `obs title summary request`; const result = parseAgentXml(text); expect(result.valid).toBe(true); if (result.valid) { expect(result.kind).toBe('observation'); } }); it('returns invalid for empty input', () => { expect(parseAgentXml('').valid).toBe(false); expect(parseAgentXml(' \n ').valid).toBe(false); }); });