/** * @jest-environment node */ import { DrizzleDatabase } from '../drizzle' import { DatabaseConfig } from '../types' import Database from 'better-sqlite3' import { drizzle } from 'drizzle-orm/better-sqlite3' import * as schema from '@fitai/database' describe('DrizzleDatabase', () => { let db: DrizzleDatabase let sqlite: Database.Database let drizzleDb: ReturnType beforeEach(async () => { // Create in-memory SQLite database sqlite = new Database(':memory:') drizzleDb = drizzle(sqlite, { schema }) const config: DatabaseConfig = { type: 'sqlite', connection: { filename: ':memory:' }, options: { logging: false } } // Initialize DrizzleDatabase with the in-memory db db = new DrizzleDatabase(config, drizzleDb as any) await db.connect() }) afterEach(async () => { await db.disconnect() sqlite.close() }) describe('User Operations', () => { it('should create and retrieve a user', async () => { const newUser = { email: 'test@example.com', firstName: 'Test', lastName: 'User', password: 'password123', role: 'client' as const } const createdUser = await db.createUser(newUser) expect(createdUser).toBeDefined() expect(createdUser.id).toBeDefined() expect(createdUser.email).toBe(newUser.email) const fetchedUser = await db.getUserById(createdUser.id) expect(fetchedUser).toBeDefined() expect(fetchedUser?.id).toBe(createdUser.id) expect(fetchedUser?.email).toBe(createdUser.email) // SQLite/Drizzle might truncate ms or handle dates differently in test env expect(new Date(fetchedUser!.createdAt).getTime()).toBeLessThanOrEqual(createdUser.createdAt.getTime()) expect(new Date(fetchedUser!.updatedAt).getTime()).toBeLessThanOrEqual(createdUser.updatedAt.getTime()) }) it('should update a user', async () => { const user = await db.createUser({ email: 'update@example.com', firstName: 'Update', lastName: 'Me', password: 'password', role: 'client' }) const updated = await db.updateUser(user.id, { firstName: 'Updated' }) expect(updated?.firstName).toBe('Updated') const fetched = await db.getUserById(user.id) expect(fetched?.firstName).toBe('Updated') }) it('should delete a user', async () => { const user = await db.createUser({ email: 'delete@example.com', firstName: 'Delete', lastName: 'Me', password: 'password', role: 'client' }) const deleted = await db.deleteUser(user.id) expect(deleted).toBe(true) const fetched = await db.getUserById(user.id) expect(fetched).toBeNull() }) }) describe('Client Operations', () => { it('should create and retrieve a client', async () => { const user = await db.createUser({ email: 'client@example.com', firstName: 'Client', lastName: 'User', password: 'password', role: 'client' }) const newClient = { userId: user.id, membershipType: 'basic' as const, membershipStatus: 'active' as const, joinDate: new Date() } const createdClient = await db.createClient(newClient) expect(createdClient).toBeDefined() expect(createdClient.userId).toBe(user.id) const fetchedClient = await db.getClientById(createdClient.id) expect(fetchedClient).toBeDefined() expect(fetchedClient?.id).toBe(createdClient.id) expect(fetchedClient?.userId).toBe(createdClient.userId) expect(fetchedClient?.membershipType).toBe(createdClient.membershipType) }) }) describe('Fitness Profile Operations', () => { it('should create and retrieve a fitness profile', async () => { const user = await db.createUser({ email: 'profile@example.com', firstName: 'Profile', lastName: 'User', password: 'password', role: 'client' }) const newProfile = { userId: user.id, height: 180, weight: 75, age: 30, gender: 'male' as const, activityLevel: 'moderately_active' as const, fitnessGoals: ['weight_loss'], exerciseHabits: 'None', dietHabits: 'None', medicalConditions: 'None' } const createdProfile = await db.createFitnessProfile(newProfile as any) expect(createdProfile).toBeDefined() expect(createdProfile.userId).toBe(user.id) const fetchedProfile = await db.getFitnessProfileByUserId(user.id) expect(fetchedProfile).toBeDefined() expect(fetchedProfile?.userId).toBe(user.id) expect(fetchedProfile?.fitnessGoals).toEqual(expect.arrayContaining(['weight_loss'])) }) }) describe('Attendance Operations', () => { it('should check in and check out', async () => { const user = await db.createUser({ email: 'attendance@example.com', firstName: 'Attendance', lastName: 'User', password: 'password', role: 'client' }) const checkIn = await db.checkIn(user.id, 'gym') expect(checkIn).toBeDefined() expect(checkIn.checkOutTime).toBeUndefined() const activeCheckIn = await db.getActiveCheckIn(user.id) expect(activeCheckIn).toBeDefined() expect(activeCheckIn?.id).toBe(checkIn.id) const checkOut = await db.checkOut(checkIn.id) expect(checkOut?.checkOutTime).toBeDefined() const activeCheckInAfter = await db.getActiveCheckIn(user.id) expect(activeCheckInAfter).toBeNull() }) }) })