From 882a1e0f29276e5626d3993db9f90fa1280a29d4 Mon Sep 17 00:00:00 2001 From: Oleg Marshev Date: Mon, 24 Mar 2014 17:57:22 +0200 Subject: [PATCH] Change resource_link_id on import (BLD-768). LTI: Update resource_link_id to change on import to another system or context (BLD-768). --- CHANGELOG.rst | 2 ++ common/lib/xmodule/xmodule/lti_module.py | 20 ++++++++++++++++++- .../xmodule/xmodule/tests/test_lti_unit.py | 20 +++++++++++-------- .../courseware/tests/test_lti_integration.py | 9 +++++---- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 97990e9f41..873ce7ed69 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes, in roughly chronological order, most recent first. Add your entries at or near the top. Include a label indicating the component affected. +Blades: Update LTI resource_link_id parameter. BLD-768. + Blades: Transcript translations should be displayed in their source language (BLD-935). Blades: Create an upload modal for video transcript translations (BLD-751). diff --git a/common/lib/xmodule/xmodule/lti_module.py b/common/lib/xmodule/xmodule/lti_module.py index 5e2bf900a7..ddca9d0058 100644 --- a/common/lib/xmodule/xmodule/lti_module.py +++ b/common/lib/xmodule/xmodule/lti_module.py @@ -309,8 +309,26 @@ class LTIModule(LTIFields, XModule): context and imported into another system or context. This parameter is required. + + Example: u'edx.org-i4x-2-3-lti-31de800015cf4afb973356dbe81496df' + + Hostname, edx.org, + makes resource_link_id change on import to another system. + + Last part of location, location.name - 31de800015cf4afb973356dbe81496df, + is random hash, updated by course_id, + this makes resource_link_id unique inside single course. + + First part of location is tag-org-course-category, i4x-2-3-lti. + + Location.name itself does not change on import to another course, + but org and course_id change. + + So together with org and course_id in a form of + i4x-2-3-lti-31de800015cf4afb973356dbe81496df this part of resource_link_id: + makes resource_link_id to be unique among courses inside same system. """ - return unicode(urllib.quote(self.id)) + return unicode(urllib.quote("{}-{}".format(self.system.hostname, self.location.html_id()))) def get_lis_result_sourcedid(self): """ diff --git a/common/lib/xmodule/xmodule/tests/test_lti_unit.py b/common/lib/xmodule/xmodule/tests/test_lti_unit.py index 141fe6645c..e42dbd9100 100644 --- a/common/lib/xmodule/xmodule/tests/test_lti_unit.py +++ b/common/lib/xmodule/xmodule/tests/test_lti_unit.py @@ -59,9 +59,9 @@ class LTIModuleTest(LogicTest): self.user_id = self.xmodule.runtime.anonymous_student_id self.lti_id = self.xmodule.lti_id - self.module_id = '//MITx/999/lti/' + self.unquoted_resource_link_id= u'{}-i4x-2-3-lti-31de800015cf4afb973356dbe81496df'.format(self.xmodule.runtime.hostname) - sourcedId = u':'.join(urllib.quote(i) for i in (self.lti_id, self.module_id, self.user_id)) + sourcedId = u':'.join(urllib.quote(i) for i in (self.lti_id, self.unquoted_resource_link_id, self.user_id)) self.DEFAULTS = { 'sourcedId': sourcedId, @@ -255,16 +255,20 @@ class LTIModuleTest(LogicTest): self.assertEqual(real_outcome_service_url, expected_outcome_service_url) def test_resource_link_id(self): - with patch('xmodule.lti_module.LTIModule.id', new_callable=PropertyMock) as mock_id: - mock_id.return_value = self.module_id - expected_resource_link_id = unicode(urllib.quote(self.module_id)) + with patch('xmodule.lti_module.LTIModule.location', new_callable=PropertyMock) as mock_location: + self.xmodule.location.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df' + expected_resource_link_id = unicode(urllib.quote(self.unquoted_resource_link_id)) real_resource_link_id = self.xmodule.get_resource_link_id() self.assertEqual(real_resource_link_id, expected_resource_link_id) def test_lis_result_sourcedid(self): - with patch('xmodule.lti_module.LTIModule.id', new_callable=PropertyMock) as mock_id: - mock_id.return_value = self.module_id - expected_sourcedId = u':'.join(urllib.quote(i) for i in (self.lti_id, self.module_id, self.user_id)) + with patch('xmodule.lti_module.LTIModule.location', new_callable=PropertyMock) as mock_location: + self.xmodule.location.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df' + expected_sourcedId = u':'.join(urllib.quote(i) for i in ( + self.lti_id, + urllib.quote(self.unquoted_resource_link_id), + self.user_id + )) real_lis_result_sourcedid = self.xmodule.get_lis_result_sourcedid() self.assertEqual(real_lis_result_sourcedid, expected_sourcedId) diff --git a/lms/djangoapps/courseware/tests/test_lti_integration.py b/lms/djangoapps/courseware/tests/test_lti_integration.py index e98b4b5ec9..66a92153ab 100644 --- a/lms/djangoapps/courseware/tests/test_lti_integration.py +++ b/lms/djangoapps/courseware/tests/test_lti_integration.py @@ -28,17 +28,18 @@ class TestLTI(BaseTestXmodule): mocked_decoded_signature = u'my_signature=' lti_id = self.item_descriptor.lti_id - module_id = unicode(urllib.quote(self.item_descriptor.id)) user_id = unicode(self.item_descriptor.xmodule_runtime.anonymous_student_id) + hostname = self.item_descriptor.xmodule_runtime.hostname + resource_link_id = unicode(urllib.quote('{}-{}'.format(hostname, self.item_descriptor.location.html_id()))) sourcedId = "{id}:{resource_link}:{user_id}".format( id=urllib.quote(lti_id), - resource_link=urllib.quote(module_id), + resource_link=urllib.quote(resource_link_id), user_id=urllib.quote(user_id) ) lis_outcome_service_url = 'https://{host}{path}'.format( - host=self.item_descriptor.xmodule_runtime.hostname, + host=hostname, path=self.item_descriptor.xmodule_runtime.handler_url(self.item_descriptor, 'grade_handler', thirdparty=True).rstrip('/?') ) self.correct_headers = { @@ -49,7 +50,7 @@ class TestLTI(BaseTestXmodule): u'lti_version': 'LTI-1p0', u'roles': u'Student', - u'resource_link_id': module_id, + u'resource_link_id': resource_link_id, u'lis_result_sourcedid': sourcedId, u'oauth_nonce': mocked_nonce,