@@ -11,6 +11,10 @@ import IntegrationTestHelper, {
1111import { Website } from "../types/websites"
1212import PaginationControls from "../components/PaginationControls"
1313import * as searchHooks from "../hooks/search"
14+ import React from "react"
15+ import { render , fireEvent } from "@testing-library/react"
16+ import { StatusWithDateHover , formatDateTime } from "./SitesDashboard"
17+ import { PublishStatus } from "../constants"
1418
1519jest . mock ( "../hooks/search" , ( ) => {
1620 return {
@@ -169,3 +173,188 @@ describe("SitesDashboard", () => {
169173 expect ( paginationControls . prop ( "previous" ) ) . toBe ( previous )
170174 } )
171175} )
176+
177+ describe ( "StatusWithDateHover component" , ( ) => {
178+ it ( "displays status text by default" , ( ) => {
179+ const { getByText } = render (
180+ < StatusWithDateHover
181+ statusText = "Published"
182+ dateTime = "2023-01-15T12:30:45Z"
183+ className = "text-success"
184+ /> ,
185+ )
186+
187+ expect ( getByText ( "Published" ) ) . toBeInTheDocument ( )
188+ } )
189+
190+ it ( "shows formatted date on hover" , ( ) => {
191+ const { getByText, container } = render (
192+ < StatusWithDateHover
193+ statusText = "Published"
194+ dateTime = "2023-01-15T12:30:45Z"
195+ className = "text-success"
196+ /> ,
197+ )
198+
199+ const element = container . firstChild as HTMLElement
200+ fireEvent . mouseEnter ( element )
201+
202+ expect ( getByText ( / P u b l i s h e d o n J a n 1 5 , 2 0 2 3 / ) ) . toBeInTheDocument ( )
203+ } )
204+
205+ it ( "reverts to status text when mouse leaves" , ( ) => {
206+ const { getByText, container } = render (
207+ < StatusWithDateHover
208+ statusText = "Published"
209+ dateTime = "2023-01-15T12:30:45Z"
210+ className = "text-success"
211+ /> ,
212+ )
213+
214+ const element = container . firstChild as HTMLElement
215+
216+ // Hover
217+ fireEvent . mouseEnter ( element )
218+ expect ( getByText ( / P u b l i s h e d o n J a n 1 5 , 2 0 2 3 / ) ) . toBeInTheDocument ( )
219+
220+ // Un-hover
221+ fireEvent . mouseLeave ( element )
222+ expect ( getByText ( "Published" ) ) . toBeInTheDocument ( )
223+ } )
224+
225+ it ( "applies the provided className" , ( ) => {
226+ const { container } = render (
227+ < StatusWithDateHover
228+ statusText = "Published"
229+ dateTime = "2023-01-15T12:30:45Z"
230+ className = "text-success"
231+ /> ,
232+ )
233+
234+ expect ( container . firstChild ) . toHaveClass ( "text-success" )
235+ } )
236+ } )
237+
238+ describe ( "formatDateTime function" , ( ) => {
239+ it ( "formats date strings" , ( ) => {
240+ const result = formatDateTime ( "2023-01-15T12:30:45Z" )
241+
242+ expect ( result ) . toContain ( "2023" )
243+ expect ( result ) . toContain ( "Jan" )
244+ expect ( result ) . toContain ( "15" )
245+ } )
246+ } )
247+
248+ describe ( "Site status indicators" , ( ) => {
249+ it ( "shows status for different site states" , async ( ) => {
250+ const testHelper = new IntegrationTestHelper ( )
251+ const testWebsites = makeWebsites ( 5 )
252+
253+ // Never published site - no publish dates or statuses
254+ const neverPublishedSite = {
255+ ...testWebsites [ 0 ] ,
256+ name : "never-published-site" ,
257+ uuid : "test-uuid-1" ,
258+ publish_date : null ,
259+ draft_publish_date : null ,
260+ live_publish_status : null ,
261+ unpublished : false ,
262+ } ,
263+ // Unpublished site - has publish_date but marked as unpublished
264+ unpublishedSite = {
265+ ...testWebsites [ 1 ] ,
266+ name : "unpublished-site" ,
267+ uuid : "test-uuid-2" ,
268+ publish_date : "2023-01-01T12:00:00Z" ,
269+ unpublished : true ,
270+ unpublish_status : PublishStatus . Success ,
271+ unpublish_status_updated_on : "2023-01-15T12:30:45Z" ,
272+ updated_on : "2023-01-15T12:30:45Z" ,
273+ } ,
274+ // Draft site - has draft_publish_status and draft_publish_date
275+ // but no publish_date and unpublished is false
276+ draftSite = {
277+ ...testWebsites [ 2 ] ,
278+ name : "draft-site" ,
279+ uuid : "test-uuid-3" ,
280+ draft_publish_date : "2023-01-15T12:30:45Z" ,
281+ draft_publish_status : PublishStatus . Success ,
282+ publish_date : null ,
283+ live_publish_status : null ,
284+ unpublished : false ,
285+ updated_on : "2023-01-15T12:30:45Z" ,
286+ } ,
287+ // Published site - has publish_date and live_publish_status
288+ publishedSite = {
289+ ...testWebsites [ 3 ] ,
290+ name : "published-site" ,
291+ uuid : "test-uuid-4" ,
292+ publish_date : "2023-01-01T12:00:00Z" ,
293+ live_publish_status : PublishStatus . Success ,
294+ unpublished : false ,
295+ updated_on : "2023-01-15T12:30:45Z" ,
296+ } ,
297+ // Failed site - has live_publish_status marked as errored
298+ failedSite = {
299+ ...testWebsites [ 4 ] ,
300+ name : "failed-site" ,
301+ uuid : "test-uuid-5" ,
302+ publish_date : "2023-01-01T12:00:00Z" ,
303+ live_publish_status : PublishStatus . Errored ,
304+ unpublished : false ,
305+ updated_on : "2023-01-15T12:30:45Z" ,
306+ }
307+
308+ const statusSites = [
309+ neverPublishedSite ,
310+ unpublishedSite ,
311+ draftSite ,
312+ publishedSite ,
313+ failedSite ,
314+ ]
315+ const testResponse = {
316+ results : statusSites ,
317+ next : "https://example.com" ,
318+ previous : null ,
319+ count : statusSites . length ,
320+ }
321+
322+ testHelper . mockGetRequest (
323+ siteApiListingUrl . param ( { offset : 0 } ) . toString ( ) ,
324+ testResponse ,
325+ )
326+
327+ const websitesLookup : Record < string , Website > = { }
328+ for ( const site of statusSites ) {
329+ websitesLookup [ site . name ] = site
330+ }
331+
332+ const testRender = testHelper . configureRenderer (
333+ SitesDashboard ,
334+ { } ,
335+ {
336+ entities : {
337+ websitesListing : {
338+ [ "0" ] : {
339+ ...testResponse ,
340+ results : statusSites . map ( ( site ) => site . name ) ,
341+ } ,
342+ } ,
343+ websiteDetails : websitesLookup ,
344+ } ,
345+ queries : { } ,
346+ } ,
347+ )
348+
349+ const { wrapper } = await testRender ( )
350+
351+ // Check for status text
352+ expect ( wrapper . text ( ) ) . toContain ( "Never Published" )
353+ expect ( wrapper . text ( ) ) . toContain ( "Unpublished from Production" )
354+ expect ( wrapper . text ( ) ) . toContain ( "Draft" )
355+ expect ( wrapper . text ( ) ) . toContain ( "Published" )
356+
357+ // Cleanup
358+ testHelper . cleanup ( )
359+ } )
360+ } )
0 commit comments