Files
orca/src/main/git/status-upstream-ref.test.ts
T
Brennan Benson de64337c26 fix(worktree-watcher): refresh status after external pushes (#12361)
* fix(worktree-watcher): surface external push -u through the git-common watch

An external-shell 'git push -u' writes only the common .git/config (plus
refs/remotes/<remote>/<branch>), both invisible to the git-common event
filter, so the Checks panel stayed on 'No upstream configured' until the
renderer safety poll. Classify the common config and remote-tracking refs
as status-tier signals, poll config alongside the other primary-checkout
metadata files, and keep FETCH_HEAD/reflog/ref-lock churn ignored.

* fix(worktree-watcher): refresh after subsequent pushes
2026-08-05 11:26:13 -07:00

123 lines
3.5 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import { resolveGitStatusUpstreamRef } from './status-upstream-ref'
const signal = (): AbortSignal => new AbortController().signal
describe('resolveGitStatusUpstreamRef', () => {
it('preserves the exact namespace for a slash-containing remote name', async () => {
const execGit = vi.fn().mockResolvedValue({
stdout:
'refs/heads/feature/main\0refs/remotes/team/fork/feature/main\0team/fork/feature/main\n'
})
await expect(
resolveGitStatusUpstreamRef(
execGit,
'/repo',
'refs/heads/feature/main',
'team/fork/feature/main',
signal()
)
).resolves.toBe('refs/remotes/team/fork/feature/main')
expect(execGit).toHaveBeenCalledWith(
[
'for-each-ref',
'--format=%(refname)%00%(upstream)%00%(upstream:short)',
'--count=1',
'refs/heads/feature/main'
],
'/repo',
expect.any(AbortSignal)
)
})
it('returns a slash-named local upstream for the binding validator to reject', async () => {
const execGit = vi.fn().mockResolvedValue({
stdout: 'refs/heads/feature/topic\0refs/heads/feature/base\0feature/base\n'
})
await expect(
resolveGitStatusUpstreamRef(
execGit,
'/repo',
'refs/heads/feature/topic',
'feature/base',
signal()
)
).resolves.toBe('refs/heads/feature/base')
})
it('returns a missing custom refspec destination from branch configuration', async () => {
const execGit = vi.fn().mockResolvedValue({
stdout: 'refs/heads/feature/main\0refs/custom/origin/main\0custom/origin/main\n'
})
await expect(
resolveGitStatusUpstreamRef(
execGit,
'/repo',
'refs/heads/feature/main',
'custom/origin/main',
signal()
)
).resolves.toBe('refs/custom/origin/main')
expect(execGit).toHaveBeenCalledOnce()
})
it('resolves an accepted effective upstream override explicitly', async () => {
const execGit = vi
.fn()
.mockResolvedValueOnce({
stdout: 'refs/heads/feature/prompts\0refs/remotes/origin/main\0origin/main\n'
})
.mockResolvedValueOnce({
stdout: '--end-of-options\nrefs/remotes/origin/feature/prompts\n'
})
await expect(
resolveGitStatusUpstreamRef(
execGit,
'/repo',
'refs/heads/feature/prompts',
'origin/feature/prompts',
signal()
)
).resolves.toBe('refs/remotes/origin/feature/prompts')
expect(execGit).toHaveBeenNthCalledWith(
2,
['rev-parse', '--symbolic-full-name', '--end-of-options', 'origin/feature/prompts'],
'/repo',
expect.any(AbortSignal)
)
})
it('fails safe when an effective override is ambiguous', async () => {
const execGit = vi
.fn()
.mockResolvedValueOnce({
stdout: 'refs/heads/feature/main\0refs/remotes/origin/main\0origin/main\n'
})
.mockResolvedValueOnce({
stdout: 'refs/heads/origin/feature/main\nrefs/remotes/origin/feature/main\n'
})
await expect(
resolveGitStatusUpstreamRef(
execGit,
'/repo',
'refs/heads/feature/main',
'origin/feature/main',
signal()
)
).resolves.toBeUndefined()
})
it('rejects a stale status whose accepted branch no longer exists', async () => {
const execGit = vi.fn().mockResolvedValue({ stdout: '' })
await expect(
resolveGitStatusUpstreamRef(execGit, '/repo', 'refs/heads/old', 'origin/old', signal())
).resolves.toBeUndefined()
})
})