Skip to content

Commit

Permalink
fix: update discussions blackout dates logic to use discussions confi…
Browse files Browse the repository at this point in the history
…g data

fix: resolved conflicts
  • Loading branch information
AhtishamShahid committed Aug 4, 2023
1 parent b37286e commit c19b388
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 24 deletions.
22 changes: 1 addition & 21 deletions lms/djangoapps/discussion/rest_api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
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
Expand Down Expand Up @@ -128,7 +127,7 @@
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
)


Expand Down Expand Up @@ -324,25 +323,6 @@ def _format_datetime(dt):
"""
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)
Expand Down
99 changes: 98 additions & 1 deletion lms/djangoapps/discussion/rest_api/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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

Expand All @@ -24,7 +25,7 @@
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

Expand Down Expand Up @@ -307,3 +308,99 @@ def test_comment_creators_own_response(self):
_get_mfe_url(self.course.id, self.thread.id)
)
self.assertEqual(args_comment.app_name, 'discussion')


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()
)

def test_posting_disabled(self):
"""
Test posting when the posting restriction is disabled.
Assertion:
Posting should be allowed.
"""
date_ranges = self._get_date_ranges()
self._set_discussion_blackouts(date_ranges)

posting_allowed = self._check_posting_allowed(PostingRestriction.DISABLED)
self.assertTrue(posting_allowed)

def test_posting_enabled(self):
"""
Test posting when the posting restriction is enabled.
Assertion:
Posting should not be allowed.
"""
date_ranges = self._get_date_ranges()
self._set_discussion_blackouts(date_ranges)

posting_allowed = self._check_posting_allowed(PostingRestriction.ENABLED)
self.assertFalse(posting_allowed)

def test_posting_scheduled(self):
"""
Test posting when the posting restriction is scheduled.
Assertion:
Posting should not be allowed.
"""
date_ranges = self._get_date_ranges()
self._set_discussion_blackouts(date_ranges)

posting_allowed = self._check_posting_allowed(PostingRestriction.SCHEDULED)
self.assertFalse(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)
29 changes: 27 additions & 2 deletions lms/djangoapps/discussion/rest_api/utils.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -10,6 +12,7 @@

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,
Expand All @@ -33,13 +36,15 @@ 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_config = DiscussionsConfiguration.get(course.id).posting_restrictions
blackout_dates = course.get_discussion_blackout_datetimes()
return is_posting_allowed(discussions_config, blackout_dates) or has_discussion_privileges(user, course.id)


def set_attribute(threads, attribute, value):
Expand Down Expand Up @@ -455,3 +460,23 @@ def send_new_comment_on_response_notification(self):
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

0 comments on commit c19b388

Please sign in to comment.