Merge pull request #12723 from edx/release
Merge hotfix-2016-06-10 release into master
This commit is contained in:
@@ -17,7 +17,7 @@ from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core import mail
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse as django_reverse
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.test import RequestFactory, TestCase
|
||||
from django.test.utils import override_settings
|
||||
@@ -34,7 +34,9 @@ from xmodule.modulestore import ModuleStoreEnum
|
||||
from bulk_email.models import BulkEmailFlag
|
||||
from course_modes.models import CourseMode
|
||||
from courseware.models import StudentModule
|
||||
from courseware.tests.factories import StaffFactory, InstructorFactory, BetaTesterFactory, UserProfileFactory
|
||||
from courseware.tests.factories import (
|
||||
BetaTesterFactory, GlobalStaffFactory, InstructorFactory, StaffFactory, UserProfileFactory
|
||||
)
|
||||
from courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
from django_comment_common.models import FORUM_ROLE_COMMUNITY_TA
|
||||
from django_comment_common.utils import seed_permissions_roles
|
||||
@@ -131,6 +133,82 @@ EXECUTIVE_SUMMARY_DATA = (
|
||||
)
|
||||
|
||||
|
||||
INSTRUCTOR_GET_ENDPOINTS = set([
|
||||
'get_anon_ids',
|
||||
'get_coupon_codes',
|
||||
'get_issued_certificates',
|
||||
'get_sale_order_records',
|
||||
'get_sale_records',
|
||||
])
|
||||
INSTRUCTOR_POST_ENDPOINTS = set([
|
||||
'active_registration_codes',
|
||||
'add_users_to_cohorts',
|
||||
'bulk_beta_modify_access',
|
||||
'calculate_grades_csv',
|
||||
'change_due_date',
|
||||
'export_ora2_data',
|
||||
'generate_registration_codes',
|
||||
'get_enrollment_report',
|
||||
'get_exec_summary_report',
|
||||
'get_grading_config',
|
||||
'get_problem_responses',
|
||||
'get_proctored_exam_results',
|
||||
'get_registration_codes',
|
||||
'get_student_progress_url',
|
||||
'get_students_features',
|
||||
'get_students_who_may_enroll',
|
||||
'get_user_invoice_preference',
|
||||
'list_background_email_tasks',
|
||||
'list_course_role_members',
|
||||
'list_email_content',
|
||||
'list_entrance_exam_instructor_tasks',
|
||||
'list_financial_report_downloads',
|
||||
'list_forum_members',
|
||||
'list_instructor_tasks',
|
||||
'list_report_downloads',
|
||||
'mark_student_can_skip_entrance_exam',
|
||||
'modify_access',
|
||||
'register_and_enroll_students',
|
||||
'rescore_entrance_exam',
|
||||
'rescore_problem',
|
||||
'reset_due_date',
|
||||
'reset_student_attempts',
|
||||
'reset_student_attempts_for_entrance_exam',
|
||||
'sale_validation',
|
||||
'show_student_extensions',
|
||||
'show_unit_extensions',
|
||||
'send_email',
|
||||
'spent_registration_codes',
|
||||
'students_update_enrollment',
|
||||
'update_forum_role_membership',
|
||||
])
|
||||
|
||||
|
||||
def reverse(endpoint, args=None, kwargs=None, is_dashboard_endpoint=True):
|
||||
"""
|
||||
Simple wrapper of Django's reverse that first ensures that we have declared
|
||||
each endpoint under test.
|
||||
|
||||
Arguments:
|
||||
args: The args to be passed through to reverse.
|
||||
endpoint: The endpoint to be passed through to reverse.
|
||||
kwargs: The kwargs to be passed through to reverse.
|
||||
is_dashboard_endpoint: True if this is an instructor dashboard endpoint
|
||||
that must be declared in the INSTRUCTOR_GET_ENDPOINTS or
|
||||
INSTRUCTOR_GET_ENDPOINTS sets, or false otherwise.
|
||||
|
||||
Returns:
|
||||
The return of Django's reverse function
|
||||
|
||||
"""
|
||||
is_endpoint_declared = endpoint in INSTRUCTOR_GET_ENDPOINTS or endpoint in INSTRUCTOR_POST_ENDPOINTS
|
||||
if is_dashboard_endpoint and is_endpoint_declared is False:
|
||||
# Verify that all endpoints are declared so we can ensure they are
|
||||
# properly validated elsewhere.
|
||||
raise ValueError("The endpoint {} must be declared in ENDPOINTS before use.".format(endpoint))
|
||||
return django_reverse(endpoint, args=args, kwargs=kwargs)
|
||||
|
||||
|
||||
@common_exceptions_400
|
||||
def view_success(request): # pylint: disable=unused-argument
|
||||
"A dummy view for testing that returns a simple HTTP response"
|
||||
@@ -191,6 +269,61 @@ class TestCommonExceptions400(TestCase):
|
||||
self.assertIn("Task is already running", result["error"])
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
@ddt.ddt
|
||||
class TestEndpointHttpMethods(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
Ensure that users can make GET requests against endpoints that allow GET,
|
||||
and not against those that don't allow GET.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""
|
||||
Set up test course.
|
||||
"""
|
||||
super(TestEndpointHttpMethods, cls).setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up global staff role so authorization will not fail.
|
||||
"""
|
||||
super(TestEndpointHttpMethods, self).setUp()
|
||||
global_user = GlobalStaffFactory()
|
||||
self.client.login(username=global_user.username, password='test')
|
||||
|
||||
@ddt.data(*INSTRUCTOR_POST_ENDPOINTS)
|
||||
def test_endpoints_reject_get(self, data):
|
||||
"""
|
||||
Tests that POST endpoints are rejected with 405 when using GET.
|
||||
"""
|
||||
url = reverse(data, kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(
|
||||
response.status_code, 405,
|
||||
"Endpoint {} returned status code {} instead of a 405. It should not allow GET.".format(
|
||||
data, response.status_code
|
||||
)
|
||||
)
|
||||
|
||||
@ddt.data(*INSTRUCTOR_GET_ENDPOINTS)
|
||||
def test_endpoints_accept_get(self, data):
|
||||
"""
|
||||
Tests that GET endpoints are not rejected with 405 when using GET.
|
||||
"""
|
||||
url = reverse(data, kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertNotEqual(
|
||||
response.status_code, 405,
|
||||
"Endpoint {} returned status code 405 where it shouldn't, since it should allow GET.".format(
|
||||
data
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
@patch('bulk_email.models.html_to_text', Mock(return_value='Mocking CourseEmail.text_message', autospec=True))
|
||||
class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
@@ -271,10 +404,10 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
|
||||
msg: message to display if assertion fails.
|
||||
"""
|
||||
url = reverse(endpoint, kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
if endpoint in ['send_email', 'students_update_enrollment', 'bulk_beta_modify_access']:
|
||||
response = self.client.post(url, args)
|
||||
else:
|
||||
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
|
||||
response = self.client.get(url, args)
|
||||
else:
|
||||
response = self.client.post(url, args)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
status_code,
|
||||
@@ -1919,13 +2052,13 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
def test_modify_access_noparams(self):
|
||||
""" Test missing all query parameters. """
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_modify_access_bad_action(self):
|
||||
""" Test with an invalid action parameter. """
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_staff.email,
|
||||
'rolename': 'staff',
|
||||
'action': 'robot-not-an-action',
|
||||
@@ -1935,7 +2068,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
def test_modify_access_bad_role(self):
|
||||
""" Test with an invalid action parameter. """
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_staff.email,
|
||||
'rolename': 'robot-not-a-roll',
|
||||
'action': 'revoke',
|
||||
@@ -1944,7 +2077,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
|
||||
def test_modify_access_allow(self):
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_user.email,
|
||||
'rolename': 'staff',
|
||||
'action': 'allow',
|
||||
@@ -1953,7 +2086,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
|
||||
def test_modify_access_allow_with_uname(self):
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_instructor.username,
|
||||
'rolename': 'staff',
|
||||
'action': 'allow',
|
||||
@@ -1962,7 +2095,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
|
||||
def test_modify_access_revoke(self):
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_staff.email,
|
||||
'rolename': 'staff',
|
||||
'action': 'revoke',
|
||||
@@ -1971,7 +2104,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
|
||||
def test_modify_access_revoke_with_username(self):
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_staff.username,
|
||||
'rolename': 'staff',
|
||||
'action': 'revoke',
|
||||
@@ -1980,7 +2113,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
|
||||
def test_modify_access_with_fake_user(self):
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': 'GandalfTheGrey',
|
||||
'rolename': 'staff',
|
||||
'action': 'revoke',
|
||||
@@ -1997,7 +2130,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
self.other_user.is_active = False
|
||||
self.other_user.save() # pylint: disable=no-member
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_user.username,
|
||||
'rolename': 'beta',
|
||||
'action': 'allow',
|
||||
@@ -2013,7 +2146,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
def test_modify_access_revoke_not_allowed(self):
|
||||
""" Test revoking access that a user does not have. """
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.other_staff.email,
|
||||
'rolename': 'instructor',
|
||||
'action': 'revoke',
|
||||
@@ -2025,7 +2158,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
Test that an instructor cannot remove instructor privelages from themself.
|
||||
"""
|
||||
url = reverse('modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.instructor.email,
|
||||
'rolename': 'instructor',
|
||||
'action': 'revoke',
|
||||
@@ -2044,20 +2177,20 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
def test_list_course_role_members_noparams(self):
|
||||
""" Test missing all query parameters. """
|
||||
url = reverse('list_course_role_members', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_list_course_role_members_bad_rolename(self):
|
||||
""" Test with an invalid rolename parameter. """
|
||||
url = reverse('list_course_role_members', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'rolename': 'robot-not-a-rolename',
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_list_course_role_members_staff(self):
|
||||
url = reverse('list_course_role_members', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'rolename': 'staff',
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -2079,7 +2212,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
|
||||
def test_list_course_role_members_beta(self):
|
||||
url = reverse('list_course_role_members', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'rolename': 'beta',
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -2112,7 +2245,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
|
||||
Get unique_student_identifier, rolename and action and update forum role.
|
||||
"""
|
||||
url = reverse('update_forum_role_membership', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(
|
||||
response = self.client.post(
|
||||
url,
|
||||
{
|
||||
'unique_student_identifier': identifier,
|
||||
@@ -2185,7 +2318,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
"""
|
||||
enroll user using a registration code
|
||||
"""
|
||||
redeem_url = reverse('register_code_redemption', args=[code])
|
||||
redeem_url = reverse('shoppingcart.views.register_code_redemption', args=[code], is_dashboard_endpoint=False)
|
||||
self.client.login(username=user.username, password='test')
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
@@ -2265,10 +2398,16 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
mode_slug=CourseMode.HONOR
|
||||
)
|
||||
# update the quantity of the cart item paid_course_reg_item
|
||||
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': paid_course_reg_item.id, 'qty': '4'})
|
||||
resp = self.client.post(
|
||||
reverse('shoppingcart.views.update_user_cart', is_dashboard_endpoint=False),
|
||||
{'ItemId': paid_course_reg_item.id, 'qty': '4'}
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
# apply the coupon code to the item in the cart
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': coupon.code})
|
||||
resp = self.client.post(
|
||||
reverse('shoppingcart.views.use_code', is_dashboard_endpoint=False),
|
||||
{'code': coupon.code}
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.cart.purchase()
|
||||
# get the updated item
|
||||
@@ -2277,7 +2416,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
coupon_redemption = CouponRedemption.objects.select_related('coupon').filter(order=self.cart)
|
||||
|
||||
sale_order_url = reverse('get_sale_order_records', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(sale_order_url)
|
||||
response = self.client.post(sale_order_url)
|
||||
self.assertEqual(response['Content-Type'], 'text/csv')
|
||||
self.assertIn('36', response.content.split('\r\n')[1])
|
||||
self.assertIn(str(item.unit_cost), response.content.split('\r\n')[1],)
|
||||
@@ -2301,11 +2440,18 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course.id)
|
||||
# apply the coupon code to the item in the cart
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': coupon.code})
|
||||
resp = self.client.post(
|
||||
reverse('shoppingcart.views.use_code', is_dashboard_endpoint=False),
|
||||
{'code': coupon.code}
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
# URL for instructor dashboard
|
||||
instructor_dashboard = reverse('instructor_dashboard', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
instructor_dashboard = reverse(
|
||||
'instructor_dashboard',
|
||||
kwargs={'course_id': self.course.id.to_deprecated_string()},
|
||||
is_dashboard_endpoint=False
|
||||
)
|
||||
# visit the instructor dashboard page and
|
||||
# check that the coupon redeem count should be 0
|
||||
resp = self.client.get(instructor_dashboard)
|
||||
@@ -2342,7 +2488,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
'get_sale_records',
|
||||
kwargs={'course_id': self.course.id.to_deprecated_string()}
|
||||
)
|
||||
response = self.client.get(url + '/csv', {})
|
||||
response = self.client.post(url + '/csv', {})
|
||||
self.assertEqual(response['Content-Type'], 'text/csv')
|
||||
|
||||
def test_get_sale_records_features_json(self):
|
||||
@@ -2361,7 +2507,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
course_registration_code.save()
|
||||
|
||||
url = reverse('get_sale_records', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('sale', res_json)
|
||||
|
||||
@@ -2411,7 +2557,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
course_registration_code.save()
|
||||
|
||||
url = reverse('get_sale_records', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('sale', res_json)
|
||||
|
||||
@@ -2459,7 +2605,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
)
|
||||
problem_location = ''
|
||||
|
||||
response = self.client.get(url, {'problem_location': problem_location})
|
||||
response = self.client.post(url, {'problem_location': problem_location})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertEqual(res_json, 'Could not find problem with this location.')
|
||||
|
||||
@@ -2494,7 +2640,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
)
|
||||
problem_location = ''
|
||||
|
||||
response = self.client.get(url, {'problem_location': problem_location})
|
||||
response = self.client.post(url, {'problem_location': problem_location})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('status', res_json)
|
||||
status = res_json['status']
|
||||
@@ -2515,7 +2661,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
with patch('instructor_task.api.submit_calculate_problem_responses_csv') as submit_task_function:
|
||||
error = AlreadyRunningError()
|
||||
submit_task_function.side_effect = error
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('status', res_json)
|
||||
self.assertIn('already in progress', res_json['status'])
|
||||
@@ -2529,7 +2675,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
student.profile.city = "Mos Eisley {}".format(student.id)
|
||||
student.profile.save()
|
||||
url = reverse('get_students_features', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('students', res_json)
|
||||
for student in self.students:
|
||||
@@ -2551,7 +2697,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
url = reverse('get_students_features', kwargs={'course_id': unicode(self.course.id)})
|
||||
set_course_cohort_settings(self.course.id, is_cohorted=is_cohorted)
|
||||
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
self.assertEqual('cohort' in res_json['feature_names'], is_cohorted)
|
||||
@@ -2571,7 +2717,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
|
||||
url = reverse('get_students_features', kwargs={'course_id': unicode(self.course.id)})
|
||||
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
self.assertEqual('team' in res_json['feature_names'], has_teams)
|
||||
@@ -2587,7 +2733,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
kwargs={'course_id': unicode(self.course.id)}
|
||||
)
|
||||
# Successful case:
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('status', res_json)
|
||||
self.assertNotIn('currently being created', res_json['status'])
|
||||
@@ -2595,7 +2741,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
with patch('instructor_task.api.submit_calculate_may_enroll_csv') as submit_task_function:
|
||||
error = AlreadyRunningError()
|
||||
submit_task_function.side_effect = error
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('status', res_json)
|
||||
self.assertIn('currently being created', res_json['status'])
|
||||
@@ -2610,7 +2756,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
kwargs={'course_id': unicode(self.course.id)}
|
||||
)
|
||||
# Successful case:
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('status', res_json)
|
||||
self.assertNotIn('currently being created', res_json['status'])
|
||||
@@ -2618,7 +2764,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
with patch('instructor_task.api.submit_proctored_exam_results_report') as submit_task_function:
|
||||
error = AlreadyRunningError()
|
||||
submit_task_function.side_effect = error
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('status', res_json)
|
||||
self.assertIn('currently being created', res_json['status'])
|
||||
@@ -2704,7 +2850,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
url = reverse('get_enrollment_report', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertIn('The detailed enrollment report is being created.', response.content)
|
||||
|
||||
def test_bulk_purchase_detailed_report(self):
|
||||
@@ -2716,11 +2862,16 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
"""
|
||||
paid_course_reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course.id)
|
||||
# update the quantity of the cart item paid_course_reg_item
|
||||
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'),
|
||||
{'ItemId': paid_course_reg_item.id, 'qty': '4'})
|
||||
resp = self.client.post(
|
||||
reverse('shoppingcart.views.update_user_cart', is_dashboard_endpoint=False),
|
||||
{'ItemId': paid_course_reg_item.id, 'qty': '4'}
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
# apply the coupon code to the item in the cart
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
resp = self.client.post(
|
||||
reverse('shoppingcart.views.use_code', is_dashboard_endpoint=False),
|
||||
{'code': self.coupon_code}
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.cart.purchase()
|
||||
|
||||
@@ -2754,7 +2905,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
|
||||
url = reverse('get_enrollment_report', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertIn('The detailed enrollment report is being created.', response.content)
|
||||
|
||||
def test_create_registration_code_without_invoice_and_order(self):
|
||||
@@ -2776,7 +2927,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
|
||||
url = reverse('get_enrollment_report', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertIn('The detailed enrollment report is being created.', response.content)
|
||||
|
||||
def test_invoice_payment_is_still_pending_for_registration_codes(self):
|
||||
@@ -2801,7 +2952,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
|
||||
url = reverse('get_enrollment_report', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertIn('The detailed enrollment report is being created.', response.content)
|
||||
|
||||
@patch.object(instructor.views.api, 'anonymous_id_for_user', Mock(return_value='42'))
|
||||
@@ -2811,7 +2962,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
Test the CSV output for the anonymized user ids.
|
||||
"""
|
||||
url = reverse('get_anon_ids', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response['Content-Type'], 'text/csv')
|
||||
body = response.content.replace('\r', '')
|
||||
self.assertTrue(body.startswith(
|
||||
@@ -2829,7 +2980,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
('mock_file_name_1', 'https://1.mock.url'),
|
||||
('mock_file_name_2', 'https://2.mock.url'),
|
||||
]
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
|
||||
expected_response = {
|
||||
"downloads": [
|
||||
@@ -2858,12 +3009,12 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
success_status = "The {report_type} report is being created.".format(report_type=report_type)
|
||||
if report_type == 'problem responses':
|
||||
with patch(task_api_endpoint):
|
||||
response = self.client.get(url, {'problem_location': ''})
|
||||
response = self.client.post(url, {'problem_location': ''})
|
||||
self.assertIn(success_status, response.content)
|
||||
else:
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
with patch(task_api_endpoint):
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertIn(success_status, response.content)
|
||||
|
||||
@ddt.data(*EXECUTIVE_SUMMARY_DATA)
|
||||
@@ -2881,7 +3032,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
with patch(task_api_endpoint):
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
success_status = "The {report_type} report is being created." \
|
||||
" To view the status of the report, see Pending" \
|
||||
" Tasks below".format(report_type=report_type)
|
||||
@@ -2903,7 +3054,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
with patch(task_api_endpoint) as mock:
|
||||
mock.side_effect = AlreadyRunningError()
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
already_running_status = "The {report_type} report is currently being created." \
|
||||
" To view the status of the report, see Pending Tasks below." \
|
||||
" You will be able to download the report" \
|
||||
@@ -2916,7 +3067,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
|
||||
with patch('instructor_task.api.submit_export_ora2_data') as mock_submit_ora2_task:
|
||||
mock_submit_ora2_task.return_value = True
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
success_status = "The ORA data report is being generated."
|
||||
self.assertIn(success_status, response.content)
|
||||
|
||||
@@ -2925,17 +3076,15 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
|
||||
with patch('instructor_task.api.submit_export_ora2_data') as mock_submit_ora2_task:
|
||||
mock_submit_ora2_task.side_effect = AlreadyRunningError()
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
already_running_status = "An ORA data report generation task is already in progress."
|
||||
self.assertIn(already_running_status, response.content)
|
||||
|
||||
def test_get_student_progress_url(self):
|
||||
""" Test that progress_url is in the successful response. """
|
||||
url = reverse('get_student_progress_url', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
url += "?unique_student_identifier={}".format(
|
||||
quote(self.students[0].email.encode("utf-8"))
|
||||
)
|
||||
response = self.client.get(url)
|
||||
data = {'unique_student_identifier': self.students[0].email.encode("utf-8")}
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('progress_url', res_json)
|
||||
@@ -2943,10 +3092,8 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
def test_get_student_progress_url_from_uname(self):
|
||||
""" Test that progress_url is in the successful response. """
|
||||
url = reverse('get_student_progress_url', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
url += "?unique_student_identifier={}".format(
|
||||
quote(self.students[0].username.encode("utf-8"))
|
||||
)
|
||||
response = self.client.get(url)
|
||||
data = {'unique_student_identifier': self.students[0].username.encode("utf-8")}
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('progress_url', res_json)
|
||||
@@ -2954,13 +3101,13 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
def test_get_student_progress_url_noparams(self):
|
||||
""" Test that the endpoint 404's without the required query params. """
|
||||
url = reverse('get_student_progress_url', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_get_student_progress_url_nostudent(self):
|
||||
""" Test that the endpoint 400's when requesting an unknown email. """
|
||||
url = reverse('get_student_progress_url', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
|
||||
@@ -3001,7 +3148,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_reset_student_attempts_deletall(self):
|
||||
""" Make sure no one can delete all students state on a problem. """
|
||||
url = reverse('reset_student_attempts', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'all_students': True,
|
||||
'delete_module': True,
|
||||
@@ -3011,7 +3158,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_reset_student_attempts_single(self):
|
||||
""" Test reset single student attempts. """
|
||||
url = reverse('reset_student_attempts', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
@@ -3028,7 +3175,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_reset_student_attempts_all(self, act):
|
||||
""" Test reset all student attempts. """
|
||||
url = reverse('reset_student_attempts', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'all_students': True,
|
||||
})
|
||||
@@ -3038,7 +3185,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_reset_student_attempts_missingmodule(self):
|
||||
""" Test reset for non-existant problem. """
|
||||
url = reverse('reset_student_attempts', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': 'robot-not-a-real-module',
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
@@ -3047,7 +3194,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_reset_student_attempts_delete(self):
|
||||
""" Test delete single student state. """
|
||||
url = reverse('reset_student_attempts', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'unique_student_identifier': self.student.email,
|
||||
'delete_module': True,
|
||||
@@ -3066,7 +3213,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_reset_student_attempts_nonsense(self):
|
||||
""" Test failure with both unique_student_identifier and all_students. """
|
||||
url = reverse('reset_student_attempts', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'unique_student_identifier': self.student.email,
|
||||
'all_students': True,
|
||||
@@ -3077,7 +3224,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_rescore_problem_single(self, act):
|
||||
""" Test rescoring of a single student. """
|
||||
url = reverse('rescore_problem', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
@@ -3088,7 +3235,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_rescore_problem_single_from_uname(self, act):
|
||||
""" Test rescoring of a single student. """
|
||||
url = reverse('rescore_problem', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'unique_student_identifier': self.student.username,
|
||||
})
|
||||
@@ -3099,7 +3246,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_rescore_problem_all(self, act):
|
||||
""" Test rescoring for all students. """
|
||||
url = reverse('rescore_problem', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_to_reset': self.problem_urlname,
|
||||
'all_students': True,
|
||||
})
|
||||
@@ -3111,7 +3258,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
""" Test course has entrance exam id set while resetting attempts"""
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'all_students': True,
|
||||
'delete_module': False,
|
||||
})
|
||||
@@ -3121,7 +3268,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
|
||||
def test_rescore_entrance_exam_with_invalid_exam(self):
|
||||
""" Test course has entrance exam id set while re-scoring. """
|
||||
url = reverse('rescore_entrance_exam', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
@@ -3225,7 +3372,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Make sure no one can delete all students state on entrance exam. """
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'all_students': True,
|
||||
'delete_module': True,
|
||||
})
|
||||
@@ -3235,7 +3382,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test reset single student attempts for entrance exam. """
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -3253,7 +3400,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test reset all student attempts for entrance exam. """
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'all_students': True,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -3263,7 +3410,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test reset for invalid entrance exam. """
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course_with_invalid_ee.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
@@ -3272,7 +3419,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test delete single student entrance exam state. """
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
'delete_module': True,
|
||||
})
|
||||
@@ -3288,7 +3435,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
self.client.login(username=staff_user.username, password='test')
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
'delete_module': True,
|
||||
})
|
||||
@@ -3298,7 +3445,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test failure with both unique_student_identifier and all_students. """
|
||||
url = reverse('reset_student_attempts_for_entrance_exam',
|
||||
kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
'all_students': True,
|
||||
})
|
||||
@@ -3308,7 +3455,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
def test_rescore_entrance_exam_single_student(self, act):
|
||||
""" Test re-scoring of entrance exam for single student. """
|
||||
url = reverse('rescore_entrance_exam', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -3317,7 +3464,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
def test_rescore_entrance_exam_all_student(self):
|
||||
""" Test rescoring for all students. """
|
||||
url = reverse('rescore_entrance_exam', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'all_students': True,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -3325,7 +3472,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
def test_rescore_entrance_exam_all_student_and_single(self):
|
||||
""" Test re-scoring with both all students and single student parameters. """
|
||||
url = reverse('rescore_entrance_exam', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
'all_students': True,
|
||||
})
|
||||
@@ -3334,7 +3481,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
def test_rescore_entrance_exam_with_invalid_exam(self):
|
||||
""" Test re-scoring of entrance exam with invalid exam. """
|
||||
url = reverse('rescore_entrance_exam', kwargs={'course_id': unicode(self.course_with_invalid_ee.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
@@ -3343,13 +3490,13 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test list task history for entrance exam AND student. """
|
||||
# create a re-score entrance exam task
|
||||
url = reverse('rescore_entrance_exam', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
url = reverse('list_entrance_exam_instructor_tasks', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -3362,7 +3509,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
def test_list_entrance_exam_instructor_tasks_all_student(self):
|
||||
""" Test list task history for entrance exam AND all student. """
|
||||
url = reverse('list_entrance_exam_instructor_tasks', kwargs={'course_id': unicode(self.course.id)})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# check response
|
||||
@@ -3373,7 +3520,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
|
||||
""" Test list task history for entrance exam failure if course has invalid exam. """
|
||||
url = reverse('list_entrance_exam_instructor_tasks',
|
||||
kwargs={'course_id': unicode(self.course_with_invalid_ee.id)})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
@@ -3589,7 +3736,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
|
||||
mock_factory = MockCompletionInfo()
|
||||
with patch('instructor.views.instructor_task_helpers.get_task_completion_info') as mock_completion_info:
|
||||
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# check response
|
||||
@@ -3608,7 +3755,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
|
||||
mock_factory = MockCompletionInfo()
|
||||
with patch('instructor.views.instructor_task_helpers.get_task_completion_info') as mock_completion_info:
|
||||
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# check response
|
||||
@@ -3627,7 +3774,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
|
||||
mock_factory = MockCompletionInfo()
|
||||
with patch('instructor.views.instructor_task_helpers.get_task_completion_info') as mock_completion_info:
|
||||
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_location_str': self.problem_urlname,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -3648,7 +3795,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
|
||||
mock_factory = MockCompletionInfo()
|
||||
with patch('instructor.views.instructor_task_helpers.get_task_completion_info') as mock_completion_info:
|
||||
mock_completion_info.side_effect = mock_factory.mock_get_task_completion_info
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'problem_location_str': self.problem_urlname,
|
||||
'unique_student_identifier': self.student.email,
|
||||
})
|
||||
@@ -3709,7 +3856,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
|
||||
url = reverse('list_email_content', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
with patch('instructor.views.api.CourseEmail.objects.get') as mock_email_info:
|
||||
mock_email_info.side_effect = self.get_matching_mock_email
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
return response
|
||||
|
||||
@@ -3760,7 +3907,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
|
||||
invalid_task.make_invalid_input()
|
||||
task_history_request.return_value = [invalid_task]
|
||||
url = reverse('list_email_content', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertTrue(task_history_request.called)
|
||||
@@ -3786,7 +3933,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
|
||||
url = reverse('list_email_content', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
with patch('instructor.views.api.CourseEmail.objects.get') as mock_email_info:
|
||||
mock_email_info.return_value = email
|
||||
response = self.client.get(url, {})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertTrue(task_history_request.called)
|
||||
@@ -3937,7 +4084,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
def test_change_due_date(self):
|
||||
url = reverse('change_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week1.location.to_deprecated_string(),
|
||||
'due_datetime': '12/30/2013 00:00'
|
||||
@@ -3948,7 +4095,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
def test_change_to_invalid_due_date(self):
|
||||
url = reverse('change_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week1.location.to_deprecated_string(),
|
||||
'due_datetime': '01/01/2009 00:00'
|
||||
@@ -3961,7 +4108,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
def test_change_nonexistent_due_date(self):
|
||||
url = reverse('change_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week3.location.to_deprecated_string(),
|
||||
'due_datetime': '12/30/2013 00:00'
|
||||
@@ -3975,7 +4122,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
def test_reset_date(self):
|
||||
self.test_change_due_date()
|
||||
url = reverse('reset_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week1.location.to_deprecated_string(),
|
||||
})
|
||||
@@ -3987,7 +4134,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
def test_reset_nonexistent_extension(self):
|
||||
url = reverse('reset_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week1.location.to_deprecated_string(),
|
||||
})
|
||||
@@ -3997,7 +4144,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.test_change_due_date()
|
||||
url = reverse('show_unit_extensions',
|
||||
kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {'url': self.week1.location.to_deprecated_string()})
|
||||
response = self.client.post(url, {'url': self.week1.location.to_deprecated_string()})
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
self.assertEqual(json.loads(response.content), {
|
||||
u'data': [{u'Extended Due Date': u'2013-12-30 00:00',
|
||||
@@ -4011,7 +4158,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.test_change_due_date()
|
||||
url = reverse('show_student_extensions',
|
||||
kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {'student': self.user1.username})
|
||||
response = self.client.post(url, {'student': self.user1.username})
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
self.assertEqual(json.loads(response.content), {
|
||||
u'data': [{u'Extended Due Date': u'2013-12-30 00:00',
|
||||
@@ -4105,7 +4252,7 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
|
||||
"""
|
||||
|
||||
url = reverse('change_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week1.location.to_deprecated_string(),
|
||||
'due_datetime': '12/30/2013 00:00'
|
||||
@@ -4118,7 +4265,7 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
|
||||
self.week1 = self.store.update_item(self.week1, self.user1.id)
|
||||
# Now, week1's normal due date is deleted but the extension still exists.
|
||||
url = reverse('reset_due_date', kwargs={'course_id': self.course.id.to_deprecated_string()})
|
||||
response = self.client.get(url, {
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': self.week1.location.to_deprecated_string(),
|
||||
})
|
||||
@@ -4166,14 +4313,14 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
|
||||
for __ in xrange(certificate_count):
|
||||
self.generate_certificate(course_id=self.course.id, mode='honor', status=CertificateStatuses.generating)
|
||||
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('certificates', res_json)
|
||||
self.assertEqual(len(res_json['certificates']), 0)
|
||||
|
||||
# Certificates with status 'downloadable' should be in response.
|
||||
self.generate_certificate(course_id=self.course.id, mode='honor', status=CertificateStatuses.downloadable)
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('certificates', res_json)
|
||||
self.assertEqual(len(res_json['certificates']), 1)
|
||||
@@ -4188,7 +4335,7 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
|
||||
for __ in xrange(certificate_count):
|
||||
self.generate_certificate(course_id=self.course.id, mode='honor', status=CertificateStatuses.downloadable)
|
||||
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('certificates', res_json)
|
||||
self.assertEqual(len(res_json['certificates']), 1)
|
||||
@@ -4207,7 +4354,7 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
|
||||
status=CertificateStatuses.downloadable
|
||||
)
|
||||
|
||||
response = self.client.get(url)
|
||||
response = self.client.post(url)
|
||||
res_json = json.loads(response.content)
|
||||
self.assertIn('certificates', res_json)
|
||||
|
||||
@@ -4224,14 +4371,13 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
|
||||
Test for certificate csv features.
|
||||
"""
|
||||
url = reverse('get_issued_certificates', kwargs={'course_id': unicode(self.course.id)})
|
||||
url += '?csv=true'
|
||||
# firstly generating downloadable certificates with 'honor' mode
|
||||
certificate_count = 3
|
||||
for __ in xrange(certificate_count):
|
||||
self.generate_certificate(course_id=self.course.id, mode='honor', status=CertificateStatuses.downloadable)
|
||||
|
||||
current_date = datetime.date.today().strftime("%B %d, %Y")
|
||||
response = self.client.get(url)
|
||||
response = self.client.get(url, {'csv': 'true'})
|
||||
self.assertEqual(response['Content-Type'], 'text/csv')
|
||||
self.assertEqual(response['Content-Disposition'], 'attachment; filename={0}'.format('issued_certificates.csv'))
|
||||
self.assertEqual(
|
||||
@@ -4680,7 +4826,7 @@ class TestCourseRegistrationCodes(SharedModuleStoreTestCase):
|
||||
)
|
||||
coupon.save()
|
||||
|
||||
response = self.client.get(get_coupon_code_url)
|
||||
response = self.client.post(get_coupon_code_url)
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
# filter all the coupons
|
||||
for coupon in Coupon.objects.all():
|
||||
@@ -4721,7 +4867,7 @@ class TestBulkCohorting(SharedModuleStoreTestCase):
|
||||
self.tempdir = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, self.tempdir)
|
||||
|
||||
def call_add_users_to_cohorts(self, csv_data, suffix='.csv', method='POST'):
|
||||
def call_add_users_to_cohorts(self, csv_data, suffix='.csv'):
|
||||
"""
|
||||
Call `add_users_to_cohorts` with a file generated from `csv_data`.
|
||||
"""
|
||||
@@ -4731,10 +4877,7 @@ class TestBulkCohorting(SharedModuleStoreTestCase):
|
||||
file_pointer.write(csv_data.encode('utf-8'))
|
||||
with open(file_name, 'r') as file_pointer:
|
||||
url = reverse('add_users_to_cohorts', kwargs={'course_id': unicode(self.course.id)})
|
||||
if method == 'POST':
|
||||
return self.client.post(url, {'uploaded-file': file_pointer})
|
||||
elif method == 'GET':
|
||||
return self.client.get(url, {'uploaded-file': file_pointer})
|
||||
return self.client.post(url, {'uploaded-file': file_pointer})
|
||||
|
||||
def expect_error_on_file_content(self, file_content, error, file_suffix='.csv'):
|
||||
"""
|
||||
@@ -4803,14 +4946,6 @@ class TestBulkCohorting(SharedModuleStoreTestCase):
|
||||
response = self.call_add_users_to_cohorts('')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_post_only(self):
|
||||
"""
|
||||
Verify that we can't call the view when we aren't using POST.
|
||||
"""
|
||||
self.client.login(username=self.staff_user.username, password='test')
|
||||
response = self.call_add_users_to_cohorts('', method='GET')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
|
||||
@patch('instructor.views.api.instructor_task.api.submit_cohort_students')
|
||||
@patch('instructor.views.api.store_uploaded_file')
|
||||
def test_success_username(self, mock_store_upload, mock_cohort_task):
|
||||
|
||||
@@ -140,51 +140,14 @@ def common_exceptions_400(func):
|
||||
return wrapped
|
||||
|
||||
|
||||
def require_query_params(*args, **kwargs):
|
||||
"""
|
||||
Checks for required paremters or renders a 400 error.
|
||||
(decorator with arguments)
|
||||
|
||||
`args` is a *list of required GET parameter names.
|
||||
`kwargs` is a **dict of required GET parameter names
|
||||
to string explanations of the parameter
|
||||
"""
|
||||
required_params = []
|
||||
required_params += [(arg, None) for arg in args]
|
||||
required_params += [(key, kwargs[key]) for key in kwargs]
|
||||
# required_params = e.g. [('action', 'enroll or unenroll'), ['emails', None]]
|
||||
|
||||
def decorator(func): # pylint: disable=missing-docstring
|
||||
def wrapped(*args, **kwargs): # pylint: disable=missing-docstring
|
||||
request = args[0]
|
||||
|
||||
error_response_data = {
|
||||
'error': 'Missing required query parameter(s)',
|
||||
'parameters': [],
|
||||
'info': {},
|
||||
}
|
||||
|
||||
for (param, extra) in required_params:
|
||||
default = object()
|
||||
if request.GET.get(param, default) == default:
|
||||
error_response_data['parameters'].append(param)
|
||||
error_response_data['info'][param] = extra
|
||||
|
||||
if len(error_response_data['parameters']) > 0:
|
||||
return JsonResponse(error_response_data, status=400)
|
||||
else:
|
||||
return func(*args, **kwargs)
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
|
||||
def require_post_params(*args, **kwargs):
|
||||
"""
|
||||
Checks for required parameters or renders a 400 error.
|
||||
(decorator with arguments)
|
||||
|
||||
Functions like 'require_query_params', but checks for
|
||||
POST parameters rather than GET parameters.
|
||||
`args` is a *list of required POST parameter names.
|
||||
`kwargs` is a **dict of required POST parameter names
|
||||
to string explanations of the parameter
|
||||
"""
|
||||
required_params = []
|
||||
required_params += [(arg, None) for arg in args]
|
||||
@@ -314,6 +277,7 @@ NAME_INDEX = 2
|
||||
COUNTRY_INDEX = 3
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -604,6 +568,7 @@ def create_and_enroll_user(email, username, name, country, password, course_id,
|
||||
return errors
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -768,6 +733,7 @@ def students_update_enrollment(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
@@ -848,11 +814,12 @@ def bulk_beta_modify_access(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
@common_exceptions_400
|
||||
@require_query_params(
|
||||
@require_post_params(
|
||||
unique_student_identifier="email or username of user to change access",
|
||||
rolename="'instructor', 'staff', 'beta', or 'ccx_coach'",
|
||||
action="'allow' or 'revoke'"
|
||||
@@ -874,10 +841,10 @@ def modify_access(request, course_id):
|
||||
request.user, 'instructor', course_id, depth=None
|
||||
)
|
||||
try:
|
||||
user = get_student_from_identifier(request.GET.get('unique_student_identifier'))
|
||||
user = get_student_from_identifier(request.POST.get('unique_student_identifier'))
|
||||
except User.DoesNotExist:
|
||||
response_payload = {
|
||||
'unique_student_identifier': request.GET.get('unique_student_identifier'),
|
||||
'unique_student_identifier': request.POST.get('unique_student_identifier'),
|
||||
'userDoesNotExist': True,
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
@@ -892,8 +859,8 @@ def modify_access(request, course_id):
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
rolename = request.GET.get('rolename')
|
||||
action = request.GET.get('action')
|
||||
rolename = request.POST.get('rolename')
|
||||
action = request.POST.get('action')
|
||||
|
||||
if rolename not in ROLES:
|
||||
error = strip_tags("unknown rolename '{}'".format(rolename))
|
||||
@@ -928,10 +895,11 @@ def modify_access(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
@require_query_params(rolename="'instructor', 'staff', or 'beta'")
|
||||
@require_post_params(rolename="'instructor', 'staff', or 'beta'")
|
||||
def list_course_role_members(request, course_id):
|
||||
"""
|
||||
List instructors and staff.
|
||||
@@ -956,7 +924,7 @@ def list_course_role_members(request, course_id):
|
||||
request.user, 'instructor', course_id, depth=None
|
||||
)
|
||||
|
||||
rolename = request.GET.get('rolename')
|
||||
rolename = request.POST.get('rolename')
|
||||
|
||||
if rolename not in ROLES:
|
||||
return HttpResponseBadRequest()
|
||||
@@ -980,6 +948,7 @@ def list_course_role_members(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -996,7 +965,7 @@ def get_problem_responses(request, course_id):
|
||||
Responds with BadRequest if problem location is faulty.
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
problem_location = request.GET.get('problem_location', '')
|
||||
problem_location = request.POST.get('problem_location', '')
|
||||
|
||||
try:
|
||||
problem_key = UsageKey.from_string(problem_location)
|
||||
@@ -1025,6 +994,7 @@ def get_problem_responses(request, course_id):
|
||||
return JsonResponse({"status": already_running_status})
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1223,6 +1193,7 @@ def get_issued_certificates(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1315,6 +1286,7 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=red
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1422,6 +1394,7 @@ def get_coupon_codes(request, course_id): # pylint: disable=unused-argument
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1446,6 +1419,7 @@ def get_enrollment_report(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1471,6 +1445,7 @@ def get_exec_summary_report(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1495,6 +1470,7 @@ def get_course_survey_results(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -1901,11 +1877,12 @@ def get_anon_ids(request, course_id): # pylint: disable=unused-argument
|
||||
return csv_response(course_id.to_deprecated_string().replace('/', '-') + '-anon-ids.csv', header, rows)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@common_exceptions_400
|
||||
@require_level('staff')
|
||||
@require_query_params(
|
||||
@require_post_params(
|
||||
unique_student_identifier="email or username of student for whom to get progress url"
|
||||
)
|
||||
def get_student_progress_url(request, course_id):
|
||||
@@ -1913,13 +1890,13 @@ def get_student_progress_url(request, course_id):
|
||||
Get the progress url of a student.
|
||||
Limited to staff access.
|
||||
|
||||
Takes query paremeter unique_student_identifier and if the student exists
|
||||
Takes query parameter unique_student_identifier and if the student exists
|
||||
returns e.g. {
|
||||
'progress_url': '/../...'
|
||||
}
|
||||
"""
|
||||
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
user = get_student_from_identifier(request.GET.get('unique_student_identifier'))
|
||||
user = get_student_from_identifier(request.POST.get('unique_student_identifier'))
|
||||
|
||||
progress_url = reverse('student_progress', kwargs={'course_id': course_id.to_deprecated_string(), 'student_id': user.id})
|
||||
|
||||
@@ -1931,10 +1908,11 @@ def get_student_progress_url(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params(
|
||||
@require_post_params(
|
||||
problem_to_reset="problem urlname to reset"
|
||||
)
|
||||
@common_exceptions_400
|
||||
@@ -1961,13 +1939,13 @@ def reset_student_attempts(request, course_id):
|
||||
request.user, 'staff', course_id, depth=None
|
||||
)
|
||||
|
||||
problem_to_reset = strip_if_string(request.GET.get('problem_to_reset'))
|
||||
student_identifier = request.GET.get('unique_student_identifier', None)
|
||||
problem_to_reset = strip_if_string(request.POST.get('problem_to_reset'))
|
||||
student_identifier = request.POST.get('unique_student_identifier', None)
|
||||
student = None
|
||||
if student_identifier is not None:
|
||||
student = get_student_from_identifier(student_identifier)
|
||||
all_students = request.GET.get('all_students', False) in ['true', 'True', True]
|
||||
delete_module = request.GET.get('delete_module', False) in ['true', 'True', True]
|
||||
all_students = request.POST.get('all_students', False) in ['true', 'True', True]
|
||||
delete_module = request.POST.get('delete_module', False) in ['true', 'True', True]
|
||||
|
||||
# parameter combinations
|
||||
if all_students and student:
|
||||
@@ -2019,6 +1997,7 @@ def reset_student_attempts(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2049,12 +2028,12 @@ def reset_student_attempts_for_entrance_exam(request, course_id): # pylint: dis
|
||||
_("Course has no entrance exam section.")
|
||||
)
|
||||
|
||||
student_identifier = request.GET.get('unique_student_identifier', None)
|
||||
student_identifier = request.POST.get('unique_student_identifier', None)
|
||||
student = None
|
||||
if student_identifier is not None:
|
||||
student = get_student_from_identifier(student_identifier)
|
||||
all_students = request.GET.get('all_students', False) in ['true', 'True', True]
|
||||
delete_module = request.GET.get('delete_module', False) in ['true', 'True', True]
|
||||
all_students = request.POST.get('all_students', False) in ['true', 'True', True]
|
||||
delete_module = request.POST.get('delete_module', False) in ['true', 'True', True]
|
||||
|
||||
# parameter combinations
|
||||
if all_students and student:
|
||||
@@ -2085,10 +2064,11 @@ def reset_student_attempts_for_entrance_exam(request, course_id): # pylint: dis
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
@require_query_params(problem_to_reset="problem urlname to reset")
|
||||
@require_post_params(problem_to_reset="problem urlname to reset")
|
||||
@common_exceptions_400
|
||||
def rescore_problem(request, course_id):
|
||||
"""
|
||||
@@ -2103,13 +2083,13 @@ def rescore_problem(request, course_id):
|
||||
all_students and unique_student_identifier cannot both be present.
|
||||
"""
|
||||
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
problem_to_reset = strip_if_string(request.GET.get('problem_to_reset'))
|
||||
student_identifier = request.GET.get('unique_student_identifier', None)
|
||||
problem_to_reset = strip_if_string(request.POST.get('problem_to_reset'))
|
||||
student_identifier = request.POST.get('unique_student_identifier', None)
|
||||
student = None
|
||||
if student_identifier is not None:
|
||||
student = get_student_from_identifier(student_identifier)
|
||||
|
||||
all_students = request.GET.get('all_students') in ['true', 'True', True]
|
||||
all_students = request.POST.get('all_students') in ['true', 'True', True]
|
||||
|
||||
if not (problem_to_reset and (all_students or student)):
|
||||
return HttpResponseBadRequest("Missing query parameters.")
|
||||
@@ -2141,6 +2121,7 @@ def rescore_problem(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
@@ -2161,12 +2142,12 @@ def rescore_entrance_exam(request, course_id):
|
||||
request.user, 'staff', course_id, depth=None
|
||||
)
|
||||
|
||||
student_identifier = request.GET.get('unique_student_identifier', None)
|
||||
student_identifier = request.POST.get('unique_student_identifier', None)
|
||||
student = None
|
||||
if student_identifier is not None:
|
||||
student = get_student_from_identifier(student_identifier)
|
||||
|
||||
all_students = request.GET.get('all_students') in ['true', 'True', True]
|
||||
all_students = request.POST.get('all_students') in ['true', 'True', True]
|
||||
|
||||
if not course.entrance_exam_id:
|
||||
return HttpResponseBadRequest(
|
||||
@@ -2193,6 +2174,7 @@ def rescore_entrance_exam(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2211,6 +2193,7 @@ def list_background_email_tasks(request, course_id): # pylint: disable=unused-a
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2229,6 +2212,7 @@ def list_email_content(request, course_id): # pylint: disable=unused-argument
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2243,8 +2227,8 @@ def list_instructor_tasks(request, course_id):
|
||||
history for problem AND student (intersection)
|
||||
"""
|
||||
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
problem_location_str = strip_if_string(request.GET.get('problem_location_str', False))
|
||||
student = request.GET.get('unique_student_identifier', None)
|
||||
problem_location_str = strip_if_string(request.POST.get('problem_location_str', False))
|
||||
student = request.POST.get('unique_student_identifier', None)
|
||||
if student is not None:
|
||||
student = get_student_from_identifier(student)
|
||||
|
||||
@@ -2274,6 +2258,7 @@ def list_instructor_tasks(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2287,7 +2272,7 @@ def list_entrance_exam_instructor_tasks(request, course_id): # pylint: disable=
|
||||
"""
|
||||
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
course = get_course_by_id(course_id)
|
||||
student = request.GET.get('unique_student_identifier', None)
|
||||
student = request.POST.get('unique_student_identifier', None)
|
||||
if student is not None:
|
||||
student = get_student_from_identifier(student)
|
||||
|
||||
@@ -2308,6 +2293,7 @@ def list_entrance_exam_instructor_tasks(request, course_id): # pylint: disable=
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2327,6 +2313,7 @@ def list_report_downloads(_request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2348,6 +2335,7 @@ def list_financial_report_downloads(_request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2373,6 +2361,7 @@ def export_ora2_data(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2394,6 +2383,7 @@ def calculate_grades_csv(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2420,10 +2410,11 @@ def problem_grade_report(request, course_id):
|
||||
})
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params('rolename')
|
||||
@require_post_params('rolename')
|
||||
def list_forum_members(request, course_id):
|
||||
"""
|
||||
Lists forum members of a certain rolename.
|
||||
@@ -2442,7 +2433,7 @@ def list_forum_members(request, course_id):
|
||||
request.user, course_id, FORUM_ROLE_ADMINISTRATOR
|
||||
)
|
||||
|
||||
rolename = request.GET.get('rolename')
|
||||
rolename = request.POST.get('rolename')
|
||||
|
||||
# default roles require either (staff & forum admin) or (instructor)
|
||||
if not (has_forum_admin or has_instructor_access):
|
||||
@@ -2483,6 +2474,7 @@ def list_forum_members(request, course_id):
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@@ -2539,10 +2531,11 @@ def send_email(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params(
|
||||
@require_post_params(
|
||||
unique_student_identifier="email or username of user to change access",
|
||||
rolename="the forum role",
|
||||
action="'allow' or 'revoke'",
|
||||
@@ -2569,9 +2562,9 @@ def update_forum_role_membership(request, course_id):
|
||||
request.user, course_id, FORUM_ROLE_ADMINISTRATOR
|
||||
)
|
||||
|
||||
unique_student_identifier = request.GET.get('unique_student_identifier')
|
||||
rolename = request.GET.get('rolename')
|
||||
action = request.GET.get('action')
|
||||
unique_student_identifier = request.POST.get('unique_student_identifier')
|
||||
rolename = request.POST.get('rolename')
|
||||
action = request.POST.get('action')
|
||||
|
||||
# default roles require either (staff & forum admin) or (instructor)
|
||||
if not (has_forum_admin or has_instructor_access):
|
||||
@@ -2629,18 +2622,19 @@ def _display_unit(unit):
|
||||
|
||||
|
||||
@handle_dashboard_error
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params('student', 'url', 'due_datetime')
|
||||
@require_post_params('student', 'url', 'due_datetime')
|
||||
def change_due_date(request, course_id):
|
||||
"""
|
||||
Grants a due date extension to a student for a particular unit.
|
||||
"""
|
||||
course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id))
|
||||
student = require_student_from_identifier(request.GET.get('student'))
|
||||
unit = find_unit(course, request.GET.get('url'))
|
||||
due_date = parse_datetime(request.GET.get('due_datetime'))
|
||||
student = require_student_from_identifier(request.POST.get('student'))
|
||||
unit = find_unit(course, request.POST.get('url'))
|
||||
due_date = parse_datetime(request.POST.get('due_datetime'))
|
||||
set_due_date_extension(course, unit, student, due_date)
|
||||
|
||||
return JsonResponse(_(
|
||||
@@ -2650,17 +2644,18 @@ def change_due_date(request, course_id):
|
||||
|
||||
|
||||
@handle_dashboard_error
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params('student', 'url')
|
||||
@require_post_params('student', 'url')
|
||||
def reset_due_date(request, course_id):
|
||||
"""
|
||||
Rescinds a due date extension for a student on a particular unit.
|
||||
"""
|
||||
course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id))
|
||||
student = require_student_from_identifier(request.GET.get('student'))
|
||||
unit = find_unit(course, request.GET.get('url'))
|
||||
student = require_student_from_identifier(request.POST.get('student'))
|
||||
unit = find_unit(course, request.POST.get('url'))
|
||||
set_due_date_extension(course, unit, student, None)
|
||||
if not getattr(unit, "due", None):
|
||||
# It's possible the normal due date was deleted after an extension was granted:
|
||||
@@ -2676,30 +2671,32 @@ def reset_due_date(request, course_id):
|
||||
|
||||
|
||||
@handle_dashboard_error
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params('url')
|
||||
@require_post_params('url')
|
||||
def show_unit_extensions(request, course_id):
|
||||
"""
|
||||
Shows all of the students which have due date extensions for the given unit.
|
||||
"""
|
||||
course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id))
|
||||
unit = find_unit(course, request.GET.get('url'))
|
||||
unit = find_unit(course, request.POST.get('url'))
|
||||
return JsonResponse(dump_module_extensions(course, unit))
|
||||
|
||||
|
||||
@handle_dashboard_error
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params('student')
|
||||
@require_post_params('student')
|
||||
def show_student_extensions(request, course_id):
|
||||
"""
|
||||
Shows all of the due date extensions granted to a particular student in a
|
||||
particular course.
|
||||
"""
|
||||
student = require_student_from_identifier(request.GET.get('student'))
|
||||
student = require_student_from_identifier(request.POST.get('student'))
|
||||
course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id))
|
||||
return JsonResponse(dump_student_extensions(course, student))
|
||||
|
||||
@@ -3076,7 +3073,6 @@ def generate_certificate_exceptions(request, course_id, generate_for=None):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_global_staff
|
||||
@require_POST
|
||||
|
||||
@@ -110,6 +110,7 @@ class DataDownload
|
||||
url = @$list_proctored_exam_results_csv_btn.data 'endpoint'
|
||||
# display html from proctored exam results config endpoint
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: (std_ajax_err) =>
|
||||
@@ -129,6 +130,7 @@ class DataDownload
|
||||
url = @$survey_results_csv_btn.data 'endpoint'
|
||||
# display html from survey results config endpoint
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: (std_ajax_err) =>
|
||||
@@ -153,6 +155,7 @@ class DataDownload
|
||||
url += '/csv'
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: (std_ajax_err) =>
|
||||
@@ -171,6 +174,7 @@ class DataDownload
|
||||
|
||||
# fetch user list
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: (std_ajax_err) =>
|
||||
@@ -199,6 +203,7 @@ class DataDownload
|
||||
|
||||
url = @$list_problem_responses_csv_btn.data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
data:
|
||||
@@ -215,6 +220,7 @@ class DataDownload
|
||||
|
||||
url = @$list_may_enroll_csv_btn.data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: (std_ajax_err) =>
|
||||
@@ -228,6 +234,7 @@ class DataDownload
|
||||
url = @$grade_config_btn.data 'endpoint'
|
||||
# display html from grading config endpoint
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: (std_ajax_err) =>
|
||||
@@ -244,6 +251,7 @@ class DataDownload
|
||||
@clear_display()
|
||||
url = $(e.target).data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
error: std_ajax_err =>
|
||||
|
||||
@@ -45,6 +45,7 @@ class Extensions
|
||||
due_datetime: @$due_datetime_input.val()
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$change_due_date.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -60,6 +61,7 @@ class Extensions
|
||||
url: @$url_input.val()
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$reset_due_date.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -75,6 +77,7 @@ class Extensions
|
||||
send_data =
|
||||
url: @$url_input.val()
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
data: send_data
|
||||
@@ -90,6 +93,7 @@ class Extensions
|
||||
send_data =
|
||||
student: @$student_input.val()
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
data: send_data
|
||||
|
||||
@@ -137,6 +137,7 @@ class AuthListWidget extends MemberListWidget
|
||||
# `cb` is called with cb(error, member_list)
|
||||
get_member_list: (cb) ->
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @list_endpoint
|
||||
data: rolename: @rolename
|
||||
@@ -151,6 +152,7 @@ class AuthListWidget extends MemberListWidget
|
||||
# `cb` is called with cb(error, data)
|
||||
modify_member_access: (unique_student_identifier, action, cb) ->
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @modify_endpoint
|
||||
data:
|
||||
@@ -645,6 +647,7 @@ class AuthList
|
||||
# the endpoint comes from data-endpoint of the table
|
||||
$.ajax
|
||||
dataType: 'json'
|
||||
type: 'POST'
|
||||
url: @$display_table.data 'endpoint'
|
||||
data: rolename: @rolename
|
||||
success: load_auth_list
|
||||
@@ -664,6 +667,7 @@ class AuthList
|
||||
access_change: (email, action, cb) ->
|
||||
$.ajax
|
||||
dataType: 'json'
|
||||
type: 'POST'
|
||||
url: @$add_section.data 'endpoint'
|
||||
data:
|
||||
email: email
|
||||
|
||||
@@ -104,6 +104,7 @@ class @SendEmail
|
||||
@$btn_task_history_email.click =>
|
||||
url = @$btn_task_history_email.data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: url
|
||||
success: (data) =>
|
||||
@@ -120,6 +121,7 @@ class @SendEmail
|
||||
@$btn_task_history_email_content.click =>
|
||||
url = @$btn_task_history_email_content.data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url : url
|
||||
success: (data) =>
|
||||
|
||||
@@ -76,6 +76,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({student_id: unique_student_identifier})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$progress_link.data 'endpoint'
|
||||
data: unique_student_identifier: unique_student_identifier
|
||||
@@ -101,6 +102,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({problem_id: problem_to_reset, student_id: unique_student_identifier})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_reset_attempts_single.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -127,6 +129,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({student_id: unique_student_identifier, problem_id: problem_to_reset})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_delete_state_single.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -153,6 +156,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({student_id: unique_student_identifier, problem_id: problem_to_reset})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_rescore_problem_single.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -174,6 +178,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({student_id: unique_student_identifier, problem_id: problem_to_reset})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_task_history_single.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -191,6 +196,7 @@ class @StudentAdmin
|
||||
delete_module: false
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_reset_entrance_exam_attempts.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -212,6 +218,7 @@ class @StudentAdmin
|
||||
unique_student_identifier: unique_student_identifier
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_rescore_entrance_exam.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -256,6 +263,7 @@ class @StudentAdmin
|
||||
delete_module: true
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_delete_entrance_exam_state.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -277,6 +285,7 @@ class @StudentAdmin
|
||||
unique_student_identifier: unique_student_identifier
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_entrance_exam_task_history.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -304,6 +313,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({problem_id: problem_to_reset})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_reset_attempts_all.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -330,6 +340,7 @@ class @StudentAdmin
|
||||
full_error_message = _.template(error_message)({problem_id: problem_to_reset})
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_rescore_problem_all.data 'endpoint'
|
||||
data: send_data
|
||||
@@ -348,6 +359,7 @@ class @StudentAdmin
|
||||
return @$request_response_error_all.text gettext("Please enter a problem location.")
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_task_history_all.data 'endpoint'
|
||||
data: send_data
|
||||
|
||||
@@ -336,6 +336,7 @@ class @PendingInstructorTasks
|
||||
reload_running_tasks_list: =>
|
||||
list_endpoint = @$table_running_tasks.data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: list_endpoint
|
||||
success: (data) =>
|
||||
@@ -392,6 +393,7 @@ class ReportDownloads
|
||||
reload_report_downloads: ->
|
||||
endpoint = @$report_downloads_table.data 'endpoint'
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: endpoint
|
||||
success: (data) =>
|
||||
|
||||
@@ -45,6 +45,7 @@ var edx = edx || {};
|
||||
$('input[name="user-enrollment-report"]').click(function(){
|
||||
var url = $(this).data('endpoint');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: "json",
|
||||
url: url,
|
||||
success: function (data) {
|
||||
@@ -64,6 +65,7 @@ var edx = edx || {};
|
||||
$('input[name="exec-summary-report"]').click(function(){
|
||||
var url = $(this).data('endpoint');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: "json",
|
||||
url: url,
|
||||
success: function (data) {
|
||||
|
||||
@@ -36,15 +36,15 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
// Spy on AJAX requests
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
studentadmin.$field_entrance_exam_student_select_grade.val(unique_student_identifier)
|
||||
studentadmin.$field_entrance_exam_student_select_grade.val(unique_student_identifier);
|
||||
studentadmin.$btn_reset_entrance_exam_attempts.click();
|
||||
// Verify that the client contacts the server to start instructor task
|
||||
var params = $.param({
|
||||
unique_student_identifier: unique_student_identifier,
|
||||
delete_module: false
|
||||
});
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate a success response from the server
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
@@ -63,8 +63,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
unique_student_identifier: unique_student_identifier,
|
||||
delete_module: false
|
||||
});
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate an error response from the server
|
||||
AjaxHelpers.respondWithError(requests, 400,{});
|
||||
@@ -96,8 +96,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
var params = $.param({
|
||||
unique_student_identifier: unique_student_identifier
|
||||
});
|
||||
var url = dashboard_api_url + '/rescore_entrance_exam?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/rescore_entrance_exam';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate a success response from the server
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
@@ -115,8 +115,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
var params = $.param({
|
||||
unique_student_identifier: unique_student_identifier
|
||||
});
|
||||
var url = dashboard_api_url + '/rescore_entrance_exam?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/rescore_entrance_exam';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate an error response from the server
|
||||
AjaxHelpers.respondWithError(requests, 400,{});
|
||||
@@ -195,8 +195,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
unique_student_identifier: unique_student_identifier,
|
||||
delete_module: true
|
||||
});
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate a success response from the server
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
@@ -215,8 +215,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
unique_student_identifier: unique_student_identifier,
|
||||
delete_module: true
|
||||
});
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/reset_student_attempts_for_entrance_exam';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate an error response from the server
|
||||
AjaxHelpers.respondWithError(requests, 400,{});
|
||||
@@ -248,8 +248,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
var params = $.param({
|
||||
unique_student_identifier: unique_student_identifier
|
||||
});
|
||||
var url = dashboard_api_url + '/list_entrance_exam_instructor_tasks?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/list_entrance_exam_instructor_tasks';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate a success response from the server
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
@@ -279,8 +279,8 @@ define(['jquery', 'coffee/src/instructor_dashboard/student_admin', 'common/js/sp
|
||||
var params = $.param({
|
||||
unique_student_identifier: unique_student_identifier
|
||||
});
|
||||
var url = dashboard_api_url + '/list_entrance_exam_instructor_tasks?' + params;
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', url);
|
||||
var url = dashboard_api_url + '/list_entrance_exam_instructor_tasks';
|
||||
AjaxHelpers.expectPostRequest(requests, url, params);
|
||||
|
||||
// Simulate an error response from the server
|
||||
AjaxHelpers.respondWithError(requests, 400,{});
|
||||
|
||||
@@ -91,7 +91,7 @@ define([
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.reset(locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('GET');
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
'problem_to_reset': location,
|
||||
'unique_student_identifier': 'userman',
|
||||
@@ -110,7 +110,7 @@ define([
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.sdelete(locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('GET');
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
'problem_to_reset': location,
|
||||
'unique_student_identifier': 'userman',
|
||||
@@ -130,7 +130,7 @@ define([
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.rescore(locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('GET');
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
'problem_to_reset': location,
|
||||
'unique_student_identifier': 'userman',
|
||||
|
||||
@@ -31,7 +31,7 @@ var StaffDebug = (function (){
|
||||
'delete_module': action.delete_module
|
||||
};
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
type: "POST",
|
||||
url: get_url(action.method),
|
||||
data: pdata,
|
||||
success: function(data){
|
||||
|
||||
Reference in New Issue
Block a user