Commit a725e842 by Will Daly

Merge pull request #8983 from edx/will/ecom-1912-and-1913

Credit progress page formatting bugfixes.
parents 4619e9f4 d3f58b68
......@@ -6,7 +6,6 @@ import datetime
from mock import patch
import pytz
from mock import patch
from django.conf import settings
from django.core.urlresolvers import reverse
......
"""
Tests for credit requirement display on the progress page.
"""
import datetime
from mock import patch
from pytz import UTC
from django.conf import settings
from django.core.urlresolvers import reverse
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from student.tests.factories import UserFactory, CourseEnrollmentFactory
from util.date_utils import get_time_display, DEFAULT_SHORT_DATE_FORMAT
from openedx.core.djangoapps.credit import api as credit_api
from openedx.core.djangoapps.credit.models import CreditCourse
@patch.dict(settings.FEATURES, {"ENABLE_CREDIT_ELIGIBILITY": True})
class ProgressPageCreditRequirementsTest(ModuleStoreTestCase):
"""
Tests for credit requirement display on the progress page.
"""
USERNAME = "bob"
PASSWORD = "test"
USER_FULL_NAME = "Bob"
MIN_GRADE_REQ_DISPLAY = "Final Grade Credit Requirement"
VERIFICATION_REQ_DISPLAY = "Midterm Exam Credit Requirement"
def setUp(self):
super(ProgressPageCreditRequirementsTest, self).setUp()
# Create a course and configure it as a credit course
self.course = CourseFactory.create()
CreditCourse.objects.create(course_key=self.course.id, enabled=True) # pylint: disable=no-member
# Configure credit requirements (passing grade and in-course reverification)
credit_api.set_credit_requirements(
self.course.id, # pylint: disable=no-member
[
{
"namespace": "grade",
"name": "grade",
"display_name": self.MIN_GRADE_REQ_DISPLAY,
"criteria": {
"min_grade": 0.8
}
},
{
"namespace": "reverification",
"name": "midterm",
"display_name": self.VERIFICATION_REQ_DISPLAY,
"criteria": {}
}
]
)
# Create a user and log in
self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
self.user.profile.name = self.USER_FULL_NAME
self.user.profile.save()
result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
self.assertTrue(result, msg="Could not log in")
# Enroll the user in the course as "verified"
self.enrollment = CourseEnrollmentFactory(
user=self.user,
course_id=self.course.id, # pylint: disable=no-member
mode="verified"
)
def test_credit_requirements_maybe_eligible(self):
# The user hasn't satisfied any of the credit requirements yet, but she
# also hasn't failed any.
response = self._get_progress_page()
# Expect that the requirements are displayed
self.assertContains(response, self.MIN_GRADE_REQ_DISPLAY)
self.assertContains(response, self.VERIFICATION_REQ_DISPLAY)
self.assertContains(response, "Upcoming")
self.assertContains(
response,
"{}, you have not yet met the requirements for credit".format(self.USER_FULL_NAME)
)
def test_credit_requirements_eligible(self):
# Mark the user as eligible for all requirements
credit_api.set_credit_requirement_status(
self.user.username, self.course.id,
"grade", "grade",
status="satisfied",
reason={"final_grade": 0.95}
)
credit_api.set_credit_requirement_status(
self.user.username, self.course.id,
"reverification", "midterm",
status="satisfied", reason={}
)
# Check the progress page display
response = self._get_progress_page()
self.assertContains(response, self.MIN_GRADE_REQ_DISPLAY)
self.assertContains(response, self.VERIFICATION_REQ_DISPLAY)
self.assertContains(
response,
"{}, you have met the requirements for credit in this course.".format(self.USER_FULL_NAME)
)
self.assertContains(response, "Verified on {date}".format(date=self._now_formatted_date()))
self.assertContains(response, "95%")
def test_credit_requirements_not_eligible(self):
# Mark the user as having failed both requirements
credit_api.set_credit_requirement_status(
self.user.username, self.course.id,
"reverification", "midterm",
status="failed", reason={}
)
# Check the progress page display
response = self._get_progress_page()
self.assertContains(response, self.MIN_GRADE_REQ_DISPLAY)
self.assertContains(response, self.VERIFICATION_REQ_DISPLAY)
self.assertContains(
response,
"{}, you are no longer eligible for credit in this course.".format(self.USER_FULL_NAME)
)
self.assertContains(response, "Verification Failed")
def _get_progress_page(self):
"""Load the progress page for the course the user is enrolled in. """
url = reverse("progress", kwargs={"course_id": unicode(self.course.id)})
return self.client.get(url)
def _now_formatted_date(self):
"""Retrieve the formatted current date. """
return get_time_display(
datetime.datetime.now(UTC),
DEFAULT_SHORT_DATE_FORMAT,
settings.TIME_ZONE
)
......@@ -105,13 +105,13 @@ from django.utils.http import urlquote_plus
<h2>${_("Requirements for Course Credit")}</h2>
</div>
%if credit_course_requirements['eligibility_status'] == 'not_eligible':
<span class="eligibility_msg">${student.get_full_name()}, ${_("You are no longer eligible for this course.")}</span>
<span class="eligibility_msg">${_("{student_name}, you are no longer eligible for credit in this course.").format(student_name=student.profile.name)}</span>
%elif credit_course_requirements['eligibility_status'] == 'eligible':
<span class="eligibility_msg">${student.get_full_name()}, ${_("You have met the requirements for credit in this course.")}
<span class="eligibility_msg">${_("{student_name}, you have met the requirements for credit in this course.").format(student_name=student.profile.name)}
${_("{link} to purchase course credit.").format(link="<a href={url}>{url_name}</a>".format(url = reverse('dashboard'), url_name = _('Go to your dashboard')))}
</span>
%elif credit_course_requirements['eligibility_status'] == 'partial_eligible':
<span>${_("{student_name}, you have not yet met the requirements for credit.").format(student_name=student.get_full_name())}</span>
<span>${_("{student_name}, you have not yet met the requirements for credit.").format(student_name=student.profile.name)}</span>
%endif
<a href="${settings.CREDIT_HELP_LINK_URL}" class="credit-help"><i class="fa fa-question"></i><span class="sr">${_("Information about course credit requirements")}</span></a><br>
<div class="requirement-container" data-eligible="${credit_course_requirements['eligibility_status']}">
......@@ -127,7 +127,13 @@ from django.utils.http import urlquote_plus
<span>${_("Verification Failed" )}</span>
%elif requirement['status'] == 'satisfied':
<i class="fa fa-check"></i>
% if requirement['namespace'] == 'reverification':
<span>Verified on ${get_time_display(requirement['status_date'], DEFAULT_SHORT_DATE_FORMAT, settings.TIME_ZONE)}</span>
% elif requirement['namespace'] == 'grade' and 'final_grade' in requirement['reason']:
<span>${int(requirement['reason']['final_grade'] * 100)}%</span>
% else:
<span>Completed</span>
% endif
%endif
%else:
<span class="not-achieve">${_("Upcoming")}</span>
......
......@@ -294,6 +294,7 @@ def get_credit_requirement_status(course_key, username, namespace=None, name=Non
"name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
"display_name": "In Course Reverification",
"criteria": {},
"reason": {},
"status": "failed",
"status_date": "2015-06-26 07:49:13",
},
......@@ -302,6 +303,7 @@ def get_credit_requirement_status(course_key, username, namespace=None, name=Non
"name": "i4x://edX/DemoX/proctoring-block/final_uuid",
"display_name": "Proctored Mid Term Exam",
"criteria": {},
"reason": {},
"status": "satisfied",
"status_date": "2015-06-26 11:07:42",
},
......@@ -310,7 +312,8 @@ def get_credit_requirement_status(course_key, username, namespace=None, name=Non
"name": "i4x://edX/DemoX/proctoring-block/final_uuid",
"display_name": "Minimum Passing Grade",
"criteria": {"min_grade": 0.8},
"status": "failed",
"reason": {"final_grade": 0.95},
"status": "satisfied",
"status_date": "2015-06-26 11:07:44",
},
]
......@@ -329,6 +332,7 @@ def get_credit_requirement_status(course_key, username, namespace=None, name=Non
"name": requirement.name,
"display_name": requirement.display_name,
"criteria": requirement.criteria,
"reason": requirement_status.reason if requirement_status else None,
"status": requirement_status.status if requirement_status else None,
"status_date": requirement_status.modified if requirement_status else None,
})
......
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