import { render } from "@testing-library/react";

import { Select } from "../Select";

describe("rendering Select", () => {
  describe("initial state", () => {
    it("has default class select", () => {
      const { getByTestId } = render(<Select data-testid="test-id" />);
      expect(getByTestId("test-id")).toHaveClass("select");
    });
    it("has generated id", () => {
      const { getByTestId } = render(<Select data-testid="test-id" />);
      const pattern = /id-\d+/;
      expect(
        pattern.test(getByTestId("test-id").getAttribute("id")),
      ).toBeTruthy();
    });
    it("name attribute is set to id when its not defined", () => {
      const { getByTestId } = render(<Select data-testid="test-id" />);
      expect(getByTestId("test-id").getAttribute("name")).toBe(
        getByTestId("test-id").getAttribute("id"),
      );
    });
  });
  describe("passed props", () => {
    const options = ["option1", { text: "option2", value: "option2" }];
    it("renders children", () => {
      const { getByText } = render(<Select data-testid="test-id">test</Select>);
      expect(getByText("test")).toBeInTheDocument();
    });
    it("has is-invalid class when isInvalid prop is passed", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" isInvalid />,
      );
      expect(getByTestId("test-id")).toHaveClass("is-invalid");
    });
    it("has select--large class when size prop is set to large", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" size="large" />,
      );
      expect(getByTestId("test-id")).toHaveClass("select--large");
    });
    ["shrink", "fullwidth"].map((width) => {
      it(`has select--${width} class when width prop is set to ${width}`, () => {
        const { getByTestId } = render(
          <Select data-testid="test-id" width={width} />,
        );
        expect(getByTestId("test-id")).toHaveClass(`select--${width}`);
      });
    });
    it("has additional class when className is set", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" className="test-class" />,
      );
      expect(getByTestId("test-id")).toHaveClass("select");
      expect(getByTestId("test-id")).toHaveClass("test-class");
    });
    it("id attribute is set to id prop when prop is passed", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" id="test" />,
      );
      expect(getByTestId("test-id").getAttribute("id")).toBe("test");
    });
    it("name attribute is set to id when its not defined and id is prop is set", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" id="test" />,
      );
      expect(getByTestId("test-id").getAttribute("name")).toBe(
        getByTestId("test-id").getAttribute("id"),
      );
    });
    it("name attribute is set to name prop when prop is passed", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" name="test" />,
      );
      expect(getByTestId("test-id").getAttribute("name")).toBe("test");
    });
    it("disabled attribute is set to true when isDisabled prop is passed", () => {
      const { getByTestId } = render(
        <Select data-testid="test-id" isDisabled />,
      );
      expect(getByTestId("test-id").disabled).toBe(true);
    });
    it("renders options", () => {
      const { container } = render(
        <Select options={options} data-testid="test-id" name="test" />,
      );
      const optionElements = container.querySelectorAll("option");
      expect(optionElements.length).toBe(2);
      for (let i in options) {
        expect(optionElements[i].getAttribute("value")).toBe(
          `option${parseInt(i) + 1}`,
        );
        expect(optionElements[i].textContent).toBe(`option${parseInt(i) + 1}`);
      }
    });
  });
});
