fix: update discussions blackout dates logic to use discussions confi… (#32896)

This commit is contained in:
Ahtisham Shahid
2023-08-04 18:02:26 +05:00
committed by GitHub
parent b37286e035
commit 7e23feeb33
3 changed files with 111 additions and 24 deletions

View File

@@ -44,7 +44,6 @@ from openedx.core.djangoapps.discussions.models import (
DiscussionsConfiguration,
DiscussionTopicLink,
Provider,
PostingRestriction
)
from openedx.core.djangoapps.discussions.utils import get_accessible_discussion_xblocks
from openedx.core.djangoapps.django_comment_common import comment_client
@@ -128,7 +127,7 @@ from .utils import (
discussion_open_for_user,
get_usernames_for_course,
get_usernames_from_search_string,
set_attribute, send_response_notifications
set_attribute, send_response_notifications, is_posting_allowed
)
@@ -324,25 +323,6 @@ def get_course(request, course_key):
"""
return dt.isoformat().replace('+00:00', 'Z')
def is_posting_allowed(posting_restrictions, blackout_schedules):
"""
Check if posting is allowed based on the given posting restrictions and blackout schedules.
Args:
posting_restrictions (str): Values would be "disabled", "scheduled" or "enabled".
blackout_schedules (List[Dict[str, datetime]]): The list of blackout schedules
Returns:
bool: True if posting is allowed, False otherwise.
"""
now = datetime.now(UTC)
if posting_restrictions == PostingRestriction.DISABLED:
return True
elif posting_restrictions == PostingRestriction.SCHEDULED:
return not any(schedule["start"] <= now <= schedule["end"] for schedule in blackout_schedules)
else:
return False
course = _get_course(course_key, request.user)
user_roles = get_user_role_names(request.user, course_key)
course_config = DiscussionsConfiguration.get(course_key)

View File

@@ -5,6 +5,7 @@ Tests for Discussion REST API utils.
from datetime import datetime, timedelta
from unittest.mock import Mock
import ddt
from django.conf import settings
from httpretty import httpretty
from pytz import UTC
@@ -12,6 +13,7 @@ import unittest
from common.djangoapps.student.roles import CourseStaffRole, CourseInstructorRole
from lms.djangoapps.discussion.django_comment_client.tests.utils import ForumsEnableMixin
from lms.djangoapps.discussion.rest_api.tests.utils import CommentsServiceMockMixin, ThreadMock
from openedx.core.djangoapps.discussions.models import PostingRestriction
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -24,7 +26,7 @@ from lms.djangoapps.discussion.rest_api.utils import (
get_moderator_users_list,
get_archived_topics,
remove_empty_sequentials,
send_response_notifications
send_response_notifications, is_posting_allowed
)
from openedx_events.learning.signals import USER_NOTIFICATION_REQUESTED
@@ -307,3 +309,80 @@ class TestSendResponseNotifications(ForumsEnableMixin, CommentsServiceMockMixin,
_get_mfe_url(self.course.id, self.thread.id)
)
self.assertEqual(args_comment.app_name, 'discussion')
@ddt.ddt
class TestBlackoutDates(ForumsEnableMixin, CommentsServiceMockMixin, ModuleStoreTestCase):
"""
Test for the is_posting_allowed function
"""
def setUp(self):
super().setUp()
self.course = CourseFactory.create()
def _get_date_ranges(self):
"""
Generate date ranges for testing purposes.
Returns:
list: List of date range tuples.
"""
now = datetime.now(UTC)
date_ranges = [
(now - timedelta(days=14), now + timedelta(days=23)),
]
return date_ranges
def _set_discussion_blackouts(self, date_ranges):
"""
Set discussion blackouts for the given date ranges.
Args:
date_ranges (list): List of date range tuples.
"""
self.course.discussion_blackouts = [
[start_date.isoformat(), end_date.isoformat()] for start_date, end_date in date_ranges
]
def _check_posting_allowed(self, posting_restriction):
"""
Check if posting is allowed for the given posting restriction.
Args:
posting_restriction (str): Posting restriction type.
Returns:
bool: True if posting is allowed, False otherwise.
"""
return is_posting_allowed(
posting_restriction,
self.course.get_discussion_blackout_datetimes()
)
@ddt.data(
(PostingRestriction.DISABLED, True),
(PostingRestriction.ENABLED, False),
(PostingRestriction.SCHEDULED, False),
)
@ddt.unpack
def test_blackout_dates(self, restriction, state):
"""
Test is_posting_allowed function with the misc posting restriction
"""
date_ranges = self._get_date_ranges()
self._set_discussion_blackouts(date_ranges)
posting_allowed = self._check_posting_allowed(restriction)
self.assertEqual(state, posting_allowed)
def test_posting_scheduled_future(self):
"""
Test posting when the posting restriction is scheduled in the future.
Assertion:
Posting should be allowed.
"""
now = datetime.now(UTC)
date_ranges = [
(now + timedelta(days=6), now + timedelta(days=23)),
]
self._set_discussion_blackouts(date_ranges)
posting_allowed = self._check_posting_allowed(PostingRestriction.SCHEDULED)
self.assertTrue(posting_allowed)

View File

@@ -1,6 +1,8 @@
"""
Utils for discussion API.
"""
from datetime import datetime
from pytz import UTC
from typing import List, Dict
from django.conf import settings
@@ -10,6 +12,7 @@ from django.db.models.functions import Length
from common.djangoapps.student.roles import CourseStaffRole, CourseInstructorRole
from lms.djangoapps.discussion.django_comment_client.utils import has_discussion_privileges
from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, PostingRestriction
from openedx.core.djangoapps.django_comment_common.models import (
Role,
FORUM_ROLE_ADMINISTRATOR,
@@ -33,13 +36,18 @@ class AttributeDict(dict):
def discussion_open_for_user(course, user):
"""
Check if course discussion are open or not for user.
Check if the course discussion are open or not for user.
Arguments:
course: Course to check discussions for
user: User to check for privileges in course
"""
return course.forum_posts_allowed or has_discussion_privileges(user, course.id)
discussions_posting_restrictions = DiscussionsConfiguration.get(course.id).posting_restrictions
blackout_dates = course.get_discussion_blackout_datetimes()
return (
is_posting_allowed(discussions_posting_restrictions, blackout_dates) or
has_discussion_privileges(user, course.id)
)
def set_attribute(threads, attribute, value):
@@ -455,3 +463,23 @@ class DiscussionNotificationSender:
self._response_and_thread_has_same_creator()
):
self._send_notification([self.parent_response.user_id], "new_comment_on_response")
def is_posting_allowed(posting_restrictions: str, blackout_schedules: List):
"""
Check if posting is allowed based on the given posting restrictions and blackout schedules.
Args:
posting_restrictions (str): Values would be "disabled", "scheduled" or "enabled".
blackout_schedules (List[Dict[str, datetime]]): The list of blackout schedules
Returns:
bool: True if posting is allowed, False otherwise.
"""
now = datetime.now(UTC)
if posting_restrictions == PostingRestriction.DISABLED:
return True
elif posting_restrictions == PostingRestriction.SCHEDULED:
return not any(schedule["start"] <= now <= schedule["end"] for schedule in blackout_schedules)
else:
return False