@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
213 lines • 11.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @jest-environment jsdom
*/
const react_1 = require("@testing-library/react");
const rxjs_1 = require("rxjs");
const errors_1 = require("@ledgerhq/errors");
const useGenuineCheck_1 = require("./useGenuineCheck");
const getGenuineCheckFromDeviceId_1 = require("../getGenuineCheckFromDeviceId");
jest.mock("../getGenuineCheckFromDeviceId");
jest.useFakeTimers();
const mockedGetGenuineCheckFromDeviceId = jest.mocked(getGenuineCheckFromDeviceId_1.getGenuineCheckFromDeviceId);
describe("useGenuineCheck", () => {
afterEach(() => {
mockedGetGenuineCheckFromDeviceId.mockClear();
jest.clearAllTimers();
});
describe("When the genuine check requests for a device permission", () => {
it("should notify the hook consumer of the request", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "device-permission-requested" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.devicePermissionState).toEqual("requested");
expect(result.current.genuineState).toEqual("unchecked");
expect(result.current.error).toBeNull();
});
it("should notify the hook consumer if the device permission is granted", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "device-permission-granted" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.devicePermissionState).toEqual("granted");
expect(result.current.genuineState).toEqual("unchecked");
expect(result.current.error).toBeNull();
});
it("should notify the hook consumer if the device permission is refused", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.throwError)(() => new errors_1.UserRefusedAllowManager()));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.devicePermissionState).toEqual("refused");
expect(result.current.genuineState).toEqual("unchecked");
expect(result.current.error).toBeNull();
});
});
describe("When an error occurred during the genuine check", () => {
it("should notify the hook consumer that an error occurred", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.throwError)(() => new errors_1.DisconnectedDeviceDuringOperation()));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.genuineState).toEqual("unchecked");
expect(result.current.error).toBeInstanceOf(errors_1.DisconnectedDeviceDuringOperation);
});
});
describe("When the genuine check is completed", () => {
describe("and it is a success", () => {
it("should notify the hook consumer of the success", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "result", payload: "0000" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.genuineState).toEqual("genuine");
expect(result.current.error).toBeNull();
});
});
describe("and the device is not genuine", () => {
it("should notify the hook consumer that the device is not genuine", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "result", payload: "1111" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.genuineState).toEqual("non-genuine");
expect(result.current.error).toBeNull();
});
});
});
describe("When the hook consumer requests to reset the genuine check state", () => {
it("should reset the device permission and genuine states", async () => {
// In the case of an unsuccessful genuine check
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "device-permission-granted" },
lockedDevice: false,
}, {
socketEvent: { type: "result", payload: "1111" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
isHookEnabled: true,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.devicePermissionState).toEqual("granted");
expect(result.current.genuineState).toEqual("non-genuine");
expect(result.current.error).toBeNull();
// We ask to reset the genuine check state
await (0, react_1.act)(async () => {
result.current.resetGenuineCheckState();
});
expect(result.current.devicePermissionState).toEqual("unrequested");
expect(result.current.genuineState).toEqual("unchecked");
expect(result.current.error).toBeNull();
});
});
describe("When the device is locked during the genuine check", () => {
it("should notify the hook consumer of the need to unlock the device", async () => {
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: null,
lockedDevice: true,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.devicePermissionState).toEqual("unlock-needed");
expect(result.current.genuineState).toEqual("unchecked");
expect(result.current.error).toBeNull();
});
});
describe("When device permission is requested but times out", () => {
const mockedGetGenuineCheckFromDeviceId = jest.fn();
const permissionTimeoutMs = 60 * 1000;
it("should throw UnresponsiveDeviceError after 30 seconds if permission is not granted", async () => {
// Given the getGenuineCheckFromDeviceId function will return a device permission request
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "device-permission-requested" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
permissionTimeoutMs,
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
expect(result.current.devicePermissionState).toEqual("requested");
expect(result.current.error).toBeNull();
// When the permission times out
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(permissionTimeoutMs + 1);
});
// Then the hook consumer should be notified of the error
expect(result.current.error).toBeInstanceOf(errors_1.UnresponsiveDeviceError);
expect(result.current.devicePermissionState).toEqual("requested");
});
});
describe("When device permission is granted", () => {
const mockedGetGenuineCheckFromDeviceId = jest.fn();
it("should not throw UnresponsiveDeviceError and set permission state to granted", async () => {
// Given the getGenuineCheckFromDeviceId function will return a device permission granted
mockedGetGenuineCheckFromDeviceId.mockReturnValue((0, rxjs_1.of)({
socketEvent: { type: "device-permission-granted" },
lockedDevice: false,
}));
const { result } = (0, react_1.renderHook)(() => (0, useGenuineCheck_1.useGenuineCheck)({
getGenuineCheckFromDeviceId: mockedGetGenuineCheckFromDeviceId,
deviceId: "A_DEVICE_ID",
}));
await (0, react_1.act)(async () => {
jest.advanceTimersByTime(1);
});
// Then the hook consumer should not have errors and the permission state should be granted
expect(result.current.devicePermissionState).toEqual("granted");
expect(result.current.error).toBeNull();
});
});
});
//# sourceMappingURL=useGenuineCheck.test.js.map