Implement use cases page
This commit is contained in:
@@ -109,4 +109,17 @@ describe("Icon (behavioral tests)", () => {
|
||||
const card = screen.getByRole("button");
|
||||
expect(card).toHaveAttribute("aria-label", "Test Title: Test Description");
|
||||
});
|
||||
|
||||
it("uses article semantics when interactive is false", () => {
|
||||
render(
|
||||
<Icon
|
||||
interactive={false}
|
||||
icon={<div>Icon</div>}
|
||||
title="Static Title"
|
||||
description="Static Description"
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByRole("article")).toBeInTheDocument();
|
||||
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from "react";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import RelatedArticles from "../../app/components/sections/RelatedArticles";
|
||||
import type { BlogPost } from "../../lib/content";
|
||||
import {
|
||||
renderWithProviders as render,
|
||||
screen,
|
||||
} from "../utils/test-utils";
|
||||
|
||||
vi.mock("next/link", () => ({
|
||||
default: ({
|
||||
@@ -63,7 +66,7 @@ const mockPosts: BlogPost[] = [
|
||||
},
|
||||
];
|
||||
|
||||
// Pure presentational; no provider context needed (mocked thumbnail + useIsMobile).
|
||||
// MessagesProvider required — container uses useMessages().
|
||||
describe("RelatedArticles", () => {
|
||||
it("renders without crashing", () => {
|
||||
render(
|
||||
@@ -86,4 +89,20 @@ describe("RelatedArticles", () => {
|
||||
expect(screen.queryByTestId("thumbnail-article-1")).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId("thumbnail-article-2")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("useCases variant shows localized stacked title", () => {
|
||||
render(
|
||||
<RelatedArticles
|
||||
relatedPosts={mockPosts}
|
||||
currentPostSlug="current"
|
||||
variant="useCases"
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
screen.getByRole("heading", {
|
||||
level: 2,
|
||||
name: /Tools to set your group up for success/,
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import CaseStudy from "../../../app/components/cards/CaseStudy";
|
||||
|
||||
describe("CaseStudy", () => {
|
||||
it("renders tile container", () => {
|
||||
const { container } = render(
|
||||
<CaseStudy surface="lavender" imageAlt="Mutual Aid Colorado logo" />,
|
||||
);
|
||||
expect(container.querySelector('[data-figma-node="21993-32352"]')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders built-in raster when visual is omitted (neutral)", () => {
|
||||
render(
|
||||
<CaseStudy surface="neutral" imageAlt="Food Not Bombs logo" />,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("img", { name: "Food Not Bombs logo" }),
|
||||
).toHaveAttribute("src");
|
||||
});
|
||||
|
||||
it("uses Mutual Aid vector on lavender surface", () => {
|
||||
const { container } = render(
|
||||
<CaseStudy surface="lavender" imageAlt="Mutual Aid Colorado logo" />,
|
||||
);
|
||||
expect(container.querySelector("img")?.getAttribute("src")).toContain(
|
||||
"case-study-mutual-aid.svg",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import Groups from "../../../app/components/sections/Groups";
|
||||
|
||||
describe("Groups", () => {
|
||||
it("renders a static icon tile grid", () => {
|
||||
const { container } = render(
|
||||
<Groups
|
||||
title="Who is this for?"
|
||||
items={[
|
||||
{
|
||||
icon: <span data-testid="ico-a">a</span>,
|
||||
title: "One",
|
||||
description: "First description text.",
|
||||
},
|
||||
{
|
||||
icon: <span data-testid="ico-b">b</span>,
|
||||
title: "Two",
|
||||
description: "Second description text.",
|
||||
},
|
||||
{
|
||||
icon: <span data-testid="ico-c">c</span>,
|
||||
title: "Three",
|
||||
description: "Third description text.",
|
||||
},
|
||||
{
|
||||
icon: <span data-testid="ico-d">d</span>,
|
||||
title: "Four",
|
||||
description: "Fourth description text.",
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { level: 2, name: "Who is this for?" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getAllByRole("article")).toHaveLength(4);
|
||||
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
||||
expect(
|
||||
container.querySelector('[data-figma-node="22085-860411"]'),
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import UseCasesOrgs from "../../../app/components/sections/UseCasesOrgs";
|
||||
|
||||
describe("UseCasesOrgs", () => {
|
||||
it("renders children", () => {
|
||||
const { container } = render(
|
||||
<UseCasesOrgs>
|
||||
<div>Child A</div>
|
||||
<div>Child B</div>
|
||||
</UseCasesOrgs>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Child A")).toBeInTheDocument();
|
||||
expect(screen.getByText("Child B")).toBeInTheDocument();
|
||||
expect(
|
||||
container.querySelector('[data-figma-node="21993-33687"]'),
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import PageHeader from "../../../app/components/type/PageHeader";
|
||||
|
||||
describe("PageHeader", () => {
|
||||
it("renders title and description", () => {
|
||||
render(
|
||||
<PageHeader
|
||||
title="Test title"
|
||||
description="Test description body."
|
||||
ctaText="Go"
|
||||
ctaHref="/create"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { level: 1, name: "Test title" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Test description body.")).toBeInTheDocument();
|
||||
expect(screen.getByRole("link", { name: "Go" })).toHaveAttribute(
|
||||
"href",
|
||||
"/create",
|
||||
);
|
||||
});
|
||||
|
||||
it("omits CTA when ctaText is absent", () => {
|
||||
render(
|
||||
<PageHeader title="Only title" description="Only description" />,
|
||||
);
|
||||
|
||||
expect(screen.queryByRole("link")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("omits description when omitted and renders stacked centered title lines", () => {
|
||||
render(
|
||||
<PageHeader
|
||||
title={["See how groups use", "CommunityRule"]}
|
||||
headingAlign="center"
|
||||
sectionMinimal
|
||||
/>,
|
||||
);
|
||||
|
||||
const heading = screen.getByRole("heading", { level: 1 });
|
||||
expect(heading).toHaveTextContent(/See how groups useCommunityRule/);
|
||||
expect(
|
||||
heading.querySelectorAll("span.block"),
|
||||
).toHaveLength(2);
|
||||
expect(screen.queryByRole("paragraph")).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("link")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders use-cases lg single-line title segments when singleLineTitleFromLg", () => {
|
||||
render(
|
||||
<PageHeader
|
||||
title={["See how groups use", "CommunityRule"]}
|
||||
headingAlign="center"
|
||||
sectionMinimal
|
||||
singleLineTitleFromLg
|
||||
/>,
|
||||
);
|
||||
|
||||
const heading = screen.getByRole("heading", { level: 1 });
|
||||
expect(heading).toHaveTextContent(/See how groups use CommunityRule/);
|
||||
expect(
|
||||
heading.querySelectorAll("span.block.lg\\:inline"),
|
||||
).toHaveLength(2);
|
||||
expect(heading.closest("section")).toHaveAttribute(
|
||||
"data-figma-node",
|
||||
"21004-24825",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import TripleStep from "../../../app/components/type/TripleStep";
|
||||
|
||||
describe("TripleStep", () => {
|
||||
it("renders heading, steps, and CTA", () => {
|
||||
render(
|
||||
<TripleStep
|
||||
heading="Get organized"
|
||||
steps={[
|
||||
{ title: "Step one", body: "Body one." },
|
||||
{ title: "Step two", body: "Body two." },
|
||||
{ title: "Step three", body: "Body three." },
|
||||
]}
|
||||
ctaText="Create Rule"
|
||||
ctaHref="/create"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { level: 2, name: "Get organized" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
document.querySelector('[data-figma-node="22084-859405"]'),
|
||||
).toBeTruthy();
|
||||
expect(screen.getByText("Step one")).toBeInTheDocument();
|
||||
expect(screen.getByRole("link", { name: "Create Rule" })).toHaveAttribute(
|
||||
"href",
|
||||
"/create",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -48,4 +48,45 @@ describe("TripleTextBlock", () => {
|
||||
);
|
||||
expect(screen.getByText("Only body.")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("useCases preset renders persistent section heading, column h3 titles, dual paragraphs, outline CTA", () => {
|
||||
const { container } = render(
|
||||
<TripleTextBlock
|
||||
layoutPreset="useCases"
|
||||
title="Why Horizontal groups need CommunityRule"
|
||||
ctaText="Setup your community"
|
||||
ctaHref="/create"
|
||||
columns={[
|
||||
{
|
||||
title: "Share Leadership",
|
||||
description: "First paragraph.",
|
||||
descriptionSecondary: "Second paragraph.",
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
container.querySelector('[data-figma-node="22085-860414"]'),
|
||||
).toBeTruthy();
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", {
|
||||
level: 2,
|
||||
name: "Why Horizontal groups need CommunityRule",
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", {
|
||||
level: 3,
|
||||
name: "Share Leadership",
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("First paragraph.")).toBeInTheDocument();
|
||||
expect(screen.getByText("Second paragraph.")).toBeInTheDocument();
|
||||
expect(screen.getByRole("link", { name: "Setup your community" })).toHaveAttribute(
|
||||
"href",
|
||||
"/create",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user