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

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

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

  const input = getByTestId("input1");
  expect(input).toBeTruthy();
  expect(input.getAttribute("value")).toBe("100");

  expect(onChange).toBeCalledTimes(0);
  fireEvent.change(input, { target: { value: "test" } });
  expect(onChange).toBeCalledTimes(1);
  expect(onChange).toHaveBeenLastCalledWith("test");

  expect(onBlur).toBeCalledTimes(0);
  fireEvent.blur(input);
  expect(onBlur).toBeCalledTimes(1);

  expect(getByTestId("input1")).not.toHaveClass("is-invalid");

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

  expect(getByTestId("input1").getAttribute("readonly")).toBeNull();
  expect(getByTestId("input1").getAttribute("disabled")).toBeNull();
  expect(getByTestId("input1").getAttribute("autocomplete")).toBe("false");

  expect(getByTestId("input1")).toHaveClass("my-class-name");
  expect(getByTestId("input1").getAttribute("type")).toBe("text");
});

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

test("should show label", () => {
  const { getByTestId, queryByTestId } = render(
    <Input name="name1" value="100" 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(
    <Input
      className="my-class-name"
      name="1"
      value="100"
      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(
    <Input
      className="my-class-name"
      name="1"
      value="100"
      label="My label"
      onChange={() => {}}
      data-testid="input1"
      help="help msg"
    />
  );

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

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

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

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

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

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

  expect(getByTestId("input1").getAttribute("autocomplete")).toBe("true");
});

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

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

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

  expect(getByTestId("input1").getAttribute("type")).toBe("password");
});

test("should show input prepend and append", () => {
  const { getByTestId } = render(
    <Input
      data-testid="input"
      inputAppend="$"
      inputPrepend="@"
      label="My label"
      name="name"
      onChange={() => {}}
      value="100"
    />
  );

  expect(getByTestId("input-group-prepend-text")).toHaveTextContent("@");
  expect(getByTestId("input-group-append-text")).toHaveTextContent("$");
});
