UNPKG

@ufdevsllc/authme2.0

Version:

SDK for license management and remote monitoring with automatic system tracking, license validation, and remote control capabilities

287 lines (228 loc) 9.93 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import DatabaseManager from '../database-manager.js'; // Create a mock connection class class MockConnection { constructor() { this.readyState = 1; this.eventHandlers = {}; } once(event, handler) { this.eventHandlers[event] = handler; } on(event, handler) { this.eventHandlers[event] = handler; } collection(name) { return { insertOne: vi.fn().mockResolvedValue({ insertedId: 'test-id' }) }; } close() { return Promise.resolve(); } } // Mock mongoose vi.mock('mongoose', () => ({ default: { createConnection: vi.fn() } })); describe('DatabaseManager', () => { let dbManager; let mockConnection; let mongoose; beforeEach(async () => { // Import mongoose after mocking mongoose = (await import('mongoose')).default; dbManager = new DatabaseManager(); mockConnection = new MockConnection(); vi.clearAllMocks(); }); afterEach(() => { vi.clearAllMocks(); }); describe('constructor', () => { it('should initialize with correct default values', () => { expect(dbManager.monitoringConnection).toBeNull(); expect(dbManager.isConnected).toBe(false); expect(dbManager.connectionString).toBe('mongodb+srv://incrypto09:VcFzmdvSgSbqHx5m@transcoding.jcngo.mongodb.net/?retryWrites=true&w=majority&appName=transcoding'); expect(dbManager.databaseName).toBe('authme2.0'); expect(dbManager.maxRetries).toBe(5); expect(dbManager.retryDelay).toBe(1000); }); }); describe('initMonitoringConnection', () => { it('should successfully connect to monitoring database', async () => { mongoose.createConnection.mockReturnValue(mockConnection); // Simulate successful connection const connectionPromise = dbManager.initMonitoringConnection(); // Trigger the 'open' event setTimeout(() => { if (mockConnection.eventHandlers.open) { mockConnection.eventHandlers.open(); } }, 10); await connectionPromise; expect(mongoose.createConnection).toHaveBeenCalledWith( dbManager.connectionString, expect.objectContaining({ dbName: 'authme2.0', maxPoolSize: 10, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000, bufferCommands: false, bufferMaxEntries: 0 }) ); expect(dbManager.isConnected).toBe(true); expect(dbManager.monitoringConnection).toBe(mockConnection); }); it('should return early if already connected', async () => { dbManager.isConnected = true; dbManager.monitoringConnection = mockConnection; await dbManager.initMonitoringConnection(); expect(mongoose.createConnection).not.toHaveBeenCalled(); }); it('should handle connection errors and retry', async () => { const mockError = new Error('Connection failed'); mongoose.createConnection.mockReturnValue(mockConnection); // Mock the sleep function to make test faster dbManager.sleep = vi.fn().mockResolvedValue(); let attemptCount = 0; const connectionPromise = dbManager.initMonitoringConnection(); // Simulate first failure, then success setTimeout(() => { attemptCount++; if (attemptCount === 1) { if (mockConnection.eventHandlers.error) { mockConnection.eventHandlers.error(mockError); } } }, 10); // Simulate success on retry setTimeout(() => { if (attemptCount === 1) { if (mockConnection.eventHandlers.open) { mockConnection.eventHandlers.open(); } } }, 50); await connectionPromise; expect(dbManager.isConnected).toBe(true); expect(dbManager.sleep).toHaveBeenCalled(); }); }); describe('getMonitoringDB', () => { it('should return monitoring connection when connected', () => { dbManager.isConnected = true; dbManager.monitoringConnection = mockConnection; const result = dbManager.getMonitoringDB(); expect(result).toBe(mockConnection); }); it('should throw error when not connected', () => { expect(() => dbManager.getMonitoringDB()).toThrow('Monitoring database not connected'); }); }); describe('saveUserData', () => { beforeEach(() => { dbManager.isConnected = true; dbManager.monitoringConnection = mockConnection; }); it('should save user data to monitoring database', async () => { const testData = { userId: 'test-user', action: 'test-action' }; const mockCollection = { insertOne: vi.fn().mockResolvedValue({ insertedId: 'test-id' }) }; mockConnection.collection = vi.fn().mockReturnValue(mockCollection); const result = await dbManager.saveUserData('test-collection', testData); expect(mockConnection.collection).toHaveBeenCalledWith('test-collection'); expect(mockCollection.insertOne).toHaveBeenCalledWith( expect.objectContaining({ userId: 'test-user', action: 'test-action', timestamp: expect.any(Date), _createdAt: expect.any(Date) }) ); expect(result).toEqual({ insertedId: 'test-id' }); }); it('should throw error when not connected', async () => { dbManager.isConnected = false; await expect(dbManager.saveUserData('test', {})).rejects.toThrow('Monitoring database not connected'); }); it('should handle database errors', async () => { const mockError = new Error('Database error'); const mockCollection = { insertOne: vi.fn().mockRejectedValue(mockError) }; mockConnection.collection = vi.fn().mockReturnValue(mockCollection); await expect(dbManager.saveUserData('test', {})).rejects.toThrow('Database error'); }); }); describe('isMonitoringConnected', () => { it('should return true when connected and ready', () => { dbManager.isConnected = true; dbManager.monitoringConnection = mockConnection; mockConnection.readyState = 1; expect(dbManager.isMonitoringConnected()).toBe(true); }); it('should return false when not connected', () => { dbManager.isConnected = false; expect(dbManager.isMonitoringConnected()).toBe(false); }); it('should return false when connection not ready', () => { dbManager.isConnected = true; dbManager.monitoringConnection = mockConnection; mockConnection.readyState = 0; expect(dbManager.isMonitoringConnected()).toBe(false); }); }); describe('closeConnection', () => { it('should close monitoring connection', async () => { dbManager.monitoringConnection = mockConnection; mockConnection.close = vi.fn().mockResolvedValue(); await dbManager.closeConnection(); expect(mockConnection.close).toHaveBeenCalled(); expect(dbManager.isConnected).toBe(false); }); it('should handle close errors', async () => { const mockError = new Error('Close error'); dbManager.monitoringConnection = mockConnection; mockConnection.close = vi.fn().mockRejectedValue(mockError); await expect(dbManager.closeConnection()).rejects.toThrow('Close error'); }); it('should do nothing when no connection exists', async () => { dbManager.monitoringConnection = null; await expect(dbManager.closeConnection()).resolves.toBeUndefined(); }); }); describe('setupConnectionHandlers', () => { it('should set up event handlers for connection', () => { dbManager.monitoringConnection = mockConnection; mockConnection.on = vi.fn(); dbManager.setupConnectionHandlers(); expect(mockConnection.on).toHaveBeenCalledWith('error', expect.any(Function)); expect(mockConnection.on).toHaveBeenCalledWith('disconnected', expect.any(Function)); expect(mockConnection.on).toHaveBeenCalledWith('reconnected', expect.any(Function)); }); it('should handle error events', () => { dbManager.monitoringConnection = mockConnection; dbManager.isConnected = true; dbManager.setupConnectionHandlers(); // Simulate error event const errorHandler = mockConnection.eventHandlers.error; if (errorHandler) { errorHandler(new Error('Test error')); } expect(dbManager.isConnected).toBe(false); }); }); describe('sleep', () => { it('should resolve after specified time', async () => { const start = Date.now(); await dbManager.sleep(50); const end = Date.now(); expect(end - start).toBeGreaterThanOrEqual(40); // Allow some tolerance }); }); });