示例#1
0
    def test_contribution_set_frozen_during_rank_computation(self):
        contributor = ContributorFactory()
        country = CountryFactory()

        self.assertEqual(Contribution.objects.count(), 0)

        for i in range(3):
            self.create_contribution(contributor, country)

        self.assertEqual(Contribution.objects.count(), 3)

        contributions = list(Contribution.objects.all().select_related())
        self.assertEqual(Contribution.objects.count(), 3)

        for i in range(3):
            self.create_contribution(contributor, country)

        self.assertEqual(Contribution.objects.count(), 6)

        ContributorRank._compute_ranks(contributions)

        self.assertEqual(
            ContributorRank.objects.get(contributor=contributor,
                                        country=None).observations, 3)
        self.assertEqual(Contribution.objects.count(), 3)
    def test_leaderboard_is_paginated(self):
        today = datetime.date.today()
        country = CountryFactory()
        page_size = settings.REST_FRAMEWORK['PAGE_SIZE']

        for i in range(page_size + 1):
            contributor = ContributorFactory()
            Contribution(
                contributor=contributor,
                date=today,
                observations=1,
                point=country.geometry.point_on_surface,
            ).save()

        # Create the contributor ranks
        ContributorRank.compute_ranks()

        response = self.client.get(reverse('leaders-global-list'))
        self.assertEqual(response.status_code, 200)

        contributors_data = json.loads(response.content)
        self.assertEqual(len(contributors_data['results']), page_size)

        response = self.client.get(
            reverse('leaders-global-list'),
            {'offset': page_size},
        )
        self.assertEqual(response.status_code, 200)

        contributors_data = json.loads(response.content)
        self.assertEqual(len(contributors_data['results']), 1)
    def test_compute_ranks_matches_point_to_nearest_country(self):
        contributor = ContributorFactory()

        # Create a dummy country to find a point outside existing countries
        dummy_country = CountryFactory()
        point_outside_countries = dummy_country.geometry.point_on_surface
        dummy_country.delete()

        # The point is outside all existing countries
        self.assertFalse(
            Country.objects.filter(
                geometry__contains=point_outside_countries).exists())

        # The point is closer to country2
        self.assertGreater(
            self.country1.geometry.distance(point_outside_countries),
            self.country2.geometry.distance(point_outside_countries),
        )

        ContributionFactory(
            contributor=contributor, point=point_outside_countries)

        self.assertFalse(
            ContributorRank.objects.filter(contributor=contributor).exists())

        ContributorRank.compute_ranks()

        self.assertTrue(
            ContributorRank.objects.filter(
                contributor=contributor, country=self.country2).exists())

        self.assertFalse(
            ContributorRank.objects.filter(
                contributor=contributor, country=self.country1).exists())
    def setUp(self):
        # There are two countries
        self.country1 = CountryFactory()
        self.country2 = CountryFactory()

        # And there are three contributors
        self.contributor1 = ContributorFactory()
        self.contributor2 = ContributorFactory()

        # Contributor3 makes no contributions
        self.contributor3 = ContributorFactory()

        # Contributor1 contributes 2 times to self.country1
        for i in range(2):
            self.create_contribution(self.contributor1, self.country1)

        # Contributor1 contributes 5 times to self.country2
        for i in range(5):
            self.create_contribution(self.contributor1, self.country2)

        # Contributor2 contributes 3 times to self.country1
        for i in range(3):
            self.create_contribution(self.contributor2, self.country1)

        # Contributor2 contributes 3 times to self.country2
        for i in range(3):
            self.create_contribution(self.contributor2, self.country2)

        # Compute the global and country ranks
        ContributorRank.compute_ranks()
示例#5
0
    def test_compute_ranks_matches_point_to_nearest_country(self):
        contributor = ContributorFactory()

        # Create a dummy country to find a point outside existing countries
        dummy_country = CountryFactory()
        point_outside_countries = dummy_country.geometry.point_on_surface
        dummy_country.delete()

        # The point is outside all existing countries
        self.assertFalse(
            Country.objects.filter(
                geometry__contains=point_outside_countries).exists())

        # The point is closer to country2
        self.assertGreater(
            self.country1.geometry.distance(point_outside_countries),
            self.country2.geometry.distance(point_outside_countries),
        )

        ContributionFactory(contributor=contributor,
                            point=point_outside_countries)

        self.assertFalse(
            ContributorRank.objects.filter(contributor=contributor).exists())

        ContributorRank.compute_ranks()

        self.assertTrue(
            ContributorRank.objects.filter(contributor=contributor,
                                           country=self.country2).exists())

        self.assertFalse(
            ContributorRank.objects.filter(contributor=contributor,
                                           country=self.country1).exists())
示例#6
0
    def setUp(self):
        # There are two countries
        self.country1 = CountryFactory()
        self.country2 = CountryFactory()

        # And there are three contributors
        self.contributor1 = ContributorFactory()
        self.contributor2 = ContributorFactory()

        # Contributor3 makes no contributions
        self.contributor3 = ContributorFactory()

        # Contributor1 contributes 2 times to self.country1
        for i in range(2):
            self.create_contribution(self.contributor1, self.country1)

        # Contributor1 contributes 5 times to self.country2
        for i in range(5):
            self.create_contribution(self.contributor1, self.country2)

        # Contributor2 contributes 3 times to self.country1
        for i in range(3):
            self.create_contribution(self.contributor2, self.country1)

        # Contributor2 contributes 3 times to self.country2
        for i in range(3):
            self.create_contribution(self.contributor2, self.country2)

        # Compute the global and country ranks
        ContributorRank.compute_ranks()
    def test_sums_for_each_contributor_and_orders_by_observations(self):
        today = datetime.date.today()

        country1 = CountryFactory()
        country2 = CountryFactory()

        contributor1 = ContributorFactory()

        for i in range(3):
            Contribution(
                contributor=contributor1,
                date=today,
                observations=1,
                point=country1.geometry.point_on_surface,
            ).save()

        contributor2 = ContributorFactory()

        for i in range(4):
            Contribution(
                contributor=contributor2,
                date=today,
                observations=1,
                point=country2.geometry.point_on_surface,
            ).save()

        # Create a contributor with no contributions
        # who should not appearin the leaderboard
        ContributorFactory()

        # Create the contributor ranks
        ContributorRank.compute_ranks()

        response = self.client.get(reverse('leaders-global-list'))
        self.assertEqual(response.status_code, 200)

        contributors_data = json.loads(response.content)
        self.assertEqual(contributors_data, {
            'count': 2,
            'previous': None,
            'results': [
                {
                    'uid': contributor2.uid,
                    'name': contributor2.name,
                    'observations': 4,
                    'rank': 1,
                }, {
                    'uid': contributor1.uid,
                    'name': contributor1.name,
                    'observations': 3,
                    'rank': 2,
                }
            ],
            'next': None,
        })
    def test_filters_by_country(self):
        today = datetime.date.today()

        contributor = ContributorFactory()

        country1 = CountryFactory()
        country2 = CountryFactory()

        contribution1 = Contribution(
            contributor=contributor,
            date=today,
            observations=1,
            point=country1.geometry.point_on_surface,
        )
        contribution1.save()

        contribution2 = Contribution(
            contributor=contributor,
            date=today,
            observations=1,
            point=country1.geometry.point_on_surface,
        )
        contribution2.save()

        contribution3 = Contribution(
            contributor=contributor,
            date=today,
            observations=1,
            point=country2.geometry.point_on_surface,
        )
        contribution3.save()

        # Create the contributor ranks
        ContributorRank.compute_ranks()

        response = self.client.get(
            reverse(
                'leaders-country-list',
                kwargs={'country_id': country1.iso2}
            )
        )
        self.assertEqual(response.status_code, 200)

        contributors_data = json.loads(response.content)
        self.assertEqual(contributors_data, {
            'count': 1,
            'previous': None,
            'results': [{
                'uid': contributor.uid,
                'name': contributor.name,
                'observations': 2,
                'rank': 1,
            }],
            'next': None,
        })
    def test_compute_ranks_removes_observations_when_complete(self):
        self.assertEqual(Contribution.objects.count(), 0)

        for i in range(3):
            self.create_contribution(self.contributor1, self.country1)

        self.assertEqual(Contribution.objects.count(), 3)

        ContributorRank.compute_ranks()

        self.assertEqual(Contribution.objects.count(), 0)
示例#10
0
    def test_compute_ranks_removes_observations_when_complete(self):
        self.assertEqual(Contribution.objects.count(), 0)

        for i in range(3):
            self.create_contribution(self.contributor1, self.country1)

        self.assertEqual(Contribution.objects.count(), 3)

        ContributorRank.compute_ranks()

        self.assertEqual(Contribution.objects.count(), 0)
示例#11
0
    def test_new_contributions_updates_existing_ranks(self):
        self.assertEqual(ContributorRank.objects.count(), 6)

        self.create_contribution(self.contributor1, self.country1)

        ContributorRank.compute_ranks()

        self.assertEqual(ContributorRank.objects.count(), 6)
        rank = ContributorRank.objects.get(contributor=self.contributor1,
                                           country=self.country1)

        self.assertEqual(rank.observations, 3)
示例#12
0
    def test_get_leader_profile_returns_ranks_and_observations(self):
        today = datetime.date.today()

        contributor = ContributorFactory()

        country1 = CountryFactory()
        country2 = CountryFactory()

        for country in (country1, country2):
            for i in range(3):
                Contribution.objects.create(
                    contributor=contributor,
                    date=today,
                    observations=1,
                    point=country.geometry.point_on_surface,
                )

        # Create the contributor ranks
        ContributorRank.compute_ranks()

        response = self.client.get(
            reverse(
                'leaders-profile',
                kwargs={'uid': contributor.uid},
            ),
        )

        self.assertEqual(response.status_code, 200)
        profile_data = json.loads(response.content)
        self.assertEqual(profile_data['uid'], contributor.uid)
        self.assertEqual(profile_data['name'], contributor.name)
        self.assertEqual(len(profile_data['ranks']), 3)
        self.assertIn({
            'country': None,
            'observations': 6,
            'rank': 1
        }, profile_data['ranks'])
        self.assertIn({
            'country': {
                'iso2': country1.iso2,
                'name': country1.name,
            },
            'observations': 3,
            'rank': 1
        }, profile_data['ranks'])
        self.assertIn({
            'country': {
                'iso2': country2.iso2,
                'name': country2.name,
            },
            'observations': 3,
            'rank': 1
        }, profile_data['ranks'])
    def test_new_contributions_updates_existing_ranks(self):
        self.assertEqual(ContributorRank.objects.count(), 6)

        self.create_contribution(self.contributor1, self.country1)

        ContributorRank.compute_ranks()

        self.assertEqual(ContributorRank.objects.count(), 6)
        rank = ContributorRank.objects.get(
            contributor=self.contributor1, country=self.country1)

        self.assertEqual(rank.observations, 3)
    def test_compute_ranks_updates_existing_ranks(self):
        self.assertEqual(ContributorRank.objects.get(
            country=None, contributor=self.contributor1).rank, 1)
        self.assertEqual(ContributorRank.objects.get(
            country=None, contributor=self.contributor2).rank, 2)

        ContributionFactory(contributor=self.contributor2, observations=10)

        ContributorRank.compute_ranks()

        self.assertEqual(ContributorRank.objects.get(
            country=None, contributor=self.contributor1).rank, 2)
        self.assertEqual(ContributorRank.objects.get(
            country=None, contributor=self.contributor2).rank, 1)
    def test_list_countries_returns_country_data(self):
        today = datetime.date.today()

        countries = [CountryFactory() for i in range(3)]

        # A country with no contributions should not appear
        # in the results
        CountryFactory()

        for country in countries:
            for contributor_i in range(3):
                contributor = ContributorFactory()

                for contribution_i in range(10):
                    Contribution.objects.create(
                        contributor=contributor,
                        country=country,
                        date=today,
                        observations=1,
                    )

        ContributorRank.compute_ranks()

        response = self.client.get(reverse('countries-list'))

        self.assertEqual(response.status_code, 200)

        countries_data = json.loads(response.content)
        self.assertEqual(len(countries_data), len(countries))

        for country in countries:
            self.assertIn(
                {
                    'iso2':
                    country.iso2,
                    'name':
                    country.name,
                    'observations':
                    30,
                    'leaders_url':
                    reverse(
                        'leaders-country-list',
                        kwargs={'country_id': country.iso2},
                    ),
                }, countries_data)
示例#16
0
    def test_compute_ranks_updates_existing_ranks(self):
        self.assertEqual(
            ContributorRank.objects.get(country=None,
                                        contributor=self.contributor1).rank, 1)
        self.assertEqual(
            ContributorRank.objects.get(country=None,
                                        contributor=self.contributor2).rank, 2)

        ContributionFactory(contributor=self.contributor2, observations=10)

        ContributorRank.compute_ranks()

        self.assertEqual(
            ContributorRank.objects.get(country=None,
                                        contributor=self.contributor1).rank, 2)
        self.assertEqual(
            ContributorRank.objects.get(country=None,
                                        contributor=self.contributor2).rank, 1)
示例#17
0
    def test_list_countries_returns_country_data(self):
        today = datetime.date.today()

        countries = [CountryFactory() for i in range(3)]

        # A country with no contributions should not appear
        # in the results
        CountryFactory()

        for country in countries:
            for contributor_i in range(3):
                contributor = ContributorFactory()

                for contribution_i in range(10):
                    Contribution.objects.create(
                        contributor=contributor,
                        point=country.geometry.point_on_surface,
                        date=today,
                        observations=1,
                    )

        ContributorRank.compute_ranks()

        response = self.client.get(reverse('countries-list'))

        self.assertEqual(response.status_code, 200)

        countries_data = json.loads(response.content)
        self.assertEqual(len(countries_data), len(countries))

        for country in countries:
            self.assertIn({
                'iso2': country.iso2,
                'name': country.name,
                'observations': 30,
                'leaders_url': reverse(
                    'leaders-country-list',
                    kwargs={'country_id': country.iso2},
                ),
            }, countries_data)
    def test_contribution_set_frozen_during_rank_computation(self):
        contributor = ContributorFactory()
        country = CountryFactory()

        self.assertEqual(Contribution.objects.count(), 0)

        for i in range(3):
            self.create_contribution(contributor, country)

        self.assertEqual(Contribution.objects.count(), 3)

        contributions = list(Contribution.objects.all().select_related())
        self.assertEqual(Contribution.objects.count(), 3)

        for i in range(3):
            self.create_contribution(contributor, country)

        self.assertEqual(Contribution.objects.count(), 6)

        ContributorRank._compute_ranks(contributions)

        self.assertEqual(ContributorRank.objects.get(
            contributor=contributor, country=None).observations, 3)
        self.assertEqual(Contribution.objects.count(), 3)
示例#19
0
 def handle(self, *args, **options):
     ContributorRank.compute_ranks()