/** * Unit Tests — skill-db.js * Tests core CRUD, search, favorites, version history */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import fs from 'fs'; describe('skill-db', () => { let skillDb; const TEST_DB_PATH = '/tmp/test-skills-db.sqlite'; const TEST_SKILL = { skillName: 'test_unit_skill', description: 'A test skill for unit testing', domain: 'testing', scope: 'unit', keywords: ['test', 'unit'], status: 'enable', version: '1.0.0', layer: 1, source: 'local', tags: ['test'], roles: ['developer'], scenes: ['testing'], platforms: ['general'], }; beforeAll(() => { if (fs.existsSync(TEST_DB_PATH)) fs.unlinkSync(TEST_DB_PATH); process.env.SKILLS_DB_PATH = TEST_DB_PATH; delete require.cache[require.resolve('../../services/skill-db')]; skillDb = require('../../services/skill-db'); }); afterAll(() => { try { fs.unlinkSync(TEST_DB_PATH); } catch {} }); describe('registerSkill', () => { it('should register a new skill', () => { const skill = skillDb.registerSkill(TEST_SKILL); expect(skill).toBeDefined(); expect(skill.skillName).toBe(TEST_SKILL.skillName); expect(skill.description).toBe(TEST_SKILL.description); }); it('should throw on duplicate registration', () => { expect(() => skillDb.registerSkill(TEST_SKILL)).toThrow(/already exists/i); }); }); describe('getSkill', () => { it('should retrieve a registered skill by name', () => { const skill = skillDb.getSkill(TEST_SKILL.skillName); expect(skill).toBeDefined(); expect(skill.skillName).toBe(TEST_SKILL.skillName); expect(skill.domain).toBe(TEST_SKILL.domain); }); it('should return null for non-existent skill', () => { const skill = skillDb.getSkill('nonexistent_skill_xyz'); expect(skill).toBeNull(); }); }); describe('listSkills', () => { it('should list skills with pagination', () => { const skills = skillDb.listSkills({ limit: 10, offset: 0 }); expect(Array.isArray(skills)).toBe(true); expect(skills.length).toBeGreaterThanOrEqual(1); }); }); describe('countSkills', () => { it('should return total count', () => { const count = skillDb.countSkills(); expect(count).toBeGreaterThanOrEqual(1); }); }); describe('updateSkill', () => { it('should update skill metadata', () => { const updated = skillDb.updateSkill(TEST_SKILL.skillName, { description: 'Updated description' }); expect(updated.description).toBe('Updated description'); }); }); describe('searchSkills', () => { it('should return array from text search', () => { const results = skillDb.searchSkills('unit testing', { limit: 10 }); expect(Array.isArray(results)).toBe(true); }); it('should return empty for no match', () => { const results = skillDb.searchSkills('zzzznonexistent999', { limit: 10 }); expect(results).toHaveLength(0); }); }); describe('bumpVersion', () => { it('should increment version', () => { const before = skillDb.getSkill(TEST_SKILL.skillName); const updated = skillDb.bumpVersion(TEST_SKILL.skillName, 'minor'); expect(updated.version).not.toBe(before.version); }); }); describe('incrementUseCount', () => { it('should increase use count', () => { const before = skillDb.getSkill(TEST_SKILL.skillName); skillDb.incrementUseCount(TEST_SKILL.skillName); const after = skillDb.getSkill(TEST_SKILL.skillName); expect(after.useCount).toBe((before.useCount || 0) + 1); }); }); describe('incrementDownloadCount', () => { it('should increase download count', () => { const before = skillDb.getSkill(TEST_SKILL.skillName); skillDb.incrementDownloadCount(TEST_SKILL.skillName); const after = skillDb.getSkill(TEST_SKILL.skillName); expect(after.downloadCount).toBe((before.downloadCount || 0) + 1); }); }); describe('rowToSkill / skillToRow', () => { it('should round-trip correctly', () => { const skill = skillDb.getSkill(TEST_SKILL.skillName); const row = skillDb.skillToRow(skill); const back = skillDb.rowToSkill(row); expect(back.skillName).toBe(skill.skillName); expect(back.description).toBe(skill.description); }); it('rowToSkill should handle null input', () => { expect(skillDb.rowToSkill(null)).toBeNull(); }); }); describe('favorites', () => { const userId = 'test-user-123'; it('should add a favorite', () => { const result = skillDb.addFavorite(TEST_SKILL.skillName, userId); expect(result).toBeDefined(); }); it('should check isFavorited', () => { const fav = skillDb.isFavorited(TEST_SKILL.skillName, userId); expect(fav).toBe(true); }); it('should get favorite count', () => { const count = skillDb.getFavoriteCount(TEST_SKILL.skillName); expect(count).toBeGreaterThanOrEqual(1); }); it('should remove a favorite', () => { skillDb.removeFavorite(TEST_SKILL.skillName, userId); const fav = skillDb.isFavorited(TEST_SKILL.skillName, userId); expect(fav).toBe(false); }); }); describe('recordDownload', () => { it('should record a download', () => { skillDb.recordDownload(TEST_SKILL.skillName, { userId: 'test-user', version: '1.0.0', ipAddress: '127.0.0.1', }); const history = skillDb.getDownloadHistory(TEST_SKILL.skillName, { limit: 5 }); expect(history.length).toBeGreaterThanOrEqual(1); }); }); describe('getStats', () => { it('should return database statistics', () => { const stats = skillDb.getStats(); expect(stats).toBeDefined(); expect(stats.total).toBeGreaterThanOrEqual(1); expect(stats.enabled).toBeDefined(); }); }); describe('removeSkill', () => { it('should remove a skill', () => { const result = skillDb.removeSkill(TEST_SKILL.skillName); expect(result).toBe(true); expect(skillDb.getSkill(TEST_SKILL.skillName)).toBeNull(); }); it('should return false for non-existent skill', () => { const result = skillDb.removeSkill('nonexistent_xyz'); expect(result).toBe(false); }); }); });