mirror of
https://github.com/gethomepage/homepage.git
synced 2026-04-04 09:11:21 -07:00
Chore: homepage tests (#6278)
This commit is contained in:
76
src/components/widgets/widget/container.test.jsx
Normal file
76
src/components/widgets/widget/container.test.jsx
Normal file
@@ -0,0 +1,76 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
|
||||
import Container, { getAllClasses } from "./container";
|
||||
import PrimaryText from "./primary_text";
|
||||
import Raw from "./raw";
|
||||
import SecondaryText from "./secondary_text";
|
||||
import WidgetIcon from "./widget_icon";
|
||||
|
||||
function FakeIcon(props) {
|
||||
return <svg data-testid="fake-icon" {...props} />;
|
||||
}
|
||||
|
||||
describe("components/widgets/widget/container", () => {
|
||||
it("getAllClasses supports boxedWidgets + cardBlur and right alignment", () => {
|
||||
const boxed = getAllClasses({ style: { header: "boxedWidgets", cardBlur: "md" } }, "x");
|
||||
expect(boxed).toContain("backdrop-blur-md");
|
||||
expect(boxed).toContain("x");
|
||||
|
||||
const right = getAllClasses({ style: { isRightAligned: true } }, "y");
|
||||
expect(right).toContain("justify-center");
|
||||
expect(right).toContain("y");
|
||||
expect(right).not.toContain("max-w:full");
|
||||
});
|
||||
|
||||
it("renders an anchor when href is provided and prefers options.target over settings.target", () => {
|
||||
renderWithProviders(
|
||||
<Container options={{ href: "http://example", target: "_self" }}>
|
||||
<WidgetIcon icon={FakeIcon} />
|
||||
<PrimaryText>P</PrimaryText>
|
||||
<SecondaryText>S</SecondaryText>
|
||||
<Raw>
|
||||
<div data-testid="bottom">B</div>
|
||||
</Raw>
|
||||
</Container>,
|
||||
{ settings: { target: "_blank" } },
|
||||
);
|
||||
|
||||
const link = screen.getByRole("link");
|
||||
expect(link.getAttribute("href")).toBe("http://example");
|
||||
expect(link.getAttribute("target")).toBe("_self");
|
||||
expect(screen.getByTestId("fake-icon")).toBeInTheDocument();
|
||||
expect(screen.getByText("P")).toBeInTheDocument();
|
||||
expect(screen.getByText("S")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("bottom")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders only bottom content when children are a single Raw element", () => {
|
||||
const { container } = renderWithProviders(
|
||||
<Container options={{}}>
|
||||
<Raw>
|
||||
<div data-testid="only-bottom">B</div>
|
||||
</Raw>
|
||||
</Container>,
|
||||
{ settings: { target: "_self" } },
|
||||
);
|
||||
|
||||
expect(container.querySelector(".widget-inner")).toBeNull();
|
||||
expect(screen.getByTestId("only-bottom")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not crash when clicked (href case is normal link)", () => {
|
||||
renderWithProviders(
|
||||
<Container options={{ href: "http://example" }}>
|
||||
<Raw>
|
||||
<div>Bottom</div>
|
||||
</Raw>
|
||||
</Container>,
|
||||
{ settings: { target: "_self" } },
|
||||
);
|
||||
});
|
||||
});
|
||||
23
src/components/widgets/widget/container_button.test.jsx
Normal file
23
src/components/widgets/widget/container_button.test.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import ContainerButton from "./container_button";
|
||||
import Raw from "./raw";
|
||||
|
||||
describe("components/widgets/widget/container_button", () => {
|
||||
it("invokes callback on click", () => {
|
||||
const cb = vi.fn();
|
||||
render(
|
||||
<ContainerButton options={{}} callback={cb}>
|
||||
<Raw>
|
||||
<div>child</div>
|
||||
</Raw>
|
||||
</ContainerButton>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole("button"));
|
||||
expect(cb).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
23
src/components/widgets/widget/container_form.test.jsx
Normal file
23
src/components/widgets/widget/container_form.test.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import ContainerForm from "./container_form";
|
||||
|
||||
describe("components/widgets/widget/container_form", () => {
|
||||
it("calls callback on submit", () => {
|
||||
const cb = vi.fn((e) => e.preventDefault());
|
||||
|
||||
const { container } = render(
|
||||
<ContainerForm options={{}} callback={cb}>
|
||||
{[<div key="c">child</div>]}
|
||||
</ContainerForm>,
|
||||
);
|
||||
|
||||
const form = container.querySelector("form");
|
||||
fireEvent.submit(form);
|
||||
|
||||
expect(cb).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
24
src/components/widgets/widget/container_link.test.jsx
Normal file
24
src/components/widgets/widget/container_link.test.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import ContainerLink from "./container_link";
|
||||
import Raw from "./raw";
|
||||
|
||||
describe("components/widgets/widget/container_link", () => {
|
||||
it("renders an anchor using href or url", () => {
|
||||
const { rerender } = render(<ContainerLink options={{ href: "http://a" }} target="_self" />);
|
||||
expect(screen.getByRole("link").getAttribute("href")).toBe("http://a");
|
||||
expect(screen.getByRole("link").getAttribute("target")).toBe("_self");
|
||||
|
||||
rerender(
|
||||
<ContainerLink options={{ url: "http://b" }} target="_blank">
|
||||
<Raw>
|
||||
<div>child</div>
|
||||
</Raw>
|
||||
</ContainerLink>,
|
||||
);
|
||||
expect(screen.getByRole("link").getAttribute("href")).toBe("http://b");
|
||||
});
|
||||
});
|
||||
15
src/components/widgets/widget/error.test.jsx
Normal file
15
src/components/widgets/widget/error.test.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
|
||||
import Error from "./error";
|
||||
|
||||
describe("components/widgets/widget/error", () => {
|
||||
it("renders the api_error message", () => {
|
||||
renderWithProviders(<Error options={{}} />, { settings: { target: "_self" } });
|
||||
expect(screen.getByText("widget.api_error")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
13
src/components/widgets/widget/primary_text.test.jsx
Normal file
13
src/components/widgets/widget/primary_text.test.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import PrimaryText from "./primary_text";
|
||||
|
||||
describe("components/widgets/widget/primary_text", () => {
|
||||
it("renders children", () => {
|
||||
render(<PrimaryText>hello</PrimaryText>);
|
||||
expect(screen.getByText("hello")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
20
src/components/widgets/widget/raw.test.jsx
Normal file
20
src/components/widgets/widget/raw.test.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import Raw from "./raw";
|
||||
|
||||
describe("components/widgets/widget/raw", () => {
|
||||
it("renders nested Raw content", () => {
|
||||
render(
|
||||
<Raw>
|
||||
<Raw>
|
||||
<div>inner</div>
|
||||
</Raw>
|
||||
</Raw>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("inner")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
38
src/components/widgets/widget/resource.test.jsx
Normal file
38
src/components/widgets/widget/resource.test.jsx
Normal file
@@ -0,0 +1,38 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { UsageBar } = vi.hoisted(() => ({
|
||||
UsageBar: vi.fn(({ percent }) => <div data-testid="usagebar" data-percent={String(percent)} />),
|
||||
}));
|
||||
|
||||
vi.mock("../resources/usage-bar", () => ({
|
||||
default: UsageBar,
|
||||
}));
|
||||
|
||||
import Resource from "./resource";
|
||||
|
||||
function FakeIcon(props) {
|
||||
return <svg data-testid="resource-icon" {...props} />;
|
||||
}
|
||||
|
||||
describe("components/widgets/widget/resource", () => {
|
||||
it("renders icon/value/label and shows usage bar when percentage is set", () => {
|
||||
render(<Resource icon={FakeIcon} value="v" label="l" percentage={0} />);
|
||||
|
||||
expect(screen.getByTestId("resource-icon")).toBeInTheDocument();
|
||||
expect(screen.getByText("v")).toBeInTheDocument();
|
||||
expect(screen.getByText("l")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("usagebar").getAttribute("data-percent")).toBe("0");
|
||||
});
|
||||
|
||||
it("renders expanded values when expanded", () => {
|
||||
render(
|
||||
<Resource icon={FakeIcon} value="v" label="l" expanded expandedValue="ev" expandedLabel="el" percentage={10} />,
|
||||
);
|
||||
|
||||
expect(screen.getByText("ev")).toBeInTheDocument();
|
||||
expect(screen.getByText("el")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
31
src/components/widgets/widget/resources.test.jsx
Normal file
31
src/components/widgets/widget/resources.test.jsx
Normal file
@@ -0,0 +1,31 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import Resource from "./resource";
|
||||
import Resources from "./resources";
|
||||
import WidgetLabel from "./widget_label";
|
||||
|
||||
function FakeIcon() {
|
||||
return <svg />;
|
||||
}
|
||||
|
||||
describe("components/widgets/widget/resources", () => {
|
||||
it("filters children to Resource + WidgetLabel and wraps them in a link", () => {
|
||||
render(
|
||||
<Resources options={{ href: "http://example" }} target="_self" additionalClassNames="x">
|
||||
{[
|
||||
<Resource key="r" icon={FakeIcon} value="v" label="l" />,
|
||||
<WidgetLabel key="w" label="Label" />,
|
||||
<div key="o">Other</div>,
|
||||
]}
|
||||
</Resources>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("link").getAttribute("href")).toBe("http://example");
|
||||
expect(screen.getByText("v")).toBeInTheDocument();
|
||||
expect(screen.getByText("Label")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Other")).toBeNull();
|
||||
});
|
||||
});
|
||||
13
src/components/widgets/widget/secondary_text.test.jsx
Normal file
13
src/components/widgets/widget/secondary_text.test.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import SecondaryText from "./secondary_text";
|
||||
|
||||
describe("components/widgets/widget/secondary_text", () => {
|
||||
it("renders children", () => {
|
||||
render(<SecondaryText>world</SecondaryText>);
|
||||
expect(screen.getByText("world")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
30
src/components/widgets/widget/widget_icon.test.jsx
Normal file
30
src/components/widgets/widget/widget_icon.test.jsx
Normal file
@@ -0,0 +1,30 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import WidgetIcon from "./widget_icon";
|
||||
|
||||
function FakeIcon(props) {
|
||||
return <svg data-testid="icon" {...props} />;
|
||||
}
|
||||
|
||||
describe("components/widgets/widget/widget_icon", () => {
|
||||
it("applies size classes and pulse animation", () => {
|
||||
render(
|
||||
<>
|
||||
<WidgetIcon icon={FakeIcon} size="s" />
|
||||
<WidgetIcon icon={FakeIcon} size="m" />
|
||||
<WidgetIcon icon={FakeIcon} size="l" pulse />
|
||||
<WidgetIcon icon={FakeIcon} size="xl" />
|
||||
</>,
|
||||
);
|
||||
|
||||
const icons = screen.getAllByTestId("icon");
|
||||
expect(icons[0].getAttribute("class")).toContain("w-5 h-5");
|
||||
expect(icons[1].getAttribute("class")).toContain("w-6 h-6");
|
||||
expect(icons[2].getAttribute("class")).toContain("w-8 h-8");
|
||||
expect(icons[2].getAttribute("class")).toContain("animate-pulse");
|
||||
expect(icons[3].getAttribute("class")).toContain("w-10 h-10");
|
||||
});
|
||||
});
|
||||
13
src/components/widgets/widget/widget_label.test.jsx
Normal file
13
src/components/widgets/widget/widget_label.test.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import WidgetLabel from "./widget_label";
|
||||
|
||||
describe("components/widgets/widget/widget_label", () => {
|
||||
it("renders label text", () => {
|
||||
render(<WidgetLabel label="Label A" />);
|
||||
expect(screen.getByText("Label A")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user