diff --git a/assets/src/bundles/webapp/webapp-utils.js b/assets/src/bundles/webapp/webapp-utils.js --- a/assets/src/bundles/webapp/webapp-utils.js +++ b/assets/src/bundles/webapp/webapp-utils.js @@ -360,15 +360,36 @@ } } +function coreSWHIDIsLowerCase(swhid) { + const qualifiersPos = swhid.indexOf(';'); + let coreSWHID = swhid; + if (qualifiersPos !== -1) { + coreSWHID = swhid.slice(0, qualifiersPos); + } + return coreSWHID.toLowerCase() === coreSWHID; +} + export async function validateSWHIDInput(swhidInputElt) { const swhidInput = swhidInputElt.value.trim(); let customValidity = ''; - if (swhidInput.startsWith('swh:')) { - const resolveSWHIDUrl = Urls.api_1_resolve_swhid(swhidInput); - const response = await fetch(resolveSWHIDUrl); - const responseData = await response.json(); - if (responseData.hasOwnProperty('exception')) { - customValidity = responseData.reason; + if (swhidInput.toLowerCase().startsWith('swh:')) { + if (coreSWHIDIsLowerCase(swhidInput)) { + const resolveSWHIDUrl = Urls.api_1_resolve_swhid(swhidInput); + const response = await fetch(resolveSWHIDUrl); + const responseData = await response.json(); + if (responseData.hasOwnProperty('exception')) { + customValidity = responseData.reason; + } + } else { + const qualifiersPos = swhidInput.indexOf(';'); + if (qualifiersPos === -1) { + customValidity = 'Invalid SWHID: all characters must be in lowercase. '; + customValidity += `Valid SWHID is ${swhidInput.toLowerCase()}`; + } else { + customValidity = 'Invalid SWHID: the core part must be in lowercase. '; + const coreSWHID = swhidInput.slice(0, qualifiersPos); + customValidity += `Valid SWHID is ${swhidInput.replace(coreSWHID, coreSWHID.toLowerCase())}`; + } } } swhidInputElt.setCustomValidity(customValidity); 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 @@ -511,27 +511,46 @@ searchShouldShowNotFound(swhid, msg); }); - function checkInvalidSWHIDReport(url, searchInputElt, repoData) { - const invalidSWHID = `swh:1:cnt:${repoData.content[0].sha1git};lines=45-60/`; + function checkInvalidSWHIDReport(url, searchInputElt, swhidInput, validationMessagePattern = '') { cy.visit(url); - doSearch(invalidSWHID, searchInputElt); + doSearch(swhidInput, searchInputElt); cy.get(searchInputElt) .then($el => $el[0].checkValidity()).should('be.false'); cy.get(searchInputElt) .invoke('prop', 'validationMessage') - .should('not.equal', ''); - + .should('not.equal', '') + .should('contain', validationMessagePattern); } it('should report invalid SWHID in search page input', function() { - checkInvalidSWHIDReport(this.Urls.browse_search(), '#swh-origins-url-patterns', this.unarchivedRepo); + const swhidInput = + `swh:1:cnt:${this.unarchivedRepo.content[0].sha1git};lines=45-60/`; + checkInvalidSWHIDReport(this.Urls.browse_search(), '#swh-origins-url-patterns', swhidInput); cy.get('.invalid-feedback') .should('be.visible'); }); it('should report invalid SWHID in top right search input', function() { - checkInvalidSWHIDReport(this.Urls.browse_help(), '#swh-origins-search-top-input', this.unarchivedRepo); + const swhidInput = + `swh:1:cnt:${this.unarchivedRepo.content[0].sha1git};lines=45-60/`; + checkInvalidSWHIDReport(this.Urls.browse_help(), '#swh-origins-search-top-input', swhidInput); + }); + + it('should report SWHID with uppercase chars in search page input', function() { + const swhidInput = + `swh:1:cnt:${this.unarchivedRepo.content[0].sha1git}`.toUpperCase(); + checkInvalidSWHIDReport(this.Urls.browse_search(), '#swh-origins-url-patterns', swhidInput, swhidInput.toLowerCase()); + cy.get('.invalid-feedback') + .should('be.visible'); + }); + + it('should report SWHID with uppercase chars in top right search input', function() { + let swhidInput = + `swh:1:cnt:${this.unarchivedRepo.content[0].sha1git}`.toUpperCase(); + swhidInput += ';lines=45-60/'; + checkInvalidSWHIDReport(this.Urls.browse_help(), '#swh-origins-search-top-input', swhidInput.toLowerCase()); }); + }); });