Commit a3198631 by Awais Qureshi Committed by GitHub

Merge pull request #437 from edx/awais786/ECOM-6039-published-course-run-tabs

Published course run tabs
parents ab6ff4d6 81a36613
......@@ -902,14 +902,31 @@ class DashboardTests(TestCase):
def setUp(self):
super(DashboardTests, self).setUp()
self.user = UserFactory(is_staff=True)
self.client.login(username=self.user.username, password=USER_PASSWORD)
self.user1 = UserFactory()
self.group_a = factories.GroupFactory()
self.user1.groups.add(self.group_a)
self.user2 = UserFactory()
self.group_b = factories.GroupFactory()
self.user2.groups.add(self.group_b)
self.client.login(username=self.user1.username, password=USER_PASSWORD)
self.page_url = reverse('publisher:publisher_dashboard')
# Create courses with `DRAFT` and `NEEDS_REVIEW` and PUBLISHED state
self.course_run_1 = factories.CourseRunFactory(state=factories.StateFactory(name=State.DRAFT))
self.course_run_2 = factories.CourseRunFactory(state=factories.StateFactory(name=State.NEEDS_REVIEW))
self.course_run_3 = factories.CourseRunFactory(state=factories.StateFactory(name=State.PUBLISHED))
# group-a course
self.course_run_1 = self._create_course_assign_permissions(State.DRAFT, self.group_a)
self.course_run_2 = self._create_course_assign_permissions(State.NEEDS_REVIEW, self.group_a)
self.course_run_3 = self._create_course_assign_permissions(State.PUBLISHED, self.group_a)
# group-b course
self._create_course_assign_permissions(State.DRAFT, self.group_b)
def _create_course_assign_permissions(self, state, group):
""" DRY method to create course and assign the permissions"""
course_run = factories.CourseRunFactory(state=factories.StateFactory(name=state))
course_run.course.assign_permission_by_group(group)
return course_run
def test_page_without_login(self):
""" Verify that user can't access course runs list page when not logged in. """
......@@ -931,26 +948,39 @@ class DashboardTests(TestCase):
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200)
def test_page_with_different_group_user(self):
""" Verify that user from one group can access only that group courses. """
self.client.logout()
self.client.login(username=self.user2.username, password=USER_PASSWORD)
self.assert_dashboard_response(1, 0, 1)
def test_page_with_staff_user(self):
""" Verify that staff user can see all tabs with all course runs from all groups. """
self.client.logout()
staff_user = UserFactory(is_staff=True)
self.client.login(username=staff_user.username, password=USER_PASSWORD)
self.assert_dashboard_response(3, 1, 3)
def test_different_course_runs_counts(self):
""" Verify that user can access published, un-published and
studio requests course runs. """
self.assert_dashboard_reponse(2, 1, 2)
self.assert_dashboard_response(2, 1, 2)
def test_studio_request_course_runs(self):
""" Verify that page loads the list course runs which need studio request. """
self.course_run_1.lms_course_id = 'test'
self.course_run_1.save()
self.assert_dashboard_reponse(2, 1, 1)
self.assert_dashboard_response(2, 1, 1)
self.course_run_2.lms_course_id = 'test-2'
self.course_run_2.save()
self.assert_dashboard_reponse(2, 1, 0)
self.assert_dashboard_response(2, 1, 0)
def assert_dashboard_reponse(self, unpublished_count, published_count, studio_requests):
def assert_dashboard_response(self, unpublished_count, published_count, studio_requests):
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['unpublished_courseruns']), unpublished_count)
self.assertEqual(len(response.context['published_courseruns']), published_count)
self.assertEqual(len(response.context['unpublished_course_runs']), unpublished_count)
self.assertEqual(len(response.context['published_course_runs']), published_count)
self.assertEqual(len(response.context['studio_request_courses']), studio_requests)
if studio_requests > 0:
......@@ -958,13 +988,24 @@ class DashboardTests(TestCase):
else:
self.assertContains(response, 'There are no course-runs require studio instance.')
if published_count > 0:
self.assertContains(response, '<table class="data-table-published display"')
self.assertContains(response, 'The list below contains all course runs published in the past 30 days')
else:
self.assertContains(response, "Looks like you haven't published any course yet")
def test_without_studio_request_course_runs(self):
""" Verify that studio tab indicates a message if no course-run available. """
self.course_run_1.lms_course_id = 'test'
self.course_run_1.save()
self.course_run_2.lms_course_id = 'test-2'
self.course_run_2.save()
self.assert_dashboard_reponse(2, 1, 0)
self.assert_dashboard_response(2, 1, 0)
def test_without_published_course_runs(self):
""" Verify that published tab indicates a message if no course-run available. """
self.course_run_3.change_state(target=State.DRAFT)
self.assert_dashboard_response(3, 0, 3)
class ToggleEmailNotificationTests(TestCase):
......
......@@ -2,6 +2,7 @@
Course publisher views.
"""
import json
from datetime import datetime, timedelta
from django.contrib import messages
from django.contrib.auth.models import Group
......@@ -33,6 +34,7 @@ SEATS_HIDDEN_FIELDS = ['price', 'currency', 'upgrade_deadline', 'credit_provider
class Dashboard(mixins.LoginRequiredMixin, ListView):
""" Create Course View."""
template_name = 'publisher/dashboard.html'
default_published_days = 30
def get_queryset(self):
if self.request.user.is_staff:
......@@ -46,15 +48,17 @@ class Dashboard(mixins.LoginRequiredMixin, ListView):
def get_context_data(self, **kwargs):
context = super(Dashboard, self).get_context_data(**kwargs)
course_runs = context.get('object_list')
published_courseruns = course_runs.filter(
state__name=State.PUBLISHED
published_course_runs = course_runs.filter(
state__name=State.PUBLISHED,
state__modified__gt=datetime.today() - timedelta(days=self.default_published_days)
).select_related('state').all().order_by('-state__modified')
unpublished_courseruns = course_runs.exclude(state__name=State.PUBLISHED)
studio_request_courses = unpublished_courseruns.filter(lms_course_id__isnull=True)
unpublished_course_runs = course_runs.exclude(state__name=State.PUBLISHED)
studio_request_courses = unpublished_course_runs.filter(lms_course_id__isnull=True)
context['studio_request_courses'] = [CourseRunWrapper(course_run) for course_run in studio_request_courses]
context['unpublished_courseruns'] = [CourseRunWrapper(course_run) for course_run in unpublished_courseruns]
context['published_courseruns'] = [CourseRunWrapper(course_run) for course_run in published_courseruns]
context['unpublished_course_runs'] = [CourseRunWrapper(course_run) for course_run in unpublished_course_runs]
context['published_course_runs'] = [CourseRunWrapper(course_run) for course_run in published_course_runs]
context['default_published_days'] = self.default_published_days
return context
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-11 17:27+0500\n"
"POT-Creation-Date: 2016-11-15 13:47+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -1407,6 +1407,7 @@ msgid "No Seats Available."
msgstr ""
#: templates/publisher/course_run_detail/_studio.html
#: templates/publisher/dashboard/published.html
#: templates/publisher/dashboard/studio_requests.html
msgid "Course Name"
msgstr ""
......@@ -1491,19 +1492,51 @@ msgid "STUDIO REQUEST"
msgstr ""
#: templates/publisher/dashboard.html
msgid "PUBLISHED COURSE RUNS"
msgstr ""
#: templates/publisher/dashboard.html
msgid "In Progress"
msgstr ""
#: templates/publisher/dashboard/studio_requests.html
#: templates/publisher/dashboard/published.html
msgid "Looks like you haven't published any course yet"
msgstr ""
#: templates/publisher/dashboard/published.html
#, python-format
msgid ""
"The list below are the courses that need a studio instance to start "
"development."
"The list below contains all course runs published in the past "
"%(default_published_days)s days."
msgstr ""
#: templates/publisher/dashboard/published.html
#: templates/publisher/dashboard/studio_requests.html
msgid "Institution"
msgstr ""
#: templates/publisher/dashboard/published.html
msgid "Start"
msgstr ""
#: templates/publisher/dashboard/published.html
msgid "End"
msgstr ""
#: templates/publisher/dashboard/published.html
msgid "Published Date"
msgstr ""
#: templates/publisher/dashboard/published.html
msgid "Target Content"
msgstr ""
#: templates/publisher/dashboard/studio_requests.html
msgid ""
"The list below are the courses that need a studio instance to start "
"development."
msgstr ""
#: templates/publisher/dashboard/studio_requests.html
msgid "Studio Course Run Key"
msgstr ""
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-11 17:27+0500\n"
"POT-Creation-Date: 2016-11-15 13:47+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-11 17:27+0500\n"
"POT-Creation-Date: 2016-11-15 13:47+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -1651,6 +1651,7 @@ msgid "No Seats Available."
msgstr "Nö Séäts Àväïläßlé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
#: templates/publisher/course_run_detail/_studio.html
#: templates/publisher/dashboard/published.html
#: templates/publisher/dashboard/studio_requests.html
msgid "Course Name"
msgstr "Çöürsé Nämé Ⱡ'σяєм ιρѕυм ∂σłσя #"
......@@ -1742,9 +1743,49 @@ msgid "STUDIO REQUEST"
msgstr "STÛDÌÖ RÉQÛÉST Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
#: templates/publisher/dashboard.html
msgid "PUBLISHED COURSE RUNS"
msgstr "PÛBLÌSHÉD ÇÖÛRSÉ RÛNS Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
#: templates/publisher/dashboard.html
msgid "In Progress"
msgstr "Ìn Prögréss Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/dashboard/published.html
msgid "Looks like you haven't published any course yet"
msgstr ""
"Lööks lïké ýöü hävén't püßlïshéd äný çöürsé ýét Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,"
" ¢σηѕє¢тєтυя α#"
#: templates/publisher/dashboard/published.html
#, python-format
msgid ""
"The list below contains all course runs published in the past "
"%(default_published_days)s days."
msgstr ""
"Thé lïst ßélöw çöntäïns äll çöürsé rüns püßlïshéd ïn thé päst "
"%(default_published_days)s däýs. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя#"
#: templates/publisher/dashboard/published.html
#: templates/publisher/dashboard/studio_requests.html
msgid "Institution"
msgstr "Ìnstïtütïön Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/dashboard/published.html
msgid "Start"
msgstr "Stärt Ⱡ'σяєм ιρѕ#"
#: templates/publisher/dashboard/published.html
msgid "End"
msgstr "Énd Ⱡ'σяєм#"
#: templates/publisher/dashboard/published.html
msgid "Published Date"
msgstr "Püßlïshéd Däté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
#: templates/publisher/dashboard/published.html
msgid "Target Content"
msgstr "Tärgét Çöntént Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
#: templates/publisher/dashboard/studio_requests.html
msgid ""
"The list below are the courses that need a studio instance to start "
......@@ -1754,10 +1795,6 @@ msgstr ""
"dévélöpmént. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
#: templates/publisher/dashboard/studio_requests.html
msgid "Institution"
msgstr "Ìnstïtütïön Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/dashboard/studio_requests.html
msgid "Studio Course Run Key"
msgstr "Stüdïö Çöürsé Rün Kéý Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-11 17:27+0500\n"
"POT-Creation-Date: 2016-11-15 13:47+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......
......@@ -45,4 +45,8 @@ $(document).ready(function() {
}
});
});
$('.data-table-published').addClass('nowrap').DataTable({
"autoWidth": false
});
});
......@@ -7,13 +7,14 @@
{% endblock title %}
{% block content %}
{% with studio_count=studio_request_courses|length %}
{% with studio_count=studio_request_courses|length published_count=published_course_runs|length %}
<div class="publisher-container">
<h2 class="hd-2 emphasized">{% trans "Course runs" %}</h2>
<ul role="tablist" class="tabs">
<li role="tab" id="tab-progress" class="tab" aria-selected="true" aria-expanded="false" aria-controls="progress" tabindex="0"><span>0</span>{% trans "IN PROGRESS" %}</li>
<li role="tab" id="tab-preview" class="tab" aria-selected="false" aria-expanded="false" aria-controls="preview" tabindex="-1"><span>0</span>{% trans "PREVIEW READY" %}</li>
<li role="tab" id="tab-studio" class="tab" aria-selected="false" aria-expanded="true" aria-controls="studio" tabindex="-1" data-studio-count="{{ studio_count }}"><span id="studio-count">{{ studio_count }}</span>{% trans "STUDIO REQUEST" %}</li>
<li role="tab" id="tab-studio" class="tab" aria-selected="false" aria-expanded="true" aria-controls="studio" tabindex="-1" data-studio-count="{{ studio_count }}"><span>{{ studio_count }}</span>{% trans "STUDIO REQUEST" %}</li>
<li role="tab" id="tab-published" class="tab" aria-selected="false" aria-expanded="false" aria-controls="published" tabindex="-1"><span>{{ published_count }}</span>{% trans "PUBLISHED COURSE RUNS" %}</li>
</ul>
<div role="tabpanel" id="progress" class="tab-panel" aria-labelledby="tab-progress" aria-hidden="false" tabindex="-1">
......@@ -29,6 +30,9 @@
<div role="tabpanel" id="studio" class="tab-panel" aria-labelledby="tab-studio" aria-hidden="false" tabindex="0">
{% include "publisher/dashboard/studio_requests.html" %}
</div>
<div role="tabpanel" id="published" class="tab-panel" aria-labelledby="tab-published" aria-hidden="false" tabindex="0">
{% include "publisher/dashboard/published.html" %}
</div>
</div>
{% endwith %}
......
{% load i18n %}
{% if published_count == 0 %}
<p>{% trans "Looks like you haven't published any course yet" %}</p>
{% else %}
<p>
{% blocktrans trimmed %}
The list below contains all course runs published in the past {{ default_published_days }} days.
{% endblocktrans %}
</p>
<table class="data-table-published display" cellspacing="0" width="100%">
<thead>
<tr>
<th role="button">
{% trans "Course Name" %}
</th>
<th role="button">
{% trans "Institution" %}
</th>
<th role="button">
{% trans "Start" %}
</th>
<th role="button">
{% trans "End" %}
</th>
<th role="button">
{% trans "Published Date" %}
</th>
<th role="button">
{% trans "Target Content" %}
</th>
</tr>
</thead>
<tbody>
{% for course_run in published_course_runs %}
<tr>
<td>
<a href="{% url 'publisher:publisher_course_run_detail' course_run.id %}">{{ course_run.title }}</a>
</td>
<td>{% if course_run.course.group_institution %}
{{ course_run.course.group_institution }}
{% endif %}
</td>
<td>
{{ course_run.start|date:"Y-m-d" }}
</td>
<td>
{{ course_run.end|date:"Y-m-d" }}
</td>
<td>
{{ course_run.state.modified|date:"Y-m-d" }}
</td>
<td>
{% if course_run.target_content %}Y{% else %}N{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
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