Commit a6b97254 by Renzo Lucioni

Include raw program data on the detail page

Uses the view's ID argument to retrieve and drop unmodified programs API data on the details page. Future work will supplement with CourseOverviews data. Part of ECOM-4415.
parent 37eedf07
......@@ -2,6 +2,7 @@
Unit tests covering the program listing and detail pages.
"""
import datetime
import json
import unittest
from urlparse import urljoin
......@@ -16,10 +17,11 @@ from provider.constants import CONFIDENTIAL
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
from openedx.core.djangoapps.credentials.tests import factories as credentials_factories
from openedx.core.djangoapps.credentials.tests.mixins import CredentialsDataMixin, CredentialsApiConfigMixin
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.programs.tests import factories
from openedx.core.djangoapps.programs.tests.mixins import (
ProgramsApiConfigMixin,
ProgramsDataMixin)
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......@@ -226,25 +228,56 @@ class TestProgramListing(
self.assertNotContains(response, certificate['credential_url'])
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@httpretty.activate
@override_settings(MKTG_URLS={'ROOT': 'http://edx.org'})
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class TestProgramDetails(ProgramsApiConfigMixin, TestCase):
"""
Unit tests for the program details page
"""
program_id = 123
password = 'test'
def setUp(self):
super(TestProgramDetails, self).setUp()
self.details_page = reverse('program_details_view', args=[self.program_id])
self.user = UserFactory()
self.details_page = reverse('program_details_view', args=['123'])
self.client.login(username=self.user.username, password=self.password)
ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL)
self.data = factories.Program(
organizations=[factories.Organization()],
course_codes=[
factories.CourseCode(run_modes=[factories.RunMode()]),
]
)
def _mock_programs_api(self):
"""Helper for mocking out Programs API URLs."""
self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Programs API calls.')
url = '{api_root}/programs/{id}/'.format(
api_root=ProgramsApiConfig.current().internal_api_url.strip('/'),
id=self.program_id
)
body = json.dumps(self.data)
httpretty.register_uri(httpretty.GET, url, body=body, content_type='application/json')
self.client.login(username=self.user.username, password='test')
def _assert_program_data_present(self, response):
"""Verify that program data is present."""
self.assertContains(response, 'programData')
self.assertContains(response, self.data['name'])
def test_login_required(self):
"""
Verify that login is required to access the page.
"""
self.create_programs_config()
self._mock_programs_api()
self.client.logout()
......@@ -254,10 +287,10 @@ class TestProgramDetails(ProgramsApiConfigMixin, TestCase):
'{}?next={}'.format(reverse('signin_user'), self.details_page)
)
self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.password)
response = self.client.get(self.details_page)
self.assertEquals(response.status_code, 200)
self._assert_program_data_present(response)
def test_404_if_disabled(self):
"""
......@@ -271,12 +304,13 @@ class TestProgramDetails(ProgramsApiConfigMixin, TestCase):
def test_page_routing(self):
"""Verify that the page can be hit with or without a program name in the URL."""
self.create_programs_config()
self._mock_programs_api()
response = self.client.get(self.details_page)
self.assertEquals(response.status_code, 200)
self._assert_program_data_present(response)
response = self.client.get(self.details_page + 'program_name/')
self.assertEquals(response.status_code, 200)
self._assert_program_data_present(response)
response = self.client.get(self.details_page + 'program_name/invalid/')
self.assertEquals(response.status_code, 404)
......@@ -9,7 +9,7 @@ from django.http import Http404
from edxmako.shortcuts import render_to_response
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 ProgramProgressMeter, get_display_category
from openedx.core.djangoapps.programs.utils import ProgramProgressMeter, get_programs, get_display_category
from student.views import get_course_enrollments
......@@ -50,13 +50,16 @@ def view_programs(request):
@login_required
@require_GET
def program_details(request, program_id): # pylint: disable=unused-argument
def program_details(request, program_id):
"""View details about a specific program."""
show_program_details = ProgramsApiConfig.current().show_program_details
if not show_program_details:
raise Http404
program_data = get_programs(request.user, program_id=program_id)
context = {
'program_data': program_data,
'nav_hidden': True,
'disable_courseware_js': True,
'uses_pattern_library': True
......
......@@ -13,7 +13,9 @@ from openedx.core.djangolib.js_utils import (
<%block name="js_extra">
<%static:require_module module_name="js/learner_dashboard/program_details_factory" class_name="ProgramDetailsFactory">
ProgramDetailsFactory({});
ProgramDetailsFactory({
programData: ${program_data | n, dump_js_escaped_json}
});
</%static:require_module>
</%block>
......
......@@ -10,7 +10,7 @@ from openedx.core.lib.edx_api_utils import get_edx_api_data
log = logging.getLogger(__name__)
def get_programs(user):
def get_programs(user, program_id=None):
"""Given a user, get programs from the Programs service.
Returned value is cached depending on user permissions. Staff users making requests
against Programs will receive unpublished programs, while regular users will only receive
......@@ -19,6 +19,9 @@ def get_programs(user):
Arguments:
user (User): The user to authenticate as when requesting programs.
Keyword Arguments:
program_id (int): Identifies a specific program for which to retrieve data.
Returns:
list of dict, representing programs returned by the Programs service.
"""
......@@ -27,7 +30,7 @@ def get_programs(user):
# Bypass caching for staff users, who may be creating Programs and want
# to see them displayed immediately.
cache_key = programs_config.CACHE_KEY if programs_config.is_cache_enabled and not user.is_staff else None
return get_edx_api_data(programs_config, user, 'programs', cache_key=cache_key)
return get_edx_api_data(programs_config, user, 'programs', resource_id=program_id, cache_key=cache_key)
def flatten_programs(programs, course_ids):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment