import type { GiteaComment, GiteaIssue } from './api' import { beforeEach, describe, expect, it, vi } from 'vitest' const getCurrentUser = vi.fn() const listIssuesByFilter = vi.fn() const listIssueCommentsPage = vi.fn() const listAllRepoComments = vi.fn() const getDependencies = vi.fn() const getPullRequest = vi.fn() const postIssueComment = vi.fn() const getIssue = vi.fn() const listIssueComments = vi.fn() vi.mock('./api', () => ({ PAGE_SIZE: 50, getCurrentUser, listIssuesByFilter, listIssueCommentsPage, listAllRepoComments, getDependencies, getPullRequest, postIssueComment, getIssue, listIssueComments, })) function issue(n: number, extra: Partial = {}): GiteaIssue { return { id: n, number: n, title: `Issue ${n}`, state: 'open', comments: 0, created_at: '2020-01-01T00:00:00Z', updated_at: '2020-01-01T00:00:00Z', body: '', html_url: `https://gitea.example/o/r/issues/${n}`, user: { login: 'me' }, assignees: [{ login: 'me' }], labels: [], ...extra, } } function comment(body: string, index: number, id: number): GiteaComment { return { id, body, issue_url: `https://gitea.example/api/v1/repos/o/r/issues/${index}`, created_at: `2020-01-01T00:00:${String(id).padStart(2, '0')}Z`, updated_at: `2020-01-01T00:00:${String(id).padStart(2, '0')}Z`, } } describe('listCommentsUntilColumn', () => { beforeEach(() => { listIssueCommentsPage.mockReset() }) it('commentCount 为 0 时不发请求', async () => { const { listCommentsUntilColumn } = await import('./issueLoader.js') const out = await listCommentsUntilColumn({ host: 'gitea.example', token: 't', owner: 'o', repo: 'r', index: 1, commentCount: 0, }) expect(out).toEqual([]) expect(listIssueCommentsPage).not.toHaveBeenCalled() }) it('先拉末页,没有 column JSON 再往前翻', async () => { const { listCommentsUntilColumn } = await import('./issueLoader.js') listIssueCommentsPage.mockImplementation(async (opts: { page: number }) => { if (opts.page === 2) return [comment('later discussion', 1, 51)] if (opts.page === 1) return [comment(JSON.stringify({ column: 'in-progress' }), 1, 1)] return [] }) const out = await listCommentsUntilColumn({ host: 'gitea.example', token: 't', owner: 'o', repo: 'r', index: 1, commentCount: 51, }) expect(listIssueCommentsPage.mock.calls.map(c => (c[0] as { page: number }).page)).toEqual([2, 1]) expect(out.at(-1)?.body).toContain('later discussion') expect(out[0]?.body).toContain('in-progress') }) }) describe('loadIssues', () => { beforeEach(() => { getCurrentUser.mockReset() listIssuesByFilter.mockReset() listIssueCommentsPage.mockReset() listAllRepoComments.mockReset() getDependencies.mockReset() getPullRequest.mockReset() postIssueComment.mockReset() getCurrentUser.mockResolvedValue({ login: 'me', id: 1 }) listIssuesByFilter.mockResolvedValue([]) listIssueCommentsPage.mockResolvedValue([]) getDependencies.mockResolvedValue([]) postIssueComment.mockResolvedValue({}) }) it('不走整仓评论消防水管,只按工单拉末页', async () => { const { loadIssues } = await import('./issueLoader.js') listIssuesByFilter.mockResolvedValue([issue(7, { comments: 3 })]) listIssueCommentsPage.mockResolvedValue([ comment(JSON.stringify({ column: 'todo' }), 7, 1), ]) const { issues, me } = await loadIssues({ host: 'gitea.example', token: 't', owner: 'o', repo: 'r', scope: 'all', }) expect(me).toBe('me') expect(listAllRepoComments).not.toHaveBeenCalled() expect(listIssueCommentsPage).toHaveBeenCalledWith(expect.objectContaining({ index: 7, page: 1 })) expect(issues).toHaveLength(1) expect(issues[0].column).toBe('todo') }) it('缺 state 评论时用默认列,不代别人发评论', async () => { const { loadIssues } = await import('./issueLoader.js') listIssuesByFilter.mockResolvedValue([issue(3, { comments: 0, user: { login: 'cruldra' } })]) const { issues } = await loadIssues({ host: 'gitea.example', token: 't', owner: 'o', repo: 'r', scope: 'all', }) expect(issues[0].column).toBe('todo') expect(postIssueComment).not.toHaveBeenCalled() }) })