import { describe, it, expect, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import ContentContainer from "../../app/components/content/ContentContainer"; // Mock asset utils vi.mock("../../lib/assetUtils", () => ({ contentBlogTagPath: vi.fn((slug) => `/content/blog/${slug}-tag.svg`), contentCatalogSlugForFallback: vi.fn((slug) => { const catalog = [ "resolving-active-conflicts", "operational-security-mutual-aid", "making-decisions-without-hierarchy", ]; if (!slug) return catalog[0]; const index = Math.abs( slug.split("").reduce((acc, c) => acc + c.charCodeAt(0), 0), ) % catalog.length; return catalog[index]; }), CONTENT_CATALOG_SLUG_ORDER: [ "resolving-active-conflicts", "operational-security-mutual-aid", "making-decisions-without-hierarchy", ], })); // Mock blog post data const mockPost = { slug: "test-article", frontmatter: { title: "Test Article Title", description: "This is a test article description that should be long enough to test truncation and wrapping behavior.", author: "Test Author", date: "2025-04-15", }, }; // Pure presentational; no provider context needed. describe("ContentContainer", () => { it("renders with default props", () => { render(); // Check that the container exists const container = document.querySelector("div[class*='relative z-20']"); expect(container).toBeInTheDocument(); expect(container).toHaveClass( "relative", "z-20", "h-full", "flex", "flex-col", ); }); it("displays the icon correctly", () => { render(); const icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toBeInTheDocument(); expect(icon).toHaveAttribute( "src", "/content/blog/resolving-active-conflicts-tag.svg", ); expect(icon).toHaveClass("w-[60px]", "h-[30px]", "object-contain"); }); it("displays the article title", () => { render(); const title = screen.getByText("Test Article Title"); expect(title).toBeInTheDocument(); expect(title).toHaveClass( "font-bricolage", "font-medium", "text-[18px]", "leading-[120%]", "text-[var(--color-content-inverse-brand-royal)]", ); }); it("displays the article description", () => { render(); const description = screen.getByText(/This is a test article description/); expect(description).toBeInTheDocument(); expect(description).toHaveClass( "font-inter", "font-normal", "text-[12px]", "leading-[16px]", "text-[var(--color-content-inverse-brand-royal)]", ); }); it("displays the author and date metadata", () => { render(); expect(screen.getByText("Test Author")).toBeInTheDocument(); expect(screen.getByText("April 2025")).toBeInTheDocument(); }); it("applies correct width when specified", () => { render(); const container = document.querySelector("div[class*='relative z-20']"); expect(container).toHaveStyle("width: 300px"); }); it("applies default width when not specified", () => { render(); const container = document.querySelector("div[class*='relative z-20']"); expect(container).toHaveStyle("width: 200px"); }); it("has proper spacing between icon and text", () => { render(); const iconContainer = screen .getByAltText("Icon for Test Article Title") .closest("div"); const textContainer = screen.getByText("Test Article Title").closest("div"); // Check the content container (parent of icon) expect(iconContainer.parentElement).toHaveClass( "gap-[var(--measures-spacing-008)]", ); // Check the text container (parent of title) - it has responsive gap classes expect(textContainer.parentElement).toHaveClass("flex", "flex-col"); }); it("has proper metadata container styling", () => { render(); const metadataContainer = screen.getByText("Test Author").closest("div"); expect(metadataContainer).toHaveClass( "flex", "min-w-0", "items-end", "gap-[var(--measures-spacing-008)]", ); }); it("applies correct metadata text styling", () => { render(); const author = screen.getByText("Test Author"); expect(author).toHaveClass( "font-inter", "font-normal", "text-[10px]", "leading-[14px]", "text-[var(--color-content-inverse-brand-royal)]", ); const date = screen.getByText("April 2025"); expect(date).toHaveClass( "font-inter", "font-normal", "text-[10px]", "leading-[14px]", "text-[var(--color-content-inverse-brand-royal)]", ); }); it("uses per-article tag assets for catalog slugs", () => { const { rerender } = render(); let icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toHaveAttribute( "src", "/content/blog/resolving-active-conflicts-tag.svg", ); const post2 = { ...mockPost, slug: "operational-security-mutual-aid" }; rerender(); icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toHaveAttribute( "src", "/content/blog/operational-security-mutual-aid-tag.svg", ); const post3 = { ...mockPost, slug: "making-decisions-without-hierarchy" }; rerender(); icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toHaveAttribute( "src", "/content/blog/making-decisions-without-hierarchy-tag.svg", ); }); it("handles missing post data gracefully", () => { const incompletePost = { slug: "incomplete", frontmatter: { title: "Incomplete Post", // Missing other fields }, }; render(); expect(screen.getByText("Incomplete Post")).toBeInTheDocument(); }); it("applies correct responsive sizing for xs breakpoint", () => { render(); const icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toHaveClass("w-[60px]", "h-[30px]"); const title = screen.getByText("Test Article Title"); expect(title).toHaveClass("text-[18px]", "leading-[22px]"); const description = screen.getByText(/This is a test article description/); expect(description).toHaveClass("text-[12px]", "leading-[16px]"); }); it("applies correct responsive sizing for responsive breakpoint", () => { render(); const icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toHaveClass("w-[60px]", "h-[30px]"); const title = screen.getByText("Test Article Title"); expect(title).toHaveClass("text-[18px]", "leading-[120%]"); const description = screen.getByText(/This is a test article description/); expect(description).toHaveClass("text-[12px]", "leading-[16px]"); }); it("has proper accessibility attributes", () => { render(); const icon = screen.getByAltText("Icon for Test Article Title"); expect(icon).toHaveAttribute("alt", "Icon for Test Article Title"); }); it("handles long titles gracefully", () => { const longTitlePost = { ...mockPost, frontmatter: { ...mockPost.frontmatter, title: "This is a very long article title that should test how the component handles lengthy text content", }, }; render(); expect( screen.getByText(/This is a very long article title/), ).toBeInTheDocument(); }); it("handles long descriptions gracefully", () => { const longDescPost = { ...mockPost, frontmatter: { ...mockPost.frontmatter, description: "This is a very long article description that should test how the component handles lengthy text content and ensures proper wrapping and truncation behavior.", }, }; render(); expect( screen.getByText(/This is a very long article description/), ).toBeInTheDocument(); }); });