Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

import datetime
import ddt
import pytz
from django.test import RequestFactory

from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from common.djangoapps.student.tests.factories import UserFactory
from openedx.core.lib.courses import course_image_url
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from zoneinfo import ZoneInfo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but I just realized that this import was added in a strange place. When imports are split into sections, I think the first is usually from the standard library, the next section (separated by a blank line) are third-party imports, and the final section (also separated by a blank line) are from first-party (or other edx-platform) imports. Does zoneinfo belong at the end of the first group?

If you fix the location of all of these, please do not squash and ensure there is a separate commit, so I can just review that change. Thank you.


from ...serializers.course_runs import CourseRunSerializer
from ..utils import serialize_datetime
Expand All @@ -22,7 +22,7 @@ class CourseRunSerializerTests(ModuleStoreTestCase): # lint-amnesty, pylint: di
def setUp(self):
super().setUp()

self.course_start = datetime.datetime.now(pytz.UTC)
self.course_start = datetime.datetime.now(ZoneInfo("UTC"))
self.course_end = self.course_start + datetime.timedelta(days=30)

self.request = RequestFactory().get('')
Expand Down
16 changes: 8 additions & 8 deletions cms/djangoapps/api/v1/tests/test_views/test_course_runs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from unittest.mock import patch # lint-amnesty, pylint: disable=unused-import

import ddt
import pytz
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import RequestFactory, override_settings
from django.urls import reverse
Expand All @@ -22,6 +21,7 @@
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory, ToyCourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from zoneinfo import ZoneInfo

from ...serializers.course_runs import CourseRunSerializer
from ..utils import serialize_datetime
Expand Down Expand Up @@ -117,7 +117,7 @@ def test_update(self):
assert CourseAccessRole.objects.filter(course_id=course_run.id).count() == 0

url = reverse('api:v1:course_run-detail', kwargs={'pk': str(course_run.id)})
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
end = start + datetime.timedelta(days=30)
title = 'A New Testing Strategy'
user = UserFactory()
Expand Down Expand Up @@ -165,7 +165,7 @@ def test_update_with_pacing_type(self):
"""
Test that update run updates the pacing type
"""
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
course_run = CourseFactory(start=start, end=None, self_paced=False)
data = {
'pacing_type': 'self_paced',
Expand All @@ -183,7 +183,7 @@ def test_update_with_instructor_role(self):
Test that update creates a new instructor role only if it does not exist
"""
instructor_role = 'instructor'
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
new_user = UserFactory()
course_run = CourseFactory(start=start, end=None, self_paced=False)
assert CourseAccessRole.objects.filter(course_id=course_run.id).count() == 0
Expand Down Expand Up @@ -214,7 +214,7 @@ def test_update_with_multiple_roles(self):
"""
staff_role = 'staff'
instructor_role = 'instructor'
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
course_run = CourseFactory(start=start, end=None, self_paced=False)

existing_user = UserFactory()
Expand Down Expand Up @@ -255,7 +255,7 @@ def test_update_with_multiple_roles(self):
def test_create(self, pacing_type, expected_self_paced_value):
"""Tests successful course run creation"""
user = UserFactory()
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
end = start + datetime.timedelta(days=30)
role = 'staff'
data = self.get_course_run_data(user, start, end, pacing_type, role)
Expand All @@ -280,7 +280,7 @@ def test_create_with_invalid_course_team(self):
with expected validation message
"""
user = UserFactory()
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
end = start + datetime.timedelta(days=30)
data = self.get_course_run_data(user, start, end, 'self-paced')
data['team'] = [{'user': 'invalid-username'}]
Expand Down Expand Up @@ -334,7 +334,7 @@ def test_rerun(self, pacing_type, expected_self_paced_value, number):
'short_name': original_course_run.id.org, # lint-amnesty, pylint: disable=no-member
'description': 'Testing Organization Description',
})
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
start = datetime.datetime.now(ZoneInfo("UTC")).replace(microsecond=0)
end = start + datetime.timedelta(days=30)
user = UserFactory()
role = 'instructor'
Expand Down
18 changes: 9 additions & 9 deletions cms/djangoapps/contentstore/api/views/course_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging

import dateutil
from pytz import UTC
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

Expand All @@ -13,6 +12,7 @@
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order

from .utils import course_author_access_required, get_bool_param
from zoneinfo import ZoneInfo

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -260,34 +260,34 @@ def _get_open_responses(self, course, graded_only):

def _has_date_before_start(self, ora, start): # lint-amnesty, pylint: disable=missing-function-docstring
if ora.submission_start:
if dateutil.parser.parse(ora.submission_start).replace(tzinfo=UTC) < start:
if dateutil.parser.parse(ora.submission_start).replace(tzinfo=ZoneInfo("UTC")) < start:
return True
if ora.submission_due:
if dateutil.parser.parse(ora.submission_due).replace(tzinfo=UTC) < start:
if dateutil.parser.parse(ora.submission_due).replace(tzinfo=ZoneInfo("UTC")) < start:
return True
for assessment in ora.rubric_assessments:
if assessment['start']:
if dateutil.parser.parse(assessment['start']).replace(tzinfo=UTC) < start:
if dateutil.parser.parse(assessment['start']).replace(tzinfo=ZoneInfo("UTC")) < start:
return True
if assessment['due']:
if dateutil.parser.parse(assessment['due']).replace(tzinfo=UTC) < start:
if dateutil.parser.parse(assessment['due']).replace(tzinfo=ZoneInfo("UTC")) < start:
return True

return False

def _has_date_after_end(self, ora, end): # lint-amnesty, pylint: disable=missing-function-docstring
if ora.submission_start:
if dateutil.parser.parse(ora.submission_start).replace(tzinfo=UTC) > end:
if dateutil.parser.parse(ora.submission_start).replace(tzinfo=ZoneInfo("UTC")) > end:
return True
if ora.submission_due:
if dateutil.parser.parse(ora.submission_due).replace(tzinfo=UTC) > end:
if dateutil.parser.parse(ora.submission_due).replace(tzinfo=ZoneInfo("UTC")) > end:
return True
for assessment in ora.rubric_assessments:
if assessment['start']:
if dateutil.parser.parse(assessment['start']).replace(tzinfo=UTC) > end:
if dateutil.parser.parse(assessment['start']).replace(tzinfo=ZoneInfo("UTC")) > end:
return True
if assessment['due']:
if dateutil.parser.parse(assessment['due']).replace(tzinfo=UTC) > end:
if dateutil.parser.parse(assessment['due']).replace(tzinfo=ZoneInfo("UTC")) > end:
return True
return False

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from datetime import datetime, timedelta

from django.core.management import CommandError, call_command
import pytz

from cms.djangoapps.contentstore.models import CleanStaleCertificateAvailabilityDatesConfig
from openedx.core.lib.courses import get_course_by_id
from xmodule.data import CertificatesDisplayBehaviors
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from zoneinfo import ZoneInfo


class CleanStaleCertAvailableDateTests(ModuleStoreTestCase):
Expand All @@ -26,7 +26,7 @@ def setUp(self):
self.instructor_paced_course1 = CourseFactory()

# set the self-paced courses to self-paced, create and insert an invalid certificate available date for them
self.certificate_available_date = datetime.now(pytz.UTC) + timedelta(days=30)
self.certificate_available_date = datetime.now(ZoneInfo("UTC")) + timedelta(days=30)
self.self_paced_course1.self_paced = True
self.self_paced_course1.certificate_available_date = self.certificate_available_date
self.self_paced_course2.self_paced = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from datetime import datetime, timedelta

import ddt
import pytz
from django.conf import settings
from django.test import override_settings
from django.urls import reverse
Expand All @@ -21,6 +20,7 @@
from cms.djangoapps.modulestore_migrator.tests.factories import ModulestoreSourceFactory
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.content_libraries import api as lib_api
from zoneinfo import ZoneInfo


@ddt.ddt
Expand Down Expand Up @@ -197,7 +197,7 @@ def test_filter_and_ordering_courses(
display_name="Course (Demo)",
id=archived_course_key,
org=archived_course_key.org,
end=(datetime.now() - timedelta(days=365)).replace(tzinfo=pytz.UTC),
end=(datetime.now() - timedelta(days=365)).replace(tzinfo=ZoneInfo("UTC")),
)
active_course_key = self.store.make_course_key("sample-org", "sample-number", "sample-run")
CourseOverviewFactory.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
from datetime import datetime, timedelta

import ddt
import pytz
from django.conf import settings
from django.urls import reverse
from rest_framework import status

from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.utils import reverse_course_url
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from zoneinfo import ZoneInfo


@ddt.ddt
Expand All @@ -36,7 +36,7 @@ def setUp(self):
display_name="Demo Course (Sample)",
id=archived_course_key,
org=archived_course_key.org,
end=(datetime.now() - timedelta(days=365)).replace(tzinfo=pytz.UTC),
end=(datetime.now() - timedelta(days=365)).replace(tzinfo=ZoneInfo("UTC")),
)
self.non_staff_client, _ = self.create_non_staff_authed_user_client()

Expand Down Expand Up @@ -256,7 +256,7 @@ def test_filter_and_ordering_courses(
display_name="Course (Demo)",
id=archived_course_key,
org=archived_course_key.org,
end=(datetime.now() - timedelta(days=365)).replace(tzinfo=pytz.UTC),
end=(datetime.now() - timedelta(days=365)).replace(tzinfo=ZoneInfo("UTC")),
)
active_course_key = self.store.make_course_key("foo-org", "foo-number", "foo-run")
CourseOverviewFactory.create(
Expand Down
8 changes: 5 additions & 3 deletions cms/djangoapps/contentstore/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
XBLOCK_DELETED,
XBLOCK_UPDATED,
)
from pytz import UTC

from cms.djangoapps.contentstore.courseware_index import (
CourseAboutSearchIndexer,
Expand All @@ -45,6 +44,7 @@
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import SignalHandler, modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
from zoneinfo import ZoneInfo

from ..models import ComponentLink, ContainerLink
from ..tasks import (
Expand Down Expand Up @@ -156,7 +156,9 @@ def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=

# Kick off a courseware indexing action after the data is ready
if CoursewareSearchIndexer.indexing_is_enabled() and CourseAboutSearchIndexer.indexing_is_enabled():
transaction.on_commit(lambda: update_search_index.delay(course_key_str, datetime.now(UTC).isoformat()))
transaction.on_commit(
lambda: update_search_index.delay(course_key_str, datetime.now(ZoneInfo("UTC")).isoformat())
)

update_discussions_settings_from_course_task.apply_async(
args=[course_key_str],
Expand Down Expand Up @@ -186,7 +188,7 @@ def listen_for_library_update(sender, library_key, **kwargs): # pylint: disable
# import here, because signal is registered at startup, but items in tasks are not yet able to be loaded
from cms.djangoapps.contentstore.tasks import update_library_index

update_library_index.delay(str(library_key), datetime.now(UTC).isoformat())
update_library_index.delay(str(library_key), datetime.now(ZoneInfo("UTC")).isoformat())


@receiver(SignalHandler.item_deleted)
Expand Down
4 changes: 2 additions & 2 deletions cms/djangoapps/contentstore/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
from organizations.exceptions import InvalidOrganizationException
from organizations.models import Organization
from path import Path as path
from pytz import UTC
from user_tasks.models import UserTaskArtifact, UserTaskStatus
from user_tasks.tasks import UserTask

Expand Down Expand Up @@ -93,6 +92,7 @@
from xmodule.modulestore.xml_importer import CourseImportException, import_course_from_xml, import_library_from_xml
from xmodule.tabs import StaticTab
from xmodule.util.keys import BlockKey
from zoneinfo import ZoneInfo

from .models import ComponentLink, ContainerLink, LearningContextLinksStatus, LearningContextLinksStatusChoices
from .outlines import update_outline_from_modulestore
Expand Down Expand Up @@ -249,7 +249,7 @@ def _parse_time(time_isoformat):
# remove the +00:00 from the end of the formats generated within the system
time_isoformat.split('+')[0],
"%Y-%m-%dT%H:%M:%S.%f"
).replace(tzinfo=UTC)
).replace(tzinfo=ZoneInfo("UTC"))


@shared_task
Expand Down
21 changes: 11 additions & 10 deletions cms/djangoapps/contentstore/tests/test_course_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from edx_toggles.toggles.testutils import override_waffle_flag
from milestones.models import MilestoneRelationshipType
from milestones.tests.utils import MilestonesTestCaseMixin
from pytz import UTC

from cms.djangoapps.contentstore import toggles
from cms.djangoapps.contentstore.utils import reverse_course_url, reverse_usage_url
Expand All @@ -52,6 +51,7 @@
from xmodule.fields import Date # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from zoneinfo import ZoneInfo

from .utils import AjaxEnabledTestClient, CourseTestCase

Expand Down Expand Up @@ -84,7 +84,7 @@ def test_pre_1900_date(self):
doesn't work for these dates.
"""
details = CourseDetails.fetch(self.course.id)
pre_1900 = datetime.datetime(1564, 4, 23, 1, 1, 1, tzinfo=UTC)
pre_1900 = datetime.datetime(1564, 4, 23, 1, 1, 1, tzinfo=ZoneInfo("UTC"))
details.enrollment_start = pre_1900
dumped_jsondetails = json.dumps(details, cls=CourseSettingsEncoder)
loaded_jsondetails = json.loads(dumped_jsondetails)
Expand All @@ -97,7 +97,7 @@ def test_ooc_encoder(self):
details = {
'number': 1,
'string': 'string',
'datetime': datetime.datetime.now(UTC)
'datetime': datetime.datetime.now(ZoneInfo("UTC"))
}
jsondetails = json.dumps(details, cls=CourseSettingsEncoder)
jsondetails = json.loads(jsondetails)
Expand Down Expand Up @@ -256,12 +256,13 @@ def test_update_and_fetch(self):
resp = self.client.get_json(url)
self.compare_details_with_encoding(json.loads(resp.content.decode('utf-8')), details.__dict__, "virgin get")

self.alter_field(url, details, 'start_date', datetime.datetime(2012, 11, 12, 1, 30, tzinfo=UTC))
self.alter_field(url, details, 'start_date', datetime.datetime(2012, 11, 1, 13, 30, tzinfo=UTC))
self.alter_field(url, details, 'end_date', datetime.datetime(2013, 2, 12, 1, 30, tzinfo=UTC))
self.alter_field(url, details, 'enrollment_start', datetime.datetime(2012, 10, 12, 1, 30, tzinfo=UTC))

self.alter_field(url, details, 'enrollment_end', datetime.datetime(2012, 11, 15, 1, 30, tzinfo=UTC))
self.alter_field(url, details, 'start_date', datetime.datetime(2012, 11, 12, 1, 30, tzinfo=ZoneInfo("UTC")))
self.alter_field(url, details, 'start_date', datetime.datetime(2012, 11, 1, 13, 30, tzinfo=ZoneInfo("UTC")))
self.alter_field(url, details, 'end_date', datetime.datetime(2013, 2, 12, 1, 30, tzinfo=ZoneInfo("UTC")))
self.alter_field(
url, details, 'enrollment_start', datetime.datetime(2012, 10, 12, 1, 30, tzinfo=ZoneInfo("UTC"))
)
self.alter_field(url, details, 'enrollment_end', datetime.datetime(2012, 11, 15, 1, 30, tzinfo=ZoneInfo("UTC")))
self.alter_field(url, details, 'short_description', "Short Description")
self.alter_field(url, details, 'about_sidebar_html', "About Sidebar HTML")
self.alter_field(url, details, 'overview', "Overview")
Expand Down Expand Up @@ -1501,7 +1502,7 @@ def test_validate_update_does_not_allow_proctoring_provider_changes_after_course
Only admin users may update the provider if the course has started.
"""
field_name = "proctoring_provider"
course = CourseFactory.create(start=datetime.datetime.now(UTC) - datetime.timedelta(days=1))
course = CourseFactory.create(start=datetime.datetime.now(ZoneInfo("UTC")) - datetime.timedelta(days=1))
user = UserFactory.create(is_staff=staff_user)

did_validate, errors, test_model = CourseMetadata.validate_and_update_from_json(
Expand Down
Loading
Loading