Files
inkling/tests/unit/SettingsService.test.ts
altair823 de895b8fec feat(settings): SettingsService — JSON 영속화 + zod 검증 (v0.2.3.1)
- `<profileDir>/settings.json` atomic write (temp + rename)
- 손상 JSON / 파일 없음 → 빈 객체 fallback (no throw)
- in-memory cache (load 1회 file read)
- zod .strict() schema for ollama { endpoint: URL, model: string }
- 단위 +6 cases

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 23:23:32 +09:00

58 lines
2.2 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { SettingsService } from '@main/services/SettingsService.js';
describe('SettingsService', () => {
let dir: string;
let svc: SettingsService;
beforeEach(() => {
dir = mkdtempSync(join(tmpdir(), 'inkling-settings-'));
svc = new SettingsService(dir);
});
afterEach(() => { rmSync(dir, { recursive: true, force: true }); });
it('load() returns empty object when file does not exist', async () => {
const s = await svc.load();
expect(s).toEqual({});
});
it('load() returns empty object on corrupted JSON (no throw)', async () => {
writeFileSync(join(dir, 'settings.json'), '{ this is not json');
const s = await svc.load();
expect(s).toEqual({});
});
it('load() caches result — second call does not re-read file', async () => {
await svc.setOllama({ endpoint: 'http://localhost:11434', model: 'gemma4:e4b' });
const before = await svc.load();
// 외부에서 파일 변경
writeFileSync(join(dir, 'settings.json'), JSON.stringify({ ollama: { endpoint: 'http://lan:11434', model: 'gemma4:26b' } }));
const after = await svc.load();
// 캐시 적용 — 파일 변경 무시
expect(after).toEqual(before);
});
it('setOllama() throws on non-URL endpoint', async () => {
await expect(
svc.setOllama({ endpoint: 'not-a-url', model: 'gemma4:e4b' })
).rejects.toThrow();
});
it('setOllama() persists to disk with valid JSON', async () => {
await svc.setOllama({ endpoint: 'http://localhost:11435', model: 'gemma4:e4b' });
const raw = readFileSync(join(dir, 'settings.json'), 'utf8');
const parsed = JSON.parse(raw);
expect(parsed.ollama.endpoint).toBe('http://localhost:11435');
expect(parsed.ollama.model).toBe('gemma4:e4b');
});
it('setOllama() atomic write — tmp file does not remain', async () => {
await svc.setOllama({ endpoint: 'http://localhost:11434', model: 'gemma4:e4b' });
expect(existsSync(join(dir, 'settings.json.tmp'))).toBe(false);
expect(existsSync(join(dir, 'settings.json'))).toBe(true);
});
});