import { composeStories } from "@storybook/react"
import { screen } from "@testing-library/react"
import React from "react"
import { expect, describe, test } from "vitest"
import { render } from "../../../tests/render"
import * as stories from "./Link.stories"

const { Default } = composeStories(stories)

describe("Link", () => {
  describe("preserves href", () => {
    test("absolute", () => {
      render(<Default href="http://example.com">Foobar</Default>)
      const link = screen.getByRole("link", { name: "Foobar" })
      expect(link).toHaveAttribute("href", "http://example.com/")
    })

    test("absolute - traling slash", () => {
      render(<Default href="http://example.com/">Foobar</Default>)
      const link = screen.getByRole("link", { name: "Foobar" })
      expect(link).toHaveAttribute("href", "http://example.com/")
    })
  })

  describe("url sanitization", () => {
    test("sanitizes email", () => {
      render(<Default href="mailto:hello@example.com">Foobar</Default>)
      const link = screen.getByRole("link", { name: "Foobar" })
      expect(link).toHaveAttribute("href", "mailto:hello@example.com")
    })

    test("sanitizes absolute paths", () => {
      render(<Default href="/example-path?query=1">Foobar</Default>)
      const link = screen.getByRole("link", { name: "Foobar" })
      expect(link).toHaveAttribute("href", "/example-path?query=1")
    })

    test("sanitizes javascript", () => {
      render(<Default href="javascript:alert(document.domain)">Foobar</Default>)
      const link = screen.getByRole("link", { name: "Foobar" })
      expect(link).toHaveAttribute("href", "about:blank")
    })

    test("sanitizes encoded javascript", () => {
      render(
        <Default
          href={decodeURIComponent("JaVaScRiP%0at:alert(document.domain)")}
        >
          Foobar
        </Default>,
      )

      const link = screen.getByRole("link", { name: "Foobar" })
      expect(link).toHaveAttribute("href", "about:blank")
    })
  })

  describe("rel & target properties", () => {
    test("addspropertries to external urls by default", () => {
      render(<Default />)
      const link = screen.getByRole("link", { name: "OpenSea" })
      expect(link).toHaveAttribute("target", "_blank")
      expect(link).toHaveAttribute("rel", "nofollow noopener")
    })

    test("does not add propertries to external urls when overriden", () => {
      render(<Default rel="" target="" />)
      const link = screen.getByRole("link", { name: "OpenSea" })
      expect(link).toHaveAttribute("target", "")
      expect(link).toHaveAttribute("rel", "")
    })
  })
})
