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
429 changes: 0 additions & 429 deletions src/hooks/tests/reconcile-connected-sites.test.ts

Large diffs are not rendered by default.

8 changes: 1 addition & 7 deletions src/hooks/tests/use-connected-sites-operations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const mockConnectedWpcomSites: SyncSite[] = [
url: 'https://developer.wordpress.com/studio/',
isStaging: false,
isPressable: false,
stagingSiteIds: [ 7 ],
syncSupport: 'syncable',
lastPullTimestamp: null,
lastPushTimestamp: null,
Expand All @@ -36,7 +35,6 @@ const mockConnectedWpcomSites: SyncSite[] = [
url: 'https://developer-staging.wordpress.com/studio/',
isStaging: true,
isPressable: false,
stagingSiteIds: [],
syncSupport: 'syncable',
lastPullTimestamp: null,
lastPushTimestamp: null,
Expand All @@ -51,7 +49,6 @@ const mockSyncSites: SyncSite[] = [
url: 'https://developer.wordpress.com/studio/store',
isStaging: false,
isPressable: false,
stagingSiteIds: [ 9 ],
syncSupport: 'syncable',
lastPullTimestamp: null,
lastPushTimestamp: null,
Expand All @@ -63,7 +60,6 @@ const mockSyncSites: SyncSite[] = [
url: 'https://developer-staging.wordpress.com/studio/test-store',
isStaging: true,
isPressable: false,
stagingSiteIds: [],
syncSupport: 'syncable',
lastPullTimestamp: null,
lastPushTimestamp: null,
Expand All @@ -85,9 +81,7 @@ describe( 'useConnectedSitesOperations', () => {
);

const mockDisconnectSite = jest.fn().mockResolvedValue( [] );
const mockConnectSite = jest
.fn()
.mockResolvedValue( [ ...mockConnectedWpcomSites, { id: 6, stagingSiteIds: [] } ] );
const mockConnectSite = jest.fn().mockResolvedValue( [ ...mockConnectedWpcomSites, { id: 6 } ] );

beforeEach( () => {
( useAuth as jest.Mock ).mockReturnValue( { isAuthenticated: true } );
Expand Down
33 changes: 6 additions & 27 deletions src/hooks/use-fetch-wpcom-sites/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useOffline } from 'src/hooks/use-offline';
import { getIpcApi } from 'src/lib/get-ipc-api';
import type { SyncSite, SyncSupport } from 'src/hooks/use-fetch-wpcom-sites/types';

export const sitesEndpointSiteSchema = z.object( {
const sitesEndpointSiteSchema = z.object( {
ID: z.number(),
is_wpcom_atomic: z.boolean(),
name: z.string(),
Expand Down Expand Up @@ -50,7 +50,7 @@ export const sitesEndpointSiteSchema = z.object( {
type SitesEndpointSite = z.infer< typeof sitesEndpointSiteSchema >;

// We use a permissive schema for the API response to fail gracefully if a single site is malformed
export const sitesEndpointResponseSchema = z.object( {
const sitesEndpointResponseSchema = z.object( {
sites: z.array( z.unknown() ),
} );

Expand Down Expand Up @@ -98,7 +98,7 @@ export function getSyncSupport( site: SitesEndpointSite, connectedSiteIds: numbe
return 'syncable';
}

export function transformSingleSiteResponse(
function transformSingleSiteResponse(
site: SitesEndpointSite,
syncSupport: SyncSupport,
isStaging: boolean
Expand All @@ -111,14 +111,13 @@ export function transformSingleSiteResponse(
isStaging,
isPressable: isPressableSite( site ),
environmentType: site.environment_type,
stagingSiteIds: site.options?.wpcom_staging_blog_ids ?? [],
syncSupport,
lastPullTimestamp: null,
lastPushTimestamp: null,
};
}

export function transformSitesResponse( sites: unknown[], connectedSiteIds: number[] ): SyncSite[] {
function transformSitesResponse( sites: unknown[], connectedSiteIds: number[] ): SyncSite[] {
const validatedSites = sites.reduce< SitesEndpointSite[] >( ( acc, rawSite ) => {
try {
const site = sitesEndpointSiteSchema.parse( rawSite );
Expand Down Expand Up @@ -146,7 +145,7 @@ export function transformSitesResponse( sites: unknown[], connectedSiteIds: numb
} );
}

export type FetchSites = () => Promise< SyncSite[] >;
type FetchSites = () => Promise< SyncSite[] >;

export const useFetchWpComSites = ( connectedSiteIdsOnlyForSelectedSite: number[] ) => {
const [ rawSyncSites, setRawSyncSites ] = useState< unknown[] >( [] );
Expand Down Expand Up @@ -210,29 +209,9 @@ export const useFetchWpComSites = ( connectedSiteIdsOnlyForSelectedSite: number[
);

// whenever array of syncSites changes, we need to update connectedSites to keep them updated with wordpress.com
const { updatedConnectedSites, stagingSitesToAdd, stagingSitesToDelete } =
reconcileConnectedSites( allConnectedSites, syncSites );

const { updatedConnectedSites } = reconcileConnectedSites( allConnectedSites, syncSites );
await getIpcApi().updateConnectedWpcomSites( updatedConnectedSites );

if ( stagingSitesToDelete.length ) {
const data = stagingSitesToDelete.map( ( { id, localSiteId } ) => ( {
siteIds: [ id ],
localSiteId,
} ) );

await getIpcApi().disconnectWpcomSites( data );
}

if ( stagingSitesToAdd.length ) {
const data = stagingSitesToAdd.map( ( site ) => ( {
sites: [ site ],
localSiteId: site.localSiteId,
} ) );

await getIpcApi().connectWpcomSites( data );
}

setRawSyncSites( parsedResponse.sites );

return syncSites;
Expand Down
66 changes: 2 additions & 64 deletions src/hooks/use-fetch-wpcom-sites/reconcile-connected-sites.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { SyncSite } from 'src/hooks/use-fetch-wpcom-sites/types';

/**
* Generate updated site data to be stored in `appdata-v1.json` in three steps:
* 1. Update the list of `connectedSites` with fresh data (name, URL, etc)
* 2. Find any staging sites that have been added to an already connected site
* 3. Find any connected staging sites that have been deleted on WordPress.com
*
* We treat staging sites differently from production sites because users can't connect staging
* sites separately from production sites (they're always connected together). So, while deleted
* production sites are still rendered in the UI (with a "deleted" notice), we need to automatically
* keep the list of staging sites up-to-date, which is where `stagingSitesToAdd` and
* `stagingSitesToDelete` comes in.
* Generate updated site data to be stored in `appdata-v1.json`:
* -- Update the list of `connectedSites` with fresh data (name, URL, etc)
Comment on lines +4 to +5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow! this simplified the logic a lot! 🥳

*/
export const reconcileConnectedSites = (
connectedSites: SyncSite[],
freshWpComSites: SyncSite[]
): {
updatedConnectedSites: SyncSite[];
stagingSitesToAdd: SyncSite[];
stagingSitesToDelete: { id: number; localSiteId: string }[];
} => {
const updatedConnectedSites = connectedSites.map( ( connectedSite ): SyncSite => {
const site = freshWpComSites.find( ( site ) => site.id === connectedSite.id );
Expand All @@ -35,65 +25,13 @@ export const reconcileConnectedSites = (
name: site.name,
url: site.url,
syncSupport: site.syncSupport,
stagingSiteIds: site.stagingSiteIds,
isStaging: site.isStaging,
isPressable: site.isPressable,
environmentType: site.environmentType,
};
}, [] );

const stagingSitesToAdd = connectedSites.flatMap( ( connectedSite ) => {
const updatedConnectedSite = updatedConnectedSites.find(
( site ) => site.id === connectedSite.id
);

if ( ! updatedConnectedSite?.stagingSiteIds.length ) {
return [];
}

const addedStagingSiteIds = updatedConnectedSite.stagingSiteIds.filter(
( id ) => ! connectedSite.stagingSiteIds.includes( id )
);

return addedStagingSiteIds.flatMap( ( id ): SyncSite[] => {
const freshSite = freshWpComSites.find( ( site ) => site.id === id );

if ( ! freshSite ) {
return [];
}

return [
{
...freshSite,
localSiteId: connectedSite.localSiteId,
syncSupport: 'already-connected',
},
];
}, [] );
} );

const stagingSitesToDelete = connectedSites.flatMap( ( connectedSite ) => {
const updatedConnectedSite = updatedConnectedSites.find(
( site ) => site.id === connectedSite.id
);

if ( ! connectedSite?.stagingSiteIds.length ) {
return [];
}

return connectedSite.stagingSiteIds
.filter( ( id ) => ! updatedConnectedSite?.stagingSiteIds.includes( id ) )
.map( ( id ) => {
return {
id,
localSiteId: connectedSite.localSiteId,
};
} );
} );

return {
updatedConnectedSites,
stagingSitesToAdd,
stagingSitesToDelete,
};
};
1 change: 0 additions & 1 deletion src/hooks/use-fetch-wpcom-sites/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export type SyncSite = {
isStaging: boolean;
isPressable: boolean;
environmentType?: string | null;
stagingSiteIds: number[];
syncSupport: SyncSupport;
lastPullTimestamp: string | null;
lastPushTimestamp: string | null;
Expand Down
Loading