UNPKG

@ufdevsllc/authme2.0

Version:

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

278 lines (228 loc) 10.5 kB
import mongoose from 'mongoose'; import RemoteCommand from '../../models/remote-command.js'; describe('RemoteCommand Model', () => { beforeAll(async () => { await mongoose.connect('mongodb://localhost:27017/test-license-sdk-command'); }); afterAll(async () => { await mongoose.connection.dropDatabase(); await mongoose.connection.close(); }); beforeEach(async () => { await RemoteCommand.deleteMany({}); }); describe('Schema Validation', () => { const validCommandData = { licenseKey: 'TEST-LICENSE-123', command: 'block', parameters: { reason: 'License violation' }, priority: 5 }; test('should create a valid remote command', async () => { const command = new RemoteCommand(validCommandData); const saved = await command.save(); expect(saved._id).toBeDefined(); expect(saved.licenseKey).toBe(validCommandData.licenseKey); expect(saved.command).toBe(validCommandData.command); expect(saved.status).toBe('pending'); expect(saved.priority).toBe(validCommandData.priority); expect(saved.retryCount).toBe(0); expect(saved.maxRetries).toBe(3); }); test('should require licenseKey and command', async () => { const noLicense = new RemoteCommand({ ...validCommandData, licenseKey: undefined }); await expect(noLicense.save()).rejects.toThrow('License key is required'); const noCommand = new RemoteCommand({ ...validCommandData, command: undefined }); await expect(noCommand.save()).rejects.toThrow('Command is required'); }); test('should validate command enum', async () => { const invalidCommand = new RemoteCommand({ ...validCommandData, command: 'invalid_command' }); await expect(invalidCommand.save()).rejects.toThrow('Command must be one of: block, activate, deactivate, update, restart, status, config'); }); test('should validate status enum', async () => { const invalidStatus = new RemoteCommand({ ...validCommandData, status: 'invalid_status' }); await expect(invalidStatus.save()).rejects.toThrow('Status must be one of: pending, executing, executed, failed, cancelled'); }); test('should validate priority range', async () => { const lowPriority = new RemoteCommand({ ...validCommandData, priority: 0 }); await expect(lowPriority.save()).rejects.toThrow('Priority must be at least 1'); const highPriority = new RemoteCommand({ ...validCommandData, priority: 11 }); await expect(highPriority.save()).rejects.toThrow('Priority cannot exceed 10'); }); test('should validate executedAt is after createdAt', async () => { const command = new RemoteCommand({ ...validCommandData, executedAt: new Date(Date.now() - 24 * 60 * 60 * 1000) // Yesterday }); await expect(command.save()).rejects.toThrow('Execution date cannot be before creation date'); }); test('should validate expiresAt is after createdAt', async () => { const command = new RemoteCommand({ ...validCommandData, expiresAt: new Date(Date.now() - 60 * 60 * 1000) // 1 hour ago }); await expect(command.save()).rejects.toThrow('Expiration date must be after creation date'); }); test('should validate parameters size', async () => { const largeParams = {}; for (let i = 0; i < 1000; i++) { largeParams[`key${i}`] = 'a'.repeat(100); } const command = new RemoteCommand({ ...validCommandData, parameters: largeParams }); await expect(command.save()).rejects.toThrow('Parameters must be an object and cannot exceed 10KB'); }); test('should validate retry counts', async () => { const highRetry = new RemoteCommand({ ...validCommandData, retryCount: 6 }); await expect(highRetry.save()).rejects.toThrow('Retry count cannot exceed 5'); const highMaxRetry = new RemoteCommand({ ...validCommandData, maxRetries: 6 }); await expect(highMaxRetry.save()).rejects.toThrow('Max retries cannot exceed 5'); }); }); describe('Virtual Properties', () => { test('should calculate isExpired correctly', async () => { const activeCommand = new RemoteCommand({ licenseKey: 'ACTIVE-LICENSE-123', command: 'block', expiresAt: new Date(Date.now() + 60 * 60 * 1000) // 1 hour from now }); const expiredCommand = new RemoteCommand({ licenseKey: 'EXPIRED-LICENSE-123', command: 'block', expiresAt: new Date(Date.now() - 60 * 60 * 1000) // 1 hour ago }); expect(activeCommand.isExpired).toBe(false); expect(expiredCommand.isExpired).toBe(true); }); test('should calculate canRetry correctly', async () => { const retryableCommand = new RemoteCommand({ licenseKey: 'RETRY-LICENSE-123', command: 'block', status: 'failed', retryCount: 2, maxRetries: 3 }); const nonRetryableCommand = new RemoteCommand({ licenseKey: 'NO-RETRY-LICENSE-123', command: 'block', status: 'failed', retryCount: 3, maxRetries: 3 }); expect(retryableCommand.canRetry).toBe(true); expect(nonRetryableCommand.canRetry).toBe(false); }); }); describe('Instance Methods', () => { let command; beforeEach(async () => { command = new RemoteCommand({ licenseKey: 'TEST-LICENSE-METHODS-123', command: 'block', parameters: { reason: 'Test' } }); await command.save(); }); test('markAsExecuting should update status', async () => { expect(command.status).toBe('pending'); await command.markAsExecuting(); expect(command.status).toBe('executing'); }); test('markAsExecuted should update status and result', async () => { const result = { message: 'Command executed successfully', data: { blocked: true }, executionTime: 150 }; await command.markAsExecuted(result); expect(command.status).toBe('executed'); expect(command.executedAt).toBeDefined(); expect(command.result.success).toBe(true); expect(command.result.message).toBe(result.message); expect(command.result.data).toEqual(result.data); expect(command.result.executionTime).toBe(result.executionTime); }); test('markAsFailed should update status and result', async () => { const error = { message: 'Command execution failed', data: { error: 'Network timeout' }, executionTime: 5000 }; await command.markAsFailed(error); expect(command.status).toBe('failed'); expect(command.executedAt).toBeDefined(); expect(command.result.success).toBe(false); expect(command.result.message).toBe(error.message); expect(command.result.data).toEqual(error.data); expect(command.result.executionTime).toBe(error.executionTime); }); test('retry should increment retry count and reset status', async () => { // First mark as failed await command.markAsFailed({ message: 'Test failure' }); expect(command.status).toBe('failed'); expect(command.retryCount).toBe(0); // Then retry await command.retry(); expect(command.status).toBe('pending'); expect(command.retryCount).toBe(1); expect(command.executedAt).toBeUndefined(); expect(command.result).toEqual({}); }); test('retry should throw error when cannot retry', async () => { // Create a fresh command for this test const testCommand = new RemoteCommand({ licenseKey: 'TEST-LICENSE-RETRY-123', command: 'block', parameters: { reason: 'Test' }, retryCount: 3, maxRetries: 3, status: 'failed' }); await testCommand.save(); try { await testCommand.retry(); expect.fail('Expected retry to throw an error'); } catch (error) { expect(error.message).toBe('Command cannot be retried'); } }); test('cancel should update status for pending commands', async () => { expect(command.status).toBe('pending'); await command.cancel(); expect(command.status).toBe('cancelled'); expect(command.executedAt).toBeDefined(); expect(command.result.success).toBe(false); expect(command.result.message).toBe('Command was cancelled'); }); test('cancel should throw error for non-pending commands', async () => { // Create a fresh command for this test const testCommand = new RemoteCommand({ licenseKey: 'TEST-LICENSE-CANCEL-123', command: 'block', parameters: { reason: 'Test' } }); await testCommand.save(); await testCommand.markAsExecuting(); try { await testCommand.cancel(); expect.fail('Expected cancel to throw an error'); } catch (error) { expect(error.message).toBe('Only pending commands can be cancelled'); } }); }); });