helpdesk-validator icon indicating copy to clipboard operation
helpdesk-validator copied to clipboard

Validation of language support in Inspire services

Open giscad-sz opened this issue 2 months ago • 2 comments

Dear Inspire Validator team,

We are currently preparing Inspire View services for the GDI Bavaria (responsible there are the LDBV Bavaria and the State Office for the Environment). We are using the Inspire Validator to ensure Inspire compliance.

Two tests always fail, even though we believe they should be successful despite repeated checks. These are the following tests:

  1. at47-getcapabilities-layer-style-legend-url

According to the description, this tests that for each style element in the GetCapabilities document, a LegendURL element exists (exists in our case) for each supported language (we have one: ger), that there is an OnlineResource child element below it with an xlink:href attribute (there is), and that the specified URL returns an image (which, according to our tests, is the case for all legend URLs in our GetCapabilities document). You should then manually check whether the legend is in the correct language. This test always fails for us and all other Inspire View services (WMS) we've tested, but we can't figure out why. Is this because a manual test for the correct language is required? Or is there perhaps a bug in the test suite? Or why else does this test fail? Is it perhaps because we only support one language (German)? We also noticed that we only receive one GetLegendGraphic request, even though we have multiple layers with style and LegendURL elements in the GetCapabilities document.

  1. at68-language-parameter

According to the description, this tests that the default language complies with ISO 63902/B alpha 3 (in our case, ger) and that a GetCapabilities request with a language parameter set to the default language returns the same result in the title and abstract as a GetCapabilities request without a language parameter (in our case, even the entire GetCapabilities document is identical). This test also always fails, both for us and for all other Inspire View services (WMS) we've tested, but we can't figure out why. Is there a bug in the test suite? Or why else does this test fail? Is it perhaps because we only support one language (German)?

The view services in question are currently still accessible at the following test URLs: https://bayern3.test.giscad.cloud/wms/energieatlas/solaratlas and https://bayern3.test.giscad.cloud/wms/energieatlas/windatlas

I would appreciate an answer to my above questions and would be very grateful if you could clarify why these two tests consistently fail, both for us and for other Inspire View services we have tested.

I am happy to answer any questions you may have.

Best regards,

Stefan Zaunseder

giscad-sz avatar Oct 24 '25 07:10 giscad-sz

Dear Inspire Validator Team,

Can we interpret the classification as a validator issue to mean that this needs to be addressed on the validator's side?

I would appreciate some information on this matter, as we need to inform our clients, SDI Bavaria with the State Office for Surveying and the State Office for the Environment as the responsible authorities.

Thank you in advance!

Kind regards,

Stefan Zaunseder

giscad-sz avatar Nov 19 '25 08:11 giscad-sz

Dear @giscad-sz,

errors related to tests at47 and at68 have been resolved by the latest hotfix release (see related issue). It's strange that they're still present in your services, unless the errors are real. We will have a look and provide feedback.

fabiovinci avatar Nov 19 '25 09:11 fabiovinci

Hello,

We're experiencing the same issue with the at68-language-parameter test. After some debugging, I found what might be causing it - looks like a Content-Type header case sensitivity problem.

What's happening:

The test fails with TR.notXMLResponse at line 25 in the check-default-language step. The code checks for Content-Type like this:

for (i in ts.testRequest.response.responseHeaders.get('Content-Type')){
    if (i.contains('xml')){
        validContentType = true;
    }
}

The issue:

Our service returns the header in lowercase: content-type: text/xml instead of Content-Type: text/xml.

HTTP headers should be case-insensitive according to RFC 9110, but it seems like SoapUI's responseHeaders.get('Content-Type') might be doing a case-sensitive lookup. When I test the endpoint directly with curl, it returns valid XML with content-type: text/xml, but the test script doesn't find it.

Also found a similar issue in at47 test:

The at47-getcapabilities-layer-style-legend-url test also fails, but for a different reason. It throws NullPointerException: Cannot invoke method getAt() on null object at line 25.

The problem is in this part of the script:

for (x in capabilities.Capability.ExtendedCapabilities.SupportedLanguages.SupportedLanguage){
    supportedLanguages << x.Language;
}

When a service only supports one language (like ours with hrv), GeoServer correctly generates XML without SupportedLanguage elements - only DefaultLanguage. According to INSPIRE spec, SupportedLanguage elements are optional if only one language is supported. But the test script tries to iterate through SupportedLanguage without checking if it exists first, causing the NullPointerException.

There's also a Content-Type header issue in the same test at line 2311:

if(tsGetLegend.testRequest.response.responseHeaders.get('Content-Type')[0] != style.LegendURL.Format.toString()){

Same problem - our server returns content-type in lowercase.

Our setup:

  • WMS 1.3.0
  • Default language: hrv (ISO 639-2/B alpha 3)
  • Internationalization is configured (Title and Abstract in Croatian)
  • GetCapabilities with LANGUAGE=hrv returns the same XML as without the parameter
  • Only one language supported (no SupportedLanguage elements in XML)

Possible fixes:

For at68, maybe the test should do a case-insensitive lookup or check all headers. Something like:

def validContentType = false;
def headers = ts.testRequest.response.responseHeaders;
for (headerName in headers.keySet()) {
    if (headerName.toLowerCase() == 'content-type') {
        for (i in headers.get(headerName)) {
            if (i.contains('xml')) {
                validContentType = true;
            }
        }
    }
}

For at47, the script should check if SupportedLanguage exists before iterating:

if(capabilities.Capability.ExtendedCapabilities.SupportedLanguages.SupportedLanguage != null){
    for (x in capabilities.Capability.ExtendedCapabilities.SupportedLanguages.SupportedLanguage){
        supportedLanguages << x.Language;
    }
}

Or maybe just check if the response body is valid XML instead of relying on headers.

Test URLs:

  • at68: https://geoportal.dgu.hr/services/inspire/orthophoto_2023_2024/wms?SERVICE=WMS&REQUEST=GetCapabilities&LANGUAGE=hrv
  • at47: https://geoportal.dgu.hr/services/inspire/orthophoto_2023_2024/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0

Thanks!

mpleic avatar Dec 06 '25 23:12 mpleic