Skip to content

Commit

Permalink
Merge branch 'master' into jill/studio-home-api-enforce-org-autocreate
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisChV authored Jan 15, 2025
2 parents f1f40e0 + fa0ead4 commit 0fc54ed
Show file tree
Hide file tree
Showing 55 changed files with 522 additions and 2,860 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ jobs:
run: |
sudo apt-get update && sudo apt-get install libmysqlclient-dev libxmlsec1-dev lynx
- name: Login to Docker Hub
uses: docker/[email protected]
# We pull this image a lot, and Dockerhub will rate limit us if we pull too often.
# This is an attempt to cache the image for better performance and to work around that.
# It will cache all pulled images, so if we add new images to this we'll need to update the key.
- name: Cache Docker images
uses: ScribeMD/[email protected]
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
key: docker-${{ runner.os }}-mongo-${{ matrix.mongo-version }}

- name: Start MongoDB
uses: supercharge/[email protected]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class StudioHomeSerializer(serializers.Serializer):
libraries_v2_enabled = serializers.BooleanField()
taxonomies_enabled = serializers.BooleanField()
taxonomy_list_mfe_url = serializers.CharField()
optimization_enabled = serializers.BooleanField()
request_course_creator_url = serializers.CharField()
rerun_creator_status = serializers.BooleanField()
show_new_library_button = serializers.BooleanField()
Expand Down
1 change: 0 additions & 1 deletion cms/djangoapps/contentstore/rest_api/v1/views/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ def get(self, request: Request):
"libraries_v1_enabled": true,
"libraries_v2_enabled": true,
"library_authoring_mfe_url": "//localhost:3001/course/course-v1:edX+P315+2T2023",
"optimization_enabled": true,
"request_course_creator_url": "/request_course_creator",
"rerun_creator_status": true,
"show_new_library_button": true,
Expand Down
27 changes: 0 additions & 27 deletions cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@
from django.conf import settings
from django.test import override_settings
from django.urls import reverse
from edx_toggles.toggles.testutils import (
override_waffle_switch,
)
from rest_framework import status

from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.tests.test_libraries import LibraryTestCase
from cms.djangoapps.contentstore.views.course import ENABLE_GLOBAL_STAFF_OPTIMIZATION
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from xmodule.modulestore.tests.factories import CourseFactory


FEATURES_WITH_HOME_PAGE_COURSE_V2_API = settings.FEATURES.copy()
Expand Down Expand Up @@ -53,7 +48,6 @@ def setUp(self):
"libraries_v2_enabled": False,
"taxonomies_enabled": True,
"taxonomy_list_mfe_url": 'http://course-authoring-mfe/taxonomies',
"optimization_enabled": False,
"request_course_creator_url": "/request_course_creator",
"rerun_creator_status": True,
"show_new_library_button": True,
Expand Down Expand Up @@ -254,27 +248,6 @@ def test_home_page_response_no_courses_non_staff(self, filter_key, filter_value)
self.assertEqual(len(response.data["courses"]), 0)
self.assertEqual(response.status_code, status.HTTP_200_OK)

@override_waffle_switch(ENABLE_GLOBAL_STAFF_OPTIMIZATION, True)
def test_org_query_if_passed(self):
"""Test home page when org filter passed as a query param"""
foo_course = self.store.make_course_key('foo-org', 'bar-number', 'baz-run')
test_course = CourseFactory.create(
org=foo_course.org,
number=foo_course.course,
run=foo_course.run
)
CourseOverviewFactory.create(id=test_course.id, org='foo-org')
response = self.client.get(self.url, {"org": "foo-org"})
self.assertEqual(len(response.data['courses']), 1)
self.assertEqual(response.status_code, status.HTTP_200_OK)

@override_waffle_switch(ENABLE_GLOBAL_STAFF_OPTIMIZATION, True)
def test_org_query_if_empty(self):
"""Test home page with an empty org query param"""
response = self.client.get(self.url)
self.assertEqual(len(response.data['courses']), 0)
self.assertEqual(response.status_code, status.HTTP_200_OK)


@ddt.ddt
class HomePageLibrariesViewTest(LibraryTestCase):
Expand Down
26 changes: 0 additions & 26 deletions cms/djangoapps/contentstore/rest_api/v2/views/tests/test_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
from django.conf import settings
from django.test import override_settings
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_switch
from rest_framework import status

from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.utils import reverse_course_url
from cms.djangoapps.contentstore.views.course import ENABLE_GLOBAL_STAFF_OPTIMIZATION
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory

FEATURES_WITH_HOME_PAGE_COURSE_V2_API = settings.FEATURES.copy()
Expand Down Expand Up @@ -104,30 +102,6 @@ def test_home_page_response(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(expected_response, response.data)

@override_waffle_switch(ENABLE_GLOBAL_STAFF_OPTIMIZATION, True)
def test_org_query_if_passed(self):
"""Get list of courses when org filter passed as a query param.
Expected result:
- A list of courses available to the logged in user for the specified org.
"""
response = self.client.get(self.api_v2_url, {"org": "demo-org"})

self.assertEqual(len(response.data['results']['courses']), 1)
self.assertEqual(response.status_code, status.HTTP_200_OK)

@override_waffle_switch(ENABLE_GLOBAL_STAFF_OPTIMIZATION, True)
def test_org_query_if_empty(self):
"""Get home page with an empty org query param.
Expected result:
- An empty list of courses available to the logged in user.
"""
response = self.client.get(self.api_v2_url)

self.assertEqual(len(response.data['results']['courses']), 0)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_active_only_query_if_passed(self):
"""Get list of active courses only.
Expand Down
16 changes: 2 additions & 14 deletions cms/djangoapps/contentstore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,6 @@ def get_course_context(request):
from cms.djangoapps.contentstore.views.course import (
get_courses_accessible_to_user,
_process_courses_list,
ENABLE_GLOBAL_STAFF_OPTIMIZATION,
)

def format_in_process_course_view(uca):
Expand All @@ -1619,10 +1618,7 @@ def format_in_process_course_view(uca):
) if uca.state == CourseRerunUIStateManager.State.FAILED else ''
}

optimization_enabled = GlobalStaff().has_user(request.user) and ENABLE_GLOBAL_STAFF_OPTIMIZATION.is_enabled()

org = request.GET.get('org', '') if optimization_enabled else None
courses_iter, in_process_course_actions = get_courses_accessible_to_user(request, org)
courses_iter, in_process_course_actions = get_courses_accessible_to_user(request)
split_archived = settings.FEATURES.get('ENABLE_SEPARATE_ARCHIVED_COURSES', False)
active_courses, archived_courses = _process_courses_list(courses_iter, in_process_course_actions, split_archived)
in_process_course_actions = [format_in_process_course_view(uca) for uca in in_process_course_actions]
Expand All @@ -1637,7 +1633,6 @@ def get_course_context_v2(request):
# 'cms.djangoapps.contentstore.utils' (most likely due to a circular import)
from cms.djangoapps.contentstore.views.course import (
get_courses_accessible_to_user,
ENABLE_GLOBAL_STAFF_OPTIMIZATION,
)

def format_in_process_course_view(uca):
Expand All @@ -1664,10 +1659,7 @@ def format_in_process_course_view(uca):
) if uca.state == CourseRerunUIStateManager.State.FAILED else ''
}

optimization_enabled = GlobalStaff().has_user(request.user) and ENABLE_GLOBAL_STAFF_OPTIMIZATION.is_enabled()

org = request.GET.get('org', '') if optimization_enabled else None
courses_iter, in_process_course_actions = get_courses_accessible_to_user(request, org)
courses_iter, in_process_course_actions = get_courses_accessible_to_user(request)
in_process_course_actions = [format_in_process_course_view(uca) for uca in in_process_course_actions]
return courses_iter, in_process_course_actions

Expand All @@ -1685,7 +1677,6 @@ def get_home_context(request, no_course=False):
_accessible_libraries_iter,
_get_course_creator_status,
_format_library_for_view,
ENABLE_GLOBAL_STAFF_OPTIMIZATION,
)
from cms.djangoapps.contentstore.views.library import (
user_can_view_create_library_button,
Expand All @@ -1698,8 +1689,6 @@ def get_home_context(request, no_course=False):
archived_courses = []
in_process_course_actions = []

optimization_enabled = GlobalStaff().has_user(request.user) and ENABLE_GLOBAL_STAFF_OPTIMIZATION.is_enabled()

user = request.user
libraries = []

Expand Down Expand Up @@ -1728,7 +1717,6 @@ def get_home_context(request, no_course=False):
'rerun_creator_status': GlobalStaff().has_user(user),
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False),
'allow_course_reruns': settings.FEATURES.get('ALLOW_COURSE_RERUNS', True),
'optimization_enabled': optimization_enabled,
'active_tab': 'courses',
'allowed_organizations': get_allowed_organizations(user),
'allowed_organizations_for_libraries': get_allowed_organizations_for_libraries(user),
Expand Down
23 changes: 4 additions & 19 deletions cms/djangoapps/contentstore/views/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_GET, require_http_methods
from edx_django_utils.monitoring import function_trace
from edx_toggles.toggles import WaffleSwitch
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import BlockUsageLocator
Expand Down Expand Up @@ -138,11 +137,6 @@
'group_configurations_list_handler', 'group_configurations_detail_handler',
'get_course_and_check_access']

WAFFLE_NAMESPACE = 'studio_home'
ENABLE_GLOBAL_STAFF_OPTIMIZATION = WaffleSwitch( # lint-amnesty, pylint: disable=toggle-missing-annotation
f'{WAFFLE_NAMESPACE}.enable_global_staff_optimization', __name__
)


class AccessListFallback(Exception):
"""
Expand Down Expand Up @@ -394,15 +388,12 @@ def get_in_process_course_actions(request):
]


def _accessible_courses_summary_iter(request, org=None):
def _accessible_courses_summary_iter(request):
"""
List all courses available to the logged in user by iterating through all the courses
Arguments:
request: the request object
org (string): if not None, this value will limit the courses returned. An empty
string will result in no courses, and otherwise only courses with the
specified org will be returned. The default value is None.
"""
def course_filter(course_summary):
"""
Expand All @@ -416,9 +407,7 @@ def course_filter(course_summary):

enable_home_page_api_v2 = settings.FEATURES["ENABLE_HOME_PAGE_COURSE_API_V2"]

if org is not None:
courses_summary = [] if org == '' else CourseOverview.get_all_courses(orgs=[org])
elif enable_home_page_api_v2:
if enable_home_page_api_v2:
# If the new home page API is enabled, we should use the Django ORM to filter and order the courses
courses_summary = CourseOverview.get_all_courses()
else:
Expand Down Expand Up @@ -765,21 +754,17 @@ def course_index(request, course_key):


@function_trace('get_courses_accessible_to_user')
def get_courses_accessible_to_user(request, org=None):
def get_courses_accessible_to_user(request):
"""
Try to get all courses by first reversing django groups and fallback to old method if it fails
Note: overhead of pymongo reads will increase if getting courses from django groups fails
Arguments:
request: the request object
org (string): for global staff users ONLY, this value will be used to limit
the courses returned. A value of None will have no effect (all courses
returned), an empty string will result in no courses, and otherwise only courses with the
specified org will be returned. The default value is None.
"""
if GlobalStaff().has_user(request.user):
# user has global access so no need to get courses from django groups
courses, in_process_course_actions = _accessible_courses_summary_iter(request, org)
courses, in_process_course_actions = _accessible_courses_summary_iter(request)
else:
try:
courses, in_process_course_actions = _accessible_courses_list_from_groups(request)
Expand Down
1 change: 1 addition & 0 deletions cms/static/js/views/components/add_library_content.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function($, _, gettext, BaseModal) {
// Translators: "title" is the name of the current component being edited.
titleFormat: gettext('Add library content'),
addPrimaryActionButton: false,
showEditorModeButtons: false,
}),

initialize: function() {
Expand Down
11 changes: 11 additions & 0 deletions cms/static/js/views/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ function($, _, XBlockView, ModuleUtils, gettext, StringUtils, NotificationView)
newParent = undefined;
},
update: function(event, ui) {
try {
window.parent.postMessage(
{
type: 'refreshPositions',
message: 'Refresh positions of all xblocks',
payload: {}
}, document.referrer
);
} catch (e) {
console.error(e);
}
// When dragging from one ol to another, this method
// will be called twice (once for each list). ui.sender will
// be null if the change is related to the list the element
Expand Down
1 change: 1 addition & 0 deletions cms/static/js/views/modals/select_v2_library_content.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function($, _, gettext, BaseModal) {
viewSpecificClasses: 'modal-add-component-picker confirm',
titleFormat: gettext('Add library content'),
addPrimaryActionButton: false,
showEditorModeButtons: false,
}),

events: {
Expand Down
Loading

0 comments on commit 0fc54ed

Please sign in to comment.