Example #1
0
    def test_sync_no_push_deleted_nest(self):
        """
        An observation that was deleted on vespawatch before it was synced to iNaturalist should not be deleted on
        iNaturalist
        """

        # Create an Individual that already exists in iNaturalist after a previous push
        nest = Individual(latitude=51.2003,
                          longitude=4.9067,
                          observation_time=datetime(2019, 4, 1, 10),
                          originates_in_vespawatch=True,
                          taxon=self.vv_taxon)
        nest.save()
        nest.delete(
        )  # When the observation is deleted, it is deleted without creating a InatObsToDelete object

        self.assertEqual(len(InatObsToDelete.objects.all()), 0)

        # Now a sync is called. Since there are no InatObsToDelete, the delete_mock is never called
        call_command('inaturalist_sync')
        self.delete_mock.assert_not_called()
Example #2
0
    def test_sync_push_deleted_obs_doesnt_exist(self):
        """
        Pyinaturalist will raise a ObservationNotFound exception when you try to delete an observation
        that does not exist on iNaturalist.
        Make sure we catch that and properly handle it (delete the observation locally since it's
        already gone on iNaturalist)
        """
        # Create an Individual that already exists in iNaturalist after a previous push
        ind = Individual(inaturalist_id=30,
                         latitude=51.2003,
                         longitude=4.9067,
                         observation_time=datetime(2019, 4, 1, 10),
                         originates_in_vespawatch=True,
                         taxon=self.vv_taxon)
        ind.save()

        # Now delete it
        ind.delete()

        self.assertEqual(len(InatObsToDelete.objects.all()), 1)

        # Set a return value for the self.get_all_mock. It should return no observations
        self.get_all_mock.return_value = []

        # Set a side effect for the self.get_obs_mock. It should raise a ObservationNotFound exception
        self.delete_mock.side_effect = ObservationNotFound()

        # Run inaturalist sync.
        call_command('inaturalist_sync')
        self.assertEqual(len(InatObsToDelete.objects.all()), 0)


# TODO add tests for pulling and checking taxon id (first community taxon, then taxon)
# TODO check update description
# TODO check update date
# TODO check update taxon
Example #3
0
    def test_sync_push_deleted_indiv(self):
        """
        An observation that was created in vespawatch and deleted in vespawatch after it was synced, should be
        deleted on iNaturalist
        """

        # Create an Individual that already exists in iNaturalist after a previous push
        ind = Individual(inaturalist_id=30,
                         latitude=51.2003,
                         longitude=4.9067,
                         observation_time=datetime(2019, 4, 1, 10),
                         originates_in_vespawatch=True,
                         taxon=self.vv_taxon)
        ind.save()
        ind.delete(
        )  # When the observation is deleted, it is actually added to the InatObsToDelete table

        self.assertEqual(len(InatObsToDelete.objects.all()), 1)
        self.assertEqual(InatObsToDelete.objects.all()[0].inaturalist_id, 30)

        # Now a sync is called. The InatObsToDelete observation is deleted on iNaturalist and removed from the db
        call_command('inaturalist_sync')
        self.delete_mock.assert_called_once_with(observation_id=30,
                                                 access_token='TESTTOKEN')
Example #4
0
    def test_sync_pull_obs_taxon_changed_twice(self):
        """
        We have an observation in our database with a iNaturalist ID, but when we pull from the iNaturalist API
        this observation is not returned.
        So we check the observation individually and in this case we conclude the taxon is not known in our database
        We flag it as "unknown taxon". On a next pull, the taxon is again changed at iNaturalist, this time back
        to a taxon that is known. We should make sure the taxon is changed again
        (this test was added to fix issue #264)
        """
        # Create an Individual that already exists in iNaturalist after a previous push
        ind = Individual(inaturalist_id=30,
                         latitude=51.2003,
                         longitude=4.9067,
                         observation_time=datetime(2019, 4, 1, 10),
                         originates_in_vespawatch=True,
                         taxon=self.vv_taxon)
        ind.save()

        # Set a return value for the self.get_all_mock. It should return no observations
        self.get_all_mock.return_value = []

        # Set a side effect for the self.get_obs_mock. It should return an observation that has no vespawatch project id
        get_obs_mock_value = {
            'id': 30,
            'taxon': {
                'id': 2732,
                'name': 'Unknown taxon'
            },
            'description': '',
            'geojson': {
                'coordinates': [10, 20]
            },
            'observed_on_string': '2019-04-01T11:20:00+00:00',
            'observed_time_zone': 'Europe/Brussels',
            'photos': [],
            'project_ids': [11]  # some random project
        }
        self.get_obs_mock.return_value = get_obs_mock_value

        # Assert that the individual had no warning before the sync
        self.assertEqual(
            len(
                Individual.objects.filter(
                    inaturalist_id=30)[0].warnings.all()), 0)
        # Run inaturalist sync.
        call_command('inaturalist_sync')
        # Assert that the individual has a warning now
        self.assertEqual(
            len(
                Individual.objects.filter(
                    inaturalist_id=30)[0].warnings.all()), 2)
        warning_texts = sorted([
            x.text for x in Individual.objects.filter(
                inaturalist_id=30)[0].warnings.all()
        ])
        self.assertEqual(warning_texts[0], 'not in vespawatch project')
        self.assertEqual(warning_texts[1], 'unknown taxon')
        # Assert that the inaturalist_species field was set to the taxon name
        self.assertEqual(
            Individual.objects.filter(
                inaturalist_id=30)[0].inaturalist_species, 'Unknown taxon')

        # Now, assume that on a next pull the taxon is changed again to a known taxon
        get_obs_mock_value['taxon'][
            'id'] = self.other_taxon.inaturalist_pull_taxon_ids[0]
        get_obs_mock_value['taxon']['name'] = 'known taxon'
        call_command('inaturalist_sync')
        self.assertEqual(
            Individual.objects.filter(
                inaturalist_id=30)[0].inaturalist_species, '')
        self.assertEqual(
            Individual.objects.filter(
                inaturalist_id=30)[0].taxon.inaturalist_push_taxon_id, 2)