UNPKG

@ledgerhq/live-common

Version:
242 lines • 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @jest-environment jsdom */ const react_1 = require("@testing-library/react"); const devices_1 = require("@ledgerhq/devices"); const useBleDevicesScanning_1 = require("./useBleDevicesScanning"); jest.useFakeTimers(); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const nanoXServiceUuid = (0, devices_1.getDeviceModel)(devices_1.DeviceModelId.nanoX).bluetoothSpec[0].serviceUuid; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const staxServiceUuid = (0, devices_1.getDeviceModel)(devices_1.DeviceModelId.stax).bluetoothSpec[0].serviceUuid; // Fake devices info we would get from the bluetooth transport listen const aTransportBleDevice = (overrideProps) => { return { id: "aBleNanoId", name: "aBleNano", localName: null, rssi: 50, mtu: 50, serviceUUIDs: [nanoXServiceUuid], ...overrideProps, }; }; const mockBleTransportListenUnsubscribe = jest.fn(); // HOF creating a mocked Transport listen method to be given to useBleDevicesScanning const setupMockBleTransportListen = (mockEmitValuesByObserver) => (observer) => { mockEmitValuesByObserver(observer); return { unsubscribe: mockBleTransportListenUnsubscribe, }; }; describe("useBleDevicesScanning", () => { afterEach(() => { jest.clearAllTimers(); mockBleTransportListenUnsubscribe.mockClear(); }); describe("When several unique devices are found by the scanner", () => { const deviceIdA = "ID_A"; const deviceIdB = "ID_B"; const deviceIdC = "ID_C"; const mockEmitValuesByObserver = (observer) => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdA }), }); setTimeout(() => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdB, serviceUUIDs: [staxServiceUuid], }), }); }, 1000); setTimeout(() => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdC }), }); }, 2000); }; describe("and when no filters are applied to the scanning", () => { it("should update the list of scanned devices for each new scanned device", async () => { const { result } = (0, react_1.renderHook)(() => (0, useBleDevicesScanning_1.useBleDevicesScanning)({ bleTransportListen: setupMockBleTransportListen(mockEmitValuesByObserver), })); expect(result.current.scannedDevices).toHaveLength(1); expect(result.current.scannedDevices[0].deviceId).toBe(deviceIdA); // The model was correctly deduced from the ble spec expect(result.current.scannedDevices[0].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); expect(result.current.scannedDevices).toHaveLength(2); expect(result.current.scannedDevices[1].deviceId).toBe(deviceIdB); expect(result.current.scannedDevices[1].deviceModel.id).toBe(devices_1.DeviceModelId.stax); }); }); describe("and when filterByDeviceModelIds is not null", () => { it("should filter the scanning result by the given model ids", async () => { const { result } = (0, react_1.renderHook)(() => (0, useBleDevicesScanning_1.useBleDevicesScanning)({ bleTransportListen: setupMockBleTransportListen(mockEmitValuesByObserver), filterByDeviceModelIds: [devices_1.DeviceModelId.nanoX], })); // The first scanned device was a nanoX expect(result.current.scannedDevices).toHaveLength(1); expect(result.current.scannedDevices[0].deviceId).toBe(deviceIdA); // The model was correctly deduced from the ble spec expect(result.current.scannedDevices[0].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); // The second scanned device was a stax, and was filtered out expect(result.current.scannedDevices).toHaveLength(1); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); // The third scanned device was a nanoX expect(result.current.scannedDevices).toHaveLength(2); expect(result.current.scannedDevices[1].deviceId).toBe(deviceIdC); expect(result.current.scannedDevices[1].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); }); }); describe("and when filterOutDevicesByDeviceIds is not null nor empty", () => { it("should not add the scanned device if its ids is in the array", async () => { const { result } = (0, react_1.renderHook)(() => (0, useBleDevicesScanning_1.useBleDevicesScanning)({ bleTransportListen: setupMockBleTransportListen(mockEmitValuesByObserver), filterOutDevicesByDeviceIds: [deviceIdA, deviceIdC], })); // The first scanned device (deviceIdA) should be filtered out expect(result.current.scannedDevices).toHaveLength(0); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); // The second scanned device is deviceIdB and should be kept expect(result.current.scannedDevices).toHaveLength(1); expect(result.current.scannedDevices[0].deviceId).toBe(deviceIdB); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); // The third scanned device (deviceIdC) should be filtered out expect(result.current.scannedDevices).toHaveLength(1); }); }); describe("and when the hook consumer stops the scanning", () => { it("should stop the scanning", async () => { let stopBleScanning = false; const { result, rerender } = (0, react_1.renderHook)(() => (0, useBleDevicesScanning_1.useBleDevicesScanning)({ bleTransportListen: setupMockBleTransportListen(mockEmitValuesByObserver), stopBleScanning, })); // At first the scanning finds device(s) expect(result.current.scannedDevices).toHaveLength(1); expect(result.current.scannedDevices[0].deviceId).toBe(deviceIdA); expect(result.current.scannedDevices[0].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); // Then the consumer stops the scanning stopBleScanning = true; rerender({ bleTransportListen: setupMockBleTransportListen(mockEmitValuesByObserver), stopBleScanning, }); await (0, react_1.act)(async () => { jest.advanceTimersByTime(2000); }); // It should not find any new devices expect(result.current.scannedDevices).toHaveLength(1); }); }); }); describe("When the same device is being scanned several times", () => { const deviceIdA = "ID_A"; const deviceIdB = "ID_B"; const mockEmitValuesByObserver = (observer) => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdA }), }); setTimeout(() => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdA }), }); }, 1000); setTimeout(() => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdB }), }); }, 2000); }; it("should update the list of scanned devices without any duplicate", async () => { const { result } = (0, react_1.renderHook)(() => (0, useBleDevicesScanning_1.useBleDevicesScanning)({ bleTransportListen: setupMockBleTransportListen(mockEmitValuesByObserver), })); // The first time it gets the device from the scanning expect(result.current.scannedDevices).toHaveLength(1); expect(result.current.scannedDevices[0].deviceId).toBe(deviceIdA); expect(result.current.scannedDevices[0].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); // The second time it gets the same device from the scanning // It should not have been added to the list expect(result.current.scannedDevices).toHaveLength(1); await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); // The third time it gets a new device expect(result.current.scannedDevices).toHaveLength(2); expect(result.current.scannedDevices[1].deviceId).toBe(deviceIdB); expect(result.current.scannedDevices[1].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); }); }); describe("When a device is only seen after a cleaned scanning", () => { const deviceIdA = "ID_A"; const deviceIdB = "ID_B"; const emitTimeOfDeviceB = 3000; const mockEmitValuesByObserver = (observer) => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdA }), }); setTimeout(() => { observer.next({ type: "add", descriptor: aTransportBleDevice({ id: deviceIdB }), }); }, emitTimeOfDeviceB); }; it("should restart the scanning after a defined time and update the list of scanned devices", async () => { const restartScanningTimeoutMs = emitTimeOfDeviceB; // To avoid re-rendering the hook when mockEmitValuesByObserver // emits a new value with the setTimeout const bleTransportListen = setupMockBleTransportListen(mockEmitValuesByObserver); const { result } = (0, react_1.renderHook)(() => (0, useBleDevicesScanning_1.useBleDevicesScanning)({ bleTransportListen, restartScanningTimeoutMs, })); // The first time it gets the device from the scanning expect(result.current.scannedDevices).toHaveLength(1); expect(result.current.scannedDevices[0].deviceId).toBe(deviceIdA); expect(result.current.scannedDevices[0].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); const nbUnsubscribesHappeningBecauseOfRenderHook = mockBleTransportListenUnsubscribe.mock.calls.length; // Advances by less than the first restart timeout await (0, react_1.act)(async () => { jest.advanceTimersByTime(restartScanningTimeoutMs - 1000); }); expect(mockBleTransportListenUnsubscribe).toBeCalledTimes(nbUnsubscribesHappeningBecauseOfRenderHook); // Advances by the total time of the restart timeout await (0, react_1.act)(async () => { jest.advanceTimersByTime(1000); }); expect(mockBleTransportListenUnsubscribe).toBeCalledTimes(nbUnsubscribesHappeningBecauseOfRenderHook + 1); expect(result.current.scannedDevices).toHaveLength(2); expect(result.current.scannedDevices[1].deviceId).toBe(deviceIdB); expect(result.current.scannedDevices[1].deviceModel.id).toBe(devices_1.DeviceModelId.nanoX); }); }); }); //# sourceMappingURL=useBleDevicesScanning.test.js.map