Skip to content

Commit

Permalink
Updated quiz service grade and email certificate unit test. Increased…
Browse files Browse the repository at this point in the history
… quiz service unit test coverage.
  • Loading branch information
felder101 committed Dec 12, 2023
1 parent 7651faf commit 84f6f2c
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 16 deletions.
5 changes: 1 addition & 4 deletions training/services/quiz.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,7 @@ def grade(self, quiz_id: int, user_id: int, submission: QuizSubmission) -> QuizG
logging.info(f"Sent confirmation email to {user.email} for passing training quiz")
except Exception as e:
logging.error("Error sending quiz confirmation mail", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Server Error"
)
raise

return grade

Expand Down
9 changes: 8 additions & 1 deletion training/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Generator
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
import jwt
from pydantic import TypeAdapter
import pytest
Expand Down Expand Up @@ -351,3 +351,10 @@ def valid_user_certificate() -> Generator[schemas.UserCertificate, None, None]:
'completion_date': '2023-08-21T22:59:36'
}
yield UserCertificate.model_validate(testdata)


@pytest.fixture
def smtp_instance():
with patch('training.services.quiz.SMTP') as smtp_mock:
with smtp_mock() as smtp:
yield smtp
99 changes: 88 additions & 11 deletions training/tests/test_quiz_service.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
import pytest
from unittest.mock import MagicMock, patch
from training import models, schemas
from training.errors import IncompleteQuizResponseError
from training.services import QuizService, Certificate
from training.errors import IncompleteQuizResponseError, SendEmailError
from training.services import QuizService
from training.repositories import QuizRepository, QuizCompletionRepository, CertificateRepository
from sqlalchemy.orm import Session
from .factories import QuizCompletionFactory
from unittest.mock import ANY

from ..api import email


@patch.object(QuizRepository, "find_by_id")
@patch.object(QuizCompletionRepository, "create")
@patch.object(CertificateRepository, "get_certificate_by_id")
@patch.object(Certificate, "generate_pdf")
@patch.object(QuizService, "email_certificate")
def test_grade_passing(
mock_quiz_service_email_certificate: MagicMock,
mock_certificate_service_generate_pdf: MagicMock,
mock_certificate_repo_get_certificate_by_id: MagicMock,
mock_quiz_completion_repo_create: MagicMock,
mock_quiz_repo_find_by_id: MagicMock,
db_with_data: Session,
valid_passing_submission: schemas.QuizSubmission,
valid_quiz: models.Quiz,
valid_user_certificate: schemas.UserCertificate
valid_user_certificate: schemas.UserCertificate,
valid_user_ids,
valid_quiz_ids
):
quiz_service = QuizService(db_with_data)
mock_quiz_repo_find_by_id.return_value = valid_quiz

user_id = valid_user_ids[-1]
quiz_id = valid_quiz_ids[0]

mock_quiz_completion_repo_create.return_value = QuizCompletionFactory.build()

mock_certificate_repo_get_certificate_by_id.return_value = valid_user_certificate
mock_certificate_service_generate_pdf.return_value = bytearray()
mock_quiz_service_email_certificate.return_value = None

result = quiz_service.grade(quiz_id=123, user_id=123, submission=valid_passing_submission)
result = quiz_service.grade(quiz_id, user_id, submission=valid_passing_submission)

mock_quiz_service_email_certificate.assert_called_once_with(
"Test Three",
"Travel Training for Ministry of Magic",
"[email protected]",
ANY
)

assert isinstance(result, schemas.QuizGrade)
assert result.passed
Expand Down Expand Up @@ -83,3 +93,70 @@ def test_grade_invalid(
quiz_service.grade(quiz_id=123, user_id=123, submission=invalid_submission)

assert err.value.missing_responses == [1]


@patch.object(QuizCompletionRepository, "create")
@patch.object(CertificateRepository, "get_certificate_by_id")
@patch.object(QuizService, "email_certificate")
def test_grade_email_certificate_error(
mock_quiz_service_email_certificate: MagicMock,
mock_certificate_repo_get_certificate_by_id: MagicMock,
mock_quiz_completion_repo_create: MagicMock,
db_with_data: Session,
valid_passing_submission: schemas.QuizSubmission,
valid_user_certificate: schemas.UserCertificate,
valid_user_ids,
valid_quiz_ids
):
quiz_service = QuizService(db_with_data)

user_id = valid_user_ids[-1]
quiz_id = valid_quiz_ids[0]

mock_quiz_completion_repo_create.return_value = QuizCompletionFactory.build()

mock_certificate_repo_get_certificate_by_id.return_value = valid_user_certificate
mock_quiz_service_email_certificate.side_effect = SendEmailError

with pytest.raises(Exception):
quiz_service.grade(quiz_id, user_id, submission=valid_passing_submission)


@patch.multiple(email.settings,
SMTP_SERVER='email.example.com',
SMTP_PORT=999,
EMAIL_FROM='[email protected]',
EMAIL_FROM_NAME='Joseph Patrick Nannetti',
SMTP_USER='Aeolus',
SMTP_PASSWORD='cycl0ps'
)
def test_email_certificate_config(
db_with_data: Session,
smtp_instance
):
quiz_service = QuizService(db_with_data)
quiz_service.email_certificate('Test_User', 'Travel Training for Ministry of Magic', '[email protected]', b'')
smtp_instance.starttls.assert_called()
smtp_instance.login.called_with(user='Aeolus', password='cycl0ps')


def test_email_certificate_passing(
db_with_data: Session,
smtp_instance
):
quiz_service = QuizService(db_with_data)
quiz_service.email_certificate('Test_User', 'Travel Training for Ministry of Magic', '[email protected]', b'')
args, _ = smtp_instance.send_message.call_args
email_message = args[0]
assert email_message['Subject'] == 'Certificate - GSA SmartPay Travel Training for Ministry of Magic'
assert email_message['To'] == '[email protected]'


def test_email_certificate_raises_exception(
db_with_data: Session,
smtp_instance
):
quiz_service = QuizService(db_with_data)
smtp_instance.send_message.side_effect = ValueError('something went wrong')
with pytest.raises(SendEmailError):
quiz_service.email_certificate('Test_User', 'Travel Training for Ministry of Magic', '[email protected]', b'')

0 comments on commit 84f6f2c

Please sign in to comment.