jest.mock("../../services/manifestsAPI");

import {
  render,
  cleanup,
  screen,
  fireEvent,
  waitFor,
} from "@testing-library/react";
import { ManifestsProvider, useManifestsContext } from "./ManifestsContext";
import { StatusProvider, useStatusContext } from "./StatusContext";

const checkBaseResults = (error, busy) => {
  expect(screen.getByTestId("error").innerHTML).toEqual(error);
  expect(screen.getByTestId("busy").innerHTML).toEqual(busy);
};

describe("ManifestContext", () => {
  describe("updateManifest", () => {
    beforeEach(async () => {
      const TestComp = () => {
        const { busy, updateManifest } = useManifestsContext();
        const { message, setMessage } = useStatusContext();
        const update = async (data) => {
          try {
            await updateManifest(1, data);
          } catch (e) {
            setMessage(e.message);
          }
        };

        return (
          <>
            <div data-testid="error">{message}</div>
            <div data-testid="busy">{busy.toString()}</div>
            <button
              data-testid="updateManifestNull"
              onClick={() => update(null)}
            />
            <button
              data-testid="updateManifestNoName"
              onClick={() => update({type:"forced"})}
            />
            <button
              data-testid="updateManifestNoType"
              onClick={() => update({name:"update"})}
            />
            <button
              data-testid="updateManifest"
              onClick={() =>
                update({
                  name: "new package",
                  type: "forced",
                  active: true,
                })
              }
            />
          </>
        );
      };
      render(
        <StatusProvider>
          <ManifestsProvider>
            <TestComp />
          </ManifestsProvider>
        </StatusProvider>
      );
    });

    afterEach(() => {
      cleanup();
    });

    it("initial state", () => {
      checkBaseResults("", "false");
    });

    it("updateManifestNull", async () => {
      fireEvent.click(screen.getByTestId("updateManifestNull"));
      await waitFor(() =>
        expect(screen.getByTestId("busy").innerHTML).toEqual("false")
      );
      checkBaseResults("No manifest data", "false");
    });

    it("updateManifestNoName", async () => {
      fireEvent.click(screen.getByTestId("updateManifestNoName"));
      await waitFor(() =>
        expect(screen.getByTestId("busy").innerHTML).toEqual("false")
      );
      checkBaseResults("Invalid manifest name", "false");
    });

    it("updateManifestNoType", async () => {
      fireEvent.click(screen.getByTestId("updateManifestNoType"));
      await waitFor(() =>
        expect(screen.getByTestId("busy").innerHTML).toEqual("false")
      );
      checkBaseResults("Invalid manifest type", "false");
    });

    it("updateManifest", async () => {
      fireEvent.click(screen.getByTestId("updateManifest"));
      await waitFor(() =>
        expect(screen.getByTestId("busy").innerHTML).toEqual("false")
      );
      checkBaseResults("", "false");
    });
  });
});