def setUp(self): center_point = Point(25, 25, srid=4326) center_point.transform(3857) self.instance = make_instance(point=center_point, edge_length=500000) self.user = make_admin_user(self.instance) self.ie = TreeImportEvent(file_name='file', owner=self.user, instance=self.instance) self.ie.save()
def download_import_template(request, instance, import_type): if import_type == SpeciesImportEvent.import_type: filename = 'OpenTreeMap_Species_Import_Template.csv' field_names = fields.title_case(fields.species.ALL) else: filename = 'OpenTreeMap_Tree_Import_Template.csv' ie = TreeImportEvent(instance=instance) field_names = ie.ordered_legal_fields_title_case() response = HttpResponse(content_type="text/csv") response["Content-Disposition"] = "attachment; filename=%s" % filename writer = csv.DictWriter(response, field_names) writer.writeheader() return response
def test_missing_point_field(self): ie = TreeImportEvent(file_name="file", owner=self.user, instance=self.instance) ie.save() TreeImportRow.objects.count() c = self.write_csv([["Plot width", "Plot length"], ["5", "5"], ["8", "8"]]) rslt = _create_rows_for_event(ie, c) self.assertFalse(rslt) ierrors = json.loads(ie.errors) self.assertTrue(len(ierrors), 1) self.assertHasError(ie, errors.MISSING_FIELD)
def setUp(self): center_point = Point(25, 25, srid=4326) center_point.transform(3857) self.instance = make_instance(point=center_point, edge_length=500000) self.user = make_admin_user(self.instance) self.ie = TreeImportEvent(file_name="file", owner=self.user, instance=self.instance) self.ie.save()
def test_missing_point_field(self): ie = TreeImportEvent(file_name='file', owner=self.user, instance=self.instance) ie.save() TreeImportRow.objects.count() c = self.write_csv([['Plot width', 'Plot length'], ['5', '5'], ['8', '8']]) rslt = _create_rows_for_event(ie, c) self.assertFalse(rslt) ierrors = json.loads(ie.errors) self.assertTrue(len(ierrors), 1) self.assertHasError(ie, errors.MISSING_FIELD)
def test_empty_file_error(self): ie = TreeImportEvent(file_name="file", owner=self.user, instance=self.instance) ie.save() base_rows = TreeImportRow.objects.count() c = self.write_csv([["point x", "point y"]]) rslt = _create_rows_for_event(ie, c) # No rows added and validation failed self.assertEqual(TreeImportRow.objects.count(), base_rows) self.assertFalse(rslt) # The only error is a bad file error ierrors = json.loads(ie.errors) self.assertTrue(len(ierrors), 1) self.assertHasError(ie, errors.EMPTY_FILE)
def download_import_template(request, instance, import_type): if import_type == SpeciesImportEvent.import_type: filename = 'OpenTreeMap_Species_Import_Template.csv' field_names = fields.title_case(fields.species.ALL) else: filename = 'OpenTreeMap_Tree_Import_Template.csv' ie = TreeImportEvent(instance=instance) field_names = ie.ordered_legal_fields_title_case() # Encoding the field names prevents an error when the field names have # non-ASCII characters. field_names = [field_name.encode('utf-8') for field_name in field_names] response = HttpResponse(content_type="text/csv") response["Content-Disposition"] = "attachment; filename=%s" % filename writer = csv.DictWriter(response, field_names) writer.writeheader() return response
def test_empty_file_error(self): ie = TreeImportEvent(file_name='file', owner=self.user, instance=self.instance) ie.save() base_rows = TreeImportRow.objects.count() c = self.write_csv([['point x', 'point y']]) rslt = _create_rows_for_event(ie, c) # No rows added and validation failed self.assertEqual(TreeImportRow.objects.count(), base_rows) self.assertFalse(rslt) # The only error is a bad file error ierrors = json.loads(ie.errors) self.assertTrue(len(ierrors), 1) self.assertHasError(ie, errors.EMPTY_FILE)
def test_unknown_field(self): ie = TreeImportEvent(file_name='file', owner=self.user, instance=self.instance) ie.save() TreeImportRow.objects.count() c = self.write_csv([ ['street address', 'name', 'age', 'point x', 'point y'], ['123 Beach St', 'a', 'b', '5', '5'], ['222 Main St', 'a', 'b', '8', '8']]) rslt = _create_rows_for_event(ie, c) self.assertFalse(rslt) ierrors = json.loads(ie.errors) self.assertTrue(len(ierrors), 1) self.assertHasError(ie, errors.UNMATCHED_FIELDS) self.assertEqual(set(ierrors[0]['data']), set(['name', 'age']))
def test_unknown_field(self): ie = TreeImportEvent(file_name="file", owner=self.user, instance=self.instance) ie.save() TreeImportRow.objects.count() c = self.write_csv( [ ["street address", "name", "age", "point x", "point y"], ["123 Beach St", "a", "b", "5", "5"], ["222 Main St", "a", "b", "8", "8"], ] ) rslt = _create_rows_for_event(ie, c) self.assertFalse(rslt) ierrors = json.loads(ie.errors) self.assertTrue(len(ierrors), 1) self.assertHasError(ie, errors.UNMATCHED_FIELDS) self.assertEqual(set(ierrors[0]["data"]), set(["name", "age"]))
class TreeValidationTest(ValidationTest): def setUp(self): center_point = Point(25, 25, srid=4326) center_point.transform(3857) self.instance = make_instance(point=center_point, edge_length=500000) self.user = make_admin_user(self.instance) self.ie = TreeImportEvent(file_name='file', owner=self.user, instance=self.instance) self.ie.save() def mkrow(self, data): return TreeImportRow.objects.create( data=json.dumps(data), import_event=self.ie, idx=1) def test_udf(self): psycopg2.extras.register_hstore(connection.cursor(), globally=True) UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type='Plot', datatype=json.dumps({'type': 'choice', 'choices': ['a', 'b', 'c']}), iscollection=False, name='Test choice') row = {'point x': '16', 'point y': '20', 'plot: test choice': 'a'} i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.INVALID_UDF_VALUE) row['plot: test choice'] = 'z' i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.INVALID_UDF_VALUE) def test_species_diameter_and_height(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1', max_height=30, max_diameter=19) s1_gs = Species(instance=self.instance, genus='g1', species='s1', cultivar='', max_height=22, max_diameter=12) s1_gsc.save_with_system_user_bypass_auth() s1_gs.save_with_system_user_bypass_auth() row = {'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1', 'diameter': '15', 'tree height': '18'} i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row['tree height'] = 25 i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row['cultivar'] = 'c1' i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) def test_proximity(self): p1 = mkPlot(self.instance, self.user, geom=Point(25.0000001, 25.0000001, srid=4326)) p2 = mkPlot(self.instance, self.user, geom=Point(25.0000002, 25.0000002, srid=4326)) p3 = mkPlot(self.instance, self.user, geom=Point(25.0000003, 25.0000003, srid=4326)) p4 = mkPlot(self.instance, self.user, geom=Point(27.0000001, 27.0000001, srid=4326)) n1 = {p.pk for p in [p1, p2, p3]} n2 = {p4.pk} i = self.mkrow({'point x': '25.0000001', 'point y': '25.0000001'}) i.validate_row() self.assertHasError(i, errors.DUPLICATE_TREE) i = self.mkrow({'point x': '25.00000025', 'point y': '25.00000025'}) i.validate_row() self.assertHasError(i, errors.NEARBY_TREES, n1, set) i = self.mkrow({'point x': '27.00000015', 'point y': '27.00000015'}) i.validate_row() self.assertHasError(i, errors.NEARBY_TREES, n2, set) i = self.mkrow({'point x': '30.00000015', 'point y': '30.00000015'}) i.validate_row() self.assertNotHasError(i, errors.NEARBY_TREES) def test_species_id(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1') s1_gs = Species(instance=self.instance, genus='g1', species='s1', cultivar='') s1_g = Species(instance=self.instance, genus='g1', species='', cultivar='') s2_gsc = Species(instance=self.instance, genus='g2', species='s2', cultivar='c2') s2_gs = Species(instance=self.instance, genus='g2', species='s2', cultivar='') for s in [s1_gsc, s1_gs, s1_g, s2_gsc, s2_gs]: s.save_with_system_user_bypass_auth() # Simple genus, species, cultivar matches i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g1'}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1'}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1', 'cultivar': 'c1'}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) # Test no species info at all i = self.mkrow({'point x': '16', 'point y': '20'}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) # Test mismatches i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's2', 'cultivar': 'c1'}) i.validate_row() self.assertHasError(i, errors.INVALID_SPECIES) i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g2'}) i.validate_row() self.assertHasError(i, errors.INVALID_SPECIES) def test_otm_id(self): # silly invalid-int-errors should be caught i = self.mkrow({'point x': '16', 'point y': '20', 'opentreemap plot id': '44b'}) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INT_ERROR, None) i = self.mkrow({'point x': '25', 'point y': '25', 'opentreemap plot id': '-22'}) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.POS_INT_ERROR) # With no plots in the system, all ids should fail i = self.mkrow({'point x': '25', 'point y': '25', 'opentreemap plot id': '44'}) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_OTM_ID) p = mkPlot(self.instance, self.user) # With an existing plot it should be fine i = self.mkrow({'point x': '25', 'point y': '25', 'opentreemap plot id': p.pk}) r = i.validate_row() self.assertNotHasError(i, errors.INVALID_OTM_ID) self.assertNotHasError(i, errors.INT_ERROR) def test_geom_validation(self): def mkpt(x, y): return self.mkrow({'point x': str(x), 'point y': str(y)}) # Invalid numbers i = mkpt('300a', '20b') r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.FLOAT_ERROR) # Crazy lat/lngs i = mkpt(300, 20) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_GEOM) i = mkpt(50, 93) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_GEOM) i = mkpt(55, 55) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.GEOM_OUT_OF_BOUNDS) i = mkpt(-5, -5) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.GEOM_OUT_OF_BOUNDS) # This should work... i = mkpt(25, 25) r = i.validate_row() # Can't assert that r is true because other validation # logic may have tripped it self.assertNotHasError(i, errors.GEOM_OUT_OF_BOUNDS) self.assertNotHasError(i, errors.INVALID_GEOM) self.assertNotHasError(i, errors.FLOAT_ERROR)
class TreeValidationTest(ValidationTest): def setUp(self): center_point = Point(25, 25, srid=4326) center_point.transform(3857) self.instance = make_instance(point=center_point, edge_length=500000) self.user = make_admin_user(self.instance) self.ie = TreeImportEvent(file_name='file', owner=self.user, instance=self.instance) self.ie.save() def mkrow(self, data): return TreeImportRow.objects.create(data=json.dumps(data), import_event=self.ie, idx=1) def test_udf(self): psycopg2.extras.register_hstore(connection.cursor(), globally=True) UserDefinedFieldDefinition.objects.create(instance=self.instance, model_type='Plot', datatype=json.dumps({ 'type': 'choice', 'choices': ['a', 'b', 'c'] }), iscollection=False, name='Test choice') row = {'point x': '16', 'point y': '20', 'plot: test choice': 'a'} i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.INVALID_UDF_VALUE) row['plot: test choice'] = 'z' i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.INVALID_UDF_VALUE) def test_species_diameter_and_height(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1', max_height=30, max_diameter=19) s1_gs = Species(instance=self.instance, genus='g1', species='s1', cultivar='', max_height=22, max_diameter=12) s1_gsc.save_with_system_user_bypass_auth() s1_gs.save_with_system_user_bypass_auth() row = { 'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1', 'diameter': '15', 'tree height': '18' } i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row['tree height'] = 25 i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row['cultivar'] = 'c1' i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) def test_proximity(self): p1 = mkPlot(self.instance, self.user, geom=Point(25.0000001, 25.0000001, srid=4326)) p2 = mkPlot(self.instance, self.user, geom=Point(25.0000002, 25.0000002, srid=4326)) p3 = mkPlot(self.instance, self.user, geom=Point(25.0000003, 25.0000003, srid=4326)) p4 = mkPlot(self.instance, self.user, geom=Point(27.0000001, 27.0000001, srid=4326)) n1 = {p.pk for p in [p1, p2, p3]} n2 = {p4.pk} i = self.mkrow({'point x': '25.0000001', 'point y': '25.0000001'}) i.validate_row() self.assertHasError(i, errors.DUPLICATE_TREE) i = self.mkrow({'point x': '25.00000025', 'point y': '25.00000025'}) i.validate_row() self.assertHasError(i, errors.NEARBY_TREES, n1, set) i = self.mkrow({'point x': '27.00000015', 'point y': '27.00000015'}) i.validate_row() self.assertHasError(i, errors.NEARBY_TREES, n2, set) i = self.mkrow({'point x': '30.00000015', 'point y': '30.00000015'}) i.validate_row() self.assertNotHasError(i, errors.NEARBY_TREES) def test_species_id(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1') s1_gs = Species(instance=self.instance, genus='g1', species='s1', cultivar='') s1_g = Species(instance=self.instance, genus='g1', species='', cultivar='') s2_gsc = Species(instance=self.instance, genus='g2', species='s2', cultivar='c2') s2_gs = Species(instance=self.instance, genus='g2', species='s2', cultivar='') for s in [s1_gsc, s1_gs, s1_g, s2_gsc, s2_gs]: s.save_with_system_user_bypass_auth() # Simple genus, species, cultivar matches i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g1'}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) i = self.mkrow({ 'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1' }) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) i = self.mkrow({ 'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1', 'cultivar': 'c1' }) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) # Test no species info at all i = self.mkrow({'point x': '16', 'point y': '20'}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) # Test mismatches i = self.mkrow({ 'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's2', 'cultivar': 'c1' }) i.validate_row() self.assertHasError(i, errors.INVALID_SPECIES) i = self.mkrow({'point x': '16', 'point y': '20', 'genus': 'g2'}) i.validate_row() self.assertHasError(i, errors.INVALID_SPECIES) def test_otm_id(self): # silly invalid-int-errors should be caught i = self.mkrow({ 'point x': '16', 'point y': '20', 'opentreemap plot id': '44b' }) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INT_ERROR, None) i = self.mkrow({ 'point x': '25', 'point y': '25', 'opentreemap plot id': '-22' }) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.POS_INT_ERROR) # With no plots in the system, all ids should fail i = self.mkrow({ 'point x': '25', 'point y': '25', 'opentreemap plot id': '44' }) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_OTM_ID) p = mkPlot(self.instance, self.user) # With an existing plot it should be fine i = self.mkrow({ 'point x': '25', 'point y': '25', 'opentreemap plot id': p.pk }) r = i.validate_row() self.assertNotHasError(i, errors.INVALID_OTM_ID) self.assertNotHasError(i, errors.INT_ERROR) def test_geom_validation(self): def mkpt(x, y): return self.mkrow({'point x': str(x), 'point y': str(y)}) # Invalid numbers i = mkpt('300a', '20b') r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.FLOAT_ERROR) # Crazy lat/lngs i = mkpt(300, 20) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_GEOM) i = mkpt(50, 93) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_GEOM) i = mkpt(55, 55) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.GEOM_OUT_OF_BOUNDS) i = mkpt(-5, -5) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.GEOM_OUT_OF_BOUNDS) # This should work... i = mkpt(25, 25) r = i.validate_row() # Can't assert that r is true because other validation # logic may have tripped it self.assertNotHasError(i, errors.GEOM_OUT_OF_BOUNDS) self.assertNotHasError(i, errors.INVALID_GEOM) self.assertNotHasError(i, errors.FLOAT_ERROR)
class TreeValidationTest(ValidationTest): def setUp(self): center_point = Point(25, 25, srid=4326) center_point.transform(3857) self.instance = make_instance(point=center_point, edge_length=500000) self.user = make_admin_user(self.instance) self.ie = TreeImportEvent(file_name="file", owner=self.user, instance=self.instance) self.ie.save() def mkrow(self, data): return TreeImportRow.objects.create(data=json.dumps(data), import_event=self.ie, idx=1) def test_udf(self): psycopg2.extras.register_hstore(connection.cursor(), globally=True) UserDefinedFieldDefinition.objects.create( instance=self.instance, model_type="Plot", datatype=json.dumps({"type": "choice", "choices": ["a", "b", "c"]}), iscollection=False, name="Test choice", ) row = {"point x": "16", "point y": "20", "plot: test choice": "a"} i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.INVALID_UDF_VALUE) row["plot: test choice"] = "z" i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.INVALID_UDF_VALUE) def test_species_diameter_and_height(self): s1_gsc = Species( instance=self.instance, genus="g1", species="s1", cultivar="c1", max_height=30, max_diameter=19 ) s1_gs = Species(instance=self.instance, genus="g1", species="s1", cultivar="", max_height=22, max_diameter=12) s1_gsc.save_with_system_user_bypass_auth() s1_gs.save_with_system_user_bypass_auth() row = {"point x": "16", "point y": "20", "genus": "g1", "species": "s1", "diameter": "15", "tree height": "18"} i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row["tree height"] = 25 i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row["cultivar"] = "c1" i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) def test_proximity(self): p1 = mkPlot(self.instance, self.user, geom=Point(25.0000001, 25.0000001, srid=4326)) p2 = mkPlot(self.instance, self.user, geom=Point(25.0000002, 25.0000002, srid=4326)) p3 = mkPlot(self.instance, self.user, geom=Point(25.0000003, 25.0000003, srid=4326)) p4 = mkPlot(self.instance, self.user, geom=Point(27.0000001, 27.0000001, srid=4326)) n1 = {p.pk for p in [p1, p2, p3]} n2 = {p4.pk} i = self.mkrow({"point x": "25.0000001", "point y": "25.0000001"}) i.validate_row() self.assertHasError(i, errors.DUPLICATE_TREE) i = self.mkrow({"point x": "25.00000025", "point y": "25.00000025"}) i.validate_row() self.assertHasError(i, errors.NEARBY_TREES, n1, set) i = self.mkrow({"point x": "27.00000015", "point y": "27.00000015"}) i.validate_row() self.assertHasError(i, errors.NEARBY_TREES, n2, set) i = self.mkrow({"point x": "30.00000015", "point y": "30.00000015"}) i.validate_row() self.assertNotHasError(i, errors.NEARBY_TREES) def test_species_id(self): s1_gsc = Species(instance=self.instance, genus="g1", species="s1", cultivar="c1") s1_gs = Species(instance=self.instance, genus="g1", species="s1", cultivar="") s1_g = Species(instance=self.instance, genus="g1", species="", cultivar="") s2_gsc = Species(instance=self.instance, genus="g2", species="s2", cultivar="c2") s2_gs = Species(instance=self.instance, genus="g2", species="s2", cultivar="") for s in [s1_gsc, s1_gs, s1_g, s2_gsc, s2_gs]: s.save_with_system_user_bypass_auth() # Simple genus, species, cultivar matches i = self.mkrow({"point x": "16", "point y": "20", "genus": "g1"}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) i = self.mkrow({"point x": "16", "point y": "20", "genus": "g1", "species": "s1"}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) i = self.mkrow({"point x": "16", "point y": "20", "genus": "g1", "species": "s1", "cultivar": "c1"}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) # Test no species info at all i = self.mkrow({"point x": "16", "point y": "20"}) i.validate_row() self.assertNotHasError(i, errors.INVALID_SPECIES) # Test mismatches i = self.mkrow({"point x": "16", "point y": "20", "genus": "g1", "species": "s2", "cultivar": "c1"}) i.validate_row() self.assertHasError(i, errors.INVALID_SPECIES) i = self.mkrow({"point x": "16", "point y": "20", "genus": "g2"}) i.validate_row() self.assertHasError(i, errors.INVALID_SPECIES) def test_otm_id(self): # silly invalid-int-errors should be caught i = self.mkrow({"point x": "16", "point y": "20", "opentreemap plot id": "44b"}) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INT_ERROR, None) i = self.mkrow({"point x": "25", "point y": "25", "opentreemap plot id": "-22"}) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.POS_INT_ERROR) # With no plots in the system, all ids should fail i = self.mkrow({"point x": "25", "point y": "25", "opentreemap plot id": "44"}) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_OTM_ID) p = mkPlot(self.instance, self.user) # With an existing plot it should be fine i = self.mkrow({"point x": "25", "point y": "25", "opentreemap plot id": p.pk}) r = i.validate_row() self.assertNotHasError(i, errors.INVALID_OTM_ID) self.assertNotHasError(i, errors.INT_ERROR) def test_geom_validation(self): def mkpt(x, y): return self.mkrow({"point x": str(x), "point y": str(y)}) # Invalid numbers i = mkpt("300a", "20b") r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.FLOAT_ERROR) # Crazy lat/lngs i = mkpt(300, 20) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_GEOM) i = mkpt(50, 93) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.INVALID_GEOM) i = mkpt(55, 55) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.GEOM_OUT_OF_BOUNDS) i = mkpt(-5, -5) r = i.validate_row() self.assertFalse(r) self.assertHasError(i, errors.GEOM_OUT_OF_BOUNDS) # This should work... i = mkpt(25, 25) r = i.validate_row() # Can't assert that r is true because other validation # logic may have tripped it self.assertNotHasError(i, errors.GEOM_OUT_OF_BOUNDS) self.assertNotHasError(i, errors.INVALID_GEOM) self.assertNotHasError(i, errors.FLOAT_ERROR)