diff --git a/docs/changelog.rst b/docs/changelog.rst index 05482ea765..d722ccb190 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,7 @@ CHANGELOG - ApidaeTrekParser duration import is fixed for multiple-days treks - Apidae tourism parser now handles missing contact properties - ApidaeTrekParser now handles missing source website +- Fix Aggregator does not retrieve unpublished Tour Steps (#3569)" **Documentation** diff --git a/geotrek/common/tests/test_parsers.py b/geotrek/common/tests/test_parsers.py index 9881ad0670..c255ec2c11 100644 --- a/geotrek/common/tests/test_parsers.py +++ b/geotrek/common/tests/test_parsers.py @@ -668,7 +668,7 @@ class GeotrekAggregatorTestParser(GeotrekAggregatorParser): pass -class GeotrekParserTest(TestCase): +class GeotrekParserTest(GeotrekParserTestMixin, TestCase): def setUp(self, *args, **kwargs): self.filetype = FileType.objects.create(type="Photographie") @@ -676,16 +676,27 @@ def test_improperly_configurated_categories(self): with self.assertRaisesRegex(ImproperlyConfigured, 'foo_field is not configured in categories_keys_api_v2'): call_command('import', 'geotrek.common.tests.test_parsers.GeotrekTrekTestParser', verbosity=2) - def mock_json(self): - filename = os.path.join('geotrek', 'common', 'tests', 'data', 'geotrek_parser_v2', 'treks.json') - with open(filename, 'r') as f: - return json.load(f) - @mock.patch('requests.get') - def test_delete_according_to_provider(self, mocked_get): + @mock.patch('requests.head') + def test_delete_according_to_provider(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [ + ('common', 'treks.json'), + ('common', 'treks.json'), + ('trekking', 'trek_no_children.json'), + ('common', 'treks.json'), + ('common', 'treks.json'), + ('trekking', 'trek_no_children.json'), + ('common', 'treks.json'), + ('common', 'treks.json'), + ('trekking', 'trek_no_children.json')] + + # Mock GET mocked_get.return_value.status_code = 200 mocked_get.return_value.json = self.mock_json - self.assertEqual(Trek.objects.count(), 0) + mocked_get.return_value.content = b'' + mocked_head.return_value.status_code = 200 + call_command('import', 'geotrek.common.tests.test_parsers.GeotrekTrekTestProviderParser', verbosity=0) self.assertEqual(Trek.objects.count(), 1) t = Trek.objects.first() @@ -704,9 +715,26 @@ def test_delete_according_to_provider(self, mocked_get): self.assertEqual(set([t.pk, t2.pk, t3.pk]), set(Trek.objects.values_list('pk', flat=True))) @mock.patch('requests.get') - def test_delete_according_to_no_provider(self, mocked_get): + @mock.patch('requests.head') + def test_delete_according_to_no_provider(self, mocked_head, mocked_get): + self.mock_time = 0 + self.mock_json_order = [ + ('common', 'treks.json'), + ('common', 'treks.json'), + ('trekking', 'trek_no_children.json'), + ('common', 'treks.json'), + ('common', 'treks.json'), + ('trekking', 'trek_no_children.json'), + ('common', 'treks.json'), + ('common', 'treks.json'), + ('trekking', 'trek_no_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 + self.assertEqual(Trek.objects.count(), 0) call_command('import', 'geotrek.common.tests.test_parsers.GeotrekTrekTestNoProviderParser', verbosity=0) self.assertEqual(Trek.objects.count(), 1) @@ -838,6 +866,8 @@ def test_geotrek_aggregator_parser(self, mocked_head, mocked_get): ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json'), ('trekking', 'poi_ids.json'), ('trekking', 'poi.json'), ('tourism', 'informationdesk_ids.json'), @@ -863,6 +893,8 @@ def test_geotrek_aggregator_parser(self, mocked_head, mocked_get): ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json'), ('trekking', 'poi_ids.json'), ('trekking', 'poi.json'), ('tourism', 'informationdesk_ids.json'), @@ -885,9 +917,11 @@ def test_geotrek_aggregator_parser(self, mocked_head, mocked_get): string_parser = output.getvalue() self.assertIn('0000: Trek (URL_1) (00%)', string_parser) self.assertIn('0000: Poi (URL_1) (00%)', string_parser) - self.assertIn('5/5 lignes importées.', string_parser) + # Published Tour steps are imported twice, but created once + self.assertIn('7/7 lignes importées.', string_parser) + self.assertIn('6 enregistrements créés.', string_parser) self.assertIn('2/2 lignes importées.', string_parser) - self.assertEqual(Trek.objects.count(), 5) + self.assertEqual(Trek.objects.count(), 6) self.assertEqual(POI.objects.count(), 2) self.assertEqual(1, Trek.objects.get(name="Foo").information_desks.count()) self.assertEqual("Office de Tourisme de Seix", diff --git a/geotrek/trekking/parsers.py b/geotrek/trekking/parsers.py index 0d05770c9e..5a863e197e 100644 --- a/geotrek/trekking/parsers.py +++ b/geotrek/trekking/parsers.py @@ -197,18 +197,17 @@ def filter_points_reference(self, src, val): def end(self): """Add children after all treks imported are created in database.""" - super().end() self.next_url = f"{self.url}/api/v2/tour" try: params = { 'in_bbox': ','.join([str(coord) for coord in self.bbox.extent]), - 'fields': 'steps,uuid' + 'fields': 'steps,id' } response = self.request_or_retry(f"{self.next_url}", params=params) results = response.json()['results'] final_children = {} for result in results: - final_children[result['uuid']] = [step['uuid'] for step in result['steps']] + final_children[result['uuid']] = [step['id'] for step in result['steps']] for key, value in final_children.items(): if value: @@ -217,18 +216,18 @@ def end(self): self.add_warning(_(f"Trying to retrieve children for missing trek : could not find trek with UUID {key}")) return order = 0 - for child in value: - try: - trek_child_instance = Trek.objects.get(eid=child) - except Trek.DoesNotExist: - self.add_warning(_(f"One trek has not be generated for {trek_parent_instance[0].name} : could not find trek with UUID {child}")) - continue + for child_id in value: + response = self.request_or_retry(f"{self.url}/api/v2/trek/{child_id}") + child_trek = response.json() + self.parse_row(child_trek) + trek_child_instance = self.obj OrderedTrekChild.objects.update_or_create(parent=trek_parent_instance[0], child=trek_child_instance, defaults={'order': order}) order += 1 except Exception as e: self.add_warning(_(f"An error occured in children generation : {getattr(e, 'message', repr(e))}")) + super().end() class GeotrekServiceParser(GeotrekParser): diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children.json index 16226a3287..84502ccaf9 100644 --- a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children.json +++ b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children.json @@ -7,7 +7,10 @@ "uuid": "9e70b294-1134-4c50-9c56-d722720cacf1", "steps": [ { - "uuid": "c9567576-2934-43ab-979e-e13d02c671a9" + "id": 10439 + }, + { + "id": 10442 } ] }, diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children_do_not_exist.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children_do_not_exist.json index ed743a54b3..c66237ec49 100644 --- a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children_do_not_exist.json +++ b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_children_do_not_exist.json @@ -7,10 +7,10 @@ "uuid": "9e70b294-1134-4c50-9c56-d722720cacf1", "steps": [ { - "uuid": "c9567576-2934-43ab-979e-e13d02c671a9" + "id": 1234 }, { - "uuid": "c9567576-2934-43ab-666e-e13d02c671a9" + "id": 1235 } ] }, @@ -34,7 +34,7 @@ "uuid": "b2aea666-5e6e-4daa-a750-7d2ee52d3fe1", "steps": [ { - "uuid": "c9567576-2934-43ab-979e-e13d02c671a9" + "id": 457 } ] } diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_no_children.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_no_children.json new file mode 100644 index 0000000000..93133b7ef5 --- /dev/null +++ b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_no_children.json @@ -0,0 +1,27 @@ +{ + "count": 5, + "next": null, + "previous": null, + "results": [ + { + "uuid": "9e70b294-1134-4c50-9c56-d722720cacf1", + "steps": [] + }, + { + "uuid": "1ba24605-aff2-4b16-bf30-6de1ebfb2a12", + "steps": [] + }, + { + "uuid": "6761143f-9244-41d0-b1af-21114408f769", + "steps": [] + }, + { + "uuid": "c9567576-2934-43ab-979e-e13d02c671a9", + "steps": [] + }, + { + "uuid": "b2aea892-5e6e-4daa-a750-7d2ee52d3fe1", + "steps": [] + } + ] +} diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_not_found.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_not_found.json new file mode 100644 index 0000000000..0a48448444 --- /dev/null +++ b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_not_found.json @@ -0,0 +1,3 @@ +{ + "detail": "No Trek matches the given query." +} diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_published_step.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_published_step.json new file mode 100644 index 0000000000..6c7dc87b14 --- /dev/null +++ b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_published_step.json @@ -0,0 +1,209 @@ +{ + "id": 10439, + "access": { + "fr": "Bonnac Irazein", + "en": "", + "it": "" + }, + "accessibilities": [], + "accessibility_advice": { + "fr": "", + "en": null, + "it": null + }, + "accessibility_covering": { + "fr": "", + "en": null, + "it": null + }, + "accessibility_exposure": { + "fr": "", + "en": null, + "it": null + }, + "accessibility_level": null, + "accessibility_signage": { + "fr": "", + "en": null, + "it": null + }, + "accessibility_slope": { + "fr": "", + "en": null, + "it": null + }, + "accessibility_width": { + "fr": "", + "en": null, + "it": null + }, + "advice": { + "fr": "", + "en": "", + "it": "" + }, + "advised_parking": { + "fr": "", + "en": "", + "it": "" + }, + "altimetric_profile": "https://foo.fr/api/v2/trek/10439/profile/", + "ambiance": { + "fr": "Je suis une bonne ambiance.", + "en": "", + "it": "" + }, + "arrival": { + "fr": "Ourjout", + "en": "", + "it": "" + }, + "ascent": 203, + "attachments": [ + { + "backend": "", + "type": "image", + "author": "Borvan53, CC-By-SA 4.0", + "license": null, + "thumbnail": "https://foo.fr/media/paperclip/trekking_trek/10439/bocard_deylie_2013_01.JPG.400x0_q85.jpg", + "legend": "Vue du site du bocard d'Eylie", + "title": "", + "url": "https://foo.fr/media/paperclip/trekking_trek/10439/bocard_deylie_2013_01.JPG", + "uuid": "2ed7ebc0-39ed-482c-bae3-0b1182f27d3d" + }, + { + "backend": "", + "type": "image", + "author": "", + "license": null, + "thumbnail": "https://foo.fr/media/paperclip/trekking_trek/10439/eeaio.jpeg.400x0_q85.jpg", + "legend": "", + "title": "éèàïô", + "url": "https://foo.fr/media/paperclip/trekking_trek/10439/eeaio.jpeg", + "uuid": "05c0c4ad-69bd-4b86-a8dc-3cbc74ecc4b6" + } + ], + "attachments_accessibility": [], + "children": [], + "cities": [ + "09290", + "09059", + "09317", + "09062" + ], + "create_datetime": "2019-07-23T09:09:53.090318Z", + "departure": { + "fr": "Eylé", + "en": "", + "es": "", + "it": "" + }, + "departure_city": "09290", + "departure_geom": [ + 0.9377712652787816, + 42.83789927043632 + ], + "descent": -564, + "description": { + "fr": "Dede est au bar.", + "en": "", + "it": "" + }, + "description_teaser": { + "fr": "Chapeau a fleur.", + "en": "", + "it": "" + }, + "difficulty": 2, + "disabled_infrastructure": { + "fr": "", + "en": null, + "it": null + }, + "duration": 6.0, + "elevation_area_url": "https://foo.fr/api/v2/trek/10439/dem/", + "elevation_svg_url": "https://foo.fr/api/v2/trek/10439/profile/?language=fr&format=svg", + "external_id": null, + "gear": { + "fr": "", + "en": null, + "it": null + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 0.9377713, + 42.8378993, + 912.0 + ], + [ + 0.9377673, + 42.8379281, + 913.0 + ] + ] + }, + "gpx": "https://foo.fr/api/fr/treks/10439/deyle-a-ourjout.gpx", + "information_desks": [], + "kml": "https://foo.fr/api/fr/treks/10439/deyle-a-ourjout.kml", + "labels": [], + "length_2d": 12856.3, + "length_3d": 12904.9, + "max_elevation": 927, + "min_elevation": 551, + "name": { + "fr": "Foo", + "en": "Bar", + "it": "" + }, + "networks": [], + "next": { + "2": null, + "10445": 10441 + }, + "parents": [ + 2, + 10445 + ], + "parking_location": null, + "pdf": { + "fr": "https://foo.fr/api/fr/treks/10439/deyle-a-ourjout.pdf", + "en": "https://foo.fr/api/en/treks/10439/deyle-a-ourjout.pdf", + "it": "https://foo.fr/api/it/treks/10439/deyle-a-ourjout.pdf" + }, + "points_reference": null, + "portal": [], + "practice": 4, + "ratings": [], + "ratings_description": { + "fr": "", + "en": null, + "it": null + }, + "previous": { + "2": null, + "10445": null + }, + "public_transport": { + "fr": "", + "en": "", + "it": "" + }, + "published": { + "fr": true, + "en": false, + "it": false + }, + "reservation_system": null, + "reservation_id": "", + "route": 3, + "second_external_id": null, + "source": [], + "structure": 3, + "themes": [], + "update_datetime": "2021-05-17T13:54:07.091500Z", + "url": "https://foo.fr/api/v2/trek/10439/", + "uuid": "c9567576-2934-43ab-979e-e13d02c671a9", + "web_links": [] +} diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_unpublished_step.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_unpublished_step.json new file mode 100644 index 0000000000..f07733f15d --- /dev/null +++ b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_unpublished_step.json @@ -0,0 +1,308 @@ + { + "id": 10442, + "access": { + "fr": "", + "en": "", + "it": "" + }, + "accessibilities": [ + 1 + ], + "accessibility_advice": { + "fr": "", + "en": "", + "it": "" + }, + "accessibility_covering": { + "fr": "", + "en": "", + "it": "" + }, + "accessibility_exposure": { + "fr": "", + "en": "", + "it": "" + }, + "accessibility_level": null, + "accessibility_signage": { + "fr": "", + "en": "", + "it": "" + }, + "accessibility_slope": { + "fr": "", + "en": "", + "it": "" + }, + "accessibility_width": { + "fr": "", + "en": "", + "it": "" + }, + "advice": { + "fr": "
Attention en cas d'orage. Fortement déconseillé par mauvais temps!
", + "en": "", + "it": "" + }, + "advised_parking": { + "fr": "Avant le Port de Lers", + "en": "", + "it": "" + }, + "altimetric_profile": "https://foo.fr/api/v2/trek/2/profile/", + "ambiance": { + "fr": "Le nom de ce pic est issu de la légende selon laquelle les trois seigneurs des vallées de Massat, Vicdessos et Rabat-les-Trois-Seigneurs, se rencontraient sur la dalle plate en son sommet afin de débattre des droits des différentes vallées qu'ils administraient.
\r\n\r\nÀ partir du xviie siècle, de grandes caravanes d'ânes et de mulets transportaient le charbon de bois entre les forêts du Couserans et les forges à la catalane de la vallée de Rabat via le col de la Pourtanelle sur l'épaulement nord du pic.
\r\n\r\nAu xixe siècle, des porteurs de glace venaient y chercher leur butin sur le flanc nord du pic au glacier d'Ambans pour le transporter ensuite vers Toulouse. Ce glacier a totalement disparu au début du xxie siècle.
\r\n\r\n\r\nSource Wikipedia
\r\n", + "en": "Ambiance en", + "it": "" + }, + "arrival": { + "fr": "Sur la route", + "en": "", + "it": "" + }, + "ascent": 666, + "attachments": [ + { + "backend": "", + "type": "image", + "author": "Grégory Tonon", + "license": "License", + "thumbnail": "https://foo.fr/media/paperclip/trekking_trek/2/1024px-les_pyrenees_depuis_le_pic_des_3_seigneurs.jpg.400x0_q85.jpg", + "legend": "Vue sur la chaîne des Pyrénées, depuis le pics des 3 Seigneurs", + "title": "1024px-Les_Pyrénées_depuis_le_pic_des_3_Seigneurs", + "url": "https://foo.fr/media/paperclip/trekking_trek/2/1024px-les_pyrenees_depuis_le_pic_des_3_seigneurs.jpg", + "uuid": "8c62ae5f-9533-4de6-a863-3e33cd42d16c" + }, + { + "backend": "Attachment", + "type": "video", + "author": "Ariège Pyrénées", + "license": null, + "thumbnail": "", + "legend": "Grands site Occitanie - collection Ariège", + "title": "", + "url": "https://www.youtube.com/watch?v=O5fwnNceuks", + "uuid": "aeffbba4-821a-4f7b-af74-e47ed628679c" + }, + { + "backend": "", + "type": "file", + "author": "", + "license": null, + "thumbnail": "", + "legend": "", + "title": "file_example_MP3_700KB", + "url": "https://foo.fr/media/paperclip/trekking_trek/2/file_example_mp3_700kb.mp3", + "uuid": "529e754b-e5a8-4fe7-944d-161b4900a62e" + } + ], + "attachments_accessibility": [], + "children": [], + "cities": [ + "09231", + "09302" + ], + "create_datetime": "2013-12-12T16:20:01.405056Z", + "departure": { + "fr": "Port de Lers", + "en": "Lers bridge", + "it": "" + }, + "departure_city": "09231", + "departure_geom": [ + 1.411681003952174, + 42.80641572814877 + ], + "descent": -777, + "description": { + "fr": "https://foo.fr/media/paperclip/trekking_trek/2/file_example_mp3_700kb.mp3", + "en": "", + "it": "" + }, + "description_teaser": { + "fr": "Un très joli point de vue, en retrait de la chaîne des Pyrénées.
", + "en": "", + "it": "" + }, + "difficulty": 1, + "disabled_infrastructure": { + "fr": "Accessibilité aménagement", + "en": "", + "it": "" + }, + "duration": 24.0, + "elevation_area_url": "https://foo.fr/api/v2/trek/2/dem/", + "elevation_svg_url": "https://foo.fr/api/v2/trek/2/profile/?language=fr&format=svg", + "external_id": null, + "gear": { + "fr": "Il faut de la corde", + "en": "", + "it": "" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 1.411681, + 42.8064157, + 1516.0 + ], + [ + 1.4117038, + 42.8065905, + 1516.0 + ] + ] + }, + "gpx": "https://foo.fr/api/fr/treks/2/boucle-du-pic-des-trois-seigneurs.gpx", + "information_desks": [ + 2, + 1, + 3 + ], + "kml": "https://foo.fr/api/fr/treks/2/boucle-du-pic-des-trois-seigneurs.kml", + "labels": [ + 1, + 2, + 3 + ], + "length_2d": 7606.3, + "length_3d": 7811.9, + "max_elevation": 2042, + "min_elevation": 1358, + "name": { + "fr": "Etape non publiée", + "en": "Unpublished step", + "it": "" + }, + "networks": [ + 2 + ], + "next": {}, + "parents": [], + "parking_location": [ + 1.412816, + 42.8063269 + ], + "pdf": { + "fr": "https://foo.fr/api/fr/treks/2/boucle-du-pic-des-trois-seigneurs.pdf", + "en": "https://foo.fr/api/en/treks/2/boucle-du-pic-des-trois-seigneurs.pdf", + "it": "https://foo.fr/api/it/treks/2/boucle-du-pic-des-trois-seigneurs.pdf" + }, + "points_reference": { + "type": "MultiPoint", + "coordinates": [ + [ + 1.411417008494028, + 42.81070319713575 + ], + [ + 1.415279389475474, + 42.81693648180148 + ], + [ + 1.403348923777236, + 42.825246550724195 + ], + [ + 1.428325654123916, + 42.8286458024494 + ], + [ + 1.437852860544806, + 42.81611800550653 + ], + [ + 1.423759460449225, + 42.807239989743145 + ] + ] + }, + "portal": [], + "practice": 3, + "ratings": [], + "ratings_description": { + "fr": "", + "en": "", + "it": "" + }, + "previous": {}, + "public_transport": { + "fr": "Test", + "en": "", + "it": "" + }, + "published": { + "fr": true, + "en": true, + "it": false + }, + "reservation_system": null, + "reservation_id": "", + "route": 1, + "second_external_id": null, + "source": [ + 2 + ], + "structure": 1, + "themes": [ + 8, + 4 + ], + "update_datetime": "2022-05-16T12:10:59.927409Z", + "url": "https://foo.fr/api/v2/trek/2/", + "uuid": "9e70b294-1134-4c50-9c56-d722720cace6", + "web_links": [ + { + "name": { + "fr": "Camping", + "en": "Camping", + "it": null + }, + "url": "http://camping.com/", + "category": { + "label": { + "fr": "A lire", + "en": null, + "it": null + }, + "id": 4, + "pictogram": "https://foo.fr/media/upload/weblink-book.png" + } + }, + { + "name": { + "fr": "Makina Corpus", + "en": "Makina Corpus", + "it": null + }, + "url": "http://makina-corpus.com/", + "category": { + "label": { + "fr": "A lire", + "en": null, + "it": null + }, + "id": 4, + "pictogram": "https://foo.fr/media/upload/weblink-book.png" + } + }, + { + "name": { + "fr": "Test", + "en": "", + "it": "" + }, + "url": "http://toto.com", + "category": { + "label": { + "fr": "A lire", + "en": null, + "it": null + }, + "id": 4, + "pictogram": "https://foo.fr/media/upload/weblink-book.png" + } + } + ] + } diff --git a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_wrong_children.json b/geotrek/trekking/tests/data/geotrek_parser_v2/trek_wrong_children.json deleted file mode 100644 index a6ab1d4325..0000000000 --- a/geotrek/trekking/tests/data/geotrek_parser_v2/trek_wrong_children.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "count": 5, - "next": null, - "previous": null, - "results": [ - { - "uuid": "9e70b294-1134-4c50-9c56-d722720cacf1" - }, - { - "uuid": "1ba24605-aff2-4b16-bf30-6de1ebfb2a12" - }, - { - "uuid": "6761143f-9244-41d0-b1af-21114408f769" - }, - { - "uuid": "c9567576-2934-43ab-979e-e13d02c671a9" - }, - { - "uuid": "b2aea892-5e6e-4daa-a750-7d2ee52d3fe1" - } - ] -} diff --git a/geotrek/trekking/tests/test_parsers.py b/geotrek/trekking/tests/test_parsers.py index 290b175d17..2ccf04bc79 100644 --- a/geotrek/trekking/tests/test_parsers.py +++ b/geotrek/trekking/tests/test_parsers.py @@ -263,7 +263,9 @@ def test_create(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), - ('trekking', 'trek_children.json')] + ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -272,7 +274,7 @@ def test_create(self, mocked_head, mocked_get): 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(Trek.objects.count(), 6) trek = Trek.objects.all().first() self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs") self.assertEqual(trek.name_it, "Foo bar") @@ -288,6 +290,7 @@ def test_create(self, mocked_head, mocked_get): 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.children.last().name, "Etape non publiée") self.assertEqual(trek.labels.count(), 3) self.assertEqual(trek.source.first().name, "Une source numero 2") self.assertEqual(trek.source.first().website, "https://www.ecrins-parcnational.fr") @@ -312,7 +315,11 @@ class MockResponse: ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), ('trekking', 'trek_children.json'), - ('trekking', 'trek_children.json')] + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json'), + ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json')] mock_time = 0 total_mock_response = 1 @@ -341,7 +348,7 @@ def content(self): 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(Trek.objects.count(), 6) trek = Trek.objects.all().first() self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs") self.assertEqual(trek.name_it, "Foo bar") @@ -372,7 +379,9 @@ def test_create_attachment_max_size(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), - ('trekking', 'trek_children.json')] + ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -381,7 +390,7 @@ def test_create_attachment_max_size(self, mocked_head, mocked_get): 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(Trek.objects.count(), 6) self.assertEqual(Attachment.objects.count(), 0) @mock.patch('requests.get') @@ -401,7 +410,9 @@ class MockResponse: ('trekking', 'sources.json'), ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), - ('trekking', 'trek_children.json')] + ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json')] mock_time = 0 a = 0 @@ -430,15 +441,15 @@ def content(self): 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(Trek.objects.count(), 6) 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'15') + self.assertEqual(Attachment.objects.first().attachment_file.read(), b'20') call_command('import', 'geotrek.trekking.tests.test_parsers.TestGeotrekTrekParser', verbosity=0) - self.assertEqual(Trek.objects.count(), 5) + self.assertEqual(Trek.objects.count(), 6) trek.refresh_from_db() self.assertEqual(Attachment.objects.filter(object_id=trek.pk).count(), 3) - self.assertEqual(Attachment.objects.first().attachment_file.read(), b'25') + self.assertEqual(Attachment.objects.first().attachment_file.read(), b'35') @mock.patch('requests.get') @mock.patch('requests.head') @@ -458,6 +469,8 @@ def test_create_multiple_fr(self, mocked_head, mocked_get): ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json'), ('trekking', 'structure.json'), ('trekking', 'trek_difficulty.json'), ('trekking', 'trek_route.json'), @@ -469,7 +482,7 @@ def test_create_multiple_fr(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids_2.json'), ('trekking', 'trek_2.json'), - ('trekking', 'trek_children.json'), + ('trekking', 'trek_no_children.json'), ('trekking', 'structure.json'), ('trekking', 'trek_difficulty.json'), ('trekking', 'trek_route.json'), @@ -481,7 +494,7 @@ def test_create_multiple_fr(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids_2.json'), ('trekking', 'trek_2_after.json'), - ('trekking', 'trek_children.json'), ] + ('trekking', 'trek_no_children.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -490,7 +503,7 @@ def test_create_multiple_fr(self, mocked_head, mocked_get): 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(Trek.objects.count(), 6) 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") @@ -503,7 +516,7 @@ def test_create_multiple_fr(self, mocked_head, mocked_get): 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) + self.assertEqual(Trek.objects.count(), 7) trek = Trek.objects.get(name_fr="Étangs du Picot") self.assertEqual(trek.description_teaser_fr, "Chapeau") self.assertEqual(trek.description_teaser_it, "Cappello") @@ -517,7 +530,7 @@ def test_create_multiple_fr(self, mocked_head, mocked_get): 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.objects.count(), 7) self.assertEqual(trek.description_teaser_fr, "Chapeau 2") self.assertEqual(trek.description_teaser_it, "Cappello 2") self.assertEqual(trek.description_teaser_es, "Sombrero 2") @@ -547,6 +560,8 @@ def test_create_multiple_en(self, mocked_head, mocked_get): ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json'), ('trekking', 'structure.json'), ('trekking', 'trek_difficulty.json'), ('trekking', 'trek_route.json'), @@ -558,7 +573,7 @@ def test_create_multiple_en(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids_2.json'), ('trekking', 'trek_2.json'), - ('trekking', 'trek_children.json'), + ('trekking', 'trek_no_children.json'), ('trekking', 'structure.json'), ('trekking', 'trek_difficulty.json'), ('trekking', 'trek_route.json'), @@ -570,7 +585,7 @@ def test_create_multiple_en(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids_2.json'), ('trekking', 'trek_2_after.json'), - ('trekking', 'trek_children.json')] + ('trekking', 'trek_no_children.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -579,7 +594,7 @@ def test_create_multiple_en(self, mocked_head, mocked_get): 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(Trek.objects.count(), 6) 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") @@ -593,7 +608,7 @@ def test_create_multiple_en(self, mocked_head, mocked_get): 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) + self.assertEqual(Trek.objects.count(), 7) trek = Trek.objects.get(name_fr="Étangs du Picot") self.assertEqual(trek.description_teaser_fr, "Chapeau") self.assertEqual(trek.description_teaser_it, "Cappello") @@ -607,7 +622,7 @@ def test_create_multiple_en(self, mocked_head, mocked_get): 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.objects.count(), 7) self.assertEqual(trek.description_teaser_fr, "Chapeau 2") self.assertEqual(trek.description_teaser_it, "Cappello 2") self.assertEqual(trek.description_teaser_es, "Sombrero 2") @@ -635,7 +650,9 @@ def test_children_do_not_exist(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), - ('trekking', 'trek_children_do_not_exist.json')] + ('trekking', 'trek_children_do_not_exist.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -645,7 +662,6 @@ def test_children_do_not_exist(self, mocked_head, mocked_get): 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') @@ -664,7 +680,8 @@ def test_wrong_children_error(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), - ('trekking', 'trek_wrong_children.json'), ] + ('trekking', 'trek_children.json'), + ('trekking', 'trek_not_found.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -675,7 +692,7 @@ def test_wrong_children_error(self, mocked_head, mocked_get): 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()) + self.assertIn("An error occured in children generation : ValueImportError", output.getvalue()) @mock.patch('requests.get') @mock.patch('requests.head') @@ -695,6 +712,8 @@ def test_updated(self, mocked_head, mocked_get): ('trekking', 'trek_ids.json'), ('trekking', 'trek.json'), ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json'), ('trekking', 'structure.json'), ('trekking', 'trek_difficulty.json'), ('trekking', 'trek_route.json'), @@ -707,7 +726,9 @@ def test_updated(self, mocked_head, mocked_get): ('trekking', 'sources.json'), ('trekking', 'trek_ids_2.json'), ('trekking', 'trek_2.json'), - ('trekking', 'trek_children.json')] + ('trekking', 'trek_children.json'), + ('trekking', 'trek_published_step.json'), + ('trekking', 'trek_unpublished_step.json')] # Mock GET mocked_get.return_value.status_code = 200 @@ -716,7 +737,7 @@ def test_updated(self, mocked_head, mocked_get): 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(Trek.objects.count(), 6) 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") @@ -729,8 +750,8 @@ def test_updated(self, mocked_head, mocked_get): 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 2 is still in ids (trek_ids_2) => it's not removed, and neither are its children + self.assertEqual(Trek.objects.count(), 4) trek = Trek.objects.all().first() self.assertEqual(trek.name, "Boucle du Pic des Trois Seigneurs")