Skip to content

Commit

Permalink
#835 unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Bubomira committed Jan 29, 2025
1 parent 961670d commit dba632d
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@
from result import Err, Ok
from src.database.model.participant_model import Participant
from src.database.model.team_model import Team
from src.server.exception import HackathonCapacityExceededError, ParticipantNotFoundError, TeamNotFoundError
from src.server.exception import (
EmailRateLimitExceededError,
HackathonCapacityExceededError,
ParticipantAlreadyVerifiedError,
ParticipantNotFoundError,
TeamNotFoundError,
)
from src.server.handlers.verification_handlers import VerificationHandlers
from src.server.schemas.jwt_schemas.schemas import JwtParticipantInviteRegistrationData, JwtParticipantVerificationData
from src.server.schemas.response_schemas.schemas import ErrResponse, ParticipantVerifiedResponse, Response
from src.server.schemas.response_schemas.schemas import (
ErrResponse,
ParticipantVerifiedResponse,
Response,
VerificationEmailSentSuccessfullyResponse,
)
from src.utils import JwtUtility
from starlette import status
from tests.integration_tests.conftest import TEST_TEAM_NAME, TEST_USER_EMAIL, TEST_USER_NAME, mock_obj_id
Expand Down Expand Up @@ -248,3 +259,71 @@ async def test_verify_random_hackathon_capacity_reached(
assert isinstance(resp, Response)
assert isinstance(resp.response_model, ErrResponse)
assert resp.response_model.error == "Max hackathon capacity has been reached"


@pytest.mark.asyncio
async def test_send_verification_email_success(
verification_handlers: VerificationHandlers, participant_verification_service_mock: Mock, mock_obj_id: str
) -> None:
participant_verification_service_mock.send_verification_email.return_value = Ok(
Participant(name=TEST_USER_NAME, email=TEST_USER_EMAIL, is_admin=True, email_verified=False, team_id=None)
)

result = await verification_handlers.send_verification_email(mock_obj_id)

participant_verification_service_mock.send_verification_email.assert_awaited_once()

assert isinstance(result, Response)
assert isinstance(result.response_model, VerificationEmailSentSuccessfullyResponse)
assert result.status_code == status.HTTP_200_OK
assert result.response_model.participant.name == TEST_USER_NAME
assert result.response_model.participant.email == TEST_USER_EMAIL
assert result.response_model.participant.is_admin is True


@pytest.mark.asyncio
async def test_send_verification_email_rate_limit_exceeded_error(
verification_handlers: VerificationHandlers, participant_verification_service_mock: Mock, mock_obj_id: str
) -> None:
participant_verification_service_mock.send_verification_email.return_value = Err(EmailRateLimitExceededError())

result = await verification_handlers.send_verification_email(mock_obj_id)

participant_verification_service_mock.send_verification_email.assert_awaited_once()

assert isinstance(result, Response)
assert isinstance(result.response_model, ErrResponse)
assert result.status_code == status.HTTP_409_CONFLICT
assert result.response_model.error == "The rate limit for sending emails has been exceeded"


@pytest.mark.asyncio
async def test_send_verification_participant_alredy_verified_error(
verification_handlers: VerificationHandlers, participant_verification_service_mock: Mock, mock_obj_id: str
) -> None:
participant_verification_service_mock.send_verification_email.return_value = Err(ParticipantAlreadyVerifiedError())

result = await verification_handlers.send_verification_email(mock_obj_id)

participant_verification_service_mock.send_verification_email.assert_awaited_once()

assert isinstance(result, Response)
assert isinstance(result.response_model, ErrResponse)
assert result.status_code == status.HTTP_400_BAD_REQUEST
assert result.response_model.error == "You have already been verified"


@pytest.mark.asyncio
async def test_send_verification_participant_not_found_error(
verification_handlers: VerificationHandlers, participant_verification_service_mock: Mock, mock_obj_id: str
) -> None:
participant_verification_service_mock.send_verification_email.return_value = Err(ParticipantNotFoundError())

result = await verification_handlers.send_verification_email(mock_obj_id)

participant_verification_service_mock.send_verification_email.assert_awaited_once()

assert isinstance(result, Response)
assert isinstance(result.response_model, ErrResponse)
assert result.status_code == status.HTTP_404_NOT_FOUND
assert result.response_model.error == "The specified participant was not found"
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import timedelta, datetime

from unittest.mock import Mock, patch

from bson import ObjectId
Expand All @@ -6,7 +8,14 @@

from src.database.model.participant_model import Participant
from src.database.model.team_model import Team
from src.server.exception import DuplicateTeamNameError, DuplicateEmailError, TeamNameMissmatchError, TeamNotFoundError
from src.server.exception import (
DuplicateTeamNameError,
DuplicateEmailError,
ParticipantAlreadyVerifiedError,
ParticipantNotFoundError,
TeamNameMissmatchError,
TeamNotFoundError,
)
from src.server.schemas.jwt_schemas.schemas import JwtParticipantInviteRegistrationData, JwtParticipantVerificationData
from src.server.schemas.request_schemas.schemas import (
AdminParticipantInputData,
Expand All @@ -16,6 +25,9 @@
from src.service.hackathon_service import HackathonService
from tests.integration_tests.conftest import TEST_TEAM_NAME, TEST_USER_EMAIL, TEST_USER_NAME

PARTICIPANT_LAST_SENT_EMAIL_VALID_RANGE = datetime.now() - timedelta(seconds=180)
PARTICIPANT_LAST_SENT_EMAIL_INVALID_RANGE = datetime.now() - timedelta(seconds=30)


@pytest.fixture
def hackathon_service(participant_repo_mock: Mock, team_repo_mock: Mock, tx_manager_mock: Mock) -> HackathonService:
Expand Down Expand Up @@ -415,3 +427,115 @@ async def test_check_team_capacity_case_capacity_exceeded(
result = await hackathon_service.check_team_capacity(mock_obj_id)

assert result is False


@pytest.mark.asyncio
async def test_check_send_verification_email_rate_limit_success(
hackathon_service: HackathonService,
participant_repo_mock: Mock,
mock_obj_id: str,
) -> None:

participant_repo_mock.fetch_by_id.return_value = Ok(
Participant(
name=TEST_USER_NAME,
email=TEST_USER_EMAIL,
email_verified=False,
is_admin=False,
team_id=None,
last_sent_email=PARTICIPANT_LAST_SENT_EMAIL_VALID_RANGE,
)
)
result = await hackathon_service.check_send_verification_email_rate_limit(participant_id=mock_obj_id)
assert isinstance(result, Ok)
assert isinstance(result.ok_value, bool)
assert result.ok_value == True


@pytest.mark.asyncio
async def test_check_send_verification_email_rate_limit_limit_reached(
hackathon_service: HackathonService,
participant_repo_mock: Mock,
mock_obj_id: str,
) -> None:

participant_repo_mock.fetch_by_id.return_value = Ok(
Participant(
name=TEST_USER_NAME,
email=TEST_USER_EMAIL,
email_verified=False,
is_admin=False,
team_id=None,
last_sent_email=PARTICIPANT_LAST_SENT_EMAIL_INVALID_RANGE,
)
)

result = await hackathon_service.check_send_verification_email_rate_limit(participant_id=mock_obj_id)

assert isinstance(result, Ok)
assert isinstance(result.ok_value, bool)
assert result.ok_value == False


@pytest.mark.asyncio
async def test_check_send_verification_email_rate_limit_participant_without_last_sent_email(
hackathon_service: HackathonService,
participant_repo_mock: Mock,
mock_obj_id: str,
) -> None:

participant_repo_mock.fetch_by_id.return_value = Ok(
Participant(
name=TEST_USER_NAME,
email=TEST_USER_EMAIL,
email_verified=False,
is_admin=False,
team_id=None,
last_sent_email=None,
)
)

result = await hackathon_service.check_send_verification_email_rate_limit(participant_id=mock_obj_id)

assert isinstance(result, Ok)
assert isinstance(result.ok_value, bool)
assert result.ok_value == True


@pytest.mark.asyncio
async def test_check_send_verification_email_rate_limit_participant_already_verified(
hackathon_service: HackathonService,
participant_repo_mock: Mock,
mock_obj_id: str,
) -> None:

participant_repo_mock.fetch_by_id.return_value = Ok(
Participant(
name=TEST_USER_NAME,
email=TEST_USER_EMAIL,
email_verified=True,
is_admin=False,
team_id=None,
last_sent_email=None,
)
)

result = await hackathon_service.check_send_verification_email_rate_limit(participant_id=mock_obj_id)

assert isinstance(result, Err)
assert isinstance(result.err_value, ParticipantAlreadyVerifiedError)


@pytest.mark.asyncio
async def test_check_send_verification_email_rate_limit_participant_not_found(
hackathon_service: HackathonService,
participant_repo_mock: Mock,
mock_obj_id: str,
) -> None:

participant_repo_mock.fetch_by_id.return_value = Err(ParticipantNotFoundError())

result = await hackathon_service.check_send_verification_email_rate_limit(participant_id=mock_obj_id)

assert isinstance(result, Err)
assert isinstance(result.err_value, ParticipantNotFoundError)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@

from src.database.model.team_model import Team
from src.database.model.participant_model import Participant
from src.server.exception import HackathonCapacityExceededError, ParticipantNotFoundError, TeamNotFoundError
from src.server.exception import (
EmailRateLimitExceededError,
HackathonCapacityExceededError,
ParticipantNotFoundError,
TeamNotFoundError,
)
from src.server.schemas.jwt_schemas.schemas import JwtParticipantVerificationData
from src.service.participants_verification_service import ParticipantVerificationService
from tests.integration_tests.conftest import TEST_TEAM_NAME, TEST_USER_EMAIL, TEST_USER_NAME
Expand Down Expand Up @@ -215,3 +220,56 @@ async def test_verify_random_participant_hackathon_capacity_exceeded_error(

assert isinstance(result, Err)
assert isinstance(result.err_value, HackathonCapacityExceededError)


@pytest.mark.asyncio
async def test_send_verification_email_success(
p_ver_service: ParticipantVerificationService,
hackathon_service_mock: Mock,
mock_obj_id: str,
) -> None:

hackathon_service_mock.check_send_verification_email_rate_limit.return_value = Ok(True)

hackathon_service_mock.send_verification_email.return_value = Ok(
Participant(name=TEST_USER_NAME, email=TEST_USER_EMAIL, is_admin=True, email_verified=False, team_id=None)
)

result = await p_ver_service.send_verification_email(mock_obj_id)

assert isinstance(result, Ok)
assert isinstance(result.ok_value, Participant)
assert result.ok_value.name == TEST_USER_NAME
assert result.ok_value.email == TEST_USER_EMAIL


@pytest.mark.asyncio
async def test_send_verification_email_rate_limit_exceeded_error(
p_ver_service: ParticipantVerificationService,
hackathon_service_mock: Mock,
mock_obj_id: str,
) -> None:

hackathon_service_mock.check_send_verification_email_rate_limit.return_value = Ok(False)

result = await p_ver_service.send_verification_email(mock_obj_id)

assert isinstance(result, Err)
assert isinstance(result.err_value, EmailRateLimitExceededError)


# this is a test to ensure that the method returns an error if such occurs'in
# check_send_verification_email_rate_limit from Hackaton service
@pytest.mark.asyncio
async def test_send_verification_email_participant_not_found_error(
p_ver_service: ParticipantVerificationService,
hackathon_service_mock: Mock,
mock_obj_id: str,
) -> None:

hackathon_service_mock.check_send_verification_email_rate_limit.return_value = Err(ParticipantNotFoundError())

result = await p_ver_service.send_verification_email(mock_obj_id)

assert isinstance(result, Err)
assert isinstance(result.err_value, ParticipantNotFoundError)

0 comments on commit dba632d

Please sign in to comment.