Files
community-rule/tests/components/Footer.test.tsx
T
adilallo ca928e306b Match the 3 Nov color ramps and size-based strokes, and replace leftover palette hex with tokens.
Drop Cookies Settings from the footer, link the Home features that already have pages, and give leftover routes their own descriptions.
2026-11-05 15:37:55 -07:00

126 lines
3.8 KiB
TypeScript

import React from "react";
import { renderWithProviders as render, screen } from "../utils/test-utils";
import { describe, it, expect } from "vitest";
import Footer from "../../app/components/navigation/Footer";
import {
componentTestSuite,
ComponentTestSuiteConfig,
} from "../utils/componentTestSuite";
type FooterProps = React.ComponentProps<typeof Footer>;
const baseProps: FooterProps = {};
const config: ComponentTestSuiteConfig<FooterProps> = {
component: Footer,
name: "Footer",
props: baseProps,
primaryRole: "contentinfo",
testCases: {
renders: true,
accessibility: true,
keyboardNavigation: false, // Footer is not primarily keyboard navigable
disabledState: false,
errorState: false,
},
};
componentTestSuite<FooterProps>(config);
describe("Footer (behavioral tests)", () => {
it("renders organization schema markup", () => {
render(<Footer />);
const script = document.querySelector('script[type="application/ld+json"]');
expect(script).toBeInTheDocument();
const schemaData = JSON.parse(script?.textContent || "{}");
expect(schemaData["@type"]).toBe("Organization");
expect(schemaData.name).toBe("Media Economies Design Lab");
});
it("renders organization name and contact", () => {
render(<Footer />);
expect(
screen.getAllByText("Media Economies Design Lab").length,
).toBeGreaterThan(0);
expect(
screen.getAllByRole("link", { name: "medlab@colorado.edu" }).length,
).toBeGreaterThan(0);
});
it("renders social media links", () => {
render(<Footer />);
expect(
screen.getAllByRole("link", { name: "Follow us on Bluesky" }).length,
).toBeGreaterThan(0);
expect(
screen.getAllByRole("link", { name: "View source on Gitea" }).length,
).toBeGreaterThan(0);
expect(
screen.getAllByRole("link", { name: "Follow us on Mastodon" }).length,
).toBeGreaterThan(0);
});
it("renders navigation links", () => {
render(<Footer />);
expect(
screen.getAllByRole("link", { name: "Use cases" }).length,
).toBeGreaterThan(0);
expect(
screen.getAllByRole("link", { name: "Learn" }).length,
).toBeGreaterThan(0);
expect(
screen.getAllByRole("link", { name: "About" }).length,
).toBeGreaterThan(0);
});
it("renders navigation links with baseline width-fit focus targets", () => {
render(<Footer />);
const useCases = screen.getAllByRole("link", { name: "Use cases" })[0];
expect(useCases).toHaveClass(
"w-fit",
"self-start",
"text-left",
"md:ml-auto",
"md:self-end",
"md:text-right",
"md:justify-end",
);
expect(useCases).not.toHaveClass("w-full");
const nav = screen.getByRole("navigation", { name: "Footer" });
expect(nav).toHaveClass(
"items-start",
"md:ml-auto",
"md:w-auto",
"md:items-end",
"md:text-right",
);
});
it("renders a CC BY-SA 4.0 license link instead of an all-rights-reserved notice", () => {
render(<Footer />);
const license = screen.getAllByRole("link", {
name: "Content licensed under CC BY-SA 4.0",
})[0];
expect(license).toHaveAttribute(
"href",
"https://creativecommons.org/licenses/by-sa/4.0/",
);
expect(license).toHaveAttribute("rel", "license");
expect(screen.queryByText(/all right reserved/i)).not.toBeInTheDocument();
});
it("renders legal links to privacy and terms pages", () => {
render(<Footer />);
expect(
screen.getAllByRole("link", { name: "Privacy Policy" })[0],
).toHaveAttribute("href", "/privacy");
expect(
screen.getAllByRole("link", { name: "Terms of Service" })[0],
).toHaveAttribute("href", "/terms");
expect(
screen.queryByRole("link", { name: "Cookies Settings" }),
).not.toBeInTheDocument();
});
});