From 1660ad898dc461907959d73cbacf91c22a231b34 Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Tue, 18 Nov 2025 18:11:28 -0600 Subject: [PATCH 1/4] feat: add support for origin server and user info --- .../create-library/CreateLibrary.tsx | 23 ++++++++++++++++--- .../create-library/messages.ts | 7 +++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/library-authoring/create-library/CreateLibrary.tsx b/src/library-authoring/create-library/CreateLibrary.tsx index 34217222f0..b54cd37336 100644 --- a/src/library-authoring/create-library/CreateLibrary.tsx +++ b/src/library-authoring/create-library/CreateLibrary.tsx @@ -15,6 +15,7 @@ import { import { AccessTime, Widgets, + PersonOutline, } from '@openedx/paragon/icons'; import AlertError from '@src/generic/alert-error'; import classNames from 'classnames'; @@ -203,20 +204,36 @@ export const CreateLibrary = ({
- {restoreStatus.result.title} + {restoreStatus.result.title}

{restoreStatus.result.org} / {restoreStatus.result.slug}

-
+
{intl.formatMessage(messages.archiveComponentsCount, { - count: restoreStatus.result.components, + countSections: restoreStatus.result.sections, + countSubsections: restoreStatus.result.subsections, + countUnits: restoreStatus.result.units, + countComponents: restoreStatus.result.components, })}
+ { + (restoreStatus.result.createdBy?.email && restoreStatus.result.createdOnServer) && ( +
+ + + {intl.formatMessage(messages.archiveRestoredCreatedBy, { + createdBy: restoreStatus.result.createdBy?.email, + server: restoreStatus.result.createdOnServer, + })} + +
+ ) + }
diff --git a/src/library-authoring/create-library/messages.ts b/src/library-authoring/create-library/messages.ts index 190c9a5831..5f44567755 100644 --- a/src/library-authoring/create-library/messages.ts +++ b/src/library-authoring/create-library/messages.ts @@ -120,9 +120,14 @@ const messages = defineMessages({ }, archiveComponentsCount: { id: 'course-authoring.library-authoring.create-library.form.archive.components-count', - defaultMessage: 'Contains {count} Components', + defaultMessage: 'Contains {countSections} sections, {countSubsections} subsections, {countUnits} units, {countComponents} components', description: 'Text showing the number of components in the restored archive.', }, + archiveRestoredCreatedBy: { + id: 'course-authoring.library-authoring.create-library.form.archive.restored-created-by', + defaultMessage: 'Created on instance {server}, by user {createdBy}', + description: 'Text showing who restored the archive.', + }, archiveBackupDate: { id: 'course-authoring.library-authoring.create-library.form.archive.backup-date', defaultMessage: 'Backed up {date} at {time}', From 9e1564c4040465aaa6c186e2278831080c9718e6 Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Fri, 21 Nov 2025 10:38:57 -0600 Subject: [PATCH 2/4] test: add coverage for restore archive summary --- .../create-library/CreateLibrary.test.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/library-authoring/create-library/CreateLibrary.test.tsx b/src/library-authoring/create-library/CreateLibrary.test.tsx index f9762e5969..4df654bcfc 100644 --- a/src/library-authoring/create-library/CreateLibrary.test.tsx +++ b/src/library-authoring/create-library/CreateLibrary.test.tsx @@ -435,7 +435,7 @@ describe('', () => { sections: 8, subsections: 12, units: 20, - createdOnServer: '2025-01-01T10:00:00Z', + createdOnServer: 'test.com', createdAt: '2025-01-01T10:00:00Z', createdBy: { username: 'testuser', @@ -478,7 +478,10 @@ describe('', () => { await waitFor(() => { expect(screen.getByText('Test Archive Library')).toBeInTheDocument(); expect(screen.getByText('TestOrg / test-archive')).toBeInTheDocument(); - expect(screen.getByText(/Contains 15 Components/i)).toBeInTheDocument(); + // Testing the archive details summary + expect(screen.getByText(/Contains 8 sections, 12 subsections, 20 units, 15 components/i)).toBeInTheDocument(); + expect(screen.getByText(/Created on instance test.com/i)).toBeInTheDocument(); + expect(screen.getByText(/by user test@example.com/i)).toBeInTheDocument(); }); }); From 47be3ef09235c61b2faa5d70b766155164fb8bb2 Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Fri, 21 Nov 2025 13:16:07 -0600 Subject: [PATCH 3/4] test: increase coverage for restore archive summary --- .../create-library/CreateLibrary.test.tsx | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/library-authoring/create-library/CreateLibrary.test.tsx b/src/library-authoring/create-library/CreateLibrary.test.tsx index 4df654bcfc..8821557deb 100644 --- a/src/library-authoring/create-library/CreateLibrary.test.tsx +++ b/src/library-authoring/create-library/CreateLibrary.test.tsx @@ -485,6 +485,68 @@ describe('', () => { }); }); + test('shows success state without instance and user email information', async () => { + const user = userEvent.setup(); + axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock); + + const mockResult = { + learningPackageId: 123, + title: 'Test Archive Library', + org: 'TestOrg', + slug: 'test-archive', + key: 'TestOrg/test-archive', + archiveKey: 'archive-key', + containers: 5, + components: 15, + collections: 3, + sections: 8, + subsections: 12, + units: 20, + createdOnServer: null, + createdAt: '2025-01-01T10:00:00Z', + createdBy: null, + }; + + // Pre-set the restore status to succeeded + mockRestoreStatusData = { + state: LibraryRestoreStatus.Succeeded, + result: mockResult, + error: null, + errorLog: null, + }; + + // Mock the restore mutation to return a task ID + mockRestoreMutate.mockImplementation((_file: File, { onSuccess }: any) => { + onSuccess({ taskId: 'task-123' }); + }); + + render(); + + // Switch to archive mode + const createFromArchiveBtn = await screen.findByRole('button', { name: messages.createFromArchiveButton.defaultMessage }); + await user.click(createFromArchiveBtn); + + // Upload a file to trigger the restore process + const file = new File(['test content'], 'test-archive.zip', { type: 'application/zip' }); + const dropzone = screen.getByTestId('library-archive-dropzone'); + const input = dropzone.querySelector('input[type="file"]') as HTMLInputElement; + + Object.defineProperty(input, 'files', { + value: [file], + writable: false, + }); + + fireEvent.change(input); + + // Wait for the restore to complete and archive details to be shown + await waitFor(() => { + // Testing the archive details summary without instance and user email + expect(screen.getByText(/Contains 8 sections, 12 subsections, 20 units, 15 components/i)).toBeInTheDocument(); + expect(screen.queryByText(/Created on instance/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/by user/i)).not.toBeInTheDocument(); + }); + }); + test('shows error state with error message and link after failed upload', async () => { const user = userEvent.setup(); axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock); From 644b076a8a299f6bc1a4d0713198f7c3b8b6acb5 Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Mon, 24 Nov 2025 12:36:41 -0600 Subject: [PATCH 4/4] fix: address comments --- .../create-library/CreateLibrary.test.tsx | 9 ++------- src/library-authoring/create-library/CreateLibrary.tsx | 6 +++--- src/library-authoring/create-library/messages.ts | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/library-authoring/create-library/CreateLibrary.test.tsx b/src/library-authoring/create-library/CreateLibrary.test.tsx index 8821557deb..06228f1aa5 100644 --- a/src/library-authoring/create-library/CreateLibrary.test.tsx +++ b/src/library-authoring/create-library/CreateLibrary.test.tsx @@ -528,15 +528,10 @@ describe('', () => { // Upload a file to trigger the restore process const file = new File(['test content'], 'test-archive.zip', { type: 'application/zip' }); - const dropzone = screen.getByTestId('library-archive-dropzone'); + const dropzone = screen.getByRole('presentation', { hidden: true }); const input = dropzone.querySelector('input[type="file"]') as HTMLInputElement; - Object.defineProperty(input, 'files', { - value: [file], - writable: false, - }); - - fireEvent.change(input); + await user.upload(input, file); // Wait for the restore to complete and archive details to be shown await waitFor(() => { diff --git a/src/library-authoring/create-library/CreateLibrary.tsx b/src/library-authoring/create-library/CreateLibrary.tsx index b54cd37336..9bae528191 100644 --- a/src/library-authoring/create-library/CreateLibrary.tsx +++ b/src/library-authoring/create-library/CreateLibrary.tsx @@ -211,7 +211,7 @@ export const CreateLibrary = ({
- + {intl.formatMessage(messages.archiveComponentsCount, { countSections: restoreStatus.result.sections, @@ -224,7 +224,7 @@ export const CreateLibrary = ({ { (restoreStatus.result.createdBy?.email && restoreStatus.result.createdOnServer) && (
- + {intl.formatMessage(messages.archiveRestoredCreatedBy, { createdBy: restoreStatus.result.createdBy?.email, @@ -235,7 +235,7 @@ export const CreateLibrary = ({ ) }
- + {intl.formatMessage(messages.archiveBackupDate, { date: new Date(restoreStatus.result.createdAt).toLocaleDateString(), diff --git a/src/library-authoring/create-library/messages.ts b/src/library-authoring/create-library/messages.ts index 5f44567755..846b6bd5e2 100644 --- a/src/library-authoring/create-library/messages.ts +++ b/src/library-authoring/create-library/messages.ts @@ -121,7 +121,7 @@ const messages = defineMessages({ archiveComponentsCount: { id: 'course-authoring.library-authoring.create-library.form.archive.components-count', defaultMessage: 'Contains {countSections} sections, {countSubsections} subsections, {countUnits} units, {countComponents} components', - description: 'Text showing the number of components in the restored archive.', + description: 'Text showing the number of sections, subsections, units, and components in the restored archive.', }, archiveRestoredCreatedBy: { id: 'course-authoring.library-authoring.create-library.form.archive.restored-created-by',