import { describe, expect, test } from 'vitest'; import { TypeCompiler } from '@sinclair/typebox/compiler'; import { Value } from '@sinclair/typebox/value'; import { Type } from '@sinclair/typebox'; import { OB11MessageDataSchema, OB11MessageSchema, OB11PostSendMsgSchema } from '../snowcat-onebot/types/message'; import { OB11MessageSchema as OB11ActionMessageSchema } from '../snowcat-onebot/action/schemas'; import { OneBotConfigSchema, loadConfig as loadOneBotConfig, OneBotConfig } from '../snowcat-onebot/config'; import { SnowCatConfigSchema } from '../snowcat-core/helper/config'; describe('SnowCat Schemas Compilation', () => { test('should compile OB11MessageDataSchema without duplicate id error', () => { expect(() => TypeCompiler.Compile(OB11MessageDataSchema)).not.toThrow(); }); test('should compile OB11MessageSchema without duplicate id error', () => { expect(() => TypeCompiler.Compile(OB11MessageSchema)).not.toThrow(); }); test('should compile OB11ActionMessageSchema without duplicate id error', () => { expect(() => TypeCompiler.Compile(OB11ActionMessageSchema)).not.toThrow(); }); test('should compile OB11PostSendMsgSchema without error', () => { expect(() => TypeCompiler.Compile(OB11PostSendMsgSchema)).not.toThrow(); }); test('should compile QuickAction hybrid schema without error', () => { const QASchema = Type.Object({ message: OB11PostSendMsgSchema, quick_action: OB11ActionMessageSchema, }); expect(() => TypeCompiler.Compile(QASchema)).not.toThrow(); }); }); describe('SnowCat Schemas Validation & Coercion', () => { test('should coerce numeric user_id to string in OB11PostSendMsgSchema', () => { const payload = { message_type: 'private', user_id: 123456, message: [{ type: 'text', data: { text: 'hello' } }], }; let data: unknown = structuredClone(payload); data = Value.Parse(OB11PostSendMsgSchema, data); const compiler = TypeCompiler.Compile(OB11PostSendMsgSchema); expect(compiler.Check(data)).toBe(true); expect((data as Record)['user_id']).toBe('123456'); }); test('should validate complex mixed messages correctly', () => { const payload = { message_type: 'group', group_id: '654321', message: 'this is a string message', }; let data: unknown = structuredClone(payload); data = Value.Parse(OB11PostSendMsgSchema, data); const compiler = TypeCompiler.Compile(OB11PostSendMsgSchema); expect(compiler.Check(data)).toBe(true); }); }); describe('SnowCat Configuration Loaders', () => { test('OneBotConfig schemas should compile', () => { expect(() => TypeCompiler.Compile(OneBotConfigSchema)).not.toThrow(); }); test('OneBotConfig should load and apply defaults correctly', () => { const partialConfig: Partial = { network: { httpServers: [{ port: 3000, enable: true, name: 'test', host: '127.0.0.1', enableCors: true, enableWebsocket: false, messagePostFormat: 'array', token: '', debug: false, }], httpSseServers: [], httpClients: [], websocketServers: [], websocketClients: [], plugins: [], }, }; const loaded = loadOneBotConfig(partialConfig); expect(loaded.network.httpServers[0]?.host).toBe('127.0.0.1'); expect(loaded.network.httpServers[0]?.enableCors).toBe(true); expect(loaded.musicSignUrl).toBe(''); }); test('OneBotConfig websocketClients should apply verifyCertificate default', () => { const partialConfig: Partial = { network: { httpServers: [], httpSseServers: [], httpClients: [], websocketServers: [], websocketClients: [{ name: 'test-ws-client', enable: true, url: 'wss://example.com', messagePostFormat: 'array', reportSelfMessage: false, reconnectInterval: 5000, token: '', debug: false, heartInterval: 30000, }], plugins: [], }, }; const loaded = loadOneBotConfig(partialConfig); expect(loaded.network.websocketClients[0]?.verifyCertificate).toBe(true); }); test('OneBotConfig websocketClients should preserve explicit verifyCertificate false', () => { const partialConfig: Partial = { network: { httpServers: [], httpSseServers: [], httpClients: [], websocketServers: [], websocketClients: [{ name: 'test-ws-client', enable: true, url: 'wss://example.com', messagePostFormat: 'array', reportSelfMessage: false, reconnectInterval: 5000, token: '', debug: false, heartInterval: 30000, verifyCertificate: false, }], plugins: [], }, }; const loaded = loadOneBotConfig(partialConfig); expect(loaded.network.websocketClients[0]?.verifyCertificate).toBe(false); }); test('NapcatConfig should compile and apply defaults', () => { let compiled: ReturnType | undefined; expect(() => { compiled = TypeCompiler.Compile(SnowCatConfigSchema); }).not.toThrow(); let data: unknown = {}; data = Value.Parse(SnowCatConfigSchema, data); expect(compiled?.Check(data)).toBe(true); const resolved = data as Record; expect(resolved['consoleLog']).toBe(true); expect(resolved['consoleLogLevel']).toBe('info'); }); });