d3ro-voice/apps/desktop/tests/main/index-activate-redteam-r3-4.test.ts
Yun Chan ba9ef9741e fix: red-team round 3 hardening across desktop, mobile, core and server
Batch of red-team r3 fixes that were in the working tree before the
2026-09-28 design overhaul, committed as one unit with their tests.

- desktop main: STT timeouts and sidecar, voice recording store, sync
  (credentials, audio, knowledge reindex, push gates), runtime
  provisioner, update policy, AltGr keybindings, voice-command policy,
  dictionary file codec/limits, meeting transcript condensing and a
  local recording ledger so interrupted-session recovery only closes
  meetings this device recorded (a phone's live meeting is left alone).
- mobile: login CSRF via implicit token callbacks rejected, account
  deletion/retention, durable queue retention, knowledge realtime
  without unfiltered DELETE, meeting re-record failure paths, cloud STT
  client, preferences store/resync.
- core: text chunking splits long unbroken transcripts to fit, template
  field policy, dictionary limits, meeting markdown inline handling.
- server: payple webhook policy and cancellation order scope, meeting
  document generation quota, team RPC null-role guard, unified LLM
  quota in-flight accounting, knowledge chunk vector index, meeting
  re-record failure paths (migrations 20260929*).
- ci: portable/runtime feed gates, update-policy schema, Forgejo file
  delete and alias planning.

Four older tests are updated to the new contracts rather than the old
behavior: token-pair auth callbacks are rejected, knowledge realtime no
longer subscribes to DELETE, long transcript lines are split, and
meeting recovery requires the local recording ledger for empty rows.
2026-09-28 20:45:52 +09:00

46 lines
1.8 KiB
TypeScript

// redteam r3-4 회귀: macOS Dock 아이콘 클릭('activate')이 트레이로 숨긴 메인 창을 다시 띄운다.
// 예전엔 'activate' 리스너가 없어 closeToTray(기본 true)로 창을 닫은 뒤 Dock 으로 돌아올 수 없었다.
import { describe, expect, it, vi } from 'vitest'
type Listener = (...args: unknown[]) => void
const state = vi.hoisted(() => ({
appListeners: new Map<string, Listener>(),
showMainWindow: vi.fn(() => null),
}))
vi.mock('electron', () => ({
app: {
on: vi.fn((event: string, listener: Listener) => {
state.appListeners.set(event, listener)
}),
// 부트스트랩은 이 테스트의 관심사가 아니다 — ready 를 오지 않게 둔다
whenReady: vi.fn(() => new Promise<void>(() => undefined)),
setAsDefaultProtocolClient: vi.fn(),
requestSingleInstanceLock: vi.fn(() => true),
disableHardwareAcceleration: vi.fn(),
commandLine: { appendSwitch: vi.fn() },
exit: vi.fn(),
getPath: vi.fn(() => '.'),
},
}))
vi.mock('../../src/main/app-identity', () => ({ applyAppIdentity: vi.fn() }))
vi.mock('../../src/main/bootstrap', () => ({ bootstrap: vi.fn(async () => undefined) }))
vi.mock('../../src/main/lifecycle', () => ({ setupLifecycle: vi.fn() }))
vi.mock('../../src/main/windows/WindowManager', () => ({ showMainWindow: state.showMainWindow }))
vi.mock('../../src/main/services/LoggerService', () => ({
getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
}))
describe("app 'activate' (macOS Dock 클릭)", () => {
it('메인 창을 다시 띄운다', async () => {
await import('../../src/main/index')
const activate = state.appListeners.get('activate')
expect(activate).toBeTypeOf('function')
activate?.()
expect(state.showMainWindow).toHaveBeenCalledTimes(1)
})
})