diff --git a/src/main/browser/cdp-print-to-pdf.test.ts b/src/main/browser/cdp-print-to-pdf.test.ts
index 4ecf8c50b09..abcf76ccf21 100644
--- a/src/main/browser/cdp-print-to-pdf.test.ts
+++ b/src/main/browser/cdp-print-to-pdf.test.ts
@@ -5,46 +5,6 @@ const DEFAULT_MARGIN_INCHES = 1 / 2.54
const TTL_MS = 5 * 60 * 1000
describe('buildPrintToPdfOptions', () => {
- it('returns empty options for empty params', () => {
- expect(buildPrintToPdfOptions({})).toEqual({})
- })
-
- it('maps every well-formed field', () => {
- expect(
- buildPrintToPdfOptions({
- landscape: true,
- displayHeaderFooter: true,
- printBackground: true,
- preferCSSPageSize: true,
- generateTaggedPDF: true,
- generateDocumentOutline: false,
- scale: 1.5,
- paperWidth: 8.5,
- paperHeight: 11,
- marginTop: 0.25,
- marginBottom: 0.5,
- marginLeft: 0.75,
- marginRight: 1,
- pageRanges: '1-2',
- headerTemplate: '',
- footerTemplate: ''
- })
- ).toEqual({
- landscape: true,
- displayHeaderFooter: true,
- printBackground: true,
- preferCSSPageSize: true,
- generateTaggedPDF: true,
- generateDocumentOutline: false,
- scale: 1.5,
- pageSize: { width: 8.5, height: 11 },
- margins: { top: 0.25, bottom: 0.5, left: 0.75, right: 1 },
- pageRanges: '1-2',
- headerTemplate: '',
- footerTemplate: ''
- })
- })
-
it('defaults omitted margin sides to 1cm when any side is set', () => {
expect(buildPrintToPdfOptions({ marginTop: 0.25 }).margins).toEqual({
top: 0.25,
@@ -53,26 +13,6 @@ describe('buildPrintToPdfOptions', () => {
right: DEFAULT_MARGIN_INCHES
})
})
-
- it('drops non-finite and out-of-range numeric options', () => {
- const options = buildPrintToPdfOptions({
- scale: 0,
- paperWidth: Number.POSITIVE_INFINITY,
- paperHeight: 11,
- marginTop: Number.NaN
- })
- expect(options.scale).toBeUndefined()
- expect(options.pageSize).toBeUndefined()
- expect(options.margins).toBeUndefined()
- })
-
- it('requires both paper dimensions for pageSize', () => {
- expect(buildPrintToPdfOptions({ paperWidth: 8.5 }).pageSize).toBeUndefined()
- })
-
- it('ignores wrong-typed options', () => {
- expect(buildPrintToPdfOptions({ landscape: 'yes', pageRanges: 7 })).toEqual({})
- })
})
describe('CdpPdfStreamStore', () => {
@@ -91,11 +31,6 @@ describe('CdpPdfStreamStore', () => {
expect(store.ownsHandle({})).toBe(false)
})
- it('mints distinct handles per stream', () => {
- const store = new CdpPdfStreamStore()
- expect(store.create(Buffer.from('a'))).not.toBe(store.create(Buffer.from('b')))
- })
-
it('reads sequential chunks and reports eof', () => {
const store = new CdpPdfStreamStore()
const handle = store.create(Buffer.from('abcdef'))
@@ -127,28 +62,6 @@ describe('CdpPdfStreamStore', () => {
expect(store.read({ handle, offset: 99 })).toEqual({ data: '', eof: true })
})
- it('returns null for unknown handles', () => {
- const store = new CdpPdfStreamStore()
- expect(store.read({ handle: 'nope' })).toBeNull()
- expect(store.read({})).toBeNull()
- })
-
- it('drops a stream on close', () => {
- const store = new CdpPdfStreamStore()
- const handle = store.create(Buffer.from('abc'))
-
- store.close({ handle })
- expect(store.read({ handle })).toBeNull()
- })
-
- it('drops all streams on clear', () => {
- const store = new CdpPdfStreamStore()
- const handle = store.create(Buffer.from('abc'))
-
- store.clear()
- expect(store.read({ handle })).toBeNull()
- })
-
it('evicts an abandoned stream after the TTL', () => {
vi.useFakeTimers()
const store = new CdpPdfStreamStore()
diff --git a/src/main/github/pr-refresh-error-classification.test.ts b/src/main/github/pr-refresh-error-classification.test.ts
index ef55c96577d..cdda943b600 100644
--- a/src/main/github/pr-refresh-error-classification.test.ts
+++ b/src/main/github/pr-refresh-error-classification.test.ts
@@ -1,72 +1,13 @@
import { describe, expect, it } from 'vitest'
-import {
- classifyPRRefreshError,
- safePRRefreshErrorMessage
-} from './pr-refresh-error-classification'
+import { classifyPRRefreshError } from './pr-refresh-error-classification'
describe('classifyPRRefreshError', () => {
- it('classifies an HTTP 429 as rate_limited even without a rate-limit body', () => {
- expect(classifyPRRefreshError(new Error('HTTP 429 Too Many Requests'))).toBe('rate_limited')
- })
-
- it('classifies secondary rate limit markers as rate_limited, not permission', () => {
- for (const message of [
- 'You have exceeded a secondary rate limit',
- 'abuse detection mechanism triggered',
- 'abuse-rate-limits',
- 'you have triggered an abuse detection mechanism'
- ]) {
- expect(classifyPRRefreshError(new Error(message))).toBe('rate_limited')
- }
- })
-
it('classifies a 403 carrying Retry-After as rate_limited, not permission', () => {
expect(classifyPRRefreshError(new Error('HTTP 403 Forbidden; Retry-After: 60'))).toBe(
'rate_limited'
)
})
- it('classifies the primary breaker language as rate_limited', () => {
- expect(classifyPRRefreshError(new Error('API rate limit exceeded for user'))).toBe(
- 'rate_limited'
- )
- })
-
- it('classifies a plain 403 resource denial as permission', () => {
- expect(
- classifyPRRefreshError(new Error('HTTP 403: Resource not accessible by integration'))
- ).toBe('permission')
- })
-
- it('classifies network failures', () => {
- for (const message of ['ETIMEDOUT', 'could not resolve host github.com', 'network is down']) {
- expect(classifyPRRefreshError(new Error(message))).toBe('network')
- }
- })
-
- it('classifies 404 / could not resolve repository as repo_unavailable', () => {
- expect(classifyPRRefreshError(new Error('HTTP 404 Not Found'))).toBe('repo_unavailable')
- expect(
- classifyPRRefreshError(new Error('Could not resolve to a Repository with the name'))
- ).toBe('repo_unavailable')
- })
-
- it('classifies an ENOENT spawn failure as gh_unavailable', () => {
- const err = Object.assign(new Error('spawn gh ENOENT'), { code: 'ENOENT' })
- expect(classifyPRRefreshError(err)).toBe('gh_unavailable')
- expect(classifyPRRefreshError(new Error("'gh' is not recognized as an internal command"))).toBe(
- 'gh_unavailable'
- )
- })
-
- it('classifies auth failures after rate-limit and permission checks', () => {
- expect(classifyPRRefreshError(new Error('authentication failed: bad credentials'))).toBe('auth')
- })
-
- it('falls back to unknown', () => {
- expect(classifyPRRefreshError(new Error('something unexpected happened'))).toBe('unknown')
- })
-
it('does not classify a message that merely contains "author" as auth', () => {
for (const message of [
'PR author octocat has no write access to the fork',
@@ -91,10 +32,6 @@ describe('classifyPRRefreshError', () => {
).toBe('repo_unavailable')
})
- it('classifies a 401 as auth', () => {
- expect(classifyPRRefreshError(new Error('HTTP 401 Unauthorized'))).toBe('auth')
- })
-
it('classifies from the real runner error shape where the signal is on .stderr', () => {
// The runner stores diagnostics on stderr even when message is only a generic exit error.
const permission = Object.assign(new Error('gh exited with 1.'), {
@@ -119,21 +56,3 @@ describe('classifyPRRefreshError', () => {
expect(classifyPRRefreshError(auth)).toBe('auth')
})
})
-
-describe('safePRRefreshErrorMessage', () => {
- it('returns non-empty copy for every classified type without leaking raw errors', () => {
- for (const type of [
- 'rate_limited',
- 'auth',
- 'network',
- 'permission',
- 'repo_unavailable',
- 'gh_unavailable',
- 'unknown'
- ] as const) {
- const message = safePRRefreshErrorMessage(type)
- expect(message.length).toBeGreaterThan(0)
- expect(message).not.toContain('ENOENT')
- }
- })
-})
diff --git a/src/main/ipc/notification-options-localization.test.ts b/src/main/ipc/notification-options-localization.test.ts
index 891542d368b..2b0b7189446 100644
--- a/src/main/ipc/notification-options-localization.test.ts
+++ b/src/main/ipc/notification-options-localization.test.ts
@@ -43,12 +43,4 @@ describe('buildNotificationOptions localization', () => {
body: 'Un agente de programación terminó de trabajar.'
})
})
-
- it('keeps the English copy for headless and initialized English translators', () => {
- for (const translate of [undefined, translateMain]) {
- expect(buildNotificationOptions(BELL, translate).title).toBe('Bell in feature-x')
- expect(buildNotificationOptions(TOOL, translate).body).toBe('Using Bash: ls {{tool}}')
- expect(buildNotificationOptions(FALLBACK, translate).title).toBe('Task complete in workspace')
- }
- })
})
diff --git a/src/main/ipc/notifications-message-formatting.test.ts b/src/main/ipc/notifications-message-formatting.test.ts
index 42ff0acacea..5d619cc144f 100644
--- a/src/main/ipc/notifications-message-formatting.test.ts
+++ b/src/main/ipc/notifications-message-formatting.test.ts
@@ -3,7 +3,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
getDispatchHandler,
notificationCtorMock,
- notificationShowMock,
resetNotificationDispatchMocks
} from './notifications-test-harness'
@@ -32,106 +31,6 @@ describe('registerNotificationHandlers', () => {
resetNotificationDispatchMocks()
})
- it('delivers a notification when the event is allowed', async () => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- expect(
- await handler(
- {},
- { source: 'agent-task-complete', repoLabel: 'orca', worktreeLabel: 'feat/notis' }
- )
- ).toEqual({ delivered: true })
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: 'Task complete in feat/notis',
- body: 'orca'
- })
- expect(notificationShowMock).toHaveBeenCalledTimes(1)
- })
-
- it('formats agent-task-complete with the agent response when a status snapshot is present', async () => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- expect(
- await handler(
- {},
- {
- source: 'agent-task-complete',
- worktreeId: 'repo::wt1',
- worktreeLabel: 'feat/notis',
- repoLabel: 'orca',
- terminalTitle: '* Claude done',
- agentType: 'codex',
- agentState: 'done',
- agentPrompt: 'Fix rich notification text',
- agentLastAssistantMessage: 'Updated the notification body.'
- }
- )
- ).toEqual({ delivered: true })
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: 'orca / feat/notis - Codex finished',
- body: 'Updated the notification body.'
- })
- })
-
- it.each([true, false, undefined])(
- 'includes the repo name regardless of the legacy multiple-repo flag (%s)',
- async (hasMultipleActiveRepos) => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- expect(
- await handler(
- {},
- {
- source: 'agent-task-complete',
- worktreeId: 'repo::wt1',
- worktreeLabel: 'feat/notis',
- repoLabel: 'orca',
- hasMultipleActiveRepos,
- agentType: 'codex',
- agentState: 'done',
- agentLastAssistantMessage: 'Updated the notification body.'
- }
- )
- ).toEqual({ delivered: true })
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: 'orca / feat/notis - Codex finished',
- body: 'Updated the notification body.'
- })
- }
- )
-
it('keeps a readable body when no assistant response was captured', async () => {
registerNotificationHandlers({
getSettings: () => ({
@@ -167,38 +66,6 @@ describe('registerNotificationHandlers', () => {
})
})
- it.each([
- { agentType: 'opencode2', label: 'OpenCode 2' },
- { agentType: 'copilot', label: 'GitHub Copilot' }
- ])('names $agentType the way the app does', async ({ agentType, label }) => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- await getDispatchHandler()(
- {},
- {
- source: 'agent-task-complete',
- worktreeId: 'repo::wt1',
- worktreeLabel: 'feat/notis',
- agentType,
- agentState: 'done'
- }
- )
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: `feat/notis - ${label} finished`,
- body: `${label} finished.`
- })
- })
-
it('formats blocked and interrupted agent snapshots distinctly', async () => {
registerNotificationHandlers({
getSettings: () => ({
@@ -292,137 +159,4 @@ describe('registerNotificationHandlers', () => {
expect(options.body).not.toContain('\n')
expect(options.body.length).toBeLessThanOrEqual(180)
})
-
- it.each([
- { agentState: 'working', expected: 'feat/notis - Claude working' },
- { agentState: 'blocked', expected: 'feat/notis - Claude needs input' },
- { agentState: 'waiting', expected: 'feat/notis - Claude needs input' },
- { agentState: 'done', expected: 'feat/notis - Claude finished' },
- { agentState: undefined, expected: 'feat/notis - Claude finished' }
- ])('titles agentState $agentState without claiming a false finish', async (scenario) => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- await handler(
- {},
- {
- source: 'agent-task-complete',
- worktreeLabel: 'feat/notis',
- agentType: 'claude',
- ...(scenario.agentState ? { agentState: scenario.agentState } : {}),
- agentLastAssistantMessage: 'Ran the suite.'
- }
- )
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: scenario.expected,
- body: 'Ran the suite.'
- })
- })
-
- it.each([
- { agentTurnOutcome: 'cancellation', word: 'stopped' },
- { agentTurnOutcome: 'failure', word: 'failed' },
- // A turn cut short by anything but the user is a fault, worded as one.
- { agentTurnOutcome: 'interruption', word: 'failed' },
- { agentTurnOutcome: 'unconfirmed', word: 'stopped' },
- { agentTurnOutcome: 'superseded', word: 'stopped' },
- { agentTurnOutcome: 'success', word: 'finished' },
- { agentTurnOutcome: undefined, word: 'finished' }
- ] as const)('words a $agentTurnOutcome finish as $word', async ({ agentTurnOutcome, word }) => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- await handler(
- {},
- {
- source: 'agent-task-complete',
- worktreeLabel: 'feat/notis',
- agentType: 'claude',
- agentState: 'done',
- ...(agentTurnOutcome ? { agentTurnOutcome } : {})
- }
- )
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: `feat/notis - Claude ${word}`,
- body: `Claude ${word}.`
- })
- })
-
- it('counts a success verdict alone as an agent snapshot', async () => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- await handler(
- {},
- { source: 'agent-task-complete', worktreeLabel: 'feat/notis', agentTurnOutcome: 'success' }
- )
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: 'feat/notis - Agent finished',
- body: 'Agent finished.'
- })
- })
-
- it('uses tool context before falling back when no prompt or assistant preview exists', async () => {
- registerNotificationHandlers({
- getSettings: () => ({
- notifications: {
- enabled: true,
- agentTaskComplete: true,
- terminalBell: false,
- suppressWhenFocused: true
- }
- })
- } as never)
-
- const handler = getDispatchHandler()
- expect(
- await handler(
- {},
- {
- source: 'agent-task-complete',
- worktreeId: 'repo::wt1',
- worktreeLabel: 'feat/notis',
- agentType: 'unknown',
- agentState: 'working',
- agentToolName: 'Bash',
- agentToolInput: 'pnpm test'
- }
- )
- ).toEqual({ delivered: true })
-
- expect(notificationCtorMock).toHaveBeenCalledWith({
- title: 'feat/notis - Agent working',
- body: 'Using Bash: pnpm test'
- })
- })
})