mirror of
https://github.com/stablyai/orca.git
synced 2026-09-24 16:02:41 +00:00
* Add linked issue guidance and ELI5 sections to PR generation prompts Include linked GitHub issues in PR descriptions with Fixes/Refs guidance, and require ELI5 Problem and Solution sections before implementation details. Tests verify linked issue substitution and prompt structure enforcement. * Include linked issue details in PR description generation - Fetch the linked GitHub/GitLab issue title and body so generated PRs reference real issue context instead of just a number - Use provider-specific reference syntax (Fixes/Refs, Closes/Related to, AB#) and label the issue by the active provider - Feed issue title and description into the generation prompt while treating them as untrusted context, never as instructions - Fall back to a cached work-item title when the provider lookup fails, and skip cross-provider issue attachment
90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { loadPullRequestLinkedIssue } from './pull-request-linked-issue'
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
getGitHubIssue: vi.fn(),
|
|
getGitLabIssue: vi.fn()
|
|
}))
|
|
|
|
vi.mock('../github/issues', () => ({ getIssue: mocks.getGitHubIssue }))
|
|
vi.mock('../gitlab/issues', () => ({ getIssue: mocks.getGitLabIssue }))
|
|
|
|
describe('loadPullRequestLinkedIssue', () => {
|
|
beforeEach(() => {
|
|
mocks.getGitHubIssue.mockReset()
|
|
mocks.getGitLabIssue.mockReset()
|
|
})
|
|
|
|
it('loads a GitHub issue title and description', async () => {
|
|
mocks.getGitHubIssue.mockResolvedValue({
|
|
number: 12,
|
|
title: 'Stop phantom polling',
|
|
description: 'Do not stat Linux-only paths on macOS.'
|
|
})
|
|
|
|
await expect(
|
|
loadPullRequestLinkedIssue({
|
|
meta: { linkedIssue: 12 },
|
|
provider: 'github',
|
|
repoPath: '/repo'
|
|
})
|
|
).resolves.toEqual({
|
|
provider: 'github',
|
|
number: 12,
|
|
title: 'Stop phantom polling',
|
|
description: 'Do not stat Linux-only paths on macOS.'
|
|
})
|
|
})
|
|
|
|
it('loads GitLab details without falling back to the GitHub issue', async () => {
|
|
mocks.getGitLabIssue.mockResolvedValue({
|
|
number: 34,
|
|
title: 'Fix runner polling',
|
|
description: 'The runner checks paths that cannot exist.'
|
|
})
|
|
|
|
await expect(
|
|
loadPullRequestLinkedIssue({
|
|
meta: { linkedIssue: 12, linkedGitLabIssue: 34 },
|
|
provider: 'gitlab',
|
|
repoPath: '/repo',
|
|
connectionId: 'ssh-1'
|
|
})
|
|
).resolves.toMatchObject({ provider: 'gitlab', number: 34, title: 'Fix runner polling' })
|
|
expect(mocks.getGitHubIssue).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('uses persisted work-item title when the provider lookup fails', async () => {
|
|
mocks.getGitHubIssue.mockResolvedValue(null)
|
|
|
|
await expect(
|
|
loadPullRequestLinkedIssue({
|
|
meta: {
|
|
linkedIssue: 12,
|
|
linkedWorkItem: {
|
|
provider: 'github',
|
|
type: 'issue',
|
|
number: 12,
|
|
title: 'Cached title',
|
|
url: 'https://github.com/acme/repo/issues/12'
|
|
}
|
|
},
|
|
provider: 'github',
|
|
repoPath: '/repo'
|
|
})
|
|
).resolves.toMatchObject({ title: 'Cached title', description: '' })
|
|
})
|
|
|
|
it('does not attach another provider issue to a Bitbucket PR', async () => {
|
|
await expect(
|
|
loadPullRequestLinkedIssue({
|
|
meta: { linkedIssue: 12, linkedGitLabIssue: 34 },
|
|
provider: 'bitbucket',
|
|
repoPath: '/repo'
|
|
})
|
|
).resolves.toBeNull()
|
|
expect(mocks.getGitHubIssue).not.toHaveBeenCalled()
|
|
expect(mocks.getGitLabIssue).not.toHaveBeenCalled()
|
|
})
|
|
})
|