Commit f9f4876b by Bill Filler

Add 'View Consent' button to dashboard when required

Enterprise customers can require user to agree to Data Sharing Consent
form before they can access a course. We now add it conditionally to
Course Dashboard when it's required so it's apparent to user and they
have a way to revist the consent form if they've previously declined or
the course has not yet started.

WL-1281
parent dbad9fbc
...@@ -7,6 +7,7 @@ import json ...@@ -7,6 +7,7 @@ import json
import unittest import unittest
import ddt import ddt
import mock
import pytz import pytz
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
...@@ -335,3 +336,43 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin): ...@@ -335,3 +336,43 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin):
remove_prerequisite_course(self.course.id, get_course_milestones(self.course.id)[0]) remove_prerequisite_course(self.course.id, get_course_milestones(self.course.id)[0])
response = self.client.get(reverse('dashboard')) response = self.client.get(reverse('dashboard'))
self.assertNotIn('<div class="prerequisites">', response.content) self.assertNotIn('<div class="prerequisites">', response.content)
@mock.patch('student.views.consent_needed_for_course')
@mock.patch('student.views.enterprise_customer_for_request')
@ddt.data(
(True, True, True),
(True, True, False),
(True, False, False),
(False, True, False),
(False, False, False),
)
@ddt.unpack
def test_enterprise_view_consent_for_course(
self,
enterprise_enabled,
consent_needed,
future_course,
mock_enterprise_customer,
mock_consent_necessary
):
"""
Verify that the 'View Consent' icon show up if data sharing consent turned on
for enterprise customer
"""
if future_course:
self.course = CourseFactory.create(start=self.TOMORROW, emit_signals=True)
else:
self.course = CourseFactory.create(emit_signals=True)
self.course_enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user)
if enterprise_enabled:
mock_enterprise_customer.return_value = {'name': 'TestEnterprise', 'uuid': 'abc123xxx'}
else:
mock_enterprise_customer.return_value = None
mock_consent_necessary.return_value = consent_needed
# Assert 'View Consent' button shows up appropriately
response = self.client.get(reverse('dashboard'))
self.assertEquals('View Consent' in response.content, enterprise_enabled and consent_needed)
self.assertEquals('TestEnterprise' in response.content, enterprise_enabled and consent_needed)
...@@ -87,7 +87,11 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers ...@@ -87,7 +87,11 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
from openedx.core.djangoapps.user_api.preferences import api as preferences_api from openedx.core.djangoapps.user_api.preferences import api as preferences_api
from openedx.core.djangolib.markup import HTML from openedx.core.djangolib.markup import HTML
from openedx.features.course_experience import course_home_url_name from openedx.features.course_experience import course_home_url_name
from openedx.features.enterprise_support.api import get_dashboard_consent_notification from openedx.features.enterprise_support.api import (
consent_needed_for_course,
enterprise_customer_for_request,
get_dashboard_consent_notification
)
from shoppingcart.api import order_history from shoppingcart.api import order_history
from shoppingcart.models import CourseRegistrationCode, DonationConfiguration from shoppingcart.models import CourseRegistrationCode, DonationConfiguration
from student.cookies import delete_logged_in_cookies, set_logged_in_cookies, set_user_info_cookie from student.cookies import delete_logged_in_cookies, set_logged_in_cookies, set_user_info_cookie
...@@ -729,6 +733,16 @@ def dashboard(request): ...@@ -729,6 +733,16 @@ def dashboard(request):
enterprise_message = get_dashboard_consent_notification(request, user, course_enrollments) enterprise_message = get_dashboard_consent_notification(request, user, course_enrollments)
enterprise_customer = enterprise_customer_for_request(request)
consent_required_courses = set()
enterprise_customer_name = None
if enterprise_customer:
consent_required_courses = {
enrollment.course_id for enrollment in course_enrollments
if consent_needed_for_course(request, request.user, str(enrollment.course_id), True)
}
enterprise_customer_name = enterprise_customer['name']
# Account activation message # Account activation message
account_activation_messages = [ account_activation_messages = [
message for message in messages.get_messages(request) if 'account-activation' in message.tags message for message in messages.get_messages(request) if 'account-activation' in message.tags
...@@ -847,6 +861,8 @@ def dashboard(request): ...@@ -847,6 +861,8 @@ def dashboard(request):
context = { context = {
'enterprise_message': enterprise_message, 'enterprise_message': enterprise_message,
'consent_required_courses': consent_required_courses,
'enterprise_customer_name': enterprise_customer_name,
'enrollment_message': enrollment_message, 'enrollment_message': enrollment_message,
'redirect_message': redirect_message, 'redirect_message': redirect_message,
'account_activation_messages': account_activation_messages, 'account_activation_messages': account_activation_messages,
......
...@@ -721,7 +721,7 @@ ...@@ -721,7 +721,7 @@
@include clearfix(); @include clearfix();
position: relative; position: inherit;
@include left($baseline/2); @include left($baseline/2);
@include padding(($baseline * 0.4), 0, ($baseline * 0.4), ($baseline * 0.75)); @include padding(($baseline * 0.4), 0, ($baseline * 0.4), ($baseline * 0.75));
...@@ -772,6 +772,15 @@ ...@@ -772,6 +772,15 @@
opacity: 0.875; opacity: 0.875;
} }
} }
.action-view-consent {
@extend %btn-pl-white-base;
@include float(right);
&.archived {
@extend %btn-pl-default-base;
}
}
} }
// TYPE: status // TYPE: status
......
...@@ -128,7 +128,8 @@ from openedx.core.djangolib.markup import HTML, Text ...@@ -128,7 +128,8 @@ from openedx.core.djangolib.markup import HTML, Text
<% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %> <% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %>
<% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %> <% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %>
<% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %> <% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %>
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=enrollment.course_overview, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_blocked=is_course_blocked, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard' /> <% show_consent_link = (enrollment.course_id in consent_required_courses) %>
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=enrollment.course_overview, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_blocked=is_course_blocked, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name' />
% endfor % endfor
</ul> </ul>
......
<%page expression_filter="h" args="course_overview, course_target, enrollment, enterprise_customer_name" />
<%!
from django.utils.translation import ugettext as _
%>
<%namespace name='static' file='../static_content.html'/>
<div class="message message-upsell has-actions is-shown">
<div class="wrapper-extended">
<p class="message-copy" align="justify">
<b class="message-copy-bold">
${_("Consent to share your data")}
</b>
<br>
${_("To access this course, you must first consent to share your learning achievements with {enterprise_customer_name}.").format(enterprise_customer_name=enterprise_customer_name)}
</p>
<div class="action-upgrade-container">
<a class="action action-view-consent" href="${course_target}" data-course-key="${enrollment.course_id}">
<span class="wrapper-copy">
<span class="copy" id="view-consent">${_("View Consent")}</span>
<span class="sr">&nbsp;${_(course_overview.display_name_with_default)}</span>
</span>
</a>
</div>
</div>
</div>
\ No newline at end of file
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