import { describe, it, expect, beforeEach, afterEach } from '@jest/globals'; import { db } from '@/db'; import { users, content, siteConfig } from '@/db/schema'; import { eq, and, desc, like } from 'drizzle-orm'; jest.mock('@/db', () => { const mockDb = { select: jest.fn().mockReturnThis(), from: jest.fn().mockReturnThis(), where: jest.fn().mockReturnThis(), orderBy: jest.fn().mockReturnThis(), limit: jest.fn().mockReturnThis(), insert: jest.fn().mockReturnThis(), values: jest.fn().mockReturnThis(), returning: jest.fn().mockReturnThis(), update: jest.fn().mockReturnThis(), set: jest.fn().mockReturnThis(), delete: jest.fn().mockReturnThis(), }; return { db: mockDb, }; }); describe('database queries', () => { let mockDb: any; beforeEach(() => { const { db: dbInstance } = require('@/db'); mockDb = dbInstance; }); afterEach(() => { jest.clearAllMocks(); }); describe('user queries', () => { it('should query user by id', async () => { const mockUser = { id: '123', email: 'test@example.com', name: 'Test User', role: 'editor', createdAt: new Date(), updatedAt: new Date(), }; mockDb.limit.mockResolvedValue([mockUser]); const result = await db.select().from(users).where(eq(users.id, '123')).limit(1); const user = result[0]; expect(user).toBeDefined(); expect(user.id).toBe('123'); expect(user.email).toBe('test@example.com'); }); it('should query user by email', async () => { const mockUser = { id: '123', email: 'test@example.com', name: 'Test User', role: 'editor', createdAt: new Date(), updatedAt: new Date(), }; mockDb.limit.mockResolvedValue([mockUser]); const result = await db.select().from(users).where(eq(users.email, 'test@example.com')).limit(1); const user = result[0]; expect(user).toBeDefined(); expect(user.email).toBe('test@example.com'); }); it('should return null for non-existent user', async () => { mockDb.limit.mockResolvedValue([]); const result = await db.select().from(users).where(eq(users.id, 'non-existent')).limit(1); const user = result[0]; expect(user).toBeUndefined(); }); it('should query users by role', async () => { const mockUsers = [ { id: '1', email: 'admin@example.com', name: 'Admin', role: 'admin', createdAt: new Date(), updatedAt: new Date() }, { id: '2', email: 'admin2@example.com', name: 'Admin2', role: 'admin', createdAt: new Date(), updatedAt: new Date() }, ]; mockDb.limit.mockResolvedValue(mockUsers); const result = await db.select().from(users).where(eq(users.role, 'admin')).limit(10); expect(result.length).toBe(2); expect(result.every(u => u.role === 'admin')).toBe(true); }); }); describe('content queries', () => { it('should query content by id', async () => { const mockContent = { id: 'content-1', type: 'news', title: 'Test News', slug: 'test-news', content: 'Test content', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date(), }; mockDb.limit.mockResolvedValue([mockContent]); const result = await db.select().from(content).where(eq(content.id, 'content-1')).limit(1); const item = result[0]; expect(item).toBeDefined(); expect(item.id).toBe('content-1'); expect(item.title).toBe('Test News'); }); it('should query content by slug', async () => { const mockContent = { id: 'content-1', type: 'news', title: 'Test News', slug: 'test-news', content: 'Test content', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date(), }; mockDb.limit.mockResolvedValue([mockContent]); const result = await db.select().from(content).where(eq(content.slug, 'test-news')).limit(1); const item = result[0]; expect(item).toBeDefined(); expect(item.slug).toBe('test-news'); }); it('should query published content', async () => { const mockContent = [ { id: '1', type: 'news', title: 'News 1', slug: 'news-1', content: 'Content 1', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date() }, { id: '2', type: 'news', title: 'News 2', slug: 'news-2', content: 'Content 2', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date() }, ]; mockDb.limit.mockResolvedValue(mockContent); const result = await db.select().from(content).where(eq(content.status, 'published')).limit(10); expect(result.length).toBe(2); expect(result.every(c => c.status === 'published')).toBe(true); }); it('should query content by type', async () => { const mockContent = [ { id: '1', type: 'news', title: 'News 1', slug: 'news-1', content: 'Content 1', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date() }, { id: '2', type: 'news', title: 'News 2', slug: 'news-2', content: 'Content 2', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date() }, ]; mockDb.limit.mockResolvedValue(mockContent); const result = await db.select().from(content).where(eq(content.type, 'news')).limit(10); expect(result.length).toBe(2); expect(result.every(c => c.type === 'news')).toBe(true); }); it('should query content with multiple conditions', async () => { const mockContent = { id: 'content-1', type: 'news', title: 'Test News', slug: 'test-news', content: 'Test content', status: 'published', authorId: '123', createdAt: new Date(), updatedAt: new Date(), }; mockDb.limit.mockResolvedValue([mockContent]); const result = await db .select() .from(content) .where(and(eq(content.status, 'published'), eq(content.type, 'news'))) .limit(1); const item = result[0]; expect(item).toBeDefined(); expect(item.status).toBe('published'); expect(item.type).toBe('news'); }); }); describe('site config queries', () => { it('should query config by key', async () => { const mockConfig = { id: 'config-1', key: 'site.title', value: { title: 'My Site' }, category: 'general', updatedAt: new Date(), }; mockDb.limit.mockResolvedValue([mockConfig]); const result = await db.select().from(siteConfig).where(eq(siteConfig.key, 'site.title')).limit(1); const config = result[0]; expect(config).toBeDefined(); expect(config.key).toBe('site.title'); expect(config.value).toEqual({ title: 'My Site' }); }); it('should query config by category', async () => { const mockConfigs = [ { id: '1', key: 'site.title', value: { title: 'My Site' }, category: 'general', updatedAt: new Date() }, { id: '2', key: 'site.description', value: { description: 'My Description' }, category: 'general', updatedAt: new Date() }, ]; mockDb.limit.mockResolvedValue(mockConfigs); const result = await db.select().from(siteConfig).where(eq(siteConfig.category, 'general')).limit(10); expect(result.length).toBe(2); expect(result.every(c => c.category === 'general')).toBe(true); }); it('should return null for non-existent config', async () => { mockDb.limit.mockResolvedValue([]); const result = await db.select().from(siteConfig).where(eq(siteConfig.key, 'non.existent')).limit(1); const config = result[0]; expect(config).toBeUndefined(); }); }); describe('query ordering', () => { it('should order content by created date', async () => { const mockContent = [ { id: '1', type: 'news', title: 'News 1', slug: 'news-1', content: 'Content 1', status: 'published', authorId: '123', createdAt: new Date('2024-01-01'), updatedAt: new Date() }, { id: '2', type: 'news', title: 'News 2', slug: 'news-2', content: 'Content 2', status: 'published', authorId: '123', createdAt: new Date('2024-01-02'), updatedAt: new Date() }, ]; mockDb.limit.mockResolvedValue(mockContent); const result = await db .select() .from(content) .orderBy(desc(content.createdAt)) .limit(10); expect(result.length).toBe(2); expect(mockDb.orderBy).toHaveBeenCalledWith(desc(content.createdAt)); }); }); });