import * as R from "ramda";
import * as ReactNative from "react-native";

const { NativeModules } = ReactNative;

const OfflineAssetsBridge = {
  storeFiles: jest.fn((files) => {
    if (files.includes("fail")) throw new Error("Error storing file");

    return Promise.resolve(
      files.reduce((acc, curr) => {
        return R.assoc(curr.url, true, acc);
      }, {})
    );
  }),
  delete: jest.fn((file) => {
    if (file.includes("fail")) throw new Error("Error deleting file");

    return Promise.resolve(true);
  }),
  getFilesDirectory: jest.fn(() => Promise.resolve("/native/path/")),
};

NativeModules.OfflineAssetsBridge = OfflineAssetsBridge;

const { storeFiles, deleteFolders, getNativeRootPath } = require("..");

function clearMocks() {
  OfflineAssetsBridge.storeFiles.mockClear();
  OfflineAssetsBridge.delete.mockClear();
  OfflineAssetsBridge.getFilesDirectory.mockClear();
}

describe("fileManager", () => {
  describe("storeFiles", () => {
    beforeEach(clearMocks);

    it("calls the store file function of the native module with the provided args", async () => {
      const files = [{ url: "http://file" }, { url: "http://file2" }];
      const options = {};

      const result = await storeFiles(files, options);

      expect(OfflineAssetsBridge.storeFiles).toHaveBeenCalledWith(
        files,
        options
      );

      expect(result).toMatchSnapshot();
    });
  });

  describe("deleteFolders", () => {
    beforeEach(clearMocks);

    it("deletes each provided path", async () => {
      const folders = ["folder1", "folder2", "folder3"];

      const result = await deleteFolders(folders);

      expect.assertions(folders.length + 2);
      expect(result).toMatchSnapshot();
      expect(OfflineAssetsBridge.delete).toHaveBeenCalledTimes(folders.length);

      folders.forEach((folder, index) => {
        expect(OfflineAssetsBridge.delete).toHaveBeenNthCalledWith(
          index + 1,
          folder
        );
      });
    });
  });

  describe("getNativeRootPath", () => {
    beforeEach(clearMocks);

    it("returns the native root path", async () => {
      const nativePath = await OfflineAssetsBridge.getFilesDirectory();

      await expect(getNativeRootPath()).resolves.toEqual(nativePath);
    });
  });
});
