From 0567c1b6f8b54bc81c4390f6ee1c6b8d1d7bbad7 Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Wed, 10 Dec 2025 23:22:54 -0500 Subject: [PATCH] fix: support "in progress" status for lib upload When uploading a library archive file during the creation of a new library, the code prior to this commit did not properly handle the "In Progress" state, which is when the celery task doing the archive processing is actively running. Note that this is distinct from the "Pending" state, which is when the task is waiting in the queue to be run (which in practice should almost never happen unless there is an operational issue). Since celery tasks run in-process during local development, the task was always finished by the time that the browser made a call to check on the status. The problem only happened on slower sandboxes, where processing truly runs asynchronously and might take a few seconds. Because this case wasn't handled, the frontend would never poll for updates either, so the upload was basically lost as far as the user was concerned. --- .../create-library/CreateLibrary.tsx | 3 +- .../create-library/data/apiHooks.test.tsx | 28 +++++++++++++++++++ .../create-library/data/apiHooks.ts | 5 +++- .../create-library/data/restoreConstants.ts | 1 + 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/library-authoring/create-library/CreateLibrary.tsx b/src/library-authoring/create-library/CreateLibrary.tsx index 9bae528191..c9d67de91c 100644 --- a/src/library-authoring/create-library/CreateLibrary.tsx +++ b/src/library-authoring/create-library/CreateLibrary.tsx @@ -253,7 +253,8 @@ export const CreateLibrary = ({ {(restoreTaskId || isError || restoreMutation.isError) && (
- {restoreStatus?.state === LibraryRestoreStatus.Pending && ( + {(restoreStatus?.state === LibraryRestoreStatus.Pending + || restoreStatus?.state === LibraryRestoreStatus.InProgress) && ( {intl.formatMessage(messages.restoreInProgress)} diff --git a/src/library-authoring/create-library/data/apiHooks.test.tsx b/src/library-authoring/create-library/data/apiHooks.test.tsx index e4befed86d..0075bcac65 100644 --- a/src/library-authoring/create-library/data/apiHooks.test.tsx +++ b/src/library-authoring/create-library/data/apiHooks.test.tsx @@ -173,6 +173,34 @@ describe('create library apiHooks', () => { expect(axiosMock.history.get[0].url).toEqual(`http://localhost:18010/api/libraries/v2/restore/?task_id=${taskId}`); }); + it('should handle in-progress status with refetch interval', async () => { + const taskId = 'in-progress-task-id'; + const inProgressResult = { + state: LibraryRestoreStatus.InProgress, + result: null, + error: null, + error_log: null, + }; + + const expectedResult = { + state: LibraryRestoreStatus.InProgress, + result: null, + error: null, + errorLog: null, + }; + + axiosMock.onGet(`http://localhost:18010/api/libraries/v2/restore/?task_id=${taskId}`).reply(200, inProgressResult); + + const { result } = renderHook(() => useGetLibraryRestoreStatus(taskId), { wrapper }); + + await waitFor(() => { + expect(result.current.isLoading).toBeFalsy(); + }); + + expect(result.current.data).toEqual(expectedResult); + expect(axiosMock.history.get[0].url).toEqual(`http://localhost:18010/api/libraries/v2/restore/?task_id=${taskId}`); + }); + it('should handle failed status', async () => { const taskId = 'failed-task-id'; const failedResult = { diff --git a/src/library-authoring/create-library/data/apiHooks.ts b/src/library-authoring/create-library/data/apiHooks.ts index 9fac3edf75..1f53719684 100644 --- a/src/library-authoring/create-library/data/apiHooks.ts +++ b/src/library-authoring/create-library/data/apiHooks.ts @@ -41,7 +41,10 @@ export const useGetLibraryRestoreStatus = (taskId: string) => useQuery getLibraryRestoreStatus(taskId), enabled: !!taskId, // Only run the query if taskId is provided - refetchInterval: (query) => (query.state.data?.state === LibraryRestoreStatus.Pending ? 2000 : false), + refetchInterval: (query) => ( + (query.state.data?.state === LibraryRestoreStatus.Pending + || query.state.data?.state === LibraryRestoreStatus.InProgress + ) ? 2000 : false), }); export const useCreateLibraryRestore = () => useMutation({ diff --git a/src/library-authoring/create-library/data/restoreConstants.ts b/src/library-authoring/create-library/data/restoreConstants.ts index 323821e631..4545285cee 100644 --- a/src/library-authoring/create-library/data/restoreConstants.ts +++ b/src/library-authoring/create-library/data/restoreConstants.ts @@ -32,6 +32,7 @@ export interface GetLibraryRestoreStatusResponse { export enum LibraryRestoreStatus { Pending = 'Pending', + InProgress = 'In Progress', Succeeded = 'Succeeded', Failed = 'Failed', }