From a022e37a7646b3490ea1cf0094364e72e03af50d Mon Sep 17 00:00:00 2001 From: Mattia Date: Tue, 23 Jul 2024 18:25:35 +0200 Subject: [PATCH 1/6] [Fixes #257] Add remote 3dtiles handler --- importer/api/views.py | 2 +- importer/handlers/remote/__init__.py | 0 importer/handlers/remote/tiles3d.py | 180 +++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 importer/handlers/remote/__init__.py create mode 100644 importer/handlers/remote/tiles3d.py diff --git a/importer/api/views.py b/importer/api/views.py index 10a372fe..09720e4a 100644 --- a/importer/api/views.py +++ b/importer/api/views.py @@ -141,7 +141,7 @@ def create(self, request, *args, **kwargs): request, asset_dir, storage_manager, _data, handler ) - self.validate_upload(request, storage_manager) + self.validate_upload(request, storage_manager) action = ExecutionRequestAction.IMPORT.value diff --git a/importer/handlers/remote/__init__.py b/importer/handlers/remote/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/importer/handlers/remote/tiles3d.py b/importer/handlers/remote/tiles3d.py new file mode 100644 index 00000000..404444ff --- /dev/null +++ b/importer/handlers/remote/tiles3d.py @@ -0,0 +1,180 @@ +import json +import logging +import os +from pathlib import Path +import math + +import requests +from geonode.layers.models import Dataset +from geonode.resource.enumerator import ExecutionRequestAction as exa +from geonode.upload.utils import UploadLimitValidator +from importer.handlers.common.remote import BaseRemoteResourceHandler +from importer.handlers.tiles3d.handler import Tiles3DFileHandler +from importer.handlers.tiles3d.utils import box_to_wgs84, sphere_to_wgs84 +from importer.orchestrator import orchestrator +from importer.celery_tasks import import_orchestrator +from importer.handlers.common.vector import BaseVectorFileHandler +from importer.handlers.utils import create_alternate, should_be_imported +from importer.utils import ImporterRequestAction as ira +from geonode.base.models import ResourceBase +from importer.handlers.tiles3d.exceptions import Invalid3DTilesException + +logger = logging.getLogger(__name__) + + +class RemoteTiles3DFileHandler(BaseRemoteResourceHandler, Tiles3DFileHandler): + + @staticmethod + def can_handle(_data) -> bool: + """ + This endpoint will return True or False if with the info provided + the handler is able to handle the file or not + """ + if "url" in _data and '3dtiles' in _data.get("type"): + return True + return False + + + @staticmethod + def is_valid_url(url): + BaseRemoteResourceHandler.is_valid_url(url) + try: + payload = requests.get(url, timeout=10).json() + # required key described in the specification of 3dtiles + # https://docs.ogc.org/cs/22-025r4/22-025r4.html#toc92 + is_valid = all( + key in payload.keys() for key in ("asset", "geometricError", "root") + ) + + if not is_valid: + raise Invalid3DTilesException( + "The provided 3DTiles is not valid, some of the mandatory keys are missing. Mandatory keys are: 'asset', 'geometricError', 'root'" + ) + + # if the keys are there, let's check if the mandatory child are there too + asset = payload.get("asset", {}).get("version", None) + if not asset: + raise Invalid3DTilesException( + "The mandatory 'version' for the key 'asset' is missing" + ) + volume = payload.get("root", {}).get("boundingVolume", None) + if not volume: + raise Invalid3DTilesException( + "The mandatory 'boundingVolume' for the key 'root' is missing" + ) + + error = payload.get("root", {}).get("geometricError", None) + if error is None: + raise Invalid3DTilesException( + "The mandatory 'geometricError' for the key 'root' is missing" + ) + + except Exception as e: + raise Invalid3DTilesException(e) + + return True + + def create_geonode_resource( + self, + layer_name: str, + alternate: str, + execution_id: str, + resource_type: Dataset = ..., + asset=None, + ): + resource = super().create_geonode_resource(layer_name, alternate, execution_id, resource_type, asset) + + if self._has_region(js_file): + resource = self.set_bbox_from_region(js_file, resource=resource) + elif self._has_sphere(js_file): + resource = self.set_bbox_from_boundingVolume_sphere(js_file, resource=resource) + else: + resource = self.set_bbox_from_boundingVolume(js_file, resource=resource) + + return resource + + def generate_resource_payload(self, layer_name, alternate, asset, _exec, workspace): + return dict( + resource_type="dataset", + subtype="3dtiles", + dirty_state=True, + title=layer_name, + owner=_exec.user, + asset=asset, + link_type="uploaded", + extension="3dtiles", + alternate=alternate, + ) + + def set_bbox_from_region(self, js_file, resource): + # checking if the region is inside the json file + region = js_file.get("root", {}).get("boundingVolume", {}).get("region", None) + if not region: + logger.info( + f"No region found, the BBOX will not be updated for 3dtiles: {resource.title}" + ) + return resource + west, south, east, nord = region[:4] + # [xmin, ymin, xmax, ymax] + resource.set_bbox_polygon( + bbox=[ + math.degrees(west), + math.degrees(south), + math.degrees(east), + math.degrees(nord), + ], + srid="EPSG:4326", + ) + + return resource + + def set_bbox_from_boundingVolume(self, js_file, resource): + transform_raw = js_file.get("root", {}).get("transform", []) + box_raw = js_file.get("root", {}).get("boundingVolume", {}).get("box", None) + + if not box_raw or (not transform_raw and not box_raw): + # skipping if values are missing from the json file + return resource + + result = box_to_wgs84(box_raw, transform_raw) + # [xmin, ymin, xmax, ymax] + resource.set_bbox_polygon( + bbox=[ + result["minx"], + result["miny"], + result["maxx"], + result["maxy"], + ], + srid="EPSG:4326", + ) + + return resource + + def set_bbox_from_boundingVolume_sphere(self, js_file, resource): + transform_raw = js_file.get("root", {}).get("transform", []) + sphere_raw = js_file.get("root", {}).get("boundingVolume", {}).get("sphere", None) + + if not sphere_raw or (not transform_raw and not sphere_raw): + # skipping if values are missing from the json file + return resource + if not transform_raw and (sphere_raw[0], sphere_raw[1], sphere_raw[2]) == (0, 0, 0): + return resource + result = sphere_to_wgs84(sphere_raw, transform_raw) + # [xmin, ymin, xmax, ymax] + resource.set_bbox_polygon( + bbox=[ + result["minx"], + result["miny"], + result["maxx"], + result["maxy"], + ], + srid="EPSG:4326", + ) + + return resource + + def _has_region(self, js_file): + return js_file.get("root", {}).get("boundingVolume", {}).get("region", None) + + def _has_sphere(self, js_file): + return js_file.get("root", {}).get("boundingVolume", {}).get("sphere", None) From 25d275b2b118274f967985636b8d503ac054569b Mon Sep 17 00:00:00 2001 From: Mattia Date: Wed, 24 Jul 2024 11:56:13 +0200 Subject: [PATCH 2/6] [Fixes #257] Add remote 3dtiles handler --- docker-compose-test.yaml | 4 - importer/handlers/common/remote.py | 2 +- importer/handlers/common/vector.py | 2 +- importer/handlers/remote/test_3dtiles.py | 138 +++++++++++++++++++++++ importer/handlers/remote/tiles3d.py | 135 +++------------------- importer/handlers/tiles3d/handler.py | 38 ++++--- 6 files changed, 177 insertions(+), 142 deletions(-) create mode 100644 importer/handlers/remote/test_3dtiles.py diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index d86c2c4d..5887c1a5 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -42,8 +42,6 @@ services: retries: 5 env_file: - .env_test - ports: - - "8080:8080" volumes: - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data @@ -79,8 +77,6 @@ services: healthcheck: test: "pg_isready -d postgres -U postgres" # uncomment to enable remote connections to postgres - ports: - - "5432:5432" volumes: diff --git a/importer/handlers/common/remote.py b/importer/handlers/common/remote.py index 6a84c9e2..c546bbf5 100755 --- a/importer/handlers/common/remote.py +++ b/importer/handlers/common/remote.py @@ -177,7 +177,7 @@ def create_geonode_resource( sourcetype=SOURCE_TYPE_REMOTE, alternate=alternate, dirty_state=True, - title=layer_name, + title=params.get("title", layer_name), owner=_exec.user, ), ) diff --git a/importer/handlers/common/vector.py b/importer/handlers/common/vector.py index 144e0177..865dc487 100644 --- a/importer/handlers/common/vector.py +++ b/importer/handlers/common/vector.py @@ -222,7 +222,7 @@ def perform_last_step(execution_id): if _exec and not _exec.input_params.get("store_spatial_file", False): resources = ResourceHandlerInfo.objects.filter(execution_request=_exec) # getting all assets list - assets = [get_default_asset(x.resource) for x in resources] + assets = filter(None, [get_default_asset(x.resource) for x in resources]) # we need to loop and cancel one by one to activate the signal # that delete the file from the filesystem for asset in assets: diff --git a/importer/handlers/remote/test_3dtiles.py b/importer/handlers/remote/test_3dtiles.py new file mode 100644 index 00000000..d9391bfc --- /dev/null +++ b/importer/handlers/remote/test_3dtiles.py @@ -0,0 +1,138 @@ +from django.test import TestCase +from mock import MagicMock, patch +from importer.api.exception import ImportException +from django.contrib.auth import get_user_model +from importer.handlers.common.serializer import RemoteResourceSerializer +from importer.handlers.remote.tiles3d import RemoteTiles3DFileHandler +from importer.orchestrator import orchestrator +from geonode.base.populate_test_data import create_single_dataset +from geonode.resource.models import ExecutionRequest + + +class TestRemoteTiles3DFileHandler(TestCase): + databases = ("default", "datastore") + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.handler = RemoteTiles3DFileHandler() + cls.valid_url = "https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/1.1/TilesetWithFullMetadata/tileset.json" + cls.user, _ = get_user_model().objects.get_or_create(username="admin") + cls.invalid_files = { + "url": "http://abc123defsadsa.org", + "title": "Remote Title", + "type": "3dtiles", + } + cls.valid_files = { + "url": cls.valid_url, + "title": "Remote Title", + "type": "3dtiles", + } + cls.owner = get_user_model().objects.first() + cls.layer = create_single_dataset( + name="stazioni_metropolitana", owner=cls.owner + ) + + def test_can_handle_should_return_true_for_remote(self): + actual = self.handler.can_handle(self.valid_files) + self.assertTrue(actual) + + def test_can_handle_should_return_false_for_other_files(self): + actual = self.handler.can_handle({"base_file": "random.file"}) + self.assertFalse(actual) + + def test_should_get_the_specific_serializer(self): + actual = self.handler.has_serializer(self.valid_files) + self.assertEqual(type(actual), type(RemoteResourceSerializer)) + + def test_create_error_log(self): + """ + Should return the formatted way for the log of the handler + """ + actual = self.handler.create_error_log( + Exception("my exception"), + "foo_task_name", + *["exec_id", "layer_name", "alternate"], + ) + expected = "Task: foo_task_name raised an error during actions for layer: alternate: my exception" + self.assertEqual(expected, actual) + + def test_task_list_is_the_expected_one(self): + expected = ( + "start_import", + "importer.import_resource", + "importer.create_geonode_resource", + ) + self.assertEqual(len(self.handler.ACTIONS["import"]), 3) + self.assertTupleEqual(expected, self.handler.ACTIONS["import"]) + + def test_task_list_is_the_expected_one_geojson(self): + expected = ( + "start_copy", + "importer.copy_geonode_resource", + ) + self.assertEqual(len(self.handler.ACTIONS["copy"]), 2) + self.assertTupleEqual(expected, self.handler.ACTIONS["copy"]) + + def test_is_valid_should_raise_exception_if_the_url_is_invalid(self): + with self.assertRaises(ImportException) as _exc: + self.handler.is_valid_url(url=self.invalid_files["url"]) + + self.assertIsNotNone(_exc) + self.assertTrue("The provided url is not reachable") + + def test_is_valid_should_pass_with_valid_url(self): + self.handler.is_valid_url(url=self.valid_files["url"]) + + def test_extract_params_from_data(self): + actual, _data = self.handler.extract_params_from_data( + _data={ + "defaults": '{"url": "http://abc123defsadsa.org", "title": "Remote Title", "type": "3dtiles"}' + }, + action="import", + ) + self.assertTrue("title" in actual) + self.assertTrue("url" in actual) + self.assertTrue("type" in actual) + + @patch("importer.handlers.common.remote.import_orchestrator") + def test_import_resource_should_work(self, patch_upload): + patch_upload.apply_async.side_effect = MagicMock() + try: + exec_id = orchestrator.create_execution_request( + user=get_user_model().objects.first(), + func_name="funct1", + step="step", + input_params=self.valid_files, + ) + + # start the resource import + self.handler.import_resource( + files=self.valid_files, execution_id=str(exec_id) + ) + patch_upload.apply_async.assert_called_once() + finally: + if exec_id: + ExecutionRequest.objects.filter(exec_id=exec_id).delete() + + def test_create_geonode_resource(self): + exec_id = orchestrator.create_execution_request( + user=self.owner, + func_name="funct1", + step="step", + input_params={ + "url": "http://abc123defsadsa.org", + "title": "Remote Title", + "type": "3dtiles", + }, + ) + + resource = self.handler.create_geonode_resource( + "layername", + "layeralternate", + execution_id=exec_id, + resource_type="ResourceBase", + asset=None, + ) + self.assertIsNotNone(resource) + self.assertEqual(resource.subtype, "3dtiles") diff --git a/importer/handlers/remote/tiles3d.py b/importer/handlers/remote/tiles3d.py index 404444ff..2676c1f0 100644 --- a/importer/handlers/remote/tiles3d.py +++ b/importer/handlers/remote/tiles3d.py @@ -1,22 +1,10 @@ -import json import logging -import os -from pathlib import Path -import math import requests from geonode.layers.models import Dataset -from geonode.resource.enumerator import ExecutionRequestAction as exa -from geonode.upload.utils import UploadLimitValidator from importer.handlers.common.remote import BaseRemoteResourceHandler from importer.handlers.tiles3d.handler import Tiles3DFileHandler -from importer.handlers.tiles3d.utils import box_to_wgs84, sphere_to_wgs84 from importer.orchestrator import orchestrator -from importer.celery_tasks import import_orchestrator -from importer.handlers.common.vector import BaseVectorFileHandler -from importer.handlers.utils import create_alternate, should_be_imported -from importer.utils import ImporterRequestAction as ira -from geonode.base.models import ResourceBase from importer.handlers.tiles3d.exceptions import Invalid3DTilesException logger = logging.getLogger(__name__) @@ -30,11 +18,10 @@ def can_handle(_data) -> bool: This endpoint will return True or False if with the info provided the handler is able to handle the file or not """ - if "url" in _data and '3dtiles' in _data.get("type"): + if "url" in _data and "3dtiles" in _data.get("type"): return True return False - @staticmethod def is_valid_url(url): BaseRemoteResourceHandler.is_valid_url(url) @@ -51,23 +38,7 @@ def is_valid_url(url): "The provided 3DTiles is not valid, some of the mandatory keys are missing. Mandatory keys are: 'asset', 'geometricError', 'root'" ) - # if the keys are there, let's check if the mandatory child are there too - asset = payload.get("asset", {}).get("version", None) - if not asset: - raise Invalid3DTilesException( - "The mandatory 'version' for the key 'asset' is missing" - ) - volume = payload.get("root", {}).get("boundingVolume", None) - if not volume: - raise Invalid3DTilesException( - "The mandatory 'boundingVolume' for the key 'root' is missing" - ) - - error = payload.get("root", {}).get("geometricError", None) - if error is None: - raise Invalid3DTilesException( - "The mandatory 'geometricError' for the key 'root' is missing" - ) + Tiles3DFileHandler.validate_3dtile_payload(payload=payload) except Exception as e: raise Invalid3DTilesException(e) @@ -82,99 +53,25 @@ def create_geonode_resource( resource_type: Dataset = ..., asset=None, ): - resource = super().create_geonode_resource(layer_name, alternate, execution_id, resource_type, asset) + resource = super().create_geonode_resource( + layer_name, alternate, execution_id, resource_type, asset + ) + _exec = orchestrator.get_execution_object(exec_id=execution_id) + try: + js_file = requests.get(_exec.input_params.get("url"), timeout=10).json() + except Exception as e: + raise Invalid3DTilesException(e) + + if not js_file: + raise Invalid3DTilesException("The JSON file returned by the URL is empty") if self._has_region(js_file): resource = self.set_bbox_from_region(js_file, resource=resource) elif self._has_sphere(js_file): - resource = self.set_bbox_from_boundingVolume_sphere(js_file, resource=resource) + resource = self.set_bbox_from_boundingVolume_sphere( + js_file, resource=resource + ) else: resource = self.set_bbox_from_boundingVolume(js_file, resource=resource) return resource - - def generate_resource_payload(self, layer_name, alternate, asset, _exec, workspace): - return dict( - resource_type="dataset", - subtype="3dtiles", - dirty_state=True, - title=layer_name, - owner=_exec.user, - asset=asset, - link_type="uploaded", - extension="3dtiles", - alternate=alternate, - ) - - def set_bbox_from_region(self, js_file, resource): - # checking if the region is inside the json file - region = js_file.get("root", {}).get("boundingVolume", {}).get("region", None) - if not region: - logger.info( - f"No region found, the BBOX will not be updated for 3dtiles: {resource.title}" - ) - return resource - west, south, east, nord = region[:4] - # [xmin, ymin, xmax, ymax] - resource.set_bbox_polygon( - bbox=[ - math.degrees(west), - math.degrees(south), - math.degrees(east), - math.degrees(nord), - ], - srid="EPSG:4326", - ) - - return resource - - def set_bbox_from_boundingVolume(self, js_file, resource): - transform_raw = js_file.get("root", {}).get("transform", []) - box_raw = js_file.get("root", {}).get("boundingVolume", {}).get("box", None) - - if not box_raw or (not transform_raw and not box_raw): - # skipping if values are missing from the json file - return resource - - result = box_to_wgs84(box_raw, transform_raw) - # [xmin, ymin, xmax, ymax] - resource.set_bbox_polygon( - bbox=[ - result["minx"], - result["miny"], - result["maxx"], - result["maxy"], - ], - srid="EPSG:4326", - ) - - return resource - - def set_bbox_from_boundingVolume_sphere(self, js_file, resource): - transform_raw = js_file.get("root", {}).get("transform", []) - sphere_raw = js_file.get("root", {}).get("boundingVolume", {}).get("sphere", None) - - if not sphere_raw or (not transform_raw and not sphere_raw): - # skipping if values are missing from the json file - return resource - if not transform_raw and (sphere_raw[0], sphere_raw[1], sphere_raw[2]) == (0, 0, 0): - return resource - result = sphere_to_wgs84(sphere_raw, transform_raw) - # [xmin, ymin, xmax, ymax] - resource.set_bbox_polygon( - bbox=[ - result["minx"], - result["miny"], - result["maxx"], - result["maxy"], - ], - srid="EPSG:4326", - ) - - return resource - - def _has_region(self, js_file): - return js_file.get("root", {}).get("boundingVolume", {}).get("region", None) - - def _has_sphere(self, js_file): - return js_file.get("root", {}).get("boundingVolume", {}).get("sphere", None) diff --git a/importer/handlers/tiles3d/handler.py b/importer/handlers/tiles3d/handler.py index 1a9ff92a..7889ddd3 100755 --- a/importer/handlers/tiles3d/handler.py +++ b/importer/handlers/tiles3d/handler.py @@ -103,29 +103,33 @@ def is_valid(files, user): "The provided 3DTiles is not valid, some of the mandatory keys are missing. Mandatory keys are: 'asset', 'geometricError', 'root'" ) - # if the keys are there, let's check if the mandatory child are there too - asset = _file.get("asset", {}).get("version", None) - if not asset: - raise Invalid3DTilesException( - "The mandatory 'version' for the key 'asset' is missing" - ) - volume = _file.get("root", {}).get("boundingVolume", None) - if not volume: - raise Invalid3DTilesException( - "The mandatory 'boundingVolume' for the key 'root' is missing" - ) - - error = _file.get("root", {}).get("geometricError", None) - if error is None: - raise Invalid3DTilesException( - "The mandatory 'geometricError' for the key 'root' is missing" - ) + Tiles3DFileHandler.validate_3dtile_payload(payload=_file) except Exception as e: raise Invalid3DTilesException(e) return True + @staticmethod + def validate_3dtile_payload(payload): + # if the keys are there, let's check if the mandatory child are there too + asset = payload.get("asset", {}).get("version", None) + if not asset: + raise Invalid3DTilesException( + "The mandatory 'version' for the key 'asset' is missing" + ) + volume = payload.get("root", {}).get("boundingVolume", None) + if not volume: + raise Invalid3DTilesException( + "The mandatory 'boundingVolume' for the key 'root' is missing" + ) + + error = payload.get("root", {}).get("geometricError", None) + if error is None: + raise Invalid3DTilesException( + "The mandatory 'geometricError' for the key 'root' is missing" + ) + @staticmethod def extract_params_from_data(_data, action=None): """ From c10b23dd1e13c258f34ba0113faf52034cfbc547 Mon Sep 17 00:00:00 2001 From: Mattia Date: Wed, 24 Jul 2024 16:59:54 +0200 Subject: [PATCH 3/6] [Fixes #257] Fix test and update geoserver to latest version --- docker-compose-test.yaml | 4 ++-- importer/handlers/remote/test_3dtiles.py | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index 5887c1a5..1713cc81 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -32,7 +32,7 @@ services: # Geoserver backend geoserver: - image: geonode/geoserver:2.23.0 + image: geonode/geoserver:2.24.3-latest container_name: geoserver4importer healthcheck: test: "curl -m 10 --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null http://geoserver:8080/geoserver/ows" @@ -53,7 +53,7 @@ services: condition: service_healthy data-dir-conf: - image: geonode/geoserver_data:2.23.0 + image: geonode/geoserver_data:2.24.3-latest container_name: gsconf4importer entrypoint: sleep infinity volumes: diff --git a/importer/handlers/remote/test_3dtiles.py b/importer/handlers/remote/test_3dtiles.py index d9391bfc..9a282600 100644 --- a/importer/handlers/remote/test_3dtiles.py +++ b/importer/handlers/remote/test_3dtiles.py @@ -4,6 +4,7 @@ from django.contrib.auth import get_user_model from importer.handlers.common.serializer import RemoteResourceSerializer from importer.handlers.remote.tiles3d import RemoteTiles3DFileHandler +from importer.handlers.tiles3d.exceptions import Invalid3DTilesException from importer.orchestrator import orchestrator from geonode.base.populate_test_data import create_single_dataset from geonode.resource.models import ExecutionRequest @@ -115,13 +116,34 @@ def test_import_resource_should_work(self, patch_upload): if exec_id: ExecutionRequest.objects.filter(exec_id=exec_id).delete() + def test_create_geonode_resource_raise_error_if_url_is_not_reachabel(self): + with self.assertRaises(Invalid3DTilesException) as error: + exec_id = orchestrator.create_execution_request( + user=self.owner, + func_name="funct1", + step="step", + input_params={ + "url": "http://abc123defsadsa.org", + "title": "Remote Title", + "type": "3dtiles", + }, + ) + + resource = self.handler.create_geonode_resource( + "layername", + "layeralternate", + execution_id=exec_id, + resource_type="ResourceBase", + asset=None, + ) + def test_create_geonode_resource(self): exec_id = orchestrator.create_execution_request( user=self.owner, func_name="funct1", step="step", input_params={ - "url": "http://abc123defsadsa.org", + "url": "https://dummyjson.com/users", "title": "Remote Title", "type": "3dtiles", }, From a6667ca95a1f11068a7489ac85ad76b66c568513 Mon Sep 17 00:00:00 2001 From: Mattia Date: Thu, 25 Jul 2024 10:48:14 +0200 Subject: [PATCH 4/6] [Fixes #257] class rename --- importer/handlers/remote/test_3dtiles.py | 4 ++-- importer/handlers/remote/tiles3d.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/importer/handlers/remote/test_3dtiles.py b/importer/handlers/remote/test_3dtiles.py index 9a282600..bb5c569c 100644 --- a/importer/handlers/remote/test_3dtiles.py +++ b/importer/handlers/remote/test_3dtiles.py @@ -3,7 +3,7 @@ from importer.api.exception import ImportException from django.contrib.auth import get_user_model from importer.handlers.common.serializer import RemoteResourceSerializer -from importer.handlers.remote.tiles3d import RemoteTiles3DFileHandler +from importer.handlers.remote.tiles3d import RemoteTiles3DResourceHandler from importer.handlers.tiles3d.exceptions import Invalid3DTilesException from importer.orchestrator import orchestrator from geonode.base.populate_test_data import create_single_dataset @@ -16,7 +16,7 @@ class TestRemoteTiles3DFileHandler(TestCase): @classmethod def setUpClass(cls): super().setUpClass() - cls.handler = RemoteTiles3DFileHandler() + cls.handler = RemoteTiles3DResourceHandler() cls.valid_url = "https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/1.1/TilesetWithFullMetadata/tileset.json" cls.user, _ = get_user_model().objects.get_or_create(username="admin") cls.invalid_files = { diff --git a/importer/handlers/remote/tiles3d.py b/importer/handlers/remote/tiles3d.py index 2676c1f0..517b6910 100644 --- a/importer/handlers/remote/tiles3d.py +++ b/importer/handlers/remote/tiles3d.py @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) -class RemoteTiles3DFileHandler(BaseRemoteResourceHandler, Tiles3DFileHandler): +class RemoteTiles3DResourceHandler(BaseRemoteResourceHandler, Tiles3DFileHandler): @staticmethod def can_handle(_data) -> bool: From 205bc839bd3b16da2738f455d1cde48c21fbbee0 Mon Sep 17 00:00:00 2001 From: Mattia Date: Thu, 25 Jul 2024 10:50:20 +0200 Subject: [PATCH 5/6] [Fixes #257] Move test in folder --- importer/handlers/remote/{ => tests}/test_3dtiles.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename importer/handlers/remote/{ => tests}/test_3dtiles.py (100%) diff --git a/importer/handlers/remote/test_3dtiles.py b/importer/handlers/remote/tests/test_3dtiles.py similarity index 100% rename from importer/handlers/remote/test_3dtiles.py rename to importer/handlers/remote/tests/test_3dtiles.py From 4f5a3cc567a4d261dea285ae85d9bd6f35fae3ad Mon Sep 17 00:00:00 2001 From: Mattia Date: Thu, 25 Jul 2024 10:51:32 +0200 Subject: [PATCH 6/6] [Fixes #257] Add missing init file --- importer/handlers/remote/tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 importer/handlers/remote/tests/__init__.py diff --git a/importer/handlers/remote/tests/__init__.py b/importer/handlers/remote/tests/__init__.py new file mode 100644 index 00000000..e69de29b