diff --git a/stats/models.py b/stats/models.py index c7466b26..bac0060b 100644 --- a/stats/models.py +++ b/stats/models.py @@ -26,6 +26,27 @@ def for_question(self, question_id): def from_quiz(self): return self.filter(source=constants.QUESTION_SOURCE_QUIZ) + def agg_count( + self, + since="total", + week_or_month_iso_number=None, + year=None, + ): + queryset = self + # since + if since not in constants.AGGREGATION_SINCE_CHOICE_LIST: + raise ValueError(f"DailyStat agg_count: must be one of {constants.AGGREGATION_SINCE_CHOICE_LIST}") + if since == "last_30_days": + queryset = queryset.filter(created__date__gte=(date.today() - timedelta(days=30))) + if since == "month": + queryset = queryset.filter(created__month=week_or_month_iso_number) + elif since == "week": + queryset = queryset.filter(created__week=week_or_month_iso_number) + if year: + queryset = queryset.filter(created__year=year) + # field + return queryset.count() + def agg_timeseries(self): queryset = self queryset = ( @@ -109,6 +130,27 @@ def for_quiz(self, quiz_id): def last_30_days(self): return self.filter(created__date__gte=(date.today() - timedelta(days=30))) + def agg_count( + self, + since="total", + week_or_month_iso_number=None, + year=None, + ): + queryset = self + # since + if since not in constants.AGGREGATION_SINCE_CHOICE_LIST: + raise ValueError(f"DailyStat agg_count: must be one of {constants.AGGREGATION_SINCE_CHOICE_LIST}") + if since == "last_30_days": + queryset = queryset.filter(created__date__gte=(date.today() - timedelta(days=30))) + if since == "month": + queryset = queryset.filter(created__month=week_or_month_iso_number) + elif since == "week": + queryset = queryset.filter(created__week=week_or_month_iso_number) + if year: + queryset = queryset.filter(created__year=year) + # field + return queryset.count() + def agg_timeseries(self, scale="day"): queryset = self # scale diff --git a/stats/tests/test_models.py b/stats/tests/test_models.py index 0dba70cc..0089967b 100644 --- a/stats/tests/test_models.py +++ b/stats/tests/test_models.py @@ -1,4 +1,7 @@ +from datetime import timedelta + from django.test import TestCase +from django.utils import timezone from core import constants from questions.factories import QuestionFactory @@ -15,6 +18,9 @@ ) +datetime_50_days_ago = timezone.now() - timedelta(days=50) + + class QuestionStatTest(TestCase): @classmethod def setUpTestData(cls): @@ -28,9 +34,16 @@ def setUpTestData(cls): cls.question_rm_1 = QuestionFactory(type=constants.QUESTION_TYPE_QCM_RM, answer_correct="ab") cls.question_rm_2 = QuestionFactory(type=constants.QUESTION_TYPE_QCM_RM, answer_correct="abc") cls.question_rm_3 = QuestionFactory(type=constants.QUESTION_TYPE_QCM_RM, answer_correct="abcd") - QuestionAnswerEvent.objects.create(question_id=cls.question_rm_1.id, choice="cd", source="question") + QuestionAnswerEvent.objects.create( + question_id=cls.question_rm_1.id, choice="cd", source="question", created=datetime_50_days_ago + ) cls.question_vf = QuestionFactory(type=constants.QUESTION_TYPE_VF, answer_correct="b") + def test_question_answer_event_agg_count(self): + self.assertEqual(QuestionAnswerEvent.objects.count(), 2) + self.assertEqual(QuestionAnswerEvent.objects.agg_count(), 2) + self.assertEqual(QuestionAnswerEvent.objects.agg_count("last_30_days"), 1) + def test_question_agg_stat_created(self): self.assertEqual(Question.objects.count(), 1 + 3 + 1) self.assertEqual(QuestionAggStat.objects.count(), 1 + 3 + 1) @@ -54,9 +67,14 @@ def setUpTestData(cls): cls.quiz_1 = QuizFactory(name="quiz 1") # questions=[cls.question_1.id] QuizQuestion.objects.create(quiz=cls.quiz_1, question=cls.question_1) QuestionAnswerEvent.objects.create(question_id=cls.question_1.id, choice="a", source="question") - QuizAnswerEvent.objects.create(quiz_id=cls.quiz_1.id, answer_success_count=1) + QuizAnswerEvent.objects.create(quiz_id=cls.quiz_1.id, answer_success_count=1, created=datetime_50_days_ago) QuizFeedbackEvent.objects.create(quiz_id=cls.quiz_1.id, choice="dislike") + def test_quiz_answer_event_agg_count(self): + self.assertEqual(QuizAnswerEvent.objects.count(), 1) + self.assertEqual(QuizAnswerEvent.objects.agg_count(), 1) + self.assertEqual(QuizAnswerEvent.objects.agg_count("last_30_days"), 0) + def test_answer_count(self): self.assertEqual(self.quiz_1.answer_count_agg, 1)