Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: [ACI-994] increase test coverage #179

Draft
wants to merge 1 commit into
base: aci.upstream
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 111 additions & 4 deletions credentials/apps/badges/tests/test_admin_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

from django import forms
from django.contrib.sites.models import Site
from django.test import TestCase
from django.utils.translation import gettext as _
from django.test import TestCase, override_settings
from unittest.mock import MagicMock, patch

from credentials.apps.badges.admin_forms import BadgePenaltyForm
from credentials.apps.badges.admin_forms import BadgePenaltyForm, CredlyOrganizationAdminForm
from credentials.apps.badges.credly.exceptions import CredlyAPIError
from credentials.apps.badges.models import BadgeRequirement, BadgeTemplate


Expand Down Expand Up @@ -70,4 +71,110 @@ def test_clean_requirements_different_template(self):
with self.assertRaises(forms.ValidationError) as cm:
form.clean()

self.assertEqual(str(cm.exception), "['All requirements must belong to the same template.']")
self.assertEqual(
str(cm.exception), "['All requirements must belong to the same template.']"
)

@override_settings(BADGES_CONFIG={"credly": {"ORGANIZATIONS": {}}})
def test_clean(self):
form = CredlyOrganizationAdminForm()
form.cleaned_data = {
"uuid": "test_uuid",
"api_key": "test_api_key",
}

with patch(
"credentials.apps.badges.models.CredlyOrganization.get_preconfigured_organizations"
) as mock_get_orgs:
mock_get_orgs.return_value = {}

with patch(
"credentials.apps.badges.admin_forms.CredlyAPIClient"
) as mock_client:
mock_client.return_value = MagicMock()

form.clean()

mock_get_orgs.assert_called_once()
mock_client.assert_called_once_with("test_uuid", "test_api_key")

@override_settings(BADGES_CONFIG={"credly": {"ORGANIZATIONS": {"test_uuid": "test_api_key"}}})
def test_clean_with_configured_organization(self):
form = CredlyOrganizationAdminForm()
form.cleaned_data = {
"uuid": "test_uuid",
"api_key": None,
}

with patch(
"credentials.apps.badges.models.CredlyOrganization.get_preconfigured_organizations"
) as mock_get_orgs:
mock_get_orgs.return_value = {"test_uuid": "test_org"}

with patch(
"credentials.apps.badges.admin_forms.CredlyAPIClient"
) as mock_client:
mock_client.return_value = MagicMock()

form.clean()

mock_get_orgs.assert_called_once()
mock_client.assert_called_once_with("test_uuid", "test_api_key")

def test_clean_with_invalid_organization(self):
form = CredlyOrganizationAdminForm()
form.cleaned_data = {
"uuid": "invalid_uuid",
"api_key": "test_api_key",
}

with patch(
"credentials.apps.badges.models.CredlyOrganization.get_preconfigured_organizations"
) as mock_get_orgs:
mock_get_orgs.return_value = {"test_uuid": "test_org"}

with self.assertRaises(forms.ValidationError) as cm:
form.clean()

self.assertIn("You specified an invalid authorization token.", str(cm.exception))

def test_clean_cannot_provide_api_key_for_configured_organization(self):
form = CredlyOrganizationAdminForm()
form.cleaned_data = {
"uuid": "test_uuid",
"api_key": "test_api_key",
}

with patch(
"credentials.apps.badges.models.CredlyOrganization.get_preconfigured_organizations"
) as mock_get_orgs:
mock_get_orgs.return_value = {"test_uuid": "test_org"}

with self.assertRaises(forms.ValidationError) as cm:
form.clean()

self.assertEqual(
str(cm.exception),
'["You can\'t provide an API key for a configured organization."]',
)

def test_ensure_organization_exists(self):
form = CredlyOrganizationAdminForm()
api_client = MagicMock()
api_client.fetch_organization.return_value = {"data": {"org_id": "test_org_id"}}

form._ensure_organization_exists(api_client)

api_client.fetch_organization.assert_called_once()
self.assertEqual(form.api_data, {"org_id": "test_org_id"})

def test_ensure_organization_exists_with_error(self):
form = CredlyOrganizationAdminForm()
api_client = MagicMock()
api_client.fetch_organization.side_effect = CredlyAPIError("API Error")

with self.assertRaises(forms.ValidationError) as cm:
form._ensure_organization_exists(api_client)

api_client.fetch_organization.assert_called_once()
self.assertEqual(str(cm.exception), "['API Error']")
42 changes: 42 additions & 0 deletions credentials/apps/badges/tests/test_api_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from unittest import mock
from django.test import TestCase
from requests.models import Response
from credentials.apps.badges.credly.api_client import CredlyAPIClient
from credentials.apps.badges.credly.exceptions import CredlyAPIError
from credentials.apps.badges.models import CredlyOrganization
from credentials.apps.badges.credly.exceptions import CredlyError

class CredlyApiClientTestCase(TestCase):
def setUp(self):
self.api_client = CredlyAPIClient("test_organization_id", "test_api_key")

def test_get_organization_nonexistent(self):
with mock.patch("credentials.apps.badges.credly.api_client.CredlyOrganization.objects.get") as mock_get:
mock_get.side_effect = CredlyOrganization.DoesNotExist
with self.assertRaises(CredlyError) as cm:
self.api_client._get_organization("nonexistent_organization_id")
self.assertEqual(str(cm.exception), "CredlyOrganization with the uuid nonexistent_organization_id does not exist!")

def test_perform_request(self):
with mock.patch("credentials.apps.badges.credly.api_client.requests.request") as mock_request:
mock_response = mock.Mock()
mock_response.json.return_value = {"key": "value"}
mock_request.return_value = mock_response
result = self.api_client.perform_request("GET", "/api/endpoint")
mock_request.assert_called_once_with("GET", "https://api.credly.com/api/endpoint", headers=self.api_client._get_headers(), json=None)
self.assertEqual(result, {"key": "value"})

def test_raise_for_error_success(self):
response = mock.Mock(spec=Response)
response.status_code = 200
self.api_client._raise_for_error(response)

def test_raise_for_error_error(self):
response = mock.Mock(spec=Response)
response.status_code = 404
response.text = "Not Found"
response.raise_for_status.side_effect = CredlyAPIError(f"Credly API: {response.text} ({response.status_code})")

with self.assertRaises(CredlyAPIError) as cm:
self.api_client._raise_for_error(response)
self.assertEqual(str(cm.exception), "Credly API: Not Found (404)")
13 changes: 13 additions & 0 deletions credentials/apps/badges/tests/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from opaque_keys.edx.keys import CourseKey
from openedx_events.learning.data import CourseData, CoursePassingStatusData, UserData, UserPersonalData

from credentials.apps.badges.exceptions import BadgesProcessingError
from credentials.apps.badges.models import (
BadgePenalty,
BadgeProgress,
Expand Down Expand Up @@ -631,3 +632,15 @@ class TestIdentifyUser(TestCase):
def test_identify_user(self):
username = identify_user(event_type=COURSE_PASSING_EVENT, event_payload=COURSE_PASSING_DATA)
self.assertEqual(username, "test_username")

def test_identify_user_not_found(self):
event_type = "unknown_event_type"
event_payload = None

with self.assertRaises(BadgesProcessingError) as cm:
identify_user(event_type="unknown_event_type", event_payload=event_payload)

self.assertEqual(
str(cm.exception),
f"User data cannot be found (got: None): {event_payload}. Does event {event_type} include user data at all?"
)
Loading