import { render } from "@opensea/testing-utils/render"
import { Tooltip } from "@opensea/ui-kit"
import { act, screen, waitFor } from "@testing-library/react"
import { userEvent } from "@testing-library/user-event"
import React from "react"
import { beforeEach, describe, expect, test, vi } from "vitest"
import { AppRouter } from "../../tests/AppRouter"
import { Link } from "./Link"
describe("", () => {
const windowOpenSpy = vi
.spyOn(window, "open")
.mockImplementation(function noop() {
return null
})
beforeEach(() => {
Object.defineProperty(window, "location", {
writable: true,
value: { ...window.location, assign: vi.fn(), open: windowOpenSpy },
})
})
test("absolute", () => {
render(Click me, {
wrapper: ({ children }) => {children},
})
const link = screen.getByRole("link", { name: "Click me" })
expect(link).toHaveAttribute("href", "https://opensea.io/")
})
test("nested", async () => {
const nestedClickHandler = vi.fn()
render(
Click me
,
{ wrapper: ({ children }) => {children} },
)
const [outerLink, innerLink] = screen.getAllByRole("link", {
name: "Click me",
})
expect(outerLink).toHaveAttribute("href", "https://opensea.io/")
expect(outerLink.nodeName).toEqual("A")
expect(innerLink.nodeName).toEqual("SPAN")
await userEvent.click(innerLink)
expect(nestedClickHandler).toHaveBeenCalled()
expect(windowOpenSpy).toHaveBeenCalledWith("https://google.com/", "_blank")
})
test("url object - external", () => {
render(
Click me
,
{ wrapper: ({ children }) => {children} },
)
const link = screen.getByRole("link", { name: "Click me" })
expect(link).toHaveAttribute("href", "https://opensea.io/?bar=baz")
})
test("url object", () => {
render(
Click me,
{ wrapper: ({ children }) => {children} },
)
const link = screen.getByRole("link", { name: "Click me" })
expect(link).toHaveAttribute("href", "/foo?bar=baz")
})
describe("should forward ref", () => {
test("external link", async () => {
render(
Click me
,
{
wrapper: ({ children }) => {children},
},
)
expect(
screen.queryByRole("tooltip", { name: "Hello world!" }),
).not.toBeInTheDocument()
await act(async () => {
await userEvent.hover(screen.getByRole("link", { name: "Click me" }))
})
await screen.findByRole("tooltip", { name: "Hello world!" })
expect(
screen.getByRole("tooltip", { name: "Hello world!" }),
).toBeInTheDocument()
})
test("internal link", async () => {
render(
Click me
,
{
wrapper: ({ children }) => {children},
},
)
expect(
screen.queryByRole("tooltip", { name: "Hello world!" }),
).not.toBeInTheDocument()
await act(async () => {
await userEvent.hover(screen.getByRole("link", { name: "Click me" }))
})
await screen.findByRole("tooltip", { name: "Hello world!" })
expect(
screen.getByRole("tooltip", { name: "Hello world!" }),
).toBeInTheDocument()
})
})
test("onNavigationCompleted", async () => {
const onNavigationCompleted = vi.fn()
render(
Click me
,
{ wrapper: ({ children }) => {children} },
)
const [_, innerLink] = screen.getAllByRole("link", {
name: "Click me",
})
await act(async () => {
await userEvent.click(innerLink)
})
await waitFor(() => {
const args = onNavigationCompleted.mock.calls[0]
expect(args[0]).toBeTypeOf("number")
expect(args[0]).toBeGreaterThan(0)
expect(args[1]).toBeTypeOf("number")
expect(args[1]).toBeGreaterThan(0)
})
})
})