feat: Add error messages for partial migration [FC-0107] (#2555)

Adds the error messages for partial migrations
This commit is contained in:
Chris Chávez
2025-10-22 17:07:24 -05:00
committed by GitHub
parent 5ce61fa5e5
commit 76d8b2e03a
6 changed files with 130 additions and 4 deletions

View File

@@ -418,7 +418,7 @@ describe('<LegacyLibMigrationPage />', () => {
expect(axiosMock.history.post[0].data).toBe(
'{"sources":["library-v1:MBA+123","library-v1:UNIX+LG1","library-v1:MBA+1234"],"target":"lib:SampleTaxonomyOrg1:TL1","create_collections":true,"repeat_handling_strategy":"fork"}',
);
expect(mockShowToast).toHaveBeenCalledWith('Legacy libraries migration failed.');
expect(mockShowToast).toHaveBeenCalledWith('Legacy libraries migration have failed');
});
it('should show help sidebar', async () => {

View File

@@ -6,6 +6,10 @@ export async function mockGetMigrationStatus(migrationId: string): Promise<api.M
return mockGetMigrationStatus.migrationStatusData;
case mockGetMigrationStatus.migrationIdFailed:
return mockGetMigrationStatus.migrationStatusFailedData;
case mockGetMigrationStatus.migrationIdMultiple:
return mockGetMigrationStatus.migrationStatusFailedMultipleData;
case mockGetMigrationStatus.migrationIdOneLibrary:
return mockGetMigrationStatus.migrationStatusFailedOneLibraryData;
default:
/* istanbul ignore next */
throw new Error(`mockGetMigrationStatus: unknown migration ID "${migrationId}"`);
@@ -32,6 +36,7 @@ mockGetMigrationStatus.migrationStatusData = {
preserveUrlSlugs: false,
targetCollectionSlug: 'coll-1',
forwardSourceToTarget: true,
isFailed: false,
},
],
} as api.MigrateTaskStatusData;
@@ -55,6 +60,75 @@ mockGetMigrationStatus.migrationStatusFailedData = {
preserveUrlSlugs: false,
targetCollectionSlug: 'coll-1',
forwardSourceToTarget: true,
isFailed: true,
},
],
} as api.MigrateTaskStatusData;
mockGetMigrationStatus.migrationIdMultiple = '3';
mockGetMigrationStatus.migrationStatusFailedMultipleData = {
uuid: mockGetMigrationStatus.migrationId,
state: 'Succeeded',
stateText: 'Succeeded',
completedSteps: 9,
totalSteps: 9,
attempts: 1,
created: '',
modified: '',
artifacts: [],
parameters: [
{
source: 'legacy-lib-1',
target: 'lib',
compositionLevel: 'component',
repeatHandlingStrategy: 'update',
preserveUrlSlugs: false,
targetCollectionSlug: 'coll-1',
forwardSourceToTarget: true,
isFailed: true,
},
{
source: 'legacy-lib-2',
target: 'lib',
compositionLevel: 'component',
repeatHandlingStrategy: 'update',
preserveUrlSlugs: false,
targetCollectionSlug: 'coll-1',
forwardSourceToTarget: true,
isFailed: true,
},
],
} as api.MigrateTaskStatusData;
mockGetMigrationStatus.migrationIdOneLibrary = '4';
mockGetMigrationStatus.migrationStatusFailedOneLibraryData = {
uuid: mockGetMigrationStatus.migrationId,
state: 'Succeeded',
stateText: 'Succeeded',
completedSteps: 9,
totalSteps: 9,
attempts: 1,
created: '',
modified: '',
artifacts: [],
parameters: [
{
source: 'legacy-lib-1',
target: 'lib',
compositionLevel: 'component',
repeatHandlingStrategy: 'update',
preserveUrlSlugs: false,
targetCollectionSlug: 'coll-1',
forwardSourceToTarget: true,
isFailed: true,
},
{
source: 'legacy-lib-2',
target: 'lib',
compositionLevel: 'component',
repeatHandlingStrategy: 'update',
preserveUrlSlugs: false,
targetCollectionSlug: 'coll-1',
forwardSourceToTarget: true,
isFailed: false,
},
],
} as api.MigrateTaskStatusData;

View File

@@ -21,6 +21,7 @@ export interface MigrateArtifacts {
preserveUrlSlugs: boolean;
targetCollectionSlug: string;
forwardSourceToTarget: boolean;
isFailed: boolean;
}
export interface MigrateTaskStatusData {

View File

@@ -142,9 +142,19 @@ const messages = defineMessages({
},
migrationFailed: {
id: 'legacy-libraries-migration.confirmation-step.toast.migration-failed',
defaultMessage: 'Legacy libraries migration failed.',
defaultMessage: 'Legacy libraries migration have failed',
description: 'Toast message that indicates the migration of legacy libraries is failed',
},
migrationFailedMultiple: {
id: 'legacy-libraries-migration.confirmation-step.toast.migration-multiple-failed',
defaultMessage: 'Multiple legacy libraries have failed',
description: 'Toast message that indicates the migration of legacy libraries is failed',
},
migrationFailedOneLibrary: {
id: 'legacy-libraries-migration.confirmation-step.toast.migration-one-failed',
defaultMessage: 'The legacy library with this key has failed: {key}',
description: 'Toast message that indicates that one legacy library has failed in the migration',
},
migrationSuccess: {
id: 'legacy-libraries-migration.confirmation-step.toast.migration-success',
defaultMessage: 'The migration of legacy libraries has been completed successfully.',

View File

@@ -1089,6 +1089,32 @@ describe('<LibraryAuthoringPage />', () => {
},
});
await waitFor(() => expect(mockShowToast).toHaveBeenCalledWith('Legacy libraries migration failed.'));
await waitFor(() => expect(mockShowToast).toHaveBeenCalledWith('Legacy libraries migration have failed'));
});
it('Should show fail multiple legacy libraries in a migration', async () => {
render(<LibraryLayout />, {
path,
routerProps: {
initialEntries: [
`/library/${mockContentLibrary.libraryId}?migration_task=${mockGetMigrationStatus.migrationIdMultiple}`,
],
},
});
await waitFor(() => expect(mockShowToast).toHaveBeenCalledWith('Multiple legacy libraries have failed'));
});
it('Should show fail one legacy library in a migration', async () => {
render(<LibraryLayout />, {
path,
routerProps: {
initialEntries: [
`/library/${mockContentLibrary.libraryId}?migration_task=${mockGetMigrationStatus.migrationIdOneLibrary}`,
],
},
});
await waitFor(() => expect(mockShowToast).toHaveBeenCalledWith('The legacy library with this key has failed: legacy-lib-1'));
});
});

View File

@@ -225,10 +225,25 @@ const LibraryAuthoringPage = ({
if (migrationId) {
let deleteMigrationIdParam = false;
if (migrationStatusData?.state === 'Succeeded') {
showToast(intl.formatMessage(migrationMessages.migrationSuccess));
// Check if any library migrations failed.
// A `Succeeded` state means that the bulk migration ended, but some libraries might have failed.
const failedMigrations = migrationStatusData.parameters.filter(item => item.isFailed);
if (failedMigrations.length > 1) {
showToast(intl.formatMessage(migrationMessages.migrationFailedMultiple));
} else if (failedMigrations.length === 1) {
showToast(intl.formatMessage(
migrationMessages.migrationFailedOneLibrary,
{
key: failedMigrations[0].source,
},
));
} else {
showToast(intl.formatMessage(migrationMessages.migrationSuccess));
}
queryClient.invalidateQueries({ predicate: (query) => libraryQueryPredicate(query, libraryId) });
deleteMigrationIdParam = true;
} else if (migrationStatusData?.state === 'Failed') {
// A `Failed` state means that the entire bulk migration has failed.
showToast(intl.formatMessage(migrationMessages.migrationFailed));
deleteMigrationIdParam = true;
} else if (migrationStatusData?.state === 'Canceled') {