Skip to content

Commit

Permalink
Merge pull request #75 from eduNEXT/and/add_certificates_api
Browse files Browse the repository at this point in the history
feat: add certificates api client
  • Loading branch information
andrey-canon committed Aug 4, 2023
2 parents 413bca7 + d12faa2 commit ebcdb0b
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
68 changes: 68 additions & 0 deletions eox_nelp/api_clients/certificates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Client module for external certificate's API integration.
Classes:
ExternalCertificatesApiClient: Class to interact with NELP external certificates service.
"""
from django.conf import settings

from eox_nelp.api_clients import AbstractApiClient


class ExternalCertificatesApiClient(AbstractApiClient):
"""Allow to perform multiple external certificates operations."""

def __init__(self):
client_id = getattr(settings, "EXTERNAL_CERTIFICATES_API_CLIENT_ID")
client_secret = getattr(settings, "EXTERNAL_CERTIFICATES_API_CLIENT_SECRET")

super().__init__(client_id, client_secret)

@property
def base_url(self):
return getattr(settings, "EXTERNAL_CERTIFICATES_API_URL")

def create_external_certificate(self, certificate_data):
"""This will create an external certificate based on the input data, this data should have the
following keys:
id <mandatory>: edx-platform certificate identifier.
created_at <mandatory>: when the certificate was created.
expiration_date <mandatory>: when the certificate expires.
grade <mandatory>: The associated grade with the certificate.
is_passing <mandatory>: Boolean value that represent if the user has passed the course.
user <mandatory>: Dictionary with the following data:
national_id: User National identifier.
englishs_name <optional>: User name in English.
arabic_name <optional>: User name in Arabic.
Args:
certificate_data<Dict>: Information about a the certificate.
Returns:
response<Dict>: requests response as dictionary.
Raise:
KeyError: This will be raised when the mandatory are excluded in the certificate data.
"""
path = "certificates" # This is not clear at all
user = certificate_data["user"]
payload = {
"reference_id": certificate_data["id"],
"date": {
"issuance": str(certificate_data["created_at"]),
"expiration": str(certificate_data["expiration_date"]),
},
"individual": {
"name_en": user.get("english_name", ""),
"name_ar": user.get("arabic_name", ""),
"id": user["national_id"],
"id_type": "saudi",
},
"group_code": "fail", # This is not clear
"certificate_type": "completion", # What types do we have ?
"metadata": {
"degree": certificate_data["grade"],
"FAIL": certificate_data["is_passing"],
}
}

return self.make_post(path, payload)
65 changes: 65 additions & 0 deletions eox_nelp/api_clients/tests/tests_certificates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""This file contains all the test for certificates api client file.
Classes:
TestExternalCertificatesApiClient: Test for eox-nelp/api_clients/certificates.py.
"""
import unittest

from django.utils import timezone
from mock import patch

from eox_nelp.api_clients.certificates import ExternalCertificatesApiClient
from eox_nelp.api_clients.tests import BasicApiClientMixin


class TestExternalCertificatesApiClient(BasicApiClientMixin, unittest.TestCase):
"""Tests ExternalCertificatesApiClient"""

def setUp(self):
"""Setup common conditions for every test case"""
self.api_class = ExternalCertificatesApiClient

@patch.object(ExternalCertificatesApiClient, "make_post")
@patch.object(ExternalCertificatesApiClient, "_authenticate")
def test_create_certificate(self, auth_mock, post_mock):
"""Test successful post request.
Expected behavior:
- Response is the expected value
"""
auth_mock.return_value = {}
expected_value = {
"status": {"success": True, "message": "successful", "code": 1}
}
post_mock.return_value = expected_value
user = {
"national_id": "10224587",
"english_name": " Testing",
"arabic_name": "اختبارات",
}
data = {
"id": "124ABC",
"created_at": timezone.now(),
"expiration_date": timezone.now() + timezone.timedelta(days=365),
"grade": 10,
"is_passing": True,
"user": user,
}
api_client = self.api_class()

response = api_client.create_external_certificate(data)

self.assertDictEqual(response, expected_value)

@patch.object(ExternalCertificatesApiClient, "_authenticate")
def test_failed_create_certificate(self, auth_mock):
"""Test when the mandatory fields has not been sent.
Expected behavior:
- Raise KeyError exception.
"""
auth_mock.return_value = {}
data = {}
api_client = ExternalCertificatesApiClient()

self.assertRaises(KeyError, api_client.create_external_certificate, data)
3 changes: 3 additions & 0 deletions eox_nelp/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def plugin_settings(settings): # pylint: disable=function-redefined
settings.FUTUREX_API_CLIENT_ID = 'my-test-client-id'
settings.FUTUREX_API_CLIENT_SECRET = 'my-test-client-secret'
settings.FUTUREX_NOTIFY_SUBSECTION_SUBJECT_MESSAGE = DEFAULT_FUTUREX_NOTIFY_SUBSECTION_SUBJECT_MESSAGE # noqa: F405
settings.EXTERNAL_CERTIFICATES_API_URL = 'https://testing.com'
settings.EXTERNAL_CERTIFICATES_API_CLIENT_ID = 'my-test-client-id'
settings.EXTERNAL_CERTIFICATES_API_CLIENT_SECRET = 'my-test-client-secret'


SETTINGS = SettingsClass()
Expand Down

0 comments on commit ebcdb0b

Please sign in to comment.