Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle case where year is none when loading signage - #3611 #3746

Merged
merged 2 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CHANGELOG
**Bug fixes**

- Fix missing update rights for Infrastructure Condition and Infrastructure Type with no structure in Admin Site (#3747)
- Allow to load a signage with the year set to None, raise error if set to NaN (#3611)


2.100.2 (2023-09-12)
Expand Down
22 changes: 22 additions & 0 deletions geotrek/common/tests/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Dict

import fiona


def update_gis(input_file_path: str, output_file_path: str, new_properties: Dict):
'''
Utility function that reads a GIS file (GeoPackage or Shapefile), update some properties,
then write a new shapefile (typically in /tmp). Useful to test specific property values.
'''

with fiona.open(input_file_path) as source:
with fiona.open(output_file_path,
mode='w',
crs=source.crs,
driver=source.driver,
schema=source.schema) as dest:
for feat in source:
dest.write(fiona.Feature(
geometry=feat.geometry,
properties={**feat.properties, **new_properties}
))
13 changes: 11 additions & 2 deletions geotrek/signage/management/commands/loadsignage.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


class Command(BaseCommand):
help = 'Load a layer with point geometries in te structure model\n'
help = 'Load a layer with point geometries in the structure model\n'
can_import_settings = True
counter = 0

Expand Down Expand Up @@ -178,7 +178,16 @@ def handle(self, *args, **options):

structure = Structure.objects.get(name=feature.get(field_structure_type)) if field_structure_type in available_fields else structure
description = feature.get(field_description) if field_description in available_fields else default_description
year = int(feature.get(field_implantation_year)) if field_implantation_year in available_fields and feature.get(field_implantation_year).isdigit() else default_year

year = feature.get(field_implantation_year) if field_implantation_year in available_fields else default_year
if year:
if str(year).isdigit():
year = int(year)
else:
raise CommandError('Invalid year: "%s" is not a number.' % year)
else:
year = None

eid = feature.get(field_eid) if field_eid in available_fields else None
code = feature.get(field_code) if field_code in available_fields else default_code

Expand Down
53 changes: 53 additions & 0 deletions geotrek/signage/tests/test_command_signage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from io import StringIO
import tempfile

from django.contrib.gis.geos.error import GEOSException
from django.core.management import call_command
Expand All @@ -10,6 +11,7 @@
from geotrek.signage.tests.factories import SignageFactory
from geotrek.signage.models import Signage
from geotrek.authent.tests.factories import StructureFactory
from geotrek.common.tests.utils import update_gis


class SignageCommandTest(TestCase):
Expand Down Expand Up @@ -51,6 +53,57 @@ def test_load_signage_multipoints(self):
self.assertEqual(2010, value.implantation_year)
self.assertEqual(Signage.objects.count(), 1)

def test_load_signage_none_year(self):
'''Loading a signage with a year set to None should not fail.'''

input_file_path = os.path.join(os.path.dirname(__file__), 'data', 'signage.shp')

with tempfile.TemporaryDirectory() as tmp_dir:
output_file_path = os.path.join(tmp_dir, 'signage_none_year.shp')
update_gis(input_file_path, output_file_path, {'year': None})

output = StringIO()
StructureFactory.create(name='structure')
call_command(
'loadsignage',
output_file_path,
type_default='label',
name_default='name',
condition_default='condition',
structure_default='structure',
description_default='description',
year_field='year',
stdout=output
)

value = Signage.objects.first()
self.assertEqual(None, value.implantation_year)

def test_load_signage_bad_year(self):
'''Loading a signage with an invalid year should fail.'''

input_file_path = os.path.join(os.path.dirname(__file__), 'data', 'signage.shp')

with tempfile.TemporaryDirectory() as tmp_dir:
output_file_path = os.path.join(tmp_dir, 'signage_none_year.shp')
update_gis(input_file_path, output_file_path, {'year': 'not a number'})

output = StringIO()
StructureFactory.create(name='structure')

with self.assertRaisesRegex(CommandError, 'Invalid year: "not a number" is not a number.'):
call_command(
'loadsignage',
output_file_path,
type_default='label',
name_default='name',
condition_default='condition',
structure_default='structure',
description_default='description',
year_field='year',
stdout=output
)

def test_load_signage_bad_multipoints_error(self):
output = StringIO()
StructureFactory.create(name='structure')
Expand Down