Hayato Hasegawa 66ef76e823
fix(link): resolve issue where useHref is not working correctly (#5933)
* fix(link): correct props merge order in use-link to apply useHref

* chore(link): add changeset

* test(link): adjust href assertion to use getAttribute for compatibility

* fix(link): use routerLinkProps.href in handleLinkClick for consistency

* fix(link): process href with useHref before passing to useLinkProps

* test(link): comment out useHref provider test

* Revert "test(link): comment out useHref provider test"

This reverts commit de053f835fa57becf6e807a64c17339fc61d8689.

* Revert "fix(link): process href with useHref before passing to useLinkProps"

This reverts commit 81e5f7b8d1ea7002b9718cf521b5c6f2af79ac42.

* fix(provider): add `useHref` to provider context and integrate with `useLink`

* test(link): comment out useHref provider test

* fix(link): correct href handling in link component and update tests

* fix(link): simplify props handling by removing resolvedProps logic and reorder mergeProps usage

* fix(provider): remove `useHref` from provider context and related logic

* refactor(link): add spacing

* chore(changeset): add issue numbers

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-11-28 18:34:17 +08:00

102 lines
2.5 KiB
TypeScript

import type {UserEvent} from "@testing-library/user-event";
import * as React from "react";
import {render} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import {HeroUIProvider} from "@heroui/system";
import {Link} from "../src";
describe("Link", () => {
let user: UserEvent;
beforeEach(() => {
user = userEvent.setup();
});
it("should render correctly", () => {
const wrapper = render(<Link />);
expect(() => wrapper.unmount()).not.toThrow();
});
it("ref should be forwarded", () => {
const ref = React.createRef<HTMLAnchorElement>();
render(<Link ref={ref} />);
expect(ref.current).not.toBeNull();
});
it("should be no errors when href missing", () => {
const wrapper = render(<Link>Link</Link>);
expect(() => wrapper.unmount()).not.toThrow();
});
it('should show a link icon when "showAnchorIcon" is true', () => {
const {container} = render(
<Link showAnchorIcon href="#">
Link
</Link>,
);
expect(container.querySelector("svg")).not.toBeNull();
});
it("should trigger onPress function", async () => {
const onPress = jest.fn();
const {getByRole} = render(<Link onPress={onPress} />);
const link = getByRole("link");
await user.click(link);
expect(onPress).toHaveBeenCalled();
});
it("should trigger onClick function", async () => {
const onClick = jest.fn();
const {getByRole} = render(<Link onClick={onClick} />);
const link = getByRole("link");
await user.click(link);
expect(onClick).toHaveBeenCalled();
});
it('should have target="_blank" and rel="noopener noreferrer" when "isExternal" is true', () => {
const {container} = render(
<Link isExternal href="#">
Link
</Link>,
);
expect(container.querySelector("a")?.rel).toBe("noopener noreferrer");
expect(container.querySelector("a")?.target).toBe("_blank");
});
it('should have role="link" when "as" is different from "a"', () => {
const {container} = render(
<Link as="button" href="#">
Link
</Link>,
);
expect(container.querySelector("button")?.getAttribute("role")).toBe("link");
});
it("should apply useHref from provider", () => {
const useHref = (href: string) => `/example${href}`;
const {getByRole} = render(
<HeroUIProvider navigate={jest.fn()} useHref={useHref}>
<Link href="/test">Test Link</Link>
</HeroUIProvider>,
);
const link = getByRole("link");
expect(link.getAttribute("href")).toBe("/example/test");
});
});