import { deleteAppData } from "./deleteAppData";
import { DeleteAppDataError, DeleteAppDataEventType, } from "./types";
import { DeviceModelId } from "@ledgerhq/devices";
jest.mock("@ledgerhq/hw-transport");
describe("deleteAppData", () => {
    let appName;
    let deviceModelId;
    let storageProvider;
    const setItem = jest.fn();
    const getItem = jest.fn();
    const removeItem = jest.fn();
    beforeEach(() => {
        appName = "MyApp";
        deviceModelId = DeviceModelId.stax;
        storageProvider = {
            getItem,
            setItem,
            removeItem,
        };
    });
    afterEach(() => {
        jest.clearAllMocks();
    });
    describe("success case", () => {
        it("should delete the app data by emitting relative events sequentially", done => {
            const deleteObservable = deleteAppData(appName, deviceModelId, storageProvider);
            const events = [];
            getItem.mockResolvedValue({
                appDataInfo: {
                    size: 6,
                    dataVersion: "test",
                    hasSettings: true,
                    hasData: true,
                    hash: "test",
                },
                appData: "bGVkZ2Vy", // base64 encoded "ledger"
            });
            removeItem.mockResolvedValue(undefined);
            deleteObservable.subscribe({
                next: (event) => events.push(event),
                complete: () => {
                    expect(events).toHaveLength(2);
                    expect(events[0]).toEqual({
                        type: DeleteAppDataEventType.AppDataDeleteStarted,
                    });
                    expect(events[1]).toEqual({
                        type: DeleteAppDataEventType.AppDataDeleted,
                    });
                    done();
                },
                error: (e) => {
                    done(e);
                },
            });
        });
        it("should emit specific event when there is no app data to delete", done => {
            const deleteObservable = deleteAppData(appName, deviceModelId, storageProvider);
            const events = [];
            getItem.mockResolvedValue(null);
            deleteObservable.subscribe({
                next: (event) => events.push(event),
                complete: () => {
                    expect(events).toHaveLength(2);
                    expect(events[0]).toEqual({
                        type: DeleteAppDataEventType.AppDataDeleteStarted,
                    });
                    expect(events[1]).toEqual({
                        type: DeleteAppDataEventType.NoAppDataToDelete,
                    });
                    done();
                },
                error: (e) => {
                    done(e);
                },
            });
        });
    });
    describe("error case", () => {
        it("should emit an error event when there is an error during the deletion process", done => {
            const deleteObservable = deleteAppData(appName, deviceModelId, storageProvider);
            const events = [];
            getItem.mockResolvedValue({
                appDataInfo: {
                    size: 6,
                    dataVersion: "test",
                    hasSettings: true,
                    hasData: true,
                    hash: "test",
                },
                appData: "bGVkZ2Vy", // base64 encoded "ledger"
            });
            removeItem.mockRejectedValue(new Error("Failed to delete app data"));
            // Subscribe to the observable to receive the delete events
            deleteObservable.subscribe({
                next: (event) => events.push(event),
                complete: () => {
                    done(new Error("Complete should not be called"));
                },
                error: (e) => {
                    try {
                        expect(events).toHaveLength(1);
                        expect(events[0]).toEqual({
                            type: DeleteAppDataEventType.AppDataDeleteStarted,
                        });
                        expect(e).toBeInstanceOf(DeleteAppDataError);
                        expect(e.message).toBe("Failed to delete app data");
                        done();
                    }
                    catch (error) {
                        done(error);
                    }
                },
            });
        });
        it("should emit an error event when there is an error getting the app data from storage", done => {
            const deleteObservable = deleteAppData(appName, deviceModelId, storageProvider);
            getItem.mockRejectedValue(new Error("Error fetching app data"));
            const events = [];
            deleteObservable.subscribe({
                next: (event) => events.push(event),
                complete: () => {
                    done(new Error("Complete should not be called"));
                },
                error: (e) => {
                    try {
                        expect(events).toHaveLength(1);
                        expect(events[0]).toEqual({
                            type: DeleteAppDataEventType.AppDataDeleteStarted,
                        });
                        expect(e).toEqual(new Error("Error fetching app data"));
                        done();
                    }
                    catch (error) {
                        done(error);
                    }
                },
            });
        });
        it("should emit an error event when there is an unkown error getting the app data from storage", done => {
            const deleteObservable = deleteAppData(appName, deviceModelId, storageProvider);
            getItem.mockRejectedValue(null);
            const events = [];
            deleteObservable.subscribe({
                next: (event) => events.push(event),
                complete: () => {
                    done(new Error("Complete should not be called"));
                },
                error: (e) => {
                    try {
                        expect(e).toEqual(new Error("Unknown error"));
                        done();
                    }
                    catch (error) {
                        done(error);
                    }
                },
            });
        });
    });
});
//# sourceMappingURL=deleteAppData.test.js.map