diff --git a/lms/djangoapps/learner_dashboard/tests/test_programs.py b/lms/djangoapps/learner_dashboard/tests/test_programs.py
index 23d0301362..27c3ad024e 100644
--- a/lms/djangoapps/learner_dashboard/tests/test_programs.py
+++ b/lms/djangoapps/learner_dashboard/tests/test_programs.py
@@ -4,7 +4,6 @@ Unit tests covering the program listing and detail pages.
"""
import json
import re
-import unittest
from urlparse import urljoin
from uuid import uuid4
@@ -16,8 +15,6 @@ import mock
from openedx.core.djangoapps.catalog.tests.factories import ProgramFactory, CourseFactory, CourseRunFactory
from openedx.core.djangoapps.catalog.tests.mixins import CatalogIntegrationMixin
-from openedx.core.djangoapps.credentials.tests.factories import UserCredential, ProgramCredential
-from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin
from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin
from openedx.core.djangolib.testing.utils import skip_unless_lms
from student.tests.factories import UserFactory, CourseEnrollmentFactory
@@ -25,15 +22,13 @@ from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory as ModuleStoreCourseFactory
-CATALOG_UTILS_MODULE = 'openedx.core.djangoapps.catalog.utils'
-CREDENTIALS_UTILS_MODULE = 'openedx.core.djangoapps.credentials.utils'
PROGRAMS_UTILS_MODULE = 'openedx.core.djangoapps.programs.utils'
@skip_unless_lms
@override_settings(MKTG_URLS={'ROOT': 'https://www.example.com'})
@mock.patch(PROGRAMS_UTILS_MODULE + '.get_programs')
-class TestProgramListing(ProgramsApiConfigMixin, CredentialsApiConfigMixin, SharedModuleStoreTestCase):
+class TestProgramListing(ProgramsApiConfigMixin, SharedModuleStoreTestCase):
"""Unit tests for the program listing page."""
maxDiff = None
password = 'test'
@@ -65,15 +60,6 @@ class TestProgramListing(ProgramsApiConfigMixin, CredentialsApiConfigMixin, Shar
"""
return program['title']
- def credential_sort_key(self, credential):
- """
- Helper function used to sort dictionaries representing credentials.
- """
- try:
- return credential['certificate_url']
- except KeyError:
- return credential['credential_url']
-
def load_serialized_data(self, response, key):
"""
Extract and deserialize serialized data from the response.
@@ -184,48 +170,6 @@ class TestProgramListing(ProgramsApiConfigMixin, CredentialsApiConfigMixin, Shar
expected_url = reverse('program_details_view', kwargs={'program_uuid': expected_program['uuid']})
self.assertEqual(actual_program['detail_url'], expected_url)
- @mock.patch(CREDENTIALS_UTILS_MODULE + '.get_credentials')
- @mock.patch(CREDENTIALS_UTILS_MODULE + '.get_programs')
- def test_certificates_listed(self, mock_get_programs, mock_get_credentials, __):
- """
- Verify that the response contains accurate certificate data when certificates are available.
- """
- self.create_programs_config()
- self.create_credentials_config(is_learner_issuance_enabled=True)
-
- mock_get_programs.return_value = self.data
-
- first_credential = UserCredential(
- username=self.user.username,
- credential=ProgramCredential(
- program_uuid=self.first_program['uuid']
- )
- )
- second_credential = UserCredential(
- username=self.user.username,
- credential=ProgramCredential(
- program_uuid=self.second_program['uuid']
- )
- )
-
- credentials_data = sorted([first_credential, second_credential], key=self.credential_sort_key)
- mock_get_credentials.return_value = credentials_data
-
- response = self.client.get(self.url)
- actual = self.load_serialized_data(response, 'certificatesData')
- actual = sorted(actual, key=self.credential_sort_key)
-
- self.assertEqual(len(actual), len(credentials_data))
- for index, actual_credential in enumerate(actual):
- expected_credential = credentials_data[index]
-
- self.assertEqual(
- # TODO: certificate_url is needlessly transformed to credential_url. (╯°□°)╯︵ ┻━┻
- # Clean this up!
- actual_credential['credential_url'],
- expected_credential['certificate_url']
- )
-
@skip_unless_lms
@mock.patch(PROGRAMS_UTILS_MODULE + '.get_programs')
diff --git a/lms/djangoapps/learner_dashboard/views.py b/lms/djangoapps/learner_dashboard/views.py
index d8d8207705..f8411ca5df 100644
--- a/lms/djangoapps/learner_dashboard/views.py
+++ b/lms/djangoapps/learner_dashboard/views.py
@@ -7,7 +7,6 @@ from django.views.decorators.http import require_GET
from edxmako.shortcuts import render_to_response
from lms.djangoapps.learner_dashboard.utils import strip_course_id, FAKE_COURSE_KEY
from openedx.core.djangoapps.catalog.utils import get_programs
-from openedx.core.djangoapps.credentials.utils import get_programs_credentials
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.programs.utils import (
get_program_marketing_url,
@@ -29,7 +28,6 @@ def program_listing(request):
meter = ProgramProgressMeter(request.user)
context = {
- 'credentials': get_programs_credentials(request.user),
'disable_courseware_js': True,
'marketing_url': get_program_marketing_url(programs_config),
'nav_hidden': True,
diff --git a/lms/static/js/learner_dashboard/views/certificate_view.js b/lms/static/js/learner_dashboard/views/certificate_view.js
deleted file mode 100644
index 6cb4ad3d36..0000000000
--- a/lms/static/js/learner_dashboard/views/certificate_view.js
+++ /dev/null
@@ -1,39 +0,0 @@
-(function(define) {
- 'use strict';
- define(['backbone',
- 'jquery',
- 'underscore',
- 'gettext',
- 'text!../../../templates/learner_dashboard/certificate.underscore'
- ],
- function(
- Backbone,
- $,
- _,
- gettext,
- certificateTpl
- ) {
- return Backbone.View.extend({
- el: '.certificates-list',
- tpl: _.template(certificateTpl),
- initialize: function(data) {
- this.context = data.context;
- this.render();
- },
- render: function() {
- var certificatesData = this.context.certificatesData || [];
-
- if (certificatesData.length) {
- this.$el.html(this.tpl(this.context));
- } else {
- /**
- * If not rendering remove el because
- * styles are applied to it
- */
- this.remove();
- }
- }
- });
- }
- );
-}).call(this, define || RequireJS.define);
diff --git a/lms/static/js/learner_dashboard/views/sidebar_view.js b/lms/static/js/learner_dashboard/views/sidebar_view.js
index c7bd481dbc..77340e4fd1 100644
--- a/lms/static/js/learner_dashboard/views/sidebar_view.js
+++ b/lms/static/js/learner_dashboard/views/sidebar_view.js
@@ -6,7 +6,6 @@
'underscore',
'gettext',
'js/learner_dashboard/views/explore_new_programs_view',
- 'js/learner_dashboard/views/certificate_view',
'text!../../../templates/learner_dashboard/sidebar.underscore'
],
function(
@@ -15,7 +14,6 @@
_,
gettext,
NewProgramsView,
- CertificateView,
sidebarTpl
) {
return Backbone.View.extend({
@@ -36,10 +34,6 @@
this.newProgramsView = new NewProgramsView({
context: this.context
});
-
- this.newCertificateView = new CertificateView({
- context: this.context
- });
}
});
}
diff --git a/lms/static/js/spec/learner_dashboard/certificate_view_spec.js b/lms/static/js/spec/learner_dashboard/certificate_view_spec.js
deleted file mode 100644
index 2f2ed20fc9..0000000000
--- a/lms/static/js/spec/learner_dashboard/certificate_view_spec.js
+++ /dev/null
@@ -1,62 +0,0 @@
-define([
- 'backbone',
- 'jquery',
- 'js/learner_dashboard/views/certificate_view'
-], function(Backbone, $, CertificateView) {
- 'use strict';
- describe('Certificate View', function() {
- var view = null,
- data = {
- context: {
- certificatesData: [
- {
- 'display_name': 'Testing',
- 'credential_url': 'https://credentials.stage.edx.org/credentials/dummy-uuid-1/'
- },
- {
- 'display_name': 'Testing2',
- 'credential_url': 'https://credentials.stage.edx.org/credentials/dummy-uuid-2/'
- }
- ],
- sampleCertImageSrc: '/images/programs/sample-cert.png'
- }
- };
-
- beforeEach(function() {
- setFixtures('
');
- view = new CertificateView(data);
- view.render();
- });
-
- afterEach(function() {
- view.remove();
- });
-
- it('should exist', function() {
- expect(view).toBeDefined();
- });
-
- it('should load the certificates based on passed in certificates list', function() {
- var $certificates = view.$el.find('.certificate-link');
- expect($certificates.length).toBe(2);
-
- $certificates.each(function(index, el) {
- expect($(el).html().trim()).toEqual(data.context.certificatesData[index].display_name);
- expect($(el).attr('href')).toEqual(data.context.certificatesData[index].credential_url);
- });
- expect(view.$el.find('.hd-6').html().trim()).toEqual('Program Certificates');
- expect(view.$el.find('img').attr('src')).toEqual(data.context.sampleCertImageSrc);
- });
-
- it('should display no certificate box if certificates list is empty', function() {
- view.remove();
- setFixtures('');
- view = new CertificateView({
- context: {certificatesData: []}
- });
- view.render();
- expect(view.$('.certificates-list').length).toBe(0);
- });
- });
-}
-);
diff --git a/lms/static/js/spec/learner_dashboard/sidebar_view_spec.js b/lms/static/js/spec/learner_dashboard/sidebar_view_spec.js
index 7bc6e9fead..67368ccaf5 100644
--- a/lms/static/js/spec/learner_dashboard/sidebar_view_spec.js
+++ b/lms/static/js/spec/learner_dashboard/sidebar_view_spec.js
@@ -9,14 +9,7 @@ define([
describe('Sidebar View', function() {
var view = null,
context = {
- marketingUrl: 'https://www.example.org/programs',
- certificatesData: [
- {
- 'display_name': 'Testing',
- 'credential_url': 'https://credentials.example.com/credentials/uuid/'
- }
- ],
- sampleCertImageSrc: '/images/programs/sample-cert.png'
+ marketingUrl: 'https://www.example.org/programs'
};
beforeEach(function() {
@@ -44,21 +37,16 @@ define([
expect($sidebar.find('.program-advertise .ad-link a').attr('href')).toEqual(context.marketingUrl);
});
- it('should load the certificates based on passed in certificates list', function() {
- expect(view.$('.certificate-link').length).toBe(1);
- });
-
it('should not load the advertising panel if no marketing URL is provided', function() {
var $ad;
view.remove();
view = new SidebarView({
el: '.sidebar',
- context: {certificatesData: []}
+ context: {}
});
view.render();
$ad = view.$el.find('.program-advertise');
expect($ad.length).toBe(0);
- expect(view.$('.certificate-link').length).toBe(0);
});
});
}
diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js
index 11ff778593..b6f4374cfe 100644
--- a/lms/static/lms/js/spec/main.js
+++ b/lms/static/lms/js/spec/main.js
@@ -737,7 +737,6 @@
'js/spec/instructor_dashboard/certificates_spec.js',
'js/spec/instructor_dashboard/ecommerce_spec.js',
'js/spec/instructor_dashboard/student_admin_spec.js',
- 'js/spec/learner_dashboard/certificate_view_spec.js',
'js/spec/learner_dashboard/collection_list_view_spec.js',
'js/spec/learner_dashboard/program_card_view_spec.js',
'js/spec/learner_dashboard/sidebar_view_spec.js',
diff --git a/lms/static/sass/views/_program-list.scss b/lms/static/sass/views/_program-list.scss
index 1f552a98b4..17dd16f0f7 100644
--- a/lms/static/sass/views/_program-list.scss
+++ b/lms/static/sass/views/_program-list.scss
@@ -43,27 +43,6 @@
margin-bottom: $baseline;
}
}
-
- .certificate-container {
- .hd-6 {
- color: palette(grayscale, dark);
- font-weight: font-weight(normal);
- margin-bottom: $baseline;
- }
-
- .certificate-link {
- padding-top: $baseline;
- color: palette(primary, base);
- display: block;
-
- &:active,
- &:focus,
- &:hover {
- color: $link-hover;
- text-decoration: underline;
- }
- }
- }
}
.empty-programs-message {
diff --git a/lms/templates/learner_dashboard/certificate.underscore b/lms/templates/learner_dashboard/certificate.underscore
deleted file mode 100644
index f7b85ddf90..0000000000
--- a/lms/templates/learner_dashboard/certificate.underscore
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/lms/templates/learner_dashboard/programs.html b/lms/templates/learner_dashboard/programs.html
index 062be9930b..1184eb827d 100644
--- a/lms/templates/learner_dashboard/programs.html
+++ b/lms/templates/learner_dashboard/programs.html
@@ -15,10 +15,8 @@ from openedx.core.djangolib.js_utils import (
<%block name="js_extra">
<%static:require_module module_name="js/learner_dashboard/program_list_factory" class_name="ProgramListFactory">
ProgramListFactory({
- certificatesData: ${credentials | n, dump_js_escaped_json},
marketingUrl: '${marketing_url | n, js_escaped_string}',
programsData: ${programs | n, dump_js_escaped_json},
- sampleCertImageSrc: '${static.url('images/programs/sample-cert.png') | n, js_escaped_string}',
userProgress: ${progress | n, dump_js_escaped_json}
});
%static:require_module>
diff --git a/lms/templates/learner_dashboard/sidebar.underscore b/lms/templates/learner_dashboard/sidebar.underscore
index 8ea51b42a8..4dad7961fc 100644
--- a/lms/templates/learner_dashboard/sidebar.underscore
+++ b/lms/templates/learner_dashboard/sidebar.underscore
@@ -1,2 +1 @@
-
diff --git a/openedx/core/djangoapps/catalog/tests/factories.py b/openedx/core/djangoapps/catalog/tests/factories.py
index ae916b92e9..5f4dabf9c4 100644
--- a/openedx/core/djangoapps/catalog/tests/factories.py
+++ b/openedx/core/djangoapps/catalog/tests/factories.py
@@ -35,6 +35,10 @@ def generate_zulu_datetime():
class DictFactoryBase(factory.Factory):
+ """
+ Subclass this to make factories that can be used to produce fake API response
+ bodies for testing.
+ """
class Meta(object):
model = dict
diff --git a/openedx/core/djangoapps/credentials/tests/factories.py b/openedx/core/djangoapps/credentials/tests/factories.py
index 51ddf2324c..87a2cbed80 100644
--- a/openedx/core/djangoapps/credentials/tests/factories.py
+++ b/openedx/core/djangoapps/credentials/tests/factories.py
@@ -1,43 +1,31 @@
"""Factories for generating fake credentials-related data."""
-import uuid
+# pylint: disable=missing-docstring, invalid-name
+from functools import partial
import factory
-from factory.fuzzy import FuzzyText
+
+from openedx.core.djangoapps.catalog.tests.factories import (
+ generate_instances,
+ generate_course_run_key,
+ DictFactoryBase,
+)
-class UserCredential(factory.Factory):
- """Factory for stubbing user credentials resources from the User Credentials
- API (v1).
- """
- class Meta(object):
- model = dict
-
- id = factory.Sequence(lambda n: n) # pylint: disable=invalid-name
- username = FuzzyText(prefix='user_')
- status = 'awarded'
- uuid = FuzzyText(prefix='uuid_')
- certificate_url = FuzzyText(prefix='https://www.example.com/credentials/')
- credential = {}
+class ProgramCredential(DictFactoryBase):
+ credential_id = factory.Faker('random_int')
+ program_uuid = factory.Faker('uuid4')
-class ProgramCredential(factory.Factory):
- """Factory for stubbing program credentials resources from the Program
- Credentials API (v1).
- """
- class Meta(object):
- model = dict
-
- credential_id = factory.Sequence(lambda n: n)
- program_uuid = factory.LazyAttribute(lambda obj: str(uuid.uuid4()))
-
-
-class CourseCredential(factory.Factory):
- """Factory for stubbing course credentials resources from the Course
- Credentials API (v1).
- """
- class Meta(object):
- model = dict
-
- course_id = 'edx/test01/2015'
- credential_id = factory.Sequence(lambda n: n)
+class CourseCredential(DictFactoryBase):
+ credential_id = factory.Faker('random_int')
+ course_id = factory.LazyFunction(generate_course_run_key)
certificate_type = 'verified'
+
+
+class UserCredential(DictFactoryBase):
+ id = factory.Faker('random_int')
+ username = factory.Faker('word')
+ status = 'awarded'
+ uuid = factory.Faker('uuid4')
+ certificate_url = factory.Faker('url')
+ credential = factory.LazyFunction(partial(generate_instances, ProgramCredential, count=1))
diff --git a/openedx/core/djangoapps/credentials/tests/mixins.py b/openedx/core/djangoapps/credentials/tests/mixins.py
index 0ba9e7e9a8..8472153fb7 100644
--- a/openedx/core/djangoapps/credentials/tests/mixins.py
+++ b/openedx/core/djangoapps/credentials/tests/mixins.py
@@ -27,94 +27,3 @@ class CredentialsApiConfigMixin(object):
CredentialsApiConfig(**fields).save()
return CredentialsApiConfig.current()
-
-
-class CredentialsDataMixin(object):
- """Mixin mocking Credentials API URLs and providing fake data for testing."""
- CREDENTIALS_API_RESPONSE = {
- "next": None,
- "results": [
- factories.UserCredential(
- id=1,
- username='test',
- credential=factories.ProgramCredential()
- ),
- factories.UserCredential(
- id=2,
- username='test',
- credential=factories.ProgramCredential()
- ),
- factories.UserCredential(
- id=3,
- status='revoked',
- username='test',
- credential=factories.ProgramCredential()
- ),
- factories.UserCredential(
- id=4,
- username='test',
- credential=factories.CourseCredential(
- certificate_type='honor'
- )
- ),
- factories.UserCredential(
- id=5,
- username='test',
- credential=factories.CourseCredential(
- course_id='edx/test02/2015'
- )
- ),
- factories.UserCredential(
- id=6,
- username='test',
- credential=factories.CourseCredential(
- course_id='edx/test02/2015'
- )
- ),
- ]
- }
-
- CREDENTIALS_NEXT_API_RESPONSE = {
- "next": None,
- "results": [
- factories.UserCredential(
- id=7,
- username='test',
- credential=factories.ProgramCredential()
- ),
- factories.UserCredential(
- id=8,
- username='test',
- credential=factories.ProgramCredential()
- )
- ]
- }
-
- def mock_credentials_api(self, user, data=None, status_code=200, reset_url=True, is_next_page=False):
- """Utility for mocking out Credentials API URLs."""
- self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Credentials API calls.')
- internal_api_url = CredentialsApiConfig.current().internal_api_url.strip('/')
-
- url = internal_api_url + '/credentials/?status=awarded&username=' + user.username
- if reset_url:
- httpretty.reset()
-
- if data is None:
- data = self.CREDENTIALS_API_RESPONSE
-
- body = json.dumps(data)
-
- if is_next_page:
- next_page_url = internal_api_url + '/credentials/?page=2&status=awarded&username=' + user.username
- self.CREDENTIALS_NEXT_API_RESPONSE['next'] = next_page_url
- next_page_body = json.dumps(self.CREDENTIALS_NEXT_API_RESPONSE)
- httpretty.register_uri(
- httpretty.GET, next_page_url, body=body, content_type='application/json', status=status_code
- )
- httpretty.register_uri(
- httpretty.GET, url, body=next_page_body, content_type='application/json', status=status_code
- )
- else:
- httpretty.register_uri(
- httpretty.GET, url, body=body, content_type='application/json', status=status_code
- )
diff --git a/openedx/core/djangoapps/credentials/tests/test_utils.py b/openedx/core/djangoapps/credentials/tests/test_utils.py
index 17c1812091..334d881688 100644
--- a/openedx/core/djangoapps/credentials/tests/test_utils.py
+++ b/openedx/core/djangoapps/credentials/tests/test_utils.py
@@ -1,218 +1,70 @@
"""Tests covering Credentials utilities."""
import uuid
-from django.core.cache import cache
from edx_oauth2_provider.tests.factories import ClientFactory
-import httpretty
import mock
from nose.plugins.attrib import attr
from provider.constants import CONFIDENTIAL
-from openedx.core.djangoapps.catalog.tests.factories import ProgramFactory
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
-from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin, CredentialsDataMixin
-from openedx.core.djangoapps.credentials.utils import (
- get_credentials,
- get_user_program_credentials,
- get_programs_credentials,
- get_programs_for_credentials
-)
+from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin
+from openedx.core.djangoapps.credentials.utils import get_credentials
from openedx.core.djangoapps.credentials.tests import factories
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms
from student.tests.factories import UserFactory
+UTILS_MODULE = 'openedx.core.djangoapps.credentials.utils'
+
+
@skip_unless_lms
@attr(shard=2)
-class TestCredentialsRetrieval(CredentialsApiConfigMixin, CredentialsDataMixin, CacheIsolationTestCase):
- """ Tests covering the retrieval of user credentials from the Credentials
- service.
- """
-
+@mock.patch(UTILS_MODULE + '.get_edx_api_data')
+class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
ENABLED_CACHES = ['default']
def setUp(self):
- super(TestCredentialsRetrieval, self).setUp()
+ super(TestGetCredentials, self).setUp()
ClientFactory(name=CredentialsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL)
- self.user = UserFactory()
- self.primary_uuid = str(uuid.uuid4())
- self.alternate_uuid = str(uuid.uuid4())
- cache.clear()
-
- def expected_credentials_display_data(self, programs):
- """ Returns expected credentials data to be represented. """
- return [
- {
- 'display_name': programs[0]['title'],
- 'subtitle': programs[0]['subtitle'],
- 'credential_url': programs[0]['credential_url']
- },
- {
- 'display_name': programs[1]['title'],
- 'subtitle': programs[1]['subtitle'],
- 'credential_url': programs[1]['credential_url']
- }
- ]
-
- @httpretty.activate
- def test_get_credentials(self):
- """Verify user credentials data can be retrieve."""
self.create_credentials_config()
- self.mock_credentials_api(self.user)
+ self.user = UserFactory()
+
+ def test_get_many(self, mock_get_edx_api_data):
+ expected = factories.UserCredential.create_batch(3)
+ mock_get_edx_api_data.return_value = expected
actual = get_credentials(self.user)
- self.assertEqual(actual, self.CREDENTIALS_API_RESPONSE['results'])
- @httpretty.activate
- def test_get_credentials_caching(self):
- """Verify that when enabled, the cache is used for non-staff users."""
- self.create_credentials_config(cache_ttl=1)
- self.mock_credentials_api(self.user)
+ mock_get_edx_api_data.assert_called_once()
+ call = mock_get_edx_api_data.mock_calls[0]
+ __, __, kwargs = call
- # Warm up the cache.
- get_credentials(self.user)
-
- # Hit the cache.
- get_credentials(self.user)
-
- # Verify only one request was made.
- self.assertEqual(len(httpretty.httpretty.latest_requests), 1)
-
- staff_user = UserFactory(is_staff=True)
-
- # Hit the Credentials API twice.
- for _ in range(2):
- get_credentials(staff_user)
-
- # Verify that three requests have been made (one for student, two for staff).
- self.assertEqual(len(httpretty.httpretty.latest_requests), 3)
-
- def test_get_user_program_credentials_issuance_disable(self):
- """Verify that user program credentials cannot be retrieved if issuance is disabled."""
- self.create_credentials_config(enable_learner_issuance=False)
- actual = get_user_program_credentials(self.user)
- self.assertEqual(actual, [])
-
- @httpretty.activate
- def test_get_user_program_credentials_no_credential(self):
- """Verify behavior if no credential exist."""
- self.create_credentials_config()
- self.mock_credentials_api(self.user, data={'results': []})
- actual = get_user_program_credentials(self.user)
- self.assertEqual(actual, [])
-
- @httpretty.activate
- def test_get_user_programs_credentials(self):
- """Verify program credentials data can be retrieved and parsed correctly."""
- # create credentials and program configuration
- self.create_credentials_config()
-
- # Mocking the API responses from programs and credentials
- primary_uuid, alternate_uuid = str(uuid.uuid4()), str(uuid.uuid4())
- credentials_api_response = {
- "next": None,
- "results": [
- factories.UserCredential(
- username='test',
- credential=factories.ProgramCredential(program_uuid=primary_uuid)
- ),
- factories.UserCredential(
- username='test',
- credential=factories.ProgramCredential(program_uuid=alternate_uuid)
- )
- ]
+ querystring = {
+ 'username': self.user.username,
+ 'status': 'awarded',
}
- self.mock_credentials_api(self.user, data=credentials_api_response, reset_url=False)
- programs = [
- ProgramFactory(uuid=primary_uuid), ProgramFactory(uuid=alternate_uuid)
- ]
+ self.assertEqual(kwargs['querystring'], querystring)
- with mock.patch("openedx.core.djangoapps.credentials.utils.get_programs_for_credentials") as mock_get_programs:
- mock_get_programs.return_value = programs
- actual = get_user_program_credentials(self.user)
+ self.assertEqual(actual, expected)
- # checking response from API is as expected
- self.assertEqual(len(actual), 2)
- self.assertEqual(actual, programs)
+ def test_get_one(self, mock_get_edx_api_data):
+ expected = factories.UserCredential()
+ mock_get_edx_api_data.return_value = expected
- @httpretty.activate
- def test_get_programs_credentials(self):
- """ Verify that the program credentials data required for display can
- be retrieved.
- """
- # create credentials and program configuration
- self.create_credentials_config()
+ program_uuid = str(uuid.uuid4())
+ actual = get_credentials(self.user, program_uuid=program_uuid)
- # Mocking the API responses from programs and credentials
- primary_uuid, alternate_uuid = str(uuid.uuid4()), str(uuid.uuid4())
- credentials_api_response = {
- "next": None,
- "results": [
- factories.UserCredential(
- username='test',
- credential=factories.ProgramCredential(program_uuid=primary_uuid)
- ),
- factories.UserCredential(
- username='test',
- credential=factories.ProgramCredential(program_uuid=alternate_uuid)
- )
- ]
+ mock_get_edx_api_data.assert_called_once()
+ call = mock_get_edx_api_data.mock_calls[0]
+ __, __, kwargs = call
+
+ querystring = {
+ 'username': self.user.username,
+ 'status': 'awarded',
+ 'program_uuid': program_uuid,
}
- self.mock_credentials_api(self.user, data=credentials_api_response, reset_url=False)
- programs = [
- ProgramFactory(uuid=primary_uuid), ProgramFactory(uuid=alternate_uuid)
- ]
+ self.assertEqual(kwargs['querystring'], querystring)
- with mock.patch("openedx.core.djangoapps.credentials.utils.get_programs") as mock_get_programs:
- mock_get_programs.return_value = programs
- actual = get_programs_credentials(self.user)
- expected = self.expected_credentials_display_data(programs)
-
- # Checking result is as expected
- self.assertEqual(len(actual), 2)
- self.assertEqual(actual, expected)
-
- def _expected_program_credentials_data(self):
- """
- Dry method for getting expected program credentials response data.
- """
- return [
- factories.UserCredential(
- username='test',
- credential=factories.ProgramCredential(
- program_uuid=self.primary_uuid
- )
- ),
- factories.UserCredential(
- username='test',
- credential=factories.ProgramCredential(
- program_uuid=self.alternate_uuid
- )
- )
- ]
-
- def test_get_program_for_certificates(self):
- """Verify programs data can be retrieved and parsed correctly for certificates."""
- programs = [
- ProgramFactory(uuid=self.primary_uuid),
- ProgramFactory(uuid=self.alternate_uuid)
- ]
-
- program_credentials_data = self._expected_program_credentials_data()
- with mock.patch("openedx.core.djangoapps.credentials.utils.get_programs") as patched_get_programs:
- patched_get_programs.return_value = programs
- actual = get_programs_for_credentials(program_credentials_data)
-
- self.assertEqual(len(actual), 2)
- self.assertEqual(actual, programs)
-
- def test_get_program_for_certificates_no_data(self):
- """Verify behavior when no programs data is found for the user."""
- program_credentials_data = self._expected_program_credentials_data()
- with mock.patch("openedx.core.djangoapps.credentials.utils.get_programs") as patched_get_programs:
- patched_get_programs.return_value = []
- actual = get_programs_for_credentials(program_credentials_data)
-
- self.assertEqual(actual, [])
+ self.assertEqual(actual, expected)
diff --git a/openedx/core/djangoapps/credentials/utils.py b/openedx/core/djangoapps/credentials/utils.py
index 38eced303c..45348afdef 100644
--- a/openedx/core/djangoapps/credentials/utils.py
+++ b/openedx/core/djangoapps/credentials/utils.py
@@ -1,18 +1,13 @@
"""Helper functions for working with Credentials."""
from __future__ import unicode_literals
-import logging
-
from django.conf import settings
from edx_rest_api_client.client import EdxRestApiClient
-from openedx.core.djangoapps.catalog.utils import get_programs
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
from openedx.core.lib.edx_api_utils import get_edx_api_data
from openedx.core.lib.token_utils import JwtBuilder
-log = logging.getLogger(__name__)
-
def get_credentials_api_client(user):
""" Returns an authenticated Credentials API client. """
@@ -53,89 +48,3 @@ def get_credentials(user, program_uuid=None):
return get_edx_api_data(
credential_configuration, 'credentials', api=api, querystring=querystring, cache_key=cache_key
)
-
-
-def get_programs_for_credentials(programs_credentials):
- """ Given a user and an iterable of credentials, get corresponding programs
- data and return it as a list of dictionaries.
-
- Arguments:
- programs_credentials (list): List of credentials awarded to the user
- for completion of a program.
-
- Returns:
- list, containing programs dictionaries.
- """
- certified_programs = []
- programs = get_programs()
- for program in programs:
- for credential in programs_credentials:
- if program['uuid'] == credential['credential']['program_uuid']:
- program['credential_url'] = credential['certificate_url']
- certified_programs.append(program)
-
- return certified_programs
-
-
-def get_user_program_credentials(user):
- """Given a user, get the list of all program credentials earned and returns
- list of dictionaries containing related programs data.
-
- Arguments:
- user (User): The user object for getting programs credentials.
-
- Returns:
- list, containing programs dictionaries.
- """
- programs_credentials_data = []
- credential_configuration = CredentialsApiConfig.current()
- if not credential_configuration.is_learner_issuance_enabled:
- log.debug('Display of certificates for programs is disabled.')
- return programs_credentials_data
-
- credentials = get_credentials(user)
- if not credentials:
- log.info('No credential earned by the given user.')
- return programs_credentials_data
-
- programs_credentials = []
- for credential in credentials:
- try:
- if 'program_uuid' in credential['credential']:
- programs_credentials.append(credential)
- except KeyError:
- log.exception('Invalid credential structure: %r', credential)
-
- if programs_credentials:
- programs_credentials_data = get_programs_for_credentials(programs_credentials)
-
- return programs_credentials_data
-
-
-def get_programs_credentials(user):
- """Return program credentials data required for display.
-
- Given a user, find all programs for which certificates have been earned
- and return list of dictionaries of required program data.
-
- Arguments:
- user (User): user object for getting programs credentials.
-
- Returns:
- list of dict, containing data corresponding to the programs for which
- the user has been awarded a credential.
- """
- programs_credentials = get_user_program_credentials(user)
- credentials_data = []
- for program in programs_credentials:
- try:
- program_data = {
- 'display_name': program['title'],
- 'subtitle': program['subtitle'],
- 'credential_url': program['credential_url'],
- }
- credentials_data.append(program_data)
- except KeyError:
- log.warning('Program structure is invalid: %r', program)
-
- return credentials_data
diff --git a/openedx/core/djangolib/testing/utils.py b/openedx/core/djangolib/testing/utils.py
index 3aca971047..10d106c403 100644
--- a/openedx/core/djangolib/testing/utils.py
+++ b/openedx/core/djangolib/testing/utils.py
@@ -19,7 +19,6 @@ from django.test import RequestFactory, TestCase, override_settings
from django.conf import settings
from django.contrib import sites
from nose.plugins import Plugin
-from waffle.models import Switch
from request_cache.middleware import RequestCache