diff --git a/CHANGELOG.md b/CHANGELOG.md index e6521c38..0255efab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Added 'Unauthorized' to the fetch status (#90) ### Changed - On empty query result, show clear message (#86) diff --git a/cypress/e2e/fetch-status.cy.js b/cypress/e2e/fetch-status.cy.js index e1b0e451..ca9c8fec 100644 --- a/cypress/e2e/fetch-status.cy.js +++ b/cypress/e2e/fetch-status.cy.js @@ -15,10 +15,10 @@ describe("Fetch Status", () => { // Check if the correct icons appear cy.get('[aria-label="Authentication required"]').should("exist"); - cy.get('[aria-label="Fetch failed"]').should("exist"); + cy.get('[aria-label="Unauthorized"]').should("exist"); cy.get('[aria-label="No authentication required"]').should("exist"); - cy.get('[aria-label="Fetch was succesful"]').should("exist"); + cy.get('[aria-label="Fetch was successful"]').should("exist"); // Checking that a non-authorized book is not appearing @@ -60,13 +60,36 @@ describe("Fetch Status", () => { // Check if the correct icons appear cy.get('[aria-label="Authentication required"]').should("exist"); cy.get('[aria-label="Fetch Failed"]').should("not.exist"); + cy.get('[aria-label="Unauthorized"]').should("not.exist"); cy.get('[aria-label="No authentication required"]').should("exist"); - cy.get('[aria-label="Fetch was succesful"]').should("exist"); + cy.get('[aria-label="Fetch was successful"]').should("exist"); // Checking that you see authorized books cy.contains("It Ends With Us"); cy.contains("Too Late"); }); + it("Failed to fetch data", () => { + + cy.visit("/"); + + // Go immediately to query + cy.contains("My favourite musicians").click(); + + // Check if the good and bad sources appear + cy.get('[aria-label="Sources info"]').click(); + + // First fetch should be a success + cy.contains("http://localhost:8080/example/favourite-musicians"); + cy.get('[aria-label="No authentication required"]').should("exist"); + cy.get('[aria-label="Unauthorized"]').should("not.exist"); + cy.get('[aria-label="Fetch was successful"]').should("exist"); + + // the bad source should fail to fetch + cy.contains("http://www.example.com/fetch-failure-but-query-success"); + cy.get('[aria-label="Fetch failed"]').should("exist"); + + }); + }) \ No newline at end of file diff --git a/cypress/e2e/sources-info.cy.js b/cypress/e2e/sources-info.cy.js index 40a74557..d6122179 100644 --- a/cypress/e2e/sources-info.cy.js +++ b/cypress/e2e/sources-info.cy.js @@ -16,7 +16,7 @@ describe("Sources info", () => { cy.contains("Finished in:"); cy.get('[aria-label="Sources info"]').click(); - cy.get('[aria-label="Fetch was succesful"]').should("exist"); + cy.get('[aria-label="Fetch was successful"]').should("exist"); }); it("Fetch status on cached source - see https://github.com/SolidLabResearch/generic-data-viewer-react-admin/issues/59", () => { @@ -26,13 +26,13 @@ describe("Sources info", () => { cy.contains("Finished in:"); cy.get('[aria-label="Sources info"]').click(); - cy.get('[aria-label="Fetch was succesful"]').should("exist"); + cy.get('[aria-label="Fetch was successful"]').should("exist"); cy.contains("Components and their materials").click(); cy.contains("Finished in:"); cy.get('[aria-label="Sources info"]').click(); - cy.get('[aria-label="Fetch was succesful"]').should("exist"); + cy.get('[aria-label="Fetch was successful"]').should("exist"); cy.get('[aria-label="Fetch failed"]').should("not.exist"); }); diff --git a/src/components/ActionBar/SourceFetchStatusIcon/SourceFetchStatusIcon.jsx b/src/components/ActionBar/SourceFetchStatusIcon/SourceFetchStatusIcon.jsx index 6dd13906..f6d8c190 100644 --- a/src/components/ActionBar/SourceFetchStatusIcon/SourceFetchStatusIcon.jsx +++ b/src/components/ActionBar/SourceFetchStatusIcon/SourceFetchStatusIcon.jsx @@ -1,5 +1,6 @@ import CheckIcon from '@mui/icons-material/Check'; import CancelIcon from "@mui/icons-material/Cancel"; +import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import { Tooltip } from "@mui/material"; import PropTypes from "prop-types"; import { Component } from "react"; @@ -16,14 +17,23 @@ function SourceFetchStatusIcon({ context, source, proxyUrl }) { if (context.useProxy) { actualSource = `${proxyUrl}${source}`; } - const status = context.fetchSuccess[actualSource]; - if (status) { + const status = context.fetchStatusNumber[actualSource]; + + if (context.fetchSuccess[actualSource]) { return ( - + ); - } else { + } + else if (status == 401 || status == 403){ + return ( + + + + ); + } + else { return ( diff --git a/src/dataProvider/SparqlDataProvider.js b/src/dataProvider/SparqlDataProvider.js index 181762eb..e197c4be 100644 --- a/src/dataProvider/SparqlDataProvider.js +++ b/src/dataProvider/SparqlDataProvider.js @@ -207,6 +207,7 @@ function generateContext(context) { if (!context.fetchSuccess) { context.fetchSuccess = {}; + context.fetchStatusNumber = {}; // avoid faulty fetch status for sources cached in Comunica for (const source of context.sources) { context.fetchSuccess[source] = true; @@ -239,6 +240,7 @@ function statusFetch(customFetch, context) { try{ const response = await customFetch(arg); context.fetchSuccess[arg] = response.ok; + context.fetchStatusNumber[arg] = response.status; return response; } catch(error){ @@ -246,6 +248,7 @@ function statusFetch(customFetch, context) { throw error; } } + return wrappedFetchFunction; }