/** * Test utilities for @skillhub/db package * * Factory functions and helpers for creating test data */ import type { skills, categories, users, ratings, favorites, installations } from './schema.js'; type SkillInsert = typeof skills.$inferInsert; type CategoryInsert = typeof categories.$inferInsert; type UserInsert = typeof users.$inferInsert; type RatingInsert = typeof ratings.$inferInsert; type FavoriteInsert = typeof favorites.$inferInsert; type InstallationInsert = typeof installations.$inferInsert; /** * Create a test skill with sensible defaults */ export function createTestSkill(overrides: Partial = {}): SkillInsert { const id = overrides.id || 'test-owner/test-repo/test-skill'; return { id, name: 'test-skill', description: 'A test skill for unit testing', githubOwner: 'test-owner', githubRepo: 'test-repo', skillPath: 'skills/test-skill', branch: 'main', version: '1.0.0', license: 'MIT', author: 'Test Author', compatibility: { platforms: ['claude', 'codex'], }, githubStars: 100, githubForks: 10, downloadCount: 50, viewCount: 200, rating: 4, ratingCount: 5, ratingSum: 20, securityScore: 85, isVerified: false, isFeatured: false, rawContent: '# Test Skill\n\nThis is a test skill.', contentHash: 'abc123', createdAt: new Date(), updatedAt: new Date(), indexedAt: new Date(), ...overrides, }; } /** * Create a test category with sensible defaults */ export function createTestCategory(overrides: Partial = {}): CategoryInsert { const id = overrides.id || `cat-${Date.now()}`; return { id, name: 'Test Category', slug: overrides.slug || `test-category-${Date.now()}`, description: 'A test category', icon: 'folder', color: '#3B82F6', sortOrder: 0, skillCount: 0, createdAt: new Date(), ...overrides, }; } /** * Create a test user with sensible defaults */ export function createTestUser(overrides: Partial = {}): UserInsert { const id = overrides.id || `user-${Date.now()}`; return { id, githubId: overrides.githubId || `gh-${Date.now()}`, username: 'testuser', displayName: 'Test User', email: 'test@example.com', avatarUrl: 'https://example.com/avatar.png', bio: 'A test user', isAdmin: false, createdAt: new Date(), updatedAt: new Date(), lastLoginAt: new Date(), ...overrides, }; } /** * Create a test rating with sensible defaults */ export function createTestRating(overrides: Partial = {}): RatingInsert { return { id: overrides.id || `rating-${Date.now()}`, skillId: 'test-owner/test-repo/test-skill', userId: 'user-1', rating: 4, review: 'Great skill!', createdAt: new Date(), updatedAt: new Date(), ...overrides, }; } /** * Create a test favorite with sensible defaults */ export function createTestFavorite(overrides: Partial = {}): FavoriteInsert { return { userId: 'user-1', skillId: 'test-owner/test-repo/test-skill', createdAt: new Date(), ...overrides, }; } /** * Create a test installation with sensible defaults */ export function createTestInstallation(overrides: Partial = {}): InstallationInsert { return { id: overrides.id || `install-${Date.now()}`, skillId: 'test-owner/test-repo/test-skill', platform: 'claude', method: 'cli', createdAt: new Date(), ...overrides, }; } /** * Mock database type for testing * This provides a mock implementation of the database client */ export interface MockDb { select: ReturnType; insert: ReturnType; update: ReturnType; delete: ReturnType; } /** * Create a chainable mock for database operations */ export function createMockDbChain(finalResult: unknown = []) { const chain: Record> = {}; const createChainedMock = (): ReturnType => { const mock = vi.fn().mockImplementation(() => { return new Proxy({}, { get: (_target, prop: string) => { if (prop === 'then') { return (resolve: (value: unknown) => void) => resolve(finalResult); } if (!chain[prop]) { chain[prop] = createChainedMock(); } return chain[prop]; }, }); }); return mock; }; return { select: createChainedMock(), insert: createChainedMock(), update: createChainedMock(), delete: createChainedMock(), }; } /** * Create a simple mock database for unit tests */ export function createMockDb() { const mockResult: unknown[] = []; const createChained = () => { const chained = { from: vi.fn().mockReturnThis(), where: vi.fn().mockReturnThis(), limit: vi.fn().mockReturnThis(), offset: vi.fn().mockReturnThis(), orderBy: vi.fn().mockReturnThis(), innerJoin: vi.fn().mockReturnThis(), leftJoin: vi.fn().mockReturnThis(), groupBy: vi.fn().mockReturnThis(), values: vi.fn().mockReturnThis(), set: vi.fn().mockReturnThis(), onConflictDoUpdate: vi.fn().mockReturnThis(), onConflictDoNothing: vi.fn().mockReturnThis(), returning: vi.fn().mockResolvedValue(mockResult), then: (resolve: (v: unknown) => void) => Promise.resolve(mockResult).then(resolve), }; return chained; }; return { select: vi.fn().mockReturnValue(createChained()), insert: vi.fn().mockReturnValue(createChained()), update: vi.fn().mockReturnValue(createChained()), delete: vi.fn().mockReturnValue(createChained()), _setMockResult: (result: unknown[]) => { mockResult.length = 0; mockResult.push(...result); }, }; }