test_lti_stub.py 4.17 KB
Newer Older
1 2 3 4 5 6 7 8 9
"""
Unit tests for stub LTI implementation.
"""
from mock import Mock, patch
import unittest
import urllib2
import requests
from terrain.stubs.lti import StubLtiService

10

11 12 13 14 15 16 17 18
class StubLtiServiceTest(unittest.TestCase):
    """
    A stub of the LTI provider that listens on a local
    port and responds with pre-defined grade messages.

    Used for lettuce BDD tests in lms/courseware/features/lti.feature
    """
    def setUp(self):
19
        super(StubLtiServiceTest, self).setUp()
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
        self.server = StubLtiService()
        self.uri = 'http://127.0.0.1:{}/'.format(self.server.port)
        self.launch_uri = self.uri + 'correct_lti_endpoint'
        self.addCleanup(self.server.shutdown)
        self.payload = {
            'user_id': 'default_user_id',
            'roles': 'Student',
            'oauth_nonce': '',
            'oauth_timestamp': '',
            'oauth_consumer_key': 'test_client_key',
            'lti_version': 'LTI-1p0',
            'oauth_signature_method': 'HMAC-SHA1',
            'oauth_version': '1.0',
            'oauth_signature': '',
            'lti_message_type': 'basic-lti-launch-request',
            'oauth_callback': 'about:blank',
            'launch_presentation_return_url': '',
            'lis_outcome_service_url': 'http://localhost:8001/test_callback',
            'lis_result_sourcedid': '',
39
            'resource_link_id': '',
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
        }

    def test_invalid_request_url(self):
        """
        Tests that LTI server processes request with right program path but with wrong header.
        """
        self.launch_uri = self.uri + 'wrong_lti_endpoint'
        response = requests.post(self.launch_uri, data=self.payload)
        self.assertIn('Invalid request URL', response.content)

    def test_wrong_signature(self):
        """
        Tests that LTI server processes request with right program
        path and responses with incorrect signature.
        """
        response = requests.post(self.launch_uri, data=self.payload)
        self.assertIn('Wrong LTI signature', response.content)

    @patch('terrain.stubs.lti.signature.verify_hmac_sha1', return_value=True)
    def test_success_response_launch_lti(self, check_oauth):
        """
        Success lti launch.
        """
        response = requests.post(self.launch_uri, data=self.payload)
        self.assertIn('This is LTI tool. Success.', response.content)

    @patch('terrain.stubs.lti.signature.verify_hmac_sha1', return_value=True)
67
    def test_send_graded_result(self, verify_hmac):  # pylint: disable=unused-argument
68 69 70 71 72 73 74
        response = requests.post(self.launch_uri, data=self.payload)
        self.assertIn('This is LTI tool. Success.', response.content)
        grade_uri = self.uri + 'grade'
        with patch('terrain.stubs.lti.requests.post') as mocked_post:
            mocked_post.return_value = Mock(content='Test response', status_code=200)
            response = urllib2.urlopen(grade_uri, data='')
            self.assertIn('Test response', response.read())
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

    @patch('terrain.stubs.lti.signature.verify_hmac_sha1', return_value=True)
    def test_lti20_outcomes_put(self, verify_hmac):  # pylint: disable=unused-argument
        response = requests.post(self.launch_uri, data=self.payload)
        self.assertIn('This is LTI tool. Success.', response.content)
        grade_uri = self.uri + 'lti2_outcome'
        with patch('terrain.stubs.lti.requests.put') as mocked_put:
            mocked_put.return_value = Mock(status_code=200)
            response = urllib2.urlopen(grade_uri, data='')
            self.assertIn('LTI consumer (edX) responded with HTTP 200', response.read())

    @patch('terrain.stubs.lti.signature.verify_hmac_sha1', return_value=True)
    def test_lti20_outcomes_put_like_delete(self, verify_hmac):  # pylint: disable=unused-argument
        response = requests.post(self.launch_uri, data=self.payload)
        self.assertIn('This is LTI tool. Success.', response.content)
        grade_uri = self.uri + 'lti2_delete'
        with patch('terrain.stubs.lti.requests.put') as mocked_put:
            mocked_put.return_value = Mock(status_code=200)
            response = urllib2.urlopen(grade_uri, data='')
            self.assertIn('LTI consumer (edX) responded with HTTP 200', response.read())