106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
import { render } from "@solidjs/testing-library";
|
|
import { userEvent } from "@testing-library/user-event";
|
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
import { ScrollToTop } from "../../../../src/ts/components/layout/footer/ScrollToTop";
|
|
import * as CoreSignals from "../../../../src/ts/states/core";
|
|
|
|
describe("ScrollToTop", () => {
|
|
const getActivePageMock = vi.spyOn(CoreSignals, "getActivePage");
|
|
beforeEach(() => {
|
|
getActivePageMock.mockClear().mockReturnValue("account");
|
|
Object.defineProperty(window, "scrollY", { value: 0, writable: true });
|
|
});
|
|
|
|
function renderElement(): {
|
|
container: HTMLElement;
|
|
button: HTMLButtonElement;
|
|
} {
|
|
const { container } = render(() => <ScrollToTop />);
|
|
|
|
return {
|
|
// oxlint-disable-next-line no-non-null-assertion
|
|
container: container.children[0]! as HTMLElement,
|
|
// oxlint-disable-next-line no-non-null-assertion
|
|
button: container.querySelector("button")!,
|
|
};
|
|
}
|
|
|
|
it("renders with correct classes and structure", () => {
|
|
const { container, button } = renderElement();
|
|
|
|
expect(container).toHaveClass("content-grid", "ScrollToTop");
|
|
expect(button).toHaveClass("breakout");
|
|
expect(button.querySelector("i")).toHaveClass("fas", "fa-angle-double-up");
|
|
});
|
|
|
|
it("renders invisible when scrollY is 0", () => {
|
|
const { button } = renderElement();
|
|
|
|
expect(button).toHaveClass("opacity-0");
|
|
});
|
|
|
|
it("becomes visible when scrollY > 100 on non-test pages", () => {
|
|
const { button } = renderElement();
|
|
scrollTo(150);
|
|
|
|
expect(button).not.toHaveClass("opacity-0");
|
|
});
|
|
|
|
it("stays invisible on test page at scroll 0", () => {
|
|
getActivePageMock.mockReturnValue("test");
|
|
const { button } = renderElement();
|
|
|
|
expect(button).toHaveClass("opacity-0");
|
|
});
|
|
|
|
it("stays invisible on test page even with scroll > 100", () => {
|
|
getActivePageMock.mockReturnValue("test");
|
|
const { button } = renderElement();
|
|
scrollTo(150);
|
|
|
|
expect(button).toHaveClass("opacity-0");
|
|
});
|
|
|
|
it("becomes invisible when scroll < 100 on non-test pages", () => {
|
|
const { button } = renderElement();
|
|
scrollTo(150);
|
|
expect(button).not.toHaveClass("opacity-0");
|
|
|
|
scrollTo(50);
|
|
expect(button).toHaveClass("opacity-0");
|
|
});
|
|
|
|
it("scrolls to top and hides button on click", async () => {
|
|
const scrollToSpy = vi.fn();
|
|
window.scrollTo = scrollToSpy;
|
|
const { button } = renderElement();
|
|
scrollTo(150);
|
|
|
|
await userEvent.click(button);
|
|
|
|
expect(scrollToSpy).toHaveBeenCalledWith({
|
|
top: 0,
|
|
behavior: "smooth",
|
|
});
|
|
expect(button).toHaveClass("opacity-0");
|
|
});
|
|
|
|
it("cleans up scroll listener on unmount", () => {
|
|
const removeEventListenerSpy = vi.spyOn(window, "removeEventListener");
|
|
const { unmount } = render(() => <ScrollToTop />);
|
|
|
|
unmount();
|
|
|
|
expect(removeEventListenerSpy).toHaveBeenCalledWith(
|
|
"scroll",
|
|
expect.any(Function),
|
|
);
|
|
});
|
|
|
|
function scrollTo(value: number): void {
|
|
Object.defineProperty(window, "scrollY", { value, writable: true });
|
|
window.dispatchEvent(new Event("scroll"));
|
|
}
|
|
});
|