149 lines
4.5 KiB
TypeScript
149 lines
4.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import { screen, within } from "@testing-library/react";
|
|
import { renderWithProviders as render } from "../utils/test-utils";
|
|
import LearnPage from "../../app/(marketing)/learn/page";
|
|
|
|
vi.mock("../../lib/content", () => ({
|
|
getAllBlogPosts: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("../../app/components/sections/AskOrganizer", () => ({
|
|
default: ({
|
|
title,
|
|
subtitle,
|
|
buttonText,
|
|
}: {
|
|
title: string;
|
|
subtitle: string;
|
|
buttonText: string;
|
|
}) => (
|
|
<div data-testid="ask-organizer">
|
|
<h2>{title}</h2>
|
|
<p>{subtitle}</p>
|
|
<button type="button">{buttonText}</button>
|
|
</div>
|
|
),
|
|
}));
|
|
|
|
const mockPosts = [
|
|
{
|
|
slug: "resolving-active-conflicts",
|
|
frontmatter: {
|
|
title: "Resolving Active Conflicts",
|
|
description: "Practical steps for resolving conflicts",
|
|
author: "CommunityRule",
|
|
date: "2025-04-15",
|
|
thumbnail: {
|
|
vertical: "resolving-active-conflicts-vertical.svg",
|
|
horizontal: "resolving-active-conflicts-horizontal.svg",
|
|
},
|
|
},
|
|
content: "",
|
|
htmlContent: "",
|
|
filePath: "resolving-active-conflicts.md",
|
|
lastModified: new Date(),
|
|
},
|
|
{
|
|
slug: "operational-security-mutual-aid",
|
|
frontmatter: {
|
|
title: "Operational Security for Mutual Aid",
|
|
description: "Tactics to protect members",
|
|
author: "CommunityRule",
|
|
date: "2025-04-10",
|
|
thumbnail: {
|
|
vertical: "operational-security-mutual-aid-vertical.svg",
|
|
horizontal: "operational-security-mutual-aid-horizontal.svg",
|
|
},
|
|
},
|
|
content: "",
|
|
htmlContent: "",
|
|
filePath: "operational-security-mutual-aid.md",
|
|
lastModified: new Date(),
|
|
},
|
|
];
|
|
|
|
describe("LearnPage", () => {
|
|
beforeEach(async () => {
|
|
vi.clearAllMocks();
|
|
const { getAllBlogPosts } = await import("../../lib/content");
|
|
vi.mocked(getAllBlogPosts).mockReturnValue(mockPosts);
|
|
});
|
|
|
|
it("renders the learn sections, with the guide first and the FAQ open", () => {
|
|
render(<LearnPage />);
|
|
|
|
expect(
|
|
screen.getByRole("heading", { name: /See how groups use/ }),
|
|
).toBeInTheDocument();
|
|
expect(
|
|
screen.getByRole("link", { name: "View Boulder Street Medics use case" }),
|
|
).toHaveAttribute("href", "/use-cases/boulder-county-street-medics");
|
|
expect(
|
|
screen.getByRole("heading", { name: "Who is this for?" }),
|
|
).toBeInTheDocument();
|
|
expect(screen.getByText("Organizing is hard")).toBeInTheDocument();
|
|
expect(
|
|
screen.getByText(
|
|
/Find answers to your questions and see how other communities/,
|
|
),
|
|
).toBeInTheDocument();
|
|
const guideLinks = screen.getAllByRole("link", { name: "Read the guide" });
|
|
expect(guideLinks.length).toBeGreaterThan(0);
|
|
for (const link of guideLinks) {
|
|
expect(link).toHaveAttribute("href", "/how-it-works");
|
|
}
|
|
expect(
|
|
screen.getByRole("heading", {
|
|
name: "Why horizontal communities need CommunityRule",
|
|
}),
|
|
).toBeInTheDocument();
|
|
expect(
|
|
screen.getByText("Transparent, inclusive decisions"),
|
|
).toBeInTheDocument();
|
|
|
|
const faq = screen.getByRole("region", {
|
|
name: "Get answers to your questions",
|
|
});
|
|
expect(faq).toHaveAttribute("id", "faq");
|
|
expect(
|
|
within(faq).getByRole("button", {
|
|
name: "Do we have to start from a blank page?",
|
|
}),
|
|
).toHaveAttribute("aria-expanded", "true");
|
|
|
|
expect(screen.getByTestId("ask-organizer")).toBeInTheDocument();
|
|
expect(screen.getByText("Still have questions?")).toBeInTheDocument();
|
|
});
|
|
|
|
it("renders the guide and one card per post, without a duplicate grid", () => {
|
|
render(<LearnPage />);
|
|
|
|
const grid = screen.getByTestId("learn-article-grid");
|
|
expect(grid).toHaveClass("smd:justify-center", "smd:flex-wrap");
|
|
|
|
const links = within(grid).getAllByRole("link");
|
|
expect(links).toHaveLength(mockPosts.length + 1);
|
|
|
|
expect(links[0]).toHaveAttribute("href", "/how-it-works");
|
|
expect(links[1]).toHaveAttribute(
|
|
"href",
|
|
"/blog/resolving-active-conflicts",
|
|
);
|
|
expect(links[2]).toHaveAttribute(
|
|
"href",
|
|
"/blog/operational-security-mutual-aid",
|
|
);
|
|
expect(within(grid).queryByText("April 15, 2025")).not.toBeInTheDocument();
|
|
|
|
const sources = grid.querySelectorAll(
|
|
"picture source[media='(min-width: 530px)']",
|
|
);
|
|
expect(sources.length).toBe(mockPosts.length + 1);
|
|
|
|
const icons = grid.querySelectorAll("img");
|
|
for (const icon of icons) {
|
|
expect(icon).toHaveAttribute("alt", "");
|
|
}
|
|
});
|
|
});
|