Skip to content

Commit

Permalink
feat: fixed python apis and added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ericanwoga committed Sep 11, 2023
1 parent b33ac37 commit 56be369
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 20 deletions.
38 changes: 32 additions & 6 deletions openedx/core/djangoapps/agreements/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from openedx.core.djangoapps.agreements.models import LTIPIISignature

from .data import LTIToolsReceivingPIIData
from .data import LTIPIISignatureData

log = logging.getLogger(__name__)
User = get_user_model()
Expand Down Expand Up @@ -79,25 +80,50 @@ def create_lti_pii_signature(username, course_id, lti_tools):
Creates an lti pii tool signature. If the signature already exist, do not create a new one.
Arguments:
* course_key (str)
* lti_tools (str)
* lti_tools (dict)
* lti_tools_hash (int)
Returns:
* True or False depending on if the write was successful
"""
user = User.objects.get(username=username)
course_key = CourseKey.from_string(course_id)
lti_tools_hash = hash(lti_tools)
lti_tools_hash = hash(str(lti_tools))

signature, created = LTIPIISignature.objects.get_or_create(
user=user,
course_key=course_key,
lti_tools=lti_tools,
lti_tools_hash=lti_tools_hash)

if not created:
log.warning(
'LTI PII signature already exists for user_id={user_id} and '
'course_id={course_id}'.format(user_id=user.id, course_id=course_id)
)
return signature


def get_lti_tools_receiving_pii(course_id):
def get_lti_pii_signature(username, course_id):
"""
Get the lti pii signature of a user in a course.
Arguments:
* username (str)
* course_id (str)
Returns:
* An LTIPIISignature object, or None if one does not exist for the
user + course combination.
"""
user = User.objects.get(username=username)
course_key = CourseKey.from_string(course_id)
try:
signature = LTIPIISignature.objects.get(user=user, course_key=course_key)
return LTIPIISignatureData(lti_pii_signature=signature)
except ObjectDoesNotExist:
return None


def get_pii_receiving_lti_tools(course_id):
"""
Get a course's LTI tools that share PII.
Expand All @@ -109,14 +135,14 @@ def get_lti_tools_receiving_pii(course_id):
"""

course_key = CourseKey.from_string(course_id)
course_ltipiitools = LTIPIITool.objects.get(course_key=course_key)
course_ltipiitools = LTIPIITool.objects.get(course_key=course_key).lti_tools

return LTIToolsReceivingPIIData(
lii_tools_receiving_pii=course_ltipiitools,
)


def user_lit_pii_signature_needed(username, course_id):
def user_lti_pii_signature_needed(username, course_id):
"""
Determines if a user needs to acknowledge the LTI PII Agreement
Expand Down
9 changes: 9 additions & 0 deletions openedx/core/djangoapps/agreements/data.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import attr
from openedx.core.djangoapps.agreements.models import LTIPIISignature


@attr.s(frozen=True, auto_attribs=True)
Expand All @@ -7,3 +8,11 @@ class LTIToolsReceivingPIIData:
Class that stores data about the list of LTI tools sharing PII
"""
lii_tools_receiving_pii: dict()


@attr.s(frozen=True, auto_attribs=True)
class LTIPIISignatureData:
"""
Class that stores an lti pii signature
"""
lti_pii_signature: LTIPIISignature
85 changes: 71 additions & 14 deletions openedx/core/djangoapps/agreements/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
create_integrity_signature,
get_integrity_signature,
get_integrity_signatures_for_course,
get_lti_tools_receiving_pii
get_pii_receiving_lti_tools,
create_lti_pii_signature,
get_lti_pii_signature
)
from openedx.core.djangolib.testing.utils import skip_unless_lms
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
Expand Down Expand Up @@ -105,6 +107,62 @@ def _assert_integrity_signature(self, signature):
self.assertEqual(signature.course_key, self.course.id)


@skip_unless_lms
class TestLTIPIISignatureApi(SharedModuleStoreTestCase):
"""
Tests for the lti pii signature API
"""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.user = UserFactory()
cls.course = CourseFactory()
cls.course_id = str(cls.course.id)
cls.lti_tools = {"first_lti_tool": "This is the first tool",
"second_lti_tool": "This is the second tool", }
LTIPIITool.objects.create(
course_key=CourseKey.from_string(cls.course_id),
lti_tools=cls.lti_tools,
lti_tools_hash=11111,
)

def test_create_lti_pii_signature(self):
"""
Test to check if an lti pii signature is created from a course and its lti tools.
"""
signature = create_lti_pii_signature(self.user.username, self.course_id, self.lti_tools)
self._assert_lti_pii_signature(signature)

def test_create_duplicate_lti_pii_signature(self):
"""
Test that duplicate lti pii signatures cannot be created
"""
print(self.user, self.course, self.course_id, self.lti_tools)
with LogCapture(LOGGER_NAME, level=logging.WARNING) as logger:
create_lti_pii_signature(self.user.username, self.course_id, self.lti_tools)
create_lti_pii_signature(self.user.username, self.course_id, self.lti_tools)
data = get_lti_pii_signature(self.user.username, self.course_id)
self._assert_lti_pii_signature(data.lti_pii_signature)
logger.check((
LOGGER_NAME,
'WARNING',
(
'LTI PII signature already exists for user_id={user_id} and '
'course_id={course_id}'.format(
user_id=self.user.id, course_id=str(self.course_id)
)
)
))

def _assert_lti_pii_signature(self, signature):
"""
Helper function to assert the returned lti pii signature has the correct
user and course key
"""
self.assertEqual(signature.user, self.user)
self.assertEqual(signature.course_key, self.course.id)


@skip_unless_lms
class TestLTIPIIToolsApi(SharedModuleStoreTestCase):
"""
Expand All @@ -115,24 +173,23 @@ def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory()
cls.course_id = str(cls.course.id)
cls.course_and_tools = LTIPIITool.objects.create(
cls.lti_tools = {"first_lti_tool": "This is the first tool",
"second_lti_tool": "This is the second tool", }
LTIPIITool.objects.create(
course_key=CourseKey.from_string(cls.course_id),
lti_tools={"first_lti_tool": "This is the first tool",
"second_lti_tool": "This is the second tool", },
lti_tools_hash=112233,
lti_tools=cls.lti_tools,
lti_tools_hash=11111,
)

def test_get_lti_tools_receiving_pii(self):
def test_get_pii_receiving_lti_tools(self):
"""
Test to get an integrity signature
Test to check if a course's lti pii tools can be retrieved.
"""
tool_list = get_lti_tools_receiving_pii(self.course_id)
#print(tool_list)

#self._assert_ltitools(tool_list)
data = get_pii_receiving_lti_tools(self.course_id)
self._assert_ltitools(data.lii_tools_receiving_pii)

def _assert_ltitools(self, tool_list):
def _assert_ltitools(self, list):
"""
Helper function to assert the returned list has the correct
Helper function to assert the returned list has the correct tools
"""
self.assertEqual(self.course_and_tools, tool_list)
self.assertEqual(self.lti_tools, list)

0 comments on commit 56be369

Please sign in to comment.