feat: Add permissions filter to list courses API

The new filter, called `permissions`, allows callers to filter courses
per access granted to the specified username.  Callers can now filter
courses per roles, actions, etc.
This commit is contained in:
J. Victor Martins
2021-06-24 17:34:48 -03:00
committed by João Victor Martins
parent d25ace50b4
commit 6adf45df2f
7 changed files with 97 additions and 10 deletions

View File

@@ -100,7 +100,12 @@ class CourseListTestMixin(CourseApiTestMixin):
Common behavior for list_courses tests
"""
def _make_api_call(self, requesting_user, specified_user, org=None, filter_=None):
def _make_api_call(self,
requesting_user,
specified_user,
org=None,
filter_=None,
permissions=None):
"""
Call the list_courses api endpoint to get information about
`specified_user` on behalf of `requesting_user`.
@@ -108,7 +113,13 @@ class CourseListTestMixin(CourseApiTestMixin):
request = Request(self.request_factory.get('/'))
request.user = requesting_user
with check_mongo_calls(0):
return list_courses(request, specified_user.username, org=org, filter_=filter_)
return list_courses(
request,
specified_user.username,
org=org,
filter_=filter_,
permissions=permissions,
)
def verify_courses(self, courses):
"""
@@ -209,6 +220,28 @@ class TestGetCourseListMultipleCourses(CourseListTestMixin, ModuleStoreTestCase)
assert {course.id for course in filtered_courses} == {course.id for course in expected_courses},\
f'testing course_api.api.list_courses with filter_={filter_}'
def test_permissions(self):
# Create a second course to be filtered out of queries.
self.create_course(course='should-be-hidden-course')
# Create instructor (non-staff), and enroll him in the course.
instructor_user = self.create_user('the-instructor', is_staff=False)
self.create_enrollment(user=instructor_user, course_id=self.course.id)
self.create_courseaccessrole(
user=instructor_user,
course_id=self.course.id,
role='instructor',
org='edX',
)
filtered_courses = self._make_api_call(
instructor_user,
instructor_user,
permissions={'instructor'})
self.assertEqual({c.id for c in filtered_courses}, {self.course.id})
class TestGetCourseListExtras(CourseListTestMixin, ModuleStoreTestCase):
"""

View File

@@ -69,6 +69,7 @@ class TestCourseListGetForm(FormTestMixin, UsernameTestMixin, SharedModuleStoreT
'mobile': None,
'search_term': '',
'filter_': None,
'permissions': set(),
}
def test_basic(self):

View File

@@ -201,6 +201,36 @@ class CourseListViewTestCaseMultipleCourses(CourseApiTestViewMixin, ModuleStoreT
response = self.verify_response(params=params)
assert {course['course_id'] for course in response.data['results']} == {str(course.id) for course in expected_courses}, f'testing course_api.views.CourseListView with filter_={filter_}' # pylint: disable=line-too-long
def test_get_when_no_permission_then_filters_correctly(self):
"""
Given a user that is instructor in a course
And another course he is not an instructor
When get
Then only the first course is returned
"""
# Create a second course to be filtered out of queries.
self.create_course(course='should-be-hidden-course')
# Create instructor (non-staff), and enroll him in the course.
instructor_user = self.create_user('the-instructor', is_staff=False)
self.setup_user(instructor_user)
self.create_enrollment(user=instructor_user, course_id=self.course.id)
self.create_courseaccessrole(
user=instructor_user,
course_id=self.course.id,
role='instructor',
org='edX',
)
params = {'permissions': 'instructor',
'username': instructor_user.username}
response = self.verify_response(params=params)
self.assertEqual(response.status_code, 200)
ids = {c['course_id'] for c in response.json()['results']}
self.assertEqual(ids, {str(self.course.id)})
class CourseDetailViewTestCase(CourseApiTestViewMixin, SharedModuleStoreTestCase):
"""