@@ -3,16 +3,11 @@
|
||||
import uuid
|
||||
from unittest import mock
|
||||
|
||||
from django.conf import settings
|
||||
from requests import Response
|
||||
from requests.exceptions import HTTPError
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
|
||||
from openedx.core.djangoapps.credentials.tests import factories
|
||||
from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin
|
||||
from openedx.core.djangoapps.credentials.utils import (
|
||||
get_courses_completion_status,
|
||||
get_credentials,
|
||||
get_credentials_records_url,
|
||||
)
|
||||
@@ -107,33 +102,3 @@ class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
|
||||
|
||||
result = get_credentials_records_url("abcdefgh-ijkl-mnop-qrst-uvwxyz123456")
|
||||
assert result == "https://credentials.example.com/records/programs/abcdefghijklmnopqrstuvwxyz123456"
|
||||
|
||||
@mock.patch("requests.Response.raise_for_status")
|
||||
@mock.patch("requests.Response.json")
|
||||
@mock.patch(UTILS_MODULE + ".get_credentials_api_client")
|
||||
def test_get_courses_completion_status(self, mock_get_api_client, mock_json, mock_raise):
|
||||
"""
|
||||
Test to verify the functionality of get_courses_completion_status
|
||||
"""
|
||||
UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
|
||||
course_statuses = factories.UserCredentialsCourseRunStatus.create_batch(3)
|
||||
response_data = [course_status["course_run"]["key"] for course_status in course_statuses]
|
||||
mock_raise.return_value = None
|
||||
mock_json.return_value = {
|
||||
"lms_user_id": self.user.id,
|
||||
"status": course_statuses,
|
||||
"username": self.user.username,
|
||||
}
|
||||
mock_get_api_client.return_value.post.return_value = Response()
|
||||
course_run_keys = [course_status["course_run"]["key"] for course_status in course_statuses]
|
||||
api_response, is_exception = get_courses_completion_status(self.user.id, course_run_keys)
|
||||
assert api_response == response_data
|
||||
assert is_exception is False
|
||||
|
||||
@mock.patch("requests.Response.raise_for_status")
|
||||
def test_get_courses_completion_status_api_error(self, mock_raise):
|
||||
mock_raise.return_value = HTTPError("An Error occured")
|
||||
UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
|
||||
api_response, is_exception = get_courses_completion_status(self.user.id, ["fake1", "fake2", "fake3"])
|
||||
assert api_response == []
|
||||
assert is_exception is True
|
||||
|
||||
@@ -5,7 +5,6 @@ from typing import Dict, List
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from edx_rest_api_client.auth import SuppliedJwtAuth
|
||||
|
||||
@@ -121,59 +120,3 @@ def get_credentials(
|
||||
cache_key=cache_key,
|
||||
raise_on_error=raise_on_error,
|
||||
)
|
||||
|
||||
|
||||
def get_courses_completion_status(username, course_run_ids):
|
||||
"""
|
||||
Given the username and course run ids, checks for course completion status
|
||||
Arguments:
|
||||
username (User): Username of the user whose credentials are being requested.
|
||||
course_run_ids(List): list of course run ids for which we need to check the completion status
|
||||
Returns:
|
||||
list of course_run_ids for which user has completed the course
|
||||
Boolean: True if an exception occurred while calling the api, False otherwise
|
||||
"""
|
||||
credential_configuration = CredentialsApiConfig.current()
|
||||
if not credential_configuration.enabled:
|
||||
log.warning("%s configuration is disabled.", credential_configuration.API_NAME)
|
||||
return [], False
|
||||
|
||||
completion_status_url = f"{settings.CREDENTIALS_INTERNAL_SERVICE_URL}/api" "/credentials/v1/learner_cert_status/"
|
||||
try:
|
||||
api_client = get_credentials_api_client(User.objects.get(username=settings.CREDENTIALS_SERVICE_USERNAME))
|
||||
api_response = api_client.post(
|
||||
completion_status_url,
|
||||
json={
|
||||
"username": username,
|
||||
"course_runs": course_run_ids,
|
||||
},
|
||||
)
|
||||
api_response.raise_for_status()
|
||||
course_completion_response = api_response.json()
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
log.exception(
|
||||
"An unexpected error occurred while reqeusting course completion statuses "
|
||||
"for user [%s] for course_run_ids [%s] with exc [%s]:",
|
||||
username,
|
||||
course_run_ids,
|
||||
exc,
|
||||
)
|
||||
return [], True
|
||||
log.info(
|
||||
"Course completion status response for user [%s] for course_run_ids [%s] is [%s]",
|
||||
username,
|
||||
course_run_ids,
|
||||
course_completion_response,
|
||||
)
|
||||
# Yes, This is course_credentials_data. The key is named status but
|
||||
# it contains all the courses data from credentials.
|
||||
course_credentials_data = course_completion_response.get("status", [])
|
||||
if course_credentials_data is not None:
|
||||
filtered_records = [
|
||||
course_data["course_run"]["key"]
|
||||
for course_data in course_credentials_data
|
||||
if course_data["course_run"]["key"] in course_run_ids
|
||||
and course_data["status"] == settings.CREDENTIALS_COURSE_COMPLETION_STATE
|
||||
]
|
||||
return filtered_records, False
|
||||
return [], False
|
||||
|
||||
Reference in New Issue
Block a user