Commit 65b4c3d7 by Kevin Kim Committed by GitHub

Merge pull request #915 from edx/kkim/ora_tz_date

Convert ORA Due Dates
parents 280b820b 16bd2372
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
{% if peer_start %} {% if peer_start %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with start_date=peer_start|utc|date:"N j, Y H:i e" time_until=peer_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with start_date=peer_start|timezone:time_zone|date:"N j, Y H:i e" time_until=peer_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% elif peer_due %} {% elif peer_due %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with due_date=peer_due|utc|date:"N j, Y H:i e" time_until=peer_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with due_date=peer_due|timezone:time_zone|date:"N j, Y H:i e" time_until=peer_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% endif %} {% endif %}
</span> </span>
......
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
{% if submission_start %} {% if submission_start %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with start_date=submission_start|utc|date:"N j, Y H:i e" time_until=submission_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with start_date=submission_start|timezone:time_zone|date:"N j, Y H:i e" time_until=submission_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% elif submission_due %} {% elif submission_due %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with due_date=submission_due|utc|date:"N j, Y H:i e" time_until=submission_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with due_date=submission_due|timezone:time_zone|date:"N j, Y H:i e" time_until=submission_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% endif %} {% endif %}
</span> </span>
......
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
{% if self_start %} {% if self_start %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with start_date=self_start|utc|date:"N j, Y H:i e" time_until=self_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with start_date=self_start|timezone:time_zone|date:"N j, Y H:i e" time_until=self_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% elif self_due %} {% elif self_due %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with due_date=self_due|utc|date:"N j, Y H:i e" time_until=self_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with due_date=self_due|timezone:time_zone|date:"N j, Y H:i e" time_until=self_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% endif %} {% endif %}
</span> </span>
......
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
{% if training_start %} {% if training_start %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "available August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with start_date=training_start|utc|date:"N j, Y H:i e" time_until=training_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with start_date=training_start|timezone:time_zone|date:"N j, Y H:i e" time_until=training_start|timeuntil %}available <span class="date">{{ start_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
{% elif training_due %} {% elif training_due %}
<span class="step__deadline"> <span class="step__deadline">
{# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #} {# Translators: This string displays a date to the user, then tells them the time until that date. Example: "due August 13th, 2014 (in 5 days and 45 minutes)" #}
{% blocktrans with due_date=training_due|utc|date:"N j, Y H:i e" time_until=training_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %} {% blocktrans with due_date=training_due|timezone:time_zone|date:"N j, Y H:i e" time_until=training_due|timeuntil %}due <span class="date">{{ due_date }} (in {{ time_until }})</span>{% endblocktrans %}
</span> </span>
</span> </span>
{% endif %} {% endif %}
......
...@@ -7,11 +7,10 @@ from openassessment.assessment.api import peer as peer_api ...@@ -7,11 +7,10 @@ from openassessment.assessment.api import peer as peer_api
from openassessment.assessment.errors import ( from openassessment.assessment.errors import (
PeerAssessmentRequestError, PeerAssessmentInternalError, PeerAssessmentWorkflowError PeerAssessmentRequestError, PeerAssessmentInternalError, PeerAssessmentWorkflowError
) )
from openassessment.workflow import api as workflow_api
from openassessment.workflow.errors import AssessmentWorkflowError from openassessment.workflow.errors import AssessmentWorkflowError
from openassessment.xblock.defaults import DEFAULT_RUBRIC_FEEDBACK_TEXT from openassessment.xblock.defaults import DEFAULT_RUBRIC_FEEDBACK_TEXT
from .data_conversion import create_rubric_dict from .data_conversion import create_rubric_dict
from .resolve_dates import DISTANT_FUTURE from .resolve_dates import DISTANT_FUTURE, get_current_time_zone
from .data_conversion import clean_criterion_feedback, create_submission_dict, verify_assessment_parameters from .data_conversion import clean_criterion_feedback, create_submission_dict, verify_assessment_parameters
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -162,10 +161,12 @@ class PeerAssessmentMixin(object): ...@@ -162,10 +161,12 @@ class PeerAssessmentMixin(object):
path = 'openassessmentblock/peer/oa_peer_unavailable.html' path = 'openassessmentblock/peer/oa_peer_unavailable.html'
finished = False finished = False
problem_closed, reason, start_date, due_date = self.is_closed(step="peer-assessment") problem_closed, reason, start_date, due_date = self.is_closed(step="peer-assessment")
user_service = self.runtime.service(self, 'user')
context_dict = { context_dict = {
"rubric_criteria": self.rubric_criteria_with_labels, "rubric_criteria": self.rubric_criteria_with_labels,
"allow_latex": self.allow_latex, "allow_latex": self.allow_latex,
"time_zone": get_current_time_zone(user_service),
} }
if self.rubric_feedback_prompt is not None: if self.rubric_feedback_prompt is not None:
......
...@@ -24,6 +24,18 @@ DISTANT_PAST = dt.datetime(dt.MINYEAR, 1, 1, tzinfo=pytz.utc) ...@@ -24,6 +24,18 @@ DISTANT_PAST = dt.datetime(dt.MINYEAR, 1, 1, tzinfo=pytz.utc)
DISTANT_FUTURE = dt.datetime(dt.MAXYEAR, 1, 1, tzinfo=pytz.utc) DISTANT_FUTURE = dt.datetime(dt.MAXYEAR, 1, 1, tzinfo=pytz.utc)
def get_current_time_zone(user_service):
"""
Returns the preferred time zone for the current user, if specified, or UTC if not
:param user_service: XblockUserService
"""
user_preferences = user_service.get_current_user().opt_attrs.get('edx-platform.user_preferences')
if user_preferences is None:
return pytz.utc
return pytz.timezone(user_preferences.get('time_zone', 'utc'))
def _parse_date(value, _): def _parse_date(value, _):
""" """
Parse an ISO formatted datestring into a datetime object with timezone set to UTC. Parse an ISO formatted datestring into a datetime object with timezone set to UTC.
...@@ -46,7 +58,11 @@ def _parse_date(value, _): ...@@ -46,7 +58,11 @@ def _parse_date(value, _):
try: try:
return parse_date(value).replace(tzinfo=pytz.utc) return parse_date(value).replace(tzinfo=pytz.utc)
except ValueError: except ValueError:
raise InvalidDateFormat(_("'{date}' is an invalid date format. Make sure the date is formatted as YYYY-MM-DDTHH:MM:SS.").format(date=value)) raise InvalidDateFormat(
_("'{date}' is an invalid date format. Make sure the date is formatted as YYYY-MM-DDTHH:MM:SS.").format(
date=value
)
)
else: else:
raise InvalidDateFormat(_("'{date}' must be a date string or datetime").format(date=value)) raise InvalidDateFormat(_("'{date}' must be a date string or datetime").format(date=value))
...@@ -201,8 +217,11 @@ def resolve_dates(start, end, date_ranges, _): ...@@ -201,8 +217,11 @@ def resolve_dates(start, end, date_ranges, _):
step_end = _parse_date(step_end, _) if step_end is not None else prev_end step_end = _parse_date(step_end, _) if step_end is not None else prev_end
if step_start < prev_start: if step_start < prev_start:
msg = _(u"This step's start date '{start}' cannot be earlier than the previous step's start date '{prev}'.").format( msg = _(
start=step_start, prev=prev_start u"This step's start date '{start}' cannot be earlier than the previous step's start date '{prev}'."
).format(
start=step_start,
prev=prev_start,
) )
raise DateValidationError(msg) raise DateValidationError(msg)
......
...@@ -6,7 +6,7 @@ from webob import Response ...@@ -6,7 +6,7 @@ from webob import Response
from openassessment.assessment.api import self as self_api from openassessment.assessment.api import self as self_api
from openassessment.workflow import api as workflow_api from openassessment.workflow import api as workflow_api
from submissions import api as submission_api from submissions import api as submission_api
from .resolve_dates import DISTANT_FUTURE from .resolve_dates import DISTANT_FUTURE, get_current_time_zone
from .data_conversion import (clean_criterion_feedback, create_submission_dict, from .data_conversion import (clean_criterion_feedback, create_submission_dict,
create_rubric_dict, verify_assessment_parameters) create_rubric_dict, verify_assessment_parameters)
...@@ -51,9 +51,14 @@ class SelfAssessmentMixin(object): ...@@ -51,9 +51,14 @@ class SelfAssessmentMixin(object):
SubmissionError: Error occurred while retrieving the current submission. SubmissionError: Error occurred while retrieving the current submission.
SelfAssessmentRequestError: Error occurred while checking if we had a self-assessment. SelfAssessmentRequestError: Error occurred while checking if we had a self-assessment.
""" """
context = {'allow_latex': self.allow_latex}
path = 'openassessmentblock/self/oa_self_unavailable.html' path = 'openassessmentblock/self/oa_self_unavailable.html'
problem_closed, reason, start_date, due_date = self.is_closed(step="self-assessment") problem_closed, reason, start_date, due_date = self.is_closed(step="self-assessment")
user_service = self.runtime.service(self, 'user')
context = {
'allow_latex': self.allow_latex,
'time_zone': get_current_time_zone(user_service)
}
# We display the due date whether the problem is open or closed. # We display the due date whether the problem is open or closed.
# If no date is set, it defaults to the distant future, in which # If no date is set, it defaults to the distant future, in which
...@@ -121,7 +126,10 @@ class SelfAssessmentMixin(object): ...@@ -121,7 +126,10 @@ class SelfAssessmentMixin(object):
""" """
if self.submission_uuid is None: if self.submission_uuid is None:
return {'success': False, 'msg': self._(u"You must submit a response before you can perform a self-assessment.")} return {
'success': False,
'msg': self._(u"You must submit a response before you can perform a self-assessment.")
}
try: try:
assessment = self_api.create_assessment( assessment = self_api.create_assessment(
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -8,7 +8,7 @@ from openassessment.assessment.api import student_training ...@@ -8,7 +8,7 @@ from openassessment.assessment.api import student_training
from openassessment.workflow import api as workflow_api from openassessment.workflow import api as workflow_api
from openassessment.workflow.errors import AssessmentWorkflowError from openassessment.workflow.errors import AssessmentWorkflowError
from openassessment.xblock.data_conversion import convert_training_examples_list_to_dict, create_submission_dict from openassessment.xblock.data_conversion import convert_training_examples_list_to_dict, create_submission_dict
from .resolve_dates import DISTANT_FUTURE from .resolve_dates import DISTANT_FUTURE, get_current_time_zone
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -69,12 +69,14 @@ class StudentTrainingMixin(object): ...@@ -69,12 +69,14 @@ class StudentTrainingMixin(object):
# If no submissions have been created yet, the status will be None. # If no submissions have been created yet, the status will be None.
workflow_status = self.get_workflow_info().get('status') workflow_status = self.get_workflow_info().get('status')
problem_closed, reason, start_date, due_date = self.is_closed(step="student-training") problem_closed, reason, start_date, due_date = self.is_closed(step="student-training")
user_service = self.runtime.service(self, 'user')
context = {} context = {}
template = 'openassessmentblock/student_training/student_training_unavailable.html' template = 'openassessmentblock/student_training/student_training_unavailable.html'
# add allow_latex field to the context # add allow_latex field to the context
context['allow_latex'] = self.allow_latex context['allow_latex'] = self.allow_latex
context['time_zone'] = get_current_time_zone(user_service)
if not workflow_status: if not workflow_status:
return template, context return template, context
......
...@@ -8,7 +8,7 @@ from openassessment.fileupload import api as file_upload_api ...@@ -8,7 +8,7 @@ from openassessment.fileupload import api as file_upload_api
from openassessment.fileupload.exceptions import FileUploadError from openassessment.fileupload.exceptions import FileUploadError
from openassessment.workflow.errors import AssessmentWorkflowError from openassessment.workflow.errors import AssessmentWorkflowError
from .resolve_dates import DISTANT_FUTURE from .resolve_dates import DISTANT_FUTURE, get_current_time_zone
from data_conversion import create_submission_dict, prepare_submission_for_serialization from data_conversion import create_submission_dict, prepare_submission_for_serialization
from validation import validate_submission from validation import validate_submission
...@@ -376,9 +376,12 @@ class SubmissionMixin(object): ...@@ -376,9 +376,12 @@ class SubmissionMixin(object):
""" """
workflow = self.get_workflow_info() workflow = self.get_workflow_info()
problem_closed, reason, start_date, due_date = self.is_closed('submission') problem_closed, reason, start_date, due_date = self.is_closed('submission')
user_service = self.runtime.service(self, 'user')
path = 'openassessmentblock/response/oa_response.html' path = 'openassessmentblock/response/oa_response.html'
context = {} context = {
'time_zone': get_current_time_zone(user_service)
}
# Due dates can default to the distant future, in which case # Due dates can default to the distant future, in which case
# there's effectively no due date. # there's effectively no due date.
......
...@@ -309,6 +309,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -309,6 +309,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'must_grade': 5, 'must_grade': 5,
'review_num': 1, 'review_num': 1,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_unavailable.html', expected_context xblock, 'openassessmentblock/peer/oa_peer_unavailable.html', expected_context
...@@ -324,6 +325,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -324,6 +325,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'must_grade': 5, 'must_grade': 5,
'review_num': 1, 'review_num': 1,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_closed.html', expected_context xblock, 'openassessmentblock/peer/oa_peer_closed.html', expected_context
...@@ -339,6 +341,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -339,6 +341,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'must_grade': 5, 'must_grade': 5,
'review_num': 1, 'review_num': 1,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_unavailable.html', expected_context xblock, 'openassessmentblock/peer/oa_peer_unavailable.html', expected_context
...@@ -357,6 +360,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -357,6 +360,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'review_num': 1, 'review_num': 1,
'submit_button_text': 'submit your assessment & move to response #2', 'submit_button_text': 'submit your assessment & move to response #2',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_waiting.html', xblock, 'openassessmentblock/peer/oa_peer_waiting.html',
...@@ -396,6 +400,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -396,6 +400,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'peer_file_url': '', 'peer_file_url': '',
'submit_button_text': 'submit your assessment & move to response #2', 'submit_button_text': 'submit your assessment & move to response #2',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_assessment.html', xblock, 'openassessmentblock/peer/oa_peer_assessment.html',
...@@ -415,6 +420,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -415,6 +420,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'review_num': 1, 'review_num': 1,
'submit_button_text': 'submit your assessment & move to response #2', 'submit_button_text': 'submit your assessment & move to response #2',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
...@@ -438,6 +444,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -438,6 +444,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'review_num': 1, 'review_num': 1,
'submit_button_text': 'submit your assessment & move to response #2', 'submit_button_text': 'submit your assessment & move to response #2',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_closed.html', xblock, 'openassessmentblock/peer/oa_peer_closed.html',
...@@ -473,6 +480,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -473,6 +480,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'review_num': 1, 'review_num': 1,
'submit_button_text': 'submit your assessment & move to response #2', 'submit_button_text': 'submit your assessment & move to response #2',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_closed.html', xblock, 'openassessmentblock/peer/oa_peer_closed.html',
...@@ -500,6 +508,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -500,6 +508,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'must_grade': 5, 'must_grade': 5,
'review_num': 1, 'review_num': 1,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
...@@ -532,6 +541,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -532,6 +541,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'rubric_criteria': xblock.rubric_criteria, 'rubric_criteria': xblock.rubric_criteria,
'submit_button_text': 'Submit your assessment & review another response', 'submit_button_text': 'Submit your assessment & review another response',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_turbo_mode_waiting.html', xblock, 'openassessmentblock/peer/oa_peer_turbo_mode_waiting.html',
...@@ -562,6 +572,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -562,6 +572,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'rubric_criteria': xblock.rubric_criteria, 'rubric_criteria': xblock.rubric_criteria,
'submit_button_text': 'Submit your assessment & review another response', 'submit_button_text': 'Submit your assessment & review another response',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_turbo_mode.html', xblock, 'openassessmentblock/peer/oa_peer_turbo_mode.html',
...@@ -583,6 +594,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase): ...@@ -583,6 +594,7 @@ class TestPeerAssessmentRender(XBlockHandlerTestCase):
'rubric_criteria': xblock.rubric_criteria, 'rubric_criteria': xblock.rubric_criteria,
'submit_button_text': 'Submit your assessment & review another response', 'submit_button_text': 'Submit your assessment & review another response',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/peer/oa_peer_unavailable.html', xblock, 'openassessmentblock/peer/oa_peer_unavailable.html',
......
...@@ -3,10 +3,12 @@ Test resolving unspecified dates and date strings to datetimes. ...@@ -3,10 +3,12 @@ Test resolving unspecified dates and date strings to datetimes.
""" """
import datetime import datetime
import pytz
from django.test import TestCase from django.test import TestCase
import ddt import ddt
from openassessment.xblock.resolve_dates import resolve_dates, DISTANT_PAST, DISTANT_FUTURE from mock import MagicMock
from openassessment.xblock.resolve_dates import resolve_dates, DISTANT_PAST, DISTANT_FUTURE, get_current_time_zone
import pytz
from workbench.runtime import WorkBenchUserService
STUB_I18N = lambda x: x STUB_I18N = lambda x: x
...@@ -128,3 +130,14 @@ class ResolveDatesTest(TestCase): ...@@ -128,3 +130,14 @@ class ResolveDatesTest(TestCase):
], ],
STUB_I18N STUB_I18N
) )
@ddt.data(({}, pytz.utc),
({'pref-lang': 'en', 'time_zone': 'America/Los_Angeles'}, pytz.timezone('America/Los_Angeles')))
@ddt.unpack
def test_get_current_time_zone(self, user_preferences, expected_time_zone):
"""Verify get_current_time_zone returns correct time zone or UTC"""
user_service = WorkBenchUserService(3)
user_service.get_current_user().opt_attrs['edx-platform.user_preferences'] = user_preferences
time_zone = get_current_time_zone(user_service)
self.assertEqual(expected_time_zone, time_zone)
...@@ -169,7 +169,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -169,7 +169,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
self._assert_path_and_context( self._assert_path_and_context(
xblock, xblock,
'openassessmentblock/self/oa_self_unavailable.html', 'openassessmentblock/self/oa_self_unavailable.html',
{'self_start': datetime.datetime(5999, 1, 1).replace(tzinfo=pytz.utc), 'allow_latex': False} {
'self_start': datetime.datetime(5999, 1, 1).replace(tzinfo=pytz.utc),
'allow_latex': False,
'time_zone': pytz.utc,
}
) )
@scenario('data/self_assessment_closed.xml', user_id='Bob') @scenario('data/self_assessment_closed.xml', user_id='Bob')
...@@ -178,14 +182,22 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -178,14 +182,22 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
self._assert_path_and_context( self._assert_path_and_context(
xblock, xblock,
'openassessmentblock/self/oa_self_closed.html', 'openassessmentblock/self/oa_self_closed.html',
{'self_due': datetime.datetime(2000, 1, 1).replace(tzinfo=pytz.utc), 'allow_latex': False} {
'self_due': datetime.datetime(2000, 1, 1).replace(tzinfo=pytz.utc),
'allow_latex': False,
'time_zone': pytz.utc,
}
) )
@scenario('data/self_assessment_open.xml', user_id='Bob') @scenario('data/self_assessment_open.xml', user_id='Bob')
def test_open_no_submission(self, xblock): def test_open_no_submission(self, xblock):
# Without making a submission, this step should be unavailable # Without making a submission, this step should be unavailable
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_unavailable.html', {'allow_latex': False} xblock, 'openassessmentblock/self/oa_self_unavailable.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
}
) )
@scenario('data/self_assessment_open.xml', user_id='James Brown') @scenario('data/self_assessment_open.xml', user_id='James Brown')
...@@ -197,7 +209,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -197,7 +209,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
# Should still not be able to access self-assessment # Should still not be able to access self-assessment
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_unavailable.html', {'allow_latex': False} xblock, 'openassessmentblock/self/oa_self_unavailable.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
}
) )
@scenario('data/self_assessment_open.xml', user_id='James Brown') @scenario('data/self_assessment_open.xml', user_id='James Brown')
...@@ -209,7 +225,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -209,7 +225,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
xblock.get_student_item_dict(), u"𝓟𝓪𝓼𝓼 𝓽𝓱𝓮 𝓹𝓮𝓪𝓼" xblock.get_student_item_dict(), u"𝓟𝓪𝓼𝓼 𝓽𝓱𝓮 𝓹𝓮𝓪𝓼"
) )
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_complete.html', {'allow_latex': False}, xblock, 'openassessmentblock/self/oa_self_complete.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status='waiting', workflow_status='waiting',
status_details={ status_details={
'self': {'complete': True}, 'self': {'complete': True},
...@@ -226,7 +246,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -226,7 +246,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
# In the self --> peer configuration, self can be complete # In the self --> peer configuration, self can be complete
# if our status is "peer" # if our status is "peer"
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_complete.html', {'allow_latex': False}, xblock, 'openassessmentblock/self/oa_self_complete.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status="peer", workflow_status="peer",
status_details={ status_details={
'self': {'complete': True}, 'self': {'complete': True},
...@@ -241,7 +265,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -241,7 +265,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
xblock.get_student_item_dict(), (u"Ⱥɨn'ŧ ɨŧ fᵾnꝁɏ 1", u"Ⱥɨn'ŧ ɨŧ fᵾnꝁɏ 2") xblock.get_student_item_dict(), (u"Ⱥɨn'ŧ ɨŧ fᵾnꝁɏ 1", u"Ⱥɨn'ŧ ɨŧ fᵾnꝁɏ 2")
) )
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_complete.html', {'allow_latex': False}, xblock, 'openassessmentblock/self/oa_self_complete.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status='done' workflow_status='done'
) )
...@@ -252,7 +280,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -252,7 +280,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
xblock.get_student_item_dict(), u"Ⱥɨn'ŧ ɨŧ fᵾnꝁɏ" xblock.get_student_item_dict(), u"Ⱥɨn'ŧ ɨŧ fᵾnꝁɏ"
) )
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_cancelled.html', {'allow_latex': False}, xblock, 'openassessmentblock/self/oa_self_cancelled.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status='cancelled' workflow_status='cancelled'
) )
...@@ -270,6 +302,7 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -270,6 +302,7 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
'file_upload_type': None, 'file_upload_type': None,
'self_file_url': '', 'self_file_url': '',
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
}, },
workflow_status='self', workflow_status='self',
submission_uuid=submission['uuid'] submission_uuid=submission['uuid']
...@@ -290,7 +323,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -290,7 +323,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
create_rubric_dict(xblock.prompts, xblock.rubric_criteria) create_rubric_dict(xblock.prompts, xblock.rubric_criteria)
) )
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_complete.html', {'allow_latex': False}, xblock, 'openassessmentblock/self/oa_self_complete.html',
{
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status='self', workflow_status='self',
submission_uuid=submission['uuid'] submission_uuid=submission['uuid']
) )
...@@ -305,7 +342,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -305,7 +342,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
self._assert_path_and_context( self._assert_path_and_context(
xblock, xblock,
'openassessmentblock/self/oa_self_closed.html', 'openassessmentblock/self/oa_self_closed.html',
{'self_due': datetime.datetime(2000, 1, 1).replace(tzinfo=pytz.utc), 'allow_latex': False}, {
'self_due': datetime.datetime(2000, 1, 1).replace(tzinfo=pytz.utc),
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status='self', workflow_status='self',
submission_uuid=submission['uuid'] submission_uuid=submission['uuid']
) )
...@@ -332,7 +373,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase): ...@@ -332,7 +373,11 @@ class TestSelfAssessmentRender(XBlockHandlerTestCase):
# we ALWAYS show complete, even if the workflow tells us we're still have status 'self'. # we ALWAYS show complete, even if the workflow tells us we're still have status 'self'.
self._assert_path_and_context( self._assert_path_and_context(
xblock, 'openassessmentblock/self/oa_self_complete.html', xblock, 'openassessmentblock/self/oa_self_complete.html',
{'self_due': datetime.datetime(2000, 1, 1).replace(tzinfo=pytz.utc), 'allow_latex': False}, {
'self_due': datetime.datetime(2000, 1, 1).replace(tzinfo=pytz.utc),
'allow_latex': False,
'time_zone': pytz.utc,
},
workflow_status='self', workflow_status='self',
submission_uuid=submission['uuid'] submission_uuid=submission['uuid']
) )
......
...@@ -63,6 +63,7 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -63,6 +63,7 @@ class StudentTrainingAssessTest(StudentTrainingTest):
@ddt.file_data('data/student_training_mixin.json') @ddt.file_data('data/student_training_mixin.json')
def test_correct(self, xblock, data): def test_correct(self, xblock, data):
xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION) xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION)
data["expected_context"]['time_zone'] = pytz.utc
self.assert_path_and_context(xblock, data["expected_template"], data["expected_context"]) self.assert_path_and_context(xblock, data["expected_template"], data["expected_context"])
# Agree with the course author's assessment # Agree with the course author's assessment
...@@ -83,6 +84,7 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -83,6 +84,7 @@ class StudentTrainingAssessTest(StudentTrainingTest):
@ddt.file_data('data/student_training_mixin.json') @ddt.file_data('data/student_training_mixin.json')
def test_correct_with_error(self, xblock, data): def test_correct_with_error(self, xblock, data):
xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION) xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION)
data["expected_context"]['time_zone'] = pytz.utc
self.assert_path_and_context(xblock, data["expected_template"], data["expected_context"]) self.assert_path_and_context(xblock, data["expected_template"], data["expected_context"])
# Agree with the course author's assessment # Agree with the course author's assessment
...@@ -106,6 +108,7 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -106,6 +108,7 @@ class StudentTrainingAssessTest(StudentTrainingTest):
@ddt.file_data('data/student_training_mixin.json') @ddt.file_data('data/student_training_mixin.json')
def test_incorrect(self, xblock, data): def test_incorrect(self, xblock, data):
xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION) xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION)
data["expected_context"]['time_zone'] = pytz.utc
self.assert_path_and_context(xblock, data["expected_template"], data["expected_context"]) self.assert_path_and_context(xblock, data["expected_template"], data["expected_context"])
# Disagree with the course author's assessment # Disagree with the course author's assessment
...@@ -128,6 +131,7 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -128,6 +131,7 @@ class StudentTrainingAssessTest(StudentTrainingTest):
expected_context = data["expected_context"].copy() expected_context = data["expected_context"].copy()
expected_template = data["expected_template"] expected_template = data["expected_template"]
xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION) xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION)
expected_context['time_zone'] = pytz.utc
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
# Agree with the course author's assessment # Agree with the course author's assessment
...@@ -173,7 +177,10 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -173,7 +177,10 @@ class StudentTrainingAssessTest(StudentTrainingTest):
# Expect that we were correct # Expect that we were correct
self.assertTrue(resp['success'], msg=resp.get('msg')) self.assertTrue(resp['success'], msg=resp.get('msg'))
self.assertFalse(resp['corrections']) self.assertFalse(resp['corrections'])
expected_context = {"allow_latex": False} expected_context = {
"allow_latex": False,
'time_zone': pytz.utc,
}
expected_template = "openassessmentblock/student_training/student_training_complete.html" expected_template = "openassessmentblock/student_training/student_training_complete.html"
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
...@@ -203,6 +210,7 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -203,6 +210,7 @@ class StudentTrainingAssessTest(StudentTrainingTest):
xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION) xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION)
expected_context = data["expected_context"].copy() expected_context = data["expected_context"].copy()
expected_template = data["expected_template"] expected_template = data["expected_template"]
expected_context['time_zone'] = pytz.utc
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
resp = self.request(xblock, 'training_assess', json.dumps({}), response_format='json') resp = self.request(xblock, 'training_assess', json.dumps({}), response_format='json')
self.assertFalse(resp['success'], msg=resp.get('msg')) self.assertFalse(resp['success'], msg=resp.get('msg'))
...@@ -219,6 +227,7 @@ class StudentTrainingAssessTest(StudentTrainingTest): ...@@ -219,6 +227,7 @@ class StudentTrainingAssessTest(StudentTrainingTest):
xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION) xblock.create_submission(xblock.get_student_item_dict(), self.SUBMISSION)
expected_context = data["expected_context"].copy() expected_context = data["expected_context"].copy()
expected_template = data["expected_template"] expected_template = data["expected_template"]
expected_context['time_zone'] = pytz.utc
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
selected_data = { selected_data = {
...@@ -302,6 +311,7 @@ class StudentTrainingRenderTest(StudentTrainingTest): ...@@ -302,6 +311,7 @@ class StudentTrainingRenderTest(StudentTrainingTest):
expected_context = { expected_context = {
'training_due': "2000-01-01T00:00:00+00:00", 'training_due': "2000-01-01T00:00:00+00:00",
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
...@@ -315,6 +325,7 @@ class StudentTrainingRenderTest(StudentTrainingTest): ...@@ -315,6 +325,7 @@ class StudentTrainingRenderTest(StudentTrainingTest):
expected_template = "openassessmentblock/student_training/student_training_cancelled.html" expected_template = "openassessmentblock/student_training/student_training_cancelled.html"
expected_context = { expected_context = {
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
...@@ -333,5 +344,6 @@ class StudentTrainingRenderTest(StudentTrainingTest): ...@@ -333,5 +344,6 @@ class StudentTrainingRenderTest(StudentTrainingTest):
expected_context = { expected_context = {
'training_start': datetime.datetime(3000, 1, 1).replace(tzinfo=pytz.utc), 'training_start': datetime.datetime(3000, 1, 1).replace(tzinfo=pytz.utc),
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
self.assert_path_and_context(xblock, expected_template, expected_context) self.assert_path_and_context(xblock, expected_template, expected_context)
...@@ -182,6 +182,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -182,6 +182,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'file_upload_type': None, 'file_upload_type': None,
'submission_start': dt.datetime(4999, 4, 1).replace(tzinfo=pytz.utc), 'submission_start': dt.datetime(4999, 4, 1).replace(tzinfo=pytz.utc),
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -204,6 +205,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -204,6 +205,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'peer_incomplete': True, 'peer_incomplete': True,
'self_incomplete': True, 'self_incomplete': True,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -222,6 +224,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -222,6 +224,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'submit_enabled': False, 'submit_enabled': False,
'submission_due': dt.datetime(2999, 5, 6).replace(tzinfo=pytz.utc), 'submission_due': dt.datetime(2999, 5, 6).replace(tzinfo=pytz.utc),
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -239,6 +242,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -239,6 +242,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'save_status': 'This response has not been saved.', 'save_status': 'This response has not been saved.',
'submit_enabled': False, 'submit_enabled': False,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -262,6 +266,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -262,6 +266,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'submit_enabled': True, 'submit_enabled': True,
'submission_due': dt.datetime(2999, 5, 6).replace(tzinfo=pytz.utc), 'submission_due': dt.datetime(2999, 5, 6).replace(tzinfo=pytz.utc),
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -285,6 +290,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -285,6 +290,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'submit_enabled': True, 'submit_enabled': True,
'submission_due': dt.datetime(2999, 5, 6).replace(tzinfo=pytz.utc), 'submission_due': dt.datetime(2999, 5, 6).replace(tzinfo=pytz.utc),
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -303,6 +309,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -303,6 +309,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'peer_incomplete': True, 'peer_incomplete': True,
'self_incomplete': True, 'self_incomplete': True,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -333,7 +340,8 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -333,7 +340,8 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'cancelled_at': xblock.get_workflow_cancellation_info(submission['uuid']).get('cancelled_at'), 'cancelled_at': xblock.get_workflow_cancellation_info(submission['uuid']).get('cancelled_at'),
'cancelled_by_id': 'Bob', 'cancelled_by_id': 'Bob',
'cancelled_by': mock_staff 'cancelled_by': mock_staff
} },
'time_zone': pytz.utc,
} }
) )
...@@ -359,6 +367,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -359,6 +367,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'peer_incomplete': True, 'peer_incomplete': True,
'self_incomplete': True, 'self_incomplete': True,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -370,6 +379,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -370,6 +379,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'file_upload_type': None, 'file_upload_type': None,
'submission_due': dt.datetime(2014, 4, 5).replace(tzinfo=pytz.utc), 'submission_due': dt.datetime(2014, 4, 5).replace(tzinfo=pytz.utc),
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -388,6 +398,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -388,6 +398,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'peer_incomplete': False, 'peer_incomplete': False,
'self_incomplete': True, 'self_incomplete': True,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -412,6 +423,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -412,6 +423,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'student_submission': create_submission_dict(submission, xblock.prompts), 'student_submission': create_submission_dict(submission, xblock.prompts),
'file_upload_type': None, 'file_upload_type': None,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
...@@ -436,6 +448,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase): ...@@ -436,6 +448,7 @@ class SubmissionRenderTest(XBlockHandlerTestCase):
'student_submission': create_submission_dict(submission, xblock.prompts), 'student_submission': create_submission_dict(submission, xblock.prompts),
'file_upload_type': None, 'file_upload_type': None,
'allow_latex': False, 'allow_latex': False,
'time_zone': pytz.utc,
} }
) )
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
coverage==4.0.2 coverage==4.0.2
django-nose==1.4.1 django-nose==1.4.1
freezegun==0.1.11
mock==1.0.1 mock==1.0.1
moto==0.3.1 moto==0.3.1
pep8==1.7.0 pep8==1.7.0
......
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