From dda77ed6e22528e26bfaf75ebe0f2deabaa8bb3c Mon Sep 17 00:00:00 2001 From: John Labbate <90406009+john-labbate@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:04:12 -0400 Subject: [PATCH] Feature/549 response tracking (#641) * Track user quiz question responses. * Update tests. --- ...328fd0a_add_results_to_quiz_completions.py | 32 +++++++++++++++++++ training/models/quiz_completion.py | 2 ++ training/repositories/quiz_completion.py | 3 +- training/schemas/quiz_completion.py | 2 ++ training/services/quiz.py | 3 ++ .../tests/test_quiz_completion_repository.py | 3 +- 6 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 alembic/versions/12049328fd0a_add_results_to_quiz_completions.py diff --git a/alembic/versions/12049328fd0a_add_results_to_quiz_completions.py b/alembic/versions/12049328fd0a_add_results_to_quiz_completions.py new file mode 100644 index 00000000..f91f4ded --- /dev/null +++ b/alembic/versions/12049328fd0a_add_results_to_quiz_completions.py @@ -0,0 +1,32 @@ +"""add results to quiz completions + +Revision ID: 12049328fd0a +Revises: 291331bea272 +Create Date: 2024-09-11 10:23:37.753893 + +""" +from alembic import op +from sqlalchemy.dialects import postgresql +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '12049328fd0a' +down_revision = '291331bea272' +branch_labels = None +depends_on = None + + +def upgrade(): + # Add the 'responses' column + op.add_column('quiz_completions', sa.Column( + 'responses', + postgresql.JSONB(astext_type=sa.Text()), + nullable=False, + server_default=sa.text("'{}'::jsonb") + )) + + +def downgrade(): + # Remove the 'responses' column + op.drop_column('quiz_completions', 'responses') diff --git a/training/models/quiz_completion.py b/training/models/quiz_completion.py index dc92ed8a..28002643 100644 --- a/training/models/quiz_completion.py +++ b/training/models/quiz_completion.py @@ -2,6 +2,7 @@ from training.models import Base from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy import ForeignKey, func +from typing import Any class QuizCompletion(Base): @@ -12,3 +13,4 @@ class QuizCompletion(Base): user_id: Mapped[int] = mapped_column(ForeignKey("users.id")) passed: Mapped[bool] = mapped_column() submit_ts: Mapped[datetime] = mapped_column(server_default=func.now()) + responses: Mapped[dict[str, Any]] = mapped_column() diff --git a/training/repositories/quiz_completion.py b/training/repositories/quiz_completion.py index 6caee0c7..f3efb211 100644 --- a/training/repositories/quiz_completion.py +++ b/training/repositories/quiz_completion.py @@ -12,5 +12,6 @@ def create(self, quiz_completion: schemas.QuizCompletionCreate) -> models.QuizCo return self.save(models.QuizCompletion( quiz_id=quiz_completion.quiz_id, user_id=quiz_completion.user_id, - passed=quiz_completion.passed + passed=quiz_completion.passed, + responses=quiz_completion.responses )) diff --git a/training/schemas/quiz_completion.py b/training/schemas/quiz_completion.py index 3c90f0d4..c0576de2 100644 --- a/training/schemas/quiz_completion.py +++ b/training/schemas/quiz_completion.py @@ -1,11 +1,13 @@ from datetime import datetime from pydantic import ConfigDict, BaseModel +from typing import Any class QuizCompletionBase(BaseModel): quiz_id: int user_id: int passed: bool + responses: dict[str, Any] class QuizCompletionCreate(QuizCompletionBase): diff --git a/training/services/quiz.py b/training/services/quiz.py index bc7f03da..2f855029 100644 --- a/training/services/quiz.py +++ b/training/services/quiz.py @@ -97,10 +97,13 @@ def grade(self, quiz_id: int, user_id: int, submission: QuizSubmission) -> QuizG quiz_completion_id=None ) + responses_dict = submission.model_dump() + result = self.quiz_completion_repo.create(QuizCompletionCreate( quiz_id=quiz_id, user_id=user_id, passed=grade.passed, + responses=responses_dict )) grade.quiz_completion_id = result.id diff --git a/training/tests/test_quiz_completion_repository.py b/training/tests/test_quiz_completion_repository.py index 9e4ea425..cd77ecaa 100644 --- a/training/tests/test_quiz_completion_repository.py +++ b/training/tests/test_quiz_completion_repository.py @@ -12,7 +12,8 @@ def valid_quiz_completion_create( return schemas.QuizCompletionCreate( quiz_id=valid_quiz_ids[-1], user_id=valid_user_ids[-1], - passed=True + passed=True, + responses=dict([{'question_id': 0, 'response_ids': [1]}, {'question_id': 1, 'response_ids': [1]}, {'question_id': 2, 'response_ids': [2]}]) )