Exemplo n.º 1
0
class PropertyStandListTest(TestCase):
    """
    test web service to grab json of user's propertie's stands
    [{stand-attrs}, ...]
    """

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user("featuretest", "*****@*****.**", password="******")
        self.baduser = User.objects.create_user("baduser", "*****@*****.**", password="******")

        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1)
        self.stand2.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)
        enable_sharing()

    def test_unauth(self):
        link = self.prop1.options.get_link("Property Stands GeoJSON")
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 401)

    def test_notexists(self):
        self.client.login(username="******", password="******")
        link = self.prop1.options.get_link("Property Stands GeoJSON")
        url = link.reverse(self.prop1)
        url = url.replace(self.prop1.uid, "trees_forestproperty_123456789")
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_baduser(self):
        self.client.login(username="******", password="******")
        link = self.prop1.options.get_link("Property Stands GeoJSON")
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 403)

    def test_jsonlist(self):
        self.client.login(username="******", password="******")
        link = self.prop1.options.get_link("Property Stands GeoJSON")
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        stand_list = loads(response.content)
        self.assertEquals(stand_list["features"][0]["properties"]["name"], "My Stand", stand_list)

        self.prop1.add(self.stand2)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        stand_list = loads(response.content)
        names = [stand["properties"]["name"] for stand in stand_list["features"]]
        names.sort()
        expected_names = ["My Stand", "My Stand2"]
        expected_names.sort()
        self.assertEqual(names, expected_names)
Exemplo n.º 2
0
 def test_delete_stand(self):
     stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
     stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1)
     stand1.save()
     stand2.save()
     self.assertEqual(len(Stand.objects.all()), 2)
     Stand.objects.filter(name="My Stand2").delete()
     self.assertEqual(len(Stand.objects.all()), 1)
Exemplo n.º 3
0
 def test_delete_stand(self):
     stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
     stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1)
     stand1.save()
     stand2.save()
     self.assertEqual(len(Stand.objects.all()), 2)
     Stand.objects.filter(name="My Stand2").delete()
     self.assertEqual(len(Stand.objects.all()), 1)
Exemplo n.º 4
0
class NearestPlotPyTest(TestCase):
    fixtures = ['test_treelive_summary', 'test_idb_summary', 'test_conditionvariantlookup']

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand1.add_to_collection(self.prop1)

    def _create_strata(self):
        stand_list = {
            'property': self.prop1.uid,
            'classes': [
                ('Douglas-fir', 2, 4, 145),
            ]
        }
        strata = Strata(user=self.user, name="My Strata", search_age=30.0, search_tpa=120.0, stand_list = stand_list)
        strata.save()
        return strata

    def test_bad_stand_list(self):
        stand_list = [ ('Douglas-fir', 2, 4, 145), ]
        strata = Strata(user=self.user, name="My Strata", search_age=30.0, search_tpa=120.0, stand_list=stand_list)
        with self.assertRaises(ValidationError):
            strata.save()

        stand_list = {
            'property': self.prop1.uid,
            'classes': [
                ('Douglas-fir', "booo"),
            ]
        }
        strata = Strata(user=self.user, name="My Strata", search_age=30.0, search_tpa=120.0, stand_list=stand_list)
        with self.assertRaises(ValidationError):
            strata.save()

    def test_assign_strata_to_stand(self):
        strata = self._create_strata()
        self.assertTrue(strata)
        self.stand1.strata = strata
        self.assertEqual("My Strata", self.stand1.strata.name)

    def test_candidates(self):
        from trees.plots import get_candidates
        stand_list = {
            'property': self.prop1.uid,
            'classes': [('Douglas-fir', 2, 4, 145), ]
        }
        variant = self.prop1.variant.code
        get_candidates(stand_list['classes'], variant)
Exemplo n.º 5
0
class NearestPlotPyTest(TestCase):
    fixtures = ['test_treelive_summary', 'test_idb_summary', 'test_conditionvariantlookup']

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1) 
        self.stand1.save()
        self.stand1.add_to_collection(self.prop1)

    def _create_strata(self):
        stand_list = {
            'property': self.prop1.uid,
            'classes': [
                ('Douglas-fir', 2, 4, 145),
            ]
        }
        strata = Strata(user=self.user, name="My Strata", search_age=30.0, search_tpa=120.0, stand_list = stand_list)
        strata.save()
        return strata

    def test_bad_stand_list(self):
        stand_list = [ ('Douglas-fir', 2, 4, 145), ] 
        strata = Strata(user=self.user, name="My Strata", search_age=30.0, search_tpa=120.0, stand_list=stand_list)
        with self.assertRaises(ValidationError):
            strata.save()

        stand_list = {
            'property': self.prop1.uid,
            'classes': [
                ('Douglas-fir', "booo"),
            ]
        }
        strata = Strata(user=self.user, name="My Strata", search_age=30.0, search_tpa=120.0, stand_list=stand_list)
        with self.assertRaises(ValidationError):
            strata.save()

    def test_assign_strata_to_stand(self):
        strata = self._create_strata()
        self.assertTrue(strata)
        self.stand1.strata = strata
        self.assertEqual("My Strata", self.stand1.strata.name)

    def test_candidates(self):
        from trees.plots import get_candidates
        stand_list = {
            'property': self.prop1.uid,
            'classes': [('Douglas-fir', 2, 4, 145), ]
        }
        variant = self.prop1.variant.code
        get_candidates(stand_list['classes'], variant)
Exemplo n.º 6
0
class ForestPropertyTest(TestCase):
    '''
    Basic tests for adding/removing stands from a property
    '''

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')

        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()

    def test_create_property(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()

    def test_property_bbox(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()
        self.assertEqual(prop1.bbox, p1.extent)

    def test_add_property_to_stand(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()

        self.stand1.add_to_collection(prop1)
        self.assertEqual(self.stand1.collection, prop1)
        self.assertTrue(self.stand1 in prop1.feature_set())

        self.stand1.remove_from_collection()
        self.assertEqual(self.stand1.collection, None)
        self.assertTrue(self.stand1 not in prop1.feature_set())

    def test_add_stand_to_property(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()

        prop1.add(self.stand1)
        self.assertEqual(self.stand1.collection, prop1)
        self.assertTrue(self.stand1 in prop1.feature_set())

        prop1.remove(self.stand1)
        self.assertEqual(self.stand1.collection, None)
        self.assertTrue(self.stand1 not in prop1.feature_set())

    def test_add_property_to_property(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop2 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()
        prop2.save()
        # This `prop1.add(prop2)` should fail
        self.assertRaises(AssertionError, prop1.add, prop2)
Exemplo n.º 7
0
class ForestPropertyTest(TestCase):
    '''
    Basic tests for adding/removing stands from a property
    '''

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')

        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1) 
        self.stand1.save()

    def test_create_property(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()

    def test_property_bbox(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()
        self.assertEqual(prop1.bbox, p1.extent)

    def test_add_property_to_stand(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()

        self.stand1.add_to_collection(prop1)
        self.assertEqual(self.stand1.collection, prop1)
        self.assertTrue(self.stand1 in prop1.feature_set())

        self.stand1.remove_from_collection()
        self.assertEqual(self.stand1.collection, None)
        self.assertTrue(self.stand1 not in prop1.feature_set())

    def test_add_stand_to_property(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()

        prop1.add(self.stand1)
        self.assertEqual(self.stand1.collection, prop1)
        self.assertTrue(self.stand1 in prop1.feature_set())

        prop1.remove(self.stand1)
        self.assertEqual(self.stand1.collection, None)
        self.assertTrue(self.stand1 not in prop1.feature_set())

    def test_add_property_to_property(self):
        prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop2 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        prop1.save()
        prop2.save()
        # This `prop1.add(prop2)` should fail
        self.assertRaises(AssertionError, prop1.add, prop2)
Exemplo n.º 8
0
class ManipulatorsTest(TestCase):
    """
    test overlap/sliver manipulators
    """

    def setUp(self):
        """
        A self-intersecting polyon
        """
        self.user = User.objects.create_user("featuretest", "*****@*****.**", password="******")
        self.bad_ewkt = "SRID=3857;POLYGON((-13738982.554637 5741643.81587,-13748693.674233 \
                5750032.832398,-13740702.387773 5750625.1666924,-13744294.928102 \
                5751848.1591448,-13738982.554637 5741643.81587))"

    def test_clean_badgeom(self):
        self.stand1 = Stand(user=self.user, name="Bad Stand", geometry_orig=self.bad_ewkt)
        self.stand1.save()
        self.assertTrue(self.stand1.geometry_final.valid)
Exemplo n.º 9
0
class ManipulatorsTest(TestCase):
    '''
    test overlap/sliver manipulators
    '''

    def setUp(self):
        '''
        A self-intersecting polyon
        '''
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.bad_ewkt = "SRID=3857;POLYGON((-13738982.554637 5741643.81587,-13748693.674233 \
                5750032.832398,-13740702.387773 5750625.1666924,-13744294.928102 \
                5751848.1591448,-13738982.554637 5741643.81587))"

    def test_clean_badgeom(self):
        self.stand1 = Stand(user=self.user, name="Bad Stand", geometry_orig=self.bad_ewkt)
        self.stand1.save()
        self.assertTrue(self.stand1.geometry_final.valid)
Exemplo n.º 10
0
class ImputeTest(TestCase):
    fixtures = ["fvs_species_western"]

    def setUp(self):
        settings.CELERY_ALWAYS_EAGER = True  # force syncronous execution of celery tasks
        import_rasters()
        g2 = GEOSGeometry(
            "SRID=3857;POLYGON((%(x1)s %(y1)s, %(x2)s %(y1)s, %(x2)s %(y2)s, %(x1)s %(y2)s, %(x1)s %(y1)s))"
            % {"x1": -13841975, "y1": 5308646, "x2": -13841703, "y2": 5308927}
        )
        self.client = Client()
        self.user = User.objects.create_user("featuretest", "*****@*****.**", password="******")
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g2)
        self.stand1.save()
        self.pk1 = self.stand1.pk

        self.elev = RasterDataset.objects.get(name="elevation")
        self.aspect = RasterDataset.objects.get(name="aspect")
        self.cos_aspect = RasterDataset.objects.get(name="cos_aspect")
        self.sin_aspect = RasterDataset.objects.get(name="sin_aspect")
        self.slope = RasterDataset.objects.get(name="slope")
        self.avg_elev = 145.6

    def test_impute_onsave(self):
        s1 = Stand.objects.get(pk=self.pk1)
        self.assertNotEqual(s1.elevation, None)
        self.assertAlmostEqual(s1.elevation, self.avg_elev, places=0)

    def test_zonal_null(self):
        s1 = Stand.objects.get(pk=self.pk1)
        offgeom = GEOSGeometry(
            "SRID=3857;POLYGON((-120.42 34.37, -119.64 34.32, -119.63 34.12, -120.44 34.15, -120.42 34.37))"
        )
        s1.geometry_final = offgeom  # this geom should be off the elevation map
        s1.save()
        s1 = Stand.objects.get(pk=self.pk1)
        self.assertEqual(s1.elevation, None)
Exemplo n.º 11
0
class ImputeTest(TestCase):
    fixtures = ['fvs_species_western', ]

    def setUp(self):
        settings.CELERY_ALWAYS_EAGER = True  # force syncronous execution of celery tasks
        import_rasters()
        g2 = GEOSGeometry(
            'SRID=3857;POLYGON((%(x1)s %(y1)s, %(x2)s %(y1)s, %(x2)s %(y2)s, %(x1)s %(y2)s, %(x1)s %(y1)s))' %
            {'x1': -13841975, 'y1': 5308646, 'x2': -13841703, 'y2': 5308927})
        self.client = Client()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g2)
        self.stand1.save()
        self.pk1 = self.stand1.pk

        self.elev = RasterDataset.objects.get(name="elevation")
        self.aspect = RasterDataset.objects.get(name="aspect")
        self.cos_aspect = RasterDataset.objects.get(name="cos_aspect")
        self.sin_aspect = RasterDataset.objects.get(name="sin_aspect")
        self.slope = RasterDataset.objects.get(name="slope")
        self.avg_elev = 145.6

    def test_impute_onsave(self):
        s1 = Stand.objects.get(pk=self.pk1)
        self.assertNotEqual(s1.elevation, None)
        self.assertAlmostEqual(s1.elevation, self.avg_elev, places=0)

    def test_zonal_null(self):
        s1 = Stand.objects.get(pk=self.pk1)
        offgeom = GEOSGeometry(
            'SRID=3857;POLYGON((-120.42 34.37, -119.64 34.32, -119.63 34.12, -120.44 34.15, -120.42 34.37))')
        s1.geometry_final = offgeom # this geom should be off the elevation map
        s1.save()
        s1 = Stand.objects.get(pk=self.pk1)
        self.assertEqual(s1.elevation, None)
Exemplo n.º 12
0
class ScenarioTest(TestCase):
    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user("featuretest", "*****@*****.**", password="******")

        self.stand1 = Stand(user=self.user, name="My Stand 1", geometry_orig=g1)
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand 2", geometry_orig=g1)
        self.stand2.save()
        self.stand3 = Stand(user=self.user, name="My Stand 3 (not on property)", geometry_orig=g1)
        self.stand3.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)
        self.prop1.add(self.stand2)

        self.options = Scenario.get_options()
        self.create_url = self.options.get_create_form()

        self.rx1 = Rx.objects.get(internal_name=self.prop1.variant.code + "1").id
        self.rx2 = Rx.objects.get(internal_name=self.prop1.variant.code + "2").id

        enable_sharing()

    def test_create_scenario(self):
        s1 = Scenario(
            user=self.user,
            name="My Scenario",
            input_target_boardfeet=2000,
            input_target_carbon=1,
            input_property=self.prop1,
            input_rxs={self.stand1.pk: self.rx1, self.stand2.pk: self.rx2},
        )
        s1.save()
        self.assertEquals(Scenario.objects.get(name="My Scenario").input_target_boardfeet, 2000.0)

    def test_scenario_results(self):
        s1 = Scenario(
            user=self.user,
            name="My Scenario",
            input_target_boardfeet=2000,
            input_target_carbon=1,
            input_property=self.prop1,
            input_rxs={self.stand1.pk: self.rx1, self.stand2.pk: self.rx2},
        )
        s1.save()
        out = s1.output_property_metrics
        self.assertTrue(out.has_key("__all__"))
        # TODO out = s1.output_stand_metrics

    def test_post(self):
        self.client.login(username="******", password="******")
        response = self.client.post(
            self.create_url,
            {
                "name": "My Scenario",
                "input_target_boardfeet": 2000,
                "input_target_carbon": 1,
                "input_age_class": 1,
                "input_site_diversity": 1,
                "input_property": self.prop1.pk,
                "input_rxs": dumps({self.stand1.pk: self.rx1, self.stand2.pk: self.rx2}),
            },
        )
        self.assertEqual(response.status_code, 201)

    def test_post_invalid_rx(self):
        self.client.login(username="******", password="******")
        response = self.client.post(
            self.create_url,
            {
                "name": "My Scenario",
                "input_target_boardfeet": 2000,
                "input_target_carbon": 1,
                "input_age_class": 1,
                "input_site_diversity": 1,
                "input_property": self.prop1.pk,
                "input_rxs": dumps({self.stand1.pk: 9879898, self.stand2.pk: self.rx2}),
            },
        )
        self.assertEqual(response.status_code, 400, response.content)

    def test_post_invalid_stand(self):
        self.client.login(username="******", password="******")
        response = self.client.post(
            self.create_url,
            {
                "name": "My Scenario",
                "input_target_boardfeet": 2000,
                "input_target_carbon": 1,
                "input_age_class": 1,
                "input_site_diversity": 1,
                "input_property": self.prop1.pk,
                "input_rxs": dumps({self.stand3.pk: self.rx1, self.stand2.pk: self.rx2}),
            },
        )
        self.assertEqual(response.status_code, 400, response.content)

    def test_json_results(self):
        s1 = Scenario(
            user=self.user,
            name="My Scenario",
            input_target_boardfeet=2000,
            input_target_carbon=1,
            input_property=self.prop1,
            input_rxs={self.stand1.pk: self.rx1, self.stand2.pk: self.rx2},
        )
        s1.save()
        geojson_link = ForestProperty.get_options().get_link("Property Scenarios")
        url = geojson_link.reverse(self.prop1)
        # not logged in yet
        response = self.client.get(url)
        self.assertEqual(response.status_code, 401, response.content)
        # now we log in
        self.client.login(username="******", password="******")
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200, response.content)
Exemplo n.º 13
0
class SpatialTest(TestCase):
    """
    Tests the spatial representations of Stands and ForestProperties
    """

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user("featuretest", "*****@*****.**", password="******")
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1)
        self.stand2.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)

    def test_rest_defaultkml_url(self):
        self.client.login(username="******", password="******")
        link = self.stand1.options.get_link("KML")
        url = link.reverse(self.stand1)
        response = self.client.get(url)
        errors = kml_errors(response.content)
        self.assertFalse(errors, "invalid KML %s" % str(errors))

    def test_stand_json(self):
        thejson = self.stand1.geojson()
        d = loads(thejson)
        self.assertEquals(d["properties"]["name"], "My Stand")

    def test_property_json(self):
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        self.assertEquals(len(d["features"]), 1)
        self.assertEquals(d["features"][0]["properties"]["name"], "My Stand")
        self.prop1.add(self.stand2)
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        self.assertEquals(len(d["features"]), 2)

    def test_property_bbox(self):
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        for x, y in zip(d["bbox"], self.prop1.bbox):
            self.assertAlmostEquals(x, y, places=5)

    def test_stand_json_url(self):
        self.client.login(username="******", password="******")
        link = self.stand1.options.get_link("GeoJSON")
        url = link.reverse(self.stand1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue("application/json" in response["Content-Type"])
        d = loads(response.content)
        self.assertEquals(d["features"][0]["properties"]["name"], "My Stand")

    def test_property_json_url(self):
        self.client.login(username="******", password="******")
        link = self.stand1.options.get_link("GeoJSON")
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue("application/json" in response["Content-Type"])
        d = loads(response.content)
        self.assertEquals(d["features"][0]["properties"]["name"], "My Property")

    def test_multistand_json_url(self):
        self.client.login(username="******", password="******")
        uids = [self.stand1.uid, self.stand2.uid]
        link = Stand.get_options().get_link("GeoJSON")
        url = link.reverse([self.stand1, self.stand2])
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue("application/json" in response["Content-Type"])
        d = loads(response.content)
        self.assertEquals(len(d["features"]), 2)
        foundit = False
        for f in d["features"]:
            if f["properties"]["name"] == "My Stand2":
                foundit = True
        self.assertTrue(foundit)

    def test_property_stands_json_url(self):
        self.prop1.add(self.stand2)
        self.client.login(username="******", password="******")
        link = self.prop1.options.get_link("Property Stands GeoJSON")
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200, response)
        self.assertTrue("application/json" in response["Content-Type"])
        d = loads(response.content)
        self.assertEquals(len(d["features"]), 2)
        foundit = False
        for f in d["features"]:
            if f["properties"]["name"] == "My Stand2":
                foundit = True
        self.assertTrue(foundit)
Exemplo n.º 14
0
class RESTTest(TestCase):
    '''
    Basic tests of the REST API
    A bit of a dup of the features tests but more concise and specific
    '''

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.options = Stand.get_options()
        self.create_url = self.options.get_create_form()
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand1_form_url = self.options.get_update_form(self.stand1.pk)
        self.stand1_url = self.stand1.get_absolute_url()
        enable_sharing()

    def test_submit_not_authenticated(self):
        response = self.client.post(self.create_url,
            {'name': "My Test", 'user': 1})
        self.assertEqual(response.status_code, 401)

    def test_submit_valid_form(self):
        old_count = Stand.objects.count()
        self.client.login(username='******', password='******')
        response = self.client.post(self.create_url, {'name': 'test', 'geometry_orig': g1.wkt, })
        self.assertEqual(response.status_code, 201, response.content)
        self.assertTrue(old_count < Stand.objects.count())
        uid = json.loads(response.content)['X-Madrona-Select']
        inst = get_feature_by_uid(uid)
        self.assertTrue(
            response._get_content().find(inst.get_absolute_url()) > -1)

    def test_get_form(self):
        self.client.login(username='******', password='******')
        response = self.client.get(self.stand1_form_url)
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.content.find('My Stand'), -1)

    def test_post(self):
        self.client.login(username='******', password='******')
        response = self.client.post(self.stand1_url, {
            'name': 'My New Name',
            'geometry_orig': self.stand1.geometry_orig.wkt,
        })
        self.assertEqual(response.status_code, 200, response.content)
        self.assertEqual(Stand.objects.get(pk=self.stand1.pk).name, 'My New Name')

    def test_delete(self):
        self.client.login(username='******', password='******')
        self.assertEqual(Stand.objects.filter(pk=self.stand1.pk).count(), 1)
        response = self.client.delete(self.stand1_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(Stand.objects.filter(pk=self.stand1.pk).count(), 0)

    def test_show(self):
        self.client.login(username='******', password='******')
        response = self.client.get(self.stand1_url)
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.content.find('<title>My Stand</title>'), -1)

    def test_unauthorized(self):
        response = self.client.get(self.stand1_url)
        self.assertEqual(response.status_code, 401)
Exemplo n.º 15
0
class SpatialTest(TestCase):
    '''
    Tests the spatial representations of Stands and ForestProperties
    '''

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1) 
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1) 
        self.stand2.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)

    def test_rest_defaultkml_url(self):
        self.client.login(username='******', password='******')
        link = self.stand1.options.get_link('KML')
        url = link.reverse(self.stand1)
        response = self.client.get(url)
        errors = kml_errors(response.content)
        self.assertFalse(errors,"invalid KML %s" % str(errors))

    def test_stand_json(self):
        thejson = self.stand1.geojson()
        d = loads(thejson)
        self.assertEquals(d['properties']['name'], 'My Stand')

    def test_property_json(self):
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        self.assertEquals(len(d['features']), 1)
        self.assertEquals(d['features'][0]['properties']['name'], 'My Stand')
        self.prop1.add(self.stand2)
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        self.assertEquals(len(d['features']), 2)

    def test_property_bbox(self):
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        for x, y in zip(d['bbox'], self.prop1.bbox):
            self.assertAlmostEquals(x, y, places=5)

    def test_stand_json_url(self):
        self.client.login(username='******', password='******')
        link = self.stand1.options.get_link('GeoJSON')
        url = link.reverse(self.stand1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(d['features'][0]['properties']['name'], 'My Stand')
        
    def test_property_json_url(self):
        self.client.login(username='******', password='******')
        link = self.stand1.options.get_link('GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(d['features'][0]['properties']['name'], 'My Property')

    def test_multistand_json_url(self):
        self.client.login(username='******', password='******')
        uids = [self.stand1.uid, self.stand2.uid]
        link = Stand.get_options().get_link('GeoJSON')
        url = link.reverse([self.stand1, self.stand2])
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(len(d['features']), 2)
        foundit = False
        for f in d['features']:
            if f['properties']['name'] == 'My Stand2':
                foundit = True
        self.assertTrue(foundit)

    def test_property_stands_json_url(self):
        self.prop1.add(self.stand2)
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200, response)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(len(d['features']), 2)
        foundit = False
        for f in d['features']:
            if f['properties']['name'] == 'My Stand2':
                foundit = True
        self.assertTrue(foundit)
Exemplo n.º 16
0
class RESTTest(TestCase):
    """
    Basic tests of the REST API
    A bit of a dup of the features tests but more concise and specific
    """

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user("featuretest", "*****@*****.**", password="******")
        self.options = Stand.get_options()
        self.create_url = self.options.get_create_form()
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand1_form_url = self.options.get_update_form(self.stand1.pk)
        self.stand1_url = self.stand1.get_absolute_url()
        enable_sharing()

    def test_submit_not_authenticated(self):
        response = self.client.post(self.create_url, {"name": "My Test", "user": 1})
        self.assertEqual(response.status_code, 401)

    def test_submit_valid_form(self):
        old_count = Stand.objects.count()
        self.client.login(username="******", password="******")
        response = self.client.post(self.create_url, {"name": "test", "geometry_orig": g1.wkt})
        self.assertEqual(response.status_code, 201, response.content)
        self.assertTrue(old_count < Stand.objects.count())
        uid = json.loads(response.content)["X-Madrona-Select"]
        inst = get_feature_by_uid(uid)
        self.assertTrue(response._get_content().find(inst.get_absolute_url()) > -1)

    def test_get_form(self):
        self.client.login(username="******", password="******")
        response = self.client.get(self.stand1_form_url)
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.content.find("My Stand"), -1)

    def test_post(self):
        self.client.login(username="******", password="******")
        response = self.client.post(
            self.stand1_url, {"name": "My New Name", "geometry_orig": self.stand1.geometry_orig.wkt}
        )
        self.assertEqual(response.status_code, 200, response.content)
        self.assertEqual(Stand.objects.get(pk=self.stand1.pk).name, "My New Name")

    def test_delete(self):
        self.client.login(username="******", password="******")
        self.assertEqual(Stand.objects.filter(pk=self.stand1.pk).count(), 1)
        response = self.client.delete(self.stand1_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(Stand.objects.filter(pk=self.stand1.pk).count(), 0)

    def test_show(self):
        self.client.login(username="******", password="******")
        response = self.client.get(self.stand1_url)
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.content.find("<title>My Stand</title>"), -1)

    def test_unauthorized(self):
        response = self.client.get(self.stand1_url)
        self.assertEqual(response.status_code, 401)
Exemplo n.º 17
0
class ScenarioTest(TestCase):

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')

        self.stand1 = Stand(user=self.user, name="My Stand 1", geometry_orig=g1)
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand 2", geometry_orig=g1)
        self.stand2.save()
        self.stand3 = Stand(user=self.user, name="My Stand 3 (not on property)", geometry_orig=g1)
        self.stand3.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)
        self.prop1.add(self.stand2)

        self.options = Scenario.get_options()
        self.create_url = self.options.get_create_form()

        self.rx1 = Rx.objects.get(internal_name=self.prop1.variant.code + "1").id
        self.rx2 = Rx.objects.get(internal_name=self.prop1.variant.code + "2").id

        enable_sharing()

    def test_create_scenario(self):
        s1 = Scenario(user=self.user, name="My Scenario",
                input_target_boardfeet=2000,
                input_target_carbon=1,
                input_property=self.prop1,
                input_rxs={self.stand1.pk: self.rx1, self.stand2.pk: self.rx2},
             )
        s1.save()
        self.assertEquals(Scenario.objects.get(name="My Scenario").input_target_boardfeet, 2000.0)

    def test_scenario_results(self):
        s1 = Scenario(user=self.user, name="My Scenario",
                input_target_boardfeet=2000,
                input_target_carbon=1,
                input_property=self.prop1,
                input_rxs={self.stand1.pk: self.rx1, self.stand2.pk: self.rx2},
             )
        s1.save()
        out = s1.output_property_metrics
        self.assertTrue(out.has_key("__all__"))
        # TODO out = s1.output_stand_metrics

    def test_post(self):
        self.client.login(username='******', password='******')
        response = self.client.post(self.create_url, {
            'name': "My Scenario",
            'input_target_boardfeet': 2000,
            'input_target_carbon': 1,
            'input_age_class': 1,
            'input_site_diversity': 1,
            'input_property': self.prop1.pk,
            'input_rxs': dumps({self.stand1.pk: self.rx1, self.stand2.pk: self.rx2}),
        })
        self.assertEqual(response.status_code, 201)

    def test_post_invalid_rx(self):
        self.client.login(username='******', password='******')
        response = self.client.post(self.create_url, {
            'name': "My Scenario",
            'input_target_boardfeet': 2000,
            'input_target_carbon': 1,
            'input_age_class': 1,
            'input_site_diversity': 1,
            'input_property': self.prop1.pk,
            'input_rxs': dumps({self.stand1.pk: 9879898, self.stand2.pk: self.rx2}),
        })
        self.assertEqual(response.status_code, 400, response.content)

    def test_post_invalid_stand(self):
        self.client.login(username='******', password='******')
        response = self.client.post(self.create_url, {
            'name': "My Scenario",
            'input_target_boardfeet': 2000,
            'input_target_carbon': 1,
            'input_age_class': 1,
            'input_site_diversity': 1,
            'input_property': self.prop1.pk,
            'input_rxs': dumps({self.stand3.pk: self.rx1, self.stand2.pk: self.rx2}),
        })
        self.assertEqual(response.status_code, 400, response.content)

    def test_json_results(self):
        s1 = Scenario(user=self.user, name="My Scenario",
                input_target_boardfeet=2000,
                input_target_carbon=1,
                input_property=self.prop1,
                input_rxs={self.stand1.pk: self.rx1, self.stand2.pk: self.rx2},
             )
        s1.save()
        geojson_link = ForestProperty.get_options().get_link('Property Scenarios')
        url = geojson_link.reverse(self.prop1)
        # not logged in yet
        response = self.client.get(url)
        self.assertEqual(response.status_code, 401, response.content)
        # now we log in
        self.client.login(username='******', password='******')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200, response.content)
Exemplo n.º 18
0
class PropertyStandListTest(TestCase):
    '''
    test web service to grab json of user's propertie's stands
    [{stand-attrs}, ...]
    '''

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.baduser = User.objects.create_user(
            'baduser', '*****@*****.**', password='******')

        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1)
        self.stand2.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)
        enable_sharing()

    def test_unauth(self):
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 401)

    def test_notexists(self):
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        url = url.replace(self.prop1.uid, 'trees_forestproperty_123456789')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_baduser(self):
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 403)

    def test_jsonlist(self):
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        stand_list = loads(response.content)
        self.assertEquals(stand_list['features'][0]['properties']['name'], 'My Stand', stand_list)

        self.prop1.add(self.stand2)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        stand_list = loads(response.content)
        names = [stand['properties']['name'] for stand in stand_list['features']]
        names.sort()
        expected_names = ['My Stand', 'My Stand2']
        expected_names.sort()
        self.assertEqual(names, expected_names)
Exemplo n.º 19
0
class SpatialTest(TestCase):
    '''
    Tests the spatial representations of Stands and ForestProperties
    '''

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1)
        self.stand2.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)

    def test_rest_defaultkml_url(self):
        self.client.login(username='******', password='******')
        link = self.stand1.options.get_link('KML')
        url = link.reverse(self.stand1)
        response = self.client.get(url)
        errors = kml_errors(response.content)
        self.assertFalse(errors,"invalid KML %s" % str(errors))

    def test_stand_json(self):
        thejson = self.stand1.geojson()
        d = loads(thejson)
        self.assertEquals(d['properties']['name'], 'My Stand')

    def test_property_json(self):
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        self.assertEquals(len(d['features']), 1)
        self.assertEquals(d['features'][0]['properties']['name'], 'My Stand')
        self.prop1.add(self.stand2)
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        self.assertEquals(len(d['features']), 2)

    def test_property_bbox(self):
        thejson = self.prop1.feature_set_geojson()
        d = loads(thejson)
        for x, y in zip(d['bbox'], self.prop1.bbox):
            self.assertAlmostEquals(x, y, places=5)

    def test_stand_json_url(self):
        self.client.login(username='******', password='******')
        link = self.stand1.options.get_link('GeoJSON')
        url = link.reverse(self.stand1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(d['features'][0]['properties']['name'], 'My Stand')

    def test_property_json_url(self):
        self.client.login(username='******', password='******')
        link = self.stand1.options.get_link('GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(d['features'][0]['properties']['name'], 'My Property')

    def test_multistand_json_url(self):
        self.client.login(username='******', password='******')
        uids = [self.stand1.uid, self.stand2.uid]
        link = Stand.get_options().get_link('GeoJSON')
        url = link.reverse([self.stand1, self.stand2])
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(len(d['features']), 2)
        foundit = False
        for f in d['features']:
            if f['properties']['name'] == 'My Stand2':
                foundit = True
        self.assertTrue(foundit)

    def test_property_stands_json_url(self):
        self.prop1.add(self.stand2)
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200, response)
        self.assertTrue('application/json' in response['Content-Type'])
        d = loads(response.content)
        self.assertEquals(len(d['features']), 2)
        foundit = False
        for f in d['features']:
            if f['properties']['name'] == 'My Stand2':
                foundit = True
        self.assertTrue(foundit)
Exemplo n.º 20
0
 def test_add_stand(self):
     stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
     # geometry_final will be set with manipulator
     stand1.save()
Exemplo n.º 21
0
 def test_add_stand(self):
     stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1)
     # geometry_final will be set with manipulator
     stand1.save()
Exemplo n.º 22
0
class PropertyStandListTest(TestCase):
    '''
    test web service to grab json of user's propertie's stands
    [{stand-attrs}, ...]
    '''

    def setUp(self):
        self.client = Client()
        import_rasters()
        self.user = User.objects.create_user(
            'featuretest', '*****@*****.**', password='******')
        self.baduser = User.objects.create_user(
            'baduser', '*****@*****.**', password='******')

        self.stand1 = Stand(user=self.user, name="My Stand", geometry_orig=g1) 
        self.stand1.save()
        self.stand2 = Stand(user=self.user, name="My Stand2", geometry_orig=g1) 
        self.stand2.save()
        self.prop1 = ForestProperty(user=self.user, name="My Property", geometry_final=p1)
        self.prop1.save()
        self.prop1.add(self.stand1)
        enable_sharing()

    def test_unauth(self):
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 401)

    def test_notexists(self):
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        url = url.replace(self.prop1.uid, 'trees_forestproperty_123456789')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_baduser(self):
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 403) 

    def test_jsonlist(self):
        self.client.login(username='******', password='******')
        link = self.prop1.options.get_link('Property Stands GeoJSON')
        url = link.reverse(self.prop1)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200) 
        stand_list = loads(response.content)
        self.assertEquals(stand_list['features'][0]['properties']['name'], 'My Stand', stand_list)

        self.prop1.add(self.stand2)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200) 
        stand_list = loads(response.content)
        names = [stand['properties']['name'] for stand in stand_list['features']]
        names.sort()
        expected_names = ['My Stand', 'My Stand2']
        expected_names.sort()
        self.assertEqual(names, expected_names)
Exemplo n.º 23
0
    def import_ogr(self, shp_path, field_mapping=None, layer_num=0,
                   forest_property=None, new_property_name=None, pre_impute=False):
        ds = DataSource(shp_path)
        layer = ds[0]
        num_features = len(layer)
        field_mapping = self._validate_field_mapping(layer, field_mapping)

        if not forest_property and not new_property_name:
            raise Exception(
                "Must provide either existing forest_property OR new_property_name")

        if new_property_name:
            # Calculating property outline from stands
            stands = []
            for feature in layer:
                stands.append(wkt.loads(feature.geom.wkt))
            casc_poly = cascaded_union(stands)

            if casc_poly.type == 'MultiPolygon':
                polys = []
                for c in casc_poly:
                    # Identify small 'slivers' or areas of empty space b/t polygons that are unintentional
                    # If they're smaller than the threshold, remove them
                    interiors = [x for x in c.interiors if Polygon(
                        x).area > settings.SLIVER_THRESHOLD]
                    polys.append(Polygon(shell=c.exterior, holes=interiors))
            elif casc_poly.type == 'Polygon':
                # Identify small 'slivers' or areas of empty space b/t polygons that are unintentional
                # If they're smaller than the threshold, remove them
                interiors = [x for x in casc_poly.interiors if Polygon(
                    x).area > settings.SLIVER_THRESHOLD]
                polys = [Polygon(shell=casc_poly.exterior, holes=interiors)]

            casc = MultiPolygon(polys)

            # Creating Property
            self.forest_property = ForestProperty.objects.create(
                user=self.user, name=new_property_name, geometry_final=casc.wkt)
        else:
            self.forest_property = forest_property

        stands = []
        for feature in layer:
            stand = Stand(
                user=self.user,
                name=str(datetime_to_unix(datetime.datetime.now())),
                geometry_orig=feature.geom.geos)
                # geometry_final=feature.geom.geos)

            for fname in self.optional_fields:
                if fname in field_mapping.keys():
                    try:
                        stand.__dict__[fname] = feature.get(
                            field_mapping[fname])
                    except OGRIndexError:
                        pass

            stand.full_clean()
            stands.append(stand)
            del stand

        for stand in stands:
            stand.save()
            self.forest_property.add(stand)
            if pre_impute:
                stand.geojson()
Exemplo n.º 24
0
    def import_ogr(self, shp_path, field_mapping=None, layer_num=0,
                   forest_property=None, new_property_name=None, pre_impute=False):
        ds = DataSource(shp_path)
        layer = ds[0]
        num_features = len(layer)
        field_mapping = self._validate_field_mapping(layer, field_mapping)

        if not forest_property and not new_property_name:
            raise Exception(
                "Must provide either existing forest_property OR new_property_name")

        if new_property_name:
            # Calculating property outline from stands
            stands = []
            for feature in layer:
                stands.append(wkt.loads(feature.geom.wkt))
            casc_poly = cascaded_union(stands)

            if casc_poly.type == 'MultiPolygon':
                polys = []
                for c in casc_poly:
                    # Identify small 'slivers' or areas of empty space b/t polygons that are unintentional
                    # If they're smaller than the threshold, remove them
                    interiors = [x for x in c.interiors if Polygon(
                        x).area > settings.SLIVER_THRESHOLD]
                    polys.append(Polygon(shell=c.exterior, holes=interiors))
            elif casc_poly.type == 'Polygon':
                # Identify small 'slivers' or areas of empty space b/t polygons that are unintentional
                # If they're smaller than the threshold, remove them
                interiors = [x for x in casc_poly.interiors if Polygon(
                    x).area > settings.SLIVER_THRESHOLD]
                polys = [Polygon(shell=casc_poly.exterior, holes=interiors)]

            casc = MultiPolygon(polys)

            # Creating Property
            self.forest_property = ForestProperty.objects.create(
                user=self.user, name=new_property_name, geometry_final=casc.wkt)
        else:
            self.forest_property = forest_property

        try:
            # special case for user-inventory situation
            # if there is a condid field, it is implicitly required.
            use_condid = False
            if 'condid' in layer.fields:
                use_condid = True
                variant = self.forest_property.variant
                valid_condids = FVSAggregate.valid_condids(variant)

            stands = []
            stratum = {}
            for feature in layer:
                stand = Stand(
                    user=self.user,
                    name=str(datetime_to_unix(datetime.datetime.now())),
                    geometry_orig=feature.geom.geos)

                for fname in self.optional_fields:
                    if fname in field_mapping.keys():
                        try:
                            stand.__dict__[fname] = feature.get(
                                field_mapping[fname])
                        except OGRIndexError:
                            pass

                # If user inventory case, check each feature which must contain integer condids
                # that refer to valid fvsaggregate records for that variant
                if use_condid:
                    condid = feature.get('condid')

                    if condid not in valid_condids:
                        raise Exception('Condition id {} is not valid for the {} variant (check fvsaggregate table)'.format(condid, variant))

                    if condid in stratum.keys():
                        # use cached
                        strata = stratum[condid]
                    else:
                        # create it
                        kwargs = condid_strata(condid, self.forest_property.uid)
                        strata = Strata(user=self.user, name=condid, **kwargs)
                        strata.save(skip_validation=True)  # no need for NN validation
                        self.forest_property.add(strata)
                        stratum[condid] = strata

                    stand.cond_id = condid
                    stand.locked_cond_id = condid
                    stand.strata = strata

                stand.full_clean()
                stands.append(stand)
                del stand

            for stand in stands:
                stand.save()
                self.forest_property.add(stand)
                if pre_impute:
                    # Technically locked stands won't need terrain variables
                    # ... but terrain info is nice to have anyways for all stands.
                    # Note the work is done asynchronously to ensure fast uploads
                    stand.preimpute()
        except:
            # Any failures? Rollback and re-raise...
            for stand in stands:
                stand.delete()
            if new_property_name:
                self.forest_property.delete()
            raise

        return True