UNPKG

@ufdevsllc/authme2.0

Version:

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

939 lines (773 loc) 47.4 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import LicenseMonitoringSDK from '../../index.js'; // Mock all the dependencies vi.mock('../database-manager.js'); vi.mock('../license-validator.js'); vi.mock('../system-tracker.js'); vi.mock('../data-logger.js'); vi.mock('../remote-control-handler.js'); describe('LicenseMonitoringSDK', () => { let sdk; const testLicenseKey = 'test-license-key-12345'; beforeEach(() => { sdk = new LicenseMonitoringSDK(); vi.clearAllMocks(); }); afterEach(async () => { if (sdk && sdk.initialized) { // Mock cleanup methods to prevent errors if (sdk.systemTracker) { sdk.systemTracker.stopPeriodicTracking = vi.fn(); } if (sdk.remoteControlHandler) { sdk.remoteControlHandler.cleanup = vi.fn().mockResolvedValue(); } if (sdk.licenseValidator) { sdk.licenseValidator.cleanup = vi.fn().mockResolvedValue(); } if (sdk.dataLogger) { sdk.dataLogger.close = vi.fn().mockResolvedValue(); } if (sdk.databaseManager) { sdk.databaseManager.closeConnection = vi.fn().mockResolvedValue(); } await sdk.shutdown(); } }); describe('Constructor', () => { it('should initialize with default state', () => { expect(sdk.initialized).toBe(false); expect(sdk.licenseKey).toBe(null); expect(sdk.initializationError).toBe(null); expect(sdk.databaseManager).toBeDefined(); expect(sdk.licenseValidator).toBeDefined(); expect(sdk.systemTracker).toBeDefined(); expect(sdk.dataLogger).toBeDefined(); expect(sdk.remoteControlHandler).toBeDefined(); }); it('should initialize component flags as false', () => { const expectedFlags = { database: false, license: false, systemTracker: false, dataLogger: false, remoteControl: false }; expect(sdk.componentsInitialized).toEqual(expectedFlags); }); }); describe('init()', () => { it('should throw error for missing license key', async () => { await expect(sdk.init()).rejects.toThrow('Invalid license key'); await expect(sdk.init('')).rejects.toThrow('Invalid license key'); await expect(sdk.init(123)).rejects.toThrow('Invalid license key'); }); it('should return early if already initialized', async () => { // Mock successful initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); // First initialization await sdk.init(testLicenseKey); expect(sdk.initialized).toBe(true); // Reset mocks vi.clearAllMocks(); // Second initialization should return early await sdk.init(testLicenseKey); expect(sdk.databaseManager.initMonitoringConnection).not.toHaveBeenCalled(); }); it('should initialize all components successfully', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); expect(sdk.initialized).toBe(true); expect(sdk.licenseKey).toBe(testLicenseKey); expect(sdk.databaseManager.initMonitoringConnection).toHaveBeenCalledOnce(); expect(sdk.licenseValidator.initialize).toHaveBeenCalledOnce(); expect(sdk.licenseValidator.preventStartupOnInvalidLicense).toHaveBeenCalledWith( testLicenseKey, { exitOnFailure: true, logToConsole: true } ); expect(sdk.dataLogger.init).toHaveBeenCalledOnce(); expect(sdk.systemTracker.startPeriodicTracking).toHaveBeenCalledWith(testLicenseKey); expect(sdk.remoteControlHandler.initialize).toHaveBeenCalledWith(testLicenseKey); expect(sdk.remoteControlHandler.startCommandPolling).toHaveBeenCalledOnce(); }); it('should handle initialization options correctly', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); const options = { validateLicense: false, startSystemTracking: false, startRemoteControl: false, exitOnLicenseFailure: false, logToConsole: false }; await sdk.init(testLicenseKey, options); expect(sdk.initialized).toBe(true); expect(sdk.licenseValidator.initialize).not.toHaveBeenCalled(); expect(sdk.systemTracker.startPeriodicTracking).not.toHaveBeenCalled(); expect(sdk.remoteControlHandler.initialize).not.toHaveBeenCalled(); }); it('should handle database initialization failure', async () => { const error = new Error('Database connection failed'); sdk.databaseManager.initMonitoringConnection = vi.fn().mockRejectedValue(error); sdk._cleanup = vi.fn().mockResolvedValue(); await expect(sdk.init(testLicenseKey)).rejects.toThrow('SDK initialization failed: Database initialization failed: Database connection failed'); expect(sdk.initialized).toBe(false); expect(sdk.initializationError.message).toBe('Database initialization failed: Database connection failed'); expect(sdk._cleanup).toHaveBeenCalledOnce(); }); it('should handle license validation failure', async () => { sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); const error = new Error('License validation failed'); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockRejectedValue(error); sdk._cleanup = vi.fn().mockResolvedValue(); await expect(sdk.init(testLicenseKey)).rejects.toThrow('SDK initialization failed: License validation failed: License validation failed'); expect(sdk.initialized).toBe(false); expect(sdk._cleanup).toHaveBeenCalledOnce(); }); it('should continue initialization even if system tracking fails', async () => { // Mock successful components sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); // Mock system tracker failure sdk.systemTracker.startPeriodicTracking = vi.fn().mockRejectedValue(new Error('System tracking failed')); // Should still initialize successfully await sdk.init(testLicenseKey); expect(sdk.initialized).toBe(true); expect(sdk.componentsInitialized.systemTracker).toBe(false); }); }); describe('logData()', () => { beforeEach(async () => { // Setup initialized SDK sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); }); it('should throw error if SDK not initialized', async () => { const uninitializedSDK = new LicenseMonitoringSDK(); await expect(uninitializedSDK.logData('test', {}, 'create')).rejects.toThrow('SDK not initialized. Call init() first.'); }); it('should throw error if data logger not initialized', async () => { sdk.componentsInitialized.dataLogger = false; await expect(sdk.logData('test', {}, 'create')).rejects.toThrow('Data logger not initialized'); }); it('should successfully log data', async () => { const testData = { name: 'test', value: 123 }; const expectedResult = { success: true, id: 'test-id' }; sdk.dataLogger.logData = vi.fn().mockResolvedValue(expectedResult); const result = await sdk.logData('testCollection', testData, 'create'); expect(sdk.dataLogger.logData).toHaveBeenCalledWith('testCollection', testData, 'create'); expect(result).toEqual(expectedResult); }); it('should handle data logger errors', async () => { const error = new Error('Logging failed'); sdk.dataLogger.logData = vi.fn().mockRejectedValue(error); await expect(sdk.logData('test', {}, 'create')).rejects.toThrow('Failed to log data: Logging failed'); }); }); describe('isLicenseValid()', () => { it('should return false if SDK not initialized', async () => { const result = await sdk.isLicenseValid(); expect(result).toBe(false); }); it('should return false if license validator not initialized', async () => { sdk.initialized = true; sdk.componentsInitialized.license = false; const result = await sdk.isLicenseValid(); expect(result).toBe(false); }); it('should return license validation result', async () => { sdk.initialized = true; sdk.componentsInitialized.license = true; sdk.licenseValidator.isLicenseActive = vi.fn().mockResolvedValue(true); const result = await sdk.isLicenseValid(); expect(result).toBe(true); expect(sdk.licenseValidator.isLicenseActive).toHaveBeenCalledWith(sdk.licenseKey); }); it('should handle license validation errors', async () => { sdk.initialized = true; sdk.componentsInitialized.license = true; sdk.licenseValidator.isLicenseActive = vi.fn().mockRejectedValue(new Error('Validation error')); const result = await sdk.isLicenseValid(); expect(result).toBe(false); }); }); describe('getStatus()', () => { it('should return correct status for uninitialized SDK', () => { const status = sdk.getStatus(); expect(status).toEqual({ initialized: false, licenseKey: null, initializationError: null, components: { database: false, license: false, systemTracker: false, dataLogger: false, remoteControl: false }, isBlocked: false, blockReason: null, databaseConnected: false, dataLoggerReady: false }); }); it('should return correct status for initialized SDK', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(false); sdk.remoteControlHandler.getBlockReason = vi.fn().mockReturnValue(null); await sdk.init(testLicenseKey); const status = sdk.getStatus(); expect(status.initialized).toBe(true); expect(status.licenseKey).toBe('test-lic...'); expect(status.databaseConnected).toBe(true); expect(status.dataLoggerReady).toBe(true); }); }); describe('shutdown()', () => { it('should handle shutdown of uninitialized SDK', async () => { await sdk.shutdown(); expect(sdk.initialized).toBe(false); }); it('should cleanup all components during shutdown', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); // Mock cleanup methods sdk.systemTracker.stopPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.cleanup = vi.fn().mockResolvedValue(); sdk.licenseValidator.cleanup = vi.fn().mockResolvedValue(); sdk.dataLogger.close = vi.fn().mockResolvedValue(); sdk.databaseManager.closeConnection = vi.fn().mockResolvedValue(); await sdk.shutdown(); expect(sdk.systemTracker.stopPeriodicTracking).toHaveBeenCalledOnce(); expect(sdk.remoteControlHandler.cleanup).toHaveBeenCalledOnce(); expect(sdk.licenseValidator.cleanup).toHaveBeenCalledOnce(); expect(sdk.dataLogger.close).toHaveBeenCalledOnce(); expect(sdk.databaseManager.closeConnection).toHaveBeenCalledOnce(); expect(sdk.initialized).toBe(false); expect(sdk.licenseKey).toBe(null); expect(sdk.initializationError).toBe(null); }); it('should handle cleanup errors gracefully', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); // Mock cleanup methods with errors sdk.systemTracker.stopPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.cleanup = vi.fn().mockRejectedValue(new Error('Cleanup error')); sdk.licenseValidator.cleanup = vi.fn().mockRejectedValue(new Error('Cleanup error')); sdk.dataLogger.close = vi.fn().mockRejectedValue(new Error('Cleanup error')); sdk.databaseManager.closeConnection = vi.fn().mockRejectedValue(new Error('Cleanup error')); // Should not throw despite cleanup errors await expect(sdk.shutdown()).resolves.not.toThrow(); expect(sdk.initialized).toBe(false); }); }); describe('License Validation Integration', () => { it('should validate license during initialization with default options', async () => { // Mock successful components sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); expect(sdk.licenseValidator.initialize).toHaveBeenCalledOnce(); expect(sdk.licenseValidator.preventStartupOnInvalidLicense).toHaveBeenCalledWith( testLicenseKey, { exitOnFailure: true, logToConsole: true } ); expect(sdk.componentsInitialized.license).toBe(true); }); it('should skip license validation when validateLicense option is false', async () => { // Mock successful components sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey, { validateLicense: false }); expect(sdk.licenseValidator.initialize).not.toHaveBeenCalled(); expect(sdk.licenseValidator.preventStartupOnInvalidLicense).not.toHaveBeenCalled(); expect(sdk.componentsInitialized.license).toBe(false); }); it('should pass custom validation options to license validator', async () => { // Mock successful components sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); const options = { exitOnLicenseFailure: false, logToConsole: false }; await sdk.init(testLicenseKey, options); expect(sdk.licenseValidator.preventStartupOnInvalidLicense).toHaveBeenCalledWith( testLicenseKey, { exitOnFailure: false, logToConsole: false } ); }); it('should fail initialization when license validation fails', async () => { sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockRejectedValue( new Error('License expired') ); sdk._cleanup = vi.fn().mockResolvedValue(); await expect(sdk.init(testLicenseKey)).rejects.toThrow( 'SDK initialization failed: License validation failed: License expired' ); expect(sdk.initialized).toBe(false); expect(sdk.componentsInitialized.license).toBe(false); expect(sdk._cleanup).toHaveBeenCalledOnce(); }); it('should fail initialization when license validator initialization fails', async () => { sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockRejectedValue( new Error('Database connection failed') ); sdk._cleanup = vi.fn().mockResolvedValue(); await expect(sdk.init(testLicenseKey)).rejects.toThrow( 'SDK initialization failed: License validation failed: Database connection failed' ); expect(sdk.initialized).toBe(false); expect(sdk.componentsInitialized.license).toBe(false); }); it('should provide license status through getLicenseStatus method', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); const mockLicenseStatus = { isValid: true, reason: 'LICENSE_VALID', message: 'License is valid and active' }; sdk.licenseValidator.validateLicense = vi.fn().mockResolvedValue(mockLicenseStatus); const status = await sdk.getLicenseStatus(); expect(sdk.licenseValidator.validateLicense).toHaveBeenCalledWith(testLicenseKey); expect(status).toEqual(mockLicenseStatus); }); it('should throw error when getting license status without initialization', async () => { await expect(sdk.getLicenseStatus()).rejects.toThrow( 'SDK not initialized or license validator not available' ); }); it('should handle license status errors gracefully', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); sdk.licenseValidator.validateLicense = vi.fn().mockRejectedValue( new Error('Validation failed') ); await expect(sdk.getLicenseStatus()).rejects.toThrow( 'Failed to get license status: Validation failed' ); }); }); describe('System Tracking Integration', () => { it('should start system tracking automatically during initialization', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); expect(sdk.systemTracker.startPeriodicTracking).toHaveBeenCalledWith(testLicenseKey); expect(sdk.componentsInitialized.systemTracker).toBe(true); }); it('should skip system tracking when startSystemTracking option is false', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey, { startSystemTracking: false }); expect(sdk.systemTracker.startPeriodicTracking).not.toHaveBeenCalled(); expect(sdk.componentsInitialized.systemTracker).toBe(false); }); it('should continue initialization even if system tracking fails', async () => { // Mock successful components sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); // Mock system tracker failure sdk.systemTracker.startPeriodicTracking = vi.fn().mockRejectedValue(new Error('System tracking failed')); // Should still initialize successfully await sdk.init(testLicenseKey); expect(sdk.initialized).toBe(true); expect(sdk.componentsInitialized.systemTracker).toBe(false); }); it('should stop system tracking during shutdown', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); // Mock cleanup methods sdk.systemTracker.stopPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.cleanup = vi.fn().mockResolvedValue(); sdk.licenseValidator.cleanup = vi.fn().mockResolvedValue(); sdk.dataLogger.close = vi.fn().mockResolvedValue(); sdk.databaseManager.closeConnection = vi.fn().mockResolvedValue(); await sdk.shutdown(); expect(sdk.systemTracker.stopPeriodicTracking).toHaveBeenCalledOnce(); }); it('should include system tracker status in health check', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(false); await sdk.init(testLicenseKey); // Mock license validation sdk.isLicenseValid = vi.fn().mockResolvedValue(true); const health = await sdk.healthCheck(); expect(health.components.systemTracker).toEqual({ status: 'healthy', initialized: true }); }); it('should show warning status for uninitialized system tracker', async () => { sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); const health = await sdk.healthCheck(); expect(health.components.systemTracker).toEqual({ status: 'warning', initialized: false }); }); it('should collect initial deployment information on first tracking', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); // Mock system tracker to capture the call const mockTrackingData = { licenseKey: testLicenseKey, systemInfo: { os: 'Linux' }, deploymentInfo: { ipAddress: '192.168.1.100' }, corsSettings: { allowedOrigins: ['*'] }, environmentVariables: { NODE_ENV: 'test' } }; sdk.systemTracker.trackAndSave = vi.fn().mockResolvedValue({ success: true }); sdk.systemTracker.collectAllTrackingData = vi.fn().mockResolvedValue(mockTrackingData); await sdk.init(testLicenseKey); // Verify that initial tracking was called with the license key expect(sdk.systemTracker.startPeriodicTracking).toHaveBeenCalledWith(testLicenseKey); }); }); describe('healthCheck()', () => { it('should return health status for uninitialized SDK', async () => { sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(false); sdk.dataLogger.isReady = vi.fn().mockReturnValue(false); const health = await sdk.healthCheck(); expect(health.overall).toBe('unhealthy'); expect(health.components.database.status).toBe('unhealthy'); expect(health.components.dataLogger.status).toBe('unhealthy'); }); it('should return healthy status for fully initialized SDK', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(false); await sdk.init(testLicenseKey); // Mock license validation sdk.isLicenseValid = vi.fn().mockResolvedValue(true); const health = await sdk.healthCheck(); expect(health.overall).toBe('healthy'); expect(health.components.database.status).toBe('healthy'); expect(health.components.license.status).toBe('healthy'); expect(health.components.dataLogger.status).toBe('healthy'); expect(health.components.remoteControl.status).toBe('healthy'); expect(health.components.systemTracker.status).toBe('healthy'); }); it('should show warning status for invalid license', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(false); await sdk.init(testLicenseKey); // Mock invalid license sdk.isLicenseValid = vi.fn().mockResolvedValue(false); const health = await sdk.healthCheck(); expect(health.overall).toBe('warning'); expect(health.components.license.status).toBe('warning'); expect(health.components.license.valid).toBe(false); }); it('should show unhealthy status for license validation errors', async () => { // Mock initialization sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(false); await sdk.init(testLicenseKey); // Mock license validation error sdk.isLicenseValid = vi.fn().mockRejectedValue(new Error('Validation error')); const health = await sdk.healthCheck(); expect(health.overall).toBe('unhealthy'); expect(health.components.license.status).toBe('unhealthy'); expect(health.components.license.error).toBe('Validation error'); }); }); describe('Remote Control Integration', () => { it('should initialize remote control handler during SDK initialization', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); expect(sdk.remoteControlHandler.initialize).toHaveBeenCalledWith(testLicenseKey); expect(sdk.remoteControlHandler.startCommandPolling).toHaveBeenCalledOnce(); expect(sdk.componentsInitialized.remoteControl).toBe(true); }); it('should skip remote control initialization when startRemoteControl option is false', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey, { startRemoteControl: false }); expect(sdk.remoteControlHandler.initialize).not.toHaveBeenCalled(); expect(sdk.remoteControlHandler.startCommandPolling).not.toHaveBeenCalled(); expect(sdk.componentsInitialized.remoteControl).toBe(false); }); it('should continue initialization even if remote control fails', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); // Mock remote control failure sdk.remoteControlHandler.initialize = vi.fn().mockRejectedValue(new Error('Remote control failed')); await sdk.init(testLicenseKey); expect(sdk.initialized).toBe(true); expect(sdk.componentsInitialized.remoteControl).toBe(false); }); it('should check if application is blocked', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(true); await sdk.init(testLicenseKey); const isBlocked = sdk.isApplicationBlocked(); expect(isBlocked).toBe(true); expect(sdk.remoteControlHandler.isApplicationBlocked).toHaveBeenCalledOnce(); }); it('should return false for blocked status if remote control not initialized', async () => { const isBlocked = sdk.isApplicationBlocked(); expect(isBlocked).toBe(false); }); it('should get block reason', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.getBlockReason = vi.fn().mockReturnValue('License violation detected'); await sdk.init(testLicenseKey); const blockReason = sdk.getBlockReason(); expect(blockReason).toBe('License violation detected'); expect(sdk.remoteControlHandler.getBlockReason).toHaveBeenCalledOnce(); }); it('should return null for block reason if remote control not initialized', async () => { const blockReason = sdk.getBlockReason(); expect(blockReason).toBe(null); }); it('should include remote control status in getStatus()', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(true); sdk.remoteControlHandler.getBlockReason = vi.fn().mockReturnValue('Test block reason'); await sdk.init(testLicenseKey); const status = sdk.getStatus(); expect(status.isBlocked).toBe(true); expect(status.blockReason).toBe('Test block reason'); expect(status.components.remoteControl).toBe(true); }); it('should include remote control status in health check', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.isApplicationBlocked = vi.fn().mockReturnValue(false); await sdk.init(testLicenseKey); // Mock license validation sdk.isLicenseValid = vi.fn().mockResolvedValue(true); const health = await sdk.healthCheck(); expect(health.components.remoteControl).toEqual({ status: 'healthy', initialized: true, isBlocked: false }); }); it('should show warning status for uninitialized remote control in health check', async () => { sdk.databaseManager.isMonitoringConnected = vi.fn().mockReturnValue(true); sdk.dataLogger.isReady = vi.fn().mockReturnValue(true); const health = await sdk.healthCheck(); expect(health.components.remoteControl).toEqual({ status: 'warning', initialized: false, isBlocked: false }); }); it('should cleanup remote control handler during shutdown', async () => { // Mock all component initializations sdk.databaseManager.initMonitoringConnection = vi.fn().mockResolvedValue(); sdk.licenseValidator.initialize = vi.fn().mockResolvedValue(); sdk.licenseValidator.preventStartupOnInvalidLicense = vi.fn().mockResolvedValue(); sdk.dataLogger.init = vi.fn().mockResolvedValue(); sdk.systemTracker.startPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.initialize = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.startCommandPolling = vi.fn().mockResolvedValue(); await sdk.init(testLicenseKey); // Mock cleanup methods sdk.systemTracker.stopPeriodicTracking = vi.fn().mockResolvedValue(); sdk.remoteControlHandler.cleanup = vi.fn().mockResolvedValue(); sdk.licenseValidator.cleanup = vi.fn().mockResolvedValue(); sdk.dataLogger.close = vi.fn().mockResolvedValue(); sdk.databaseManager.closeConnection = vi.fn().mockResolvedValue(); await sdk.shutdown(); expect(sdk.remoteControlHandler.cleanup).toHaveBeenCalledOnce(); }); }); });