feat: complete release preparation, 10+ ad mediation, CI/CD, and docker deployment
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped
This commit is contained in:
parent
5cd1de6859
commit
708e20f747
406 changed files with 42464 additions and 6199 deletions
179
apps/desktop/tests/red/instruction.usecase.test.ts
Normal file
179
apps/desktop/tests/red/instruction.usecase.test.ts
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { ErrorCode } from '@d3ro/core/errors'
|
||||
import { IPC_CHANNELS } from '@d3ro/core/ipc-channels'
|
||||
import { getCustomInstructionService } from '../../src/main/services/CustomInstructionService'
|
||||
import { registerInstructionHandlers } from '../../src/main/ipc/instruction-handlers'
|
||||
import { invokeIpc, useRedHarness } from './harness'
|
||||
import { USER_TEXT } from './fixtures'
|
||||
|
||||
useRedHarness()
|
||||
|
||||
describe('유스케이스: 커스텀 명령어 CRUD / 프리셋 보호 / IPC', () => {
|
||||
it('첫 실행 시 빌트인 5개가 있다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(svc.getAll()).toHaveLength(5)
|
||||
expect(svc.getAll().every((i) => i.isBuiltin)).toBe(true)
|
||||
})
|
||||
|
||||
it('빌트인 번역 명령어를 id 로 연다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(svc.getById('builtin-translate')?.id).toBe('builtin-translate')
|
||||
})
|
||||
|
||||
it('없는 명령어 조회는 null 이다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(svc.getById('nope')).toBeNull()
|
||||
})
|
||||
|
||||
it('사용자 명령어를 추가하면 목록이 6개가 된다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
const created = svc.create({
|
||||
name: '내 명령',
|
||||
description: '설명',
|
||||
prompt: '다음을 고쳐라: {{text}}',
|
||||
icon: 'Edit',
|
||||
})
|
||||
expect(created.isBuiltin).toBe(false)
|
||||
expect(svc.getAll()).toHaveLength(6)
|
||||
})
|
||||
|
||||
it('빈 이름 명령어 추가는 거부된다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(() =>
|
||||
svc.create({ name: ' ', description: 'd', prompt: 'p', icon: 'Edit' }),
|
||||
).toThrow()
|
||||
})
|
||||
|
||||
it('빈 프롬프트 추가는 거부된다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(() =>
|
||||
svc.create({ name: 'n', description: 'd', prompt: '', icon: 'Edit' }),
|
||||
).toThrow()
|
||||
})
|
||||
|
||||
it('사용자 명령어 이름을 수정한다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
const created = svc.create({ name: 'old', description: 'd', prompt: 'p', icon: 'Edit' })
|
||||
const updated = svc.update(created.id, { name: 'new' })
|
||||
expect(updated?.name).toBe('new')
|
||||
})
|
||||
|
||||
it('빌트인은 이름 수정이 적용되지 않고 프롬프트만 바뀐다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
const updated = svc.update('builtin-summarize', { name: '해킹', prompt: '새 프롬프트' })
|
||||
expect(updated?.name).not.toBe('해킹')
|
||||
expect(updated?.prompt).toBe('새 프롬프트')
|
||||
})
|
||||
|
||||
it('없는 명령어 수정은 null 이다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(svc.update('missing', { name: 'x' })).toBeNull()
|
||||
})
|
||||
|
||||
it('사용자 명령어는 삭제된다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
const created = svc.create({ name: 'del', description: 'd', prompt: 'p', icon: 'Edit' })
|
||||
expect(svc.delete(created.id)).toBe(true)
|
||||
expect(svc.getById(created.id)).toBeNull()
|
||||
})
|
||||
|
||||
it('빌트인 삭제는 거부된다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(svc.delete('builtin-translate')).toBe(false)
|
||||
expect(svc.getById('builtin-translate')).not.toBeNull()
|
||||
})
|
||||
|
||||
it('없는 명령어 삭제는 false 이다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
expect(svc.delete('missing')).toBe(false)
|
||||
})
|
||||
|
||||
it('순서를 바꾸면 getAll 순서가 바뀐다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
const ids = svc.getAll().map((i) => i.id).reverse()
|
||||
svc.reorder(ids)
|
||||
expect(svc.getAll().map((i) => i.id)).toEqual(ids)
|
||||
})
|
||||
|
||||
it('resetBuiltins 후 빌트인이 다시 5개다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
svc.update('builtin-translate', { prompt: 'changed' })
|
||||
svc.create({ name: 'keep', description: 'd', prompt: 'p', icon: 'Edit' })
|
||||
svc.resetBuiltins()
|
||||
expect(svc.getById('builtin-translate')?.prompt).not.toBe('changed')
|
||||
expect(svc.getAll().filter((i) => !i.isBuiltin)).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('유니코드 이름/프롬프트가 저장된다', () => {
|
||||
const svc = getCustomInstructionService()
|
||||
svc.initialize()
|
||||
const created = svc.create({
|
||||
name: USER_TEXT.UNICODE,
|
||||
description: USER_TEXT.UNICODE,
|
||||
prompt: USER_TEXT.UNICODE,
|
||||
icon: 'Edit',
|
||||
})
|
||||
expect(svc.getById(created.id)?.name).toBe(USER_TEXT.UNICODE)
|
||||
})
|
||||
|
||||
it('IPC instruction:getAll 은 초기화 후 5개 이상이다', async () => {
|
||||
getCustomInstructionService().initialize()
|
||||
registerInstructionHandlers()
|
||||
const res = await invokeIpc(IPC_CHANNELS.INSTRUCTION.GET_ALL)
|
||||
expect(res.success).toBe(true)
|
||||
if (res.success) expect((res.data as unknown[]).length).toBeGreaterThanOrEqual(5)
|
||||
})
|
||||
|
||||
it('IPC instruction:create 왕복', async () => {
|
||||
getCustomInstructionService().initialize()
|
||||
registerInstructionHandlers()
|
||||
const res = await invokeIpc(IPC_CHANNELS.INSTRUCTION.CREATE, {
|
||||
name: 'ipc',
|
||||
description: 'd',
|
||||
prompt: 'p',
|
||||
})
|
||||
expect(res.success).toBe(true)
|
||||
if (res.success) expect(res.data.name).toBe('ipc')
|
||||
})
|
||||
|
||||
it('IPC instruction:delete 빌트인은 실패한다', async () => {
|
||||
getCustomInstructionService().initialize()
|
||||
registerInstructionHandlers()
|
||||
const res = await invokeIpc(IPC_CHANNELS.INSTRUCTION.DELETE, { id: 'builtin-formal' })
|
||||
expect(res.success).toBe(false)
|
||||
})
|
||||
|
||||
it('IPC instruction:delete 없는 id 는 빌트인 삭제와 다른 코드다', async () => {
|
||||
getCustomInstructionService().initialize()
|
||||
registerInstructionHandlers()
|
||||
const missing = await invokeIpc(IPC_CHANNELS.INSTRUCTION.DELETE, { id: 'missing' })
|
||||
const builtin = await invokeIpc(IPC_CHANNELS.INSTRUCTION.DELETE, { id: 'builtin-explain-code' })
|
||||
expect(missing.success).toBe(false)
|
||||
expect(builtin.success).toBe(false)
|
||||
if (!missing.success && !builtin.success) {
|
||||
expect(missing.error.code).not.toBe(builtin.error.code)
|
||||
}
|
||||
})
|
||||
|
||||
it('IPC instruction:getById 없는 id 는 null 이다', async () => {
|
||||
getCustomInstructionService().initialize()
|
||||
registerInstructionHandlers()
|
||||
const res = await invokeIpc(IPC_CHANNELS.INSTRUCTION.GET_BY_ID, { id: 'missing' })
|
||||
expect(res.success).toBe(true)
|
||||
if (res.success) expect(res.data).toBeNull()
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue