1- import { render , screen } from '@testing-library/react' ;
1+ import { render , screen , waitFor } from '@testing-library/react' ;
22import { userEvent } from '@testing-library/user-event' ;
33import { Provider } from 'react-redux' ;
44import {
@@ -8,11 +8,30 @@ import {
88import { SyncSitesProvider } from 'src/hooks/sync-sites' ;
99import { ContentTabsProvider } from 'src/hooks/use-content-tabs' ;
1010import { store } from 'src/stores' ;
11+ import { connectedSitesApi } from 'src/stores/sync/connected-sites' ;
12+
13+ const mockGetConnectedWpcomSites = jest . fn ( ) ;
14+ const mockUpdateSingleConnectedWpcomSite = jest . fn ( ) ;
1115
1216jest . mock ( 'src/lib/get-ipc-api' , ( ) => ( {
13- getIpcApi : ( ) => ( {
14- getConnectedWpcomSites : jest . fn ( ) . mockResolvedValue ( [ ] ) ,
15- updateSingleConnectedWpcomSite : jest . fn ( ) . mockResolvedValue ( { } ) ,
17+ getIpcApi : jest . fn ( ( ) => ( {
18+ getConnectedWpcomSites : mockGetConnectedWpcomSites ,
19+ updateSingleConnectedWpcomSite : mockUpdateSingleConnectedWpcomSite ,
20+ } ) ) ,
21+ } ) ) ;
22+
23+ // Mock useSiteDetails to return the site passed via context
24+ jest . mock ( 'src/hooks/use-site-details' , ( ) => ( {
25+ useSiteDetails : ( ) => ( {
26+ selectedSite : { id : 'site-1' , running : false } ,
27+ } ) ,
28+ } ) ) ;
29+
30+ // Mock useAuth to return a dummy user
31+ jest . mock ( 'src/hooks/use-auth' , ( ) => ( {
32+ useAuth : ( ) => ( {
33+ user : { id : 1 } ,
34+ isAuthenticated : true ,
1635 } ) ,
1736} ) ) ;
1837
@@ -23,7 +42,14 @@ const defaultProps = {
2342} as SiteManagementActionProps ;
2443describe ( 'SiteManagementActions' , ( ) => {
2544 beforeEach ( ( ) => {
26- jest . clearAllMocks ( ) ;
45+ // Reset mock calls but preserve implementations
46+ mockGetConnectedWpcomSites . mockClear ( ) ;
47+ mockUpdateSingleConnectedWpcomSite . mockClear ( ) ;
48+ // Set default return values
49+ mockGetConnectedWpcomSites . mockResolvedValue ( [ ] ) ;
50+ mockUpdateSingleConnectedWpcomSite . mockResolvedValue ( { } ) ;
51+ // Clear RTK Query cache between tests
52+ store . dispatch ( connectedSitesApi . util . resetApiState ( ) ) ;
2753 } ) ;
2854 const renderWithProvider = ( children : React . ReactElement ) => {
2955 return render (
@@ -80,4 +106,106 @@ describe( 'SiteManagementActions', () => {
80106 ) ;
81107 expect ( screen . getByRole ( 'button' , { name : 'Start' } ) ) . toBeVisible ( ) ;
82108 } ) ;
109+
110+ describe ( 'PublishSiteButton' , ( ) => {
111+ it ( 'should render "Publish site" button when no sites are connected' , async ( ) => {
112+ renderWithProvider (
113+ < SiteManagementActions
114+ { ...defaultProps }
115+ selectedSite = { { running : false , id : 'site-1' } as SiteDetails }
116+ />
117+ ) ;
118+ // Wait for the async query to resolve
119+ const publishButton = await screen . findByRole ( 'button' , { name : 'Publish site' } ) ;
120+ expect ( publishButton ) . toBeInTheDocument ( ) ;
121+ expect ( publishButton ) . toBeVisible ( ) ;
122+ } ) ;
123+
124+ it ( 'should not render "Publish site" button when one site is connected' , async ( ) => {
125+ // Set up mock to return connected sites and clear the cache
126+ mockGetConnectedWpcomSites . mockResolvedValue ( [
127+ {
128+ id : 1 ,
129+ localSiteId : 'site-1' ,
130+ url : 'https://example.wordpress.com' ,
131+ name : 'Example Site' ,
132+ } ,
133+ ] ) ;
134+ // Clear the cache again after changing the mock
135+ store . dispatch ( connectedSitesApi . util . resetApiState ( ) ) ;
136+
137+ renderWithProvider (
138+ < SiteManagementActions
139+ { ...defaultProps }
140+ selectedSite = { { running : false , id : 'site-1' } as SiteDetails }
141+ />
142+ ) ;
143+
144+ // First wait for the Start button to ensure component is fully rendered
145+ await screen . findByRole ( 'button' , { name : 'Start' } ) ;
146+
147+ // Then wait for Publish site button to disappear - it may appear briefly before query resolves
148+ await waitFor (
149+ ( ) => {
150+ const publishButton = screen . queryByRole ( 'button' , { name : 'Publish site' } ) ;
151+ expect ( publishButton ) . not . toBeInTheDocument ( ) ;
152+ } ,
153+ { timeout : 1000 }
154+ ) ;
155+ } ) ;
156+
157+ it ( 'should not render "Publish site" button when multiple sites are connected' , async ( ) => {
158+ // Set up mock to return multiple connected sites and clear the cache
159+ mockGetConnectedWpcomSites . mockResolvedValue ( [
160+ {
161+ id : 1 ,
162+ localSiteId : 'site-1' ,
163+ url : 'https://example1.wordpress.com' ,
164+ name : 'Example Site 1' ,
165+ } ,
166+ {
167+ id : 2 ,
168+ localSiteId : 'site-1' ,
169+ url : 'https://example2.wordpress.com' ,
170+ name : 'Example Site 2' ,
171+ } ,
172+ ] ) ;
173+ // Clear the cache again after changing the mock
174+ store . dispatch ( connectedSitesApi . util . resetApiState ( ) ) ;
175+
176+ renderWithProvider (
177+ < SiteManagementActions
178+ { ...defaultProps }
179+ selectedSite = { { running : false , id : 'site-1' } as SiteDetails }
180+ />
181+ ) ;
182+
183+ // First wait for the Start button to ensure component is fully rendered
184+ await screen . findByRole ( 'button' , { name : 'Start' } ) ;
185+
186+ // Then wait for Publish site button to disappear - it may appear briefly before query resolves
187+ await waitFor (
188+ ( ) => {
189+ const publishButton = screen . queryByRole ( 'button' , { name : 'Publish site' } ) ;
190+ expect ( publishButton ) . not . toBeInTheDocument ( ) ;
191+ } ,
192+ { timeout : 1000 }
193+ ) ;
194+ } ) ;
195+
196+ it ( 'should render "Publish site" button alongside "Running" button when no sites are connected' , async ( ) => {
197+ mockGetConnectedWpcomSites . mockResolvedValue ( [ ] ) ;
198+ renderWithProvider (
199+ < SiteManagementActions
200+ { ...defaultProps }
201+ selectedSite = { { running : true , id : 'site-1' } as SiteDetails }
202+ />
203+ ) ;
204+ // Both buttons should be present
205+ const runningButton = screen . getByRole ( 'button' , { name : 'Running' } ) ;
206+ const publishButton = await screen . findByRole ( 'button' , { name : 'Publish site' } ) ;
207+ expect ( runningButton ) . toBeVisible ( ) ;
208+ expect ( publishButton ) . toBeVisible ( ) ;
209+ } ) ;
210+ } ) ;
83211} ) ;
0 commit comments