From 21213ed8c6c873ef8e019419e3bad61836c51d76 Mon Sep 17 00:00:00 2001
From: Douglas Hall <dhall@edx.org>
Date: Tue, 19 Jan 2016 16:29:59 -0500
Subject: [PATCH] Use django.utils.timezone.now() when determining if the due
 date of a component has passed to avoid tz-aware/naive datetime comparison
 bug

---
 lti_consumer/lti_consumer.py                 |  5 +++--
 lti_consumer/tests/unit/test_lti_consumer.py | 21 +++++++++++++++++---
 setup.py                                     |  2 +-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/lti_consumer/lti_consumer.py b/lti_consumer/lti_consumer.py
index f3e4e8a..84e8430 100644
--- a/lti_consumer/lti_consumer.py
+++ b/lti_consumer/lti_consumer.py
@@ -56,10 +56,11 @@ import re
 import json
 import urllib
 
-from datetime import datetime
 from collections import namedtuple
 from webob import Response
 
+from django.utils import timezone
+
 from xblock.core import String, Scope, List, XBlock
 from xblock.fields import Boolean, Float, Integer
 from xblock.fragment import Fragment
@@ -597,7 +598,7 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
             close_date = due_date + self.graceperiod  # pylint: disable=no-member
         else:
             close_date = due_date
-        return close_date is not None and datetime.utcnow() > close_date
+        return close_date is not None and timezone.now() > close_date
 
     def student_view(self, context):
         """
diff --git a/lti_consumer/tests/unit/test_lti_consumer.py b/lti_consumer/tests/unit/test_lti_consumer.py
index 8d8d4ad..652e59f 100644
--- a/lti_consumer/tests/unit/test_lti_consumer.py
+++ b/lti_consumer/tests/unit/test_lti_consumer.py
@@ -4,9 +4,11 @@ Unit tests for LtiConsumerXBlock
 
 import unittest
 
-from datetime import datetime, timedelta
+from datetime import timedelta
 from mock import Mock, PropertyMock, patch
 
+from django.utils import timezone
+
 from lti_consumer.tests.unit.test_utils import FAKE_USER_ID, make_xblock, make_request
 
 from lti_consumer.lti_consumer import LtiConsumerXBlock, parse_handler_suffix
@@ -206,7 +208,7 @@ class TestProperties(TestLtiConsumerXBlock):
         """
         Test `is_past_due` when a graceperiod has been defined
         """
-        now = datetime.utcnow()
+        now = timezone.now()
         self.xblock.graceperiod = timedelta(days=1)
 
         self.xblock.due = now
@@ -219,7 +221,7 @@ class TestProperties(TestLtiConsumerXBlock):
         """
         Test `is_past_due` when no graceperiod has been defined
         """
-        now = datetime.utcnow()
+        now = timezone.now()
         self.xblock.graceperiod = None
 
         self.xblock.due = now - timedelta(days=1)
@@ -228,6 +230,19 @@ class TestProperties(TestLtiConsumerXBlock):
         self.xblock.due = now + timedelta(days=1)
         self.assertFalse(self.xblock.is_past_due)
 
+    @patch('lti_consumer.lti_consumer.timezone.now')
+    def test_is_past_due_timezone_now_called(self, mock_timezone_now):
+        """
+        Test `is_past_due` calls django.utils.timezone.now to get current datetime
+        """
+        now = timezone.now()
+        self.xblock.graceperiod = None
+        self.xblock.due = now
+        mock_timezone_now.return_value = now
+
+        __ = self.xblock.is_past_due
+        self.assertTrue(mock_timezone_now.called)
+
 
 class TestStudentView(TestLtiConsumerXBlock):
     """
diff --git a/setup.py b/setup.py
index 5c4a756..3622d3d 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@ def package_data(pkg, roots):
 
 setup(
     name='lti_consumer-xblock',
-    version='1.0.1',
+    version='1.0.2',
     description='This XBlock implements the consumer side of the LTI specification.',
     packages=[
         'lti_consumer',
-- 
GitLab