From 678eac24ece4fc393ae4b135d0f2f41b41c98aef Mon Sep 17 00:00:00 2001 From: George Petrakis Date: Thu, 28 Nov 2024 13:11:21 +0200 Subject: [PATCH] [Fixes ISSUE 259] Loading of dataset fails if domain contains geoserver (#301) * formating URLs from GeoServer * adding a test for url_from_geoserver * update test * fixing tests * update tests * update tests * update tests --- src/qgis_geonode/apiclient/geonode_api_v2.py | 14 +++--- src/qgis_geonode/utils.py | 14 ++++++ test/test_apiclient_geonode_api_v2.py | 48 ++++++++++++++++++-- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/qgis_geonode/apiclient/geonode_api_v2.py b/src/qgis_geonode/apiclient/geonode_api_v2.py index d1cc8e6..bbce3f0 100644 --- a/src/qgis_geonode/apiclient/geonode_api_v2.py +++ b/src/qgis_geonode/apiclient/geonode_api_v2.py @@ -18,9 +18,7 @@ from .. import network from .. import styles as geonode_styles -from ..utils import ( - log, -) +from ..utils import log, url_from_geoserver from . import models from .base import BaseGeonodeClient @@ -209,9 +207,10 @@ def _get_service_urls( if auth_provider_name == "basic": for service_type, retrieved_url in result.items(): try: - prefix, suffix = retrieved_url.partition("geoserver")[::2] - result[service_type] = f"{self.base_url}/gs{suffix}" - log(f"result[service_type]: {self.base_url}/gs{suffix}") + result[service_type] = url_from_geoserver( + self.base_url, retrieved_url + ) + log(f"result[service_type]: {result[service_type]}") except AttributeError: pass return result @@ -352,8 +351,7 @@ def _get_sld_url(self, raw_style: typing.Dict) -> typing.Optional[str]: sld_url = raw_style.get("sld_url") if auth_provider_name == "basic": try: - prefix, suffix = sld_url.partition("geoserver")[::2] - sld_url = f"{self.base_url}/gs{suffix}" + sld_url = url_from_geoserver(self.base_url, sld_url) log(f"sld_url: {sld_url}") except AttributeError: pass diff --git a/src/qgis_geonode/utils.py b/src/qgis_geonode/utils.py index 2298e62..302780e 100644 --- a/src/qgis_geonode/utils.py +++ b/src/qgis_geonode/utils.py @@ -1,4 +1,5 @@ import typing +from urllib.parse import urlparse import qgis.gui from PyQt5 import QtCore, QtWidgets @@ -48,3 +49,16 @@ def remove_comments_from_sld(element): if child.isElement(): remove_comments_from_sld(child) child = child.nextSibling() + + +def url_from_geoserver(base_url: str, raw_url: str): + + # Clean the URL path from trailing and back slashes + url_path = urlparse(raw_url).path.strip("/") + + url_path = url_path.split("/") + # re-join URL path without the geoserver path + suffix = "/".join(url_path[1:]) + result = f"{base_url}/gs/{suffix}" + + return result diff --git a/test/test_apiclient_geonode_api_v2.py b/test/test_apiclient_geonode_api_v2.py index d47ba38..2618f1a 100644 --- a/test/test_apiclient_geonode_api_v2.py +++ b/test/test_apiclient_geonode_api_v2.py @@ -12,6 +12,7 @@ geonode_api_v2, models, ) +from qgis_geonode.utils import url_from_geoserver @pytest.mark.parametrize( @@ -260,6 +261,49 @@ def test_apiclient_build_search_filters( assert result.toString() == expected +@pytest.mark.parametrize( + "base_url, geoserver_url, expected", + [ + pytest.param( + "http://fake.com", + "http://fake.com/geoserver/ows/", + "http://fake.com/gs/ows", + ), + pytest.param( + "http://fake.com", "http://fake.com/gs/ows/", "http://fake.com/gs/ows" + ), + pytest.param( + "http://fake.geoserver.com", + "http://fake.geoserver.com/geoserver/ows/", + "http://fake.geoserver.com/gs/ows", + ), + pytest.param( + "http://fake.geoserver.com", + "http://fake.geoserver.com/geoserver/ows", + "http://fake.geoserver.com/gs/ows", + ), + pytest.param( + "http://fake.geoserver.com", + "http://fake.geoserver.com/geoserver/path/to/file.sld", + "http://fake.geoserver.com/gs/path/to/file.sld", + ), + pytest.param( + "http://fake.geoserver.com", + "http://fake.geoserver.com/gs/path/to/file.sld", + "http://fake.geoserver.com/gs/path/to/file.sld", + ), + pytest.param( + "http://fake.geonode.com", + "http://fake.geonode.com/geoserver/path/to/file.sld", + "http://fake.geonode.com/gs/path/to/file.sld", + ), + ], +) +def test_url_from_geoserver(base_url, geoserver_url, expected): + result = url_from_geoserver(base_url, geoserver_url) + assert result == expected + + def test_get_common_model_properties_client(): dataset_uuid = "c22e838f-9503-484e-8769-b5b09a2b6104" raw_dataset = { @@ -324,9 +368,7 @@ def test_get_common_model_properties_client(): name="fake-style-name", sld_url="fake-sld-url" ), } - client = geonode_api_v2.GeoNodeApiClient( - "fake-base-url", 10, WfsVersion.V_1_1_0, 0 - ) + client = geonode_api_v2.GeoNodeApiClient("fake-base-url", 10, WfsVersion.V_1_1_0, 0) result = client._get_common_model_properties(raw_dataset) for k, v in expected.items(): assert result[k] == v