/**
 * @vitest-environment jsdom
 */

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

//name prop is required
describe("rendering Icon", () => {
  describe("initial state", () => {
    it("has default class icon", () => {
      const { getByTestId } = render(
        <Icon data-testid="test-id" name="test-name" />,
      );
      expect(getByTestId("test-id")).toHaveClass("icon");
    });

    it("has aria-hidden set to true", () => {
      const { getByTestId } = render(
        <Icon data-testid="test-id" name="test-name" />,
      );
      const attr = getByTestId("test-id").getAttribute("aria-hidden");
      expect(attr).toBeTruthy();
    });

    it("has default spritePath", () => {
      const { getByTestId } = render(
        <Icon data-testid="test-id" name="test-name" />,
      );
      const use = getByTestId("test-id").querySelector("use");
      expect(use.getAttribute("xlink:href")).toEqual("/sprite.svg#test-name");
    });
  });

  describe("passed props", () => {
    ["info", "success", "warning", "danger"].map((color) => {
      it(`has icon--${color} class when color is ${color}`, () => {
        const { getByTestId } = render(
          <Icon data-testid="test-id" color={color} name="test-name" />,
        );
        expect(getByTestId("test-id")).toHaveClass(`icon--${color}`);
      });
    });

    ["small", "medium", "large", "xlarge", "xxlarge", "huge"].map((size) => {
      it(`has icon--${size} class when size is ${size}`, () => {
        const { getByTestId } = render(
          <Icon data-testid="test-id" size={size} name="test-name" />,
        );
        expect(getByTestId("test-id")).toHaveClass(`icon--${size}`);
      });
    });

    it("has additional class when set", () => {
      const { getByTestId } = render(
        <Icon data-testid="test-id" className="test-class" name="test-name" />,
      );
      expect(getByTestId("test-id")).toHaveClass("icon");
      expect(getByTestId("test-id")).toHaveClass("test-class");
    });

    it("has aria-hidden set to undefined when alt is set", () => {
      const { getByTestId } = render(
        <Icon data-testid="test-id" alt="test-alt" name="test-name" />,
      );
      expect(getByTestId("test-id").getAttribute("aria-hidden")).toBeFalsy();
    });

    it("passes spritePath into xlinkhref", () => {
      const { getByTestId } = render(
        <Icon
          data-testid="test-id"
          spritePath="/test-path/"
          name="test-name"
        />,
      );
      const use = getByTestId("test-id").querySelector("use");
      expect(use.getAttribute("xlink:href")).toEqual("/test-path/#test-name");
    });

    it("passes context value into xlinkhref", () => {
      const { getByTestId } = render(
        <SpritePathContext.Provider value={"/test-path--context/"}>
          <Icon data-testid="test-id" name="test-name" />
        </SpritePathContext.Provider>,
      );
      const use = getByTestId("test-id").querySelector("use");
      expect(use.getAttribute("xlink:href")).toEqual(
        "/test-path--context/#test-name",
      );
    });

    it("passes spritePath into xlinkhref when context value is also defined", () => {
      const { getByTestId } = render(
        <SpritePathContext.Provider value={"/test-path--context/"}>
          <Icon
            data-testid="test-id"
            spritePath="/test-path--prop/"
            name="test-name"
          />
        </SpritePathContext.Provider>,
      );
      const use = getByTestId("test-id").querySelector("use");
      expect(use.getAttribute("xlink:href")).toEqual(
        "/test-path--prop/#test-name",
      );
    });
  });
});
