diff --git a/assets/src/bundles/browse/origin-search.js b/assets/src/bundles/browse/origin-search.js --- a/assets/src/bundles/browse/origin-search.js +++ b/assets/src/bundles/browse/origin-search.js @@ -5,7 +5,7 @@ * See top-level LICENSE file for more information */ -import {handleFetchError} from 'utils/functions'; +import {handleFetchError, isArchivedOrigin} from 'utils/functions'; const limit = 100; let linksPrev = []; @@ -162,7 +162,7 @@ }); } -function doSearch() { +async function doSearch() { $('#swh-no-result').hide(); let searchQueryText = $('#swh-origins-url-patterns').val(); inSearch = true; @@ -186,10 +186,13 @@ $('#swh-no-result').text(data.reason); $('#swh-no-result').show(); }); - }); + } else if (await isArchivedOrigin(searchQueryText)) { + // redirect to the browse origin + window.location.href = + `${Urls.browse_origin()}?origin_url=${encodeURIComponent(searchQueryText)}`; } else { - // otherwise, proceed with origins search + // otherwise, proceed with origins search irrespective of the error $('#swh-origin-search-results').show(); $('.swh-search-pagination').show(); searchOriginsFirst(searchQueryText, limit); diff --git a/assets/src/utils/functions.js b/assets/src/utils/functions.js --- a/assets/src/utils/functions.js +++ b/assets/src/utils/functions.js @@ -78,3 +78,22 @@ } return ``; } + +export function isValidURL(string) { + try { + new URL(string); + } catch (_) { + return false; + } + return true; +} + +export async function isArchivedOrigin(originPath) { + if (!isValidURL(originPath)) { + // Not a valid URL, return immediately + return false; + } else { + const response = await fetch(Urls.api_1_origin(originPath)); + return response.ok && response.status === 200; // Success response represents an archived origin + } +} diff --git a/cypress/integration/origin-search.spec.js b/cypress/integration/origin-search.spec.js --- a/cypress/integration/origin-search.spec.js +++ b/cypress/integration/origin-search.spec.js @@ -67,32 +67,45 @@ // .should('have.focus'); }); - it('should show in result when url is searched', function() { + it('should redirect to browse when archived URL is searched', function() { cy.get('#swh-origins-url-patterns') .type(origin.url); cy.get('.swh-search-icon') .click(); - cy.get('#origin-search-results') - .should('be.visible'); - cy.contains('tr', origin.url) - .should('be.visible') - .find('.swh-visit-status') - .find('i') - .should('have.class', 'mdi-check-bold') - .and('have.attr', 'title', - 'Software origin has been archived by Software Heritage'); - - const browseOriginUrl = `${this.Urls.browse_origin()}?origin_url=${encodeURIComponent(origin.url)}`; - cy.get('tr a') - .should('have.attr', 'href', browseOriginUrl); + cy.location('pathname') + .should('eq', this.Urls.browse_origin_directory()); + cy.location('search') + .should('eq', `?origin_url=${origin.url}`); + }); + + it('should not redirect for non valid URL', function() { + cy.get('#swh-origins-url-patterns') + .type('www.example'); // Invalid URL + cy.get('.swh-search-icon') + .click(); + + cy.location('pathname') + .should('eq', this.Urls.browse_search()); // Stay in the current page + }); + + it('should not redirect for valid non archived URL', function() { + cy.get('#swh-origins-url-patterns') + .type('http://eaxmple.com/test/'); // Valid URL, but not archived + cy.get('.swh-search-icon') + .click(); + + cy.location('pathname') + .should('eq', this.Urls.browse_search()); // Stay in the current page }); it('should remove origin URL with no archived content', function() { stubOriginVisitLatestRequests(404); + // Using a non full origin URL here + // This is because T3354 redirects to the origin in case of a valid, archived URL cy.get('#swh-origins-url-patterns') - .type(origin.url); + .type(origin.url.slice(0, -1)); cy.get('.swh-search-icon') .click(); @@ -199,11 +212,11 @@ cy.intercept(`${this.Urls.api_1_resolve_swhid('').slice(0, -1)}**`) .as('resolveSWHID'); - cy.intercept(`${this.Urls.api_1_origin_search(origin.url)}**`) + cy.intercept(`${this.Urls.api_1_origin_search(origin.url.slice(0, -1))}**`) .as('searchOrigin'); cy.get('#swh-origins-url-patterns') - .type(origin.url); + .type(origin.url.slice(0, -1)); cy.get('.swh-search-icon') .click();