From 6590f4cbb151cbf235d1c1faa0c3aaa7edd5c8a8 Mon Sep 17 00:00:00 2001 From: Tilly Woodfield <22456167+tillywoodfield@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:15:01 +0300 Subject: [PATCH] fix: show error when file upload fails --- cypress/fixtures/incorrect-extension.txt | 472 +++++++++++++++++++++++ cypress/integration/checkData.spec.js | 6 + src/components/LocalFilesValidator.vue | 3 +- src/utils/api/validate.js | 8 +- 4 files changed, 486 insertions(+), 3 deletions(-) create mode 100644 cypress/fixtures/incorrect-extension.txt diff --git a/cypress/fixtures/incorrect-extension.txt b/cypress/fixtures/incorrect-extension.txt new file mode 100644 index 00000000..17bae3e0 --- /dev/null +++ b/cypress/fixtures/incorrect-extension.txt @@ -0,0 +1,472 @@ + + + + + + + + + + + AA-AAA-123456789-ABC123 + + + + + Organisation name + Nom de l'organisme + + + + + + <narrative>Activity title</narrative> + <narrative xml:lang="fr">Titre de l'activité</narrative> + <narrative xml:lang="es">Título de la actividad</narrative> + + + + + + General activity description text. Long description of the activity with no particular structure. + Activité générale du texte de description. Longue description de l'activité sans structure particulière. + + + Objectives for the activity, for example from a logical framework. + Objectifs de l'activité, par exemple à partir d'un cadre logique. + + + Statement of groups targeted to benefit from the activity. + Déclaration de groupes ciblés pour bénéficier de l'activité. + + + + + + Name of Agency B + + + Name of Agency C + + + Name of Agency A + Nom de l'agence A + + + + + + + Organisation name + + + + + + + + + + + Planned start date of the activity + Date prévue de début de l'activité + + + + + + + + + Agency A + + + Department B + + + A. Example + + + Transparency Lead + + 0044111222333444 + transparency@example.org + http://www.example.org + + Transparency House, The Street, Town, City, Postcode + + + + + + + + + + + + + + + + + + + + + + + + Location name + + + Location description + + + A description that qualifies the activity taking place at the location. + + + + 31.616944 65.716944 + + + + + + + + + + + + + Location #2 name + + + Location #2 description + + + A description that qualifies the activity taking place at location #2 + + + + 11.5500 104.9167 + + + + + + + + + + + + Code A1 + + + + + + A description of the tag + + + A description of the tag + + + + + + + + Description text + + + + + Description text + + + + + + + + Nepal Earthquake April 2015 + Népal Earthquake Avril 2015 + + + Nepal Earthquake April 2015 + + + + + + + + Code A1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3000 + + + + + + + + 3000 + + Agency B + + + Agency A + + + + + + + + + 3000 + + + + + + + + + + + + 1000 + + Transaction description text + + + Agency B + + + Agency A + + + + + + + + + + + + + + + <narrative>Project Report 2013</narrative> + <narrative xml:lang="fr">Rapport de projet 2013</narrative> + + + Description of the content of the project report or guidance on where to access the relevant information in this report + + + + + + + + + + + + + + + + + + + + Conditions text + Conditions texte + + + + + + + + <narrative>Result title</narrative> + + + Result description text + + + + + <narrative>Results Report 2013</narrative> + + + Report of results + + + + + + + + + + + + + <narrative>Indicator title</narrative> + + + Indicator description text + + + + <narrative>Results Indicator Report 2013</narrative> + + + Report of results indicator + + + + + + + + + + + + + + + + + <narrative>Results Baseline Report 2013</narrative> + + + Report of results baseline + + + + + + + Baseline comment text + + + + + + + + + + + + + + Target comment text + + + + <narrative>Results Period Target Report 2013</narrative> + + + Report of results period target + + + + + + + + + + + + + Actual comment text + + + + <narrative>Results Period Actual Report 2013</narrative> + + + Report of results period actual + + + + + + + + + + + + + + + + + + + + + + + + + 200000 + 1500000 + 0 + 0 + + 21039 + + + + + + 10000 + + + + + + + + diff --git a/cypress/integration/checkData.spec.js b/cypress/integration/checkData.spec.js index af057b52..34587662 100644 --- a/cypress/integration/checkData.spec.js +++ b/cypress/integration/checkData.spec.js @@ -27,6 +27,12 @@ describe('The Ad Hoc Validate Check Data page', () => { cy.contains('IATI version'); cy.contains('Type'); }); + it('displays an error message if it fails to upload a file', () => { + cy.get('input[type=file').selectFile('cypress/fixtures/incorrect-extension.txt', { force: true }); + cy.contains('incorrect-extension.txt'); + cy.contains('button', 'Upload').should('not.be.disabled').click(); + cy.contains('File(s) uploading failed'); + }); it('allows you to upload from URL for validation and access the report', () => { cy.contains('URL to a remote file').click(); cy.get('#url').type( diff --git a/src/components/LocalFilesValidator.vue b/src/components/LocalFilesValidator.vue index 70047cad..bfe32a48 100644 --- a/src/components/LocalFilesValidator.vue +++ b/src/components/LocalFilesValidator.vue @@ -23,7 +23,8 @@ const parallelUpload = (files) => forkJoin(files.map((file) => uploadFile(file, props.workspaceID))); const uploadFiles = () => { - const handleError = () => { + const handleError = (error) => { + console.error(error); requestStatus.value = 'error'; }; diff --git a/src/utils/api/validate.js b/src/utils/api/validate.js index 8608e282..d03cdf17 100644 --- a/src/utils/api/validate.js +++ b/src/utils/api/validate.js @@ -12,9 +12,13 @@ export const uploadFile = async (file, tmpWorkspaceId) => { const uploadData = new FormData(); uploadData.append('file', file, file.name); - const req = await window.fetch(url, { ...getDefaultServicesAPIOptions(), method: 'post', body: uploadData }); + const response = await window.fetch(url, { ...getDefaultServicesAPIOptions(), method: 'post', body: uploadData }); - return last(req); + if (!response.ok) { + const text = await response.text(); + throw new Error(text); + } + return last(response); }; export const fetchFileFromURL = async (fileUrl, workspaceID) => {