<reponame>osoco/better-ways-of-thinking-about-software<filename>Part-03-Understanding-Software-Crafting-Your-Own-Tools/models/edx-platform/lms/djangoapps/lti_provider/tests/test_signature_validator.py<gh_stars>1-10
"""
Tests for the SignatureValidator class.
"""


from unittest.mock import patch

import ddt
from django.test import TestCase
from django.test.client import RequestFactory

from lms.djangoapps.lti_provider.models import LtiConsumer
from lms.djangoapps.lti_provider.signature_validator import SignatureValidator


def get_lti_consumer():
    """
    Helper method for all Signature Validator tests to get an LtiConsumer object.
    """
    return LtiConsumer(
        consumer_name='Consumer Name',
        consumer_key='Consumer Key',
        consumer_secret='Consumer Secret'
    )


@ddt.ddt
class ClientKeyValidatorTest(TestCase):
    """
    Tests for the check_client_key method in the SignatureValidator class.
    """

    def setUp(self):
        super().setUp()
        self.lti_consumer = get_lti_consumer()

    def test_valid_client_key(self):
        """
        Verify that check_client_key succeeds with a valid key
        """
        key = self.lti_consumer.consumer_key
        assert SignatureValidator(self.lti_consumer).check_client_key(key)

    @ddt.data(
        ('0123456789012345678901234567890123456789',),
        ('',),
        (None,),
    )
    @ddt.unpack
    def test_invalid_client_key(self, key):
        """
        Verify that check_client_key fails with a disallowed key
        """
        assert not SignatureValidator(self.lti_consumer).check_client_key(key)


@ddt.ddt
class NonceValidatorTest(TestCase):
    """
    Tests for the check_nonce method in the SignatureValidator class.
    """

    def setUp(self):
        super().setUp()
        self.lti_consumer = get_lti_consumer()

    def test_valid_nonce(self):
        """
        Verify that check_nonce succeeds with a key of maximum length
        """
        nonce = '0123456789012345678901234567890123456789012345678901234567890123'
        assert SignatureValidator(self.lti_consumer).check_nonce(nonce)

    @ddt.data(
        ('01234567890123456789012345678901234567890123456789012345678901234',),
        ('',),
        (None,),
    )
    @ddt.unpack
    def test_invalid_nonce(self, nonce):
        """
        Verify that check_nonce fails with badly formatted nonce
        """
        assert not SignatureValidator(self.lti_consumer).check_nonce(nonce)


class SignatureValidatorTest(TestCase):
    """
    Tests for the custom SignatureValidator class that uses the oauthlib library
    to check message signatures. Note that these tests mock out the library
    itself, since we assume it to be correct.
    """

    def setUp(self):
        super().setUp()
        self.lti_consumer = get_lti_consumer()

    def test_get_existing_client_secret(self):
        """
        Verify that get_client_secret returns the right value for the correct
        key
        """
        key = self.lti_consumer.consumer_key
        secret = SignatureValidator(self.lti_consumer).get_client_secret(key, None)
        assert secret == self.lti_consumer.consumer_secret

    @patch('oauthlib.oauth1.SignatureOnlyEndpoint.validate_request',
           return_value=(True, None))
    def test_verification_parameters(self, verify_mock):
        """
        Verify that the signature validaton library method is called using the
        correct parameters derived from the HttpRequest.
        """
        body = 'oauth_signature_method=HMAC-SHA1&oauth_version=1.0'
        content_type = 'application/x-www-form-urlencoded'
        request = RequestFactory().post('/url', body, content_type=content_type)
        headers = {'Content-Type': content_type}
        SignatureValidator(self.lti_consumer).verify(request)
        verify_mock.assert_called_once_with(
            request.build_absolute_uri(), 'POST', body.encode('utf-8'), headers)

"""
Tests for the SignatureValidator class.
"""


from unittest.mock import patch

import ddt
from django.test import TestCase
from django.test.client import RequestFactory

from lms.djangoapps.lti_provider.models import LtiConsumer
from lms.djangoapps.lti_provider.signature_validator import SignatureValidator


def get_lti_consumer():
    """
    Helper method for all Signature Validator tests to get an LtiConsumer object.
    """
    return LtiConsumer(
        consumer_name='Consumer Name',
        consumer_key='Consumer Key',
        consumer_secret='Consumer Secret'
    )


@ddt.ddt
class ClientKeyValidatorTest(TestCase):
    """
    Tests for the check_client_key method in the SignatureValidator class.
    """

    def setUp(self):
        super().setUp()
        self.lti_consumer = get_lti_consumer()

    def test_valid_client_key(self):
        """
        Verify that check_client_key succeeds with a valid key
        """
        key = self.lti_consumer.consumer_key
        assert SignatureValidator(self.lti_consumer).check_client_key(key)

    @ddt.data(
        ('0123456789012345678901234567890123456789',),
        ('',),
        (None,),
    )
    @ddt.unpack
    def test_invalid_client_key(self, key):
        """
        Verify that check_client_key fails with a disallowed key
        """
        assert not SignatureValidator(self.lti_consumer).check_client_key(key)


@ddt.ddt
class NonceValidatorTest(TestCase):
    """
    Tests for the check_nonce method in the SignatureValidator class.
    """

    def setUp(self):
        super().setUp()
        self.lti_consumer = get_lti_consumer()

    def test_valid_nonce(self):
        """
        Verify that check_nonce succeeds with a key of maximum length
        """
        nonce = '0123456789012345678901234567890123456789012345678901234567890123'
        assert SignatureValidator(self.lti_consumer).check_nonce(nonce)

    @ddt.data(
        ('01234567890123456789012345678901234567890123456789012345678901234',),
        ('',),
        (None,),
    )
    @ddt.unpack
    def test_invalid_nonce(self, nonce):
        """
        Verify that check_nonce fails with badly formatted nonce
        """
        assert not SignatureValidator(self.lti_consumer).check_nonce(nonce)


class SignatureValidatorTest(TestCase):
    """
    Tests for the custom SignatureValidator class that uses the oauthlib library
    to check message signatures. Note that these tests mock out the library
    itself, since we assume it to be correct.
    """

    def setUp(self):
        super().setUp()
        self.lti_consumer = get_lti_consumer()

    def test_get_existing_client_secret(self):
        """
        Verify that get_client_secret returns the right value for the correct
        key
        """
        key = self.lti_consumer.consumer_key
        secret = SignatureValidator(self.lti_consumer).get_client_secret(key, None)
        assert secret == self.lti_consumer.consumer_secret

    @patch('oauthlib.oauth1.SignatureOnlyEndpoint.validate_request',
           return_value=(True, None))
    def test_verification_parameters(self, verify_mock):
        """
        Verify that the signature validaton library method is called using the
        correct parameters derived from the HttpRequest.
        """
        body = 'oauth_signature_method=HMAC-SHA1&oauth_version=1.0'
        content_type = 'application/x-www-form-urlencoded'
        request = RequestFactory().post('/url', body, content_type=content_type)
        headers = {'Content-Type': content_type}
        SignatureValidator(self.lti_consumer).verify(request)
        verify_mock.assert_called_once_with(
            request.build_absolute_uri(), 'POST', body.encode('utf-8'), headers)
Tests for the SignatureValidator class. Helper method for all Signature Validator tests to get an LtiConsumer object. Tests for the check_client_key method in the SignatureValidator class. Verify that check_client_key succeeds with a valid key Verify that check_client_key fails with a disallowed key Tests for the check_nonce method in the SignatureValidator class. Verify that check_nonce succeeds with a key of maximum length Verify that check_nonce fails with badly formatted nonce Tests for the custom SignatureValidator class that uses the oauthlib library     to check message signatures. Note that these tests mock out the library     itself, since we assume it to be correct. Verify that get_client_secret returns the right value for the correct         key Verify that the signature validaton library method is called using the         correct parameters derived from the HttpRequest.