* refactor(settings): read stored preferences with a Valibot schema Each field falls back to its default on its own, so one bad value keeps the rest, as before. Tests pin the behavior; they pass against the previous implementation too. * refactor(mcp): read stored MCP connections with a Valibot schema A connection schema checks the ID, trimmed name, transport, and URL rule; a bearer token is kept only for the connection's own credential. A new test covers the credential check and normalization, and passes against the previous implementation. * refactor(clipboard): read Figma's image batch response with a Valibot schema * refactor(mcp): read tool descriptors with a Valibot schema The descriptor type now follows the schema, and tests cover what a descriptor must contain. * refactor(ai): read stored model settings with Valibot schemas Connections and model profiles are schemas with their defaults and bounds; the thinking-level migration and the checks between connections, models, and role assignments stay as code. Characterization tests written against the previous implementation pin the behavior.
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { describe, expect, test } from 'bun:test'
|
|
|
|
import { DEFAULT_APP_PREFERENCES, parseAppPreferences } from '@/app/settings/preferences/store'
|
|
|
|
describe('parseAppPreferences', () => {
|
|
test('starts from the defaults when nothing usable is stored', () => {
|
|
for (const stored of [undefined, null, 'preferences', [], {}]) {
|
|
expect(parseAppPreferences(stored)).toEqual(DEFAULT_APP_PREFERENCES)
|
|
}
|
|
})
|
|
|
|
test('keeps valid choices and defaults only the fields that are not', () => {
|
|
const preferences = parseAppPreferences({
|
|
appearance: { animations: 'off' },
|
|
chat: { reasoningDisplay: 'sometimes', changePreviewSize: 'large', maxAgentSteps: 'many' },
|
|
editing: { snapping: { geometry: false, objects: 'yes' } },
|
|
rendering: 'tiled'
|
|
})
|
|
expect(preferences.appearance.animations).toBe('off')
|
|
expect(preferences.chat).toEqual({
|
|
...DEFAULT_APP_PREFERENCES.chat,
|
|
changePreviewSize: 'large'
|
|
})
|
|
expect(preferences.editing.snapping).toEqual({
|
|
...DEFAULT_APP_PREFERENCES.editing.snapping,
|
|
geometry: false
|
|
})
|
|
expect(preferences.rendering).toEqual(DEFAULT_APP_PREFERENCES.rendering)
|
|
})
|
|
|
|
test('keeps each disabled design check rule once and drops what is not a rule name', () => {
|
|
const { designCheck } = parseAppPreferences({
|
|
designCheck: { preset: 'strict', disabledRules: ['contrast', 7, 'contrast', 'spacing'] }
|
|
})
|
|
expect(designCheck).toEqual({
|
|
showOnCanvas: true,
|
|
preset: 'strict',
|
|
disabledRules: ['contrast', 'spacing']
|
|
})
|
|
})
|
|
|
|
test('remembers that guided AI setup was finished or skipped', () => {
|
|
expect(parseAppPreferences({ onboarding: { aiSetup: 'done' } }).onboarding.aiSetup).toBe('done')
|
|
expect(parseAppPreferences({ onboarding: { aiSetup: 'later' } }).onboarding.aiSetup).toBe(
|
|
'pending'
|
|
)
|
|
})
|
|
})
|