From 7d787a32bd3ce3798710781f69a317952927bd0f Mon Sep 17 00:00:00 2001 From: Chatewgne Date: Fri, 19 Jan 2024 17:26:42 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20Add=20GeotrekSiteParser=20?= =?UTF-8?q?and=20tests=20(refs=20#3569)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- geotrek/outdoor/parsers.py | 53 ++ .../geotrek_parser_v2/informationdesk.json | 42 ++ .../informationdesk_type.json | 15 + .../tests/data/geotrek_parser_v2/label.json | 20 + .../data/geotrek_parser_v2/organism.json | 11 + .../geotrek_parser_v2/outdoor_course.json | 406 +++++++++++ .../geotrek_parser_v2/outdoor_course_ids.json | 22 + .../geotrek_parser_v2/outdoor_coursetype.json | 15 + .../geotrek_parser_v2/outdoor_practice.json | 16 + .../geotrek_parser_v2/outdoor_rating.json | 49 ++ .../outdoor_ratingscale.json | 55 ++ .../geotrek_parser_v2/outdoor_sector.json | 21 + .../data/geotrek_parser_v2/outdoor_site.json | 669 ++++++++++++++++++ .../geotrek_parser_v2/outdoor_site_ids.json | 25 + .../geotrek_parser_v2/outdoor_sitetype.json | 15 + .../tests/data/geotrek_parser_v2/portal.json | 24 + .../tests/data/geotrek_parser_v2/source.json | 13 + .../data/geotrek_parser_v2/structure.json | 11 + .../tests/data/geotrek_parser_v2/theme.json | 15 + .../geotrek_parser_v2/weblink_category.json | 15 + geotrek/outdoor/tests/test_parsers.py | 562 +++++++++++++++ 21 files changed, 2074 insertions(+) create mode 100644 geotrek/outdoor/parsers.py create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk_type.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/label.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/organism.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course_ids.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_coursetype.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_practice.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_rating.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_ratingscale.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sector.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site_ids.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sitetype.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/portal.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/source.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/structure.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/theme.json create mode 100644 geotrek/outdoor/tests/data/geotrek_parser_v2/weblink_category.json create mode 100644 geotrek/outdoor/tests/test_parsers.py diff --git a/geotrek/outdoor/parsers.py b/geotrek/outdoor/parsers.py new file mode 100644 index 0000000000..2e3ae5bbd2 --- /dev/null +++ b/geotrek/outdoor/parsers.py @@ -0,0 +1,53 @@ +from geotrek.common.parsers import (ApidaeBaseParser, AttachmentParserMixin, GeotrekParser, GlobalImportError, Parser) +from geotrek.outdoor.models import Site + + +class GeotrekSiteParser(GeotrekParser): + """Geotrek parser for Outoor Site""" + fill_empty_translated_fields = True + url = None + model = Site + replace_fields = { + "eid": "uuid", + "geom": "geometry" + } + url_categories = { + "practice": "outdoor_practice", + "ratings": "outdoor_rating", + "themes": "theme", + "type": "outdoor_sitetype", + 'labels': 'label', + 'source': 'source', + 'managers': 'organism', + 'structure': 'structure', + } + categories_keys_api_v2 = { + "practice": "name", + "ratings": "name", + "themes": "label", + "type": "name", + 'labels': 'name', + 'source': 'name', + 'managers': 'name', + 'structure': 'name', + } + natural_keys = { + "practice": "name", + "ratings": "name", + "themes": "label", + "type": "name", + 'labels': 'name', + 'source': 'name', + 'managers': 'organism', + 'structure': 'name', + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.next_url = f"{self.url}/api/v2/outdoor_site" + print("AFTER INIT 9999999999999999999999999999999999999999999999999999999") + + def end(self): + """Add children after all treks imported are created in database.""" + #super().end() + print("MAKE LINK BETWEEN SITES") diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk.json new file mode 100644 index 0000000000..86582b5a2c --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk.json @@ -0,0 +1,42 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "accessibility": { + "en": "", + "fr": "" + }, + "description": { + "en": "", + "fr": "" + }, + "email": null, + "label_accessibility": null, + "latitude": null, + "longitude": null, + "municipality": null, + "name": { + "en": "Test en", + "fr": "Test fr" + }, + "phone": null, + "photo_url": "", + "uuid": "f2ace594-2444-48ba-a316-5ead2fc29011", + "postal_code": null, + "provider": "", + "street": null, + "type": { + "id": 1, + "label": { + "en": "Test type", + "fr": "Test type fr" + }, + "pictogram": "http://geotrek.local:8000/media/upload/vtt_d66RAwr.svg" + }, + "website": null + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk_type.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk_type.json new file mode 100644 index 0000000000..067e1d33f5 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/informationdesk_type.json @@ -0,0 +1,15 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "label": { + "en": "Test type", + "fr": "Test type fr" + }, + "pictogram": "http://geotrek.local:8000/media/upload/vtt_d66RAwr.svg" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/label.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/label.json new file mode 100644 index 0000000000..e94e23bf13 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/label.json @@ -0,0 +1,20 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 4, + "advice": { + "en": "Reco en", + "fr": "Reco fr" + }, + "filter": true, + "name": { + "en": "Label en", + "fr": "Label fr" + }, + "pictogram": null + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/organism.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/organism.json new file mode 100644 index 0000000000..dd75283d50 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/organism.json @@ -0,0 +1,11 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "Organisme" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course.json new file mode 100644 index 0000000000..e55fe63ebe --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course.json @@ -0,0 +1,406 @@ +{ + "count": 5, + "next": null, + "previous": null, + "results": [ + { + "id": 5, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "attachments": [], + "children": [], + "children_uuids": [], + "cities": [], + "description": { + "en": "", + "fr": "" + }, + "districts": [], + "duration": null, + "eid": null, + "equipment": { + "en": "", + "fr": "" + }, + "gear": { + "en": "", + "fr": "" + }, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + 6.8225098, + 44.9492493 + ] + } + ] + }, + "height": null, + "length": 0.0, + "max_elevation": 0, + "min_elevation": 0, + "name": { + "en": "Unrelated", + "fr": "" + }, + "parents": [ + 4, + 1 + ], + "parents_uuids": [ + "0dce3b07-4e50-42f1-9af9-2d3ea0bcdbbc", + "840f4cf7-dbe0-4aa1-835f-c1219c45dd7a" + ], + "pdf": { + "en": "http://geotrek.local:8000/api/en/courses/5/unrelated.pdf", + "fr": "http://geotrek.local:8000/api/fr/courses/5/unrelated.pdf" + }, + "points_reference": null, + "published": { + "en": true, + "fr": true + }, + "provider": "", + "ratings": [], + "ratings_description": { + "en": "", + "fr": "" + }, + "sites": [ + 3 + ], + "sites_uuids": [ + "67ca9363-2f5c-4a15-b124-46674a54f08d" + ], + "structure": 1, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_course/5/", + "uuid": "43ce926d-9236-4a62-ac7f-799d1c024b5a" + }, + { + "id": 4, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "attachments": [], + "children": [ + 5 + ], + "children_uuids": [ + "43ce926d-9236-4a62-ac7f-799d1c024b5a" + ], + "cities": [], + "description": { + "en": "", + "fr": "" + }, + "districts": [], + "duration": null, + "eid": null, + "equipment": { + "en": "", + "fr": "" + }, + "gear": { + "en": "", + "fr": "" + }, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + 7.3150635, + 44.0105955 + ] + } + ] + }, + "height": null, + "length": 0.0, + "max_elevation": 0, + "min_elevation": 0, + "name": { + "en": "Leaf 1 bis", + "fr": "Feuille 1 bis" + }, + "parents": [], + "parents_uuids": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/courses/4/feuille-1-bis.pdf", + "fr": "http://geotrek.local:8000/api/fr/courses/4/feuille-1-bis.pdf" + }, + "points_reference": null, + "published": { + "en": true, + "fr": true + }, + "provider": "", + "ratings": [], + "ratings_description": { + "en": "", + "fr": "" + }, + "sites": [ + 3 + ], + "sites_uuids": [ + "67ca9363-2f5c-4a15-b124-46674a54f08d" + ], + "structure": 1, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_course/4/", + "uuid": "0dce3b07-4e50-42f1-9af9-2d3ea0bcdbbc" + }, + { + "id": 1, + "accessibility": { + "en": "Test access en", + "fr": "Test access fr" + }, + "advice": { + "en": "Test reco en", + "fr": "Test reco fr" + }, + "attachments": [], + "children": [ + 5 + ], + "children_uuids": [ + "43ce926d-9236-4a62-ac7f-799d1c024b5a" + ], + "cities": [], + "description": { + "en": "Test descr en", + "fr": "Test descr fr" + }, + "districts": [], + "duration": 100.0, + "eid": null, + "equipment": { + "en": "Test équipement en", + "fr": "Test équipement fr" + }, + "gear": { + "en": "Test matériel en", + "fr": "Test matériel fr" + }, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + 6.6888428, + 44.1634893 + ] + } + ] + }, + "height": 100, + "length": 0.0, + "max_elevation": 0, + "min_elevation": 0, + "name": { + "en": "Leaf 1", + "fr": "Leaf 1" + }, + "parents": [], + "parents_uuids": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/courses/1/leaf-1.pdf", + "fr": "http://geotrek.local:8000/api/fr/courses/1/leaf-1.pdf" + }, + "points_reference": null, + "published": { + "en": true, + "fr": true + }, + "provider": "", + "ratings": [], + "ratings_description": { + "en": "Test descr en", + "fr": "Test descr fr" + }, + "sites": [ + 5 + ], + "sites_uuids": [ + "5c0d655b-2691-4c45-903c-9ce1050ff9ea" + ], + "structure": 1, + "type": 2, + "url": "http://geotrek.local:8000/api/v2/outdoor_course/1/", + "uuid": "840f4cf7-dbe0-4aa1-835f-c1219c45dd7a" + }, + { + "id": 2, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "attachments": [], + "children": [], + "children_uuids": [], + "cities": [], + "description": { + "en": "", + "fr": "" + }, + "districts": [], + "duration": null, + "eid": null, + "equipment": { + "en": "", + "fr": "" + }, + "gear": { + "en": "", + "fr": "" + }, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + 6.6238404, + 44.0481157 + ] + } + ] + }, + "height": null, + "length": 0.0, + "max_elevation": 0, + "min_elevation": 0, + "name": { + "en": "Leaf 2", + "fr": "Leaf 2" + }, + "parents": [], + "parents_uuids": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/courses/2/leaf-2.pdf", + "fr": "http://geotrek.local:8000/api/fr/courses/2/leaf-2.pdf" + }, + "points_reference": null, + "published": { + "en": true, + "fr": true + }, + "provider": "", + "ratings": [], + "ratings_description": { + "en": "", + "fr": "" + }, + "sites": [ + 5 + ], + "sites_uuids": [ + "5c0d655b-2691-4c45-903c-9ce1050ff9ea" + ], + "structure": 1, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_course/2/", + "uuid": "b43a1f53-a810-4703-aad6-3e0327610230" + }, + { + "id": 3, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "attachments": [], + "children": [], + "children_uuids": [], + "cities": [], + "description": { + "en": "", + "fr": "" + }, + "districts": [], + "duration": null, + "eid": null, + "equipment": { + "en": "", + "fr": "" + }, + "gear": { + "en": "", + "fr": "" + }, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + 6.5332032, + 43.9453724 + ] + } + ] + }, + "height": null, + "length": 0.0, + "max_elevation": 0, + "min_elevation": 0, + "name": { + "en": "Leaf 3", + "fr": "Leaf 3" + }, + "parents": [], + "parents_uuids": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/courses/3/leaf-3.pdf", + "fr": "http://geotrek.local:8000/api/fr/courses/3/leaf-3.pdf" + }, + "points_reference": null, + "published": { + "en": true, + "fr": true + }, + "provider": "", + "ratings": [], + "ratings_description": { + "en": "", + "fr": "" + }, + "sites": [ + 5 + ], + "sites_uuids": [ + "5c0d655b-2691-4c45-903c-9ce1050ff9ea" + ], + "structure": 1, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_course/3/", + "uuid": "1d6f5bd3-3559-4484-bd78-f8a091ab81a2" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course_ids.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course_ids.json new file mode 100644 index 0000000000..faeee8aa71 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_course_ids.json @@ -0,0 +1,22 @@ +{ + "count": 5, + "next": null, + "previous": null, + "results": [ + { + "uuid": "43ce926d-9236-4a62-ac7f-799d1c024b5a" + }, + { + "uuid": "0dce3b07-4e50-42f1-9af9-2d3ea0bcdbbc" + }, + { + "uuid": "840f4cf7-dbe0-4aa1-835f-c1219c45dd7a" + }, + { + "uuid": "b43a1f53-a810-4703-aad6-3e0327610230" + }, + { + "uuid": "1d6f5bd3-3559-4484-bd78-f8a091ab81a2" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_coursetype.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_coursetype.json new file mode 100644 index 0000000000..0dd85911dc --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_coursetype.json @@ -0,0 +1,15 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 2, + "name": { + "en": "Type 1", + "fr": null + }, + "practice": 1 + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_practice.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_practice.json new file mode 100644 index 0000000000..aa1d13e170 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_practice.json @@ -0,0 +1,16 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": { + "en": "Climbing", + "fr": "Escalade" + }, + "sector": 2, + "pictogram": null + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_rating.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_rating.json new file mode 100644 index 0000000000..031ef22db1 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_rating.json @@ -0,0 +1,49 @@ +{ + "count": 3, + "next": null, + "previous": null, + "results": [ + { + "id": 35, + "name": { + "en": null, + "fr": "3+" + }, + "description": { + "en": null, + "fr": null + }, + "scale": 6, + "order": 302, + "color": "#D9D9D9" + }, + { + "id": 36, + "name": { + "en": null, + "fr": "4a" + }, + "description": { + "en": null, + "fr": null + }, + "scale": 6, + "order": 411, + "color": "#D9D9D9" + }, + { + "id": 38, + "name": { + "en": null, + "fr": "4c" + }, + "description": { + "en": null, + "fr": null + }, + "scale": 6, + "order": 431, + "color": "#D9D9D9" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_ratingscale.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_ratingscale.json new file mode 100644 index 0000000000..1679e1b9d5 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_ratingscale.json @@ -0,0 +1,55 @@ +{ + "count": 6, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": { + "en": "Class", + "fr": "Classe" + }, + "practice": 2 + }, + { + "id": 2, + "name": { + "en": null, + "fr": "Caractère vertical" + }, + "practice": 6 + }, + { + "id": 3, + "name": { + "en": null, + "fr": "Caractère aquatique" + }, + "practice": 6 + }, + { + "id": 4, + "name": { + "en": null, + "fr": "Engagement / envergure" + }, + "practice": 6 + }, + { + "id": 5, + "name": { + "en": null, + "fr": "Niveau" + }, + "practice": 4 + }, + { + "id": 6, + "name": { + "en": null, + "fr": "Cotation" + }, + "practice": 1 + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sector.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sector.json new file mode 100644 index 0000000000..e0bf7c1244 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sector.json @@ -0,0 +1,21 @@ +{ + "count": 2, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": { + "en": "White water", + "fr": "Eau vive" + } + }, + { + "id": 2, + "name": { + "en": "Vertical", + "fr": "Vertical" + } + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site.json new file mode 100644 index 0000000000..7679d5c5a3 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site.json @@ -0,0 +1,669 @@ +{ + "count": 6, + "next": null, + "previous": null, + "results": [ + { + "id": 2, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "ambiance": { + "en": "", + "fr": "" + }, + "attachments": [], + "cities": [], + "children": [ + 4, + 5 + ], + "children_uuids": [ + "d4fd523b-c4e3-43a0-8a23-08005c26f77f", + "5c0d655b-2691-4c45-903c-9ce1050ff9ea" + ], + "description": { + "en": "", + "fr": "" + }, + "description_teaser": { + "en": "", + "fr": "" + }, + "districts": [], + "eid": null, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Polygon", + "coordinates": [ + [ + [ + 6.3793946, + 43.8523552 + ], + [ + 6.3793946, + 44.2235521 + ], + [ + 7.0220948, + 44.2235521 + ], + [ + 7.0220948, + 43.8523552 + ], + [ + 6.3793946, + 43.8523552 + ] + ] + ] + } + ] + }, + "information_desks": [], + "labels": [], + "managers": [], + "name": { + "en": "Node", + "fr": "Noeud 1" + }, + "orientation": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/sites/2/noeud-1.pdf", + "fr": "http://geotrek.local:8000/api/fr/sites/2/noeud-1.pdf" + }, + "period": { + "en": "", + "fr": "" + }, + "parent": 1, + "parent_uuid": "57a8fb52-213d-4dce-8224-bc997f892aae", + "portal": [], + "practice": null, + "provider": "", + "ratings": [], + "sector": null, + "source": [], + "structure": 1, + "themes": [], + "view_points": [], + "published": { + "en": true, + "fr": true + }, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_site/2/", + "uuid": "e59979d2-8d07-48c8-a958-327d07f9e0d1", + "courses": [], + "courses_uuids": [], + "web_links": [], + "wind": [] + }, + { + "id": 3, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "ambiance": { + "en": "", + "fr": "" + }, + "attachments": [], + "cities": [], + "children": [ + 6 + ], + "children_uuids": [ + "6825ca31-e6b0-421c-9b08-377c376728e7" + ], + "description": { + "en": "", + "fr": "" + }, + "description_teaser": { + "en": "", + "fr": "" + }, + "districts": [], + "eid": null, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Polygon", + "coordinates": [ + [ + [ + 7.0431519, + 43.8563163 + ], + [ + 7.0431519, + 44.2156785 + ], + [ + 7.6638794, + 44.2156785 + ], + [ + 7.6638794, + 43.8563163 + ], + [ + 7.0431519, + 43.8563163 + ] + ] + ] + } + ] + }, + "information_desks": [], + "labels": [], + "managers": [], + "name": { + "en": "Node 1 bis", + "fr": "Noeud 1 bis" + }, + "orientation": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/sites/3/noeud-1-bis.pdf", + "fr": "http://geotrek.local:8000/api/fr/sites/3/noeud-1-bis.pdf" + }, + "period": { + "en": "", + "fr": "" + }, + "parent": 1, + "parent_uuid": "57a8fb52-213d-4dce-8224-bc997f892aae", + "portal": [], + "practice": null, + "provider": "", + "ratings": [], + "sector": null, + "source": [], + "structure": 1, + "themes": [], + "view_points": [], + "published": { + "en": true, + "fr": true + }, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_site/3/", + "uuid": "67ca9363-2f5c-4a15-b124-46674a54f08d", + "courses": [ + 5, + 4 + ], + "courses_uuids": [ + "43ce926d-9236-4a62-ac7f-799d1c024b5a", + "0dce3b07-4e50-42f1-9af9-2d3ea0bcdbbc" + ], + "web_links": [], + "wind": [] + }, + { + "id": 4, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "ambiance": { + "en": "", + "fr": "" + }, + "attachments": [], + "cities": [], + "children": [], + "children_uuids": [], + "description": { + "en": "", + "fr": "" + }, + "description_teaser": { + "en": "", + "fr": "" + }, + "districts": [], + "eid": null, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Polygon", + "coordinates": [ + [ + [ + 6.7506409, + 43.8652279 + ], + [ + 6.7506409, + 44.2097726 + ], + [ + 7.0115662, + 44.2097726 + ], + [ + 7.0115662, + 43.8652279 + ], + [ + 6.7506409, + 43.8652279 + ] + ] + ] + } + ] + }, + "information_desks": [], + "labels": [], + "managers": [], + "name": { + "en": "Node 2", + "fr": "Noeud 2" + }, + "orientation": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/sites/4/noeud-2.pdf", + "fr": "http://geotrek.local:8000/api/fr/sites/4/noeud-2.pdf" + }, + "period": { + "en": "", + "fr": "" + }, + "parent": 2, + "parent_uuid": "e59979d2-8d07-48c8-a958-327d07f9e0d1", + "portal": [], + "practice": null, + "provider": "", + "ratings": [], + "sector": null, + "source": [], + "structure": 1, + "themes": [], + "view_points": [], + "published": { + "en": true, + "fr": true + }, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_site/4/", + "uuid": "d4fd523b-c4e3-43a0-8a23-08005c26f77f", + "courses": [], + "courses_uuids": [], + "web_links": [], + "wind": [] + }, + { + "id": 5, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "ambiance": { + "en": "", + "fr": "" + }, + "attachments": [], + "cities": [], + "children": [], + "children_uuids": [], + "description": { + "en": "", + "fr": "" + }, + "description_teaser": { + "en": "", + "fr": "" + }, + "districts": [], + "eid": null, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Polygon", + "coordinates": [ + [ + [ + 6.4746094, + 43.8672081 + ], + [ + 6.4746094, + 44.2097726 + ], + [ + 6.7341614, + 44.2097726 + ], + [ + 6.7341614, + 43.8672081 + ], + [ + 6.4746094, + 43.8672081 + ] + ] + ] + } + ] + }, + "information_desks": [], + "labels": [], + "managers": [], + "name": { + "en": "Node 2 bis", + "fr": "Noeud 2 bis" + }, + "orientation": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/sites/5/noeud-2-bis.pdf", + "fr": "http://geotrek.local:8000/api/fr/sites/5/noeud-2-bis.pdf" + }, + "period": { + "en": "", + "fr": "" + }, + "parent": 2, + "parent_uuid": "e59979d2-8d07-48c8-a958-327d07f9e0d1", + "portal": [], + "practice": 1, + "provider": "", + "ratings": [], + "sector": 2, + "source": [], + "structure": 1, + "themes": [], + "view_points": [], + "published": { + "en": true, + "fr": true + }, + "type": 1, + "url": "http://geotrek.local:8000/api/v2/outdoor_site/5/", + "uuid": "5c0d655b-2691-4c45-903c-9ce1050ff9ea", + "courses": [ + 1, + 2, + 3 + ], + "courses_uuids": [ + "840f4cf7-dbe0-4aa1-835f-c1219c45dd7a", + "b43a1f53-a810-4703-aad6-3e0327610230", + "1d6f5bd3-3559-4484-bd78-f8a091ab81a2" + ], + "web_links": [], + "wind": [] + }, + { + "id": 6, + "accessibility": { + "en": "", + "fr": "" + }, + "advice": { + "en": "", + "fr": "" + }, + "ambiance": { + "en": "", + "fr": "" + }, + "attachments": [], + "cities": [], + "children": [], + "children_uuids": [], + "description": { + "en": "", + "fr": "" + }, + "description_teaser": { + "en": "", + "fr": "" + }, + "districts": [], + "eid": null, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Polygon", + "coordinates": [ + [ + [ + 7.0912171, + 43.950316 + ], + [ + 7.0912171, + 44.1457542 + ], + [ + 7.2244263, + 44.1457542 + ], + [ + 7.2244263, + 43.950316 + ], + [ + 7.0912171, + 43.950316 + ] + ] + ] + } + ] + }, + "information_desks": [], + "labels": [], + "managers": [], + "name": { + "en": "Node 3", + "fr": "Noeud 3" + }, + "orientation": [], + "pdf": { + "en": "http://geotrek.local:8000/api/en/sites/6/noeud-3.pdf", + "fr": "http://geotrek.local:8000/api/fr/sites/6/noeud-3.pdf" + }, + "period": { + "en": "", + "fr": "" + }, + "parent": 3, + "parent_uuid": "67ca9363-2f5c-4a15-b124-46674a54f08d", + "portal": [], + "practice": null, + "provider": "", + "ratings": [], + "sector": null, + "source": [], + "structure": 1, + "themes": [], + "view_points": [], + "published": { + "en": true, + "fr": true + }, + "type": null, + "url": "http://geotrek.local:8000/api/v2/outdoor_site/6/", + "uuid": "6825ca31-e6b0-421c-9b08-377c376728e7", + "courses": [], + "courses_uuids": [], + "web_links": [], + "wind": [] + }, + { + "id": 1, + "accessibility": { + "en": "Test access en", + "fr": "Test access fr" + }, + "advice": { + "en": "Test reco en", + "fr": "Test reco fr" + }, + "ambiance": { + "en": "Test ambiance en", + "fr": "Test ambiance fr" + }, + "attachments": [], + "cities": [], + "children": [ + 2, + 3 + ], + "children_uuids": [ + "e59979d2-8d07-48c8-a958-327d07f9e0d1", + "67ca9363-2f5c-4a15-b124-46674a54f08d" + ], + "description": { + "en": "Test descr en", + "fr": "Test descr fr" + }, + "description_teaser": { + "en": "Test en", + "fr": "Test fr" + }, + "districts": [], + "eid": null, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Polygon", + "coordinates": [ + [ + [ + 6.3574219, + 43.8266013 + ], + [ + 6.3574219, + 44.2766713 + ], + [ + 7.7087403, + 44.2766713 + ], + [ + 7.7087403, + 43.8266013 + ], + [ + 6.3574219, + 43.8266013 + ] + ] + ] + } + ] + }, + "information_desks": [ + 1 + ], + "labels": [ + 4 + ], + "managers": [ + 1 + ], + "name": { + "en": "Root", + "fr": "Racine" + }, + "orientation": [ + "NE", + "S" + ], + "pdf": { + "en": "http://geotrek.local:8000/api/en/sites/1/racine.pdf", + "fr": "http://geotrek.local:8000/api/fr/sites/1/racine.pdf" + }, + "period": { + "en": "Test période en", + "fr": "Test périod fr" + }, + "parent": null, + "parent_uuid": null, + "portal": [ + 1 + ], + "practice": 1, + "provider": "", + "ratings": [ + 35, + 36, + 38 + ], + "sector": 2, + "source": [ + 1 + ], + "structure": 1, + "themes": [ + 1 + ], + "view_points": [], + "published": { + "en": true, + "fr": true + }, + "type": 1, + "url": "http://geotrek.local:8000/api/v2/outdoor_site/1/", + "uuid": "57a8fb52-213d-4dce-8224-bc997f892aae", + "courses": [], + "courses_uuids": [], + "web_links": [ + { + "name": { + "en": "Test example en", + "fr": "Test example fr" + }, + "url": "https://www.exemple.fr", + "category": { + "label": { + "en": "Categ lien web", + "fr": "Categ lien web fr" + }, + "id": 1, + "pictogram": "http://geotrek.local:8000/media/upload/vtt_8uGxKrH.svg" + } + } + ], + "wind": [ + "N", + "E" + ] + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site_ids.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site_ids.json new file mode 100644 index 0000000000..5702408e11 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_site_ids.json @@ -0,0 +1,25 @@ +{ + "count": 6, + "next": null, + "previous": null, + "results": [ + { + "uuid": "e59979d2-8d07-48c8-a958-327d07f9e0d1" + }, + { + "uuid": "67ca9363-2f5c-4a15-b124-46674a54f08d" + }, + { + "uuid": "d4fd523b-c4e3-43a0-8a23-08005c26f77f" + }, + { + "uuid": "5c0d655b-2691-4c45-903c-9ce1050ff9ea" + }, + { + "uuid": "6825ca31-e6b0-421c-9b08-377c376728e7" + }, + { + "uuid": "57a8fb52-213d-4dce-8224-bc997f892aae" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sitetype.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sitetype.json new file mode 100644 index 0000000000..e75f4bceb9 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/outdoor_sitetype.json @@ -0,0 +1,15 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": { + "en": "School", + "fr": "Ecole" + }, + "practice": 1 + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/portal.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/portal.json new file mode 100644 index 0000000000..9b69befc73 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/portal.json @@ -0,0 +1,24 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "description": { + "en": "", + "fr": "Test descr" + }, + "facebook_id": "114715079142587", + "facebook_image_height": 200, + "facebook_image_url": "http://geotrek.local:8000/images/logo-geotrek.png", + "facebook_image_width": 200, + "name": "Portal", + "title": { + "en": null, + "fr": "Example" + }, + "website": "http://www.example.fr" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/source.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/source.json new file mode 100644 index 0000000000..e37a45b736 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/source.json @@ -0,0 +1,13 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "Source", + "pictogram": "http://geotrek.local:8000/media/upload/vtt_zJeQyWP.svg", + "website": null + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/structure.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/structure.json new file mode 100644 index 0000000000..527a3114ff --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/structure.json @@ -0,0 +1,11 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "Test structure" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/theme.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/theme.json new file mode 100644 index 0000000000..bd6c0e4398 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/theme.json @@ -0,0 +1,15 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "label": { + "en": "Test thème en", + "fr": "Test thème fr" + }, + "pictogram": "http://geotrek.local:8000/media/upload/vtt_QpvFGYG.svg" + } + ] +} diff --git a/geotrek/outdoor/tests/data/geotrek_parser_v2/weblink_category.json b/geotrek/outdoor/tests/data/geotrek_parser_v2/weblink_category.json new file mode 100644 index 0000000000..8b115c2c62 --- /dev/null +++ b/geotrek/outdoor/tests/data/geotrek_parser_v2/weblink_category.json @@ -0,0 +1,15 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "label": { + "en": "Categ lien web", + "fr": "Categ lien web fr" + }, + "id": 1, + "pictogram": "http://geotrek.local:8000/media/upload/vtt_8uGxKrH.svg" + } + ] +} diff --git a/geotrek/outdoor/tests/test_parsers.py b/geotrek/outdoor/tests/test_parsers.py new file mode 100644 index 0000000000..53440506e9 --- /dev/null +++ b/geotrek/outdoor/tests/test_parsers.py @@ -0,0 +1,562 @@ +from datetime import date +import json +import os +from copy import copy +from io import StringIO +from unittest import mock +from unittest import skipIf +from unittest.mock import Mock +from urllib.parse import urlparse + +from django.conf import settings +from django.contrib.gis.geos import Point, LineString, MultiLineString, WKTWriter +from django.core.management import call_command +from django.core.management.base import CommandError +from django.test import TestCase, SimpleTestCase +from django.test.utils import override_settings + +from geotrek.common.utils import testdata +from geotrek.common.models import Organism, Theme, FileType, Attachment, Label +from geotrek.common.tests.mixins import GeotrekParserTestMixin +from geotrek.core.tests.factories import PathFactory +from geotrek.outdoor.models import Site +from geotrek.outdoor.parsers import GeotrekSiteParser +from geotrek.trekking.tests.factories import RouteFactory +from geotrek.trekking.models import POI, POIType, Service, Trek, DifficultyLevel, Route +from geotrek.trekking.parsers import ( + TrekParser, GeotrekPOIParser, GeotrekServiceParser, GeotrekTrekParser, ApidaeTrekParser, ApidaeTrekThemeParser, + ApidaePOIParser, _prepare_attachment_from_apidae_illustration, RowImportError +) + + + +class TestGeotrekSiteParser(GeotrekSiteParser): + url = "https://test.fr" + provider = 'geotrek1' + field_options = { + 'type': {'create': True, }, + 'ratings': {'create': True, }, + 'themes': {'create': True}, + 'practice': {'create': True}, + 'geom': {'required': True}, + 'labels': {'create': True}, + 'source': {'create': True}, + 'manager': {'create': True}, + 'structure': {'create': True} + } + + +class TestGeotrek2SiteParser(GeotrekSiteParser): + url = "https://test.fr" + + field_options = { + 'geom': {'required': True}, + } + provider = 'geotrek2' + + +# class TestGeotrekPOIParser(GeotrekPOIParser): # TODO IndoDesk ? WebLink ? +# url = "https://test.fr" + +# field_options = { +# 'type': {'create': True, }, +# 'geom': {'required': True}, +# } + + +# class TestGeotrekServiceParser(GeotrekServiceParser): +# url = "https://test.fr" + +# field_options = { +# 'type': {'create': True, }, +# 'geom': {'required': True}, +# } + + +@override_settings(MODELTRANSLATION_DEFAULT_LANGUAGE="fr") +@skipIf(settings.TREKKING_TOPOLOGY_ENABLED, 'Test without dynamic segmentation only') +class SiteGeotrekParserTests(GeotrekParserTestMixin, TestCase): + + @classmethod + def setUpTestData(cls): + cls.filetype = FileType.objects.create(type="Photographie") + + @mock.patch('requests.get') + @mock.patch('requests.head') + def test_create(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('outdoor', 'outdoor_practice.json'), + ('outdoor', 'outdoor_rating.json'), + ('outdoor', 'theme.json'), + ('outdoor', 'outdoor_sitetype.json'), + ('outdoor', 'label.json'), + ('outdoor', 'source.json'), + ('outdoor', 'organism.json'), + ('outdoor', 'structure.json'), + ('outdoor', 'outdoor_site_ids.json'), + ('outdoor', 'outdoor_site.json')] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.outdoor.tests.test_parsers.TestGeotrekSiteParser', verbosity=0) + self.assertEqual(Site.objects.count(), 6) + site = Site.objects.get(name_fr="Racine", name_en="Root") + # TODO : all the ones that are commented do not work + self.assertEqual(site.published, True) + self.assertEqual(site.published_fr, True) + self.assertEqual(site.published_en, True) + self.assertEqual(site.published_it, False) + self.assertEqual(site.published_es, False) + self.assertEqual(str(site.practice), 'Escalade') + self.assertEqual(str(site.labels.first()), 'Label fr') + #self.assertEqual(str(site.ratings.all()), 'Très facile') + #self.assertEqual(str(site.practice.sector), 'Vertical') + self.assertEqual(str(site.type), 'Ecole') + self.assertAlmostEqual(site.geom[0][0][0][0], 970023.8976707931, places=5) + self.assertAlmostEqual(site.geom[0][0][0][1], 6308806.903248067, places=5) + self.assertAlmostEqual(site.geom[0][0][1][0], 967898.282139539, places=5) + self.assertAlmostEqual(site.geom[0][0][1][1], 6358768.657410889, places=5) + self.assertEqual(str(site.labels.first()), "Label fr") + self.assertEqual(str(site.source.first()), "Source") + self.assertEqual(str(site.themes.first()), "Test thème fr") + #self.assertEqual(str(site.managers.first()), "Organisme") + self.assertEqual(str(site.structure), "Test structure") + self.assertEqual(site.description_teaser, "Test fr") + self.assertEqual(site.description_teaser_en, "Test en") + self.assertEqual(site.description, "Test descr fr") + self.assertEqual(site.description_en, "Test descr en") + self.assertEqual(site.advice, "Test reco fr") + self.assertEqual(site.accessibility, "Test access fr") + self.assertEqual(site.period, "Test périod fr") + self.assertEqual(site.orientation, ['NE', 'S']) + self.assertEqual(site.ambiance, "Test ambiance fr") + self.assertEqual(site.ambiance_en, "Test ambiance en") + #self.assertEqual(site.parent) # TODO use other to test this + self.assertEqual(site.wind, ['N', 'E']) + # self.assertEqual(site.information_desks.count(), 1) + # self.assertEqual(site.weblink.count(), 1) + # self.assertEqual(site.excluded_pois.count(), 1) + self.assertEqual(site.eid, "57a8fb52-213d-4dce-8224-bc997f892aae") + # self.assertEqual(Attachment.objects.filter(object_id=site.pk).count(), 3) + # self.assertEqual(Attachment.objects.get(object_id=site.pk, license__isnull=False).license.label, "License") + + @mock.patch('requests.get') + @mock.patch('requests.head') + def test_create_multiple_page(self, mocked_head, mocked_get): + class MockResponse: + mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_children.json')] + mock_time = 0 + total_mock_response = 1 + + def __init__(self, status_code): + self.status_code = status_code + + def json(self): + filename = os.path.join('geotrek', self.mock_json_order[self.mock_time][0], 'tests', 'data', + 'geotrek_parser_v2', self.mock_json_order[self.mock_time][1]) + with open(filename, 'r') as f: + data_json = json.load(f) + if self.mock_json_order[self.mock_time] == 'trek.json': + data_json['count'] = 10 + if self.total_mock_response == 1: + self.total_mock_response += 1 + data_json['next'] = "foo" + self.mock_time += 1 + return data_json + + @property + def content(self): + return b'' + + # Mock GET + mocked_get.return_value = MockResponse(200) + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + trek = Trek.objects.all().first() + self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs") + self.assertEqual(trek.name_it, "Foo bar") + self.assertEqual(str(trek.difficulty), 'Très facile') + self.assertEqual(str(trek.practice), 'Cheval') + self.assertAlmostEqual(trek.geom[0][0], 569946.9850365581, places=5) + self.assertAlmostEqual(trek.geom[0][1], 6190964.893167565, places=5) + self.assertEqual(trek.children.first().name, "Foo") + self.assertEqual(trek.labels.count(), 3) + self.assertEqual(trek.labels.first().name, "Chien autorisé") + self.assertEqual(Attachment.objects.filter(object_id=trek.pk).count(), 3) + self.assertEqual(Attachment.objects.get(object_id=trek.pk, license__isnull=False).license.label, "License") + + @override_settings(PAPERCLIP_MAX_BYTES_SIZE_IMAGE=1) + @mock.patch('requests.get') + @mock.patch('requests.head') + def test_create_attachment_max_size(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children.json')] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'11' + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + self.assertEqual(Attachment.objects.count(), 0) + + @mock.patch('requests.get') + @mock.patch('requests.head') + def test_update_attachment(self, mocked_head, mocked_get): + + class MockResponse: + mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children.json')] + mock_time = 0 + a = 0 + + def __init__(self, status_code): + self.status_code = status_code + + def json(self): + if len(self.mock_json_order) <= self.mock_time: + self.mock_time = 0 + filename = os.path.join('geotrek', self.mock_json_order[self.mock_time][0], 'tests', 'data', + 'geotrek_parser_v2', self.mock_json_order[self.mock_time][1]) + + self.mock_time += 1 + with open(filename, 'r') as f: + return json.load(f) + + @property + def content(self): + # We change content of attachment every time + self.a += 1 + return bytes(f'{self.a}', 'utf-8') + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value = MockResponse(200) + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + trek = Trek.objects.all().first() + self.assertEqual(Attachment.objects.filter(object_id=trek.pk).count(), 3) + self.assertEqual(Attachment.objects.first().attachment_file.read(), b'11') + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + trek.refresh_from_db() + self.assertEqual(Attachment.objects.filter(object_id=trek.pk).count(), 3) + self.assertEqual(Attachment.objects.first().attachment_file.read(), b'13') + + @mock.patch('requests.get') + @mock.patch('requests.head') + @override_settings(MODELTRANSLATION_DEFAULT_LANGUAGE="fr") + def test_create_multiple_fr(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids_2.json'), + ('trekking', 'trek_2.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids_2.json'), + ('trekking', 'trek_2_after.json'), + ('trekking', 'trek_children.json'), ] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + trek = Trek.objects.all().first() + self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs") + self.assertEqual(trek.name_en, "Loop of the pic of 3 lords") + self.assertEqual(trek.name_fr, "Boucle du Pic des Trois Seigneurs") + self.assertEqual(str(trek.difficulty), 'Très facile') + self.assertEqual(str(trek.practice), 'Cheval') + self.assertAlmostEqual(trek.geom[0][0], 569946.9850365581, places=5) + self.assertAlmostEqual(trek.geom[0][1], 6190964.893167565, places=5) + self.assertEqual(trek.children.first().name, "Foo") + self.assertEqual(trek.labels.count(), 3) + self.assertEqual(trek.labels.first().name, "Chien autorisé") + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrek2TrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 6) + trek = Trek.objects.get(name_fr="Étangs du Picot") + self.assertEqual(trek.description_teaser_fr, "Chapeau") + self.assertEqual(trek.description_teaser_it, "Cappello") + self.assertEqual(trek.description_teaser_es, "Chapeau") + self.assertEqual(trek.description_teaser_en, "Cap") + self.assertEqual(trek.description_teaser, "Chapeau") + self.assertEqual(trek.published, True) + self.assertEqual(trek.published_fr, True) + self.assertEqual(trek.published_en, False) + self.assertEqual(trek.published_it, False) + self.assertEqual(trek.published_es, False) + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrek2TrekParser', verbosity=0) + trek.refresh_from_db() + self.assertEqual(Trek.objects.count(), 6) + self.assertEqual(trek.description_teaser_fr, "Chapeau 2") + self.assertEqual(trek.description_teaser_it, "Cappello 2") + self.assertEqual(trek.description_teaser_es, "Sombrero 2") + self.assertEqual(trek.description_teaser_en, "Cap 2") + self.assertEqual(trek.description_teaser, "Chapeau 2") + self.assertEqual(trek.published, True) + self.assertEqual(trek.published_fr, True) + self.assertEqual(trek.published_en, False) + self.assertEqual(trek.published_it, False) + self.assertEqual(trek.published_es, False) + + @mock.patch('requests.get') + @mock.patch('requests.head') + @override_settings(MODELTRANSLATION_DEFAULT_LANGUAGE="en") + def test_create_multiple_en(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids_2.json'), + ('trekking', 'trek_2.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids_2.json'), + ('trekking', 'trek_2_after.json'), + ('trekking', 'trek_children.json')] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + trek = Trek.objects.get(name_fr="Boucle du Pic des Trois Seigneurs") + self.assertEqual(trek.name, "Loop of the pic of 3 lords") + self.assertEqual(trek.name_en, "Loop of the pic of 3 lords") + self.assertEqual(trek.name_fr, "Boucle du Pic des Trois Seigneurs") + self.assertEqual(str(trek.difficulty), 'Very easy') + self.assertEqual(str(trek.difficulty.difficulty_en), 'Very easy') + self.assertEqual(str(trek.practice), 'Horse') + self.assertAlmostEqual(trek.geom[0][0], 569946.9850365581, places=5) + self.assertAlmostEqual(trek.geom[0][1], 6190964.893167565, places=5) + self.assertEqual(trek.children.first().name, "Bar") + self.assertEqual(trek.labels.count(), 3) + self.assertEqual(trek.labels.first().name, "Dogs are great") + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrek2TrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 6) + trek = Trek.objects.get(name_fr="Étangs du Picot") + self.assertEqual(trek.description_teaser_fr, "Chapeau") + self.assertEqual(trek.description_teaser_it, "Cappello") + self.assertEqual(trek.description_teaser_es, "Cap") + self.assertEqual(trek.description_teaser_en, "Cap") + self.assertEqual(trek.description_teaser, "Cap") + self.assertEqual(trek.published, False) + self.assertEqual(trek.published_fr, True) + self.assertEqual(trek.published_en, False) + self.assertEqual(trek.published_it, False) + self.assertEqual(trek.published_es, False) + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrek2TrekParser', verbosity=0) + trek.refresh_from_db() + self.assertEqual(Trek.objects.count(), 6) + self.assertEqual(trek.description_teaser_fr, "Chapeau 2") + self.assertEqual(trek.description_teaser_it, "Cappello 2") + self.assertEqual(trek.description_teaser_es, "Sombrero 2") + self.assertEqual(trek.description_teaser_en, "Cap 2") + self.assertEqual(trek.description_teaser, "Cap 2") + self.assertEqual(trek.published, False) + self.assertEqual(trek.published_fr, True) + self.assertEqual(trek.published_en, False) + self.assertEqual(trek.published_it, False) + self.assertEqual(trek.published_es, False) + + @mock.patch('requests.get') + @mock.patch('requests.head') + def test_children_do_not_exist(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children_do_not_exist.json')] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + output = StringIO() + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=2, + stdout=output) + self.assertIn("One trek has not be generated for Boucle du Pic des Trois Seigneurs : could not find trek with UUID c9567576-2934-43ab-666e-e13d02c671a9,\n", output.getvalue()) + self.assertIn("Trying to retrieve children for missing trek : could not find trek with UUID b2aea666-5e6e-4daa-a750-7d2ee52d3fe1", output.getvalue()) + + @mock.patch('requests.get') + @mock.patch('requests.head') + def test_wrong_children_error(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_wrong_children.json'), ] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + output = StringIO() + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=2, + stdout=output) + self.assertIn("An error occured in children generation : KeyError('steps'", output.getvalue()) + + @mock.patch('requests.get') + @mock.patch('requests.head') + @override_settings(MODELTRANSLATION_DEFAULT_LANGUAGE="fr") + def test_updated(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids.json'), + ('trekking', 'trek.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_difficulty.json'), + ('trekking', 'trek_route.json'), + ('trekking', 'trek_theme.json'), + ('trekking', 'trek_practice.json'), + ('trekking', 'trek_accessibility.json'), + ('trekking', 'trek_network.json'), + ('trekking', 'trek_label.json'), + ('trekking', 'sources.json'), + ('trekking', 'trek_ids_2.json'), + ('trekking', 'trek_2.json'), + ('trekking', 'trek_children.json')] + + # Mock GET + mocked_get.return_value.status_code = 200 + mocked_get.return_value.json = self.mock_json + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + self.assertEqual(Trek.objects.count(), 5) + trek = Trek.objects.all().first() + self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs") + self.assertEqual(trek.name_fr, "Boucle du Pic des Trois Seigneurs") + self.assertEqual(trek.name_en, "Loop of the pic of 3 lords") + self.assertEqual(str(trek.difficulty), 'Très facile') + self.assertEqual(str(trek.practice), 'Cheval') + self.assertAlmostEqual(trek.geom[0][0], 569946.9850365581, places=5) + self.assertAlmostEqual(trek.geom[0][1], 6190964.893167565, places=5) + self.assertEqual(trek.children.first().name, "Foo") + self.assertEqual(trek.labels.count(), 3) + self.assertEqual(trek.labels.first().name, "Chien autorisé") + call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) + # Trek 2 is still in ids (trek_ids_2) => it's not removed + self.assertEqual(Trek.objects.count(), 2) + trek = Trek.objects.all().first() + self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs")