diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index b4b69d6b651..afa721690d0 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -1117,7 +1117,6 @@ jobs: src/main/browser/cookies/browser-google-cookie-clear.electron.test.ts src/main/browser/guest-lifecycle/popups/presentation/popup-origin-chrome.electron.test.ts src/main/browser/guest-lifecycle/navigation/browser-link-materialization.electron.test.ts - src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-native-compatibility.electron.test.ts src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-background-compatibility.electron.test.ts src/main/browser/extensions/api-runtime/browser-extension-api.electron.test.ts diff --git a/config/scripts/ci/unit-selection/dependency-graph/ci-unit-files.mjs b/config/scripts/ci/unit-selection/dependency-graph/ci-unit-files.mjs index 2ff54f9cccc..8613ec9468f 100644 --- a/config/scripts/ci/unit-selection/dependency-graph/ci-unit-files.mjs +++ b/config/scripts/ci/unit-selection/dependency-graph/ci-unit-files.mjs @@ -52,7 +52,6 @@ export const UNIT_EXCLUDE = [ 'src/main/browser/guest-lifecycle/popups/presentation/popup-origin-chrome.electron.test.ts', 'src/main/browser/guest-lifecycle/navigation/browser-link-materialization.electron.test.ts', 'src/main/browser/client-pages/renderer/browser-client-page-renderer-lifecycle.electron.test.ts', - 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts', 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-native-compatibility.electron.test.ts', 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-background-compatibility.electron.test.ts', 'src/main/browser/extensions/api-runtime/browser-extension-api.electron.test.ts', diff --git a/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs b/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs index c3860f770ef..155ed1f6ec5 100644 --- a/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs +++ b/config/scripts/test-runtime/sqlite-admission/vitest-node-runtime-files.mjs @@ -107,7 +107,6 @@ const NODE_RUNTIME_INCLUDE = [ // Playwright's CDP transport needs Node's WebSocket implementation. 'src/main/browser/guest-lifecycle/popups/presentation/popup-origin-chrome.electron.test.ts', 'src/main/browser/guest-lifecycle/navigation/browser-link-materialization.electron.test.ts', - 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts', 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-native-compatibility.electron.test.ts', 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-background-compatibility.electron.test.ts', 'src/main/ai-vault/scanners/devin/session-scanner-devin-db.test.ts', diff --git a/config/scripts/workflow/source-routing/pr-package-test-paths.mjs b/config/scripts/workflow/source-routing/pr-package-test-paths.mjs index 950cc4fa4ba..4062cc63ed3 100644 --- a/config/scripts/workflow/source-routing/pr-package-test-paths.mjs +++ b/config/scripts/workflow/source-routing/pr-package-test-paths.mjs @@ -129,7 +129,6 @@ export const LINUX_PACKAGE_TESTS = [ 'src/main/browser/guest-lifecycle/popups/presentation/popup-origin-chrome.electron.test.ts', 'src/main/browser/guest-lifecycle/navigation/browser-link-materialization.electron.test.ts', 'src/main/browser/client-pages/renderer/browser-client-page-renderer-lifecycle.electron.test.ts', - 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts', 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-native-compatibility.electron.test.ts', 'src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-background-compatibility.electron.test.ts', 'src/main/browser/extensions/api-runtime/browser-extension-api.electron.test.ts', diff --git a/src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts b/src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts deleted file mode 100644 index 506af3c6687..00000000000 --- a/src/main/browser/guest-lifecycle/popups/compatibility/browser-popup-compatibility.electron.test.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { - browser, - closeChildren, - guest, - origin, - receipts, - status -} from './browser-popup-compatibility-cdp-fixture' - -describe('hidden Chromium popup compatibility', () => { - it.each(['local', 'route'])( - 'keeps POST bodies, headers, referrers and cookie jars: %s', - async (name) => { - for (const id of ['post', 'multipart', 'empty']) { - const before = receipts.length - await guest(name).locator(`#${id}`).click() - await expect - .poll(() => receipts.slice(before).find((receipt) => receipt.path === `/${id}`)) - .toMatchObject({ - method: 'POST', - referrer: `${origin}/${name}`, - cookie: `synthetic_session=${name}`, - proxied: name === 'route', - origin, - fetchSite: 'same-origin' - }) - const receipt = receipts.slice(before).find((receipt) => receipt.path === `/${id}`) - expect(receipt?.body).toEqual( - id === 'post' - ? 'code=synthetic%2Bvalue' - : id === 'empty' - ? '' - : expect.stringContaining('synthetic-multipart') - ) - expect(receipt?.contentType).toMatch( - id === 'multipart' - ? /^multipart\/form-data; boundary=/ - : /^application\/x-www-form-urlencoded/ - ) - await closeChildren(guest(name)) - } - } - ) - - it('retains remote no-gesture, stale-gesture, scheme and four-window guards', async () => { - const page = guest('route') - expect(await page.evaluate('window.open("about:blank")===null')).toBe(true) - await page.locator('#invalid').click() - expect(await page.locator('body').getAttribute('data-handle')).toBe('false') - await page.locator('#stale').click() - await expect - .poll(() => page.locator('body').getAttribute('data-handle'), { timeout: 4_000 }) - .toBe('false') - await page.locator('#burst').click() - expect(await page.locator('body').getAttribute('data-handles')).toBe( - '[true,false,false,false,false]' - ) - await closeChildren(page) - for (let index = 0; index < 3; index += 1) { - await page.locator('#blank').click() - } - await page.locator('#shift').evaluate((link) => link.setAttribute('href', '/native-owned')) - await page.locator('#shift').click({ modifiers: ['Shift'] }) - await expect - .poll(() => - browser - ?.contexts() - .flatMap((context) => context.pages()) - .some((candidate) => candidate.url() === `${origin}/native-owned`) - ) - .toBe(true) - const native = browser - ?.contexts() - .flatMap((context) => context.pages()) - .find((candidate) => candidate.url() === `${origin}/native-owned`) - if (!native) { - throw new Error('Missing owned native child') - } - expect(await native.evaluate('window.open("about:blank")===null')).toBe(true) - await page.evaluate('window.livePopup=window.popup') - expect(await page.locator('body').getAttribute('data-handle')).toBe('true') - await page.locator('#blank').click() - expect(await page.locator('body').getAttribute('data-handle')).toBe('false') - expect(status().blocked.length).toBeGreaterThanOrEqual(7) - expect(status().windowsHidden).toBe(true) - expect(await page.evaluate('Notification.requestPermission()')).toBe('denied') - await page.evaluate('console.log("orca-popup-fixture:fence")') - await expect.poll(() => status().routeGranted).toBe(false) - await expect.poll(() => page.evaluate('window.livePopup.closed')).toBe(true) - await expect.poll(() => native.isClosed()).toBe(true) - await page.locator('#blank').click() - expect(await page.locator('body').getAttribute('data-handle')).toBe('false') - await page.evaluate('console.log("orca-popup-fixture:grant")') - await expect.poll(() => status().routeGranted).toBe(true) - await page.locator('#blank').click() - expect(await page.locator('body').getAttribute('data-handle')).toBe('true') - const child = browser - ?.contexts() - .flatMap((context) => context.pages()) - .find((candidate) => candidate.url() === 'about:blank#state') - if (!child) { - throw new Error('Missing child for opener-close check') - } - await page.locator('#shift').click({ modifiers: ['Shift'] }) - await expect - .poll(() => - browser - ?.contexts() - .flatMap((context) => context.pages()) - .some((candidate) => candidate.url() === `${origin}/native-owned`) - ) - .toBe(true) - const regrantedNative = browser - ?.contexts() - .flatMap((context) => context.pages()) - .find((candidate) => candidate.url() === `${origin}/native-owned`) - if (!regrantedNative) { - throw new Error('Missing regranted native child') - } - await page.evaluate('console.log("orca-popup-fixture:close")') - await expect.poll(() => child.isClosed()).toBe(true) - await expect.poll(() => regrantedNative.isClosed()).toBe(true) - }) -}) diff --git a/src/main/native-chat/agent-session-journal/history-import/journal-pi-context-import.spec.ts b/src/main/native-chat/agent-session-journal/history-import/journal-pi-context-import.spec.ts index 2afb48e405f..df7700a83b1 100644 --- a/src/main/native-chat/agent-session-journal/history-import/journal-pi-context-import.spec.ts +++ b/src/main/native-chat/agent-session-journal/history-import/journal-pi-context-import.spec.ts @@ -1,8 +1,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import Database from '../../../sqlite/sync-database' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' import { prepareLegacyTranscriptImport } from './journal-legacy-import' import { createTrackedJournalOpener } from '../store-lifecycle/journal-host-database-test-support' import './journal-pi-active-branch' @@ -40,36 +39,6 @@ export function registerJournalPiContextImportTests(): void { } describe('saved Pi context import', () => { - it('keeps prepared history when temporary database teardown reports an error', async () => { - const close = Database.prototype.close - const closeSpy = vi.spyOn(Database.prototype, 'close').mockImplementation(function ( - this: Database.Database - ) { - close.call(this) - throw new Error('test teardown failure') - }) - const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined) - try { - const items = await prepare([ - { - type: 'message', - id: 'first', - parentId: null, - message: { role: 'user', content: 'hello' } - } - ]) - expect(items).toHaveLength(1) - expect(items[0]?.identity).toMatchObject({ provider: 'legacy', recordId: 'first' }) - expect(warn).toHaveBeenCalledWith( - '[journal-pi-import] temporary database close failed:', - expect.objectContaining({ message: 'test teardown failure' }) - ) - } finally { - closeSpy.mockRestore() - warn.mockRestore() - } - }) - it.each(PI_CONTEXT_FIXTURES)('$name', async (fixture) => { const items = await prepare(fixture.entries, 'version' in fixture ? fixture.version : 3) expect( diff --git a/src/main/plugins/workers/host-api/plugin-host-project-visibility.test.ts b/src/main/plugins/workers/host-api/plugin-host-project-visibility.test.ts deleted file mode 100644 index efda2025aa2..00000000000 --- a/src/main/plugins/workers/host-api/plugin-host-project-visibility.test.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import type { PluginCapabilityKind } from '../../../../shared/plugins/capabilities/plugin-capabilities' -import { PluginRuntimeRpcError } from '../../plugin-runtime-rpc' -import { callPluginHost, pluginHostTestServices } from './__mocks__/plugin-host-services-fixture' -import type { PluginRuntimeRpc } from './plugin-host-runtime-call' - -const REPOS = { - repos: [ - { id: 'r1', displayName: 'App', path: '/src/app', executionHostId: 'local' }, - { id: 'gone', displayName: 'Old', path: '/src/old', executionHostId: 'local', hiddenAt: 5 }, - { id: 'twin', displayName: 'Twin', path: '/l/twin', executionHostId: 'local' }, - { id: 'twin', displayName: 'Twin', path: '/r/twin', connectionId: 'box', hiddenAt: 'x' } - ] -} - -function runtime(answers: Record = {}) { - const all: Record = { - 'repo.list': REPOS, - 'repo.setHidden': (params: { repoHostId: string; hidden: boolean }) => ({ - repo: {}, - hostId: params.repoHostId, - hidden: params.hidden - }), - ...answers - } - return vi.fn(async (method, params) => { - const answer = all[method] - if (answer instanceof Error) { - throw answer - } - return typeof answer === 'function' ? answer(params) : answer - }) -} - -const call = ( - method: string, - params: unknown, - rpc: PluginRuntimeRpc, - granted: PluginCapabilityKind[] = ['workspace:write', 'workspace:read'], - audit = { record: vi.fn().mockResolvedValue(undefined) } -) => callPluginHost({ method, params, granted, services: pluginHostTestServices(rpc), audit }) - -const setHiddenParams = (rpc: ReturnType) => - rpc.mock.calls.filter(([name]) => name === 'repo.setHidden').map(([, params]) => params) - -describe('project.setHidden', () => { - it("hides one host's copy by id, host-qualified even when the plugin names no host", async () => { - const rpc = runtime() - const audit = { record: vi.fn().mockResolvedValue(undefined) } - expect( - await call('project.setHidden', { projectId: 'r1', hidden: true }, rpc, undefined, audit) - ).toEqual({ ok: true, value: { hostId: 'local', hidden: true } }) - expect( - await call('project.setHidden', { projectId: 'twin', hostId: 'ssh:box', hidden: false }, rpc) - ).toEqual({ ok: true, value: { hostId: 'ssh:box', hidden: false } }) - expect(setHiddenParams(rpc)).toEqual([ - { repo: 'id:r1', repoHostId: 'local', hidden: true }, - { repo: 'id:twin', repoHostId: 'ssh:box', hidden: false } - ]) - // Ids only: no project name or path reaches the audit log. - expect(JSON.stringify(audit.record.mock.calls)).toContain('project=r1 host=any hidden=true') - expect(JSON.stringify(audit.record.mock.calls)).not.toContain('/src/app') - }) - - it('refuses an unknown project, or a twin without hostId, before changing anything', async () => { - const rpc = runtime() - const outcomes = await Promise.all([ - call('project.setHidden', { projectId: 'twin', hidden: true }, rpc), - call('project.setHidden', { projectId: 'nope', hidden: true }, rpc), - call('project.setHidden', { projectId: 'r1', hostId: 'ssh:box', hidden: true }, rpc) - ]) - expect(outcomes).toEqual([ - { - ok: false, - code: 'action_failed', - error: 'two hosts have this project; pass the hostId project.list gives' - }, - { ok: false, code: 'action_failed', error: 'no project has this id' }, - { ok: false, code: 'action_failed', error: 'no project has this id' } - ]) - expect(setHiddenParams(rpc)).toEqual([]) - }) - - it('needs workspace:write and takes no name or path selector', async () => { - const rpc = runtime() - expect( - await call('project.setHidden', { projectId: 'r1', hidden: true }, rpc, ['workspace:read']) - ).toMatchObject({ ok: false, code: 'capability_denied' }) - expect( - await call('project.setHidden', { projectId: 'r1', path: '/src/app', hidden: true }, rpc) - ).toMatchObject({ ok: false, code: 'invalid_params' }) - expect(await call('project.setHidden', { projectId: 'r1' }, rpc)).toMatchObject({ - ok: false, - code: 'invalid_params' - }) - expect(rpc).not.toHaveBeenCalled() - }) - - it('maps runtime refusals and a host that drops the field to fixed messages', async () => { - const removed = runtime({ - 'repo.setHidden': new PluginRuntimeRpcError('runtime_error', 'repo_not_found') - }) - const older = runtime({ 'repo.setHidden': { repo: {} } }) - const disconnected = runtime({ - 'repo.setHidden': new PluginRuntimeRpcError('runtime_unavailable', 'ssh box offline at /x') - }) - expect( - await Promise.all( - [removed, older, disconnected].map((rpc) => - call('project.setHidden', { projectId: 'r1', hidden: true }, rpc) - ) - ) - ).toEqual([ - { ok: false, code: 'action_failed', error: 'no project has this id' }, - { - ok: false, - code: 'action_failed', - error: "this project's host could not change it; it may need an Orca update" - }, - { - ok: false, - code: 'unavailable', - error: 'this Orca host cannot run workspace actions now' - } - ]) - }) -}) - -describe('project.list', () => { - it('marks hidden copies, reading a malformed hiddenAt as shown', async () => { - const outcome = await call('project.list', undefined, runtime()) - expect(outcome.ok && outcome.value).toMatchObject({ - projects: [ - { id: 'r1', hostId: 'local', hidden: false }, - { id: 'gone', hostId: 'local', hidden: true }, - { id: 'twin', hostId: 'local', hidden: false }, - { id: 'twin', hostId: 'ssh:box', hidden: false } - ], - truncated: false - }) - }) -})