64 lines
3.1 KiB
TypeScript
64 lines
3.1 KiB
TypeScript
// tests/unit/renderer-models-redteam-r2-1.test.ts
|
|
// 렌더러 순수 모델:
|
|
// - 녹음 화면 복원: main 사본과 먼저 도착한 이벤트를 id 로 합친다
|
|
// - 회의 채팅 패널: main 이 기억하는 대화를 표시 메시지로 바꾼다(키 충돌 없음)
|
|
// - 명령어 폼: 저장 거부 사유를 검증 메시지로 바꾼다(빈 프롬프트·길이 초과)
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
import { ErrorCode } from '@d3ro/core/errors'
|
|
import { mergeRestoredItems } from '../../src/renderer/pages/meeting/live-restore'
|
|
import { toPanelMessages, withRestoredHistory } from '../../src/renderer/components/meeting/meeting-chat-history'
|
|
import { commandSaveError } from '../../src/renderer/pages/commands/command-form'
|
|
|
|
describe('mergeRestoredItems', () => {
|
|
it('main 사본을 기준으로, 조회 중 먼저 온 항목은 중복 없이 합치고 시간 순으로 둔다', () => {
|
|
const restored = [
|
|
{ id: 'a', t: 1 },
|
|
{ id: 'b', t: 2 },
|
|
]
|
|
const arrived = [
|
|
{ id: 'b', t: 2 },
|
|
{ id: 'c', t: 3 },
|
|
]
|
|
expect(mergeRestoredItems(restored, arrived, (x) => x.t).map((x) => x.id)).toEqual(['a', 'b', 'c'])
|
|
})
|
|
})
|
|
|
|
describe('meeting chat history', () => {
|
|
it('보관된 턴을 순서 번호 timestamp 로 바꿔 목록 키가 겹치지 않는다', () => {
|
|
const messages = toPanelMessages([
|
|
{ role: 'user', content: 'q1' },
|
|
{ role: 'assistant', content: 'a1' },
|
|
{ role: 'user', content: 'q2' },
|
|
])
|
|
const keys = messages.map((m) => `${m.role}-${m.timestamp}`)
|
|
expect(new Set(keys).size).toBe(3)
|
|
expect(messages.map((m) => m.content)).toEqual(['q1', 'a1', 'q2'])
|
|
})
|
|
|
|
it('조회가 끝나기 전에 보낸 새 메시지는 지우지 않고 뒤에 둔다', () => {
|
|
const merged = withRestoredHistory(
|
|
[{ role: 'user', content: '새 질문', timestamp: 1_700_000_000_000 }],
|
|
[{ role: 'user', content: '이전 질문' }, { role: 'assistant', content: '이전 답' }],
|
|
)
|
|
expect(merged.map((m) => m.content)).toEqual(['이전 질문', '이전 답', '새 질문'])
|
|
})
|
|
})
|
|
|
|
describe('commandSaveError', () => {
|
|
it('빈 프롬프트·길이 초과는 저장 전에 검증 메시지다', () => {
|
|
expect(commandSaveError({ kind: 'draft', draft: { name: 'n', description: '', prompt: ' ' } })).toEqual({
|
|
key: 'mobile.commands.syncError.validation',
|
|
})
|
|
expect(commandSaveError({ kind: 'draft', draft: { name: 'n'.repeat(81), description: '', prompt: 'p' } })).not.toBeNull()
|
|
expect(commandSaveError({ kind: 'draft', draft: { name: 'n', description: '', prompt: 'p' } })).toBeNull()
|
|
})
|
|
|
|
it('main 의 검증 거부는 검증 메시지, 그 밖의 실패는 호출자가 원문을 보여 준다(null)', () => {
|
|
expect(
|
|
commandSaveError({ kind: 'ipc', error: { code: ErrorCode.ConfigWriteFailed, message: 'Failed: Instruction prompt is too long (max 4000 characters)' } }),
|
|
).not.toBeNull()
|
|
expect(commandSaveError({ kind: 'ipc', error: { code: ErrorCode.ConfigInvalidValue, message: 'x' } })).not.toBeNull()
|
|
expect(commandSaveError({ kind: 'ipc', error: { code: ErrorCode.ConfigWriteFailed, message: 'disk full' } })).toBeNull()
|
|
})
|
|
})
|