From b15f913a14d4b321b01013209d26a45414d5b0bb Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:42:35 -0600 Subject: [PATCH] Update storybook and tests --- app/components/ContentBanner.js | 6 +- content/blog/resolving-active-conflicts.md | 2 + .../resolving-active-conflicts-banner.svg | 9 ++ stories/ContentBanner.stories.js | 34 +++++++- tests/unit/ContentBanner.test.jsx | 83 ++++++++++++++----- tests/unit/ContentThumbnailTemplate.test.jsx | 53 +++++++++--- tests/unit/Header.test.jsx | 77 ++++++++--------- tests/unit/validation.test.js | 41 ++++++++- 8 files changed, 228 insertions(+), 77 deletions(-) create mode 100644 public/content/blog/resolving-active-conflicts-banner.svg diff --git a/app/components/ContentBanner.js b/app/components/ContentBanner.js index 75ff265..0615058 100644 --- a/app/components/ContentBanner.js +++ b/app/components/ContentBanner.js @@ -14,10 +14,14 @@ export default function ContentBanner({ post }) { }; const getBannerImageMd = (post) => { - // Use banner.horizontal when provided; fallback to default banner asset + // Use banner.horizontal when provided; fallback to horizontal thumbnail if (post.frontmatter?.banner?.horizontal) { return `/content/blog/${post.frontmatter.banner.horizontal}`; } + // Fallback to horizontal thumbnail, then default banner + if (post.frontmatter?.thumbnail?.horizontal) { + return `/content/blog/${post.frontmatter.thumbnail.horizontal}`; + } return getAssetPath("assets/Content_Banner_2.svg"); }; diff --git a/content/blog/resolving-active-conflicts.md b/content/blog/resolving-active-conflicts.md index 2c46eb7..8db30b4 100644 --- a/content/blog/resolving-active-conflicts.md +++ b/content/blog/resolving-active-conflicts.md @@ -8,6 +8,8 @@ related: thumbnail: vertical: "resolving-active-conflicts-vertical.svg" horizontal: "resolving-active-conflicts-horizontal.svg" +banner: + horizontal: "resolving-active-conflicts-banner.svg" background: color: "#E2EFFF" --- diff --git a/public/content/blog/resolving-active-conflicts-banner.svg b/public/content/blog/resolving-active-conflicts-banner.svg new file mode 100644 index 0000000..f9de149 --- /dev/null +++ b/public/content/blog/resolving-active-conflicts-banner.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/stories/ContentBanner.stories.js b/stories/ContentBanner.stories.js index e09c99b..1ccd8ae 100644 --- a/stories/ContentBanner.stories.js +++ b/stories/ContentBanner.stories.js @@ -8,6 +8,13 @@ const mockBlogPost = { "This is a sample article description that explains what the article covers.", author: "Sample Author", date: "2025-01-15", + thumbnail: { + horizontal: "resolving-active-conflicts-horizontal.svg", + vertical: "resolving-active-conflicts-vertical.svg", + }, + banner: { + horizontal: "resolving-active-conflicts-banner.svg", + }, }, htmlContent: "

This is the main content of the sample article.

It has multiple paragraphs.

", @@ -20,7 +27,7 @@ export default { docs: { description: { component: - "The ContentBanner component displays the header information for blog articles, including title, description, author, and date. Note: page background colors are applied at the blog page level using a hex color from frontmatter (background.color), not inside this component. Thumbnail images should be uploaded via the content pipeline to public/content/blog/ and referenced in frontmatter (thumbnail.horizontal / thumbnail.vertical).", + "The ContentBanner component displays the header information for blog articles, including title, description, author, and date.\n\nImages: sm uses thumbnail.horizontal; md+ uses banner.horizontal when provided, otherwise falls back to thumbnail.horizontal; final fallback is assets/Content_Banner_2.svg.\n\nNote: page background colors are applied at the blog page level using a hex color from frontmatter (background.color), not inside this component. Thumbnail and banner images should be uploaded via the content pipeline to public/content/blog/ and referenced in frontmatter.", }, }, }, @@ -38,6 +45,31 @@ export const Default = { }, }; +export const NoBannerFallbackToThumbnail = { + args: { + post: { + ...mockBlogPost, + frontmatter: { + ...mockBlogPost.frontmatter, + banner: undefined, + }, + }, + }, +}; + +export const NoImagesFallbackToDefault = { + args: { + post: { + ...mockBlogPost, + frontmatter: { + ...mockBlogPost.frontmatter, + thumbnail: undefined, + banner: undefined, + }, + }, + }, +}; + export const LongTitle = { args: { post: { diff --git a/tests/unit/ContentBanner.test.jsx b/tests/unit/ContentBanner.test.jsx index 97143c0..5437bee 100644 --- a/tests/unit/ContentBanner.test.jsx +++ b/tests/unit/ContentBanner.test.jsx @@ -30,6 +30,12 @@ const mockPost = { description: "This is a test article description", author: "Test Author", date: "2025-04-15", + thumbnail: { + horizontal: "test-article-horizontal.svg", + }, + banner: { + horizontal: "test-article-banner.svg", + }, }, }; @@ -39,7 +45,7 @@ describe("ContentBanner", () => { // Check that the banner container exists - it's the first div with the specific classes const banner = document.querySelector( - "div[class*='pt-[var(--measures-spacing-016)]']", + "div[class*='pt-[var(--measures-spacing-016)]']" ); expect(banner).toBeInTheDocument(); expect(banner).toHaveClass( @@ -54,7 +60,7 @@ describe("ContentBanner", () => { "xl:h-[504px]", "relative", "w-full", - "sm:overflow-hidden", + "sm:overflow-hidden" ); }); @@ -63,7 +69,7 @@ describe("ContentBanner", () => { // Check for background div with correct styling const backgroundDiv = document.querySelector( - "div[style*='background-image']", + "div[style*='background-image']" ); expect(backgroundDiv).toBeInTheDocument(); expect(backgroundDiv).toHaveClass( @@ -73,16 +79,16 @@ describe("ContentBanner", () => { "h-full", "bg-cover", "bg-no-repeat", - "aspect-[320/225.5]", + "aspect-[320/225.5]" ); }); - it("shows different background image at md breakpoint and above", () => { + it("shows banner image at md breakpoint and above", () => { render(); - // Check for the md+ background div + // Check for the md+ background div with banner image const mdBackgroundDiv = document.querySelector( - "div[style*='Content_Banner_2.svg']", + "div[style*='test-article-banner.svg']" ); expect(mdBackgroundDiv).toBeInTheDocument(); expect(mdBackgroundDiv).toHaveClass("hidden", "md:block"); @@ -98,7 +104,7 @@ describe("ContentBanner", () => { render(); expect( - screen.getByText("This is a test article description"), + screen.getByText("This is a test article description") ).toBeInTheDocument(); }); @@ -114,7 +120,7 @@ describe("ContentBanner", () => { // Check the content container div const contentContainer = document.querySelector( - "div[class*='relative z-10']", + "div[class*='relative z-10']" ); expect(contentContainer).toBeInTheDocument(); expect(contentContainer).toHaveClass( @@ -122,7 +128,7 @@ describe("ContentBanner", () => { "z-10", "h-full", "flex", - "flex-col", + "flex-col" ); }); @@ -135,7 +141,7 @@ describe("ContentBanner", () => { "font-medium", "text-[18px]", "leading-[120%]", - "text-[var(--color-content-inverse-brand-royal)]", + "text-[var(--color-content-inverse-brand-royal)]" ); const description = screen.getByText("This is a test article description"); @@ -144,7 +150,7 @@ describe("ContentBanner", () => { "font-normal", "text-[12px]", "leading-[16px]", - "text-[var(--color-content-inverse-brand-royal)]", + "text-[var(--color-content-inverse-brand-royal)]" ); }); @@ -157,7 +163,7 @@ describe("ContentBanner", () => { "font-normal", "text-[10px]", "leading-[14px]", - "text-[var(--color-content-inverse-brand-royal)]", + "text-[var(--color-content-inverse-brand-royal)]" ); const date = screen.getByText("April 2025"); @@ -166,7 +172,7 @@ describe("ContentBanner", () => { "font-normal", "text-[10px]", "leading-[14px]", - "text-[var(--color-content-inverse-brand-royal)]", + "text-[var(--color-content-inverse-brand-royal)]" ); }); @@ -175,7 +181,7 @@ describe("ContentBanner", () => { // Check the ContentContainer spacing const contentContainer = document.querySelector( - "div[class*='relative z-20']", + "div[class*='relative z-20']" ); expect(contentContainer).toHaveClass("gap-[var(--measures-spacing-012)]"); }); @@ -184,13 +190,13 @@ describe("ContentBanner", () => { render(); const outerContainer = document.querySelector( - "div[class*='pt-[var(--measures-spacing-016)]']", + "div[class*='pt-[var(--measures-spacing-016)]']" ); expect(outerContainer).toHaveClass( "pt-[var(--measures-spacing-016)]", "md:pt-[var(--measures-spacing-008)]", "lg:pt-[50px]", - "xl:pt-[112px]", + "xl:pt-[112px]" ); }); @@ -208,6 +214,45 @@ describe("ContentBanner", () => { expect(screen.getByText("Incomplete Post")).toBeInTheDocument(); }); + it("falls back to thumbnail.horizontal when banner.horizontal is missing", () => { + const postWithoutBanner = { + ...mockPost, + frontmatter: { + ...mockPost.frontmatter, + banner: undefined, + }, + }; + + render(); + + // Should use thumbnail.horizontal for md+ breakpoint + const mdBackgroundDiv = document.querySelector( + "div[style*='test-article-horizontal.svg']" + ); + expect(mdBackgroundDiv).toBeInTheDocument(); + expect(mdBackgroundDiv).toHaveClass("hidden", "md:block"); + }); + + it("falls back to default banner when no images are provided", () => { + const postWithoutImages = { + ...mockPost, + frontmatter: { + ...mockPost.frontmatter, + thumbnail: undefined, + banner: undefined, + }, + }; + + render(); + + // Should use default banner for md+ breakpoint + const mdBackgroundDiv = document.querySelector( + "div[style*='Content_Banner_2.svg']" + ); + expect(mdBackgroundDiv).toBeInTheDocument(); + expect(mdBackgroundDiv).toHaveClass("hidden", "md:block"); + }); + it("applies responsive text sizing", () => { render(); @@ -216,7 +261,7 @@ describe("ContentBanner", () => { "sm:text-[24px]", "md:text-[32px]", "lg:text-[44px]", - "xl:text-[64px]", + "xl:text-[64px]" ); const description = screen.getByText("This is a test article description"); @@ -224,7 +269,7 @@ describe("ContentBanner", () => { "sm:text-[14px]", "md:text-[14px]", "lg:text-[18px]", - "xl:text-[24px]", + "xl:text-[24px]" ); }); diff --git a/tests/unit/ContentThumbnailTemplate.test.jsx b/tests/unit/ContentThumbnailTemplate.test.jsx index 4e258f8..43b651c 100644 --- a/tests/unit/ContentThumbnailTemplate.test.jsx +++ b/tests/unit/ContentThumbnailTemplate.test.jsx @@ -28,21 +28,24 @@ const mockPost = { "This is a test description for the blog post that should be long enough to test truncation.", author: "Test Author", date: "2025-04-15", - backgroundImages: ["/test-image-1.jpg", "/test-image-2.jpg"], + thumbnail: { + vertical: "test-post-vertical.svg", + horizontal: "test-post-horizontal.svg", + }, }, }; describe("ContentThumbnailTemplate", () => { describe("Vertical Variant", () => { - it("should render vertical variant with correct dimensions", () => { + it("should render vertical variant with responsive dimensions", () => { render(); const container = screen.getByRole("link"); expect(container).toBeInTheDocument(); - // Check that the component has the correct classes for dimensions + // Check that the component has the correct classes for responsive dimensions const thumbnailDiv = container.querySelector("div"); - expect(thumbnailDiv).toHaveClass("w-[260px]", "h-[390px]"); + expect(thumbnailDiv).toHaveClass("w-full", "aspect-[2/3]"); }); it("should display post title and description", () => { @@ -50,7 +53,7 @@ describe("ContentThumbnailTemplate", () => { expect(screen.getByText("Test Blog Post Title")).toBeInTheDocument(); expect( - screen.getByText(/This is a test description/), + screen.getByText(/This is a test description/) ).toBeInTheDocument(); }); @@ -63,7 +66,7 @@ describe("ContentThumbnailTemplate", () => { }); describe("Horizontal Variant", () => { - it("should render horizontal variant", () => { + it("should render horizontal variant with responsive sizing", () => { render(); const container = screen.getByRole("link"); @@ -71,7 +74,11 @@ describe("ContentThumbnailTemplate", () => { // Check that the component has the correct classes for horizontal layout const thumbnailDiv = container.querySelector("div"); - expect(thumbnailDiv).toHaveClass("h-[225.5px]"); + expect(thumbnailDiv).toHaveClass( + "min-w-[320px]", + "max-w-[800px]", + "h-[225.5px]" + ); }); it("should display post information in horizontal layout", () => { @@ -79,7 +86,7 @@ describe("ContentThumbnailTemplate", () => { expect(screen.getByText("Test Blog Post Title")).toBeInTheDocument(); expect( - screen.getByText(/This is a test description/), + screen.getByText(/This is a test description/) ).toBeInTheDocument(); expect(screen.getByText("Test Author")).toBeInTheDocument(); }); @@ -88,7 +95,7 @@ describe("ContentThumbnailTemplate", () => { describe("Props and Customization", () => { it("should apply custom className", () => { render( - , + ); const container = screen.getByRole("link"); @@ -117,12 +124,12 @@ describe("ContentThumbnailTemplate", () => { expect(screen.getByText("Test Blog Post Title")).toBeInTheDocument(); }); - it("should handle posts without background images", () => { + it("should handle posts without thumbnail images", () => { const postWithoutImages = { ...mockPost, frontmatter: { ...mockPost.frontmatter, - backgroundImages: undefined, + thumbnail: undefined, }, }; @@ -131,6 +138,28 @@ describe("ContentThumbnailTemplate", () => { // Should still render without errors expect(screen.getByText("Test Blog Post Title")).toBeInTheDocument(); }); + + it("should use article-specific thumbnail images when provided", () => { + render(); + + // Check that the background image uses the article-specific thumbnail + const backgroundImg = document.querySelector( + "img[alt*='Background for']" + ); + expect(backgroundImg).toBeInTheDocument(); + expect(backgroundImg.src).toContain("test-post-vertical.svg"); + }); + + it("should use article-specific horizontal images for horizontal variant", () => { + render(); + + // Check that the background image uses the article-specific horizontal thumbnail + const backgroundImg = document.querySelector( + "img[alt*='Background for']" + ); + expect(backgroundImg).toBeInTheDocument(); + expect(backgroundImg.src).toContain("test-post-horizontal.svg"); + }); }); describe("Default Behavior", () => { @@ -138,7 +167,7 @@ describe("ContentThumbnailTemplate", () => { render(); const thumbnailDiv = screen.getByRole("link").querySelector("div"); - expect(thumbnailDiv).toHaveClass("w-[260px]", "h-[390px]"); + expect(thumbnailDiv).toHaveClass("w-full", "aspect-[2/3]"); }); it("should show metadata by default", () => { diff --git a/tests/unit/Header.test.jsx b/tests/unit/Header.test.jsx index bdf59ec..ec84066 100644 --- a/tests/unit/Header.test.jsx +++ b/tests/unit/Header.test.jsx @@ -8,58 +8,55 @@ import Header, { } from "../../app/components/Header.js"; describe("Header", () => { - const mockOnToggle = vi.fn(); - beforeEach(() => { - mockOnToggle.mockClear(); // Clear any existing rendered content document.body.innerHTML = ""; }); describe("Accessibility and Landmarks", () => { test("renders header with correct structure and accessibility attributes", () => { - const { container } = render(
); + const { container } = render(
); // Check main header structure - use container to scope the search const header = container.querySelector( - '[role="banner"][aria-label="Main navigation header"]', + '[role="banner"][aria-label="Main navigation header"]' ); expect(header).toBeInTheDocument(); expect(header).toHaveAttribute("aria-label", "Main navigation header"); // Check navigation - use container to scope the search const nav = container.querySelector( - '[role="navigation"][aria-label="Main navigation"]', + '[role="navigation"][aria-label="Main navigation"]' ); expect(nav).toBeInTheDocument(); expect(nav).toHaveAttribute("aria-label", "Main navigation"); }); test("renders all navigation items with proper accessibility", () => { - render(
); + render(
); // Check all navigation items have proper aria-labels - use menuitem role since they're in a menubar expect( screen.getAllByRole("menuitem", { name: "Navigate to Use cases page" }) - .length, + .length ).toBeGreaterThan(0); expect( screen.getAllByRole("menuitem", { name: "Navigate to Learn page" }) - .length, + .length ).toBeGreaterThan(0); expect( screen.getAllByRole("menuitem", { name: "Navigate to About page" }) - .length, + .length ).toBeGreaterThan(0); }); }); describe("Schema Markup", () => { test("renders schema markup for site navigation", () => { - render(
); + render(
); const script = document.querySelector( - 'script[type="application/ld+json"]', + 'script[type="application/ld+json"]' ); expect(script).toBeInTheDocument(); @@ -126,14 +123,14 @@ describe("Header", () => { describe("Logo Configuration", () => { test("renders correct number of logo variants", () => { - render(
); + render(
); const logoWrappers = screen.getAllByTestId("logo-wrapper"); expect(logoWrappers).toHaveLength(logoConfig.length); }); test("logo wrappers include expected breakpoint classes", () => { - render(
); + render(
); const logoWrappers = screen.getAllByTestId("logo-wrapper"); @@ -156,7 +153,7 @@ describe("Header", () => { describe("Navigation Structure", () => { test("renders all breakpoint-specific navigation containers", () => { - render(
); + render(
); expect(screen.getByTestId("nav-xs")).toBeInTheDocument(); expect(screen.getByTestId("nav-sm")).toBeInTheDocument(); @@ -166,7 +163,7 @@ describe("Header", () => { }); test("navigation containers use expected breakpoint classes", () => { - render(
); + render(
); // XSmall navigation const navXs = screen.getByTestId("nav-xs"); @@ -190,7 +187,7 @@ describe("Header", () => { }); test("renders navigation items with correct text and links", () => { - render(
); + render(
); // Check navigation items expect(screen.getAllByText("Use cases").length).toBeGreaterThan(0); @@ -199,7 +196,7 @@ describe("Header", () => { }); test("renders multiple instances of navigation items for responsive design", () => { - render(
); + render(
); // Should have multiple instances of navigation items for different breakpoints const useCasesLinks = screen.getAllByText("Use cases"); @@ -214,7 +211,7 @@ describe("Header", () => { describe("Authentication Structure", () => { test("renders all breakpoint-specific auth containers", () => { - render(
); + render(
); expect(screen.getByTestId("auth-xs")).toBeInTheDocument(); expect(screen.getByTestId("auth-sm")).toBeInTheDocument(); @@ -224,7 +221,7 @@ describe("Header", () => { }); test("auth containers use expected breakpoint classes", () => { - render(
); + render(
); // XSmall auth const authXs = screen.getByTestId("auth-xs"); @@ -248,7 +245,7 @@ describe("Header", () => { }); test("renders login button with correct accessibility", () => { - render(
); + render(
); const loginLinks = screen.getAllByRole("menuitem", { name: "Log in to your account", @@ -258,7 +255,7 @@ describe("Header", () => { }); test("renders multiple login buttons for responsive design", () => { - render(
); + render(
); // Should have multiple login buttons for different breakpoints const loginButtons = screen.getAllByText("Log in"); @@ -266,7 +263,7 @@ describe("Header", () => { }); test("renders create rule button with avatar decoration", () => { - render(
); + render(
); const createRuleButtons = screen.getAllByRole("button", { name: "Create a new rule with avatar decoration", @@ -276,7 +273,7 @@ describe("Header", () => { }); test("renders multiple create rule buttons for responsive design", () => { - render(
); + render(
); // Should have multiple create rule buttons for different breakpoints const createRuleButtons = screen.getAllByText("Create rule"); @@ -286,7 +283,7 @@ describe("Header", () => { describe("Avatar Images", () => { test("renders avatar images with correct attributes", () => { - render(
); + render(
); const avatars = screen.getAllByRole("img"); expect(avatars.length).toBeGreaterThan(0); @@ -296,45 +293,39 @@ describe("Header", () => { (img) => img.alt === "Avatar 1" || img.alt === "Avatar 2" || - img.alt === "Avatar 3", + img.alt === "Avatar 3" ); expect(avatarImages.length).toBeGreaterThan(0); }); }); - describe("User Interactions", () => { - test("calls onToggle when navigation items are clicked", async () => { - const user = userEvent.setup(); - render(
); + describe("Sticky Header Behavior", () => { + test("applies sticky positioning classes", () => { + const { container } = render(
); - // Find and click a navigation item - use menuitem role since they're in a menubar - const useCasesLinks = screen.getAllByRole("menuitem", { - name: "Navigate to Use cases page", - }); - expect(useCasesLinks.length).toBeGreaterThan(0); - const useCasesLink = useCasesLinks[0]; - await user.click(useCasesLink); - - expect(mockOnToggle).toHaveBeenCalledTimes(1); + const header = container.querySelector( + '[role="banner"][aria-label="Main navigation header"]' + ); + expect(header).toHaveClass("sticky", "top-0", "z-50"); }); }); describe("CSS Classes and Styling", () => { test("has correct CSS classes for styling", () => { - const { container } = render(
); + const { container } = render(
); const header = container.querySelector( - '[role="banner"][aria-label="Main navigation header"]', + '[role="banner"][aria-label="Main navigation header"]' ); expect(header).toHaveClass("bg-[var(--color-surface-default-primary)]"); expect(header).toHaveClass("w-full"); expect(header).toHaveClass("border-b"); expect(header).toHaveClass( - "border-[var(--border-color-default-tertiary)]", + "border-[var(--border-color-default-tertiary)]" ); const nav = container.querySelector( - '[role="navigation"][aria-label="Main navigation"]', + '[role="navigation"][aria-label="Main navigation"]' ); expect(nav).toHaveClass("flex"); expect(nav).toHaveClass("items-center"); diff --git a/tests/unit/validation.test.js b/tests/unit/validation.test.js index 15ff950..9f38e76 100644 --- a/tests/unit/validation.test.js +++ b/tests/unit/validation.test.js @@ -15,6 +15,16 @@ describe("Blog Post Validation", () => { author: "Test Author", date: "2025-04-15", related: ["post-1", "post-2"], + thumbnail: { + vertical: "test-vertical.svg", + horizontal: "test-horizontal.svg", + }, + banner: { + horizontal: "test-banner.svg", + }, + background: { + color: "#F4F3F1", + }, }; const result = validateBlogPost(validPost); @@ -84,11 +94,14 @@ describe("Blog Post Validation", () => { description: "Test description", author: "Test Author", date: "2025-04-15", - // Missing related + // Missing related, thumbnail, banner, background }; const sanitized = sanitizeBlogPost(post); expect(sanitized.related).toEqual([]); + expect(sanitized.thumbnail).toBeNull(); + expect(sanitized.banner).toBeNull(); + expect(sanitized.background).toBeNull(); }); it("should preserve existing optional fields", () => { @@ -98,10 +111,30 @@ describe("Blog Post Validation", () => { author: "Test Author", date: "2025-04-15", related: ["custom-post"], + thumbnail: { + vertical: "custom-vertical.svg", + horizontal: "custom-horizontal.svg", + }, + banner: { + horizontal: "custom-banner.svg", + }, + background: { + color: "#E2EFFF", + }, }; const sanitized = sanitizeBlogPost(post); expect(sanitized.related).toEqual(["custom-post"]); + expect(sanitized.thumbnail).toEqual({ + vertical: "custom-vertical.svg", + horizontal: "custom-horizontal.svg", + }); + expect(sanitized.banner).toEqual({ + horizontal: "custom-banner.svg", + }); + expect(sanitized.background).toEqual({ + color: "#E2EFFF", + }); }); }); @@ -112,6 +145,9 @@ describe("Blog Post Validation", () => { expect(BLOG_POST_SCHEMA).toHaveProperty("author"); expect(BLOG_POST_SCHEMA).toHaveProperty("date"); expect(BLOG_POST_SCHEMA).toHaveProperty("related"); + expect(BLOG_POST_SCHEMA).toHaveProperty("thumbnail"); + expect(BLOG_POST_SCHEMA).toHaveProperty("banner"); + expect(BLOG_POST_SCHEMA).toHaveProperty("background"); }); it("should have correct required field configuration", () => { @@ -120,6 +156,9 @@ describe("Blog Post Validation", () => { expect(BLOG_POST_SCHEMA.author.required).toBe(true); expect(BLOG_POST_SCHEMA.date.required).toBe(true); expect(BLOG_POST_SCHEMA.related.required).toBe(false); + expect(BLOG_POST_SCHEMA.thumbnail.required).toBe(false); + expect(BLOG_POST_SCHEMA.banner.required).toBe(false); + expect(BLOG_POST_SCHEMA.background.required).toBe(false); }); }); });