fix: update discussions blackout dates logic to use discussions confi… (#32896)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user