Commit d54f79f5 by Robert Raposa

Switch dashboard from GET to POST.

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