From 3d37557b3794c93c82d4e95179cf8c7f9f3c9c13 Mon Sep 17 00:00:00 2001 From: Vito Galatro Date: Mon, 8 Jan 2024 16:12:53 -0500 Subject: [PATCH] THEMES-1577: Card list block - show time (#1871) * THEMES-1577: updated card list to display date and time. Fixed unit tests. * THEMES-1577: corrected typo in news.json --- .../features/card-list/default.jsx | 8 +- .../features/card-list/default.test.jsx | 470 ++++++++---------- blocks/card-list-block/themes/news.json | 2 +- 3 files changed, 212 insertions(+), 268 deletions(-) diff --git a/blocks/card-list-block/features/card-list/default.jsx b/blocks/card-list-block/features/card-list/default.jsx index 8c11929451..0fc35043dd 100644 --- a/blocks/card-list-block/features/card-list/default.jsx +++ b/blocks/card-list-block/features/card-list/default.jsx @@ -17,7 +17,7 @@ import { isServerSide, LazyLoad, Link, - localizeDate, + localizeDateTime, Overline, Separator, Stack, @@ -48,7 +48,7 @@ const CardListItems = (props) => { dateLocalization: { language, timeZone, dateFormat } = { language: "en", timeZone: "GMT", - dateFormat: "%B %d, %Y", + dateFormat: "%B %d, %Y at %l:%M%p %Z", }, } = props; const phrases = usePhrases(); @@ -135,7 +135,7 @@ const CardListItems = (props) => { const sourceContent = contentElements[0]; - const displayDate = localizeDate(sourceContent.display_date, dateFormat, language, timeZone); + const displayDate = localizeDateTime(sourceContent.display_date, dateFormat, language, timeZone); /* Author Formatting */ const bylineNodes = formatAuthors(sourceContent?.credits?.by, phrases.t("global.and-text")); @@ -210,7 +210,7 @@ const CardListItems = (props) => { {hasAuthor ? ( <> {phrases.t("global.by-text")} {bylineNodes} - + ) : null} diff --git a/blocks/card-list-block/features/card-list/default.test.jsx b/blocks/card-list-block/features/card-list/default.test.jsx index 4beb7065e4..b66cfd2d8b 100644 --- a/blocks/card-list-block/features/card-list/default.test.jsx +++ b/blocks/card-list-block/features/card-list/default.test.jsx @@ -1,274 +1,218 @@ -describe("This test is disabled", () => { - it("should succeed", () => { - expect(true); +import React from "react"; +import { render, screen } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import getThemeStyle from "fusion:themes"; +import { useContent } from "fusion:content"; +import { useFusionContext } from "fusion:context"; +import mockData, { oneListItem, oneListItemDisplayLabel, twoListItemNoSiteUrl } from "./mock-data"; +import CardList from "./default"; + +jest.mock("@wpmedia/arc-themes-components", () => ({ + ...jest.requireActual("@wpmedia/arc-themes-components"), + isServerSide: jest.fn(() => true), + LazyLoad: ({ children }) => children, + localizeDateTime: jest.fn(() => "date"), +})); + +jest.mock("fusion:content", () => ({ + useContent: jest.fn(() => mockData), +})); + +jest.mock("fusion:context", () => ({ + useFusionContext: jest.fn(() => ({ + id: "", + arcSite: "the-sun", + deployment: jest.fn(() => {}), + })), +})); + +describe("Card list", () => { + it("should render null if isServerSide and lazyLoad enabled", () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "30", + }, + contentService: "story-feed-query", + }; + const customFields = { + listContentConfig, + lazyLoad: true, + }; + + useFusionContext.mockReturnValueOnce({ + id: "", + arcSite: "the-sun", + deployment: jest.fn(() => {}), + }); + + const { container } = render(); + expect(container).toBeEmptyDOMElement(); }); -}); - -// import React from "react"; -// import { mount } from "enzyme"; -// import getThemeStyle from "fusion:themes"; -// import { useContent } from "fusion:content"; -// import { useFusionContext } from "fusion:context"; -// import mockData, { oneListItem, oneListItemDisplayLabel, twoListItemNoSiteUrl } from "./mock-data"; -// import CardList from "./default"; - -// jest.mock("@wpmedia/arc-themes-components", () => ({ -// ...jest.requireActual("@wpmedia/arc-themes-components"), -// isServerSide: jest.fn(() => true), -// LazyLoad: ({ children }) => children, -// localizeDate: jest.fn(() => "date"), -// })); - -// jest.mock("fusion:content", () => ({ -// useContent: jest.fn(() => mockData), -// })); - -// jest.mock("fusion:context", () => ({ -// useFusionContext: jest.fn(() => ({ -// id: "", -// arcSite: "the-sun", -// deployment: jest.fn(() => {}), -// })), -// })); - -// describe("Card list", () => { -// it("should render null if isServerSide and lazyLoad enabled", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "30", -// }, -// contentService: "story-feed-query", -// }; -// const customFields = { -// listContentConfig, -// lazyLoad: true, -// }; - -// useFusionContext.mockReturnValueOnce({ -// id: "", -// arcSite: "the-sun", -// deployment: jest.fn(() => {}), -// }); - -// const wrapper = mount(); -// expect(wrapper.html()).toBe(null); -// }); - -// it("it should not render anything if no list of stories", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "10", -// }, -// contentService: "fake-service", -// }; -// const customFields = { -// listContentConfig, -// offsetOverride: 100, -// }; -// useContent.mockReturnValueOnce(null); - -// const wrapper = mount(); - -// expect(wrapper.find("Stack.b-card-list__secondary-item").length).toEqual(0); -// }); - -// it("should render a list of stories", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "30", -// }, -// contentService: "story-feed-query", -// }; -// const customFields = { listContentConfig }; - -// const wrapper = mount(); -// expect(wrapper.find("Stack.b-card-list__secondary-item").length).toEqual(8); -// }); - -// it("should only render amount of stories based on displayAmount", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "30", -// }, -// contentService: "story-feed-query", -// }; -// const customFields = { listContentConfig, displayAmount: 5 }; - -// const wrapper = mount(); -// expect(wrapper.find("Stack.b-card-list__secondary-item").length).toEqual(4); -// }); - -// it("should render first item based on offsetOverride", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "30", -// }, -// contentService: "story-feed-query", -// }; -// const customFields = { listContentConfig, offsetOverride: 1 }; - -// const wrapper = mount(); - -// expect(wrapper.find("Stack.b-card-list__main-item-text-container .c-heading").text()).toBe( -// "2nd Story Title" -// ); -// }); - -// it("should render a list of stories only for the arcSite", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "30", -// }, -// contentService: "story-feed-query", -// }; -// const customFields = { listContentConfig }; - -// jest.mock("fusion:context", () => ({ -// useFusionContext: jest.fn(() => ({ -// arcSite: "the-mercury", -// deployment: jest.fn(() => {}), -// })), -// })); -// useContent.mockReturnValueOnce(oneListItem); -// const wrapper = mount(); -// expect(wrapper.find("Stack.b-card-list").length).toEqual(1); -// expect(wrapper.find("Stack.b-card-list__secondary-item").length).toEqual(0); -// }); - -// describe("renders the main list item correctly", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "1", -// }, -// contentService: "story-feed-query", -// }; -// const title = "Test Title"; -// const customFields = { listContentConfig, title }; - -// getThemeStyle.mockImplementation(() => ({ -// "primary-font-family": "Papyrus", -// })); - -// useContent.mockReturnValueOnce(oneListItem); -// const wrapper = mount(); -// it("should have one parent wrapper", () => { -// expect(wrapper.find("Stack.b-card-list").length).toEqual(1); -// }); - -// it("should render a title with the right text", () => { -// expect(wrapper.find(".b-card-list__title").first().text()).toEqual("Test Title"); -// }); - -// it("should render two anchor tags - one around image one for the title", () => { -// expect(wrapper.find(".b-card-list__main-item-image-link").length).toEqual(2); -// expect(wrapper.find(".b-card-list__main-item-image-link").find("Image").length).toEqual(1); -// }); - -// it("should render one image wrapped in an anchor tag", () => { -// expect(wrapper.find(".b-card-list__main-item-image-link Image").length).toEqual(1); -// }); - -// it("should render an anchor ", () => { -// expect(wrapper.find(".b-card-list__main-item-image-link").at(0).find("a").length).toEqual(1); -// }); - -// it("should render an anchor and an image with the correct url", () => { -// const anchors = wrapper.find(".c-link"); -// expect(anchors.at(0).prop("href")).toEqual("/this/is/the/correct/url"); -// expect(anchors.at(1).prop("href")).toEqual("/this/is/the/correct/url"); -// }); - -// it("should render an overline", () => { -// expect(wrapper.find(".c-overline").length).toEqual(1); -// }); - -// it("should render a main headline", () => { -// expect(wrapper.find(".b-card-list__main-item-text-container Heading").text()).toBe( -// "Article with a YouTube embed in it" -// ); -// }); - -// it("should render a byline", () => { -// expect(wrapper.find(".c-attribution").length).toEqual(1); -// }); - -// it("should render a separator", () => { -// expect(wrapper.find(".c-separator").length).toEqual(1); -// }); - -// it("should render a publish date", () => { -// expect(wrapper.find(".c-date").length).toEqual(1); -// }); -// }); - -// describe("render one list item correctly", () => { -// const listContentConfig = { -// contentConfigValues: { -// offset: "0", -// query: "type:story", -// size: "1", -// }, -// contentService: "story-feed-query", -// }; -// const title = "Test Title"; -// const customFields = { listContentConfig, title }; - -// const wrapper = mount(); - -// it("should render one parent wrapper", () => { -// expect(wrapper.find("Stack.b-card-list").length).toEqual(1); -// }); + it("it should not render anything if no list of stories", () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "10", + }, + contentService: "fake-service", + }; + const customFields = { + listContentConfig, + offsetOverride: 100, + }; + useContent.mockReturnValueOnce(null); + + render(); + + expect(screen.queryByRole("article")).toBeNull(); + }); -// it("should render a parent for headline and a description", () => { -// expect(wrapper.find("Stack.b-card-list__secondary-item").length).toEqual(8); -// }); + it("should render a list of stories", () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "30", + }, + contentService: "story-feed-query", + }; + const customFields = { listContentConfig }; + + render(); + expect(screen.getAllByRole("article").length).toEqual(9); + }); -// it("should render a headline", () => { -// expect(wrapper.find(".b-card-list__secondary-item-heading-link .c-heading").length).toEqual( -// 8 -// ); + it("should only render amount of stories based on displayAmount", () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "30", + }, + contentService: "story-feed-query", + }; + const customFields = { listContentConfig, displayAmount: 5 }; + + render(); + expect(screen.getAllByRole("article").length).toEqual(5); + }); -// expect(wrapper.find(".b-card-list__secondary-item-heading-link").first().text()).toEqual( -// "2nd Story Title" -// ); -// expect(wrapper.find(".b-card-list__secondary-item-heading-link").at(0).prop("href")).toEqual( -// "/this/is/the/correct/url" -// ); -// }); -// }); + it("should render first item based on offsetOverride", () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "30", + }, + contentService: "story-feed-query", + }; + const customFields = { listContentConfig, offsetOverride: 1 }; -// describe("render one list item with display label overline", () => { -// useContent.mockReturnValueOnce(oneListItemDisplayLabel); + render(); -// const wrapper = mount(); + expect(screen.getByText("2nd Story Title")).not.toBeNull(); + }); -// it("should render an overline using the label data if sourceContent.label.display is true and there is no owner", () => { -// expect(wrapper.find(".c-overline").text()).toEqual("Display Label"); -// }); -// }); + it("should render a list of stories only for the arcSite", () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "30", + }, + contentService: "story-feed-query", + }; + const customFields = { listContentConfig }; + + jest.mock("fusion:context", () => ({ + useFusionContext: jest.fn(() => ({ + arcSite: "the-mercury", + deployment: jest.fn(() => {}), + })), + })); + useContent.mockReturnValueOnce(oneListItem); + render(); + expect(screen.getAllByRole("article").length).toEqual(1); + }); -// describe("render one list item without a secondary item for a bad site website_url", () => { -// useContent.mockReturnValueOnce(twoListItemNoSiteUrl); + describe("renders the main list item correctly", () => { + const setup = () => { + const listContentConfig = { + contentConfigValues: { + offset: "0", + query: "type:story", + size: "1", + }, + contentService: "story-feed-query", + }; + const title = "Test Title"; + const customFields = { listContentConfig, title }; + + getThemeStyle.mockImplementation(() => ({ + "primary-font-family": "Papyrus", + })); + + useContent.mockReturnValueOnce(oneListItem); + render(); + }; + + + it("should render a title with the right text", () => { + setup(); + expect(screen.getByText("Test Title")).not.toBeNull(); + }); + + it("should render anchor tags", () => { + setup(); + const links = screen.getAllByRole("link"); + expect(links.length).toEqual(2); + expect(links[0]).toHaveAttribute("href", "/this/is/the/correct/url"); + }); + + it("should render one image", () => { + setup(); + expect(screen.getByRole("img", {hidden: true})).not.toBeNull(); + }); + + it("should render an overline", () => { + setup(); + expect(screen.getByText("global.sponsored-content")).not.toBeNull(); + }); + + it("should render a main headline", () => { + setup(); + expect(screen.getByText("Article with a YouTube embed in it")).not.toBeNull(); + }); + + it("should render a byline", () => { + setup(); + expect(screen.getByText("global.by-text")).not.toBeNull(); + }); + + it("should render a separator", () => { + setup(); + expect(screen.getByTestId("card-list-separator")).not.toBeNull(); + }); + + it("should render a publish date", () => { + setup(); + expect(screen.getByText("date")).not.toBeNull(); + }); + }); -// const wrapper = mount(); + it("should render an overline using the label data if sourceContent.label.display is true and there is no owner", () => { + useContent.mockReturnValueOnce(oneListItemDisplayLabel); + render(); + expect(screen.getByText("Display Label")).not.toBeNull(); + }); -// it("should render an overline using the label data if sourceContent.label.display is true and there is no owner", () => { -// expect(wrapper.find(".b-card-list__secondary-item")).not.toExist(); -// }); -// }); -// }); + it("render one list item without a secondary item for a bad site website_url", () => { + useContent.mockReturnValueOnce(twoListItemNoSiteUrl); + render(); + expect(screen.getAllByRole("article").length).toEqual(1); + }); +}); diff --git a/blocks/card-list-block/themes/news.json b/blocks/card-list-block/themes/news.json index 715756bed3..2bff95725d 100644 --- a/blocks/card-list-block/themes/news.json +++ b/blocks/card-list-block/themes/news.json @@ -34,7 +34,7 @@ "separator": { "padding-block-end": "0", "padding-block-start": "0", - "paddinginline-end": "var(--global-spacing-2)", + "padding-inline-end": "var(--global-spacing-2)", "padding-inline-start": "var(--global-spacing-2)" }, "stack": {