diff --git a/AUTHORS b/AUTHORS index 11d9f5dd74e862e366875a8aba98c87232611e4b..5e0d710513de4d5308c65cdc20dd1882118bf68a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -269,3 +269,4 @@ Florian Haas <florian@hastexo.com> Leonardo Quiñonez <leonardo.quinonez@edunext.co> Dmitry Viskov <dmitry.viskov@webenterprise.ru> Brian Jacobel <bjacobel@edx.org> +Sigberto Alarcon <salarcon@stanford.edu> diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 49d8426ecd6417a3774379bf9e5b9acd6b0768e8..cf5c9cba884049460967ca1c0c830dabfa667f95 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -11,6 +11,7 @@ import unittest from datetime import datetime, timedelta from HTMLParser import HTMLParser from nose.plugins.attrib import attr +from freezegun import freeze_time from django.conf import settings from django.contrib.auth.models import AnonymousUser @@ -18,6 +19,7 @@ from django.core.urlresolvers import reverse from django.http import Http404, HttpResponseBadRequest from django.test import TestCase from django.test.client import RequestFactory +from django.test.client import Client from django.test.utils import override_settings from mock import MagicMock, patch, create_autospec, Mock from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey @@ -614,6 +616,39 @@ class ViewsTestCase(ModuleStoreTestCase): self.assertIn("Score: 3.0 / 3.0", response_content) self.assertIn('#4', response_content) + @ddt.data(('America/New_York', -5), # UTC - 5 + ('Asia/Pyongyang', 9), # UTC + 9 + ('Europe/London', 0), # UTC + ('Canada/Yukon', -8), # UTC - 8 + ('Europe/Moscow', 4)) # UTC + 3 + 1 for daylight savings + @ddt.unpack + @freeze_time('2012-01-01') + def test_submission_history_timezone(self, timezone, hour_diff): + with (override_settings(TIME_ZONE=timezone)): + course = CourseFactory.create() + course_key = course.id + client = Client() + admin = AdminFactory.create() + client.login(username=admin.username, password='test') + state_client = DjangoXBlockUserStateClient(admin) + usage_key = course_key.make_usage_key('problem', 'test-history') + state_client.set( + username=admin.username, + block_key=usage_key, + state={'field_a': 'x', 'field_b': 'y'} + ) + url = reverse('submission_history', kwargs={ + 'course_id': unicode(course_key), + 'student_username': admin.username, + 'location': unicode(usage_key), + }) + response = client.get(url) + response_content = HTMLParser().unescape(response.content) + expected_time = datetime.now() + timedelta(hours=hour_diff) + expected_tz = expected_time.strftime('%Z') + self.assertIn(expected_tz, response_content) + self.assertIn(str(expected_time), response_content) + def _email_opt_in_checkbox(self, response, org_name_string=None): """Check if the email opt-in checkbox appears in the response content.""" checkbox_html = '<input id="email-opt-in" type="checkbox" name="opt-in" class="email-opt-in" value="true" checked>' diff --git a/lms/templates/courseware/submission_history.html b/lms/templates/courseware/submission_history.html index b7994c0cf5e5cd4ac31ba9d13a9e98593016ad52..b6b8f65676a647c36198ec23a9fa81ed2f0d9a09 100644 --- a/lms/templates/courseware/submission_history.html +++ b/lms/templates/courseware/submission_history.html @@ -1,11 +1,13 @@ <%page expression_filter="h"/> -<% import json %> +<% import json, pytz %> <h3>${username} > ${course_id} > ${location}</h3> % for i, (entry, score) in enumerate(zip(history_entries, scores)): <hr/> <div> -<b>#${len(history_entries) - i}</b>: ${entry.updated} UTC</br> + <% timedate = entry.updated.astimezone(pytz.timezone(settings.TIME_ZONE))%> + <% timedate_str = timedate.strftime('%Y-%m-%d %H:%M:%S %Z') %> +<b>#${len(history_entries) - i}</b>: ${timedate_str}</br> Score: ${score.grade} / ${score.max_grade} <pre> ${json.dumps(entry.state, indent=2, sort_keys=True)}