✨ feat(vscode): 工单状态评论改写成隐藏格式,Gitea 和 YouTrack 共用一套读写

This commit is contained in:
cruldra committed 2026-10-19 07:35:55 +11:00
1 parent fa7b32d205
commit 38ca193434
17 files changed
+588 -660

No files matched your search

+32 -24
View File
@@ -1,32 +1,40 @@
import { describe, expect, it } from 'vitest'
import { findLatestState, parseStateComment, STATE_MARKER } from '../../src/youtrack/stateComment'
import { beforeEach, describe, expect, it, vi } from 'vitest'
describe('youtrack stateComment parsing', () => {
it('parses a marker-prefixed state blob', () => {
const body = `${STATE_MARKER}\n${JSON.stringify({ column: 'in-progress', sessionId: 'abc' })}`
expect(parseStateComment(body)).toEqual({ column: 'in-progress', sessionId: 'abc' })
const listComments = vi.fn()
const addComment = vi.fn()
vi.mock('../../src/youtrack/api', () => ({ listComments, addComment }))
const auth = { baseUrl: 'https://yt.example', token: 't' }
describe('youtrack 状态评论', () => {
beforeEach(() => {
listComments.mockReset()
addComment.mockReset()
})
it('tolerates a bare JSON blob written without the marker', () => {
expect(parseStateComment(JSON.stringify({ column: 'done' }))).toEqual({ column: 'done' })
})
it('rejects JSON objects without any known state field (customer replies)', () => {
expect(parseStateComment(JSON.stringify({ hello: 'world' }))).toBeNull()
expect(parseStateComment('just a plain comment')).toBeNull()
expect(parseStateComment('')).toBeNull()
})
it('returns the latest state comment, skipping trailing non-state comments', () => {
const comments = [
{ id: '1', text: `${STATE_MARKER}\n${JSON.stringify({ column: 'todo' })}` },
{ id: '2', text: `${STATE_MARKER}\n${JSON.stringify({ column: 'in-progress', branch: 'feat/x' })}` },
it('读到旧标记格式写的状态,跳过客户后来的回复', async () => {
const { readStateComment } = await import('../../src/youtrack/stateComment.js')
listComments.mockResolvedValue([
{ id: '1', text: '<!--spx-state-->\n{"column":"todo"}' },
{ id: '2', text: '<!--spx-state-->\n{"column":"in-progress","branch":"feat/x"}' },
{ id: '3', text: '客户后续补充:还是不行' },
]
expect(findLatestState(comments)).toEqual({ column: 'in-progress', branch: 'feat/x' })
])
expect(await readStateComment(auth, 'LXF-1')).toEqual({ column: 'in-progress', branch: 'feat/x' })
})
it('returns null when no state comment exists', () => {
expect(findLatestState([{ id: '1', text: 'hi' }, { id: '2', text: 'thanks' }])).toBeNull()
it('合并后用隐藏格式写回', async () => {
const { mergeStateComment } = await import('../../src/youtrack/stateComment.js')
const { serializeStateComment } = await import('../../src/issues/stateComment.js')
const comments = [{ id: '1', text: '{"column":"todo"}' }]
listComments.mockImplementation(async () => [...comments])
addComment.mockImplementation(async (_auth: unknown, _id: string, text: string) => {
comments.push({ id: String(comments.length + 1), text })
})
await mergeStateComment(auth, 'LXF-1', { branch: 'feat/y' })
expect(addComment).toHaveBeenCalledOnce()
expect(addComment).toHaveBeenCalledWith(auth, 'LXF-1', serializeStateComment({ column: 'todo', branch: 'feat/y' }))
})
})