forked from openedx/credentials
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'aci.main' into hantkovskyi/aci-742/badge-incompletion-s…
…ignal
- Loading branch information
Showing
11 changed files
with
209 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from django.contrib.contenttypes.models import ContentType | ||
|
||
from ..models import BadgeTemplate, UserCredential | ||
|
||
|
||
def create_user_credential(username, badge_template): | ||
if not isinstance(username, str): | ||
raise ValueError("`username` must be a string") | ||
|
||
if not isinstance(badge_template, BadgeTemplate): | ||
raise TypeError("`badge_template` must be an instance of BadgeTemplate") | ||
|
||
|
||
UserCredential.objects.create( | ||
credential_content_type=ContentType.objects.get_for_model( | ||
badge_template), | ||
credential_id=badge_template.id, | ||
username=username, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from django.test import TestCase | ||
from django.core.exceptions import ObjectDoesNotExist | ||
from django.contrib.contenttypes.models import ContentType | ||
|
||
from ..models import BadgeTemplate, UserCredential | ||
from ..services.badge_templates import get_badge_template_by_id | ||
from ..services.user_credentials import create_user_credential | ||
|
||
|
||
class UserCredentialServiceTestCase(TestCase): | ||
def setUp(self): | ||
# Create a test badge template | ||
self.badge_template = BadgeTemplate.objects.create( | ||
origin='openedx', site_id=1) | ||
|
||
def test_create_user_credential(self): | ||
# Call create_user_credential with valid arguments | ||
create_user_credential('test_user', self.badge_template) | ||
|
||
# Check if user credential is created | ||
self.assertTrue( | ||
UserCredential.objects.filter( | ||
username='test_user', | ||
credential_content_type=ContentType.objects.get_for_model( | ||
self.badge_template), | ||
credential_id=self.badge_template.id, | ||
).exists() | ||
) | ||
|
||
def test_create_user_credential_invalid_username(self): | ||
# Call create_user_credential with non-existent username | ||
with self.assertRaises(ValueError): | ||
# Passing int as username | ||
create_user_credential(123, self.badge_template) | ||
|
||
def test_create_user_credential_invalid_template(self): | ||
# Call create_user_credential with non-existent badge template | ||
with self.assertRaises(TypeError): | ||
# Passing None as badge template | ||
create_user_credential('test_user', None) | ||
|
||
|
||
class BadgeTemplateServiceTestCase(TestCase): | ||
def setUp(self): | ||
self.badge_template = BadgeTemplate.objects.create(origin='openedx', site_id=1) | ||
|
||
def test_get_badge_template_by_id(self): | ||
# Call get_badge_template_by_id with existing badge template ID | ||
badge_template = get_badge_template_by_id(self.badge_template.id) | ||
|
||
# Check if the returned badge template is correct | ||
self.assertEqual(badge_template, self.badge_template) | ||
|
||
def test_get_badge_template_by_id_nonexistent(self): | ||
# Call get_badge_template_by_id with non-existent ID | ||
badge_template = get_badge_template_by_id(999) # Non-existent ID | ||
|
||
# Check that None is returned | ||
self.assertIsNone(badge_template) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from django.test import TestCase | ||
from django.core.exceptions import ObjectDoesNotExist | ||
from django.contrib.contenttypes.models import ContentType | ||
|
||
from ..models import BadgeTemplate, UserCredential | ||
from ..signals.signals import BADGE_PROGRESS_COMPLETE | ||
|
||
|
||
class BadgeSignalReceiverTestCase(TestCase): | ||
def setUp(self): | ||
# Create a test badge template | ||
self.badge_template = BadgeTemplate.objects.create( | ||
name='test', site_id=1) | ||
|
||
def test_signal_emission_and_receiver_execution(self): | ||
# Emit the signal | ||
BADGE_PROGRESS_COMPLETE.send( | ||
sender=self, | ||
username='test_user', | ||
badge_template_id=self.badge_template.id, | ||
) | ||
|
||
# UserCredential object | ||
user_credential = UserCredential.objects.filter( | ||
username='test_user', | ||
credential_content_type=ContentType.objects.get_for_model( | ||
self.badge_template), | ||
credential_id=self.badge_template.id, | ||
) | ||
|
||
# Check if user credential is created | ||
self.assertTrue(user_credential.exists()) | ||
|
||
# Check if user credential status is 'awarded' | ||
self.assertTrue(user_credential[0].status == 'awarded') | ||
|
||
def test_behavior_for_nonexistent_badge_templates(self): | ||
# Emit the signal with a non-existent badge template ID | ||
BADGE_PROGRESS_COMPLETE.send( | ||
sender=self, | ||
username='test_user', | ||
badge_template_id=999, # Non-existent ID | ||
) | ||
|
||
# Check that no user credential is created | ||
self.assertFalse( | ||
UserCredential.objects.filter(username='test_user').exists() | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import unittest | ||
|
||
from credentials.utils import keypath | ||
|
||
class TestKeypath(unittest.TestCase): | ||
def test_keypath_exists(self): | ||
payload = { | ||
"course": { | ||
"key": "105-3332", | ||
} | ||
} | ||
result = keypath(payload, "course.key") | ||
self.assertEqual(result, "105-3332") | ||
|
||
def test_keypath_not_exists(self): | ||
payload = { | ||
"course": { | ||
"id": "105-3332", | ||
} | ||
} | ||
result = keypath(payload, "course.key") | ||
self.assertIsNone(result) | ||
|
||
def test_keypath_deep(self): | ||
payload = { | ||
"course": { | ||
"data": { | ||
"identification": { | ||
"id": 25 | ||
} | ||
} | ||
} | ||
} | ||
result = keypath(payload, "course.data.identification.id") | ||
self.assertEqual(result, 25) | ||
|
||
def test_keypath_invalid_path(self): | ||
payload = { | ||
"course": { | ||
"key": "105-3332", | ||
} | ||
} | ||
result = keypath(payload, "course.id") | ||
self.assertIsNone(result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
def keypath(payload, keys_path): | ||
keys = keys_path.split('.') | ||
current = payload | ||
|
||
def traverse(current, keys): | ||
if not keys: | ||
return current | ||
key = keys[0] | ||
if isinstance(current, dict) and key in current: | ||
return traverse(current[key], keys[1:]) | ||
else: | ||
return None | ||
|
||
return traverse(current, keys) |