Skip to content

Commit

Permalink
REF: Make duration a property of AbstractQuestion
Browse files Browse the repository at this point in the history
  • Loading branch information
cortadocodes committed Feb 7, 2024
1 parent 2ab715f commit 47da2bf
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
9 changes: 0 additions & 9 deletions django_twined/admin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,6 @@ def result(obj):
"""
return obj.result.data

@staticmethod
def duration(obj):
"""Show the time it took to answer the question in seconds.
:return int|None:
"""
if obj.answered and obj.asked:
return (obj.answered - obj.asked).seconds

def ask_question(self, obj):
"""Override this to ask a question using an async task queue or other method. This will ask the question directly."""
obj.ask()
Expand Down
9 changes: 9 additions & 0 deletions django_twined/models/questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ def status_message(self):
"""
return STATUS_MESSAGE_MAP[self.status]

@property
def duration(self):
"""Show the time it took to answer the question in seconds.
:return int|None:
"""
if self.answered and self.asked:
return (self.answered - self.asked).seconds

def get_duplicate(self, save=True):
"""Duplicate the question instance and optionally save to the database"""
kwargs = {}
Expand Down
23 changes: 23 additions & 0 deletions tests/test_models/test_questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# pylint: disable=missing-docstring
# pylint: disable=protected-access
# pylint: disable=too-many-public-methods
import datetime
import os
import time
from unittest import skipIf
from unittest.mock import patch

Expand All @@ -18,6 +20,12 @@


class QuestionTestCase(TestCase):
def test_unasked_question_duration(self):
"""Test that the duration of an unasked question is `None`."""
sr = ServiceRevision.objects.create(name="test-service")
q = QuestionWithValuesDatabaseStorage.objects.create(service_revision=sr)
self.assertIsNone(q.duration)

@patch("django_twined.models.ServiceRevision.ask", return_value=("subscription", "question_uuid"))
def test_ask_question(self, mock):
"""Ensures that a question can be asked"""
Expand All @@ -32,6 +40,21 @@ def test_ask_question(self, mock):
self.assertIn("input_manifest", mock.call_args.kwargs)
self.assertIn("question_attribute", mock.call_args.kwargs["input_values"])

# Check that the duration is `None` as the question hasn't been answered.
self.assertIsNone(q.duration)

@patch("django_twined.models.ServiceRevision.ask", return_value=("subscription", "question_uuid"))
def test_answered_question_duration(self, mock):
"""Test that the duration of an answered question is a non-zero integer."""
sr = ServiceRevision.objects.create(name="test-service")
q = QuestionWithValuesDatabaseStorage.objects.create(service_revision=sr)
q.input_values = {"question_attribute": "1"}
q.ask()

time.sleep(1)
q.answered = datetime.datetime.now(tz=datetime.timezone.utc)
self.assertTrue(q.duration > 0)

def test_input_values_get_saved(self):
"""Ensures that input values get saved on the mixin.
I'm testing this because the objects.create() doesn't accept the input_values
Expand Down

0 comments on commit 47da2bf

Please sign in to comment.