Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: AA-1058: Update edx-when version #29074

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
8253d41
fix: drop segment call for streak discount
mikix Sep 28, 2021
3a736ee
feat: Codejail as external service (optional)
ericfab179 Aug 1, 2021
d672d30
fix: Improve and fix codejail service integration
ericfab179 Aug 1, 2021
fc7104c
fix: Address PR comments
ericfab179 Oct 5, 2021
fe68828
fix: Address more PR comments
ericfab179 Oct 7, 2021
2a371e8
fix: Constrain nltk version for py35 sandbox
ericfab179 Oct 9, 2021
f9a28d1
fix: Mark user change as expected in LTIToolLaunchView.post
feanil Oct 15, 2021
2100537
Merge pull request #27795 from eduNEXT/eric/codejail_rest_service
felipemontoya Oct 15, 2021
03bf61d
Merge pull request #29033 from edx/feanil/mark_expected_user_change_i…
feanil Oct 15, 2021
2200b53
feat: only log requests that fail user verification in SafeSessionMid…
Oct 15, 2021
4dd5365
build: nudge devs about Maple release in github
regisb Oct 15, 2021
bc00e64
fix: Decorate celery task to set code owner attribute.
feanil Oct 15, 2021
835666a
fix: do not log error for sessions where user is changed to None (#29…
Oct 15, 2021
6a671f2
fix: Add the notices to plugin mapping.
feanil Oct 15, 2021
2cd130a
Merge pull request #29039 from edx/feanil/set_code_owner
feanil Oct 15, 2021
cc385b2
Merge pull request #29040 from edx/feanil/add_notices_to_code_owners
feanil Oct 15, 2021
32d35ac
feat: update the text for unearned certificates
Oct 15, 2021
79a7ad5
build: use the correct base branch for xsscommitlint
Oct 15, 2021
9726d14
fix: display right-to-left for rtl-languages in mobile (#28861)
meysam81 Oct 18, 2021
4b2161e
temp: Add logs for CourseMode selection errors (#28964)
julianajlk Oct 18, 2021
17f2d24
chore: update edx-proctoring version (#29051)
alangsto Oct 18, 2021
f4974ae
fix(program-portals): prevent resume course links from 404ing (#27046)
Oct 18, 2021
b92bc52
fix: mark register user change
robrap Oct 18, 2021
ab9fedf
fix: mark access token login user change
robrap Oct 18, 2021
d543a23
fix: User unretirement admin template use static instead of admin_sta…
schenedx Oct 18, 2021
e399fa4
Merge pull request #29053 from edx/robrap/exempt-register-safe-session
robrap Oct 18, 2021
ac8b4f5
Weekly Learning Goal back end (#28955)
cdeery Oct 18, 2021
24544aa
chore: bumping enterprise version to 3.30.12
long74100 Oct 19, 2021
d1aa75e
build: run xss-commit-linter verbosely
Oct 18, 2021
a6cc521
test: don't run xss-commit-linter unless we have a target branch
Oct 18, 2021
098bc97
feat: Release edx-enterprise 3.30.14 (#29064)
binodpant Oct 19, 2021
3611a8c
feat: Add support for course dashboard redirect for notices app
justinhynes Oct 7, 2021
b3b3ef9
feat: add courserun_key property to GA event transformer. (#28761)
brianhw Oct 19, 2021
22d106d
refactor: refactoring feature list for providers
Oct 15, 2021
5a6d056
build: remove python 3.5 requirement files (#29070)
UsamaSadiq Oct 20, 2021
ab4c14a
fix: fix pylint warnings (#29049)
UsamaSadiq Oct 20, 2021
7919bba
chore: Updating Python Requirements (#29059)
edx-requirements-bot Oct 20, 2021
668ae8b
chore: add ownership mapping for eventtracking (#29065)
Oct 20, 2021
d245c0d
Merge pull request #29017 from edx/jhynes/microba-1520_b2c-redirect
justinhynes Oct 20, 2021
f640727
Revert "feat: Add support for course dashboard redirect for notices app"
justinhynes Oct 20, 2021
34418a2
fix: check enterprise_enabled in is_enterprise_learner
long74100 Oct 19, 2021
4854af6
Merge pull request #29072 from edx/jhynes/revert-redirect
justinhynes Oct 20, 2021
9ee8df0
fix: Remove pylint constraint and fix warnings (#28646)
UsamaSadiq Oct 20, 2021
5635782
feat: leave IDV out of proctoring requirements mail if honorcode
ashultz0 Oct 20, 2021
e0d2cda
fix: ensure goal reminder command respects flag cofiguration of indiv…
MatthewPiatetsky Oct 20, 2021
ae18a96
feat: Add support for course dashboard redirect for notices app
justinhynes Oct 20, 2021
b0cc253
docs: Switch to management commands in Studio OAuth Maple migration (…
timmc-edx Oct 20, 2021
7e17f71
geoip2: update maxmind geolite country database
Oct 20, 2021
ba75bb6
feat: django codemods changes for common folder (#28775)
Oct 21, 2021
99ceec8
Merge pull request #29077 from edx/jhynes/microba-1520_redirectv2
justinhynes Oct 21, 2021
ef135fb
feat: only redirect to login for top-level page navigation requests (…
jinder1s Oct 21, 2021
9bf266f
fix: add missing __init__.py files
kdmccormick Jun 7, 2021
470be08
build: check for __init__.py files in each directory
kdmccormick Jun 8, 2021
9542725
fix: fixed pylint warnings
UsamaSadiq Oct 20, 2021
f79e18b
Merge pull request #29076 from edx/ashultz0/mst-853
ashultz0 Oct 21, 2021
706df06
feat: updated pages to the new custom pages design (#28686)
Oct 21, 2021
2ecb4da
fix: update course URL match pattern to also match learning MFE (#29050)
xitij2000 Oct 21, 2021
6e2277f
Merge pull request #28868 from edx/mikix/double-coupon
mikix Oct 21, 2021
71c3d9b
build: kickoff the Maple release
regisb Oct 15, 2021
1895f4e
chore: AA-1058: Update edx-when version
Dillon-Dumesnil Oct 20, 2021
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
6 changes: 5 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<!--

Happy Autumn!
🍁🍁
🍁🍁🍁🍁 🍁 Note: the Maple master branch has been created. Please consider whether your change
🍁🍁🍁🍁 should also be applied to Maple. If so, make another pull request against the
🍁🍁🍁🍁 open-release/maple.master branch, or ping @nedbat for help or questions.
🍁🍁

Please give your pull request a short but descriptive title.
Use conventional commits to separate and summarize commits logically:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/quality-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
with:
fetch-depth: 2

- name: Fetch master for comparison
run: git fetch --depth=1 origin master
- name: Fetch base branch for comparison
run: git fetch --depth=1 origin ${{ github.base_ref }}

- name: Install Required System Packages
run: sudo apt-get update && sudo apt-get install libxmlsec1-dev
Expand Down Expand Up @@ -65,6 +65,7 @@ jobs:
SCRIPT_TO_RUN: ./scripts/generic-ci-tests.sh
SHARD: 4
PIP_SRC_DIR: ${{ runner.temp }}
TARGET_BRANCH: ${{ github.base_ref }}
run: |
./scripts/all-tests.sh

Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/verify-dunder-init.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI

on:
pull_request:
branches:
- master

jobs:

verify_dunder_init:

name: Verify __init__.py Files
runs-on: ubuntu-20.04

steps:

- name: Check out branch
uses: actions/checkout@v2

- name: Ensure git is installed
run: |
sudo apt-get update && sudo apt-get install git

- name: Verify __init__.py files exist
run: |
scripts/verify-dunder-init.sh
13 changes: 13 additions & 0 deletions .tx/config
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,16 @@ file_filter = conf/locale/<lang>/LC_MESSAGES/edx_proctoring_proctortrack.po
source_file = conf/locale/en/LC_MESSAGES/edx_proctoring_proctortrack.po
source_lang = en
type = PO

[open-edx-releases.release-maple]
file_filter = conf/locale/<lang>/LC_MESSAGES/django.po
source_file = conf/locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO

[open-edx-releases.release-maple-js]
file_filter = conf/locale/<lang>/LC_MESSAGES/djangojs.po
source_file = conf/locale/en/LC_MESSAGES/djangojs.po
source_lang = en
type = PO

1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ REQ_FILES = \
requirements/edx/coverage \
requirements/edx/doc \
requirements/edx/paver \
requirements/edx-sandbox/py35 \
requirements/edx-sandbox/py38 \
requirements/edx/base \
requirements/edx/testing \
Expand Down
22 changes: 13 additions & 9 deletions cms/djangoapps/contentstore/rest_api/v0/tests/test_tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ def setUp(self):
)

# add a static tab to the course, for code coverage
self.test_tab = ItemFactory.create(
parent_location=self.course.location,
category="static_tab",
display_name="Static_1",
)
# add 4 static tabs to the course, for code coverage
self.test_tabs = []
for i in range(1, 5):
tab = ItemFactory.create(
parent_location=self.course.location,
category="static_tab",
display_name=f"Static_{i}"
)
self.test_tabs.append(tab)
self.reload_course()

def check_invalid_response(self, resp):
Expand Down Expand Up @@ -107,13 +111,13 @@ def test_reorder_tabs(self):
# reorder the last two tabs
tab_ids[num_orig_tabs - 1], tab_ids[num_orig_tabs - 2] = tab_ids[num_orig_tabs - 2], tab_ids[num_orig_tabs - 1]

# remove the middle tab
# remove the third to the last tab, the removed tab has to be a static tab
# (the code needs to handle the case where tabs requested for re-ordering is a subset of the tabs in the course)
removed_tab = tab_ids.pop(num_orig_tabs // 2)
assert len(tab_ids) == num_orig_tabs - 1
removed_tab = tab_ids.pop(num_orig_tabs - 3)
self.assertEqual(len(tab_ids), num_orig_tabs - 1)

# post the request
resp = self.make_reorder_tabs_request([{"tab_id": tab_id} for tab_id in tab_ids])
resp = self.make_reorder_tabs_request([{"tab_id": tab_id} for tab_id in tab_ids if 'static' in tab_id])
assert resp.status_code == 204

# reload the course and verify the new tab order
Expand Down
6 changes: 3 additions & 3 deletions cms/djangoapps/contentstore/rest_api/v0/views/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from common.djangoapps.student.auth import has_studio_read_access, has_studio_write_access
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, verify_course_exists, view_auth_classes
from ..serializers import CourseTabSerializer, CourseTabUpdateSerializer, TabIDLocatorSerializer
from ....views.tabs import edit_tab_handler, get_course_tabs, reorder_tabs_handler
from ....views.tabs import edit_tab_handler, get_course_static_tabs, reorder_tabs_handler


@view_auth_classes(is_authenticated=True)
Expand All @@ -34,7 +34,7 @@ class CourseTabListView(DeveloperErrorViewMixin, APIView):
@verify_course_exists()
def get(self, request: Request, course_id: str) -> Response:
"""
Get a list of all the tabs in a course including hidden tabs.
Get a list of all the static tabs in a course including hidden tabs.

**Example Request**

Expand Down Expand Up @@ -82,7 +82,7 @@ def get(self, request: Request, course_id: str) -> Response:
self.permission_denied(request)

course_module = modulestore().get_course(course_key)
tabs_to_render = get_course_tabs(course_module, request.user)
tabs_to_render = get_course_static_tabs(course_module, request.user)
return Response(CourseTabSerializer(tabs_to_render, many=True).data)


Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_404_no_course_module(self):
class ProctoringExamSettingsGetTests(ProctoringExamSettingsTestMixin, ModuleStoreTestCase, APITestCase):
""" Tests for proctored exam settings GETs """
@classmethod
def get_expected_response_data(cls, course, user):
def get_expected_response_data(cls, course, user): # pylint: disable=unused-argument
return {
'proctored_exam_settings': {
'enable_proctored_exams': course.enable_proctored_exams,
Expand Down
7 changes: 5 additions & 2 deletions cms/djangoapps/contentstore/rest_api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,13 @@ def get(self, request, course_id):

def post(self, request, course_id):
""" POST handler """
serializer = ProctoredExamSettingsSerializer if request.user.is_staff else LimitedProctoredExamSettingsSerializer
serializer = ProctoredExamSettingsSerializer if request.user.is_staff \
else LimitedProctoredExamSettingsSerializer
exam_config = serializer(data=request.data.get('proctored_exam_settings', {}))
valid_request = exam_config.is_valid()
if not request.user.is_staff and valid_request and ProctoredExamSettingsSerializer(data=request.data.get('proctored_exam_settings', {})).is_valid():
if not request.user.is_staff and valid_request and ProctoredExamSettingsSerializer(
data=request.data.get('proctored_exam_settings', {})
).is_valid():
return Response(status=status.HTTP_403_FORBIDDEN)

with modulestore().bulk_operations(CourseKey.from_string(course_id)):
Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/views/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def create_support_legend_dict():
# Set component types according to course policy file
if isinstance(course_advanced_keys, list):
for category in course_advanced_keys:
if category in advanced_component_types.keys() and category not in categories:
if category in advanced_component_types.keys() and category not in categories: # pylint: disable=consider-iterating-dictionary
# boilerplates not supported for advanced components
try:
component_display_name = xblock_type_display_name(category, default_display_name=category)
Expand Down
3 changes: 1 addition & 2 deletions cms/djangoapps/contentstore/views/course.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
Views related to operations on course objects
"""
# pylint: disable=filter-builtin-not-iterating


import copy
Expand Down Expand Up @@ -916,7 +915,7 @@ def _create_or_rerun_course(request):
return JsonResponse({
"ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format(name=display_name, err=str(error))}
)
except PermissionDenied as error:
except PermissionDenied as error: # pylint: disable=unused-variable
log.info(
"User does not have the permission to create course in this organization"
"or course creation is disabled."
Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/views/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def _create_library(request):
)
# Give the user admin ("Instructor") role for this library:
add_instructor(new_lib.location.library_key, request.user, request.user)
except PermissionDenied as error:
except PermissionDenied as error: # pylint: disable=unused-variable
log.info(
"User does not have the permission to create LIBRARY in this organization."
"User: '%s' Org: '%s' LIBRARY #: '%s'.",
Expand Down
59 changes: 40 additions & 19 deletions cms/djangoapps/contentstore/views/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ def tabs_handler(request, course_key_string):
return JsonResponse()

elif request.method == "GET": # assume html
# get all tabs from the tabs list: static tabs (a.k.a. user-created tabs) and built-in tabs
# get all tabs from the tabs list and select only static tabs (a.k.a. user-created tabs)
# present in the same order they are displayed in LMS

tabs_to_render = list(get_course_tabs(course_item, request.user))
tabs_to_render = list(get_course_static_tabs(course_item, request.user))

return render_to_response(
"edit-tabs.html",
Expand All @@ -78,9 +78,9 @@ def tabs_handler(request, course_key_string):
return HttpResponseNotFound()


def get_course_tabs(course_item: CourseBlock, user: User) -> Iterable[CourseTab]:
def get_course_static_tabs(course_item: CourseBlock, user: User) -> Iterable[CourseTab]:
"""
Yields all the course tabs in a course including hidden tabs.
Yields all the static tabs in a course including hidden tabs.

Args:
course_item (CourseBlock): The course object from which to get the tabs
Expand All @@ -96,7 +96,7 @@ def get_course_tabs(course_item: CourseBlock, user: User) -> Iterable[CourseTab]
# static tab needs its locator information to render itself as an xmodule
static_tab_loc = course_item.id.make_usage_key("static_tab", tab.url_slug)
tab.locator = static_tab_loc
yield tab
yield tab


def update_tabs_handler(course_item: CourseBlock, tabs_data: Dict, user: User) -> None:
Expand All @@ -119,7 +119,7 @@ def update_tabs_handler(course_item: CourseBlock, tabs_data: Dict, user: User) -

def reorder_tabs_handler(course_item, tabs_data, user):
"""
Helper function for handling reorder of tabs request
Helper function for handling reorder of static tabs request
"""

# Tabs are identified by tab_id or locators.
Expand All @@ -128,10 +128,40 @@ def reorder_tabs_handler(course_item, tabs_data, user):
# their tab_ids since the xmodule editor uses only locators to identify new objects.
requested_tab_id_locators = tabs_data["tabs"]

# original tab list in original order
old_tab_list = course_item.tabs
#get original tab list of only static tabs with their original index(position) in the full course tabs list
old_tab_dict = {}
for idx, tab in enumerate(course_item.tabs):
if isinstance(tab, StaticTab):
old_tab_dict[tab] = idx
old_tab_list = list(old_tab_dict.keys())

new_tab_list = create_new_list(requested_tab_id_locators, old_tab_list)

# Creates a full new course tab list of both default and static course tabs
# by looping through the new tab list of static only tabs and
# putting them in their new position in the list of course item tabs
# original_idx gives the list of positions of all static tabs in course tabs originally
full_new_tab_list = course_item.tabs
original_idx = list(old_tab_dict.values())
for i in range(len(new_tab_list)):
full_new_tab_list[original_idx[i]] = new_tab_list[i]

# validate the tabs to make sure everything is Ok (e.g., did the client try to reorder unmovable tabs?)
try:
CourseTabList.validate_tabs(full_new_tab_list)
except InvalidTabsException as exception:
raise ValidationError({"error": f"New list of tabs is not valid: {str(exception)}."}) from exception

# persist the new order of the tabs
course_item.tabs = full_new_tab_list
modulestore().update_item(course_item, user.id)

# create a new list in the new order

def create_new_list(requested_tab_id_locators, old_tab_list):
"""
Helper function for creating a new course tab list in the new order
of reordered tabs
"""
new_tab_list = []
for tab_id_locator in requested_tab_id_locators:
tab = get_tab_by_tab_id_locator(old_tab_list, tab_id_locator)
Expand All @@ -143,16 +173,7 @@ def reorder_tabs_handler(course_item, tabs_data, user):
# global or course settings. so add those to the end of the list.
non_displayed_tabs = set(old_tab_list) - set(new_tab_list)
new_tab_list.extend(non_displayed_tabs)

# validate the tabs to make sure everything is Ok (e.g., did the client try to reorder unmovable tabs?)
try:
CourseTabList.validate_tabs(new_tab_list)
except InvalidTabsException as exception:
raise ValidationError({"error": f"New list of tabs is not valid: {str(exception)}."}) from exception

# persist the new order of the tabs
course_item.tabs = new_tab_list
modulestore().update_item(course_item, user.id)
return new_tab_list


def edit_tab_handler(course_item: CourseBlock, tabs_data: Dict, user: User):
Expand Down
27 changes: 14 additions & 13 deletions cms/djangoapps/contentstore/views/tests/test_tabs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
""" Tests for tab functions (just primitive). """


import json

from cms.djangoapps.contentstore.tests.utils import CourseTestCase
Expand All @@ -25,12 +24,15 @@ def setUp(self):
# Set the URL for tests
self.url = reverse_course_url('tabs_handler', self.course.id)

# add a static tab to the course, for code coverage
self.test_tab = ItemFactory.create(
parent_location=self.course.location,
category="static_tab",
display_name="Static_1"
)
# add 4 static tabs to the course, for code coverage
self.test_tabs = []
for i in range(1, 5):
tab = ItemFactory.create(
parent_location=self.course.location,
category="static_tab",
display_name=f"Static_{i}"
)
self.test_tabs.append(tab)
self.reload_course()

def check_invalid_tab_id_response(self, resp):
Expand All @@ -39,7 +41,6 @@ def check_invalid_tab_id_response(self, resp):
self.assertEqual(resp.status_code, 400)
resp_content = json.loads(resp.content.decode('utf-8'))
self.assertIn("error", resp_content)
self.assertIn("invalid_tab_id", resp_content['error'])

def test_not_implemented(self):
"""Verify not implemented errors"""
Expand Down Expand Up @@ -85,15 +86,15 @@ def test_reorder_tabs(self):
# reorder the last two tabs
tab_ids[num_orig_tabs - 1], tab_ids[num_orig_tabs - 2] = tab_ids[num_orig_tabs - 2], tab_ids[num_orig_tabs - 1]

# remove the middle tab
# remove the third to the last tab, the removed tab has to be a static tab
# (the code needs to handle the case where tabs requested for re-ordering is a subset of the tabs in the course)
removed_tab = tab_ids.pop(num_orig_tabs // 2)
removed_tab = tab_ids.pop(num_orig_tabs - 3)
self.assertEqual(len(tab_ids), num_orig_tabs - 1)

# post the request
# post the request with the reordered static tabs only
resp = self.client.ajax_post(
self.url,
data={'tabs': [{'tab_id': tab_id} for tab_id in tab_ids]},
data={'tabs': [{'tab_id': tab_id} for tab_id in tab_ids if 'static' in tab_id]},
)
self.assertEqual(resp.status_code, 204)

Expand Down Expand Up @@ -178,7 +179,7 @@ def test_tab_preview_html(self):
"""
Verify that the static tab renders itself with the correct HTML
"""
preview_url = f'/xblock/{self.test_tab.location}/{STUDENT_VIEW}'
preview_url = f'/xblock/{self.test_tabs[0].location}/{STUDENT_VIEW}'

resp = self.client.get(preview_url, HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 200)
Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/course_creators/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def post_save_callback(sender, **kwargs):
# We need to keep track of all_organization switch. If this switch is changed we are going to remove the
# Course Creator group.
if instance.state != instance.orig_state or instance.all_organizations != instance.orig_all_organizations:
granted_state_change = instance.state == CourseCreator.GRANTED or instance.orig_state == CourseCreator.GRANTED
granted_state_change = instance.state == CourseCreator.GRANTED or instance.orig_state == CourseCreator.GRANTED # pylint: disable=consider-using-in
# If either old or new state is 'granted', we must manipulate the course creator
# group maintained by authz. That requires staff permissions (stored admin).
if granted_state_change:
Expand Down
Empty file.
Loading