diff --git a/django/website/transport/taxonomies.py b/django/website/transport/taxonomies.py index 7016ad9e4ac39292ee1cc71d8513aea21a9f626c..f5b98dcdefc1303aa6241be5b279deee89156ec4 100644 --- a/django/website/transport/taxonomies.py +++ b/django/website/transport/taxonomies.py @@ -5,7 +5,7 @@ from rest_framework.test import APIRequestFactory from rest_framework import status from .exceptions import TransportException - +from .terms import list as terms_list request_factory = APIRequestFactory() @@ -34,13 +34,38 @@ def list(**kwargs): return view(request).data -def term_itemcount(slug): +def _add_zero_counts_for_missing_terms(slug, itemcounts): + # We want to return zero counts for terms that fall outside the date range, + # which the API doesn't do for us. So we need to get all the terms for the + # taxonomy and set any that aren't in the date range results to count: 0 + all_terms = terms_list(taxonomy=slug) + + itemcounts_by_name = {t['name']: t for t in itemcounts} + + new_itemcounts = [] + + for term in all_terms: + if term['name'] not in itemcounts_by_name: + term['count'] = 0 + else: + term = itemcounts_by_name[term['name']] + + new_itemcounts.append(term) + + return new_itemcounts + + +def term_itemcount(slug, **kwargs): view = get_view(actions={'get': 'itemcount'}) - request = request_factory.get(itemcount_url(slug)) + request = request_factory.get(itemcount_url(slug), + kwargs) response = view(request, slug=slug) - if status.is_success(response.status_code): + if not status.is_success(response.status_code): + response.data['status_code'] = response.status_code + raise TransportException(response.data) + + if 'start_time' not in kwargs or 'end_time' not in kwargs: return response.data - response.data['status_code'] = response.status_code - raise TransportException(response.data) + return _add_zero_counts_for_missing_terms(slug, response.data) diff --git a/django/website/transport/tests/taxonomy_term_itemcount_tests.py b/django/website/transport/tests/taxonomy_term_itemcount_tests.py index c3e99f5279e4297dbe40d9eb1da115a617e55235..dceecfcb04d5d322da34c907c54957a25a545355 100644 --- a/django/website/transport/tests/taxonomy_term_itemcount_tests.py +++ b/django/website/transport/tests/taxonomy_term_itemcount_tests.py @@ -1,6 +1,10 @@ from __future__ import unicode_literals, absolute_import + +from datetime import timedelta import pytest +from django.utils import timezone + from taxonomies.tests.factories import ( TaxonomyFactory, TermFactory, @@ -10,16 +14,23 @@ import transport from ..exceptions import TransportException +def time_now(): + return timezone.now().replace( + microsecond=0 # MySQL discards microseconds + ) + + @pytest.fixture -def item_data(): - item = {'body': "What is the cuse of ebola?"} +def item_data(**kwargs): + item = kwargs + item['body'] = "What is the cuse of ebola?" return transport.items.create(item) @pytest.fixture def questions_category(): # TODO: Replace with transport call when we have one - return TaxonomyFactory(name="Ebola Questions") + return TaxonomyFactory(name="Test Ebola Questions") @pytest.fixture @@ -54,3 +65,58 @@ def test_itemcount_fails_if_taxonomy_does_not_exist(item_data): assert error['status_code'] == 400 assert error['detail'] == "Taxonomy with slug 'a-taxonomy-that-does-not-exist' does not exist." + + +@pytest.mark.django_db +def test_term_itemcount_returns_terms_and_counts_for_range( + questions_category, + questions_term): + + now = time_now() + + items = [item_data(timestamp=now - timedelta(days=d)) for d in range(0, 9)] + + for item in items: + transport.items.add_term(item['id'], + questions_category.slug, + questions_term.name) + + # 9 8 7 6 5 4 3 2 1 0 + # n y y y y y y y n n + start_time = now - timedelta(days=8) + end_time = now - timedelta(days=2) + + [term] = transport.taxonomies.term_itemcount( + slug=questions_category.slug, + start_time=start_time, + end_time=end_time) + + assert term['count'] == 7 + + +@pytest.mark.django_db +def test_term_itemcount_returns_zero_term_counts_for_range( + questions_category, + questions_term): + + now = time_now() + one_day_ago = now - timedelta(days=1) + one_week_ago = now - timedelta(weeks=1) + eight_days_ago = now - timedelta(days=8) + + item_too_recent = item_data(timestamp=now) + item_too_old = item_data(timestamp=eight_days_ago) + + transport.items.add_term(item_too_recent['id'], + questions_category.slug, + questions_term.name) + transport.items.add_term(item_too_old['id'], + questions_category.slug, + questions_term.name) + + [term] = transport.taxonomies.term_itemcount( + slug=questions_category.slug, + start_time=one_week_ago, + end_time=one_day_ago) + + assert term['count'] == 0