fix(desktop): map behind: -1 to null instead of clamping the sentinel to 0
The backend update-check endpoint answers behind: -1
(source_check.UPDATE_AVAILABLE_NO_COUNT) when the checkout is behind but
the count can't be computed — a shallow clone without a merge-base or an
unusable GitHub compare. mapBackendCheck clamped it to 0, making that
state byte-identical to the genuinely-up-to-date answer while
update_available still pitched the install, so every behind-based branch
disagreed with the overlay on the same screen and the changelog rendered
"what changed" over zero rows.
DesktopUpdateStatus already types this state as null ("never render it
as a literal number"), so pass the sentinel through as null. The
check-failed predicate is unchanged: it still keys on behind === null
with can_apply, which -1 correctly does not trigger (the check did run).
Also updates the pre-existing updates.test.ts expectation that encoded
the old clamp, and pins the sentinel in updates-backend-check.test.ts.
This commit is contained in:
committed by
brooklyn!
parent
31a68e9235
commit
69ccfa69e4
@@ -47,12 +47,25 @@ describe('mapBackendCheck', () => {
|
||||
expect(status.targetSha).toBe('backend:9.9.9')
|
||||
})
|
||||
|
||||
it('maps the "behind but uncountable" sentinel to behind: null, not 0', () => {
|
||||
// The producer answers behind: -1 (source_check.UPDATE_AVAILABLE_NO_COUNT)
|
||||
// when the checkout is behind but the count can't be computed (shallow
|
||||
// clone without a merge-base, unusable compare API). DesktopUpdateStatus
|
||||
// types that state as null — "never render it as a literal number" — so
|
||||
// clamping -1 to 0 made it byte-identical to the up-to-date answer while
|
||||
// updateAvailable still pitched the install.
|
||||
const status = mapBackendCheck(response({ behind: -1, update_available: true }))
|
||||
|
||||
expect(status.error).toBeUndefined()
|
||||
expect(status.behind).toBeNull()
|
||||
expect(status.updateAvailable).toBe(true)
|
||||
expect(status.targetSha).toBe('backend:9.9.9')
|
||||
})
|
||||
|
||||
it('leaves a backend that cannot self-update to the unsupported branch', () => {
|
||||
// pip/nix and managed runtimes also answer `behind: null`, but `can_apply: false` renders
|
||||
// the "not available" copy first — those must not be turned into failures.
|
||||
const status = mapBackendCheck(
|
||||
response({ can_apply: false, behind: null, message: 'pip install -U hermes-agent' })
|
||||
)
|
||||
const status = mapBackendCheck(response({ can_apply: false, behind: null, message: 'pip install -U hermes-agent' }))
|
||||
|
||||
expect(status.supported).toBe(false)
|
||||
expect(status.error).toBeUndefined()
|
||||
|
||||
@@ -438,7 +438,9 @@ describe('checkBackendUpdates', () => {
|
||||
|
||||
const result = await checkBackendUpdates()
|
||||
|
||||
expect(result?.behind).toBe(0)
|
||||
// behind: -1 is the producer's "update available, count unknown" sentinel;
|
||||
// DesktopUpdateStatus carries it as null, never a literal number.
|
||||
expect(result?.behind).toBeNull()
|
||||
expect(result?.updateAvailable).toBe(true)
|
||||
expect(result?.targetSha).toBe('backend:0.16.0')
|
||||
})
|
||||
|
||||
@@ -489,7 +489,13 @@ function isRemoteMode(): boolean {
|
||||
}
|
||||
|
||||
export function mapBackendCheck(res: BackendUpdateCheckResponse): DesktopUpdateStatus {
|
||||
const behind = res.behind ?? 0
|
||||
// The producer's contract (web_routers/actions.py): behind is 0 = up to
|
||||
// date, -1 = update available but the count is unknown (shallow clone
|
||||
// without a merge-base, unusable GitHub compare), null = the check could
|
||||
// not run at all. DesktopUpdateStatus types "unknown count" as null —
|
||||
// "never render it as a literal number" — so pass that through instead of
|
||||
// clamping the sentinel to a byte-identical copy of "up to date".
|
||||
const behind = res.behind === undefined ? 0 : res.behind
|
||||
|
||||
// `behind: null` from a supported (git) backend is the endpoint's "the check
|
||||
// could not run" answer (GitHub unreachable, rate limited, offline) and
|
||||
@@ -507,7 +513,7 @@ export function mapBackendCheck(res: BackendUpdateCheckResponse): DesktopUpdateS
|
||||
error: checkFailed ? 'check-failed' : undefined,
|
||||
message: res.message ?? undefined,
|
||||
updateAvailable: res.update_available,
|
||||
behind: behind > 0 ? behind : 0,
|
||||
behind: behind === null || behind < 0 ? null : behind,
|
||||
currentVersion: res.current_version,
|
||||
targetSha: res.update_available ? `backend:${res.current_version}` : undefined,
|
||||
commits: res.commits,
|
||||
|
||||
Reference in New Issue
Block a user