Source code for devices.tests.test_models.test_remote_device_credential

"""Tests for the RemoteDeviceCredential model."""

from datetime import timedelta
from typing import Any

import pytest

from devices.models import RemoteDeviceCredentialDownloadModel


@pytest.mark.django_db
[docs] def test_create_remote_device_credential_from_tls_client_credential( tls_client_credential_instance: dict[str, Any], ) -> None: """Test the creation of a RemoteDeviceCredentialDownloadModel instance using the `tls_client_credential` fixture.""" device = tls_client_credential_instance['device'] issued_credential = tls_client_credential_instance['issued_credential'] otp_token = 'test-otp-token' # noqa: S105 remote_download = RemoteDeviceCredentialDownloadModel.objects.create( issued_credential_model=issued_credential, otp=otp_token, device=device, ) assert remote_download.issued_credential_model == issued_credential, ( 'The issued credential model should match the one used in the creation.' ) assert remote_download.device == device, 'The device should match the one used in the creation.' assert remote_download.otp == otp_token, 'The OTP should match the one used during creation.' assert remote_download.attempts == 0, 'Initial attempts should be 0.' assert remote_download.download_token == '', 'The download token should initially be empty.' assert remote_download.token_created_at is None, 'Token created timestamp should initially be None.' expected_str = f'RemoteDeviceCredentialDownloadModel(credential={issued_credential.id})' assert str(remote_download) == expected_str, f"The string representation should be '{expected_str}'."
# ----------------------------------- save----------------------------------- @pytest.mark.django_db
[docs] def test_save_generates_otp_if_not_set(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `save` generates a new OTP if no OTP is set.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] remote_device_credential_download.otp = '' remote_device_credential_download.save() assert remote_device_credential_download.otp != '', 'OTP should be generated if it was not set.' assert isinstance(remote_device_credential_download.otp, str), 'Generated OTP should be a string.'
@pytest.mark.django_db
[docs] def test_save_does_not_modify_existing_otp(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `save` does not modify the OTP if it is already set.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] existing_otp = remote_device_credential_download.otp remote_device_credential_download.save() assert remote_device_credential_download.otp == existing_otp, 'Existing OTP should not be modified.'
# ----------------------------------- check_token ----------------------------------- @pytest.mark.django_db
[docs] def test_check_token_valid(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `check_token` returns True for a valid token within the validity period.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] assert remote_device_credential_download.check_otp(remote_device_credential_download.otp) is True token = remote_device_credential_download.download_token assert remote_device_credential_download.check_token(token) is True, ( 'The token should be valid within its validity period.' )
@pytest.mark.django_db
[docs] def test_check_token_missing_token(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `check_token` returns False if no token is set.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] assert remote_device_credential_download.download_token == '', 'Token should not be set initially.' assert remote_device_credential_download.check_token('some-token') is False, ( '`check_token` should return False if no token is set.' )
@pytest.mark.django_db
[docs] def test_check_token_wrong_token(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `check_token` returns False for an incorrect token.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] assert remote_device_credential_download.check_otp(remote_device_credential_download.otp) is True non_sensitive_test_token = 'wrong-token' # noqa: S105 assert remote_device_credential_download.check_token(non_sensitive_test_token) is False, ( '`check_token` should return False for an incorrect token.' )
@pytest.mark.django_db
[docs] def test_check_token_expired(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `check_token` returns False for an expired token.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] assert remote_device_credential_download.check_otp(remote_device_credential_download.otp) is True token = remote_device_credential_download.download_token remote_device_credential_download.token_created_at -= timedelta( minutes=RemoteDeviceCredentialDownloadModel.TOKEN_VALIDITY.total_seconds() / 60 + 1 ) remote_device_credential_download.save() assert remote_device_credential_download.check_token(token) is False, ( 'The token should be invalid after expiration.' ) with pytest.raises(RemoteDeviceCredentialDownloadModel.DoesNotExist): RemoteDeviceCredentialDownloadModel.objects.get(pk=remote_device_credential_download.pk)
# ----------------------------------- check_otp----------------------------------- @pytest.mark.django_db
[docs] def test_check_otp_valid(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `check_otp` returns True for a valid OTP and invalidates it afterward.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] otp = remote_device_credential_download.otp assert remote_device_credential_download.check_otp(otp) is True, 'Valid OTP should return True.' assert remote_device_credential_download.check_otp(otp) is False, ( 'OTP should not be reusable after a valid attempt.' ) assert remote_device_credential_download.otp == '-', 'OTP should be marked as invalid after being used.'
@pytest.mark.django_db
[docs] def test_check_otp_invalid(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `check_otp` returns False for an invalid OTP.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] invalid_otp = 'wrong-otp' assert remote_device_credential_download.check_otp(invalid_otp) is False, 'Invalid OTP should return False.' assert remote_device_credential_download.attempts == 1, 'Incorrect OTP attempts should update the attempts counter.'
@pytest.mark.django_db
[docs] def test_check_otp_exceed_max_attempts(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that the OTP is invalidated after exceeding the maximum number of allowed attempts.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] max_attempts = RemoteDeviceCredentialDownloadModel.BROWSER_MAX_OTP_ATTEMPTS invalid_otp = 'wrong-otp' for attempt in range(max_attempts): assert remote_device_credential_download.check_otp(invalid_otp) is False, ( f'Attempt {attempt + 1}: Invalid OTP should return False.' ) assert remote_device_credential_download.otp == '-', 'OTP should be invalid after exceeding max attempts.' with pytest.raises(RemoteDeviceCredentialDownloadModel.DoesNotExist): RemoteDeviceCredentialDownloadModel.objects.get(pk=remote_device_credential_download.pk)
@pytest.mark.django_db
[docs] def test_check_otp_resets_on_max_attempts(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that the object is deleted after exceeding max OTP attempts.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] max_attempts = RemoteDeviceCredentialDownloadModel.BROWSER_MAX_OTP_ATTEMPTS invalid_otp = 'wrong-otp' for _ in range(max_attempts): remote_device_credential_download.check_otp(invalid_otp) with pytest.raises(RemoteDeviceCredentialDownloadModel.DoesNotExist): RemoteDeviceCredentialDownloadModel.objects.get(pk=remote_device_credential_download.pk)
@pytest.mark.django_db
[docs] def test_check_otp_creates_download_token(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that a valid OTP generates a download token and sets the creation time.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] otp = remote_device_credential_download.otp assert remote_device_credential_download.check_otp(otp) is True, 'Valid OTP should return True.' assert remote_device_credential_download.download_token != '', 'A valid OTP should generate a download token.' assert remote_device_credential_download.token_created_at is not None, ( 'A valid OTP should set the token creation time.' )
# ----------------------------------- get_otp_display----------------------------------- @pytest.mark.django_db
[docs] def test_get_otp_display_valid_otp(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `get_otp_display` returns the OTP in the correct format when the OTP is valid.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] otp_display = remote_device_credential_download.get_otp_display() expected_display = ( f'{remote_device_credential_download.issued_credential_model.id}.{remote_device_credential_download.otp}' ) assert otp_display == expected_display, f'Expected display format: {expected_display}, got: {otp_display}'
@pytest.mark.django_db
[docs] def test_get_otp_display_invalidated_otp(remote_device_credential_download_instance: dict[str, Any]) -> None: """Test that `get_otp_display` returns 'OTP no longer valid' when the OTP is invalidated.""" remote_device_credential_download = remote_device_credential_download_instance['remote_credential'] remote_device_credential_download.otp = '-' remote_device_credential_download.save() otp_display = remote_device_credential_download.get_otp_display() expected_display = 'OTP no longer valid' assert otp_display == expected_display, f'Expected display: {expected_display}, got: {otp_display}'