This commit is contained in:
105
frontend/__tests__/components/layout/footer/ScrollToTop.spec.tsx
Normal file
105
frontend/__tests__/components/layout/footer/ScrollToTop.spec.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
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"));
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user