Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions src/components/site-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { speak } from '@wordpress/a11y';
import { Spinner } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { useEffect } from 'react';
import { useSyncSites } from '../hooks/sync-sites';
import { useImportExport } from '../hooks/use-import-export';
import { useSiteDetails } from '../hooks/use-site-details';
import { isMac } from '../lib/app-globals';
Expand Down Expand Up @@ -108,9 +109,24 @@ function ButtonToRun( { running, id, name }: Pick< SiteDetails, 'running' | 'id'
}
function SiteItem( { site }: { site: SiteDetails } ) {
const { selectedSite, setSelectedSiteId } = useSiteDetails();
const { isSiteImporting } = useImportExport();
const isSelected = site === selectedSite;
const { isSiteImporting } = useImportExport();
const { isSiteIdPulling } = useSyncSites();
const isImporting = isSiteImporting( site.id );
const isPulling = isSiteIdPulling( site.id );
const showSpinner = site.isAddingSite || isImporting || isPulling;

let tooltipText;
if ( site.isAddingSite ) {
tooltipText = __( 'Adding' );
} else if ( isImporting ) {
tooltipText = __( 'Importing' );
} else if ( isPulling ) {
tooltipText = __( 'Syncing' );
} else {
tooltipText = __( 'Loading' );
}

return (
<li
className={ cx(
Expand All @@ -127,8 +143,12 @@ function SiteItem( { site }: { site: SiteDetails } ) {
>
{ site.name }
</button>
{ site.isAddingSite || isImporting ? (
<Spinner className="!w-2.5 !h-2.5 !top-[6px] !mr-2 [&>circle]:stroke-a8c-gray-70" />
{ showSpinner ? (
<Tooltip text={ tooltipText }>
<div className="grid place-items-center">
<Spinner className="!w-2.5 !h-2.5 !top-[6px] !mr-2 [&>circle]:stroke-a8c-gray-70" />
</div>
</Tooltip>
) : (
<ButtonToRun { ...site } />
) }
Expand Down
19 changes: 12 additions & 7 deletions src/components/tests/main-sidebar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { render, act, screen } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { SyncSitesProvider } from '../../hooks/sync-sites';
import { useAuth } from '../../hooks/use-auth';
import MainSidebar from '../main-sidebar';

Expand Down Expand Up @@ -55,46 +56,50 @@ jest.mock( '../../hooks/use-site-details', () => ( {
useSiteDetails: () => ( { ...siteDetailsMocked } ),
} ) );

const renderWithProvider = ( children: React.ReactElement ) => {
return render( <SyncSitesProvider>{ children }</SyncSitesProvider> );
};

describe( 'MainSidebar Footer', () => {
beforeEach( () => {
jest.clearAllMocks();
} );
it( 'Has add site button', async () => {
( useAuth as jest.Mock ).mockReturnValue( { isAuthenticated: false } );
await act( async () => render( <MainSidebar /> ) );
await act( async () => renderWithProvider( <MainSidebar /> ) );
expect( screen.getByRole( 'button', { name: 'Add site' } ) ).toBeVisible();
} );

it( 'applies className prop', async () => {
const { container } = await act( async () =>
render( <MainSidebar className={ 'test-class' } /> )
renderWithProvider( <MainSidebar className={ 'test-class' } /> )
);
expect( container.firstChild ).toHaveClass( 'test-class' );
} );

it( 'shows a "Stop All" button when there are running sites', async () => {
await act( async () => render( <MainSidebar /> ) );
await act( async () => renderWithProvider( <MainSidebar /> ) );
expect( screen.getByRole( 'button', { name: 'Stop all' } ) ).toBeVisible();
} );
} );

describe( 'MainSidebar Site Menu', () => {
it( 'renders the list of sites', async () => {
await act( async () => render( <MainSidebar /> ) );
await act( async () => renderWithProvider( <MainSidebar /> ) );
expect( screen.getByRole( 'button', { name: 'test-1' } ) ).toBeVisible();
expect( screen.getByRole( 'button', { name: 'test-2' } ) ).toBeVisible();
expect( screen.getByRole( 'button', { name: 'test-3' } ) ).toBeVisible();
} );

it( 'has "start site" buttons when sites are not running', async () => {
await act( async () => render( <MainSidebar /> ) );
await act( async () => renderWithProvider( <MainSidebar /> ) );
expect( screen.getByRole( 'button', { name: 'start test-1 site' } ) ).toBeVisible();
expect( screen.getByRole( 'button', { name: 'start test-2 site' } ) ).toBeVisible();
} );

it( 'starts a site', async () => {
const user = userEvent.setup();
await act( async () => render( <MainSidebar /> ) );
await act( async () => renderWithProvider( <MainSidebar /> ) );
const greenDotFirstSite = screen.getByRole( 'button', { name: 'start test-1 site' } );
expect( greenDotFirstSite ).toBeVisible();
await user.click( greenDotFirstSite );
Expand All @@ -105,7 +110,7 @@ describe( 'MainSidebar Site Menu', () => {

it( 'stops a site', async () => {
const user = userEvent.setup();
await act( async () => render( <MainSidebar /> ) );
await act( async () => renderWithProvider( <MainSidebar /> ) );
const greenDotFirstSite = screen.getByRole( 'button', { name: 'stop test-3 site' } );
expect( greenDotFirstSite ).toBeVisible();
await user.click( greenDotFirstSite );
Expand Down