diff options
Diffstat (limited to 'ishtar_common/tests.py')
| -rw-r--r-- | ishtar_common/tests.py | 481 | 
1 files changed, 480 insertions, 1 deletions
| diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index a7cc8361c..71bf38f28 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -39,7 +39,15 @@ from django.apps import apps  from django.conf import settings  from django.contrib.auth.models import User, Permission  from django.contrib.contenttypes.models import ContentType -from django.contrib.gis.geos import GEOSGeometry +from django.contrib.gis.geos import ( +    GEOSGeometry,  +    Point, +    MultiPoint, +    LineString, +    MultiLineString, +    Polygon, +    MultiPolygon +)  from django.core.cache import cache  from django.core.exceptions import ValidationError  from django.core.files import File as DjangoFile @@ -84,6 +92,7 @@ from ishtar_common.utils import (      move_dict_data,      rename_and_simplify_media_name,      try_fix_file, +    reverse_coordinates,  )  from ishtar_common.tasks import launch_export  from ishtar_common import utils_secretary @@ -2833,6 +2842,476 @@ class IshtarBasicTest(TestCase):          self.assertEqual(town.cached_label, "Sin City - 99 (2050)") +class GeoVectorTest(TestCase): +    fixtures = FILE_FIXTURES + +    def setUp(self): +        Operation = apps.get_model("archaeological_operations", "Operation") +        self.username, self.password, self.user = create_superuser() +        self.ct = ContentType.objects.get_for_model(models.GeoVectorData) +        operation_type = models.OperationType.objects.get(txt_idx="arch_diagnostic") +        dct = { +            "year": 2010, +            "operation_type_id": operation_type.pk, +            "history_modifier": self.user, +            "code_patriarche": 99999 +        } +        self.operation = Operation.objects.create(**dct) + +        self.origin = models.GeoOriginType.objects.get( +            txt_idx="georeferencement", +        ) +        self.data_type = models.GeoDataType.objects.get( +            txt_idx="operation-center", +        ) +        self.provider = models.GeoProviderType.objects.get( +            txt_idx="france-ign", +        ) +        self.srs, _ = models.SpatialReferenceSystem.objects.get_or_create( +            label="EPSG-27572", +            txt_idx="epsg-27572", +            srid=2154 +        ) +        self.app_source = "archaeological_operations" +        self.model_source = "operation" +        self.source_pk = self.operation.pk + +    def _test_get_create_geo(self, c, geom_type): +        response = c.get(reverse( +            "create-geo", +            kwargs={ +                "app_source": self.app_source, +                "model_source": self.model_source, +                "source_pk": self.source_pk, +                "geom_type": geom_type +            } +        )) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self.assertIn("id_name", content) +        self.assertIn("id_origin", content) +        self.assertIn("id_data_type", content) +        self.assertIn("id_provider", content) +        self.assertIn("id_comment", content) +        return content + +    def _test_fields_geo_coordinates(self, edited_geo): +        self.assertEqual(edited_geo.x, 1.3) +        self.assertEqual(edited_geo.y, 3.4) +        self.assertEqual(edited_geo.z, 4.4) +        self.assertEqual(edited_geo.estimated_error_x, 0.1) +        self.assertEqual(edited_geo.estimated_error_y, 0.1) +        self.assertEqual(edited_geo.estimated_error_z, 0.1) +        self.assertEqual( +            edited_geo.spatial_reference_system, +            self.srs +        ) + +    def _test_post_geo(self, c, geom_type, data, geo_vector=None): +        if geo_vector: +            response = c.post(reverse( +                "edit-geo", +                kwargs={ +                    "pk": geo_vector.pk, +                } +            ), data) +        else: +            response = c.post(reverse( +                "create-geo", +                kwargs={ +                    "app_source": self.app_source, +                    "model_source": self.model_source, +                    "source_pk": self.source_pk, +                    "geom_type": geom_type +                } +            ), data) +        edited_geo = models.GeoVectorData.objects.get( +            name="Test Geo {}".format(geom_type) +        ) +        self.assertRedirects(response, "/geo/edit/{}/".format(edited_geo.pk)) +        self.assertEqual(edited_geo.name, "Test Geo {}".format(geom_type)) +        self.assertEqual(edited_geo.origin, self.origin) +        self.assertEqual(edited_geo.data_type, self.data_type) +        self.assertEqual(edited_geo.provider, self.provider) +        self.assertEqual(edited_geo.comment, "This is a comment") +        self.assertEqual(edited_geo, self.operation.geodata.last()) +        return edited_geo + +    def _update_data_coordinates(self, data): +        data.update({ +            "x": 1.3, +            "y": 3.4, +            "z": 4.4, +            "estimated_error_x": 0.1, +            "estimated_error_y": 0.1, +            "estimated_error_z": 0.1, +            "spatial_reference_system": self.srs.pk, +        }) +        return data + +    def _init_default_data(self, geom_type): +        data = { +            f"related_items_{self.app_source}_{self.model_source}": self.operation.pk, +            "name": "Test Geo {}".format(geom_type), +            "origin": self.origin.pk, +            "data_type": self.data_type.pk, +            "provider": self.provider.pk, +            "comment": "This is a comment", +        } +        return data + +    def test_create_geo_vector(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        response = c.get(reverse( +            "create-pre-geo", +            kwargs={ +                "app_source": self.app_source, +                "model_source": self.model_source, +                "source_pk": self.source_pk, +            } +        )) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self.assertIn("coordinates", content) +        self.assertIn("point_2d", content) +        self.assertIn("point_3d", content) +        self.assertIn("multi_points", content) +        self.assertIn("multi_line", content) +        self.assertIn("multi_polygon", content) + +    def test_create_geo_vector_coordinates(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "coordinates" + +        content = self._test_get_create_geo(c, geom_type) +        self.assertIn("id_x", content) +        self.assertIn("id_y", content) +        self.assertIn("id_z", content) +        self.assertIn("id_estimated_error_x", content) +        self.assertIn("id_estimated_error_y", content) +        self.assertIn("id_estimated_error_z", content) +        self.assertIn("id_spatial_reference_system", content) +        self._test_post_create_pre_geo(c, geom_type) + +        data = self._init_default_data(geom_type) +        data = self._update_data_coordinates(data) +        edited_geo = self._test_post_geo(c, geom_type, data) +        self._test_fields_geo_coordinates(edited_geo) + +    def test_create_geo_vector_point2d(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "point_2d" +        point_2d = Point(3.8, 3, srid=4326) + +        content = self._test_get_create_geo(c, geom_type) + +        self.assertIn("id_point_2d", content) +        self._test_post_create_pre_geo(c, geom_type) +        data = self._init_default_data(geom_type) +        data.update({geom_type: reverse_coordinates(point_2d.ewkt)}) +        edited_geo = self._test_post_geo(c, geom_type, data) +        self.assertEqual(edited_geo.point_2d.coords, point_2d.coords) +        self.assertEqual(edited_geo.point_2d.srid, point_2d.srid) + +    def test_create_geo_vector_point3d(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "point_3d" +        point = Point(3.8, 3, 10, srid=4326) + +        content = self._test_get_create_geo(c, geom_type) +        self.assertIn("id_point_3d", content) +        self.assertIn("id_z", content) +        self._test_post_create_pre_geo(c, geom_type) +        data = self._init_default_data(geom_type) +        data.update({ +            "point_3d": reverse_coordinates(point.ewkt), +            "z": 10 +        }) +        edited_geo = self._test_post_geo(c, geom_type, data) +        self.assertEqual(edited_geo.point_3d.coords, point.coords) +        self.assertEqual(edited_geo.point_3d.srid, point.srid) +        self.assertEqual(edited_geo.z, 10) + +    def test_create_geo_vector_multipoints(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "multi_points" +        points = MultiPoint(Point(3.8, 3), Point(7.8, 5), srid=4326) + +        content = self._test_get_create_geo(c, geom_type) + +        self.assertIn("id_multi_points", content) +        self._test_post_create_pre_geo(c, geom_type) +        data = self._init_default_data(geom_type) +        data.update({geom_type: points.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data) +        self.assertEqual( +            list(edited_geo.multi_points.coords),  +            [tuple(reversed(t)) for t in points.coords] +        ) +        self.assertEqual(edited_geo.multi_points.srid, 4326) + +    def test_create_geo_vector_multilines(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        lines = MultiLineString( +            LineString(Point(1, 1), Point(2, 2)), +            LineString(Point(3, 3), Point(4, 4)), +            srid=4326 +        ) +        geom_type = "multi_line" + +        content = self._test_get_create_geo(c, geom_type) + +        self.assertIn("id_multi_line", content) +        self._test_post_create_pre_geo(c, geom_type) +        data = self._init_default_data(geom_type) +        data.update({geom_type: lines.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data) +        self.assertEqual( +            list(edited_geo.multi_line.coords),  +            [tuple(t[::-1] for t in tu) for tu in lines.coords] +        ) +        self.assertEqual(edited_geo.multi_line.srid, 4326) + +    def test_create_geo_vector_multipolygon(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        multi_polygon = MultiPolygon( +            Polygon(((1, 1), (5, 1), (5, 5), (1, 1))), +            Polygon(((2, 2), (2, 3), (3, 3), (2, 2))), +            srid=4326 +        ) +        geom_type = "multi_polygon" + +        content = self._test_get_create_geo(c, geom_type) +        self.assertIn("id_multi_polygon", content) +        self._test_post_create_pre_geo(c, geom_type) +        data = self._init_default_data(geom_type) +        data.update({geom_type: multi_polygon.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data) +        self.assertEqual( +            list(edited_geo.multi_polygon.coords), +            [tuple(tuple(t[::-1] for t in tu) for tu in tup) for tup in multi_polygon.coords] +        ) +        self.assertEqual(edited_geo.multi_polygon.srid, 4326) + +    def test_edit_geo_vector_coordinates(self): +        c = Client() +        c.login(username=self.username, password=self.password) + +        geom_type = "coordinates" +        geo_vector = self._create_geo(geom_type) +        geo_vector.x = 10.3 +        geo_vector.y = 32.4 +        geo_vector.z = 44.4 +        geo_vector.estimated_error_x = geo_vector.estimated_error_y = geo_vector.estimated_error_z = 2.43 +        geo_vector.spatial_reference_system = self.srs +        geo_vector.save() + +        response = c.get(reverse("edit-geo", kwargs={"pk": geo_vector.pk})) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self._test_get_edit_geo(geo_vector, content) +        self.assertIn(self.srs.label, content) +        data = self._init_default_data(geom_type) +        data = self._update_data_coordinates(data) +        edited_geo = self._test_post_geo(c, geom_type, data, geo_vector) +        self._test_fields_geo_coordinates(edited_geo) + +    def test_edit_geo_vector_point2d(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "point_2d" +        point_2d = Point(3.9, 3, srid=4326) +        point_2d_for_edit = Point(6, 9.2, srid=4326) +        geo_vector = self._create_geo(geom_type) +        geo_vector.point_2d = point_2d +        geo_vector.save() + +        response = c.get(reverse("edit-geo", kwargs={"pk": geo_vector.pk})) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self._test_get_edit_geo(geo_vector, content) +        data = self._init_default_data(geom_type) +        data.update({geom_type: point_2d_for_edit.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data, geo_vector) +        # Old version of django reverse coordinates +        self.assertEqual(edited_geo.point_2d.coords, point_2d_for_edit.coords[::-1]) +        self.assertEqual(edited_geo.point_2d.srid, point_2d_for_edit.srid) + +    def test_edit_geo_vector_point3d(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "point_3d" +        point_3d = Point(3.9, 3, -40, srid=4326) +        point_for_edit = Point(6, 9.2, 20, srid=4326) +        geo_vector = self._create_geo(geom_type) +        geo_vector.point_3d = point_3d +        geo_vector.z = -40 +        geo_vector.save() + +        response = c.get(reverse("edit-geo", kwargs={"pk": geo_vector.pk})) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self._test_get_edit_geo(geo_vector, content) +        data = self._init_default_data(geom_type) +        data.update({"z": 20}) +        data.update({geom_type: reverse_coordinates(point_for_edit.ewkt)}) +        edited_geo = self._test_post_geo(c, geom_type, data, geo_vector) +        # Old version of django reverse coordinates +        self.assertEqual(edited_geo.point_3d.coords, point_for_edit.coords) +        self.assertEqual(edited_geo.point_3d.srid, point_for_edit.srid) +        self.assertEqual(edited_geo.z, 20) + +    def test_edit_geo_vector_multipoints(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "multi_points" +        points = MultiPoint(Point(34.9, 20.2), Point(64.2, 58.21), srid=4326) +        points_edit = MultiPoint(Point(3.8, 3), Point(7.8, 5), srid=4326) +        geo_vector = self._create_geo(geom_type) +        geo_vector.multi_points = points +        geo_vector.save() + +        response = c.get(reverse("edit-geo", kwargs={"pk": geo_vector.pk})) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self._test_get_edit_geo(geo_vector, content) +        data = self._init_default_data(geom_type) +        data.update({geom_type: points_edit.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data, geo_vector) +        # Old version of django reverse coordinates +        self.assertEqual( +            list(edited_geo.multi_points.coords),  +            [tuple(reversed(t)) for t in points_edit.coords] +        ) +        self.assertEqual(edited_geo.multi_points.srid, 4326) + +    def test_edit_geo_vector_multilines(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "multi_line" +        lines = MultiLineString( +            LineString(Point(4, 5), Point(5, 10)), +            LineString(Point(10, 49), Point(40, 1)), +            srid=4326 +        ) +        lines_edit = MultiLineString( +            LineString(Point(3, 2), Point(1, 2)), +            LineString(Point(4, 5), Point(6, 7)), +            srid=4326 +        ) +        geo_vector = self._create_geo(geom_type) +        geo_vector.multi_line = lines +        geo_vector.save() + +        response = c.get(reverse("edit-geo", kwargs={"pk": geo_vector.pk})) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self._test_get_edit_geo(geo_vector, content) +        data = self._init_default_data(geom_type) +        data.update({geom_type: lines_edit.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data, geo_vector) +        # Old version of django reverse coordinates +        self.assertEqual( +            list(edited_geo.multi_line.coords),  +            [tuple(t[::-1] for t in tu) for tu in lines_edit.coords] +        ) +        self.assertEqual(edited_geo.multi_line.srid, 4326) + +    def test_edit_geo_vector_multipolygon(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        geom_type = "multi_polygon" +        multi_polygon = MultiPolygon( +            Polygon(((0, 0), (0, 1), (1, 1), (0, 0))), +            Polygon(((1, 1), (1, 2), (2, 2), (1, 1))), +            srid=4326 +        ) +        multi_polygon_edit = MultiPolygon( +            Polygon(((1, 1), (5, 1), (5, 5), (1, 1))), +            Polygon(((2, 2), (2, 3), (3, 3), (2, 2))), +            srid=4326 +        ) +        geo_vector = self._create_geo(geom_type) +        geo_vector.multi_polygon = multi_polygon +        geo_vector.save() +         +        response = c.get(reverse("edit-geo", kwargs={"pk": geo_vector.pk})) +        self.assertEqual(response.status_code, 200) +        content = response.content.decode() +        self._test_get_edit_geo(geo_vector, content) +        data = self._init_default_data(geom_type) +        data.update({geom_type: multi_polygon_edit.ewkt}) +        edited_geo = self._test_post_geo(c, geom_type, data, geo_vector) +        # Old version of django reverse coordinates +        self.assertEqual( +            list(edited_geo.multi_polygon.coords), +            [tuple(tuple(t[::-1] for t in tu) for tu in tup) for tup in multi_polygon_edit.coords] +        ) +        self.assertEqual(edited_geo.multi_polygon.srid, 4326) + +    def _test_get_edit_geo(self, geo_vector, content): +        geo_vector_dict = geo_vector.__dict__ + +        self.assertIn(self.operation.name, content) +        for field in geo_vector_dict: +            val = geo_vector_dict[field] +            if ( +                # Exclude fields not in form +                # Must be careful if GeoVectorData models is modified +                # and important boolean fields are added +                val is not None and +                type(val) is not bool and +                field.startswith(("_", "id", "cached")) == False and +                field.endswith("_id") == False +            ): +                self.assertIn(f"id_{field}", content) +                if isinstance(val, GEOSGeometry): +                    # TODO: need to know how osmwidget convert coordinates +                    self.assertIn(str(val.srid), content) +                else: +                    self.assertIn(str(val), content) + +    def _create_geo(self, geom_type): +        geo_vector = models.GeoVectorData.objects.create( +            source_content_type_id=self.source_pk, +            source_id=self.source_pk, +            name=f"Before edition geo {geom_type}", +            origin=self.origin, +            data_type=self.data_type, +            provider=self.provider, +            comment="This is a comment not edited." +        ) +        return geo_vector + +    def _test_post_create_pre_geo(self, c, geom_type): +        data_pre_geo = {"geom_type": geom_type} +        response = c.post(reverse( +            "create-pre-geo", +            kwargs={ +                "app_source": self.app_source, +                "model_source": self.model_source, +                "source_pk": self.source_pk, +            } +        ), data_pre_geo) + +        self.assertRedirects( +            response, +            "/geo/create/{}/{}/{}/{}/".format( +                self.app_source, +                self.model_source, +                self.source_pk, +                geom_type +            ) +        ) + +  class NewItems(TestCase):      fixtures = COMMON_FIXTURES | 
