diff --git a/cypress/integration/vault.spec.js b/cypress/integration/vault.spec.js --- a/cypress/integration/vault.spec.js +++ b/cypress/integration/vault.spec.js @@ -404,4 +404,24 @@ }); + it('should offer to recook an object if previous vault task failed', function() { + + cy.visit(this.directoryUrl); + + // Stub responses when requesting the vault API to simulate + // the last cooking of the directory tarball has failed + cy.route({ + method: 'GET', + url: this.vaultDirectoryUrl, + response: this.genVaultDirCookingResponse('failed') + }).as('checkVaultCookingTask'); + + checkVaultCookingTask('as tarball'); + + // Check that recooking the directory is offered to user + cy.get('.modal-dialog') + .contains('button:visible', 'Ok') + .should('be.visible'); + }); + }); diff --git a/swh/web/assets/src/bundles/vault/vault-create-tasks.js b/swh/web/assets/src/bundles/vault/vault-create-tasks.js --- a/swh/web/assets/src/bundles/vault/vault-create-tasks.js +++ b/swh/web/assets/src/bundles/vault/vault-create-tasks.js @@ -19,9 +19,13 @@ .then(response => response.json()) .then(data => { // object needs to be cooked - if (data.exception === 'NotFoundExc') { + if (data.exception === 'NotFoundExc' || data.status === 'failed') { + // if last cooking has failed, remove previous task info from localStorage + // in order to force the recooking of the object + swh.vault.removeCookingTaskInfo([objectId]); $(`#vault-cook-${objectType}-modal`).modal('show'); - // object has been cooked and is in the vault cache + // object has been cooked and should be in the vault cache, + // it will be asked to cook it again if it is not } else if (data.status === 'done') { $(`#vault-fetch-${objectType}-modal`).modal('show'); } diff --git a/swh/web/assets/src/bundles/vault/vault-ui.js b/swh/web/assets/src/bundles/vault/vault-ui.js --- a/swh/web/assets/src/bundles/vault/vault-ui.js +++ b/swh/web/assets/src/bundles/vault/vault-ui.js @@ -209,6 +209,17 @@ .catch(() => {}); } +export function removeCookingTaskInfo(tasksToRemove) { + let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); + if (!vaultCookingTasks) { + return; + } + vaultCookingTasks = $.grep(vaultCookingTasks, task => { + return $.inArray(task.object_id, tasksToRemove) === -1; + }); + localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); +} + export function initUi() { $('#vault-tasks-toggle-selection').change(event => { @@ -226,11 +237,7 @@ $(row).remove(); } }); - let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); - vaultCookingTasks = $.grep(vaultCookingTasks, task => { - return $.inArray(task.object_id, tasksToRemove) === -1; - }); - localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); + removeCookingTaskInfo(tasksToRemove); $('#vault-tasks-toggle-selection').prop('checked', false); checkVaultId = setTimeout(checkVaultCookingTasks, pollingInterval); });