Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #208 from edx/hide-empty-modes
Browse files Browse the repository at this point in the history
Hiding Empty Enrollment Modes
  • Loading branch information
clintonb committed Dec 4, 2014
2 parents 01bfd13 + 01da5d2 commit 44f23d1
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 78 deletions.
42 changes: 34 additions & 8 deletions acceptance_tests/test_course_enrollment.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ def assertMetricTileValid(self, stat_type, value, tooltip):
self.assertSummaryPointValueEquals(selector, self.format_number(value))
self.assertSummaryTooltipEquals(selector, tooltip)

def _get_valid_enrollment_modes(self, trends):
valid_modes = {enrollment_modes.AUDIT, enrollment_modes.HONOR}
invalid_modes = set(enrollment_modes.ALL) - valid_modes

for datum in trends:
for candidate in list(invalid_modes):
if datum.get(candidate, 0) > 0:
invalid_modes.remove(candidate)
valid_modes.add(candidate)

if len(invalid_modes) <= 0:
break

return valid_modes

def _test_enrollment_metrics_and_graph(self):
""" Verify the graph loads and that the metric tiles display the correct information. """

Expand All @@ -62,14 +77,17 @@ def _test_enrollment_metrics_and_graph(self):
self.assertMetricTileValid('enrollment_change_last_%s_days' % i, enrollment, tooltip)

if ENABLE_ENROLLMENT_MODES:
# Verify the verified enrollment metric tile.
verified_enrollment = enrollment_data[-1][enrollment_modes.VERIFIED]
tooltip = u'Number of enrolled students who are pursuing a verified certificate of achievement.'
self.assertMetricTileValid('verified_enrollment', verified_enrollment, tooltip)
valid_modes = self._get_valid_enrollment_modes(enrollment_data)

verified_enrollment = verified_enrollment - enrollment_data[-(i + 1)][enrollment_modes.VERIFIED]
tooltip = u'The difference between the number of students pursuing verified certificates at the end of the day yesterday and one week before.'
self.assertMetricTileValid('verified_change_last_%s_days' % i, verified_enrollment, tooltip)
if enrollment_modes.VERIFIED in valid_modes:
# Verify the verified enrollment metric tile.
verified_enrollment = enrollment_data[-1][enrollment_modes.VERIFIED]
tooltip = u'Number of enrolled students who are pursuing a verified certificate of achievement.'
self.assertMetricTileValid('verified_enrollment', verified_enrollment, tooltip)

verified_enrollment = verified_enrollment - enrollment_data[-(i + 1)][enrollment_modes.VERIFIED]
tooltip = u'The difference between the number of students pursuing verified certificates at the end of the day yesterday and one week before.'
self.assertMetricTileValid('verified_change_last_%s_days' % i, verified_enrollment, tooltip)

# Verify *something* rendered where the graph should be. We cannot easily verify what rendered
self.assertElementHasContent("[data-section=enrollment-basics] #enrollment-trend-view")
Expand All @@ -83,7 +101,15 @@ def _test_enrollment_trend_table(self):
headings = ['Date', 'Total Enrollment']

if ENABLE_ENROLLMENT_MODES:
headings.append('Verified Track')
headings.append('Honor Code')

valid_modes = self._get_valid_enrollment_modes(enrollment_data)

if enrollment_modes.VERIFIED in valid_modes:
headings.append('Verified')

if enrollment_modes.PROFESSIONAL in valid_modes:
headings.append('Professional')

self.assertTableColumnHeadingsEqual(table_selector, headings)

Expand Down
37 changes: 36 additions & 1 deletion analytics_dashboard/courses/presenters.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
GENDER.OTHER: 2
}


KNOWN_EDUCATION_LEVELS = [EDUCATION_LEVEL.NONE, EDUCATION_LEVEL.OTHER, EDUCATION_LEVEL.PRIMARY,
EDUCATION_LEVEL.JUNIOR_SECONDARY, EDUCATION_LEVEL.SECONDARY, EDUCATION_LEVEL.ASSOCIATES,
EDUCATION_LEVEL.BACHELORS, EDUCATION_LEVEL.MASTERS, EDUCATION_LEVEL.DOCTORATE]
Expand Down Expand Up @@ -221,6 +220,42 @@ def get_summary_and_trend_data(self):

if self.display_verified_enrollment:
trends = self._merge_audit_and_honor(trends)
summary, trends = self._remove_empty_enrollment_modes(summary, trends)

return summary, trends

def _get_valid_enrollment_modes(self, trends):
"""
Return enrollment modes for which there is currently, or have been in the past, at least one enrolled student.
"""
valid_modes = {enrollment_modes.AUDIT, enrollment_modes.HONOR}
invalid_modes = set(enrollment_modes.ALL) - valid_modes

for datum in trends:
for candidate in invalid_modes.copy():
if datum.get(candidate, 0) > 0:
invalid_modes.remove(candidate)
valid_modes.add(candidate)

if len(invalid_modes) == 0:
break

return valid_modes

def _remove_empty_enrollment_modes(self, summary, trends):
"""
Based on the trend data, identify enrollment modes with no enrollments and remove them from display.
"""
valid_modes = self._get_valid_enrollment_modes(trends)
invalid_modes = set(enrollment_modes.ALL) - valid_modes

for trend in trends:
for mode in invalid_modes:
trend.pop(mode, None)

if enrollment_modes.VERIFIED not in valid_modes:
summary.pop('verified_enrollment')
summary.pop('verified_change_last_7_days')

return summary, trends

Expand Down
116 changes: 60 additions & 56 deletions analytics_dashboard/courses/templates/courses/enrollment_activity.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ <h4 class="section-title">{% trans "Daily Student Enrollment" %}</h4>
</div>

{% if js_data.course.enrollmentTrends %}
<div class="section-content section-data-graph">
<div class="section-content section-data-viz">
<div class="analytics-chart-container">
<div class="chart-info">{% trans "Enrollments" %}</div>
{% trans "This graph displays total enrollment for the course calculated at the end of each day. Total enrollment includes new enrollments as well as unenrollments." as tip_text %}
{% include "chart_tooltip.html" with tip_text=tip_text track_category="trend"%}
<div id="enrollment-trend-view" class="analytics-chart">
{% include "loading.html" %}
</div>
</div>
<div class="section-content section-data-graph">
<div class="section-content section-data-viz">
<div class="analytics-chart-container">
<div class="chart-info">{% trans "Enrollments" %}</div>
{% trans "This graph displays total enrollment for the course calculated at the end of each day. Total enrollment includes new enrollments as well as unenrollments." as tip_text %}
{% include "chart_tooltip.html" with tip_text=tip_text track_category="trend" %}
<div id="enrollment-trend-view" class="analytics-chart">
{% include "loading.html" %}
</div>
</div>
</div>
</div>
{% else %}
{% show_chart_error %}
{% show_chart_error %}
{% endif %}
</section>

Expand All @@ -48,45 +48,49 @@ <h4 class="section-title">{% trans "Daily Student Enrollment" %}</h4>
<h4 class="section-title">{% trans "Enrollment Metrics" %}</h4>
</div>

{% if summary %}
<div class="section-content">
<div class="row">
<div class="col-xs-12 col-sm-3" data-stat-type="current_enrollment">
{# Translators: This is a label to identify current student enrollment. #}
{% trans "Total Enrollment" as label %}
{# Translators: This is a label indicating the number of students enrolled in a course. #}
{% trans "Students enrolled in the course." as tooltip %}
{% summary_point summary.current_enrollment label tooltip=tooltip %}
</div>

<div class="col-xs-12 col-sm-3" data-stat-type="enrollment_change_last_7_days">
{# Translators: This is a label indicating the change in the number of students enrolled in a course since the previous week. #}
{% trans "Change in Last Week" as label %}
{% trans "The difference between the number of students enrolled at the end of the day yesterday and one week before." as tooltip %}
{% summary_point summary.enrollment_change_last_7_days label tooltip=tooltip %}
</div>
{% if summary %}
<div class="section-content">
<div class="row">
<div class="col-xs-12 col-sm-3" data-stat-type="current_enrollment">
{# Translators: This is a label to identify current student enrollment. #}
{% trans "Total Enrollment" as label %}
{# Translators: This is a label indicating the number of students enrolled in a course. #}
{% trans "Students enrolled in the course." as tooltip %}
{% summary_point summary.current_enrollment label tooltip=tooltip %}
</div>

{% switch display_verified_enrollment %}
<div class="col-xs-12 col-sm-3" data-stat-type="verified_enrollment">
{# Translators: This is a label to identify enrollment of students on the verified track. #}
{% trans "Verified Enrollment" as label %}
{# Translators: This is a label indicating the number of students enrolled in a course on the verified track. #}
{% trans "Number of enrolled students who are pursuing a verified certificate of achievement." as tooltip %}
{% summary_point summary.verified_enrollment label tooltip=tooltip %}
</div>
<div class="col-xs-12 col-sm-3" data-stat-type="enrollment_change_last_7_days">
{# Translators: This is a label indicating the change in the number of students enrolled in a course since the previous week. #}
{% trans "Change in Last Week" as label %}
{% trans "The difference between the number of students enrolled at the end of the day yesterday and one week before." as tooltip %}
{% summary_point summary.enrollment_change_last_7_days label tooltip=tooltip %}
</div>

<div class="col-xs-12 col-sm-3" data-stat-type="verified_change_last_7_days">
{# Translators: This is a label indicating the change in the number of students enrolled in the verified track of a course since the previous week. #}
{% trans "Change in Verified Enrollments Last Week" as label %}
{% trans "The difference between the number of students pursuing verified certificates at the end of the day yesterday and one week before." as tooltip %}
{% summary_point summary.verified_change_last_7_days label tooltip=tooltip %}
{% switch display_verified_enrollment %}
{% if summary.verified_enrollment %}
<div class="col-xs-12 col-sm-3" data-stat-type="verified_enrollment">
{# Translators: This is a label to identify enrollment of students on the verified track. #}
{% trans "Verified Enrollment" as label %}
{# Translators: This is a label indicating the number of students enrolled in a course on the verified track. #}
{% trans "Number of enrolled students who are pursuing a verified certificate of achievement." as tooltip %}
{% summary_point summary.verified_enrollment label tooltip=tooltip %}
</div>
{% endif %}

{% if summary.verified_change_last_7_days %}
<div class="col-xs-12 col-sm-3" data-stat-type="verified_change_last_7_days">
{# Translators: This is a label indicating the change in the number of students enrolled in the verified track of a course since the previous week. #}
{% trans "Change in Verified Enrollments Last Week" as label %}
{% trans "The difference between the number of students pursuing verified certificates at the end of the day yesterday and one week before." as tooltip %}
{% summary_point summary.verified_change_last_7_days label tooltip=tooltip %}
</div>
{% endif %}
{% endswitch %}
</div>
{% endswitch %}
</div>
</div>
{% else %}
{% show_metrics_error %}
{% endif %}
{% else %}
{% show_metrics_error %}
{% endif %}
</section>

<section class="view-section">
Expand All @@ -95,22 +99,22 @@ <h4 class="section-title">{% trans "Enrollment Over Time" %}</h4>

<div class="section-actions">
{% if js_data.course.enrollmentTrends %}
<a href="{% url 'courses:csv_enrollment' course_id=course_id %}" class="btn btn-default"
data-role="enrollment-trend-csv" data-track-type="click"
data-track-event="edx.bi.csv.downloaded" data-track-category="trend">
<i class="ico fa fa-download" aria-hidden="true"></i> {% trans "Download CSV" %}
<span class="sr-only">{% trans "Enrollment Over Time" %}</span>
</a>
<a href="{% url 'courses:csv_enrollment' course_id=course_id %}" class="btn btn-default"
data-role="enrollment-trend-csv" data-track-type="click"
data-track-event="edx.bi.csv.downloaded" data-track-category="trend">
<i class="ico fa fa-download" aria-hidden="true"></i> {% trans "Download CSV" %}
<span class="sr-only">{% trans "Enrollment Over Time" %}</span>
</a>
{% endif %}
</div>
</div>

{% if js_data.course.enrollmentTrends %}
<div class="section-content section-data-table" data-role="enrollment-table">
{% include "loading.html" %}
</div>
<div class="section-content section-data-table" data-role="enrollment-table">
{% include "loading.html" %}
</div>
{% else %}
{% show_table_error %}
{% show_table_error %}
{% endif %}

</section>
Expand Down
13 changes: 11 additions & 2 deletions analytics_dashboard/courses/tests/test_presenters.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ def test_get_trend_summary_no_data(self):
'last_updated': None,
'current_enrollment': None,
'enrollment_change_last_7_days': None,
'verified_enrollment': None,
'verified_change_last_7_days': None,
}

self.assertDictEqual(actual_summary, expected_summary)
Expand Down Expand Up @@ -187,6 +185,17 @@ def test_get_geography_data(self, mock_enrollment):
self.assertDictEqual(summary, expected_summary)
self.assertListEqual(actual_data, expected_data)

@mock.patch('analyticsclient.course.Course.enrollment')
def test_hide_empty_enrollment_modes(self, mock_enrollment):
""" Enrollment modes with no enrolled students should not be returned. """
mock_enrollment.return_value = utils.get_mock_api_enrollment_data(self.course_id, include_verified=False)

actual_summary, actual_trend = self.presenter.get_summary_and_trend_data()
self.assertDictEqual(actual_summary, utils.get_mock_enrollment_summary(include_verified=False))

expected_trend = utils.get_mock_presenter_enrollment_trend(self.course_id, include_verified=False)
self.assertListEqual(actual_trend, expected_trend)


class CourseEnrollmentDemographicsPresenterTests(TestCase):
def setUp(self):
Expand Down
31 changes: 20 additions & 11 deletions analytics_dashboard/courses/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@
GAP_END = 4


def get_mock_api_enrollment_data(course_id):
def get_mock_api_enrollment_data(course_id, include_verified=True):
data = []
start_date = datetime.date(year=2014, month=1, day=1)
modes = enrollment_modes.ALL if include_verified else [enrollment_modes.AUDIT, enrollment_modes.HONOR]

for index in range(31):
date = start_date + datetime.timedelta(days=index)

datum = {
'date': date.strftime(Client.DATE_FORMAT),
'course_id': unicode(course_id),
'count': index * len(enrollment_modes.ALL),
'count': index * len(modes),
'created': CREATED_DATETIME_STRING
}

for mode in enrollment_modes.ALL:
for mode in modes:
datum[mode] = index

data.append(datum)
Expand All @@ -47,15 +48,23 @@ def get_mock_api_enrollment_data_with_gaps(course_id):
return data


def get_mock_enrollment_summary():
return {
def get_mock_enrollment_summary(include_verified=True):
summary = {
'last_updated': CREATED_DATETIME,
'current_enrollment': 120,
'enrollment_change_last_7_days': 28,
'verified_enrollment': 30,
'verified_change_last_7_days': 7,
'current_enrollment': 60,
'enrollment_change_last_7_days': 14,
}

if include_verified:
summary.update({
'current_enrollment': 120,
'enrollment_change_last_7_days': 28,
'verified_enrollment': 30,
'verified_change_last_7_days': 7,
})

return summary


def get_mock_enrollment_summary_and_trend(course_id):
return get_mock_enrollment_summary(), get_mock_presenter_enrollment_trend(course_id)
Expand All @@ -78,8 +87,8 @@ def _clean_modes(data):
return data


def get_mock_presenter_enrollment_trend(course_id):
trend = get_mock_api_enrollment_data(course_id)
def get_mock_presenter_enrollment_trend(course_id, include_verified=True):
trend = get_mock_api_enrollment_data(course_id, include_verified=include_verified)
trend = _clean_modes(trend)
return trend

Expand Down

0 comments on commit 44f23d1

Please sign in to comment.