Move the use-case index onto Learn so the pilot stories stay reachable, and make share images resolve on the host that serves the page.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
18abeb56dd
commit
9ea3f9fd0a
27 files changed
+656
-419
No files matched your search
+48
-10
@@ -69,42 +69,80 @@ describe("LearnPage", () => {
|
||||
vi.mocked(getAllBlogPosts).mockReturnValue(mockPosts);
|
||||
});
|
||||
|
||||
it("renders content lockup and ask organizer copy", () => {
|
||||
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 groups/,
|
||||
/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 one card per post (single responsive grid, no duplication)", () => {
|
||||
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);
|
||||
expect(links).toHaveLength(mockPosts.length + 1);
|
||||
|
||||
expect(links[0]).toHaveAttribute(
|
||||
expect(links[0]).toHaveAttribute("href", "/how-it-works");
|
||||
expect(links[1]).toHaveAttribute(
|
||||
"href",
|
||||
"/blog/resolving-active-conflicts",
|
||||
);
|
||||
expect(links[1]).toHaveAttribute(
|
||||
expect(links[2]).toHaveAttribute(
|
||||
"href",
|
||||
"/blog/operational-security-mutual-aid",
|
||||
);
|
||||
expect(within(grid).queryByText("April 15, 2025")).not.toBeInTheDocument();
|
||||
|
||||
// <picture> with a smd source provides the orientation swap without a
|
||||
// duplicate card per breakpoint.
|
||||
const sources = grid?.querySelectorAll(
|
||||
const sources = grid.querySelectorAll(
|
||||
"picture source[media='(min-width: 530px)']",
|
||||
);
|
||||
expect(sources?.length).toBe(mockPosts.length);
|
||||
expect(sources.length).toBe(mockPosts.length + 1);
|
||||
|
||||
const icons = grid.querySelectorAll("img");
|
||||
for (const icon of icons) {
|
||||
expect(icon).toHaveAttribute("alt", "");
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -69,6 +69,14 @@ describe("UseCaseCompletedRulePage", () => {
|
||||
screen.getByRole("heading", { name: fixture.title }),
|
||||
).toBeInTheDocument();
|
||||
if (slug === "mutual-aid-colorado") {
|
||||
expect(
|
||||
screen.getByText(/political solidarity rather than charity/),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(/Food Not Bombs is not a charity/),
|
||||
).not.toBeInTheDocument();
|
||||
}
|
||||
if (slug === "food-not-bombs") {
|
||||
expect(
|
||||
screen.getByText(/Food Not Bombs is not a charity/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
@@ -1,35 +1,19 @@
|
||||
import { describe, test, expect, vi } from "vitest";
|
||||
import { screen } from "@testing-library/react";
|
||||
import { renderWithProviders as render } from "../utils/test-utils";
|
||||
import UseCasesPage from "../../app/(marketing)/use-cases/page";
|
||||
import messages from "../../messages/en/index";
|
||||
|
||||
vi.mock("next/dynamic", () => ({
|
||||
default: () => {
|
||||
const Component = vi.fn(() => (
|
||||
<section data-testid="related-articles">Related articles</section>
|
||||
));
|
||||
return Component;
|
||||
},
|
||||
const { redirect } = vi.hoisted(() => ({
|
||||
redirect: vi.fn((url) => {
|
||||
throw new Error(`NEXT_REDIRECT:${url}`);
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("next/link", () => ({
|
||||
default: ({ children, href, ...props }) => (
|
||||
<a href={href} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
vi.mock("next/navigation", () => ({
|
||||
redirect,
|
||||
}));
|
||||
|
||||
describe("UseCasesPage", () => {
|
||||
const links = messages.pages.useCases.caseStudyTiles.links;
|
||||
|
||||
test("renders case study tiles as links to detail pages", () => {
|
||||
render(<UseCasesPage />);
|
||||
|
||||
for (const link of links) {
|
||||
const anchor = screen.getByRole("link", { name: link.ariaLabel });
|
||||
expect(anchor).toHaveAttribute("href", link.href);
|
||||
}
|
||||
test("sends the use cases index to Learn", () => {
|
||||
expect(() => UseCasesPage()).toThrow("NEXT_REDIRECT:/learn");
|
||||
expect(redirect).toHaveBeenCalledWith("/learn");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user