/** * BLE Manager Cleanup Tests * Tests for BLE cleanup functionality on logout */ import { RealBLEManager } from '../BLEManager'; import { MockBLEManager } from '../MockBLEManager'; describe('BLEManager cleanup', () => { describe('RealBLEManager', () => { let manager: RealBLEManager; beforeEach(() => { manager = new RealBLEManager(); }); it('should have cleanup method', () => { expect(manager.cleanup).toBeDefined(); expect(typeof manager.cleanup).toBe('function'); }); it('should not throw when cleaning up with no connections', async () => { await expect(manager.cleanup()).resolves.not.toThrow(); }); it('should stop scanning when cleanup is called during scan', async () => { // Mock the scanning state (manager as any).scanning = true; const stopScanSpy = jest.spyOn(manager, 'stopScan'); await manager.cleanup(); expect(stopScanSpy).toHaveBeenCalled(); }); it('should clear connected devices map after cleanup', async () => { // Simulate connected devices const mockDevice = { id: 'device-1' } as any; (manager as any).connectedDevices.set('device-1', mockDevice); await manager.cleanup(); expect((manager as any).connectedDevices.size).toBe(0); }); it('should attempt to disconnect all connected devices', async () => { // Mock connected devices const device1 = { id: 'device-1', cancelConnection: jest.fn().mockResolvedValue(undefined) } as any; const device2 = { id: 'device-2', cancelConnection: jest.fn().mockResolvedValue(undefined) } as any; (manager as any).connectedDevices.set('device-1', device1); (manager as any).connectedDevices.set('device-2', device2); await manager.cleanup(); expect(device1.cancelConnection).toHaveBeenCalled(); expect(device2.cancelConnection).toHaveBeenCalled(); expect((manager as any).connectedDevices.size).toBe(0); }); it('should continue cleanup even if one device disconnection fails', async () => { const device1 = { id: 'device-1', cancelConnection: jest.fn().mockRejectedValue(new Error('Connection lost')) } as any; const device2 = { id: 'device-2', cancelConnection: jest.fn().mockResolvedValue(undefined) } as any; (manager as any).connectedDevices.set('device-1', device1); (manager as any).connectedDevices.set('device-2', device2); // Should not throw even if one device fails await expect(manager.cleanup()).resolves.not.toThrow(); // Both should have been attempted expect(device1.cancelConnection).toHaveBeenCalled(); expect(device2.cancelConnection).toHaveBeenCalled(); // Map should still be cleared expect((manager as any).connectedDevices.size).toBe(0); }); }); describe('MockBLEManager', () => { let manager: MockBLEManager; beforeEach(() => { manager = new MockBLEManager(); }); it('should have cleanup method', () => { expect(manager.cleanup).toBeDefined(); expect(typeof manager.cleanup).toBe('function'); }); it('should not throw when cleaning up with no connections', async () => { await expect(manager.cleanup()).resolves.not.toThrow(); }); it('should clear connected devices set after cleanup', async () => { // Simulate connected devices await manager.connectDevice('mock-743'); await manager.connectDevice('mock-769'); expect((manager as any).connectedDevices.size).toBe(2); await manager.cleanup(); expect((manager as any).connectedDevices.size).toBe(0); }); it('should call disconnectDevice for each connected device', async () => { await manager.connectDevice('mock-743'); await manager.connectDevice('mock-769'); const disconnectSpy = jest.spyOn(manager, 'disconnectDevice'); await manager.cleanup(); expect(disconnectSpy).toHaveBeenCalledTimes(2); expect(disconnectSpy).toHaveBeenCalledWith('mock-743'); expect(disconnectSpy).toHaveBeenCalledWith('mock-769'); }); }); });