import React from "react";
import "@testing-library/jest-dom/extend-expect";
import { render, fireEvent } from "@testing-library/react";
import { Checkbox } from "../../";

test("Checkbox basic props", () => {
  const onChange = jest.fn();

  const { getByTestId, queryByTestId } = render(
    <Checkbox
      className="my-class-name"
      name="name1"
      label="My label"
      onChange={onChange}
      data-testid="input1"
    />
  );

  const checkbox = getByTestId("input1");

  expect(checkbox).toBeTruthy();
  expect(checkbox.getAttribute("checked")).toBeNull();

  expect(onChange).toBeCalledTimes(0);
  fireEvent.click(checkbox);
  expect(onChange).toBeCalledTimes(1);
  expect(onChange).toHaveBeenLastCalledWith(true);

  expect(checkbox).not.toHaveClass("is-invalid");

  expect(queryByTestId("input1-error")).toBeNull();
  expect(queryByTestId("input1-help")).toBeNull();

  expect(checkbox.getAttribute("readonly")).toBeNull();
  expect(checkbox.getAttribute("disabled")).toBeNull();

  expect(checkbox).toHaveClass("my-class-name");
});

test("should show default testid", () => {
  const { queryByTestId } = render(<Checkbox name="name1" label="My label" onChange={() => {}} />);
  expect(queryByTestId("honeyui-input")).not.toBeNull();
});

test("should show label", () => {
  const { getByTestId } = render(
    <Checkbox name="name1" label="My label" onChange={() => {}} data-testid="input1" />
  );

  expect(getByTestId("input1").getAttribute("id")).toBe("name1");
  expect(getByTestId("input1-label")).toHaveTextContent("My label");
  expect(getByTestId("input1-label").getAttribute("for")).toBe("name1");
});

test("should show error", () => {
  const { getByTestId } = render(
    <Checkbox
      className="my-class-name"
      name="1"
      label="My label"
      onChange={() => {}}
      data-testid="input1"
      error="error msg"
    />
  );

  expect(getByTestId("input1")).toHaveClass("is-invalid");
  expect(getByTestId("input1-error")).toHaveTextContent("error msg");
  expect(getByTestId("input1-error")).toHaveClass("invalid-feedback");
});

test("should show help", () => {
  const { getByTestId } = render(
    <Checkbox
      className="my-class-name"
      name="1"
      label="My label"
      onChange={() => {}}
      data-testid="input1"
      help="help msg"
    />
  );

  expect(getByTestId("input1-help")).toHaveTextContent("help msg");
});

test("should be readOnly", () => {
  const { getByTestId } = render(
    <Checkbox name="1" label="My label" onChange={() => {}} data-testid="input1" readOnly />
  );

  expect(getByTestId("input1").getAttribute("readonly")).toBe("");
});

test("should be disabled", () => {
  const { getByTestId } = render(
    <Checkbox name="1" label="My label" onChange={() => {}} data-testid="input1" disabled />
  );

  expect(getByTestId("input1").getAttribute("disabled")).toBe("");
});

test("should be required", () => {
  const { getByTestId } = render(
    <Checkbox name="input1" label="My label" onChange={() => {}} data-testid="input1" required />
  );

  expect(getByTestId("input1").getAttribute("required")).toBe("");
});

test("Checkbox specific props", () => {
  const onChange = jest.fn();

  const { getByTestId } = render(
    <Checkbox
      className="my-class-name"
      name="name1"
      label="My label"
      onChange={onChange}
      data-testid="checkbox1"
      checked
    />
  );

  const checkbox = getByTestId("checkbox1");
  expect(checkbox).toBeTruthy();
  expect(checkbox.getAttribute("checked")).not.toBeNull();
});

test("Checkbox interactions props", () => {
  const onChange = jest.fn();
  const { getByTestId, rerender } = render(
    <Checkbox
      className="my-class-name"
      name="name1"
      label="My label"
      onChange={onChange}
      data-testid="checkbox1"
      checked={true}
    />
  );
  expect(getByTestId("checkbox1").getAttribute("checked")).not.toBeNull();
  fireEvent.click(getByTestId("checkbox1"));
  expect(onChange).lastCalledWith(false);

  rerender(
    <Checkbox
      className="my-class-name"
      name="name1"
      label="My label"
      onChange={onChange}
      data-testid="checkbox1"
      checked={false}
    />
  );
  fireEvent.click(getByTestId("checkbox1"));
  expect(onChange).lastCalledWith(true);
});
