import { MockDatabaseStrategy } from '../MockDatabaseStrategy'; import { AccountStatus } from '../../auth/auth.constants'; import { Frequency } from '../../../types'; describe('MockDatabaseStrategy', () => { let strategy: MockDatabaseStrategy; beforeEach(() => { strategy = new MockDatabaseStrategy(); }); describe('user operations', () => { test('should create user with auto-generated ID', async () => { const userData = { username: 'testuser', email: 'test@example.com', }; const user = await strategy.createUser(userData); expect(user._id).toBeDefined(); expect(user._rev).toBeDefined(); expect(user.username).toBe('testuser'); expect(user.email).toBe('test@example.com'); expect(user.createdAt).toBeInstanceOf(Date); }); test('should create user with password', async () => { const user = await strategy.createUserWithPassword( 'test@example.com', 'hashedpassword', 'testuser' ); expect(user.email).toBe('test@example.com'); expect(user.password).toBe('hashedpassword'); expect(user.username).toBe('testuser'); expect(user.status).toBe(AccountStatus.PENDING); expect(user.emailVerified).toBe(false); }); test('should create OAuth user', async () => { const user = await strategy.createUserFromOAuth( 'oauth@example.com', 'OAuth User', 'google' ); expect(user.email).toBe('oauth@example.com'); expect(user.username).toBe('OAuth User'); expect(user.status).toBe(AccountStatus.ACTIVE); expect(user.emailVerified).toBe(true); }); test('should find user by email', async () => { const createdUser = await strategy.createUserWithPassword( 'findme@example.com', 'password', 'finduser' ); const foundUser = await strategy.findUserByEmail('findme@example.com'); expect(foundUser?._id).toBe(createdUser._id); expect(foundUser?.email).toBe(createdUser.email); expect(foundUser?.username).toBe(createdUser.username); }); test('should return null when user not found by email', async () => { const user = await strategy.findUserByEmail('notfound@example.com'); expect(user).toBeNull(); }); test('should get user by ID', async () => { const createdUser = await strategy.createUser({ username: 'testuser', email: 'test@example.com', }); const foundUser = await strategy.getUserById(createdUser._id); expect(foundUser?._id).toBe(createdUser._id); expect(foundUser?.email).toBe(createdUser.email); expect(foundUser?.username).toBe(createdUser.username); }); test('should return null when user not found by ID', async () => { const user = await strategy.getUserById('nonexistent-id'); expect(user).toBeNull(); }); test('should update user', async () => { const createdUser = await strategy.createUser({ username: 'original', email: 'original@example.com', }); const updatedUser = await strategy.updateUser({ ...createdUser, username: 'updated', }); expect(updatedUser.username).toBe('updated'); expect(updatedUser._id).toBe(createdUser._id); expect(updatedUser._rev).not.toBe(createdUser._rev); }); test('should delete user', async () => { const createdUser = await strategy.createUser({ username: 'tobedeleted', email: 'delete@example.com', }); const result = await strategy.deleteUser(createdUser._id); expect(result).toBe(true); const deletedUser = await strategy.getUserById(createdUser._id); expect(deletedUser).toBeNull(); }); test('should get all users', async () => { await strategy.createUser({ username: 'user1', email: 'user1@example.com', }); await strategy.createUser({ username: 'user2', email: 'user2@example.com', }); const users = await strategy.getAllUsers(); expect(users).toHaveLength(2); expect(users[0].username).toBe('user1'); expect(users[1].username).toBe('user2'); }); }); describe('medication operations', () => { let userId: string; beforeEach(async () => { const user = await strategy.createUser({ username: 'meduser', email: 'med@example.com', }); userId = user._id; }); test('should create medication', async () => { const medicationData = { name: 'Aspirin', dosage: '100mg', frequency: Frequency.Daily, startTime: '08:00', notes: 'Take with food', }; const medication = await strategy.createMedication( userId, medicationData ); expect(medication._id).toBeDefined(); expect(medication._rev).toBeDefined(); expect(medication.name).toBe('Aspirin'); expect(medication.dosage).toBe('100mg'); expect(medication.frequency).toBe(Frequency.Daily); }); test('should get medications for user', async () => { await strategy.createMedication(userId, { name: 'Med1', dosage: '10mg', frequency: Frequency.Daily, startTime: '08:00', notes: '', }); await strategy.createMedication(userId, { name: 'Med2', dosage: '20mg', frequency: Frequency.TwiceADay, startTime: '12:00', notes: '', }); const medications = await strategy.getMedications(userId); expect(medications).toHaveLength(2); expect(medications[0].name).toBe('Med1'); expect(medications[1].name).toBe('Med2'); }); test('should update medication', async () => { const created = await strategy.createMedication(userId, { name: 'Original', dosage: '10mg', frequency: Frequency.Daily, startTime: '08:00', notes: '', }); const updated = await strategy.updateMedication({ ...created, name: 'Updated', dosage: '20mg', }); expect(updated.name).toBe('Updated'); expect(updated.dosage).toBe('20mg'); expect(updated._rev).not.toBe(created._rev); }); test('should delete medication', async () => { const created = await strategy.createMedication(userId, { name: 'ToDelete', dosage: '10mg', frequency: Frequency.Daily, startTime: '08:00', notes: '', }); const result = await strategy.deleteMedication(created._id); expect(result).toBe(true); const medications = await strategy.getMedications(userId); expect(medications).toHaveLength(0); }); }); describe('user settings operations', () => { let userId: string; beforeEach(async () => { const user = await strategy.createUser({ username: 'settingsuser', email: 'settings@example.com', }); userId = user._id; }); test('should get default user settings', async () => { const settings = await strategy.getUserSettings(userId); expect(settings._id).toBe(userId); expect(settings._rev).toBeDefined(); expect(settings.notificationsEnabled).toBe(true); expect(settings.hasCompletedOnboarding).toBe(false); }); test('should update user settings', async () => { const currentSettings = await strategy.getUserSettings(userId); const updatedSettings = await strategy.updateUserSettings({ ...currentSettings, notificationsEnabled: false, hasCompletedOnboarding: true, }); expect(updatedSettings.notificationsEnabled).toBe(false); expect(updatedSettings.hasCompletedOnboarding).toBe(true); expect(updatedSettings._rev).not.toBe(currentSettings._rev); }); }); describe('taken doses operations', () => { let userId: string; beforeEach(async () => { const user = await strategy.createUser({ username: 'dosesuser', email: 'doses@example.com', }); userId = user._id; }); test('should get default taken doses', async () => { const takenDoses = await strategy.getTakenDoses(userId); expect(takenDoses._id).toBe(userId); expect(takenDoses._rev).toBeDefined(); expect(takenDoses.doses).toEqual({}); }); test('should update taken doses', async () => { const currentDoses = await strategy.getTakenDoses(userId); const updatedDoses = await strategy.updateTakenDoses({ ...currentDoses, doses: { 'med1-2024-01-01': new Date().toISOString(), }, }); expect(Object.keys(updatedDoses.doses)).toHaveLength(1); expect(updatedDoses.doses['med1-2024-01-01']).toBeTruthy(); }); }); describe('custom reminders operations', () => { let userId: string; beforeEach(async () => { const user = await strategy.createUser({ username: 'reminderuser', email: 'reminder@example.com', }); userId = user._id; }); test('should create custom reminder', async () => { const reminderData = { title: 'Drink Water', icon: '💧', startTime: '08:00', endTime: '20:00', frequencyMinutes: 60, }; const reminder = await strategy.createCustomReminder( userId, reminderData ); expect(reminder._id).toBeDefined(); expect(reminder._rev).toBeDefined(); expect(reminder.title).toBe('Drink Water'); expect(reminder.icon).toBe('💧'); expect(reminder.frequencyMinutes).toBe(60); }); test('should get custom reminders for user', async () => { await strategy.createCustomReminder(userId, { title: 'Reminder 1', icon: '⏰', startTime: '09:00', endTime: '17:00', frequencyMinutes: 30, }); const reminders = await strategy.getCustomReminders(userId); expect(reminders).toHaveLength(1); expect(reminders[0].title).toBe('Reminder 1'); }); test('should update custom reminder', async () => { const created = await strategy.createCustomReminder(userId, { title: 'Original', icon: '⏰', startTime: '09:00', endTime: '17:00', frequencyMinutes: 30, }); const updated = await strategy.updateCustomReminder({ ...created, title: 'Updated', frequencyMinutes: 60, }); expect(updated.title).toBe('Updated'); expect(updated.frequencyMinutes).toBe(60); expect(updated._rev).not.toBe(created._rev); }); test('should delete custom reminder', async () => { const created = await strategy.createCustomReminder(userId, { title: 'ToDelete', icon: '⏰', startTime: '09:00', endTime: '17:00', frequencyMinutes: 30, }); const result = await strategy.deleteCustomReminder(created._id); expect(result).toBe(true); const reminders = await strategy.getCustomReminders(userId); expect(reminders).toHaveLength(0); }); }); describe('error handling', () => { test('should create new document when updating non-existent user', async () => { const result = await strategy.updateUser({ _id: 'nonexistent', _rev: 'rev', username: 'test', }); expect(result._id).toBe('nonexistent'); expect(result.username).toBe('test'); }); test('should create new document when updating non-existent medication', async () => { const result = await strategy.updateMedication({ _id: 'nonexistent', _rev: 'rev', name: 'test', dosage: '10mg', frequency: Frequency.Daily, startTime: '08:00', notes: '', }); expect(result._id).toBe('nonexistent'); expect(result.name).toBe('test'); }); test('should return false when deleting non-existent user', async () => { const result = await strategy.deleteUser('nonexistent'); expect(result).toBe(false); }); test('should return false when deleting non-existent medication', async () => { const result = await strategy.deleteMedication('nonexistent'); expect(result).toBe(false); }); }); describe('data persistence', () => { test('should maintain data across multiple operations', async () => { // Create user const user = await strategy.createUser({ username: 'persistent', email: 'persistent@example.com', }); // Create medication const medication = await strategy.createMedication(user._id, { name: 'Persistent Med', dosage: '10mg', frequency: Frequency.Daily, startTime: '08:00', notes: '', }); // Verify data persists const retrievedUser = await strategy.getUserById(user._id); const medications = await strategy.getMedications(user._id); expect(retrievedUser?._id).toBe(user._id); expect(retrievedUser?.username).toBe(user.username); expect(medications).toHaveLength(1); expect(medications[0]._id).toBe(medication._id); expect(medications[0].name).toBe(medication.name); }); }); });