replaced unittest assertions pytest assertions (#26544)
This commit is contained in:
@@ -45,37 +45,37 @@ class TestStudentModuleHistoryBackends(TestCase):
|
||||
def test_get_history_true_true(self):
|
||||
student_module = StudentModule.objects.all()
|
||||
history = BaseStudentModuleHistory.get_history(student_module)
|
||||
self.assertEqual(len(history), 6)
|
||||
self.assertEqual({'type': 'csmhe', 'order': 3}, json.loads(history[0].state))
|
||||
self.assertEqual({'type': 'csmhe', 'order': 2}, json.loads(history[1].state))
|
||||
self.assertEqual({'type': 'csmhe', 'order': 1}, json.loads(history[2].state))
|
||||
self.assertEqual({'type': 'csmh', 'order': 3}, json.loads(history[3].state))
|
||||
self.assertEqual({'type': 'csmh', 'order': 2}, json.loads(history[4].state))
|
||||
self.assertEqual({'type': 'csmh', 'order': 1}, json.loads(history[5].state))
|
||||
assert len(history) == 6
|
||||
assert {'type': 'csmhe', 'order': 3} == json.loads(history[0].state)
|
||||
assert {'type': 'csmhe', 'order': 2} == json.loads(history[1].state)
|
||||
assert {'type': 'csmhe', 'order': 1} == json.loads(history[2].state)
|
||||
assert {'type': 'csmh', 'order': 3} == json.loads(history[3].state)
|
||||
assert {'type': 'csmh', 'order': 2} == json.loads(history[4].state)
|
||||
assert {'type': 'csmh', 'order': 1} == json.loads(history[5].state)
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_CSMH_EXTENDED": True})
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_READING_FROM_MULTIPLE_HISTORY_TABLES": False})
|
||||
def test_get_history_true_false(self):
|
||||
student_module = StudentModule.objects.all()
|
||||
history = BaseStudentModuleHistory.get_history(student_module)
|
||||
self.assertEqual(len(history), 3)
|
||||
self.assertEqual({'type': 'csmhe', 'order': 3}, json.loads(history[0].state))
|
||||
self.assertEqual({'type': 'csmhe', 'order': 2}, json.loads(history[1].state))
|
||||
self.assertEqual({'type': 'csmhe', 'order': 1}, json.loads(history[2].state))
|
||||
assert len(history) == 3
|
||||
assert {'type': 'csmhe', 'order': 3} == json.loads(history[0].state)
|
||||
assert {'type': 'csmhe', 'order': 2} == json.loads(history[1].state)
|
||||
assert {'type': 'csmhe', 'order': 1} == json.loads(history[2].state)
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_CSMH_EXTENDED": False})
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_READING_FROM_MULTIPLE_HISTORY_TABLES": True})
|
||||
def test_get_history_false_true(self):
|
||||
student_module = StudentModule.objects.all()
|
||||
history = BaseStudentModuleHistory.get_history(student_module)
|
||||
self.assertEqual(len(history), 3)
|
||||
self.assertEqual({'type': 'csmh', 'order': 3}, json.loads(history[0].state))
|
||||
self.assertEqual({'type': 'csmh', 'order': 2}, json.loads(history[1].state))
|
||||
self.assertEqual({'type': 'csmh', 'order': 1}, json.loads(history[2].state))
|
||||
assert len(history) == 3
|
||||
assert {'type': 'csmh', 'order': 3} == json.loads(history[0].state)
|
||||
assert {'type': 'csmh', 'order': 2} == json.loads(history[1].state)
|
||||
assert {'type': 'csmh', 'order': 1} == json.loads(history[2].state)
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_CSMH_EXTENDED": False})
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_READING_FROM_MULTIPLE_HISTORY_TABLES": False})
|
||||
def test_get_history_false_false(self):
|
||||
student_module = StudentModule.objects.all()
|
||||
history = BaseStudentModuleHistory.get_history(student_module)
|
||||
self.assertEqual(len(history), 0)
|
||||
assert len(history) == 0
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
"""
|
||||
Provide tests for git_add_course management command.
|
||||
"""
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
@@ -10,6 +8,7 @@ import subprocess
|
||||
import unittest
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.core.management import call_command
|
||||
@@ -31,7 +30,6 @@ from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM
|
||||
|
||||
TEST_MONGODB_LOG = {
|
||||
'host': MONGO_HOST,
|
||||
'port': MONGO_PORT_NUM,
|
||||
@@ -108,16 +106,16 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Various exit path tests for test_add_repo
|
||||
"""
|
||||
with self.assertRaises(GitImportErrorNoDir):
|
||||
with pytest.raises(GitImportErrorNoDir):
|
||||
git_import.add_repo(self.TEST_REPO, None, None)
|
||||
|
||||
os.mkdir(self.git_repo_dir)
|
||||
self.addCleanup(shutil.rmtree, self.git_repo_dir)
|
||||
|
||||
with self.assertRaises(GitImportErrorUrlBad):
|
||||
with pytest.raises(GitImportErrorUrlBad):
|
||||
git_import.add_repo('foo', None, None)
|
||||
|
||||
with self.assertRaises(GitImportErrorCannotPull):
|
||||
with pytest.raises(GitImportErrorCannotPull):
|
||||
git_import.add_repo('file:///foobar.git', None, None)
|
||||
|
||||
# Test git repo that exists, but is "broken"
|
||||
@@ -127,7 +125,7 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
subprocess.check_output(['git', '--bare', 'init', ], stderr=subprocess.STDOUT,
|
||||
cwd=bare_repo)
|
||||
|
||||
with self.assertRaises(GitImportErrorBadRepo):
|
||||
with pytest.raises(GitImportErrorBadRepo):
|
||||
git_import.add_repo('file://{0}'.format(bare_repo), None, None)
|
||||
|
||||
def test_detached_repo(self):
|
||||
@@ -145,7 +143,7 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
subprocess.check_output(['git', 'checkout', 'HEAD~2', ],
|
||||
stderr=subprocess.STDOUT,
|
||||
cwd=repo_dir / 'edx4edx_lite')
|
||||
with self.assertRaises(GitImportErrorCannotPull):
|
||||
with pytest.raises(GitImportErrorCannotPull):
|
||||
git_import.add_repo(self.TEST_REPO, repo_dir / 'edx4edx_lite', None)
|
||||
|
||||
def test_branching(self):
|
||||
@@ -159,7 +157,7 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
self.addCleanup(shutil.rmtree, repo_dir)
|
||||
|
||||
# Checkout non existent branch
|
||||
with self.assertRaises(GitImportErrorRemoteBranchMissing):
|
||||
with pytest.raises(GitImportErrorRemoteBranchMissing):
|
||||
git_import.add_repo(self.TEST_REPO, repo_dir / 'edx4edx_lite', 'asdfasdfasdf')
|
||||
|
||||
# Checkout new branch
|
||||
@@ -168,7 +166,7 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
self.TEST_BRANCH)
|
||||
def_ms = modulestore()
|
||||
# Validate that it is different than master
|
||||
self.assertIsNotNone(def_ms.get_course(self.TEST_BRANCH_COURSE))
|
||||
assert def_ms.get_course(self.TEST_BRANCH_COURSE) is not None
|
||||
|
||||
# Attempt to check out the same branch again to validate branch choosing
|
||||
# works
|
||||
@@ -178,12 +176,12 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
|
||||
# Delete to test branching back to master
|
||||
def_ms.delete_course(self.TEST_BRANCH_COURSE, ModuleStoreEnum.UserID.test)
|
||||
self.assertIsNone(def_ms.get_course(self.TEST_BRANCH_COURSE))
|
||||
assert def_ms.get_course(self.TEST_BRANCH_COURSE) is None
|
||||
git_import.add_repo(self.TEST_REPO,
|
||||
repo_dir / 'edx4edx_lite',
|
||||
'master')
|
||||
self.assertIsNone(def_ms.get_course(self.TEST_BRANCH_COURSE))
|
||||
self.assertIsNotNone(def_ms.get_course(CourseKey.from_string(self.TEST_COURSE)))
|
||||
assert def_ms.get_course(self.TEST_BRANCH_COURSE) is None
|
||||
assert def_ms.get_course(CourseKey.from_string(self.TEST_COURSE)) is not None
|
||||
|
||||
def test_branch_exceptions(self):
|
||||
"""
|
||||
@@ -203,7 +201,7 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
self.addCleanup(shutil.rmtree, repo_dir)
|
||||
|
||||
rdir = '{0}/bare'.format(repo_dir)
|
||||
with self.assertRaises(GitImportErrorBadRepo):
|
||||
with pytest.raises(GitImportErrorBadRepo):
|
||||
git_import.add_repo('file://{0}'.format(bare_repo), None, None)
|
||||
|
||||
# Get logger for checking strings in logs
|
||||
@@ -218,7 +216,7 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
try:
|
||||
git_import.switch_branch('master', rdir)
|
||||
except GitImportError:
|
||||
self.assertIn('Unable to fetch remote', output.getvalue())
|
||||
assert 'Unable to fetch remote' in output.getvalue()
|
||||
shutil.move('{0}/not_bare.git'.format(settings.TEST_ROOT), bare_repo)
|
||||
output.truncate(0)
|
||||
|
||||
@@ -227,6 +225,6 @@ class TestGitAddCourse(SharedModuleStoreTestCase):
|
||||
['git', 'remote', 'rename', 'origin', 'blah', ],
|
||||
stderr=subprocess.STDOUT, cwd=rdir
|
||||
)
|
||||
with self.assertRaises(GitImportError):
|
||||
with pytest.raises(GitImportError):
|
||||
git_import.switch_branch('master', rdir)
|
||||
self.assertIn('Getting a list of remote branches failed', output.getvalue())
|
||||
assert 'Getting a list of remote branches failed' in output.getvalue()
|
||||
|
||||
@@ -165,15 +165,15 @@ class TestSysAdminMongoCourseImport(SysadminBaseTestCase):
|
||||
self._mkdir(settings.GIT_REPO_DIR)
|
||||
|
||||
def_ms = modulestore()
|
||||
self.assertNotEqual('xml', def_ms.get_modulestore_type(None))
|
||||
assert 'xml' != def_ms.get_modulestore_type(None)
|
||||
|
||||
self._add_edx4edx()
|
||||
course = def_ms.get_course(CourseLocator('MITx', 'edx4edx', 'edx4edx'))
|
||||
self.assertIsNotNone(course)
|
||||
assert course is not None
|
||||
|
||||
self._rm_edx4edx()
|
||||
course = def_ms.get_course(CourseLocator('MITx', 'edx4edx', 'edx4edx'))
|
||||
self.assertIsNone(course)
|
||||
assert course is None
|
||||
|
||||
def test_course_info(self):
|
||||
"""
|
||||
@@ -333,22 +333,22 @@ class TestSysAdminMongoCourseImport(SysadminBaseTestCase):
|
||||
password='foo')
|
||||
response = self.client.get(reverse('gitlogs'))
|
||||
# Make sure our non privileged user doesn't have access to all logs
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
# Or specific logs
|
||||
response = self.client.get(reverse('gitlogs_detail', kwargs={
|
||||
'course_id': 'course-v1:MITx+edx4edx+edx4edx'
|
||||
}))
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
# Add user as staff in course team
|
||||
def_ms = modulestore()
|
||||
course = def_ms.get_course(CourseLocator('MITx', 'edx4edx', 'edx4edx'))
|
||||
CourseStaffRole(course.id).add_users(self.user)
|
||||
|
||||
self.assertTrue(CourseStaffRole(course.id).has_user(self.user))
|
||||
assert CourseStaffRole(course.id).has_user(self.user)
|
||||
logged_in = self.client.login(username=self.user.username,
|
||||
password='foo')
|
||||
self.assertTrue(logged_in)
|
||||
assert logged_in
|
||||
|
||||
response = self.client.get(
|
||||
reverse('gitlogs_detail', kwargs={
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
# pylint: skip-file
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Tests for django comment client views."""
|
||||
@@ -363,11 +364,11 @@ class ViewsTestCaseMixin(object):
|
||||
}),
|
||||
data={"body": "foo", "title": "foo", "commentable_id": "some_topic"}
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(data['body'], 'foo')
|
||||
self.assertEqual(data['title'], 'foo')
|
||||
self.assertEqual(data['commentable_id'], 'some_topic')
|
||||
assert data['body'] == 'foo'
|
||||
assert data['title'] == 'foo'
|
||||
assert data['commentable_id'] == 'some_topic'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -525,7 +526,7 @@ class ViewsTestCase(
|
||||
kwargs={"course_id": six.text_type(self.course_id), "thread_id": 'i4x-MITx-999-course-Robot_Super_Course'}
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_delete_thread(self, mock_request):
|
||||
self._set_mock_request_data(mock_request, {
|
||||
@@ -542,8 +543,8 @@ class ViewsTestCase(
|
||||
course_id=six.text_type(self.course.id),
|
||||
thread_id=test_thread_id
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
|
||||
def test_delete_comment(self, mock_request):
|
||||
self._set_mock_request_data(mock_request, {
|
||||
@@ -560,11 +561,11 @@ class ViewsTestCase(
|
||||
course_id=six.text_type(self.course.id),
|
||||
comment_id=test_comment_id
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
args = mock_request.call_args[0]
|
||||
self.assertEqual(args[0], "delete")
|
||||
self.assertTrue(args[1].endswith("/{}".format(test_comment_id)))
|
||||
assert args[0] == 'delete'
|
||||
assert args[1].endswith('/{}'.format(test_comment_id))
|
||||
|
||||
def _test_request_error(self, view_name, view_kwargs, data, mock_request):
|
||||
"""
|
||||
@@ -575,9 +576,9 @@ class ViewsTestCase(
|
||||
self._setup_mock_request(mock_request, include_depth=(view_name == "create_sub_comment"))
|
||||
|
||||
response = self.client.post(reverse(view_name, kwargs=view_kwargs), data=data)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
for call in mock_request.call_args_list:
|
||||
self.assertEqual(call[0][0].lower(), "get")
|
||||
assert call[0][0].lower() == 'get'
|
||||
|
||||
def test_create_thread_no_title(self, mock_request):
|
||||
self._test_request_error(
|
||||
@@ -669,7 +670,7 @@ class ViewsTestCase(
|
||||
),
|
||||
data={"body": "body"}
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_create_comment_no_body(self, mock_request):
|
||||
self._test_request_error(
|
||||
@@ -731,7 +732,7 @@ class ViewsTestCase(
|
||||
),
|
||||
data={"body": updated_body}
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
mock_request.assert_called_with(
|
||||
"put",
|
||||
"{prefix}/comments/{comment_id}".format(prefix=CS_PREFIX, comment_id=comment_id),
|
||||
@@ -1052,7 +1053,7 @@ class ViewsTestCase(
|
||||
kwargs={item_id: 'dummy', 'course_id': six.text_type(self.course_id)}
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_endorse_comment(self, mock_request):
|
||||
self._setup_mock_request(mock_request)
|
||||
@@ -1064,7 +1065,7 @@ class ViewsTestCase(
|
||||
kwargs={'comment_id': 'dummy', 'course_id': six.text_type(self.course_id)}
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@patch("openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request", autospec=True)
|
||||
@@ -1102,7 +1103,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("pin_thread", kwargs={"course_id": six.text_type(self.course.id), "thread_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
assert response.status_code == 401
|
||||
|
||||
def test_pin_thread_as_moderator(self, mock_request):
|
||||
self._set_mock_request_data(mock_request, {})
|
||||
@@ -1110,7 +1111,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("pin_thread", kwargs={"course_id": six.text_type(self.course.id), "thread_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_un_pin_thread_as_student(self, mock_request):
|
||||
self._set_mock_request_data(mock_request, {})
|
||||
@@ -1118,7 +1119,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("un_pin_thread", kwargs={"course_id": six.text_type(self.course.id), "thread_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
assert response.status_code == 401
|
||||
|
||||
def test_un_pin_thread_as_moderator(self, mock_request):
|
||||
self._set_mock_request_data(mock_request, {})
|
||||
@@ -1126,7 +1127,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("un_pin_thread", kwargs={"course_id": six.text_type(self.course.id), "thread_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def _set_mock_request_thread_and_comment(self, mock_request, thread_data, comment_data):
|
||||
def handle_request(*args, **kwargs):
|
||||
@@ -1149,7 +1150,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("endorse_comment", kwargs={"course_id": six.text_type(self.course.id), "comment_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_endorse_response_as_student(self, mock_request):
|
||||
self._set_mock_request_thread_and_comment(
|
||||
@@ -1161,7 +1162,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("endorse_comment", kwargs={"course_id": six.text_type(self.course.id), "comment_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
assert response.status_code == 401
|
||||
|
||||
def test_endorse_response_as_student_question_author(self, mock_request):
|
||||
self._set_mock_request_thread_and_comment(
|
||||
@@ -1173,7 +1174,7 @@ class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStor
|
||||
response = self.client.post(
|
||||
reverse("endorse_comment", kwargs={"course_id": six.text_type(self.course.id), "comment_id": "dummy"})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
class CreateThreadUnicodeTestCase(
|
||||
@@ -1210,10 +1211,10 @@ class CreateThreadUnicodeTestCase(
|
||||
request, course_id=six.text_type(self.course.id), commentable_id=u"non_tåem_dummy_id"
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["title"], text)
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
assert mock_request.call_args[1]['data']['body'] == text
|
||||
assert mock_request.call_args[1]['data']['title'] == text
|
||||
|
||||
|
||||
@disable_signal(views, 'thread_edited')
|
||||
@@ -1253,12 +1254,12 @@ class UpdateThreadUnicodeTestCase(
|
||||
request.view_name = "update_thread"
|
||||
response = views.update_thread(request, course_id=six.text_type(self.course.id), thread_id="dummy_thread_id")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["title"], text)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["thread_type"], "question")
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["commentable_id"], "test_commentable")
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
assert mock_request.call_args[1]['data']['body'] == text
|
||||
assert mock_request.call_args[1]['data']['title'] == text
|
||||
assert mock_request.call_args[1]['data']['thread_type'] == 'question'
|
||||
assert mock_request.call_args[1]['data']['commentable_id'] == 'test_commentable'
|
||||
|
||||
|
||||
@disable_signal(views, 'comment_created')
|
||||
@@ -1301,9 +1302,9 @@ class CreateCommentUnicodeTestCase(
|
||||
request, course_id=six.text_type(self.course.id), thread_id="dummy_thread_id"
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
assert mock_request.call_args[1]['data']['body'] == text
|
||||
finally:
|
||||
del Thread.commentable_id
|
||||
|
||||
@@ -1341,9 +1342,9 @@ class UpdateCommentUnicodeTestCase(
|
||||
request.view_name = "update_comment"
|
||||
response = views.update_comment(request, course_id=six.text_type(self.course.id), comment_id="dummy_comment_id")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
assert mock_request.call_args[1]['data']['body'] == text
|
||||
|
||||
|
||||
@disable_signal(views, 'comment_created')
|
||||
@@ -1390,9 +1391,9 @@ class CreateSubCommentUnicodeTestCase(
|
||||
request, course_id=six.text_type(self.course.id), comment_id="dummy_comment_id"
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
|
||||
assert response.status_code == 200
|
||||
assert mock_request.called
|
||||
assert mock_request.call_args[1]['data']['body'] == text
|
||||
finally:
|
||||
del Thread.commentable_id
|
||||
|
||||
@@ -1567,7 +1568,7 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
|
||||
),
|
||||
data={"body": "foo", "title": "foo", "commentable_id": commentable_id}
|
||||
)
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
|
||||
@ddt.data(
|
||||
# Students can delete their own posts
|
||||
@@ -1611,7 +1612,7 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
|
||||
),
|
||||
data={"body": "foo", "title": "foo"}
|
||||
)
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
|
||||
@ddt.data(*ddt_permissions_args)
|
||||
@ddt.unpack
|
||||
@@ -1632,7 +1633,7 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
|
||||
),
|
||||
data={"body": "foo", "title": "foo"}
|
||||
)
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
|
||||
@ddt.data(*ddt_permissions_args)
|
||||
@ddt.unpack
|
||||
@@ -1655,7 +1656,7 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
|
||||
),
|
||||
data={"body": "foo", "title": "foo"}
|
||||
)
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
|
||||
@ddt.data(*ddt_permissions_args)
|
||||
@ddt.unpack
|
||||
@@ -1676,7 +1677,7 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
|
||||
kwargs={"course_id": six.text_type(self.course.id), "comment_id": "dummy_comment"}
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
|
||||
@ddt.data(*ddt_permissions_args)
|
||||
@ddt.unpack
|
||||
@@ -1698,7 +1699,7 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
|
||||
kwargs={"course_id": six.text_type(self.course.id), "thread_id": "dummy_thread"}
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
|
||||
|
||||
TEAM_COMMENTABLE_ID = 'test-team-discussion'
|
||||
@@ -1744,13 +1745,13 @@ class ForumEventTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockReque
|
||||
views.create_comment(request, course_id=six.text_type(self.course.id), thread_id='test_thread_id')
|
||||
|
||||
event_name, event = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, 'edx.forum.response.created')
|
||||
self.assertEqual(event['body'], "Test comment")
|
||||
self.assertEqual(event['commentable_id'], 'test_commentable_id')
|
||||
self.assertEqual(event['user_forums_roles'], ['Student'])
|
||||
self.assertEqual(event['user_course_roles'], ['Wizard'])
|
||||
self.assertEqual(event['discussion']['id'], 'test_thread_id')
|
||||
self.assertEqual(event['options']['followed'], True)
|
||||
assert event_name == 'edx.forum.response.created'
|
||||
assert event['body'] == 'Test comment'
|
||||
assert event['commentable_id'] == 'test_commentable_id'
|
||||
assert event['user_forums_roles'] == ['Student']
|
||||
assert event['user_course_roles'] == ['Wizard']
|
||||
assert event['discussion']['id'] == 'test_thread_id'
|
||||
assert event['options']['followed'] is True
|
||||
|
||||
@patch('eventtracking.tracker.emit')
|
||||
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)
|
||||
@@ -1771,13 +1772,13 @@ class ForumEventTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockReque
|
||||
views.create_sub_comment(request, course_id=six.text_type(self.course.id), comment_id="dummy_comment_id")
|
||||
|
||||
event_name, event = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, "edx.forum.comment.created")
|
||||
self.assertEqual(event['body'], 'Another comment')
|
||||
self.assertEqual(event['discussion']['id'], 'test_thread_id')
|
||||
self.assertEqual(event['response']['id'], 'test_response_id')
|
||||
self.assertEqual(event['user_forums_roles'], ['Student'])
|
||||
self.assertEqual(event['user_course_roles'], ['Wizard'])
|
||||
self.assertEqual(event['options']['followed'], False)
|
||||
assert event_name == 'edx.forum.comment.created'
|
||||
assert event['body'] == 'Another comment'
|
||||
assert event['discussion']['id'] == 'test_thread_id'
|
||||
assert event['response']['id'] == 'test_response_id'
|
||||
assert event['user_forums_roles'] == ['Student']
|
||||
assert event['user_course_roles'] == ['Wizard']
|
||||
assert event['options']['followed'] is False
|
||||
|
||||
@patch('eventtracking.tracker.emit')
|
||||
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)
|
||||
@@ -1820,8 +1821,8 @@ class ForumEventTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockReque
|
||||
getattr(views, view_name)(request, course_id=six.text_type(self.course.id), **view_kwargs)
|
||||
|
||||
name, event = mock_emit.call_args[0]
|
||||
self.assertEqual(name, event_name)
|
||||
self.assertEqual(event['team_id'], team.team_id)
|
||||
assert name == event_name
|
||||
assert event['team_id'] == team.team_id
|
||||
|
||||
@ddt.data(
|
||||
('vote_for_thread', 'thread_id', 'thread'),
|
||||
@@ -1850,12 +1851,12 @@ class ForumEventTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockReque
|
||||
kwargs.update(value='up')
|
||||
view_function(request, **kwargs)
|
||||
|
||||
self.assertTrue(mock_emit.called)
|
||||
assert mock_emit.called
|
||||
event_name, event = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, 'edx.forum.{}.voted'.format(obj_type))
|
||||
self.assertEqual(event['target_username'], 'gumprecht')
|
||||
self.assertEqual(event['undo_vote'], undo)
|
||||
self.assertEqual(event['vote_value'], 'up')
|
||||
assert event_name == 'edx.forum.{}.voted'.format(obj_type)
|
||||
assert event['target_username'] == 'gumprecht'
|
||||
assert event['undo_vote'] == undo
|
||||
assert event['vote_value'] == 'up'
|
||||
|
||||
|
||||
class UsersEndpointTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockRequestSetupMixin):
|
||||
@@ -1897,55 +1898,52 @@ class UsersEndpointTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockRe
|
||||
def test_finds_exact_match(self, mock_request):
|
||||
self.set_post_counts(mock_request)
|
||||
response = self.make_request(username="other")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
json.loads(response.content.decode('utf-8'))["users"],
|
||||
[{"id": self.other_user.id, "username": self.other_user.username}]
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8'))['users'] == [{'id': self.other_user.id, 'username': self.other_user.username}]
|
||||
|
||||
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)
|
||||
def test_finds_no_match(self, mock_request):
|
||||
self.set_post_counts(mock_request)
|
||||
response = self.make_request(username="othor")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8'))["users"], [])
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8'))['users'] == []
|
||||
|
||||
def test_requires_GET(self):
|
||||
response = self.make_request(method='post', username="other")
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
|
||||
def test_requires_username_param(self):
|
||||
response = self.make_request()
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertIn("errors", content)
|
||||
self.assertNotIn("users", content)
|
||||
assert 'errors' in content
|
||||
assert 'users' not in content
|
||||
|
||||
def test_course_does_not_exist(self):
|
||||
course_id = CourseKey.from_string("does/not/exist")
|
||||
response = self.make_request(course_id=course_id, username="other")
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertIn("errors", content)
|
||||
self.assertNotIn("users", content)
|
||||
assert 'errors' in content
|
||||
assert 'users' not in content
|
||||
|
||||
def test_requires_requestor_enrolled_in_course(self):
|
||||
# unenroll self.student from the course.
|
||||
self.enrollment.delete()
|
||||
|
||||
response = self.make_request(username="other")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertIn("errors", content)
|
||||
self.assertNotIn("users", content)
|
||||
assert 'errors' in content
|
||||
assert 'users' not in content
|
||||
|
||||
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)
|
||||
def test_requires_matched_user_has_forum_content(self, mock_request):
|
||||
self.set_post_counts(mock_request, 0, 0)
|
||||
response = self.make_request(username="other")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8'))["users"], [])
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8'))['users'] == []
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1966,7 +1964,7 @@ class SegmentIOForumThreadViewedEventTestCase(SegmentIOTrackingTestCaseBase):
|
||||
middleware.process_request(request)
|
||||
try:
|
||||
response = segmentio.segmentio_event(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
finally:
|
||||
middleware.process_response(request, None)
|
||||
|
||||
@@ -1981,8 +1979,8 @@ class SegmentIOForumThreadViewedEventTestCase(SegmentIOTrackingTestCaseBase):
|
||||
"""
|
||||
self._raise_navigation_event('Forum: View Thread', include_name)
|
||||
event = self.get_event()
|
||||
self.assertEqual(event['name'], 'edx.forum.thread.viewed')
|
||||
self.assertEqual(event['event_type'], event['name'])
|
||||
assert event['name'] == 'edx.forum.thread.viewed'
|
||||
assert event['event_type'] == event['name']
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_non_thread_viewed(self, include_name):
|
||||
@@ -2095,7 +2093,7 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
|
||||
def test_missing_context(self):
|
||||
event = _create_event(include_context=False)
|
||||
with self.assertRaises(EventEmissionExit):
|
||||
with pytest.raises(EventEmissionExit):
|
||||
_get_transformed_event(event)
|
||||
|
||||
def test_no_data(self):
|
||||
@@ -2107,7 +2105,7 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
|
||||
def test_inner_context(self):
|
||||
_, event_trans = _create_and_transform_event(inner_context={})
|
||||
self.assertNotIn('context', event_trans['event'])
|
||||
assert 'context' not in event_trans['event']
|
||||
|
||||
def test_non_thread_view(self):
|
||||
event = _create_event(
|
||||
@@ -2116,7 +2114,7 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
topic_id=self.DUMMY_CATEGORY_ID,
|
||||
thread_id=self.DUMMY_THREAD_ID,
|
||||
)
|
||||
with self.assertRaises(EventEmissionExit):
|
||||
with pytest.raises(EventEmissionExit):
|
||||
_get_transformed_event(event)
|
||||
|
||||
def test_bad_field_types(self):
|
||||
@@ -2133,19 +2131,19 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
def test_bad_course_id(self):
|
||||
event, event_trans = _create_and_transform_event(course_id='non-existent-course-id')
|
||||
event_data = event_trans['event']
|
||||
self.assertNotIn('category_id', event_data)
|
||||
self.assertNotIn('category_name', event_data)
|
||||
self.assertNotIn('url', event_data)
|
||||
self.assertNotIn('user_forums_roles', event_data)
|
||||
self.assertNotIn('user_course_roles', event_data)
|
||||
assert 'category_id' not in event_data
|
||||
assert 'category_name' not in event_data
|
||||
assert 'url' not in event_data
|
||||
assert 'user_forums_roles' not in event_data
|
||||
assert 'user_course_roles' not in event_data
|
||||
|
||||
def test_bad_username(self):
|
||||
event, event_trans = _create_and_transform_event(username='non-existent-username')
|
||||
event_data = event_trans['event']
|
||||
self.assertNotIn('category_id', event_data)
|
||||
self.assertNotIn('category_name', event_data)
|
||||
self.assertNotIn('user_forums_roles', event_data)
|
||||
self.assertNotIn('user_course_roles', event_data)
|
||||
assert 'category_id' not in event_data
|
||||
assert 'category_name' not in event_data
|
||||
assert 'user_forums_roles' not in event_data
|
||||
assert 'user_course_roles' not in event_data
|
||||
|
||||
def test_bad_url(self):
|
||||
event, event_trans = _create_and_transform_event(
|
||||
@@ -2153,7 +2151,7 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
topic_id='malformed/commentable/id',
|
||||
thread_id='malformed/thread/id',
|
||||
)
|
||||
self.assertNotIn('url', event_trans['event'])
|
||||
assert 'url' not in event_trans['event']
|
||||
|
||||
def test_renamed_fields(self):
|
||||
AUTHOR = 'joe-the-plumber'
|
||||
@@ -2163,32 +2161,32 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
thread_id=self.DUMMY_THREAD_ID,
|
||||
author=AUTHOR,
|
||||
)
|
||||
self.assertEqual(event_trans['event']['commentable_id'], self.DUMMY_CATEGORY_ID)
|
||||
self.assertEqual(event_trans['event']['id'], self.DUMMY_THREAD_ID)
|
||||
self.assertEqual(event_trans['event']['target_username'], AUTHOR)
|
||||
assert event_trans['event']['commentable_id'] == self.DUMMY_CATEGORY_ID
|
||||
assert event_trans['event']['id'] == self.DUMMY_THREAD_ID
|
||||
assert event_trans['event']['target_username'] == AUTHOR
|
||||
|
||||
def test_titles(self):
|
||||
|
||||
# No title
|
||||
_, event_1_trans = _create_and_transform_event()
|
||||
self.assertNotIn('title', event_1_trans['event'])
|
||||
self.assertNotIn('title_truncated', event_1_trans['event'])
|
||||
assert 'title' not in event_1_trans['event']
|
||||
assert 'title_truncated' not in event_1_trans['event']
|
||||
|
||||
# Short title
|
||||
_, event_2_trans = _create_and_transform_event(
|
||||
action='!',
|
||||
)
|
||||
self.assertIn('title', event_2_trans['event'])
|
||||
self.assertIn('title_truncated', event_2_trans['event'])
|
||||
self.assertFalse(event_2_trans['event']['title_truncated'])
|
||||
assert 'title' in event_2_trans['event']
|
||||
assert 'title_truncated' in event_2_trans['event']
|
||||
assert not event_2_trans['event']['title_truncated']
|
||||
|
||||
# Long title
|
||||
_, event_3_trans = _create_and_transform_event(
|
||||
action=('covfefe' * 200),
|
||||
)
|
||||
self.assertIn('title', event_3_trans['event'])
|
||||
self.assertIn('title_truncated', event_3_trans['event'])
|
||||
self.assertTrue(event_3_trans['event']['title_truncated'])
|
||||
assert 'title' in event_3_trans['event']
|
||||
assert 'title_truncated' in event_3_trans['event']
|
||||
assert event_3_trans['event']['title_truncated']
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
|
||||
def test_urls(self, store):
|
||||
@@ -2203,7 +2201,7 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
expected_path = '/courses/{0}/discussion/forum/{1}/threads/{2}'.format(
|
||||
course.id, commentable_id, thread_id
|
||||
)
|
||||
self.assertTrue(event_trans['event'].get('url').endswith(expected_path))
|
||||
assert event_trans['event'].get('url').endswith(expected_path)
|
||||
|
||||
def test_categories(self):
|
||||
|
||||
@@ -2213,8 +2211,8 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
course_id=self.course.id,
|
||||
topic_id='non-existent-category-id',
|
||||
)
|
||||
self.assertNotIn('category_id', event_trans_1['event'])
|
||||
self.assertNotIn('category_name', event_trans_1['event'])
|
||||
assert 'category_id' not in event_trans_1['event']
|
||||
assert 'category_name' not in event_trans_1['event']
|
||||
|
||||
# Good category
|
||||
_, event_trans_2 = _create_and_transform_event(
|
||||
@@ -2222,9 +2220,9 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
course_id=self.course.id,
|
||||
topic_id=self.category.discussion_id,
|
||||
)
|
||||
self.assertEqual(event_trans_2['event'].get('category_id'), self.category.discussion_id)
|
||||
assert event_trans_2['event'].get('category_id') == self.category.discussion_id
|
||||
full_category_name = u'{0} / {1}'.format(self.category.discussion_category, self.category.discussion_target)
|
||||
self.assertEqual(event_trans_2['event'].get('category_name'), full_category_name)
|
||||
assert event_trans_2['event'].get('category_name') == full_category_name
|
||||
|
||||
def test_roles(self):
|
||||
|
||||
@@ -2232,24 +2230,24 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
_, event_trans_1 = _create_and_transform_event(
|
||||
course_id=self.course.id,
|
||||
)
|
||||
self.assertNotIn('user_forums_roles', event_trans_1['event'])
|
||||
self.assertNotIn('user_course_roles', event_trans_1['event'])
|
||||
assert 'user_forums_roles' not in event_trans_1['event']
|
||||
assert 'user_course_roles' not in event_trans_1['event']
|
||||
|
||||
# Student user
|
||||
_, event_trans_2 = _create_and_transform_event(
|
||||
course_id=self.course.id,
|
||||
username=self.student.username,
|
||||
)
|
||||
self.assertEqual(event_trans_2['event'].get('user_forums_roles'), [FORUM_ROLE_STUDENT])
|
||||
self.assertEqual(event_trans_2['event'].get('user_course_roles'), [])
|
||||
assert event_trans_2['event'].get('user_forums_roles') == [FORUM_ROLE_STUDENT]
|
||||
assert event_trans_2['event'].get('user_course_roles') == []
|
||||
|
||||
# Course staff user
|
||||
_, event_trans_3 = _create_and_transform_event(
|
||||
course_id=self.course.id,
|
||||
username=self.staff.username,
|
||||
)
|
||||
self.assertEqual(event_trans_3['event'].get('user_forums_roles'), [])
|
||||
self.assertEqual(event_trans_3['event'].get('user_course_roles'), [CourseStaffRole.ROLE])
|
||||
assert event_trans_3['event'].get('user_forums_roles') == []
|
||||
assert event_trans_3['event'].get('user_course_roles') == [CourseStaffRole.ROLE]
|
||||
|
||||
def test_teams(self):
|
||||
|
||||
@@ -2257,18 +2255,18 @@ class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin
|
||||
_, event_trans_1 = _create_and_transform_event(
|
||||
course_id=self.course.id,
|
||||
)
|
||||
self.assertNotIn('team_id', event_trans_1)
|
||||
assert 'team_id' not in event_trans_1
|
||||
|
||||
# Non-team category
|
||||
_, event_trans_2 = _create_and_transform_event(
|
||||
course_id=self.course.id,
|
||||
topic_id=self.CATEGORY_ID,
|
||||
)
|
||||
self.assertNotIn('team_id', event_trans_2)
|
||||
assert 'team_id' not in event_trans_2
|
||||
|
||||
# Team category
|
||||
_, event_trans_3 = _create_and_transform_event(
|
||||
course_id=self.course.id,
|
||||
topic_id=self.TEAM_CATEGORY_ID,
|
||||
)
|
||||
self.assertEqual(event_trans_3['event'].get('team_id'), self.team.team_id)
|
||||
assert event_trans_3['event'].get('team_id') == self.team.team_id
|
||||
|
||||
@@ -23,12 +23,12 @@ class GroupIdAssertionMixin(object):
|
||||
return call[1]["data"]
|
||||
|
||||
def _assert_comments_service_called_with_group_id(self, mock_request, group_id):
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertEqual(self._data_or_params_cs_request(mock_request)["group_id"], group_id)
|
||||
assert mock_request.called
|
||||
assert self._data_or_params_cs_request(mock_request)['group_id'] == group_id
|
||||
|
||||
def _assert_comments_service_called_without_group_id(self, mock_request):
|
||||
self.assertTrue(mock_request.called)
|
||||
self.assertNotIn("group_id", self._data_or_params_cs_request(mock_request))
|
||||
assert mock_request.called
|
||||
assert 'group_id' not in self._data_or_params_cs_request(mock_request)
|
||||
|
||||
def _assert_html_response_contains_group_info(self, response):
|
||||
group_info = {"group_id": None, "group_name": None}
|
||||
@@ -52,8 +52,8 @@ class GroupIdAssertionMixin(object):
|
||||
self._assert_thread_contains_group_info(thread)
|
||||
|
||||
def _assert_thread_contains_group_info(self, thread):
|
||||
self.assertEqual(thread['group_id'], self.student_cohort.id)
|
||||
self.assertEqual(thread['group_name'], self.student_cohort.name)
|
||||
assert thread['group_id'] == self.student_cohort.id
|
||||
assert thread['group_name'] == self.student_cohort.name
|
||||
|
||||
|
||||
class CohortedTopicGroupIdTestMixin(GroupIdAssertionMixin):
|
||||
@@ -103,7 +103,7 @@ class CohortedTopicGroupIdTestMixin(GroupIdAssertionMixin):
|
||||
def test_cohorted_topic_moderator_with_invalid_group_id(self, mock_request):
|
||||
invalid_id = self.student_cohort.id + self.moderator_cohort.id
|
||||
response = self.call_view(mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return
|
||||
self.assertEqual(response.status_code, 500)
|
||||
assert response.status_code == 500
|
||||
|
||||
def test_cohorted_topic_enrollment_track_invalid_group_id(self, mock_request):
|
||||
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.AUDIT)
|
||||
@@ -117,7 +117,7 @@ class CohortedTopicGroupIdTestMixin(GroupIdAssertionMixin):
|
||||
|
||||
invalid_id = -1000
|
||||
response = self.call_view(mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return
|
||||
self.assertEqual(response.status_code, 500)
|
||||
assert response.status_code == 500
|
||||
|
||||
|
||||
class NonCohortedTopicGroupIdTestMixin(GroupIdAssertionMixin):
|
||||
|
||||
@@ -57,4 +57,4 @@ class MockCommentServiceServerTest(unittest.TestCase):
|
||||
response_dict = json.loads(response.read())
|
||||
|
||||
# You should have received the response specified in the setup above
|
||||
self.assertEqual(response_dict, self.expected_response)
|
||||
assert response_dict == self.expected_response
|
||||
|
||||
@@ -24,21 +24,15 @@ class AjaxExceptionTestCase(TestCase): # lint-amnesty, pylint: disable=missing-
|
||||
|
||||
def test_process_exception(self):
|
||||
response1 = self.a.process_exception(self.request1, self.exception1)
|
||||
self.assertIsInstance(response1, middleware.JsonError)
|
||||
self.assertEqual(self.exception1.status_code, response1.status_code)
|
||||
self.assertEqual(
|
||||
{"errors": json.loads(text_type(self.exception1))},
|
||||
json.loads(response1.content.decode('utf-8'))
|
||||
)
|
||||
assert isinstance(response1, middleware.JsonError)
|
||||
assert self.exception1.status_code == response1.status_code
|
||||
assert {'errors': json.loads(text_type(self.exception1))} == json.loads(response1.content.decode('utf-8'))
|
||||
|
||||
response2 = self.a.process_exception(self.request1, self.exception2)
|
||||
self.assertIsInstance(response2, middleware.JsonError)
|
||||
self.assertEqual(self.exception2.status_code, response2.status_code)
|
||||
self.assertEqual(
|
||||
{"errors": [text_type(self.exception2)]},
|
||||
json.loads(response2.content.decode('utf-8'))
|
||||
)
|
||||
assert isinstance(response2, middleware.JsonError)
|
||||
assert self.exception2.status_code == response2.status_code
|
||||
assert {'errors': [text_type(self.exception2)]} == json.loads(response2.content.decode('utf-8'))
|
||||
|
||||
self.assertIsNone(self.a.process_exception(self.request1, self.exception0))
|
||||
self.assertIsNone(self.a.process_exception(self.request0, self.exception1))
|
||||
self.assertIsNone(self.a.process_exception(self.request0, self.exception0))
|
||||
assert self.a.process_exception(self.request1, self.exception0) is None
|
||||
assert self.a.process_exception(self.request0, self.exception1) is None
|
||||
assert self.a.process_exception(self.request0, self.exception0) is None
|
||||
|
||||
@@ -40,13 +40,13 @@ class RoleClassTestCase(ModuleStoreTestCase):
|
||||
# Roles with the same FORUM_ROLE in same class also receives the same
|
||||
# permission.
|
||||
# Is this desirable behavior?
|
||||
self.assertTrue(self.student_role.has_permission("delete_thread"))
|
||||
self.assertTrue(self.student_2_role.has_permission("delete_thread"))
|
||||
self.assertFalse(self.TA_role.has_permission("delete_thread"))
|
||||
assert self.student_role.has_permission('delete_thread')
|
||||
assert self.student_2_role.has_permission('delete_thread')
|
||||
assert not self.TA_role.has_permission('delete_thread')
|
||||
|
||||
def test_inherit_permission(self):
|
||||
self.TA_role.inherit_permissions(self.student_role)
|
||||
self.assertTrue(self.TA_role.has_permission("delete_thread"))
|
||||
assert self.TA_role.has_permission('delete_thread')
|
||||
# Despite being from 2 different courses, TA_role_2 can still inherit
|
||||
# permissions from TA_role without error
|
||||
self.TA_role_2.inherit_permissions(self.TA_role)
|
||||
@@ -62,4 +62,4 @@ class PermissionClassTestCase(TestCase):
|
||||
self.permission = models.Permission.objects.get_or_create(name="test")[0]
|
||||
|
||||
def test_unicode(self):
|
||||
self.assertEqual(str(self.permission), "test")
|
||||
assert str(self.permission) == 'test'
|
||||
|
||||
@@ -60,17 +60,17 @@ class DictionaryTestCase(TestCase):
|
||||
d = {'cats': 'meow', 'dogs': 'woof'}
|
||||
k = ['cats', 'dogs', 'hamsters']
|
||||
expected = {'cats': 'meow', 'dogs': 'woof', 'hamsters': None}
|
||||
self.assertEqual(utils.extract(d, k), expected)
|
||||
assert utils.extract(d, k) == expected
|
||||
|
||||
def test_strip_none(self):
|
||||
d = {'cats': 'meow', 'dogs': 'woof', 'hamsters': None}
|
||||
expected = {'cats': 'meow', 'dogs': 'woof'}
|
||||
self.assertEqual(utils.strip_none(d), expected)
|
||||
assert utils.strip_none(d) == expected
|
||||
|
||||
def test_strip_blank(self):
|
||||
d = {'cats': 'meow', 'dogs': 'woof', 'hamsters': ' ', 'yetis': ''}
|
||||
expected = {'cats': 'meow', 'dogs': 'woof'}
|
||||
self.assertEqual(utils.strip_blank(d), expected)
|
||||
assert utils.strip_blank(d) == expected
|
||||
|
||||
|
||||
class AccessUtilsTestCase(ModuleStoreTestCase):
|
||||
@@ -106,25 +106,25 @@ class AccessUtilsTestCase(ModuleStoreTestCase):
|
||||
def test_get_role_ids(self):
|
||||
ret = utils.get_role_ids(self.course_id)
|
||||
expected = {u'Moderator': [3], u'Community TA': [4, 5]}
|
||||
self.assertEqual(ret, expected)
|
||||
assert ret == expected
|
||||
|
||||
def test_has_discussion_privileges(self):
|
||||
self.assertFalse(utils.has_discussion_privileges(self.student1, self.course_id))
|
||||
self.assertFalse(utils.has_discussion_privileges(self.student2, self.course_id))
|
||||
self.assertFalse(utils.has_discussion_privileges(self.course_staff, self.course_id))
|
||||
self.assertTrue(utils.has_discussion_privileges(self.moderator, self.course_id))
|
||||
self.assertTrue(utils.has_discussion_privileges(self.community_ta1, self.course_id))
|
||||
self.assertTrue(utils.has_discussion_privileges(self.community_ta2, self.course_id))
|
||||
assert not utils.has_discussion_privileges(self.student1, self.course_id)
|
||||
assert not utils.has_discussion_privileges(self.student2, self.course_id)
|
||||
assert not utils.has_discussion_privileges(self.course_staff, self.course_id)
|
||||
assert utils.has_discussion_privileges(self.moderator, self.course_id)
|
||||
assert utils.has_discussion_privileges(self.community_ta1, self.course_id)
|
||||
assert utils.has_discussion_privileges(self.community_ta2, self.course_id)
|
||||
|
||||
def test_has_forum_access(self):
|
||||
ret = utils.has_forum_access('student', self.course_id, 'Student')
|
||||
self.assertTrue(ret)
|
||||
assert ret
|
||||
|
||||
ret = utils.has_forum_access('not_a_student', self.course_id, 'Student')
|
||||
self.assertFalse(ret)
|
||||
assert not ret
|
||||
|
||||
ret = utils.has_forum_access('student', self.course_id, 'NotARole')
|
||||
self.assertFalse(ret)
|
||||
assert not ret
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -158,7 +158,7 @@ class CoursewareContextTestCase(ModuleStoreTestCase):
|
||||
orig = {"commentable_id": "non-inline"}
|
||||
modified = dict(orig)
|
||||
utils.add_courseware_context([modified], self.course, self.user)
|
||||
self.assertEqual(modified, orig)
|
||||
assert modified == orig
|
||||
|
||||
def test_basic(self):
|
||||
threads = [
|
||||
@@ -169,21 +169,9 @@ class CoursewareContextTestCase(ModuleStoreTestCase):
|
||||
|
||||
def assertThreadCorrect(thread, discussion, expected_title): # pylint: disable=invalid-name
|
||||
"""Asserts that the given thread has the expected set of properties"""
|
||||
self.assertEqual(
|
||||
set(thread.keys()),
|
||||
set(["commentable_id", "courseware_url", "courseware_title"])
|
||||
)
|
||||
self.assertEqual(
|
||||
thread.get("courseware_url"),
|
||||
reverse(
|
||||
"jump_to",
|
||||
kwargs={
|
||||
"course_id": text_type(self.course.id),
|
||||
"location": text_type(discussion.location)
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertEqual(thread.get("courseware_title"), expected_title)
|
||||
assert set(thread.keys()) == set(['commentable_id', 'courseware_url', 'courseware_title'])
|
||||
assert thread.get('courseware_url') == reverse('jump_to', kwargs={'course_id': text_type(self.course.id), 'location': text_type(discussion.location)})
|
||||
assert thread.get('courseware_title') == expected_title
|
||||
|
||||
assertThreadCorrect(threads[0], self.discussion1, "Chapter / Discussion 1")
|
||||
assertThreadCorrect(threads[1], self.discussion2, "Subsection / Discussion 2")
|
||||
@@ -202,7 +190,7 @@ class CoursewareContextTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
thread = {"commentable_id": discussion.discussion_id}
|
||||
utils.add_courseware_context([thread], self.course, self.user)
|
||||
self.assertNotIn('/', thread.get("courseware_title"))
|
||||
assert '/' not in thread.get('courseware_title')
|
||||
|
||||
@ddt.data((ModuleStoreEnum.Type.mongo, 2), (ModuleStoreEnum.Type.split, 1))
|
||||
@ddt.unpack
|
||||
@@ -216,10 +204,10 @@ class CoursewareContextTestCase(ModuleStoreTestCase):
|
||||
test_discussion = self.store.create_child(self.user.id, course.location, 'discussion', 'test_discussion')
|
||||
|
||||
# Assert that created discussion xblock is not an orphan.
|
||||
self.assertNotIn(test_discussion.location, self.store.get_orphans(course.id))
|
||||
assert test_discussion.location not in self.store.get_orphans(course.id)
|
||||
|
||||
# Assert that there is only one discussion xblock in the course at the moment.
|
||||
self.assertEqual(len(utils.get_accessible_discussion_xblocks(course, self.user)), 1)
|
||||
assert len(utils.get_accessible_discussion_xblocks(course, self.user)) == 1
|
||||
|
||||
# The above call is request cached, so we need to clear it for this test.
|
||||
RequestCache.clear_all_namespaces()
|
||||
@@ -228,9 +216,9 @@ class CoursewareContextTestCase(ModuleStoreTestCase):
|
||||
self.store.create_item(self.user.id, orphan.course_key, orphan.block_type, block_id=orphan.block_id)
|
||||
|
||||
# Assert that the discussion xblock is an orphan.
|
||||
self.assertIn(orphan, self.store.get_orphans(course.id))
|
||||
assert orphan in self.store.get_orphans(course.id)
|
||||
|
||||
self.assertEqual(len(utils.get_accessible_discussion_xblocks(course, self.user)), expected_discussion_xblocks)
|
||||
assert len(utils.get_accessible_discussion_xblocks(course, self.user)) == expected_discussion_xblocks
|
||||
|
||||
|
||||
class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
|
||||
@@ -276,15 +264,15 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_cache_returns_correct_key(self):
|
||||
usage_key = utils.get_cached_discussion_key(self.course.id, 'test_discussion_id')
|
||||
self.assertEqual(usage_key, self.discussion.location)
|
||||
assert usage_key == self.discussion.location
|
||||
|
||||
def test_cache_returns_none_if_id_is_not_present(self):
|
||||
usage_key = utils.get_cached_discussion_key(self.course.id, 'bogus_id')
|
||||
self.assertIsNone(usage_key)
|
||||
assert usage_key is None
|
||||
|
||||
def test_cache_raises_exception_if_discussion_id_map_not_cached(self):
|
||||
DiscussionsIdMapping.objects.all().delete()
|
||||
with self.assertRaises(utils.DiscussionIdMapIsNotCached):
|
||||
with pytest.raises(utils.DiscussionIdMapIsNotCached):
|
||||
utils.get_cached_discussion_key(self.course.id, 'test_discussion_id')
|
||||
|
||||
def test_cache_raises_exception_if_discussion_id_not_cached(self):
|
||||
@@ -292,12 +280,12 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
|
||||
cache.mapping = None
|
||||
cache.save()
|
||||
|
||||
with self.assertRaises(utils.DiscussionIdMapIsNotCached):
|
||||
with pytest.raises(utils.DiscussionIdMapIsNotCached):
|
||||
utils.get_cached_discussion_key(self.course.id, 'test_discussion_id')
|
||||
|
||||
def test_xblock_does_not_have_required_keys(self):
|
||||
self.assertTrue(utils.has_required_keys(self.discussion))
|
||||
self.assertFalse(utils.has_required_keys(self.bad_discussion))
|
||||
assert utils.has_required_keys(self.discussion)
|
||||
assert not utils.has_required_keys(self.bad_discussion)
|
||||
|
||||
def verify_discussion_metadata(self):
|
||||
"""Retrieves the metadata for self.discussion and self.discussion2 and verifies that it is correct"""
|
||||
@@ -308,10 +296,10 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
discussion1 = metadata[self.discussion.discussion_id]
|
||||
discussion2 = metadata[self.discussion2.discussion_id]
|
||||
self.assertEqual(discussion1['location'], self.discussion.location)
|
||||
self.assertEqual(discussion1['title'], 'Chapter / Discussion 1')
|
||||
self.assertEqual(discussion2['location'], self.discussion2.location)
|
||||
self.assertEqual(discussion2['title'], 'Chapter 2 / Discussion 2')
|
||||
assert discussion1['location'] == self.discussion.location
|
||||
assert discussion1['title'] == 'Chapter / Discussion 1'
|
||||
assert discussion2['location'] == self.discussion2.location
|
||||
assert discussion2['title'] == 'Chapter 2 / Discussion 2'
|
||||
|
||||
def test_get_discussion_id_map_from_cache(self):
|
||||
self.verify_discussion_metadata()
|
||||
@@ -322,34 +310,34 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_get_missing_discussion_id_map_from_cache(self):
|
||||
metadata = utils.get_cached_discussion_id_map(self.course, ['bogus_id'], self.user)
|
||||
self.assertEqual(metadata, {})
|
||||
assert metadata == {}
|
||||
|
||||
def test_get_discussion_id_map_from_cache_without_access(self):
|
||||
user = UserFactory.create()
|
||||
|
||||
metadata = utils.get_cached_discussion_id_map(self.course, ['private_discussion_id'], self.user)
|
||||
self.assertEqual(metadata['private_discussion_id']['title'], 'Chapter 3 / Beta Testing')
|
||||
assert metadata['private_discussion_id']['title'] == 'Chapter 3 / Beta Testing'
|
||||
|
||||
metadata = utils.get_cached_discussion_id_map(self.course, ['private_discussion_id'], user)
|
||||
self.assertEqual(metadata, {})
|
||||
assert metadata == {}
|
||||
|
||||
def test_get_bad_discussion_id(self):
|
||||
metadata = utils.get_cached_discussion_id_map(self.course, ['bad_discussion_id'], self.user)
|
||||
self.assertEqual(metadata, {})
|
||||
assert metadata == {}
|
||||
|
||||
def test_discussion_id_accessible(self):
|
||||
self.assertTrue(utils.discussion_category_id_access(self.course, self.user, 'test_discussion_id'))
|
||||
assert utils.discussion_category_id_access(self.course, self.user, 'test_discussion_id')
|
||||
|
||||
def test_bad_discussion_id_not_accessible(self):
|
||||
self.assertFalse(utils.discussion_category_id_access(self.course, self.user, 'bad_discussion_id'))
|
||||
assert not utils.discussion_category_id_access(self.course, self.user, 'bad_discussion_id')
|
||||
|
||||
def test_missing_discussion_id_not_accessible(self):
|
||||
self.assertFalse(utils.discussion_category_id_access(self.course, self.user, 'bogus_id'))
|
||||
assert not utils.discussion_category_id_access(self.course, self.user, 'bogus_id')
|
||||
|
||||
def test_discussion_id_not_accessible_without_access(self):
|
||||
user = UserFactory.create()
|
||||
self.assertTrue(utils.discussion_category_id_access(self.course, self.user, 'private_discussion_id'))
|
||||
self.assertFalse(utils.discussion_category_id_access(self.course, user, 'private_discussion_id'))
|
||||
assert utils.discussion_category_id_access(self.course, self.user, 'private_discussion_id')
|
||||
assert not utils.discussion_category_id_access(self.course, user, 'private_discussion_id')
|
||||
|
||||
|
||||
class CategoryMapTestMixin(object):
|
||||
@@ -364,7 +352,7 @@ class CategoryMapTestMixin(object):
|
||||
"""
|
||||
actual = utils.get_discussion_category_map(self.course, requesting_user or self.user)
|
||||
actual['subcategories']['Week 1']['children'].sort()
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase):
|
||||
@@ -404,12 +392,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase):
|
||||
"""
|
||||
Asserts the expected map with the map returned by get_discussion_category_map method.
|
||||
"""
|
||||
self.assertEqual(
|
||||
utils.get_discussion_category_map(
|
||||
self.course, self.instructor, divided_only_if_explicit, exclude_unstarted
|
||||
),
|
||||
expected
|
||||
)
|
||||
assert utils.get_discussion_category_map(self.course, self.instructor, divided_only_if_explicit, exclude_unstarted) == expected
|
||||
|
||||
def test_empty(self):
|
||||
self.assert_category_map_equals({"entries": {}, "subcategories": {}, "children": []})
|
||||
@@ -680,15 +663,15 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase):
|
||||
chapter1_discussions = set(["Discussion A", "Discussion B", "Discussion A (1)", "Discussion A (2)"])
|
||||
chapter1_discussions_with_types = set([("Discussion A", TYPE_ENTRY), ("Discussion B", TYPE_ENTRY),
|
||||
("Discussion A (1)", TYPE_ENTRY), ("Discussion A (2)", TYPE_ENTRY)])
|
||||
self.assertEqual(set(chapter1["children"]), chapter1_discussions_with_types)
|
||||
self.assertEqual(set(chapter1["entries"].keys()), chapter1_discussions)
|
||||
assert set(chapter1['children']) == chapter1_discussions_with_types
|
||||
assert set(chapter1['entries'].keys()) == chapter1_discussions
|
||||
|
||||
chapter2 = category_map["subcategories"]["Chapter 2"]
|
||||
subsection1 = chapter2["subcategories"]["Section 1"]["subcategories"]["Subsection 1"]
|
||||
subsection1_discussions = set(["Discussion", "Discussion (1)"])
|
||||
subsection1_discussions_with_types = set([("Discussion", TYPE_ENTRY), ("Discussion (1)", TYPE_ENTRY)])
|
||||
self.assertEqual(set(subsection1["children"]), subsection1_discussions_with_types)
|
||||
self.assertEqual(set(subsection1["entries"].keys()), subsection1_discussions)
|
||||
assert set(subsection1['children']) == subsection1_discussions_with_types
|
||||
assert set(subsection1['entries'].keys()) == subsection1_discussions
|
||||
|
||||
def test_start_date_filter(self):
|
||||
now = datetime.datetime.now()
|
||||
@@ -699,7 +682,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase):
|
||||
self.create_discussion("Chapter 2 / Section 1 / Subsection 2", "Discussion", start=self.later)
|
||||
self.create_discussion("Chapter 3 / Section 1", "Discussion", start=self.later)
|
||||
|
||||
self.assertFalse(self.course.self_paced)
|
||||
assert not self.course.self_paced
|
||||
self.assert_category_map_equals(
|
||||
{
|
||||
"entries": {},
|
||||
@@ -742,7 +725,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase):
|
||||
self.create_discussion("Chapter 2 / Section 1 / Subsection 2", "Discussion", start=self.later)
|
||||
self.create_discussion("Chapter 3 / Section 1", "Discussion", start=self.later)
|
||||
|
||||
self.assertTrue(self.course.self_paced)
|
||||
assert self.course.self_paced
|
||||
self.assert_category_map_equals(
|
||||
{
|
||||
"entries": {},
|
||||
@@ -1012,7 +995,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase):
|
||||
)
|
||||
|
||||
def test_ids_empty(self):
|
||||
self.assertEqual(utils.get_discussion_categories_ids(self.course, self.user), [])
|
||||
assert utils.get_discussion_categories_ids(self.course, self.user) == []
|
||||
|
||||
def test_ids_configured_topics(self):
|
||||
self.course.discussion_topics = {
|
||||
@@ -1222,7 +1205,7 @@ class JsonResponseTestCase(TestCase, UnicodeTestMixin):
|
||||
def _test_unicode_data(self, text):
|
||||
response = utils.JsonResponse(text)
|
||||
reparsed = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(reparsed, text)
|
||||
assert reparsed == text
|
||||
|
||||
|
||||
class DiscussionTabTestCase(ModuleStoreTestCase):
|
||||
@@ -1244,18 +1227,18 @@ class DiscussionTabTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_tab_access(self):
|
||||
with self.settings(FEATURES={'ENABLE_DISCUSSION_SERVICE': True}):
|
||||
self.assertTrue(self.discussion_tab_present(self.staff_user))
|
||||
self.assertTrue(self.discussion_tab_present(self.enrolled_user))
|
||||
self.assertFalse(self.discussion_tab_present(self.unenrolled_user))
|
||||
assert self.discussion_tab_present(self.staff_user)
|
||||
assert self.discussion_tab_present(self.enrolled_user)
|
||||
assert not self.discussion_tab_present(self.unenrolled_user)
|
||||
|
||||
@mock.patch('lms.djangoapps.ccx.overrides.get_current_ccx')
|
||||
def test_tab_settings(self, mock_get_ccx):
|
||||
mock_get_ccx.return_value = True
|
||||
with self.settings(FEATURES={'ENABLE_DISCUSSION_SERVICE': False}):
|
||||
self.assertFalse(self.discussion_tab_present(self.enrolled_user))
|
||||
assert not self.discussion_tab_present(self.enrolled_user)
|
||||
|
||||
with self.settings(FEATURES={'CUSTOM_COURSES_EDX': True}):
|
||||
self.assertFalse(self.discussion_tab_present(self.enrolled_user))
|
||||
assert not self.discussion_tab_present(self.enrolled_user)
|
||||
|
||||
|
||||
class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
@@ -1274,35 +1257,26 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_is_commentable_divided(self):
|
||||
course = modulestore().get_course(self.toy_course_key)
|
||||
self.assertFalse(cohorts.is_course_cohorted(course.id))
|
||||
assert not cohorts.is_course_cohorted(course.id)
|
||||
|
||||
def to_id(name):
|
||||
"""Helper for topic_name_to_id that uses course."""
|
||||
return topic_name_to_id(course, name)
|
||||
|
||||
# no topics
|
||||
self.assertFalse(
|
||||
utils.is_commentable_divided(course.id, to_id("General")),
|
||||
"Course doesn't even have a 'General' topic"
|
||||
)
|
||||
assert not utils.is_commentable_divided(course.id, to_id('General')), "Course doesn't even have a 'General' topic"
|
||||
|
||||
# not cohorted
|
||||
config_course_cohorts(course, is_cohorted=False)
|
||||
config_course_discussions(course, discussion_topics=["General", "Feedback"])
|
||||
self.assertFalse(
|
||||
utils.is_commentable_divided(course.id, to_id("General")),
|
||||
"Course isn't cohorted"
|
||||
)
|
||||
assert not utils.is_commentable_divided(course.id, to_id('General')), "Course isn't cohorted"
|
||||
|
||||
# cohorted, but top level topics aren't
|
||||
config_course_cohorts(course, is_cohorted=True)
|
||||
config_course_discussions(course, discussion_topics=["General", "Feedback"])
|
||||
|
||||
self.assertTrue(cohorts.is_course_cohorted(course.id))
|
||||
self.assertFalse(
|
||||
utils.is_commentable_divided(course.id, to_id("General")),
|
||||
"Course is cohorted, but 'General' isn't."
|
||||
)
|
||||
assert cohorts.is_course_cohorted(course.id)
|
||||
assert not utils.is_commentable_divided(course.id, to_id('General')), "Course is cohorted, but 'General' isn't."
|
||||
|
||||
# cohorted, including "Feedback" top-level topics aren't
|
||||
config_course_cohorts(
|
||||
@@ -1311,19 +1285,13 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
config_course_discussions(course, discussion_topics=["General", "Feedback"], divided_discussions=["Feedback"])
|
||||
|
||||
self.assertTrue(cohorts.is_course_cohorted(course.id))
|
||||
self.assertFalse(
|
||||
utils.is_commentable_divided(course.id, to_id("General")),
|
||||
"Course is cohorted, but 'General' isn't."
|
||||
)
|
||||
self.assertTrue(
|
||||
utils.is_commentable_divided(course.id, to_id("Feedback")),
|
||||
"Feedback was listed as cohorted. Should be."
|
||||
)
|
||||
assert cohorts.is_course_cohorted(course.id)
|
||||
assert not utils.is_commentable_divided(course.id, to_id('General')), "Course is cohorted, but 'General' isn't."
|
||||
assert utils.is_commentable_divided(course.id, to_id('Feedback')), 'Feedback was listed as cohorted. Should be.'
|
||||
|
||||
def test_is_commentable_divided_inline_discussion(self):
|
||||
course = modulestore().get_course(self.toy_course_key)
|
||||
self.assertFalse(cohorts.is_course_cohorted(course.id))
|
||||
assert not cohorts.is_course_cohorted(course.id)
|
||||
|
||||
def to_id(name):
|
||||
return topic_name_to_id(course, name)
|
||||
@@ -1338,10 +1306,7 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
divided_discussions=["Feedback", "random_inline"]
|
||||
)
|
||||
|
||||
self.assertFalse(
|
||||
utils.is_commentable_divided(course.id, to_id("random")),
|
||||
"By default, Non-top-level discussions are not cohorted in a cohorted courses."
|
||||
)
|
||||
assert not utils.is_commentable_divided(course.id, to_id('random')), 'By default, Non-top-level discussions are not cohorted in a cohorted courses.'
|
||||
|
||||
# if always_divide_inline_discussions is set to False, non-top-level discussion are always
|
||||
# not divided unless they are explicitly set in divided_discussions
|
||||
@@ -1356,23 +1321,13 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
always_divide_inline_discussions=False
|
||||
)
|
||||
|
||||
self.assertFalse(
|
||||
utils.is_commentable_divided(course.id, to_id("random")),
|
||||
"Non-top-level discussion is not cohorted if always_divide_inline_discussions is False."
|
||||
)
|
||||
self.assertTrue(
|
||||
utils.is_commentable_divided(course.id, to_id("random_inline")),
|
||||
"If always_divide_inline_discussions set to False, Non-top-level discussion is "
|
||||
"cohorted if explicitly set in cohorted_discussions."
|
||||
)
|
||||
self.assertTrue(
|
||||
utils.is_commentable_divided(course.id, to_id("Feedback")),
|
||||
"If always_divide_inline_discussions set to False, top-level discussion are not affected."
|
||||
)
|
||||
assert not utils.is_commentable_divided(course.id, to_id('random')), 'Non-top-level discussion is not cohorted if always_divide_inline_discussions is False.'
|
||||
assert utils.is_commentable_divided(course.id, to_id('random_inline')), 'If always_divide_inline_discussions set to False, Non-top-level discussion is cohorted if explicitly set in cohorted_discussions.'
|
||||
assert utils.is_commentable_divided(course.id, to_id('Feedback')), 'If always_divide_inline_discussions set to False, top-level discussion are not affected.'
|
||||
|
||||
def test_is_commentable_divided_team(self):
|
||||
course = modulestore().get_course(self.toy_course_key)
|
||||
self.assertFalse(cohorts.is_course_cohorted(course.id))
|
||||
assert not cohorts.is_course_cohorted(course.id)
|
||||
|
||||
config_course_cohorts(course, is_cohorted=True)
|
||||
config_course_discussions(course, always_divide_inline_discussions=True)
|
||||
@@ -1381,8 +1336,8 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
|
||||
# Verify that team discussions are not cohorted, but other discussions are
|
||||
# if "always cohort inline discussions" is set to true.
|
||||
self.assertFalse(utils.is_commentable_divided(course.id, team.discussion_topic_id))
|
||||
self.assertTrue(utils.is_commentable_divided(course.id, "random"))
|
||||
assert not utils.is_commentable_divided(course.id, team.discussion_topic_id)
|
||||
assert utils.is_commentable_divided(course.id, 'random')
|
||||
|
||||
def test_is_commentable_divided_cohorts(self):
|
||||
course = modulestore().get_course(self.toy_course_key)
|
||||
@@ -1395,7 +1350,7 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
|
||||
# Although Cohorts are enabled, discussion division is explicitly disabled.
|
||||
self.assertFalse(utils.is_commentable_divided(course.id, "random"))
|
||||
assert not utils.is_commentable_divided(course.id, 'random')
|
||||
|
||||
# Now set the discussion division scheme.
|
||||
set_discussion_division_settings(
|
||||
@@ -1405,7 +1360,7 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
always_divide_inline_discussions=True,
|
||||
division_scheme=CourseDiscussionSettings.COHORT,
|
||||
)
|
||||
self.assertTrue(utils.is_commentable_divided(course.id, "random"))
|
||||
assert utils.is_commentable_divided(course.id, 'random')
|
||||
|
||||
def test_is_commentable_divided_enrollment_track(self):
|
||||
course = modulestore().get_course(self.toy_course_key)
|
||||
@@ -1418,12 +1373,12 @@ class IsCommentableDividedTestCase(ModuleStoreTestCase):
|
||||
|
||||
# Although division scheme is set to ENROLLMENT_TRACK, divided returns
|
||||
# False because there is only a single enrollment mode.
|
||||
self.assertFalse(utils.is_commentable_divided(course.id, "random"))
|
||||
assert not utils.is_commentable_divided(course.id, 'random')
|
||||
|
||||
# Now create 2 explicit course modes.
|
||||
CourseModeFactory.create(course_id=course.id, mode_slug=CourseMode.AUDIT)
|
||||
CourseModeFactory.create(course_id=course.id, mode_slug=CourseMode.VERIFIED)
|
||||
self.assertTrue(utils.is_commentable_divided(course.id, "random"))
|
||||
assert utils.is_commentable_divided(course.id, 'random')
|
||||
|
||||
|
||||
class GroupIdForUserTestCase(ModuleStoreTestCase):
|
||||
@@ -1446,30 +1401,24 @@ class GroupIdForUserTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_discussion_division_disabled(self):
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertEqual(CourseDiscussionSettings.NONE, course_discussion_settings.division_scheme)
|
||||
self.assertIsNone(utils.get_group_id_for_user(self.test_user, course_discussion_settings))
|
||||
assert CourseDiscussionSettings.NONE == course_discussion_settings.division_scheme
|
||||
assert utils.get_group_id_for_user(self.test_user, course_discussion_settings) is None
|
||||
|
||||
def test_discussion_division_by_cohort(self):
|
||||
set_discussion_division_settings(
|
||||
self.course.id, enable_cohorts=True, division_scheme=CourseDiscussionSettings.COHORT
|
||||
)
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertEqual(CourseDiscussionSettings.COHORT, course_discussion_settings.division_scheme)
|
||||
self.assertEqual(
|
||||
self.test_cohort.id,
|
||||
utils.get_group_id_for_user(self.test_user, course_discussion_settings)
|
||||
)
|
||||
assert CourseDiscussionSettings.COHORT == course_discussion_settings.division_scheme
|
||||
assert self.test_cohort.id == utils.get_group_id_for_user(self.test_user, course_discussion_settings)
|
||||
|
||||
def test_discussion_division_by_enrollment_track(self):
|
||||
set_discussion_division_settings(
|
||||
self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK
|
||||
)
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertEqual(CourseDiscussionSettings.ENROLLMENT_TRACK, course_discussion_settings.division_scheme)
|
||||
self.assertEqual(
|
||||
-2, # Verified has group ID 2, and we negate that value to ensure unique IDs
|
||||
utils.get_group_id_for_user(self.test_user, course_discussion_settings)
|
||||
)
|
||||
assert CourseDiscussionSettings.ENROLLMENT_TRACK == course_discussion_settings.division_scheme
|
||||
assert (- 2) == utils.get_group_id_for_user(self.test_user, course_discussion_settings)
|
||||
|
||||
|
||||
class CourseDiscussionDivisionEnabledTestCase(ModuleStoreTestCase):
|
||||
@@ -1487,35 +1436,35 @@ class CourseDiscussionDivisionEnabledTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_discussion_division_disabled(self):
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertFalse(utils.course_discussion_division_enabled(course_discussion_settings))
|
||||
self.assertEqual([], utils.available_division_schemes(self.course.id))
|
||||
assert not utils.course_discussion_division_enabled(course_discussion_settings)
|
||||
assert [] == utils.available_division_schemes(self.course.id)
|
||||
|
||||
def test_discussion_division_by_cohort(self):
|
||||
set_discussion_division_settings(
|
||||
self.course.id, enable_cohorts=False, division_scheme=CourseDiscussionSettings.COHORT
|
||||
)
|
||||
# Because cohorts are disabled, discussion division is not enabled.
|
||||
self.assertFalse(utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id)))
|
||||
self.assertEqual([], utils.available_division_schemes(self.course.id))
|
||||
assert not utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
|
||||
assert [] == utils.available_division_schemes(self.course.id)
|
||||
# Now enable cohorts, which will cause discussions to be divided.
|
||||
set_discussion_division_settings(
|
||||
self.course.id, enable_cohorts=True, division_scheme=CourseDiscussionSettings.COHORT
|
||||
)
|
||||
self.assertTrue(utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id)))
|
||||
self.assertEqual([CourseDiscussionSettings.COHORT], utils.available_division_schemes(self.course.id))
|
||||
assert utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
|
||||
assert [CourseDiscussionSettings.COHORT] == utils.available_division_schemes(self.course.id)
|
||||
|
||||
def test_discussion_division_by_enrollment_track(self):
|
||||
set_discussion_division_settings(
|
||||
self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK
|
||||
)
|
||||
# Only a single enrollment track exists, so discussion division is not enabled.
|
||||
self.assertFalse(utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id)))
|
||||
self.assertEqual([], utils.available_division_schemes(self.course.id))
|
||||
assert not utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
|
||||
assert [] == utils.available_division_schemes(self.course.id)
|
||||
|
||||
# Now create a second CourseMode, which will cause discussions to be divided.
|
||||
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.VERIFIED)
|
||||
self.assertTrue(utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id)))
|
||||
self.assertEqual([CourseDiscussionSettings.ENROLLMENT_TRACK], utils.available_division_schemes(self.course.id))
|
||||
assert utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
|
||||
assert [CourseDiscussionSettings.ENROLLMENT_TRACK] == utils.available_division_schemes(self.course.id)
|
||||
|
||||
|
||||
class GroupNameTestCase(ModuleStoreTestCase):
|
||||
@@ -1539,51 +1488,29 @@ class GroupNameTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_discussion_division_disabled(self):
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertEqual({}, utils.get_group_names_by_id(course_discussion_settings))
|
||||
self.assertIsNone(utils.get_group_name(-1000, course_discussion_settings))
|
||||
assert {} == utils.get_group_names_by_id(course_discussion_settings)
|
||||
assert utils.get_group_name((- 1000), course_discussion_settings) is None
|
||||
|
||||
def test_discussion_division_by_cohort(self):
|
||||
set_discussion_division_settings(
|
||||
self.course.id, enable_cohorts=True, division_scheme=CourseDiscussionSettings.COHORT
|
||||
)
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertEqual(
|
||||
{
|
||||
self.test_cohort_1.id: self.test_cohort_1.name,
|
||||
self.test_cohort_2.id: self.test_cohort_2.name
|
||||
},
|
||||
utils.get_group_names_by_id(course_discussion_settings)
|
||||
)
|
||||
self.assertEqual(
|
||||
self.test_cohort_2.name,
|
||||
utils.get_group_name(self.test_cohort_2.id, course_discussion_settings)
|
||||
)
|
||||
assert {self.test_cohort_1.id: self.test_cohort_1.name, self.test_cohort_2.id: self.test_cohort_2.name} == utils.get_group_names_by_id(course_discussion_settings)
|
||||
assert self.test_cohort_2.name == utils.get_group_name(self.test_cohort_2.id, course_discussion_settings)
|
||||
# Test also with a group_id that doesn't exist.
|
||||
self.assertIsNone(
|
||||
utils.get_group_name(-1000, course_discussion_settings)
|
||||
)
|
||||
assert utils.get_group_name((- 1000), course_discussion_settings) is None
|
||||
|
||||
def test_discussion_division_by_enrollment_track(self):
|
||||
set_discussion_division_settings(
|
||||
self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK
|
||||
)
|
||||
course_discussion_settings = get_course_discussion_settings(self.course.id)
|
||||
self.assertEqual(
|
||||
{
|
||||
-1: "audit course",
|
||||
-2: "verified course"
|
||||
},
|
||||
utils.get_group_names_by_id(course_discussion_settings)
|
||||
)
|
||||
assert {(- 1): 'audit course', (- 2): 'verified course'} == utils.get_group_names_by_id(course_discussion_settings)
|
||||
|
||||
self.assertEqual(
|
||||
"verified course",
|
||||
utils.get_group_name(-2, course_discussion_settings)
|
||||
)
|
||||
assert 'verified course' == utils.get_group_name((- 2), course_discussion_settings)
|
||||
# Test also with a group_id that doesn't exist.
|
||||
self.assertIsNone(
|
||||
utils.get_group_name(-1000, course_discussion_settings)
|
||||
)
|
||||
assert utils.get_group_name((- 1000), course_discussion_settings) is None
|
||||
|
||||
|
||||
class PermissionsTestCase(ModuleStoreTestCase):
|
||||
@@ -1601,24 +1528,10 @@ class PermissionsTestCase(ModuleStoreTestCase):
|
||||
'lms.djangoapps.discussion.django_comment_client.utils.check_permissions_by_view'
|
||||
) as check_perm:
|
||||
check_perm.return_value = True
|
||||
self.assertEqual(utils.get_ability(None, content, user), {
|
||||
'editable': True,
|
||||
'can_reply': True,
|
||||
'can_delete': True,
|
||||
'can_openclose': True,
|
||||
'can_vote': False,
|
||||
'can_report': False
|
||||
})
|
||||
assert utils.get_ability(None, content, user) == {'editable': True, 'can_reply': True, 'can_delete': True, 'can_openclose': True, 'can_vote': False, 'can_report': False}
|
||||
|
||||
content['user_id'] = '2'
|
||||
self.assertEqual(utils.get_ability(None, content, user), {
|
||||
'editable': True,
|
||||
'can_reply': True,
|
||||
'can_delete': True,
|
||||
'can_openclose': True,
|
||||
'can_vote': True,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(None, content, user) == {'editable': True, 'can_reply': True, 'can_delete': True, 'can_openclose': True, 'can_vote': True, 'can_report': True}
|
||||
|
||||
def test_get_ability_with_global_staff(self):
|
||||
"""
|
||||
@@ -1633,14 +1546,7 @@ class PermissionsTestCase(ModuleStoreTestCase):
|
||||
# check_permissions_by_view returns false because user is not enrolled in the course.
|
||||
check_perm.return_value = False
|
||||
global_staff = UserFactory(username='global_staff', email='global_staff@edx.org', is_staff=True)
|
||||
self.assertEqual(utils.get_ability(None, content, global_staff), {
|
||||
'editable': False,
|
||||
'can_reply': False,
|
||||
'can_delete': False,
|
||||
'can_openclose': False,
|
||||
'can_vote': False,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(None, content, global_staff) == {'editable': False, 'can_reply': False, 'can_delete': False, 'can_openclose': False, 'can_vote': False, 'can_report': True}
|
||||
|
||||
def test_is_content_authored_by(self):
|
||||
content = {}
|
||||
@@ -1649,23 +1555,23 @@ class PermissionsTestCase(ModuleStoreTestCase):
|
||||
|
||||
# strict equality checking
|
||||
content['user_id'] = 1
|
||||
self.assertTrue(utils.is_content_authored_by(content, user))
|
||||
assert utils.is_content_authored_by(content, user)
|
||||
|
||||
# cast from string to int
|
||||
content['user_id'] = '1'
|
||||
self.assertTrue(utils.is_content_authored_by(content, user))
|
||||
assert utils.is_content_authored_by(content, user)
|
||||
|
||||
# strict equality checking, fails
|
||||
content['user_id'] = 2
|
||||
self.assertFalse(utils.is_content_authored_by(content, user))
|
||||
assert not utils.is_content_authored_by(content, user)
|
||||
|
||||
# cast from string to int, fails
|
||||
content['user_id'] = 'string'
|
||||
self.assertFalse(utils.is_content_authored_by(content, user))
|
||||
assert not utils.is_content_authored_by(content, user)
|
||||
|
||||
# content has no known author
|
||||
del content['user_id']
|
||||
self.assertFalse(utils.is_content_authored_by(content, user))
|
||||
assert not utils.is_content_authored_by(content, user)
|
||||
|
||||
|
||||
class GroupModeratorPermissionsTestCase(ModuleStoreTestCase):
|
||||
@@ -1733,32 +1639,11 @@ class GroupModeratorPermissionsTestCase(ModuleStoreTestCase):
|
||||
Group moderator should not have moderator permissions if the discussions are not divided.
|
||||
"""
|
||||
content = {'user_id': self.plain_user.id, 'type': 'thread', 'username': self.plain_user.username}
|
||||
self.assertEqual(utils.get_ability(self.course.id, content, self.group_moderator), {
|
||||
'editable': False,
|
||||
'can_reply': True,
|
||||
'can_delete': False,
|
||||
'can_openclose': False,
|
||||
'can_vote': True,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(self.course.id, content, self.group_moderator) == {'editable': False, 'can_reply': True, 'can_delete': False, 'can_openclose': False, 'can_vote': True, 'can_report': True}
|
||||
content = {'user_id': self.cohorted_user.id, 'type': 'thread'}
|
||||
self.assertEqual(utils.get_ability(self.course.id, content, self.group_moderator), {
|
||||
'editable': False,
|
||||
'can_reply': True,
|
||||
'can_delete': False,
|
||||
'can_openclose': False,
|
||||
'can_vote': True,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(self.course.id, content, self.group_moderator) == {'editable': False, 'can_reply': True, 'can_delete': False, 'can_openclose': False, 'can_vote': True, 'can_report': True}
|
||||
content = {'user_id': self.verified_user.id, 'type': 'thread'}
|
||||
self.assertEqual(utils.get_ability(self.course.id, content, self.group_moderator), {
|
||||
'editable': False,
|
||||
'can_reply': True,
|
||||
'can_delete': False,
|
||||
'can_openclose': False,
|
||||
'can_vote': True,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(self.course.id, content, self.group_moderator) == {'editable': False, 'can_reply': True, 'can_delete': False, 'can_openclose': False, 'can_vote': True, 'can_report': True}
|
||||
|
||||
@mock.patch(
|
||||
'lms.djangoapps.discussion.django_comment_client.permissions._check_condition',
|
||||
@@ -1771,14 +1656,7 @@ class GroupModeratorPermissionsTestCase(ModuleStoreTestCase):
|
||||
set_discussion_division_settings(self.course.id, enable_cohorts=True,
|
||||
division_scheme=CourseDiscussionSettings.COHORT)
|
||||
content = {'user_id': self.cohorted_user.id, 'type': 'thread', 'username': self.cohorted_user.username}
|
||||
self.assertEqual(utils.get_ability(self.course.id, content, self.group_moderator), {
|
||||
'editable': True,
|
||||
'can_reply': True,
|
||||
'can_delete': True,
|
||||
'can_openclose': True,
|
||||
'can_vote': True,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(self.course.id, content, self.group_moderator) == {'editable': True, 'can_reply': True, 'can_delete': True, 'can_openclose': True, 'can_vote': True, 'can_report': True}
|
||||
|
||||
@mock.patch(
|
||||
'lms.djangoapps.discussion.django_comment_client.permissions._check_condition',
|
||||
@@ -1791,14 +1669,7 @@ class GroupModeratorPermissionsTestCase(ModuleStoreTestCase):
|
||||
content = {'user_id': self.plain_user.id, 'type': 'thread', 'username': self.plain_user.username}
|
||||
set_discussion_division_settings(self.course.id, division_scheme=CourseDiscussionSettings.NONE)
|
||||
|
||||
self.assertEqual(utils.get_ability(self.course.id, content, self.group_moderator), {
|
||||
'editable': False,
|
||||
'can_reply': True,
|
||||
'can_delete': False,
|
||||
'can_openclose': False,
|
||||
'can_vote': True,
|
||||
'can_report': True
|
||||
})
|
||||
assert utils.get_ability(self.course.id, content, self.group_moderator) == {'editable': False, 'can_reply': True, 'can_delete': False, 'can_openclose': False, 'can_vote': True, 'can_report': True}
|
||||
|
||||
|
||||
class ClientConfigurationTestCase(TestCase):
|
||||
@@ -1810,7 +1681,7 @@ class ClientConfigurationTestCase(TestCase):
|
||||
config.enabled = False
|
||||
config.save()
|
||||
|
||||
with self.assertRaises(CommentClientMaintenanceError):
|
||||
with pytest.raises(CommentClientMaintenanceError):
|
||||
perform_request('GET', 'http://www.google.com')
|
||||
|
||||
@patch('requests.request')
|
||||
@@ -1827,7 +1698,7 @@ class ClientConfigurationTestCase(TestCase):
|
||||
mock_request.return_value = response
|
||||
|
||||
result = perform_request('GET', 'http://www.google.com')
|
||||
self.assertEqual(result, {})
|
||||
assert result == {}
|
||||
|
||||
|
||||
def set_discussion_division_settings(
|
||||
@@ -1865,10 +1736,10 @@ class MiscUtilsTests(TestCase):
|
||||
thread_data = {'id': content_id, 'course_id': course_id, 'commentable_id': discussion_id, 'type': 'thread'}
|
||||
expected_url = reverse('single_thread', kwargs=url_kwargs)
|
||||
|
||||
self.assertEqual(utils.permalink(thread_data), expected_url)
|
||||
assert utils.permalink(thread_data) == expected_url
|
||||
|
||||
thread_data['course_id'] = CourseKey.from_string(course_id)
|
||||
self.assertEqual(utils.permalink(thread_data), expected_url)
|
||||
assert utils.permalink(thread_data) == expected_url
|
||||
|
||||
@ddt.data(
|
||||
('course-v1:edX+foo101+bar_t2', '99', '99'),
|
||||
@@ -1887,7 +1758,7 @@ class MiscUtilsTests(TestCase):
|
||||
}
|
||||
expected_url = reverse('single_thread', kwargs=url_kwargs) + '#' + thread_data['id']
|
||||
|
||||
self.assertEqual(utils.permalink(thread_data), expected_url)
|
||||
assert utils.permalink(thread_data) == expected_url
|
||||
|
||||
thread_data['course_id'] = CourseKey.from_string(course_id)
|
||||
self.assertEqual(utils.permalink(thread_data), expected_url)
|
||||
assert utils.permalink(thread_data) == expected_url
|
||||
|
||||
@@ -58,17 +58,16 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
def assertPrefValid(self, user):
|
||||
"""Ensure that the correct preference for the user is persisted"""
|
||||
pref = UserPreference.objects.get(user=user, key=NOTIFICATION_PREF_KEY)
|
||||
self.assertTrue(pref) # check exists and only 1 (.get)
|
||||
assert pref
|
||||
# check exists and only 1 (.get)
|
||||
# now coerce username to utf-8 encoded str, since we test with non-ascii unicdoe above and
|
||||
# the unittest framework has hard time coercing to unicode.
|
||||
# decrypt also can't take a unicode input, so coerce its input to str
|
||||
self.assertEqual(six.binary_type(user.username.encode('utf-8')), UsernameCipher().decrypt(str(pref.value)))
|
||||
assert six.binary_type(user.username.encode('utf-8')) == UsernameCipher().decrypt(str(pref.value))
|
||||
|
||||
def assertNotPrefExists(self, user):
|
||||
"""Ensure that the user does not have a persisted preference"""
|
||||
self.assertFalse(
|
||||
UserPreference.objects.filter(user=user, key=NOTIFICATION_PREF_KEY).exists()
|
||||
)
|
||||
assert not UserPreference.objects.filter(user=user, key=NOTIFICATION_PREF_KEY).exists()
|
||||
|
||||
# AJAX status view
|
||||
|
||||
@@ -76,22 +75,22 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
request = self.request_factory.get("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_status(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8')), {"status": 0})
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8')) == {'status': 0}
|
||||
|
||||
def test_ajax_status_get_1(self):
|
||||
self.create_prefs()
|
||||
request = self.request_factory.get("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_status(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8')), {"status": 1})
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8')) == {'status': 1}
|
||||
|
||||
def test_ajax_status_post(self):
|
||||
request = self.request_factory.post("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_status(request)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
|
||||
def test_ajax_status_anon_user(self):
|
||||
request = self.request_factory.get("dummy")
|
||||
@@ -104,7 +103,7 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
request = self.request_factory.get("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_enable(request)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
self.assertNotPrefExists(self.user)
|
||||
|
||||
def test_ajax_enable_anon_user(self):
|
||||
@@ -121,7 +120,7 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
request = self.request_factory.post("dummy")
|
||||
request.user = user
|
||||
response = ajax_enable(request)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
assert response.status_code == 204
|
||||
self.assertPrefValid(user)
|
||||
|
||||
for user in self.tokens.keys():
|
||||
@@ -132,7 +131,7 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
request = self.request_factory.post("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_enable(request)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
assert response.status_code == 204
|
||||
self.assertPrefValid(self.user)
|
||||
|
||||
def test_ajax_enable_distinct_values(self):
|
||||
@@ -142,10 +141,11 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
other_user = UserFactory.create()
|
||||
request.user = other_user
|
||||
ajax_enable(request)
|
||||
self.assertNotEqual(
|
||||
UserPreference.objects.get(user=self.user, key=NOTIFICATION_PREF_KEY).value,
|
||||
UserPreference.objects.get(user=other_user, key=NOTIFICATION_PREF_KEY).value
|
||||
)
|
||||
assert UserPreference.objects.get(
|
||||
user=self.user, key=NOTIFICATION_PREF_KEY
|
||||
).value != UserPreference.objects.get(
|
||||
user=other_user, key=NOTIFICATION_PREF_KEY
|
||||
).value
|
||||
|
||||
# AJAX disable view
|
||||
|
||||
@@ -154,7 +154,7 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
request = self.request_factory.get("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_disable(request)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
self.assertPrefValid(self.user)
|
||||
|
||||
def test_ajax_disable_anon_user(self):
|
||||
@@ -169,14 +169,14 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
request = self.request_factory.post("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_disable(request)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
assert response.status_code == 204
|
||||
self.assertNotPrefExists(self.user)
|
||||
|
||||
def test_ajax_disable_already_disabled(self):
|
||||
request = self.request_factory.post("dummy")
|
||||
request.user = self.user
|
||||
response = ajax_disable(request)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
assert response.status_code == 204
|
||||
self.assertNotPrefExists(self.user)
|
||||
|
||||
# Unsubscribe view
|
||||
@@ -184,7 +184,7 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
def test_unsubscribe_post(self):
|
||||
request = self.request_factory.post("dummy")
|
||||
response = set_subscription(request, "dummy", subscribe=False)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
|
||||
def test_unsubscribe_invalid_token(self):
|
||||
def test_invalid_token(token, message):
|
||||
@@ -225,7 +225,7 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
url = reverse('unsubscribe_forum_update', args=[self.tokens[user]])
|
||||
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
self.assertNotPrefExists(user)
|
||||
|
||||
for user in self.tokens.keys():
|
||||
@@ -237,16 +237,16 @@ class NotificationPrefViewTest(UrlResetMixin, TestCase): # lint-amnesty, pylint
|
||||
url = reverse('unsubscribe_forum_update', args=[self.tokens[self.user]])
|
||||
self.client.get(url)
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
self.assertNotPrefExists(self.user)
|
||||
|
||||
def test_resubscribe_success(self):
|
||||
def test_user(user):
|
||||
# start without a pref key
|
||||
self.assertFalse(UserPreference.objects.filter(user=user, key=NOTIFICATION_PREF_KEY))
|
||||
assert not UserPreference.objects.filter(user=user, key=NOTIFICATION_PREF_KEY)
|
||||
url = reverse('resubscribe_forum_update', args=[self.tokens[user]])
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
self.assertPrefValid(user)
|
||||
|
||||
for user in self.tokens.keys():
|
||||
|
||||
@@ -5,7 +5,7 @@ Tests for Discussion API internal interface
|
||||
|
||||
import itertools
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pytest
|
||||
import ddt
|
||||
import httpretty
|
||||
import mock
|
||||
@@ -153,32 +153,28 @@ class GetCourseTest(ForumsEnableMixin, UrlResetMixin, SharedModuleStoreTestCase)
|
||||
self.request.user = self.user
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
get_course(self.request, CourseLocator.from_string("non/existent/course"))
|
||||
|
||||
def test_not_enrolled(self):
|
||||
unenrolled_user = UserFactory.create()
|
||||
self.request.user = unenrolled_user
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
get_course(self.request, self.course.id)
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
get_course(self.request, _discussion_disabled_course_for(self.user).id)
|
||||
|
||||
def test_basic(self):
|
||||
self.assertEqual(
|
||||
get_course(self.request, self.course.id),
|
||||
{
|
||||
"id": six.text_type(self.course.id),
|
||||
"blackouts": [],
|
||||
"thread_list_url": "http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz",
|
||||
"following_thread_list_url": (
|
||||
"http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz&following=True"
|
||||
),
|
||||
"topics_url": "http://testserver/api/discussion/v1/course_topics/x/y/z",
|
||||
}
|
||||
)
|
||||
assert get_course(self.request, self.course.id) == {
|
||||
'id': six.text_type(self.course.id),
|
||||
'blackouts': [],
|
||||
'thread_list_url': 'http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz',
|
||||
'following_thread_list_url':
|
||||
'http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz&following=True',
|
||||
'topics_url': 'http://testserver/api/discussion/v1/course_topics/x/y/z'
|
||||
}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -205,13 +201,10 @@ class GetCourseTestBlackouts(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCa
|
||||
]
|
||||
modulestore().update_item(self.course, self.user.id)
|
||||
result = get_course(self.request, self.course.id)
|
||||
self.assertEqual(
|
||||
result["blackouts"],
|
||||
[
|
||||
{"start": "2015-06-09T00:00:00Z", "end": "2015-06-10T00:00:00Z"},
|
||||
{"start": "2015-06-11T00:00:00Z", "end": "2015-06-12T00:00:00Z"},
|
||||
]
|
||||
)
|
||||
assert result['blackouts'] == [
|
||||
{'start': '2015-06-09T00:00:00Z', 'end': '2015-06-10T00:00:00Z'},
|
||||
{'start': '2015-06-11T00:00:00Z', 'end': '2015-06-12T00:00:00Z'}
|
||||
]
|
||||
|
||||
@ddt.data(None, "not a datetime", "2015", [])
|
||||
def test_blackout_errors(self, bad_value):
|
||||
@@ -221,7 +214,7 @@ class GetCourseTestBlackouts(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCa
|
||||
]
|
||||
modulestore().update_item(self.course, self.user.id)
|
||||
result = get_course(self.request, self.course.id)
|
||||
self.assertEqual(result["blackouts"], [])
|
||||
assert result['blackouts'] == []
|
||||
|
||||
|
||||
@mock.patch.dict("django.conf.settings.FEATURES", {"DISABLE_START_DATES": False})
|
||||
@@ -300,18 +293,18 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
return node
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
get_course_topics(self.request, CourseLocator.from_string("non/existent/course"))
|
||||
|
||||
def test_not_enrolled(self):
|
||||
unenrolled_user = UserFactory.create()
|
||||
self.request.user = unenrolled_user
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
self.get_course_topics()
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
_remove_discussion_tab(self.course, self.user.id)
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
self.get_course_topics()
|
||||
|
||||
def test_without_courseware(self):
|
||||
@@ -322,7 +315,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-topic-id", "Test Topic")
|
||||
],
|
||||
}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
def test_with_courseware(self):
|
||||
self.make_discussion_xblock("courseware-topic-id", "Foo", "Bar")
|
||||
@@ -339,7 +332,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-topic-id", "Test Topic")
|
||||
],
|
||||
}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
def test_many(self):
|
||||
with self.store.bulk_operations(self.course.id, emit_signals=False):
|
||||
@@ -383,7 +376,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-2", "B"),
|
||||
],
|
||||
}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
def test_sort_key(self):
|
||||
with self.store.bulk_operations(self.course.id, emit_signals=False):
|
||||
@@ -432,7 +425,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-1", "W"),
|
||||
],
|
||||
}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
def test_access_control(self):
|
||||
"""
|
||||
@@ -499,7 +492,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-topic-id", "Test Topic"),
|
||||
],
|
||||
}
|
||||
self.assertEqual(student_actual, student_expected)
|
||||
assert student_actual == student_expected
|
||||
self.request.user = beta_tester
|
||||
beta_actual = self.get_course_topics()
|
||||
beta_expected = {
|
||||
@@ -522,7 +515,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-topic-id", "Test Topic"),
|
||||
],
|
||||
}
|
||||
self.assertEqual(beta_actual, beta_expected)
|
||||
assert beta_actual == beta_expected
|
||||
|
||||
self.request.user = staff
|
||||
staff_actual = self.get_course_topics()
|
||||
@@ -550,7 +543,7 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_expected_tree("non-courseware-topic-id", "Test Topic"),
|
||||
],
|
||||
}
|
||||
self.assertEqual(staff_actual, staff_expected)
|
||||
assert staff_actual == staff_expected
|
||||
|
||||
def test_discussion_topic(self):
|
||||
"""
|
||||
@@ -561,41 +554,35 @@ class GetCourseTopicsTest(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
self.make_discussion_xblock(topic_id_1, "test_category_1", "test_target_1")
|
||||
self.make_discussion_xblock(topic_id_2, "test_category_2", "test_target_2")
|
||||
actual = get_course_topics(self.request, self.course.id, {"topic_id_1", "topic_id_2"})
|
||||
self.assertEqual(
|
||||
actual,
|
||||
{
|
||||
"non_courseware_topics": [],
|
||||
"courseware_topics": [
|
||||
{
|
||||
"children": [{
|
||||
"children": [],
|
||||
"id": "topic_id_1",
|
||||
"thread_list_url": "http://testserver/api/discussion/v1/threads/?"
|
||||
"course_id=x%2Fy%2Fz&topic_id=topic_id_1",
|
||||
"name": "test_target_1"
|
||||
}],
|
||||
"id": None,
|
||||
"thread_list_url": "http://testserver/api/discussion/v1/threads/?"
|
||||
"course_id=x%2Fy%2Fz&topic_id=topic_id_1",
|
||||
"name": "test_category_1"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[{
|
||||
"children": [],
|
||||
"id": "topic_id_2",
|
||||
"thread_list_url": "http://testserver/api/discussion/v1/threads/?"
|
||||
"course_id=x%2Fy%2Fz&topic_id=topic_id_2",
|
||||
"name": "test_target_2"
|
||||
}],
|
||||
"id": None,
|
||||
"thread_list_url": "http://testserver/api/discussion/v1/threads/?"
|
||||
"course_id=x%2Fy%2Fz&topic_id=topic_id_2",
|
||||
"name": "test_category_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert actual == {
|
||||
'non_courseware_topics': [],
|
||||
'courseware_topics': [
|
||||
{'children': [
|
||||
{'children': [],
|
||||
'id': 'topic_id_1',
|
||||
'thread_list_url':
|
||||
'http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz&topic_id=topic_id_1',
|
||||
'name': 'test_target_1'}
|
||||
],
|
||||
'id': None,
|
||||
'thread_list_url':
|
||||
'http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz&topic_id=topic_id_1',
|
||||
'name': 'test_category_1'
|
||||
},
|
||||
{'children': [
|
||||
{'children': [],
|
||||
'id': 'topic_id_2',
|
||||
'thread_list_url':
|
||||
'http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz&topic_id=topic_id_2',
|
||||
'name': 'test_target_2'}
|
||||
],
|
||||
'id': None,
|
||||
'thread_list_url':
|
||||
'http://testserver/api/discussion/v1/threads/?course_id=x%2Fy%2Fz&topic_id=topic_id_2',
|
||||
'name': 'test_category_2'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -645,36 +632,35 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
return ret
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
get_thread_list(self.request, CourseLocator.from_string("non/existent/course"), 1, 1)
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
self.get_thread_list([])
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
self.get_thread_list([], course=_discussion_disabled_course_for(self.user))
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(
|
||||
self.get_thread_list([], num_pages=0).data,
|
||||
{
|
||||
"pagination": {
|
||||
"next": None,
|
||||
"previous": None,
|
||||
"num_pages": 0,
|
||||
"count": 0
|
||||
},
|
||||
"results": [],
|
||||
"text_search_rewrite": None,
|
||||
}
|
||||
)
|
||||
assert self.get_thread_list(
|
||||
[], num_pages=0
|
||||
).data == {
|
||||
'pagination': {
|
||||
'next': None,
|
||||
'previous': None,
|
||||
'num_pages': 0,
|
||||
'count': 0
|
||||
},
|
||||
'results': [],
|
||||
'text_search_rewrite': None
|
||||
}
|
||||
|
||||
def test_get_threads_by_topic_id(self):
|
||||
self.get_thread_list([], topic_id_list=["topic_x", "topic_meow"])
|
||||
self.assertEqual(urlparse(httpretty.last_request().path).path, "/api/v1/threads") # lint-amnesty, pylint: disable=no-member
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads' # lint-amnesty, pylint: disable=no-member
|
||||
self.assert_last_query_params({
|
||||
"user_id": [six.text_type(self.user.id)],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
@@ -774,10 +760,7 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
results=expected_threads, count=2, num_pages=1, next_link=None, previous_link=None
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(
|
||||
self.get_thread_list(source_threads).data,
|
||||
expected_result
|
||||
)
|
||||
assert self.get_thread_list(source_threads).data == expected_result
|
||||
|
||||
@ddt.data(
|
||||
*itertools.product(
|
||||
@@ -799,7 +782,7 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
self.get_thread_list([], course=cohort_course)
|
||||
actual_has_group = "group_id" in httpretty.last_request().querystring # lint-amnesty, pylint: disable=no-member
|
||||
expected_has_group = (course_is_cohorted and role_name == FORUM_ROLE_STUDENT)
|
||||
self.assertEqual(actual_has_group, expected_has_group)
|
||||
assert actual_has_group == expected_has_group
|
||||
|
||||
def test_pagination(self):
|
||||
# N.B. Empty thread list is not realistic but convenient for this test
|
||||
@@ -807,10 +790,7 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
results=[], count=0, num_pages=3, next_link="http://testserver/test_path?page=2", previous_link=None
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(
|
||||
self.get_thread_list([], page=1, num_pages=3).data,
|
||||
expected_result
|
||||
)
|
||||
assert self.get_thread_list([], page=1, num_pages=3).data == expected_result
|
||||
|
||||
expected_result = make_paginated_api_response(
|
||||
results=[],
|
||||
@@ -820,23 +800,17 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
previous_link="http://testserver/test_path?page=1"
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(
|
||||
self.get_thread_list([], page=2, num_pages=3).data,
|
||||
expected_result
|
||||
)
|
||||
assert self.get_thread_list([], page=2, num_pages=3).data == expected_result
|
||||
|
||||
expected_result = make_paginated_api_response(
|
||||
results=[], count=0, num_pages=3, next_link=None, previous_link="http://testserver/test_path?page=2"
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(
|
||||
self.get_thread_list([], page=3, num_pages=3).data,
|
||||
expected_result
|
||||
)
|
||||
assert self.get_thread_list([], page=3, num_pages=3).data == expected_result
|
||||
|
||||
# Test page past the last one
|
||||
self.register_get_threads_response([], page=3, num_pages=3)
|
||||
with self.assertRaises(PageNotFoundError):
|
||||
with pytest.raises(PageNotFoundError):
|
||||
get_thread_list(self.request, self.course.id, page=4, page_size=10)
|
||||
|
||||
@ddt.data(None, "rewritten search string")
|
||||
@@ -846,16 +820,13 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": text_search_rewrite})
|
||||
self.register_get_threads_search_response([], text_search_rewrite, num_pages=0)
|
||||
self.assertEqual(
|
||||
get_thread_list(
|
||||
self.request,
|
||||
self.course.id,
|
||||
page=1,
|
||||
page_size=10,
|
||||
text_search="test search string"
|
||||
).data,
|
||||
expected_result
|
||||
)
|
||||
assert get_thread_list(
|
||||
self.request,
|
||||
self.course.id,
|
||||
page=1,
|
||||
page_size=10,
|
||||
text_search='test search string'
|
||||
).data == expected_result
|
||||
self.assert_last_query_params({
|
||||
"user_id": [six.text_type(self.user.id)],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
@@ -879,14 +850,10 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
results=[], count=0, num_pages=0, next_link=None, previous_link=None
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(
|
||||
result,
|
||||
expected_result
|
||||
)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/users/{}/subscribed_threads".format(self.user.id)
|
||||
)
|
||||
assert result == expected_result
|
||||
assert urlparse(
|
||||
httpretty.last_request().path # lint-amnesty, pylint: disable=no-member
|
||||
).path == '/api/v1/users/{}/subscribed_threads'.format(self.user.id)
|
||||
self.assert_last_query_params({
|
||||
"user_id": [six.text_type(self.user.id)],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
@@ -910,14 +877,8 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
results=[], count=0, num_pages=0, next_link=None, previous_link=None
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(
|
||||
result,
|
||||
expected_result
|
||||
)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/threads"
|
||||
)
|
||||
assert result == expected_result
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads' # lint-amnesty, pylint: disable=no-member
|
||||
self.assert_last_query_params({
|
||||
"user_id": [six.text_type(self.user.id)],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
@@ -954,11 +915,8 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
results=[], count=0, num_pages=0, next_link=None, previous_link=None
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(result, expected_result)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/threads"
|
||||
)
|
||||
assert result == expected_result
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads' # lint-amnesty, pylint: disable=no-member
|
||||
self.assert_last_query_params({
|
||||
"user_id": [six.text_type(self.user.id)],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
@@ -985,11 +943,8 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
results=[], count=0, num_pages=0, next_link=None, previous_link=None
|
||||
)
|
||||
expected_result.update({"text_search_rewrite": None})
|
||||
self.assertEqual(result, expected_result)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/threads"
|
||||
)
|
||||
assert result == expected_result
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads' # lint-amnesty, pylint: disable=no-member
|
||||
self.assert_last_query_params({
|
||||
"user_id": [six.text_type(self.user.id)],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
@@ -1002,7 +957,7 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
"""
|
||||
Test with invalid order_direction (e.g. "asc")
|
||||
"""
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
self.register_get_threads_response([], page=1, num_pages=0)
|
||||
get_thread_list( # pylint: disable=expression-not-assigned
|
||||
self.request,
|
||||
@@ -1011,7 +966,7 @@ class GetThreadListTest(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetMix
|
||||
page_size=11,
|
||||
order_direction="asc",
|
||||
).data
|
||||
self.assertIn("order_direction", assertion.exception.message_dict)
|
||||
assert 'order_direction' in assertion.value.message_dict
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1059,21 +1014,21 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
def test_nonexistent_thread(self):
|
||||
thread_id = "nonexistent_thread"
|
||||
self.register_get_thread_error_response(thread_id, 404)
|
||||
with self.assertRaises(ThreadNotFoundError):
|
||||
with pytest.raises(ThreadNotFoundError):
|
||||
get_comment_list(self.request, thread_id, endorsed=False, page=1, page_size=1)
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
self.get_comment_list(self.make_minimal_cs_thread({"course_id": "non/existent/course"}))
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
self.get_comment_list(self.make_minimal_cs_thread())
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
disabled_course = _discussion_disabled_course_for(self.user)
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
self.get_comment_list(
|
||||
self.make_minimal_cs_thread(
|
||||
overrides={"course_id": six.text_type(disabled_course.id)}
|
||||
@@ -1128,41 +1083,33 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
)
|
||||
try:
|
||||
self.get_comment_list(thread)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_discussion_endorsed(self, endorsed_value):
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
self.get_comment_list(
|
||||
self.make_minimal_cs_thread({"thread_type": "discussion"}),
|
||||
endorsed=endorsed_value
|
||||
)
|
||||
self.assertEqual(
|
||||
assertion.exception.message_dict,
|
||||
{"endorsed": ["This field may not be specified for discussion threads."]}
|
||||
)
|
||||
assert assertion.value.message_dict == {'endorsed': ['This field may not be specified for discussion threads.']}
|
||||
|
||||
def test_question_without_endorsed(self):
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
self.get_comment_list(
|
||||
self.make_minimal_cs_thread({"thread_type": "question"}),
|
||||
endorsed=None
|
||||
)
|
||||
self.assertEqual(
|
||||
assertion.exception.message_dict,
|
||||
{"endorsed": ["This field is required for question threads."]}
|
||||
)
|
||||
assert assertion.value.message_dict == {'endorsed': ['This field is required for question threads.']}
|
||||
|
||||
def test_empty(self):
|
||||
discussion_thread = self.make_minimal_cs_thread(
|
||||
{"thread_type": "discussion", "children": [], "resp_total": 0}
|
||||
)
|
||||
self.assertEqual(
|
||||
self.get_comment_list(discussion_thread).data,
|
||||
make_paginated_api_response(results=[], count=0, num_pages=1, next_link=None, previous_link=None)
|
||||
)
|
||||
assert self.get_comment_list(discussion_thread).data == make_paginated_api_response(
|
||||
results=[], count=0, num_pages=1, next_link=None, previous_link=None)
|
||||
|
||||
question_thread = self.make_minimal_cs_thread({
|
||||
"thread_type": "question",
|
||||
@@ -1170,14 +1117,10 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
"non_endorsed_responses": [],
|
||||
"non_endorsed_resp_total": 0
|
||||
})
|
||||
self.assertEqual(
|
||||
self.get_comment_list(question_thread, endorsed=False).data,
|
||||
make_paginated_api_response(results=[], count=0, num_pages=1, next_link=None, previous_link=None)
|
||||
)
|
||||
self.assertEqual(
|
||||
self.get_comment_list(question_thread, endorsed=True).data,
|
||||
make_paginated_api_response(results=[], count=0, num_pages=1, next_link=None, previous_link=None)
|
||||
)
|
||||
assert self.get_comment_list(question_thread, endorsed=False).data == make_paginated_api_response(
|
||||
results=[], count=0, num_pages=1, next_link=None, previous_link=None)
|
||||
assert self.get_comment_list(question_thread, endorsed=True).data == make_paginated_api_response(
|
||||
results=[], count=0, num_pages=1, next_link=None, previous_link=None)
|
||||
|
||||
def test_basic_query_params(self):
|
||||
self.get_comment_list(
|
||||
@@ -1284,7 +1227,7 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
actual_comments = self.get_comment_list(
|
||||
self.make_minimal_cs_thread({"children": source_comments})
|
||||
).data["results"]
|
||||
self.assertEqual(actual_comments, expected_comments)
|
||||
assert actual_comments == expected_comments
|
||||
|
||||
def test_question_content(self):
|
||||
thread = self.make_minimal_cs_thread({
|
||||
@@ -1297,10 +1240,10 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
})
|
||||
|
||||
endorsed_actual = self.get_comment_list(thread, endorsed=True).data
|
||||
self.assertEqual(endorsed_actual["results"][0]["id"], "endorsed_comment")
|
||||
assert endorsed_actual['results'][0]['id'] == 'endorsed_comment'
|
||||
|
||||
non_endorsed_actual = self.get_comment_list(thread, endorsed=False).data
|
||||
self.assertEqual(non_endorsed_actual["results"][0]["id"], "non_endorsed_comment")
|
||||
assert non_endorsed_actual['results'][0]['id'] == 'non_endorsed_comment'
|
||||
|
||||
def test_endorsed_by_anonymity(self):
|
||||
"""
|
||||
@@ -1317,7 +1260,7 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
]
|
||||
})
|
||||
actual_comments = self.get_comment_list(thread).data["results"]
|
||||
self.assertIsNone(actual_comments[0]["endorsed_by"])
|
||||
assert actual_comments[0]['endorsed_by'] is None
|
||||
|
||||
@ddt.data(
|
||||
("discussion", None, "children", "resp_total"),
|
||||
@@ -1345,23 +1288,23 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
|
||||
# Only page
|
||||
actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=1, page_size=5).data
|
||||
self.assertIsNone(actual["pagination"]["next"])
|
||||
self.assertIsNone(actual["pagination"]["previous"])
|
||||
assert actual['pagination']['next'] is None
|
||||
assert actual['pagination']['previous'] is None
|
||||
|
||||
# First page of many
|
||||
actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=1, page_size=2).data
|
||||
self.assertEqual(actual["pagination"]["next"], "http://testserver/test_path?page=2")
|
||||
self.assertIsNone(actual["pagination"]["previous"])
|
||||
assert actual['pagination']['next'] == 'http://testserver/test_path?page=2'
|
||||
assert actual['pagination']['previous'] is None
|
||||
|
||||
# Middle page of many
|
||||
actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=2, page_size=2).data
|
||||
self.assertEqual(actual["pagination"]["next"], "http://testserver/test_path?page=3")
|
||||
self.assertEqual(actual["pagination"]["previous"], "http://testserver/test_path?page=1")
|
||||
assert actual['pagination']['next'] == 'http://testserver/test_path?page=3'
|
||||
assert actual['pagination']['previous'] == 'http://testserver/test_path?page=1'
|
||||
|
||||
# Last page of many
|
||||
actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=3, page_size=2).data
|
||||
self.assertIsNone(actual["pagination"]["next"])
|
||||
self.assertEqual(actual["pagination"]["previous"], "http://testserver/test_path?page=2")
|
||||
assert actual['pagination']['next'] is None
|
||||
assert actual['pagination']['previous'] == 'http://testserver/test_path?page=2'
|
||||
|
||||
# Page past the end
|
||||
thread = self.make_minimal_cs_thread({
|
||||
@@ -1369,7 +1312,7 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
response_field: [],
|
||||
response_total_field: 5
|
||||
})
|
||||
with self.assertRaises(PageNotFoundError):
|
||||
with pytest.raises(PageNotFoundError):
|
||||
self.get_comment_list(thread, endorsed=endorsed_arg, page=2, page_size=5)
|
||||
|
||||
def test_question_endorsed_pagination(self):
|
||||
@@ -1388,17 +1331,12 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
"""
|
||||
actual = self.get_comment_list(thread, endorsed=True, page=page, page_size=page_size).data
|
||||
result_ids = [result["id"] for result in actual["results"]]
|
||||
self.assertEqual(
|
||||
result_ids,
|
||||
["comment_{}".format(i) for i in range(expected_start, expected_stop)]
|
||||
assert result_ids == ['comment_{}'.format(i) for i in range(expected_start, expected_stop)]
|
||||
assert actual['pagination']['next'] == (
|
||||
'http://testserver/test_path?page={}'.format(expected_next) if expected_next else None
|
||||
)
|
||||
self.assertEqual(
|
||||
actual["pagination"]["next"],
|
||||
"http://testserver/test_path?page={}".format(expected_next) if expected_next else None
|
||||
)
|
||||
self.assertEqual(
|
||||
actual["pagination"]["previous"],
|
||||
"http://testserver/test_path?page={}".format(expected_prev) if expected_prev else None
|
||||
assert actual['pagination']['previous'] == (
|
||||
'http://testserver/test_path?page={}'.format(expected_prev) if expected_prev else None
|
||||
)
|
||||
|
||||
# Only page
|
||||
@@ -1442,7 +1380,7 @@ class GetCommentListTest(ForumsEnableMixin, CommentsServiceMockMixin, SharedModu
|
||||
)
|
||||
|
||||
# Page past the end
|
||||
with self.assertRaises(PageNotFoundError):
|
||||
with pytest.raises(PageNotFoundError):
|
||||
self.get_comment_list(thread, endorsed=True, page=2, page_size=10)
|
||||
|
||||
|
||||
@@ -1534,39 +1472,33 @@ class CreateThreadTest(
|
||||
"comment_list_url": "http://testserver/api/discussion/v1/comments/?thread_id=test_id",
|
||||
"read": True,
|
||||
})
|
||||
self.assertEqual(actual, expected)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"commentable_id": ["test_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Test Title"],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
}
|
||||
)
|
||||
assert actual == expected
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'commentable_id': ['test_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Test Title'],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)]
|
||||
}
|
||||
event_name, event_data = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, "edx.forum.thread.created")
|
||||
self.assertEqual(
|
||||
event_data,
|
||||
{
|
||||
"commentable_id": "test_topic",
|
||||
"group_id": None,
|
||||
"thread_type": "discussion",
|
||||
"title": "Test Title",
|
||||
"title_truncated": False,
|
||||
"anonymous": False,
|
||||
"anonymous_to_peers": False,
|
||||
"options": {"followed": False},
|
||||
"id": "test_id",
|
||||
"truncated": False,
|
||||
"body": "Test body",
|
||||
"url": "",
|
||||
"user_forums_roles": [FORUM_ROLE_STUDENT],
|
||||
"user_course_roles": [],
|
||||
}
|
||||
)
|
||||
assert event_name == 'edx.forum.thread.created'
|
||||
assert event_data == {
|
||||
'commentable_id': 'test_topic',
|
||||
'group_id': None,
|
||||
'thread_type': 'discussion',
|
||||
'title': 'Test Title',
|
||||
'title_truncated': False,
|
||||
'anonymous': False,
|
||||
'anonymous_to_peers': False,
|
||||
'options': {'followed': False},
|
||||
'id': 'test_id',
|
||||
'truncated': False,
|
||||
'body': 'Test body',
|
||||
'url': '',
|
||||
'user_forums_roles': [FORUM_ROLE_STUDENT],
|
||||
'user_course_roles': []
|
||||
}
|
||||
|
||||
def test_basic_in_blackout_period(self):
|
||||
"""
|
||||
@@ -1652,26 +1584,23 @@ class CreateThreadTest(
|
||||
with self.assert_signal_sent(api, 'thread_created', sender=None, user=self.user, exclude_args=('post',)):
|
||||
create_thread(self.request, data)
|
||||
event_name, event_data = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, "edx.forum.thread.created")
|
||||
self.assertEqual(
|
||||
event_data,
|
||||
{
|
||||
"commentable_id": "test_topic",
|
||||
"group_id": None,
|
||||
"thread_type": "discussion",
|
||||
"title": self.LONG_TITLE[:1000],
|
||||
"title_truncated": True,
|
||||
"anonymous": False,
|
||||
"anonymous_to_peers": False,
|
||||
"options": {"followed": False},
|
||||
"id": "test_id",
|
||||
"truncated": False,
|
||||
"body": "Test body",
|
||||
"url": "",
|
||||
"user_forums_roles": [FORUM_ROLE_STUDENT],
|
||||
"user_course_roles": [],
|
||||
}
|
||||
)
|
||||
assert event_name == 'edx.forum.thread.created'
|
||||
assert event_data == {
|
||||
'commentable_id': 'test_topic',
|
||||
'group_id': None,
|
||||
'thread_type': 'discussion',
|
||||
'title': self.LONG_TITLE[:1000],
|
||||
'title_truncated': True,
|
||||
'anonymous': False,
|
||||
'anonymous_to_peers': False,
|
||||
'options': {'followed': False},
|
||||
'id': 'test_id',
|
||||
'truncated': False,
|
||||
'body': 'Test body',
|
||||
'url': '',
|
||||
'user_forums_roles': [FORUM_ROLE_STUDENT],
|
||||
'user_course_roles': []
|
||||
}
|
||||
|
||||
@ddt.data(
|
||||
*itertools.product(
|
||||
@@ -1724,14 +1653,14 @@ class CreateThreadTest(
|
||||
)
|
||||
try:
|
||||
create_thread(self.request, data)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
actual_post_data = httpretty.last_request().parsed_body # lint-amnesty, pylint: disable=no-member
|
||||
if data_group_state == "group_is_set":
|
||||
self.assertEqual(actual_post_data["group_id"], [str(data["group_id"])])
|
||||
assert actual_post_data['group_id'] == [str(data['group_id'])]
|
||||
elif data_group_state == "no_group_set" and course_is_cohorted and topic_is_cohorted:
|
||||
self.assertEqual(actual_post_data["group_id"], [str(cohort.id)])
|
||||
assert actual_post_data['group_id'] == [str(cohort.id)]
|
||||
else:
|
||||
self.assertNotIn("group_id", actual_post_data)
|
||||
assert 'group_id' not in actual_post_data
|
||||
except ValidationError as ex:
|
||||
if not expected_error:
|
||||
self.fail(u"Unexpected validation error: {}".format(ex))
|
||||
@@ -1742,17 +1671,11 @@ class CreateThreadTest(
|
||||
data = self.minimal_data.copy()
|
||||
data["following"] = "True"
|
||||
result = create_thread(self.request, data)
|
||||
self.assertEqual(result["following"], True)
|
||||
assert result['following'] is True
|
||||
cs_request = httpretty.last_request()
|
||||
self.assertEqual(
|
||||
urlparse(cs_request.path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/users/{}/subscriptions".format(self.user.id)
|
||||
)
|
||||
self.assertEqual(cs_request.method, "POST")
|
||||
self.assertEqual(
|
||||
cs_request.parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{"source_type": ["thread"], "source_id": ["test_id"]}
|
||||
)
|
||||
assert urlparse(cs_request.path).path == '/api/v1/users/{}/subscriptions'.format(self.user.id) # lint-amnesty, pylint: disable=no-member
|
||||
assert cs_request.method == 'POST'
|
||||
assert cs_request.parsed_body == {'source_type': ['thread'], 'source_id': ['test_id']} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def test_voted(self):
|
||||
self.register_post_thread_response({"id": "test_id", "username": self.user.username})
|
||||
@@ -1761,14 +1684,11 @@ class CreateThreadTest(
|
||||
data["voted"] = "True"
|
||||
with self.assert_signal_sent(api, 'thread_voted', sender=None, user=self.user, exclude_args=('post',)):
|
||||
result = create_thread(self.request, data)
|
||||
self.assertEqual(result["voted"], True)
|
||||
assert result['voted'] is True
|
||||
cs_request = httpretty.last_request()
|
||||
self.assertEqual(urlparse(cs_request.path).path, "/api/v1/threads/test_id/votes") # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual(cs_request.method, "PUT")
|
||||
self.assertEqual(
|
||||
cs_request.parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{"user_id": [str(self.user.id)], "value": ["up"]}
|
||||
)
|
||||
assert urlparse(cs_request.path).path == '/api/v1/threads/test_id/votes' # lint-amnesty, pylint: disable=no-member
|
||||
assert cs_request.method == 'PUT'
|
||||
assert cs_request.parsed_body == {'user_id': [str(self.user.id)], 'value': ['up']} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def test_abuse_flagged(self):
|
||||
self.register_post_thread_response({"id": "test_id", "username": self.user.username})
|
||||
@@ -1776,41 +1696,41 @@ class CreateThreadTest(
|
||||
data = self.minimal_data.copy()
|
||||
data["abuse_flagged"] = "True"
|
||||
result = create_thread(self.request, data)
|
||||
self.assertEqual(result["abuse_flagged"], True)
|
||||
assert result['abuse_flagged'] is True
|
||||
cs_request = httpretty.last_request()
|
||||
self.assertEqual(urlparse(cs_request.path).path, "/api/v1/threads/test_id/abuse_flag") # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual(cs_request.method, "PUT")
|
||||
self.assertEqual(cs_request.parsed_body, {"user_id": [str(self.user.id)]}) # lint-amnesty, pylint: disable=no-member
|
||||
assert urlparse(cs_request.path).path == '/api/v1/threads/test_id/abuse_flag' # lint-amnesty, pylint: disable=no-member
|
||||
assert cs_request.method == 'PUT'
|
||||
assert cs_request.parsed_body == {'user_id': [str(self.user.id)]} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def test_course_id_missing(self):
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
create_thread(self.request, {})
|
||||
self.assertEqual(assertion.exception.message_dict, {"course_id": ["This field is required."]})
|
||||
assert assertion.value.message_dict == {'course_id': ['This field is required.']}
|
||||
|
||||
def test_course_id_invalid(self):
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
create_thread(self.request, {"course_id": "invalid!"})
|
||||
self.assertEqual(assertion.exception.message_dict, {"course_id": ["Invalid value."]})
|
||||
assert assertion.value.message_dict == {'course_id': ['Invalid value.']}
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
create_thread(self.request, {"course_id": "non/existent/course"})
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
create_thread(self.request, self.minimal_data)
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
disabled_course = _discussion_disabled_course_for(self.user)
|
||||
self.minimal_data["course_id"] = six.text_type(disabled_course.id)
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
create_thread(self.request, self.minimal_data)
|
||||
|
||||
def test_invalid_field(self):
|
||||
data = self.minimal_data.copy()
|
||||
data["type"] = "invalid_type"
|
||||
with self.assertRaises(ValidationError):
|
||||
with pytest.raises(ValidationError):
|
||||
create_thread(self.request, data)
|
||||
|
||||
|
||||
@@ -1893,23 +1813,17 @@ class CreateCommentTest(
|
||||
"editable_fields": ["abuse_flagged", "raw_body", "voted"],
|
||||
"child_count": 0,
|
||||
}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
expected_url = (
|
||||
"/api/v1/comments/{}".format(parent_id) if parent_id else
|
||||
"/api/v1/threads/test_thread/comments"
|
||||
)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
expected_url
|
||||
)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)]
|
||||
}
|
||||
)
|
||||
assert urlparse(httpretty.last_request().path).path == expected_url # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)]
|
||||
}
|
||||
expected_event_name = (
|
||||
"edx.forum.comment.created" if parent_id else
|
||||
"edx.forum.response.created"
|
||||
@@ -1928,8 +1842,8 @@ class CreateCommentTest(
|
||||
if parent_id:
|
||||
expected_event_data["response"] = {"id": parent_id}
|
||||
actual_event_name, actual_event_data = mock_emit.call_args[0]
|
||||
self.assertEqual(actual_event_name, expected_event_name)
|
||||
self.assertEqual(actual_event_data, expected_event_data)
|
||||
assert actual_event_name == expected_event_name
|
||||
assert actual_event_data == expected_event_data
|
||||
|
||||
@ddt.data(None, "test_parent")
|
||||
@mock.patch("eventtracking.tracker.emit")
|
||||
@@ -2060,10 +1974,10 @@ class CreateCommentTest(
|
||||
)
|
||||
try:
|
||||
create_comment(self.request, data)
|
||||
self.assertEqual(httpretty.last_request().parsed_body["endorsed"], ["True"]) # lint-amnesty, pylint: disable=no-member
|
||||
self.assertFalse(expected_error)
|
||||
assert httpretty.last_request().parsed_body['endorsed'] == ['True'] # lint-amnesty, pylint: disable=no-member
|
||||
assert not expected_error
|
||||
except ValidationError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
def test_voted(self):
|
||||
self.register_post_comment_response({"id": "test_comment", "username": self.user.username}, "test_thread")
|
||||
@@ -2072,14 +1986,11 @@ class CreateCommentTest(
|
||||
data["voted"] = "True"
|
||||
with self.assert_signal_sent(api, 'comment_voted', sender=None, user=self.user, exclude_args=('post',)):
|
||||
result = create_comment(self.request, data)
|
||||
self.assertEqual(result["voted"], True)
|
||||
assert result['voted'] is True
|
||||
cs_request = httpretty.last_request()
|
||||
self.assertEqual(urlparse(cs_request.path).path, "/api/v1/comments/test_comment/votes") # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual(cs_request.method, "PUT")
|
||||
self.assertEqual(
|
||||
cs_request.parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{"user_id": [str(self.user.id)], "value": ["up"]}
|
||||
)
|
||||
assert urlparse(cs_request.path).path == '/api/v1/comments/test_comment/votes' # lint-amnesty, pylint: disable=no-member
|
||||
assert cs_request.method == 'PUT'
|
||||
assert cs_request.parsed_body == {'user_id': [str(self.user.id)], 'value': ['up']} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def test_abuse_flagged(self):
|
||||
self.register_post_comment_response({"id": "test_comment", "username": self.user.username}, "test_thread")
|
||||
@@ -2087,32 +1998,32 @@ class CreateCommentTest(
|
||||
data = self.minimal_data.copy()
|
||||
data["abuse_flagged"] = "True"
|
||||
result = create_comment(self.request, data)
|
||||
self.assertEqual(result["abuse_flagged"], True)
|
||||
assert result['abuse_flagged'] is True
|
||||
cs_request = httpretty.last_request()
|
||||
self.assertEqual(urlparse(cs_request.path).path, "/api/v1/comments/test_comment/abuse_flag") # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual(cs_request.method, "PUT")
|
||||
self.assertEqual(cs_request.parsed_body, {"user_id": [str(self.user.id)]}) # lint-amnesty, pylint: disable=no-member
|
||||
assert urlparse(cs_request.path).path == '/api/v1/comments/test_comment/abuse_flag' # lint-amnesty, pylint: disable=no-member
|
||||
assert cs_request.method == 'PUT'
|
||||
assert cs_request.parsed_body == {'user_id': [str(self.user.id)]} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def test_thread_id_missing(self):
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
create_comment(self.request, {})
|
||||
self.assertEqual(assertion.exception.message_dict, {"thread_id": ["This field is required."]})
|
||||
assert assertion.value.message_dict == {'thread_id': ['This field is required.']}
|
||||
|
||||
def test_thread_id_not_found(self):
|
||||
self.register_get_thread_error_response("test_thread", 404)
|
||||
with self.assertRaises(ThreadNotFoundError):
|
||||
with pytest.raises(ThreadNotFoundError):
|
||||
create_comment(self.request, self.minimal_data)
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
self.register_get_thread_response(
|
||||
make_minimal_cs_thread({"id": "test_thread", "course_id": "non/existent/course"})
|
||||
)
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
create_comment(self.request, self.minimal_data)
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
create_comment(self.request, self.minimal_data)
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
@@ -2124,7 +2035,7 @@ class CreateCommentTest(
|
||||
"commentable_id": "test_topic",
|
||||
})
|
||||
)
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
create_comment(self.request, self.minimal_data)
|
||||
|
||||
@ddt.data(
|
||||
@@ -2161,14 +2072,14 @@ class CreateCommentTest(
|
||||
)
|
||||
try:
|
||||
create_comment(self.request, data)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
def test_invalid_field(self):
|
||||
data = self.minimal_data.copy()
|
||||
del data["raw_body"]
|
||||
with self.assertRaises(ValidationError):
|
||||
with pytest.raises(ValidationError):
|
||||
create_comment(self.request, data)
|
||||
|
||||
|
||||
@@ -2230,57 +2141,54 @@ class UpdateThreadTest(
|
||||
self.register_thread()
|
||||
update_thread(self.request, "test_thread", {})
|
||||
for request in httpretty.httpretty.latest_requests:
|
||||
self.assertEqual(request.method, "GET")
|
||||
assert request.method == 'GET'
|
||||
|
||||
def test_basic(self):
|
||||
self.register_thread()
|
||||
with self.assert_signal_sent(api, 'thread_edited', sender=None, user=self.user, exclude_args=('post',)):
|
||||
actual = update_thread(self.request, "test_thread", {"raw_body": "Edited body"})
|
||||
|
||||
self.assertEqual(actual, self.expected_thread_data({
|
||||
"raw_body": "Edited body",
|
||||
"rendered_body": "<p>Edited body</p>",
|
||||
"topic_id": "original_topic",
|
||||
"read": True,
|
||||
"title": "Original Title",
|
||||
}))
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"commentable_id": ["original_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Original Title"],
|
||||
"body": ["Edited body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"closed": ["False"],
|
||||
"pinned": ["False"],
|
||||
"read": ["False"],
|
||||
}
|
||||
)
|
||||
assert actual == self.expected_thread_data({
|
||||
'raw_body': 'Edited body',
|
||||
'rendered_body': '<p>Edited body</p>',
|
||||
'topic_id': 'original_topic',
|
||||
'read': True,
|
||||
'title': 'Original Title'
|
||||
})
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'commentable_id': ['original_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Original Title'],
|
||||
'body': ['Edited body'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'closed': ['False'],
|
||||
'pinned': ['False'],
|
||||
'read': ['False']
|
||||
}
|
||||
|
||||
def test_nonexistent_thread(self):
|
||||
self.register_get_thread_error_response("test_thread", 404)
|
||||
with self.assertRaises(ThreadNotFoundError):
|
||||
with pytest.raises(ThreadNotFoundError):
|
||||
update_thread(self.request, "test_thread", {})
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
self.register_thread({"course_id": "non/existent/course"})
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
update_thread(self.request, "test_thread", {})
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.register_thread()
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
update_thread(self.request, "test_thread", {})
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
disabled_course = _discussion_disabled_course_for(self.user)
|
||||
self.register_thread(overrides={"course_id": six.text_type(disabled_course.id)})
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
update_thread(self.request, "test_thread", {})
|
||||
|
||||
@ddt.data(
|
||||
@@ -2313,9 +2221,9 @@ class UpdateThreadTest(
|
||||
)
|
||||
try:
|
||||
update_thread(self.request, "test_thread", {})
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
@ddt.data(
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
@@ -2331,13 +2239,10 @@ class UpdateThreadTest(
|
||||
expected_error = role_name == FORUM_ROLE_STUDENT
|
||||
try:
|
||||
update_thread(self.request, "test_thread", data)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ValidationError as err:
|
||||
self.assertTrue(expected_error)
|
||||
self.assertEqual(
|
||||
err.message_dict,
|
||||
{field: ["This field is not editable."] for field in data.keys()}
|
||||
)
|
||||
assert expected_error
|
||||
assert err.message_dict == {field: ['This field is not editable.'] for field in data.keys()}
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2357,26 +2262,20 @@ class UpdateThreadTest(
|
||||
self.register_thread()
|
||||
data = {"following": new_following}
|
||||
result = update_thread(self.request, "test_thread", data)
|
||||
self.assertEqual(result["following"], new_following)
|
||||
assert result['following'] == new_following
|
||||
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
|
||||
subscription_url = "/api/v1/users/{}/subscriptions".format(self.user.id)
|
||||
if old_following == new_following:
|
||||
self.assertNotEqual(last_request_path, subscription_url)
|
||||
assert last_request_path != subscription_url
|
||||
else:
|
||||
self.assertEqual(last_request_path, subscription_url)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().method,
|
||||
"POST" if new_following else "DELETE"
|
||||
)
|
||||
assert last_request_path == subscription_url
|
||||
assert httpretty.last_request().method == ('POST' if new_following else 'DELETE')
|
||||
request_data = (
|
||||
httpretty.last_request().parsed_body if new_following else # lint-amnesty, pylint: disable=no-member
|
||||
parse_qs(urlparse(httpretty.last_request().path).query) # lint-amnesty, pylint: disable=no-member
|
||||
)
|
||||
request_data.pop("request_id", None)
|
||||
self.assertEqual(
|
||||
request_data,
|
||||
{"source_type": ["thread"], "source_id": ["test_thread"]}
|
||||
)
|
||||
assert request_data == {'source_type': ['thread'], 'source_id': ['test_thread']}
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2397,17 +2296,14 @@ class UpdateThreadTest(
|
||||
self.register_thread()
|
||||
data = {"voted": new_vote_status}
|
||||
result = update_thread(self.request, "test_thread", data)
|
||||
self.assertEqual(result["voted"], new_vote_status)
|
||||
assert result['voted'] == new_vote_status
|
||||
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
|
||||
votes_url = "/api/v1/threads/test_thread/votes"
|
||||
if current_vote_status == new_vote_status:
|
||||
self.assertNotEqual(last_request_path, votes_url)
|
||||
assert last_request_path != votes_url
|
||||
else:
|
||||
self.assertEqual(last_request_path, votes_url)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().method,
|
||||
"PUT" if new_vote_status else "DELETE"
|
||||
)
|
||||
assert last_request_path == votes_url
|
||||
assert httpretty.last_request().method == ('PUT' if new_vote_status else 'DELETE')
|
||||
actual_request_data = (
|
||||
httpretty.last_request().parsed_body if new_vote_status else # lint-amnesty, pylint: disable=no-member
|
||||
parse_qs(urlparse(httpretty.last_request().path).query) # lint-amnesty, pylint: disable=no-member
|
||||
@@ -2416,23 +2312,20 @@ class UpdateThreadTest(
|
||||
expected_request_data = {"user_id": [str(self.user.id)]}
|
||||
if new_vote_status:
|
||||
expected_request_data["value"] = ["up"]
|
||||
self.assertEqual(actual_request_data, expected_request_data)
|
||||
assert actual_request_data == expected_request_data
|
||||
|
||||
event_name, event_data = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, "edx.forum.thread.voted")
|
||||
self.assertEqual(
|
||||
event_data,
|
||||
{
|
||||
'undo_vote': not new_vote_status,
|
||||
'url': '',
|
||||
'target_username': self.user.username,
|
||||
'vote_value': 'up',
|
||||
'user_forums_roles': [FORUM_ROLE_STUDENT],
|
||||
'user_course_roles': [],
|
||||
'commentable_id': 'original_topic',
|
||||
'id': 'test_thread'
|
||||
}
|
||||
)
|
||||
assert event_name == 'edx.forum.thread.voted'
|
||||
assert event_data == {
|
||||
'undo_vote': (not new_vote_status),
|
||||
'url': '',
|
||||
'target_username': self.user.username,
|
||||
'vote_value': 'up',
|
||||
'user_forums_roles': [FORUM_ROLE_STUDENT],
|
||||
'user_course_roles': [],
|
||||
'commentable_id': 'original_topic',
|
||||
'id': 'test_thread'
|
||||
}
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2452,12 +2345,12 @@ class UpdateThreadTest(
|
||||
data = {"voted": first_vote}
|
||||
result = update_thread(self.request, "test_thread", data)
|
||||
self.register_thread(overrides={"voted": first_vote})
|
||||
self.assertEqual(result["vote_count"], 1 if first_vote else 0)
|
||||
assert result['vote_count'] == (1 if first_vote else 0)
|
||||
|
||||
#second vote
|
||||
data = {"voted": second_vote}
|
||||
result = update_thread(self.request, "test_thread", data)
|
||||
self.assertEqual(result["vote_count"], 1 if second_vote else 0)
|
||||
assert result['vote_count'] == (1 if second_vote else 0)
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False], [True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2496,14 +2389,14 @@ class UpdateThreadTest(
|
||||
data = {"voted": user_vote}
|
||||
result = update_thread(request, "test_thread", data)
|
||||
if current_vote == user_vote:
|
||||
self.assertEqual(result["vote_count"], vote_count)
|
||||
assert result['vote_count'] == vote_count
|
||||
elif user_vote:
|
||||
vote_count += 1
|
||||
self.assertEqual(result["vote_count"], vote_count)
|
||||
assert result['vote_count'] == vote_count
|
||||
self.register_get_user_response(self.user, upvoted_ids=["test_thread"])
|
||||
else:
|
||||
vote_count -= 1
|
||||
self.assertEqual(result["vote_count"], vote_count)
|
||||
assert result['vote_count'] == vote_count
|
||||
self.register_get_user_response(self.user, upvoted_ids=[])
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False]))
|
||||
@@ -2523,32 +2416,23 @@ class UpdateThreadTest(
|
||||
self.register_thread({"abuse_flaggers": [str(self.user.id)] if old_flagged else []})
|
||||
data = {"abuse_flagged": new_flagged}
|
||||
result = update_thread(self.request, "test_thread", data)
|
||||
self.assertEqual(result["abuse_flagged"], new_flagged)
|
||||
assert result['abuse_flagged'] == new_flagged
|
||||
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
|
||||
flag_url = "/api/v1/threads/test_thread/abuse_flag"
|
||||
unflag_url = "/api/v1/threads/test_thread/abuse_unflag"
|
||||
if old_flagged == new_flagged:
|
||||
self.assertNotEqual(last_request_path, flag_url)
|
||||
self.assertNotEqual(last_request_path, unflag_url)
|
||||
assert last_request_path != flag_url
|
||||
assert last_request_path != unflag_url
|
||||
else:
|
||||
self.assertEqual(
|
||||
last_request_path,
|
||||
flag_url if new_flagged else unflag_url
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "PUT")
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{"user_id": [str(self.user.id)]}
|
||||
)
|
||||
assert last_request_path == (flag_url if new_flagged else unflag_url)
|
||||
assert httpretty.last_request().method == 'PUT'
|
||||
assert httpretty.last_request().parsed_body == {'user_id': [str(self.user.id)]} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
def test_invalid_field(self):
|
||||
self.register_thread()
|
||||
with self.assertRaises(ValidationError) as assertion:
|
||||
with pytest.raises(ValidationError) as assertion:
|
||||
update_thread(self.request, "test_thread", {"raw_body": ""})
|
||||
self.assertEqual(
|
||||
assertion.exception.message_dict,
|
||||
{"raw_body": ["This field may not be blank."]}
|
||||
)
|
||||
assert assertion.value.message_dict == {'raw_body': ['This field may not be blank.']}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -2618,7 +2502,7 @@ class UpdateCommentTest(
|
||||
self.register_comment()
|
||||
update_comment(self.request, "test_comment", {})
|
||||
for request in httpretty.httpretty.latest_requests:
|
||||
self.assertEqual(request.method, "GET")
|
||||
assert request.method == 'GET'
|
||||
|
||||
@ddt.data(None, "test_parent")
|
||||
def test_basic(self, parent_id):
|
||||
@@ -2646,38 +2530,35 @@ class UpdateCommentTest(
|
||||
"editable_fields": ["abuse_flagged", "raw_body", "voted"],
|
||||
"child_count": 0,
|
||||
}
|
||||
self.assertEqual(actual, expected)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"body": ["Edited body"],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"user_id": [str(self.user.id)],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"endorsed": ["False"],
|
||||
}
|
||||
)
|
||||
assert actual == expected
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'body': ['Edited body'],
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'user_id': [str(self.user.id)],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'endorsed': ['False']
|
||||
}
|
||||
|
||||
def test_nonexistent_comment(self):
|
||||
self.register_get_comment_error_response("test_comment", 404)
|
||||
with self.assertRaises(CommentNotFoundError):
|
||||
with pytest.raises(CommentNotFoundError):
|
||||
update_comment(self.request, "test_comment", {})
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
self.register_comment(thread_overrides={"course_id": "non/existent/course"})
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
update_comment(self.request, "test_comment", {})
|
||||
|
||||
def test_unenrolled(self):
|
||||
self.register_comment()
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
update_comment(self.request, "test_comment", {})
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
self.register_comment(course=_discussion_disabled_course_for(self.user))
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
update_comment(self.request, "test_comment", {})
|
||||
|
||||
@ddt.data(
|
||||
@@ -2715,9 +2596,9 @@ class UpdateCommentTest(
|
||||
)
|
||||
try:
|
||||
update_comment(self.request, "test_comment", {})
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
@ddt.data(*itertools.product(
|
||||
[
|
||||
@@ -2741,13 +2622,10 @@ class UpdateCommentTest(
|
||||
expected_error = role_name == FORUM_ROLE_STUDENT and not is_comment_author
|
||||
try:
|
||||
update_comment(self.request, "test_comment", {"raw_body": "edited"})
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ValidationError as err:
|
||||
self.assertTrue(expected_error)
|
||||
self.assertEqual(
|
||||
err.message_dict,
|
||||
{"raw_body": ["This field is not editable."]}
|
||||
)
|
||||
assert expected_error
|
||||
assert err.message_dict == {'raw_body': ['This field is not editable.']}
|
||||
|
||||
@ddt.data(*itertools.product(
|
||||
[
|
||||
@@ -2776,13 +2654,10 @@ class UpdateCommentTest(
|
||||
)
|
||||
try:
|
||||
update_comment(self.request, "test_comment", {"endorsed": True})
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ValidationError as err:
|
||||
self.assertTrue(expected_error)
|
||||
self.assertEqual(
|
||||
err.message_dict,
|
||||
{"endorsed": ["This field is not editable."]}
|
||||
)
|
||||
assert expected_error
|
||||
assert err.message_dict == {'endorsed': ['This field is not editable.']}
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2805,18 +2680,15 @@ class UpdateCommentTest(
|
||||
self.register_comment(overrides={"votes": {"up_count": vote_count}})
|
||||
data = {"voted": new_vote_status}
|
||||
result = update_comment(self.request, "test_comment", data)
|
||||
self.assertEqual(result["vote_count"], 1 if new_vote_status else 0)
|
||||
self.assertEqual(result["voted"], new_vote_status)
|
||||
assert result['vote_count'] == (1 if new_vote_status else 0)
|
||||
assert result['voted'] == new_vote_status
|
||||
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
|
||||
votes_url = "/api/v1/comments/test_comment/votes"
|
||||
if current_vote_status == new_vote_status:
|
||||
self.assertNotEqual(last_request_path, votes_url)
|
||||
assert last_request_path != votes_url
|
||||
else:
|
||||
self.assertEqual(last_request_path, votes_url)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().method,
|
||||
"PUT" if new_vote_status else "DELETE"
|
||||
)
|
||||
assert last_request_path == votes_url
|
||||
assert httpretty.last_request().method == ('PUT' if new_vote_status else 'DELETE')
|
||||
actual_request_data = (
|
||||
httpretty.last_request().parsed_body if new_vote_status else # lint-amnesty, pylint: disable=no-member
|
||||
parse_qs(urlparse(httpretty.last_request().path).query) # lint-amnesty, pylint: disable=no-member
|
||||
@@ -2825,24 +2697,21 @@ class UpdateCommentTest(
|
||||
expected_request_data = {"user_id": [str(self.user.id)]}
|
||||
if new_vote_status:
|
||||
expected_request_data["value"] = ["up"]
|
||||
self.assertEqual(actual_request_data, expected_request_data)
|
||||
assert actual_request_data == expected_request_data
|
||||
|
||||
event_name, event_data = mock_emit.call_args[0]
|
||||
self.assertEqual(event_name, "edx.forum.response.voted")
|
||||
assert event_name == 'edx.forum.response.voted'
|
||||
|
||||
self.assertEqual(
|
||||
event_data,
|
||||
{
|
||||
'undo_vote': not new_vote_status,
|
||||
'url': '',
|
||||
'target_username': self.user.username,
|
||||
'vote_value': 'up',
|
||||
'user_forums_roles': [FORUM_ROLE_STUDENT],
|
||||
'user_course_roles': [],
|
||||
'commentable_id': 'dummy',
|
||||
'id': 'test_comment'
|
||||
}
|
||||
)
|
||||
assert event_data == {
|
||||
'undo_vote': (not new_vote_status),
|
||||
'url': '',
|
||||
'target_username': self.user.username,
|
||||
'vote_value': 'up',
|
||||
'user_forums_roles': [FORUM_ROLE_STUDENT],
|
||||
'user_course_roles': [],
|
||||
'commentable_id': 'dummy',
|
||||
'id': 'test_comment'
|
||||
}
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2862,12 +2731,12 @@ class UpdateCommentTest(
|
||||
data = {"voted": first_vote}
|
||||
result = update_comment(self.request, "test_comment", data)
|
||||
self.register_comment(overrides={"voted": first_vote})
|
||||
self.assertEqual(result["vote_count"], 1 if first_vote else 0)
|
||||
assert result['vote_count'] == (1 if first_vote else 0)
|
||||
|
||||
#second vote
|
||||
data = {"voted": second_vote}
|
||||
result = update_comment(self.request, "test_comment", data)
|
||||
self.assertEqual(result["vote_count"], 1 if second_vote else 0)
|
||||
assert result['vote_count'] == (1 if second_vote else 0)
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False], [True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -2905,14 +2774,14 @@ class UpdateCommentTest(
|
||||
data = {"voted": user_vote}
|
||||
result = update_comment(request, "test_comment", data)
|
||||
if current_vote == user_vote:
|
||||
self.assertEqual(result["vote_count"], vote_count)
|
||||
assert result['vote_count'] == vote_count
|
||||
elif user_vote:
|
||||
vote_count += 1
|
||||
self.assertEqual(result["vote_count"], vote_count)
|
||||
assert result['vote_count'] == vote_count
|
||||
self.register_get_user_response(self.user, upvoted_ids=["test_comment"])
|
||||
else:
|
||||
vote_count -= 1
|
||||
self.assertEqual(result["vote_count"], vote_count)
|
||||
assert result['vote_count'] == vote_count
|
||||
self.register_get_user_response(self.user, upvoted_ids=[])
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False]))
|
||||
@@ -2932,23 +2801,17 @@ class UpdateCommentTest(
|
||||
self.register_comment({"abuse_flaggers": [str(self.user.id)] if old_flagged else []})
|
||||
data = {"abuse_flagged": new_flagged}
|
||||
result = update_comment(self.request, "test_comment", data)
|
||||
self.assertEqual(result["abuse_flagged"], new_flagged)
|
||||
assert result['abuse_flagged'] == new_flagged
|
||||
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
|
||||
flag_url = "/api/v1/comments/test_comment/abuse_flag"
|
||||
unflag_url = "/api/v1/comments/test_comment/abuse_unflag"
|
||||
if old_flagged == new_flagged:
|
||||
self.assertNotEqual(last_request_path, flag_url)
|
||||
self.assertNotEqual(last_request_path, unflag_url)
|
||||
assert last_request_path != flag_url
|
||||
assert last_request_path != unflag_url
|
||||
else:
|
||||
self.assertEqual(
|
||||
last_request_path,
|
||||
flag_url if new_flagged else unflag_url
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "PUT")
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{"user_id": [str(self.user.id)]}
|
||||
)
|
||||
assert last_request_path == (flag_url if new_flagged else unflag_url)
|
||||
assert httpretty.last_request().method == 'PUT'
|
||||
assert httpretty.last_request().parsed_body == {'user_id': [str(self.user.id)]} # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -2999,33 +2862,30 @@ class DeleteThreadTest(
|
||||
def test_basic(self):
|
||||
self.register_thread()
|
||||
with self.assert_signal_sent(api, 'thread_deleted', sender=None, user=self.user, exclude_args=('post',)):
|
||||
self.assertIsNone(delete_thread(self.request, self.thread_id))
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/threads/{}".format(self.thread_id)
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "DELETE")
|
||||
assert delete_thread(self.request, self.thread_id) is None
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads/{}'.format(self.thread_id) # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().method == 'DELETE'
|
||||
|
||||
def test_thread_id_not_found(self):
|
||||
self.register_get_thread_error_response("missing_thread", 404)
|
||||
with self.assertRaises(ThreadNotFoundError):
|
||||
with pytest.raises(ThreadNotFoundError):
|
||||
delete_thread(self.request, "missing_thread")
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
self.register_thread({"course_id": "non/existent/course"})
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
delete_thread(self.request, self.thread_id)
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.register_thread()
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
delete_thread(self.request, self.thread_id)
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
disabled_course = _discussion_disabled_course_for(self.user)
|
||||
self.register_thread(overrides={"course_id": six.text_type(disabled_course.id)})
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
delete_thread(self.request, self.thread_id)
|
||||
|
||||
@ddt.data(
|
||||
@@ -3040,9 +2900,9 @@ class DeleteThreadTest(
|
||||
expected_error = role_name == FORUM_ROLE_STUDENT
|
||||
try:
|
||||
delete_thread(self.request, self.thread_id)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except PermissionDenied:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
@ddt.data(
|
||||
*itertools.product(
|
||||
@@ -3082,9 +2942,9 @@ class DeleteThreadTest(
|
||||
)
|
||||
try:
|
||||
delete_thread(self.request, self.thread_id)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -3144,29 +3004,26 @@ class DeleteCommentTest(
|
||||
def test_basic(self):
|
||||
self.register_comment_and_thread()
|
||||
with self.assert_signal_sent(api, 'comment_deleted', sender=None, user=self.user, exclude_args=('post',)):
|
||||
self.assertIsNone(delete_comment(self.request, self.comment_id))
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/comments/{}".format(self.comment_id)
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "DELETE")
|
||||
assert delete_comment(self.request, self.comment_id) is None
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/comments/{}'.format(self.comment_id) # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().method == 'DELETE'
|
||||
|
||||
def test_comment_id_not_found(self):
|
||||
self.register_get_comment_error_response("missing_comment", 404)
|
||||
with self.assertRaises(CommentNotFoundError):
|
||||
with pytest.raises(CommentNotFoundError):
|
||||
delete_comment(self.request, "missing_comment")
|
||||
|
||||
def test_nonexistent_course(self):
|
||||
self.register_comment_and_thread(
|
||||
thread_overrides={"course_id": "non/existent/course"}
|
||||
)
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
delete_comment(self.request, self.comment_id)
|
||||
|
||||
def test_not_enrolled(self):
|
||||
self.register_comment_and_thread()
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
delete_comment(self.request, self.comment_id)
|
||||
|
||||
def test_discussions_disabled(self):
|
||||
@@ -3175,7 +3032,7 @@ class DeleteCommentTest(
|
||||
thread_overrides={"course_id": six.text_type(disabled_course.id)},
|
||||
overrides={"course_id": six.text_type(disabled_course.id)}
|
||||
)
|
||||
with self.assertRaises(DiscussionDisabledError):
|
||||
with pytest.raises(DiscussionDisabledError):
|
||||
delete_comment(self.request, self.comment_id)
|
||||
|
||||
@ddt.data(
|
||||
@@ -3192,9 +3049,9 @@ class DeleteCommentTest(
|
||||
expected_error = role_name == FORUM_ROLE_STUDENT
|
||||
try:
|
||||
delete_comment(self.request, self.comment_id)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except PermissionDenied:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
@ddt.data(
|
||||
*itertools.product(
|
||||
@@ -3237,9 +3094,9 @@ class DeleteCommentTest(
|
||||
)
|
||||
try:
|
||||
delete_comment(self.request, self.comment_id)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -3292,15 +3149,15 @@ class RetrieveThreadTest(
|
||||
|
||||
def test_basic(self):
|
||||
self.register_thread({"resp_total": 2})
|
||||
self.assertEqual(get_thread(self.request, self.thread_id), self.expected_thread_data({
|
||||
"response_count": 2,
|
||||
"unread_comment_count": 1,
|
||||
}))
|
||||
self.assertEqual(httpretty.last_request().method, "GET")
|
||||
assert get_thread(self.request, self.thread_id) == self.expected_thread_data({
|
||||
'response_count': 2,
|
||||
'unread_comment_count': 1
|
||||
})
|
||||
assert httpretty.last_request().method == 'GET'
|
||||
|
||||
def test_thread_id_not_found(self):
|
||||
self.register_get_thread_error_response("missing_thread", 404)
|
||||
with self.assertRaises(ThreadNotFoundError):
|
||||
with pytest.raises(ThreadNotFoundError):
|
||||
get_thread(self.request, "missing_thread")
|
||||
|
||||
def test_nonauthor_enrolled_in_course(self):
|
||||
@@ -3309,16 +3166,16 @@ class RetrieveThreadTest(
|
||||
CourseEnrollmentFactory.create(user=non_author_user, course_id=self.course.id)
|
||||
self.register_thread()
|
||||
self.request.user = non_author_user
|
||||
self.assertEqual(get_thread(self.request, self.thread_id), self.expected_thread_data({
|
||||
"editable_fields": ["abuse_flagged", "following", "read", "voted"],
|
||||
"unread_comment_count": 1,
|
||||
}))
|
||||
self.assertEqual(httpretty.last_request().method, "GET")
|
||||
assert get_thread(self.request, self.thread_id) == self.expected_thread_data({
|
||||
'editable_fields': ['abuse_flagged', 'following', 'read', 'voted'],
|
||||
'unread_comment_count': 1
|
||||
})
|
||||
assert httpretty.last_request().method == 'GET'
|
||||
|
||||
def test_not_enrolled_in_course(self):
|
||||
self.register_thread()
|
||||
self.request.user = UserFactory.create()
|
||||
with self.assertRaises(CourseNotFoundError):
|
||||
with pytest.raises(CourseNotFoundError):
|
||||
get_thread(self.request, self.thread_id)
|
||||
|
||||
@ddt.data(
|
||||
@@ -3359,6 +3216,6 @@ class RetrieveThreadTest(
|
||||
)
|
||||
try:
|
||||
get_thread(self.request, self.thread_id)
|
||||
self.assertFalse(expected_error)
|
||||
assert not expected_error
|
||||
except ThreadNotFoundError:
|
||||
self.assertTrue(expected_error)
|
||||
assert expected_error
|
||||
|
||||
@@ -59,37 +59,28 @@ class ThreadListGetFormTest(FormTestMixin, PaginationTestMixin, TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
form = self.get_form(expected_valid=True)
|
||||
self.assertEqual(
|
||||
form.cleaned_data,
|
||||
{
|
||||
"course_id": CourseLocator.from_string("Foo/Bar/Baz"),
|
||||
"page": 2,
|
||||
"page_size": 13,
|
||||
"topic_id": set(),
|
||||
"text_search": "",
|
||||
"following": None,
|
||||
"view": "",
|
||||
"order_by": "last_activity_at",
|
||||
"order_direction": "desc",
|
||||
"requested_fields": set(),
|
||||
}
|
||||
)
|
||||
assert form.cleaned_data == {
|
||||
'course_id': CourseLocator.from_string('Foo/Bar/Baz'),
|
||||
'page': 2,
|
||||
'page_size': 13,
|
||||
'topic_id': set(),
|
||||
'text_search': '',
|
||||
'following': None,
|
||||
'view': '',
|
||||
'order_by': 'last_activity_at',
|
||||
'order_direction': 'desc',
|
||||
'requested_fields': set()
|
||||
}
|
||||
|
||||
def test_topic_id(self):
|
||||
self.form_data.setlist("topic_id", ["example topic_id", "example 2nd topic_id"])
|
||||
form = self.get_form(expected_valid=True)
|
||||
self.assertEqual(
|
||||
form.cleaned_data["topic_id"],
|
||||
{"example topic_id", "example 2nd topic_id"},
|
||||
)
|
||||
assert form.cleaned_data['topic_id'] == {'example topic_id', 'example 2nd topic_id'}
|
||||
|
||||
def test_text_search(self):
|
||||
self.form_data["text_search"] = "test search string"
|
||||
form = self.get_form(expected_valid=True)
|
||||
self.assertEqual(
|
||||
form.cleaned_data["text_search"],
|
||||
"test search string",
|
||||
)
|
||||
assert form.cleaned_data['text_search'] == 'test search string'
|
||||
|
||||
def test_missing_course_id(self):
|
||||
self.form_data.pop("course_id")
|
||||
@@ -159,10 +150,7 @@ class ThreadListGetFormTest(FormTestMixin, PaginationTestMixin, TestCase):
|
||||
def test_requested_fields(self):
|
||||
self.form_data["requested_fields"] = "profile_image"
|
||||
form = self.get_form(expected_valid=True)
|
||||
self.assertEqual(
|
||||
form.cleaned_data["requested_fields"],
|
||||
{"profile_image"},
|
||||
)
|
||||
assert form.cleaned_data['requested_fields'] == {'profile_image'}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -181,16 +169,13 @@ class CommentListGetFormTest(FormTestMixin, PaginationTestMixin, TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
form = self.get_form(expected_valid=True)
|
||||
self.assertEqual(
|
||||
form.cleaned_data,
|
||||
{
|
||||
"thread_id": "deadbeef",
|
||||
"endorsed": False,
|
||||
"page": 2,
|
||||
"page_size": 13,
|
||||
"requested_fields": set(),
|
||||
}
|
||||
)
|
||||
assert form.cleaned_data == {
|
||||
'thread_id': 'deadbeef',
|
||||
'endorsed': False,
|
||||
'page': 2,
|
||||
'page_size': 13,
|
||||
'requested_fields': set()
|
||||
}
|
||||
|
||||
def test_missing_thread_id(self):
|
||||
self.form_data.pop("thread_id")
|
||||
@@ -217,7 +202,4 @@ class CommentListGetFormTest(FormTestMixin, PaginationTestMixin, TestCase):
|
||||
def test_requested_fields(self):
|
||||
self.form_data["requested_fields"] = {"profile_image"}
|
||||
form = self.get_form(expected_valid=True)
|
||||
self.assertEqual(
|
||||
form.cleaned_data["requested_fields"],
|
||||
{"profile_image"},
|
||||
)
|
||||
assert form.cleaned_data['requested_fields'] == {'profile_image'}
|
||||
|
||||
@@ -22,7 +22,7 @@ class PaginationSerializerTest(TestCase):
|
||||
request = RequestFactory().get("/test")
|
||||
paginator = DiscussionAPIPagination(request, page_num, num_pages)
|
||||
actual = paginator.get_paginated_response(objects)
|
||||
self.assertEqual(actual.data, expected)
|
||||
assert actual.data == expected
|
||||
|
||||
def test_empty(self):
|
||||
self.do_case(
|
||||
|
||||
@@ -48,7 +48,7 @@ class GetInitializableFieldsTest(ModuleStoreTestCase):
|
||||
}
|
||||
if is_privileged and is_cohorted:
|
||||
expected |= {"group_id"}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
@ddt.data(*itertools.product([True, False], ["question", "discussion"], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -64,7 +64,7 @@ class GetInitializableFieldsTest(ModuleStoreTestCase):
|
||||
}
|
||||
if (is_thread_author and thread_type == "question") or is_privileged:
|
||||
expected |= {"endorsed"}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -85,7 +85,7 @@ class GetEditableFieldsTest(ModuleStoreTestCase):
|
||||
expected |= {"topic_id", "type", "title", "raw_body"}
|
||||
if is_privileged and is_cohorted:
|
||||
expected |= {"group_id"}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False], ["question", "discussion"], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -102,7 +102,7 @@ class GetEditableFieldsTest(ModuleStoreTestCase):
|
||||
expected |= {"raw_body"}
|
||||
if (is_thread_author and thread_type == "question") or is_privileged:
|
||||
expected |= {"endorsed"}
|
||||
self.assertEqual(actual, expected)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -113,7 +113,7 @@ class CanDeleteTest(ModuleStoreTestCase):
|
||||
def test_thread(self, is_author, is_privileged):
|
||||
thread = Thread(user_id="5" if is_author else "6")
|
||||
context = _get_context(requester_id="5", is_requester_privileged=is_privileged)
|
||||
self.assertEqual(can_delete(thread, context), is_author or is_privileged)
|
||||
assert can_delete(thread, context) == (is_author or is_privileged)
|
||||
|
||||
@ddt.data(*itertools.product([True, False], [True, False], [True, False]))
|
||||
@ddt.unpack
|
||||
@@ -124,4 +124,4 @@ class CanDeleteTest(ModuleStoreTestCase):
|
||||
is_requester_privileged=is_privileged,
|
||||
thread=Thread(user_id="5" if is_thread_author else "6")
|
||||
)
|
||||
self.assertEqual(can_delete(comment, context), is_author or is_privileged)
|
||||
assert can_delete(comment, context) == (is_author or is_privileged)
|
||||
|
||||
@@ -20,7 +20,7 @@ class RenderBodyTest(TestCase):
|
||||
"""Tests for render_body"""
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(render_body(""), "")
|
||||
assert render_body('') == ''
|
||||
|
||||
@ddt.data(
|
||||
("*", "em"),
|
||||
@@ -29,10 +29,8 @@ class RenderBodyTest(TestCase):
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_markdown_inline(self, delimiter, tag):
|
||||
self.assertEqual(
|
||||
render_body(u"{delimiter}some text{delimiter}".format(delimiter=delimiter)),
|
||||
u"<p><{tag}>some text</{tag}></p>".format(tag=tag)
|
||||
)
|
||||
assert render_body(u'{delimiter}some text{delimiter}'.format(delimiter=delimiter)) == \
|
||||
u'<p><{tag}>some text</{tag}></p>'.format(tag=tag)
|
||||
|
||||
@ddt.data(
|
||||
"b", "blockquote", "code", "del", "dd", "dl", "dt", "em", "h1", "h2", "h3", "i", "kbd",
|
||||
@@ -42,52 +40,49 @@ class RenderBodyTest(TestCase):
|
||||
raw_body = "<{tag}>some text</{tag}>".format(tag=tag)
|
||||
is_inline_tag = tag in ["b", "code", "del", "em", "i", "kbd", "s", "sup", "sub", "strong", "strike"]
|
||||
rendered_body = _add_p_tags(raw_body) if is_inline_tag else raw_body
|
||||
self.assertEqual(render_body(raw_body), rendered_body)
|
||||
assert render_body(raw_body) == rendered_body
|
||||
|
||||
@ddt.data("br", "hr")
|
||||
def test_selfclosing_tag(self, tag):
|
||||
raw_body = "<{tag}>".format(tag=tag)
|
||||
is_inline_tag = tag == "br"
|
||||
rendered_body = _add_p_tags(raw_body) if is_inline_tag else raw_body
|
||||
self.assertEqual(render_body(raw_body), rendered_body)
|
||||
assert render_body(raw_body) == rendered_body
|
||||
|
||||
@ddt.data("http", "https", "ftp")
|
||||
def test_allowed_a_tag(self, protocol):
|
||||
raw_body = '<a href="{protocol}://foo" title="bar">baz</a>'.format(protocol=protocol)
|
||||
self.assertEqual(render_body(raw_body), _add_p_tags(raw_body))
|
||||
assert render_body(raw_body) == _add_p_tags(raw_body)
|
||||
|
||||
def test_disallowed_a_tag(self):
|
||||
raw_body = '<a href="gopher://foo">link content</a>'
|
||||
self.assertEqual(render_body(raw_body), "<p>link content</p>")
|
||||
assert render_body(raw_body) == '<p>link content</p>'
|
||||
|
||||
@ddt.data("http", "https")
|
||||
def test_allowed_img_tag(self, protocol):
|
||||
raw_body = '<img src="{protocol}://foo" width="111" height="222" alt="bar" title="baz">'.format(
|
||||
protocol=protocol
|
||||
)
|
||||
self.assertEqual(render_body(raw_body), _add_p_tags(raw_body))
|
||||
assert render_body(raw_body) == _add_p_tags(raw_body)
|
||||
|
||||
def test_disallowed_img_tag(self):
|
||||
raw_body = '<img src="gopher://foo">'
|
||||
self.assertEqual(render_body(raw_body), "<p></p>")
|
||||
assert render_body(raw_body) == '<p></p>'
|
||||
|
||||
def test_script_tag(self):
|
||||
raw_body = '<script type="text/javascript">alert("evil script");</script>'
|
||||
self.assertEqual(render_body(raw_body), 'alert("evil script");')
|
||||
assert render_body(raw_body) == 'alert("evil script");'
|
||||
|
||||
@ddt.data("p", "br", "li", "hr") # img is tested above
|
||||
def test_allowed_unpaired_tags(self, tag):
|
||||
raw_body = "foo<{tag}>bar".format(tag=tag)
|
||||
self.assertEqual(render_body(raw_body), _add_p_tags(raw_body))
|
||||
assert render_body(raw_body) == _add_p_tags(raw_body)
|
||||
|
||||
def test_unpaired_start_tag(self):
|
||||
self.assertEqual(render_body("foo<i>bar"), "<p>foobar</p>")
|
||||
assert render_body('foo<i>bar') == '<p>foobar</p>'
|
||||
|
||||
def test_unpaired_end_tag(self):
|
||||
self.assertEqual(render_body("foo</i>bar"), "<p>foobar</p>")
|
||||
assert render_body('foo</i>bar') == '<p>foobar</p>'
|
||||
|
||||
def test_interleaved_tags(self):
|
||||
self.assertEqual(
|
||||
render_body("foo<i>bar<b>baz</i>quux</b>greg"),
|
||||
"<p>foo<i>barbaz</i>quuxgreg</p>"
|
||||
)
|
||||
assert render_body('foo<i>bar<b>baz</i>quux</b>greg') == '<p>foo<i>barbaz</i>quuxgreg</p>'
|
||||
|
||||
@@ -100,7 +100,7 @@ class SerializerTestMixin(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetM
|
||||
self.make_cs_content({"anonymous": anonymous, "anonymous_to_peers": anonymous_to_peers})
|
||||
)
|
||||
actual_serialized_anonymous = serialized["author"] is None
|
||||
self.assertEqual(actual_serialized_anonymous, expected_serialized_anonymous)
|
||||
assert actual_serialized_anonymous == expected_serialized_anonymous
|
||||
|
||||
@ddt.data(
|
||||
(FORUM_ROLE_ADMINISTRATOR, False, "Staff"),
|
||||
@@ -128,17 +128,17 @@ class SerializerTestMixin(ForumsEnableMixin, CommentsServiceMockMixin, UrlResetM
|
||||
"""
|
||||
self.create_role(role_name, [self.author])
|
||||
serialized = self.serialize(self.make_cs_content({"anonymous": anonymous}))
|
||||
self.assertEqual(serialized["author_label"], expected_label)
|
||||
assert serialized['author_label'] == expected_label
|
||||
|
||||
def test_abuse_flagged(self):
|
||||
serialized = self.serialize(self.make_cs_content({"abuse_flaggers": [str(self.user.id)]}))
|
||||
self.assertEqual(serialized["abuse_flagged"], True)
|
||||
assert serialized['abuse_flagged'] is True
|
||||
|
||||
def test_voted(self):
|
||||
thread_id = "test_thread"
|
||||
self.register_get_user_response(self.user, upvoted_ids=[thread_id])
|
||||
serialized = self.serialize(self.make_cs_content({"id": thread_id}))
|
||||
self.assertEqual(serialized["voted"], True)
|
||||
assert serialized['voted'] is True
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -188,7 +188,7 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
|
||||
"pinned": True,
|
||||
"editable_fields": ["abuse_flagged", "following", "read", "voted"],
|
||||
})
|
||||
self.assertEqual(self.serialize(thread), expected)
|
||||
assert self.serialize(thread) == expected
|
||||
|
||||
thread["thread_type"] = "question"
|
||||
expected.update({
|
||||
@@ -201,7 +201,7 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
|
||||
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread&endorsed=False"
|
||||
),
|
||||
})
|
||||
self.assertEqual(self.serialize(thread), expected)
|
||||
assert self.serialize(thread) == expected
|
||||
|
||||
def test_pinned_missing(self):
|
||||
"""
|
||||
@@ -212,34 +212,34 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
|
||||
del thread_data["pinned"]
|
||||
self.register_get_thread_response(thread_data)
|
||||
serialized = self.serialize(thread_data)
|
||||
self.assertEqual(serialized["pinned"], False)
|
||||
assert serialized['pinned'] is False
|
||||
|
||||
def test_group(self):
|
||||
self.course.cohort_config = {"cohorted": True}
|
||||
modulestore().update_item(self.course, ModuleStoreEnum.UserID.test)
|
||||
cohort = CohortFactory.create(course_id=self.course.id)
|
||||
serialized = self.serialize(self.make_cs_content({"group_id": cohort.id}))
|
||||
self.assertEqual(serialized["group_id"], cohort.id)
|
||||
self.assertEqual(serialized["group_name"], cohort.name)
|
||||
assert serialized['group_id'] == cohort.id
|
||||
assert serialized['group_name'] == cohort.name
|
||||
|
||||
def test_following(self):
|
||||
thread_id = "test_thread"
|
||||
self.register_get_user_response(self.user, subscribed_thread_ids=[thread_id])
|
||||
serialized = self.serialize(self.make_cs_content({"id": thread_id}))
|
||||
self.assertEqual(serialized["following"], True)
|
||||
assert serialized['following'] is True
|
||||
|
||||
def test_response_count(self):
|
||||
thread_data = self.make_cs_content({"resp_total": 2})
|
||||
self.register_get_thread_response(thread_data)
|
||||
serialized = self.serialize(thread_data)
|
||||
self.assertEqual(serialized["response_count"], 2)
|
||||
assert serialized['response_count'] == 2
|
||||
|
||||
def test_response_count_missing(self):
|
||||
thread_data = self.make_cs_content({})
|
||||
del thread_data["resp_total"]
|
||||
self.register_get_thread_response(thread_data)
|
||||
serialized = self.serialize(thread_data)
|
||||
self.assertNotIn("response_count", serialized)
|
||||
assert 'response_count' not in serialized
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -313,7 +313,7 @@ class CommentSerializerTest(SerializerTestMixin, SharedModuleStoreTestCase):
|
||||
"editable_fields": ["abuse_flagged", "voted"],
|
||||
"child_count": 0,
|
||||
}
|
||||
self.assertEqual(self.serialize(comment), expected)
|
||||
assert self.serialize(comment) == expected
|
||||
|
||||
@ddt.data(
|
||||
*itertools.product(
|
||||
@@ -344,7 +344,7 @@ class CommentSerializerTest(SerializerTestMixin, SharedModuleStoreTestCase):
|
||||
)
|
||||
actual_endorser_anonymous = serialized["endorsed_by"] is None
|
||||
expected_endorser_anonymous = endorser_role_name == FORUM_ROLE_STUDENT and thread_anonymous
|
||||
self.assertEqual(actual_endorser_anonymous, expected_endorser_anonymous)
|
||||
assert actual_endorser_anonymous == expected_endorser_anonymous
|
||||
|
||||
@ddt.data(
|
||||
(FORUM_ROLE_ADMINISTRATOR, "Staff"),
|
||||
@@ -366,11 +366,11 @@ class CommentSerializerTest(SerializerTestMixin, SharedModuleStoreTestCase):
|
||||
"""
|
||||
self.create_role(role_name, [self.endorser])
|
||||
serialized = self.serialize(self.make_cs_content(with_endorsement=True))
|
||||
self.assertEqual(serialized["endorsed_by_label"], expected_label)
|
||||
assert serialized['endorsed_by_label'] == expected_label
|
||||
|
||||
def test_endorsed_at(self):
|
||||
serialized = self.serialize(self.make_cs_content(with_endorsement=True))
|
||||
self.assertEqual(serialized["endorsed_at"], self.endorsed_at)
|
||||
assert serialized['endorsed_at'] == self.endorsed_at
|
||||
|
||||
def test_children(self):
|
||||
comment = self.make_cs_content({
|
||||
@@ -393,12 +393,12 @@ class CommentSerializerTest(SerializerTestMixin, SharedModuleStoreTestCase):
|
||||
],
|
||||
})
|
||||
serialized = self.serialize(comment)
|
||||
self.assertEqual(serialized["children"][0]["id"], "test_child_1")
|
||||
self.assertEqual(serialized["children"][0]["parent_id"], "test_root")
|
||||
self.assertEqual(serialized["children"][1]["id"], "test_child_2")
|
||||
self.assertEqual(serialized["children"][1]["parent_id"], "test_root")
|
||||
self.assertEqual(serialized["children"][1]["children"][0]["id"], "test_grandchild")
|
||||
self.assertEqual(serialized["children"][1]["children"][0]["parent_id"], "test_child_2")
|
||||
assert serialized['children'][0]['id'] == 'test_child_1'
|
||||
assert serialized['children'][0]['parent_id'] == 'test_root'
|
||||
assert serialized['children'][1]['id'] == 'test_child_2'
|
||||
assert serialized['children'][1]['parent_id'] == 'test_root'
|
||||
assert serialized['children'][1]['children'][0]['id'] == 'test_grandchild'
|
||||
assert serialized['children'][1]['children'][0]['parent_id'] == 'test_child_2'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -458,69 +458,57 @@ class ThreadSerializerDeserializationTest(
|
||||
partial=(instance is not None),
|
||||
context=get_context(self.course, self.request)
|
||||
)
|
||||
self.assertTrue(serializer.is_valid())
|
||||
assert serializer.is_valid()
|
||||
serializer.save()
|
||||
return serializer.data
|
||||
|
||||
def test_create_minimal(self):
|
||||
self.register_post_thread_response({"id": "test_id", "username": self.user.username})
|
||||
saved = self.save_and_reserialize(self.minimal_data)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/test_topic/threads"
|
||||
)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"commentable_id": ["test_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Test Title"],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
}
|
||||
)
|
||||
self.assertEqual(saved["id"], "test_id")
|
||||
assert urlparse(httpretty.last_request().path).path ==\
|
||||
'/api/v1/test_topic/threads' # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'commentable_id': ['test_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Test Title'],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)]
|
||||
}
|
||||
assert saved['id'] == 'test_id'
|
||||
|
||||
def test_create_all_fields(self):
|
||||
self.register_post_thread_response({"id": "test_id", "username": self.user.username})
|
||||
data = self.minimal_data.copy()
|
||||
data["group_id"] = 42
|
||||
self.save_and_reserialize(data)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"commentable_id": ["test_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Test Title"],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"group_id": ["42"],
|
||||
}
|
||||
)
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'commentable_id': ['test_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Test Title'],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'group_id': ['42']
|
||||
}
|
||||
|
||||
def test_create_missing_field(self):
|
||||
for field in self.minimal_data:
|
||||
data = self.minimal_data.copy()
|
||||
data.pop(field)
|
||||
serializer = ThreadSerializer(data=data)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{field: ["This field is required."]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {field: ['This field is required.']}
|
||||
|
||||
@ddt.data("", " ")
|
||||
def test_create_empty_string(self, value):
|
||||
data = self.minimal_data.copy()
|
||||
data.update({field: value for field in ["topic_id", "title", "raw_body"]})
|
||||
serializer = ThreadSerializer(data=data, context=get_context(self.course, self.request))
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{field: ["This field may not be blank."] for field in ["topic_id", "title", "raw_body"]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {
|
||||
field: ['This field may not be blank.'] for field in ['topic_id', 'title', 'raw_body']
|
||||
}
|
||||
|
||||
def test_create_type(self):
|
||||
self.register_post_thread_response({"id": "test_id", "username": self.user.username})
|
||||
@@ -530,27 +518,24 @@ class ThreadSerializerDeserializationTest(
|
||||
|
||||
data["type"] = "invalid_type"
|
||||
serializer = ThreadSerializer(data=data)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
assert not serializer.is_valid()
|
||||
|
||||
def test_update_empty(self):
|
||||
self.register_put_thread_response(self.existing_thread.attributes)
|
||||
self.save_and_reserialize({}, self.existing_thread)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"commentable_id": ["original_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Original Title"],
|
||||
"body": ["Original body"],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"closed": ["False"],
|
||||
"pinned": ["False"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"read": ["False"],
|
||||
}
|
||||
)
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'commentable_id': ['original_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Original Title'],
|
||||
'body': ['Original body'],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'closed': ['False'],
|
||||
'pinned': ['False'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'read': ['False']
|
||||
}
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_update_all(self, read):
|
||||
@@ -563,24 +548,21 @@ class ThreadSerializerDeserializationTest(
|
||||
"read": read,
|
||||
}
|
||||
saved = self.save_and_reserialize(data, self.existing_thread)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"commentable_id": ["edited_topic"],
|
||||
"thread_type": ["question"],
|
||||
"title": ["Edited Title"],
|
||||
"body": ["Edited body"],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"closed": ["False"],
|
||||
"pinned": ["False"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"read": [str(read)],
|
||||
}
|
||||
)
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'commentable_id': ['edited_topic'],
|
||||
'thread_type': ['question'],
|
||||
'title': ['Edited Title'],
|
||||
'body': ['Edited body'],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'closed': ['False'],
|
||||
'pinned': ['False'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'read': [str(read)]
|
||||
}
|
||||
for key in data:
|
||||
self.assertEqual(saved[key], data[key])
|
||||
assert saved[key] == data[key]
|
||||
|
||||
@ddt.data("", " ")
|
||||
def test_update_empty_string(self, value):
|
||||
@@ -590,11 +572,10 @@ class ThreadSerializerDeserializationTest(
|
||||
partial=True,
|
||||
context=get_context(self.course, self.request)
|
||||
)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{field: ["This field may not be blank."] for field in ["topic_id", "title", "raw_body"]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {
|
||||
field: ['This field may not be blank.'] for field in ['topic_id', 'title', 'raw_body']
|
||||
}
|
||||
|
||||
def test_update_course_id(self):
|
||||
serializer = ThreadSerializer(
|
||||
@@ -603,11 +584,8 @@ class ThreadSerializerDeserializationTest(
|
||||
partial=True,
|
||||
context=get_context(self.course, self.request)
|
||||
)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{"course_id": ["This field is not allowed in an update."]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {'course_id': ['This field is not allowed in an update.']}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -657,7 +635,7 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
partial=(instance is not None),
|
||||
context=context
|
||||
)
|
||||
self.assertTrue(serializer.is_valid())
|
||||
assert serializer.is_valid()
|
||||
serializer.save()
|
||||
return serializer.data
|
||||
|
||||
@@ -677,17 +655,14 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
"/api/v1/comments/{}".format(parent_id) if parent_id else
|
||||
"/api/v1/threads/test_thread/comments"
|
||||
)
|
||||
self.assertEqual(urlparse(httpretty.last_request().path).path, expected_url) # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
}
|
||||
)
|
||||
self.assertEqual(saved["id"], "test_comment")
|
||||
self.assertEqual(saved["parent_id"], parent_id)
|
||||
assert urlparse(httpretty.last_request().path).path == expected_url # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)]
|
||||
}
|
||||
assert saved['id'] == 'test_comment'
|
||||
assert saved['parent_id'] == parent_id
|
||||
|
||||
def test_create_all_fields(self):
|
||||
data = self.minimal_data.copy()
|
||||
@@ -700,15 +675,12 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
parent_id="test_parent"
|
||||
)
|
||||
self.save_and_reserialize(data)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"endorsed": ["True"],
|
||||
}
|
||||
)
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'endorsed': ['True']
|
||||
}
|
||||
|
||||
def test_create_parent_id_nonexistent(self):
|
||||
self.register_get_comment_error_response("bad_parent", 404)
|
||||
@@ -716,15 +688,10 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
data["parent_id"] = "bad_parent"
|
||||
context = get_context(self.course, self.request, make_minimal_cs_thread())
|
||||
serializer = CommentSerializer(data=data, context=context)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{
|
||||
"non_field_errors": [
|
||||
"parent_id does not identify a comment in the thread identified by thread_id."
|
||||
]
|
||||
}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {
|
||||
'non_field_errors': ['parent_id does not identify a comment in the thread identified by thread_id.']
|
||||
}
|
||||
|
||||
def test_create_parent_id_wrong_thread(self):
|
||||
self.register_get_comment_response({"thread_id": "different_thread", "id": "test_parent"})
|
||||
@@ -732,15 +699,10 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
data["parent_id"] = "test_parent"
|
||||
context = get_context(self.course, self.request, make_minimal_cs_thread())
|
||||
serializer = CommentSerializer(data=data, context=context)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{
|
||||
"non_field_errors": [
|
||||
"parent_id does not identify a comment in the thread identified by thread_id."
|
||||
]
|
||||
}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {
|
||||
'non_field_errors': ['parent_id does not identify a comment in the thread identified by thread_id.']
|
||||
}
|
||||
|
||||
@ddt.data(None, -1, 0, 2, 5)
|
||||
def test_create_parent_id_too_deep(self, max_depth):
|
||||
@@ -758,7 +720,7 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
else:
|
||||
data["parent_id"] = None
|
||||
serializer = CommentSerializer(data=data, context=context)
|
||||
self.assertTrue(serializer.is_valid(), serializer.errors)
|
||||
assert serializer.is_valid(), serializer.errors
|
||||
if max_depth is not None:
|
||||
if max_depth >= 0:
|
||||
self.register_get_comment_response({
|
||||
@@ -770,8 +732,8 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
else:
|
||||
data["parent_id"] = None
|
||||
serializer = CommentSerializer(data=data, context=context)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(serializer.errors, {"non_field_errors": ["Comment level is too deep."]})
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {'non_field_errors': ['Comment level is too deep.']}
|
||||
|
||||
def test_create_missing_field(self):
|
||||
for field in self.minimal_data:
|
||||
@@ -781,11 +743,8 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
data=data,
|
||||
context=get_context(self.course, self.request, make_minimal_cs_thread())
|
||||
)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{field: ["This field is required."]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {field: ['This field is required.']}
|
||||
|
||||
def test_create_endorsed(self):
|
||||
# TODO: The comments service doesn't populate the endorsement field on
|
||||
@@ -794,34 +753,28 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
data = self.minimal_data.copy()
|
||||
data["endorsed"] = True
|
||||
saved = self.save_and_reserialize(data)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"endorsed": ["True"],
|
||||
}
|
||||
)
|
||||
self.assertTrue(saved["endorsed"])
|
||||
self.assertIsNone(saved["endorsed_by"])
|
||||
self.assertIsNone(saved["endorsed_by_label"])
|
||||
self.assertIsNone(saved["endorsed_at"])
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'endorsed': ['True']
|
||||
}
|
||||
assert saved['endorsed']
|
||||
assert saved['endorsed_by'] is None
|
||||
assert saved['endorsed_by_label'] is None
|
||||
assert saved['endorsed_at'] is None
|
||||
|
||||
def test_update_empty(self):
|
||||
self.register_put_comment_response(self.existing_comment.attributes)
|
||||
self.save_and_reserialize({}, instance=self.existing_comment)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"body": ["Original body"],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"user_id": [str(self.user.id)],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"endorsed": ["False"],
|
||||
}
|
||||
)
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'body': ['Original body'],
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'user_id': [str(self.user.id)],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'endorsed': ['False']
|
||||
}
|
||||
|
||||
def test_update_all(self):
|
||||
cs_response_data = self.existing_comment.attributes.copy()
|
||||
@@ -832,22 +785,19 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
self.register_put_comment_response(cs_response_data)
|
||||
data = {"raw_body": "Edited body", "endorsed": True}
|
||||
saved = self.save_and_reserialize(data, instance=self.existing_comment)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"body": ["Edited body"],
|
||||
"course_id": [six.text_type(self.course.id)],
|
||||
"user_id": [str(self.user.id)],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"endorsed": ["True"],
|
||||
"endorsement_user_id": [str(self.user.id)],
|
||||
}
|
||||
)
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'body': ['Edited body'],
|
||||
'course_id': [six.text_type(self.course.id)],
|
||||
'user_id': [str(self.user.id)],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'endorsed': ['True'],
|
||||
'endorsement_user_id': [str(self.user.id)]
|
||||
}
|
||||
for key in data:
|
||||
self.assertEqual(saved[key], data[key])
|
||||
self.assertEqual(saved["endorsed_by"], self.user.username)
|
||||
self.assertEqual(saved["endorsed_at"], "2015-06-05T00:00:00Z")
|
||||
assert saved[key] == data[key]
|
||||
assert saved['endorsed_by'] == self.user.username
|
||||
assert saved['endorsed_at'] == '2015-06-05T00:00:00Z'
|
||||
|
||||
@ddt.data("", " ")
|
||||
def test_update_empty_raw_body(self, value):
|
||||
@@ -857,11 +807,8 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
partial=True,
|
||||
context=get_context(self.course, self.request)
|
||||
)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{"raw_body": ["This field may not be blank."]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {'raw_body': ['This field may not be blank.']}
|
||||
|
||||
@ddt.data("thread_id", "parent_id")
|
||||
def test_update_non_updatable(self, field):
|
||||
@@ -871,8 +818,5 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, CommentsServiceMoc
|
||||
partial=True,
|
||||
context=get_context(self.course, self.request)
|
||||
)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
{field: ["This field is not allowed in an update."]}
|
||||
)
|
||||
assert not serializer.is_valid()
|
||||
assert serializer.errors == {field: ['This field is not allowed in an update.']}
|
||||
|
||||
@@ -82,9 +82,9 @@ class DiscussionAPIViewTestMixin(ForumsEnableMixin, CommentsServiceMockMixin, Ur
|
||||
"""
|
||||
Assert that the response has the given status code and parsed content
|
||||
"""
|
||||
self.assertEqual(response.status_code, expected_status)
|
||||
assert response.status_code == expected_status
|
||||
parsed_content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(parsed_content, expected_content)
|
||||
assert parsed_content == expected_content
|
||||
|
||||
def register_thread(self, overrides=None):
|
||||
"""
|
||||
@@ -190,10 +190,10 @@ class RetireViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
"""
|
||||
Assert that the response has the given status code and content
|
||||
"""
|
||||
self.assertEqual(response.status_code, expected_status)
|
||||
assert response.status_code == expected_status
|
||||
|
||||
if expected_content:
|
||||
self.assertEqual(response.content.decode('utf-8'), expected_content)
|
||||
assert response.content.decode('utf-8') == expected_content
|
||||
|
||||
def build_jwt_headers(self, user):
|
||||
"""
|
||||
@@ -258,10 +258,10 @@ class ReplaceUsernamesViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
"""
|
||||
Assert that the response has the given status code and content
|
||||
"""
|
||||
self.assertEqual(response.status_code, expected_status)
|
||||
assert response.status_code == expected_status
|
||||
|
||||
if expected_content:
|
||||
self.assertEqual(text_type(response.content), expected_content)
|
||||
assert text_type(response.content) == expected_content
|
||||
|
||||
def build_jwt_headers(self, user):
|
||||
"""
|
||||
@@ -288,7 +288,7 @@ class ReplaceUsernamesViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
"username_mappings": mapping_data
|
||||
}
|
||||
response = self.call_api(self.client_user, data)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_auth(self):
|
||||
""" Verify the endpoint only works with the service worker """
|
||||
@@ -301,16 +301,16 @@ class ReplaceUsernamesViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
|
||||
# Test unauthenticated
|
||||
response = self.client.post(self.url, data)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
assert response.status_code == 401
|
||||
|
||||
# Test non-service worker
|
||||
random_user = UserFactory()
|
||||
response = self.call_api(random_user, data)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
assert response.status_code == 403
|
||||
|
||||
# Test service worker
|
||||
response = self.call_api(self.client_user, data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_basic(self):
|
||||
""" Check successful replacement """
|
||||
@@ -325,8 +325,8 @@ class ReplaceUsernamesViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
}
|
||||
self.register_get_username_replacement_response(self.user)
|
||||
response = self.call_api(self.client_user, data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data, expected_response)
|
||||
assert response.status_code == 200
|
||||
assert response.data == expected_response
|
||||
|
||||
def test_not_authenticated(self):
|
||||
"""
|
||||
@@ -663,10 +663,9 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pro
|
||||
200,
|
||||
expected_response
|
||||
)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/users/{}/subscribed_threads".format(self.user.id)
|
||||
)
|
||||
assert urlparse(
|
||||
httpretty.last_request().path # lint-amnesty, pylint: disable=no-member
|
||||
).path == '/api/v1/users/{}/subscribed_threads'.format(self.user.id)
|
||||
|
||||
@ddt.data(False, "false", "0")
|
||||
def test_following_false(self, following):
|
||||
@@ -798,13 +797,13 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pro
|
||||
self.url,
|
||||
{"course_id": text_type(self.course.id), "requested_fields": "profile_image"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_threads = json.loads(response.content.decode('utf-8'))['results']
|
||||
|
||||
for response_thread in response_threads:
|
||||
expected_profile_data = self.get_expected_user_profile(response_thread['author'])
|
||||
response_users = response_thread['users']
|
||||
self.assertEqual(expected_profile_data, response_users[response_thread['author']])
|
||||
assert expected_profile_data == response_users[response_thread['author']]
|
||||
|
||||
def test_profile_image_requested_field_anonymous_user(self):
|
||||
"""
|
||||
@@ -823,10 +822,10 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pro
|
||||
self.url,
|
||||
{"course_id": text_type(self.course.id), "requested_fields": "profile_image"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_thread = json.loads(response.content.decode('utf-8'))['results'][0]
|
||||
self.assertIsNone(response_thread['author'])
|
||||
self.assertEqual({}, response_thread['users'])
|
||||
assert response_thread['author'] is None
|
||||
assert {} == response_thread['users']
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
@@ -858,20 +857,17 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
json.dumps(request_data),
|
||||
content_type="application/json"
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data, self.expected_thread_data({"read": True}))
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [text_type(self.course.id)],
|
||||
"commentable_id": ["test_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Test Title"],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
}
|
||||
)
|
||||
assert response_data == self.expected_thread_data({'read': True})
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [text_type(self.course.id)],
|
||||
'commentable_id': ['test_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Test Title'],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)]
|
||||
}
|
||||
|
||||
def test_error(self):
|
||||
request_data = {
|
||||
@@ -888,9 +884,9 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
expected_response_data = {
|
||||
"field_errors": {"course_id": {"developer_message": "This field is required."}}
|
||||
}
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data, expected_response_data)
|
||||
assert response_data == expected_response_data
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -914,39 +910,31 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
|
||||
})
|
||||
request_data = {"raw_body": "Edited body"}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data,
|
||||
self.expected_thread_data({
|
||||
"raw_body": "Edited body",
|
||||
"rendered_body": "<p>Edited body</p>",
|
||||
"editable_fields": [
|
||||
"abuse_flagged", "following", "raw_body", "read", "title", "topic_id", "type", "voted"
|
||||
],
|
||||
"created_at": "Test Created Date",
|
||||
"updated_at": "Test Updated Date",
|
||||
"comment_count": 1,
|
||||
"read": True,
|
||||
"response_count": 2,
|
||||
})
|
||||
)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [text_type(self.course.id)],
|
||||
"commentable_id": ["test_topic"],
|
||||
"thread_type": ["discussion"],
|
||||
"title": ["Test Title"],
|
||||
"body": ["Edited body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"closed": ["False"],
|
||||
"pinned": ["False"],
|
||||
"read": ["True"],
|
||||
}
|
||||
)
|
||||
assert response_data == self.expected_thread_data({
|
||||
'raw_body': 'Edited body',
|
||||
'rendered_body': '<p>Edited body</p>',
|
||||
'editable_fields': ['abuse_flagged', 'following', 'raw_body', 'read', 'title', 'topic_id', 'type', 'voted'],
|
||||
'created_at': 'Test Created Date',
|
||||
'updated_at': 'Test Updated Date',
|
||||
'comment_count': 1,
|
||||
'read': True,
|
||||
'response_count': 2
|
||||
})
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [text_type(self.course.id)],
|
||||
'commentable_id': ['test_topic'],
|
||||
'thread_type': ['discussion'],
|
||||
'title': ['Test Title'],
|
||||
'body': ['Edited body'],
|
||||
'user_id': [str(self.user.id)],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'closed': ['False'],
|
||||
'pinned': ['False'],
|
||||
'read': ['True']
|
||||
}
|
||||
|
||||
def test_error(self):
|
||||
self.register_get_user_response(self.user)
|
||||
@@ -956,9 +944,9 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
|
||||
expected_response_data = {
|
||||
"field_errors": {"title": {"developer_message": "This field may not be blank."}}
|
||||
}
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data, expected_response_data)
|
||||
assert response_data == expected_response_data
|
||||
|
||||
@ddt.data(
|
||||
("abuse_flagged", True),
|
||||
@@ -971,19 +959,15 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
|
||||
self.register_flag_response("thread", "test_thread")
|
||||
request_data = {field: value}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data,
|
||||
self.expected_thread_data({
|
||||
"read": True,
|
||||
"closed": True,
|
||||
"abuse_flagged": value,
|
||||
"editable_fields": ["abuse_flagged", "read"],
|
||||
"comment_count": 1,
|
||||
"unread_comment_count": 0,
|
||||
})
|
||||
)
|
||||
assert response_data == self.expected_thread_data({
|
||||
'read': True,
|
||||
'closed': True,
|
||||
'abuse_flagged': value,
|
||||
'editable_fields': ['abuse_flagged', 'read'],
|
||||
'comment_count': 1, 'unread_comment_count': 0
|
||||
})
|
||||
|
||||
@ddt.data(
|
||||
("raw_body", "Edited body"),
|
||||
@@ -997,7 +981,7 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
|
||||
self.register_flag_response("thread", "test_thread")
|
||||
request_data = {field: value}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_patch_read_owner_user(self):
|
||||
self.register_get_user_response(self.user)
|
||||
@@ -1006,19 +990,14 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
|
||||
request_data = {"read": True}
|
||||
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data,
|
||||
self.expected_thread_data({
|
||||
"comment_count": 1,
|
||||
"read": True,
|
||||
"editable_fields": [
|
||||
"abuse_flagged", "following", "raw_body", "read", "title", "topic_id", "type", "voted"
|
||||
],
|
||||
"response_count": 2,
|
||||
})
|
||||
)
|
||||
assert response_data == self.expected_thread_data({
|
||||
'comment_count': 1,
|
||||
'read': True,
|
||||
'editable_fields': ['abuse_flagged', 'following', 'raw_body', 'read', 'title', 'topic_id', 'type', 'voted'],
|
||||
'response_count': 2
|
||||
})
|
||||
|
||||
def test_patch_read_non_owner_user(self):
|
||||
self.register_get_user_response(self.user)
|
||||
@@ -1034,20 +1013,15 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
|
||||
|
||||
request_data = {"read": True}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data,
|
||||
self.expected_thread_data({
|
||||
"author": str(thread_owner_user.username),
|
||||
"comment_count": 1,
|
||||
"read": True,
|
||||
"editable_fields": [
|
||||
"abuse_flagged", "following", "read", "voted"
|
||||
],
|
||||
"response_count": 2,
|
||||
})
|
||||
)
|
||||
assert response_data == self.expected_thread_data({
|
||||
'author': str(thread_owner_user.username),
|
||||
'comment_count': 1,
|
||||
'read': True,
|
||||
'editable_fields': ['abuse_flagged', 'following', 'read', 'voted'],
|
||||
'response_count': 2
|
||||
})
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
@@ -1071,18 +1045,15 @@ class ThreadViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
self.register_get_thread_response(cs_thread)
|
||||
self.register_delete_thread_response(self.thread_id)
|
||||
response = self.client.delete(self.url)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(response.content, b"")
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/threads/{}".format(self.thread_id)
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "DELETE")
|
||||
assert response.status_code == 204
|
||||
assert response.content == b''
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads/{}'.format(self.thread_id) # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().method == 'DELETE'
|
||||
|
||||
def test_delete_nonexistent_thread(self):
|
||||
self.register_get_thread_error_response(self.thread_id, 404)
|
||||
response = self.client.delete(self.url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1277,7 +1248,7 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pr
|
||||
"endorsed": endorsed,
|
||||
})
|
||||
parsed_content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(parsed_content["results"][0]["id"], comment_id)
|
||||
assert parsed_content['results'][0]['id'] == comment_id
|
||||
|
||||
def test_question_invalid_endorsed(self):
|
||||
response = self.client.get(self.url, {
|
||||
@@ -1374,12 +1345,12 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pr
|
||||
self.create_profile_image(self.user, get_profile_image_storage())
|
||||
|
||||
response = self.client.get(self.url, {"thread_id": self.thread_id, "requested_fields": "profile_image"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_comments = json.loads(response.content.decode('utf-8'))['results']
|
||||
for response_comment in response_comments:
|
||||
expected_profile_data = self.get_expected_user_profile(response_comment['author'])
|
||||
response_users = response_comment['users']
|
||||
self.assertEqual(expected_profile_data, response_users[response_comment['author']])
|
||||
assert expected_profile_data == response_users[response_comment['author']]
|
||||
|
||||
def test_profile_image_requested_field_endorsed_comments(self):
|
||||
"""
|
||||
@@ -1417,14 +1388,14 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pr
|
||||
"endorsed": True,
|
||||
"requested_fields": "profile_image",
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_comments = json.loads(response.content.decode('utf-8'))['results']
|
||||
for response_comment in response_comments:
|
||||
expected_author_profile_data = self.get_expected_user_profile(response_comment['author'])
|
||||
expected_endorser_profile_data = self.get_expected_user_profile(response_comment['endorsed_by'])
|
||||
response_users = response_comment['users']
|
||||
self.assertEqual(expected_author_profile_data, response_users[response_comment['author']])
|
||||
self.assertEqual(expected_endorser_profile_data, response_users[response_comment['endorsed_by']])
|
||||
assert expected_author_profile_data == response_users[response_comment['author']]
|
||||
assert expected_endorser_profile_data == response_users[response_comment['endorsed_by']]
|
||||
|
||||
def test_profile_image_request_for_null_endorsed_by(self):
|
||||
"""
|
||||
@@ -1450,13 +1421,13 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, Pr
|
||||
"endorsed": True,
|
||||
"requested_fields": "profile_image",
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_comments = json.loads(response.content.decode('utf-8'))['results']
|
||||
for response_comment in response_comments:
|
||||
expected_author_profile_data = self.get_expected_user_profile(response_comment['author'])
|
||||
response_users = response_comment['users']
|
||||
self.assertEqual(expected_author_profile_data, response_users[response_comment['author']])
|
||||
self.assertNotIn(response_comment['endorsed_by'], response_users)
|
||||
assert expected_author_profile_data == response_users[response_comment['author']]
|
||||
assert response_comment['endorsed_by'] not in response_users
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
@@ -1487,18 +1458,15 @@ class CommentViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
self.register_get_comment_response(cs_comment)
|
||||
self.register_delete_comment_response(self.comment_id)
|
||||
response = self.client.delete(self.url)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(response.content, b"")
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/comments/{}".format(self.comment_id)
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "DELETE")
|
||||
assert response.status_code == 204
|
||||
assert response.content == b''
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/comments/{}'.format(self.comment_id) # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().method == 'DELETE'
|
||||
|
||||
def test_delete_nonexistent_comment(self):
|
||||
self.register_get_comment_error_response(self.comment_id, 404)
|
||||
response = self.client.delete(self.url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
@@ -1544,21 +1512,15 @@ class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
json.dumps(request_data),
|
||||
content_type="application/json"
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data, expected_response_data)
|
||||
self.assertEqual(
|
||||
urlparse(httpretty.last_request().path).path, # lint-amnesty, pylint: disable=no-member
|
||||
"/api/v1/threads/test_thread/comments"
|
||||
)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"course_id": [text_type(self.course.id)],
|
||||
"body": ["Test body"],
|
||||
"user_id": [str(self.user.id)],
|
||||
}
|
||||
)
|
||||
assert response_data == expected_response_data
|
||||
assert urlparse(httpretty.last_request().path).path == '/api/v1/threads/test_thread/comments' # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'course_id': [text_type(self.course.id)],
|
||||
'body': ['Test body'],
|
||||
'user_id': [str(self.user.id)]
|
||||
}
|
||||
|
||||
def test_error(self):
|
||||
response = self.client.post(
|
||||
@@ -1569,9 +1531,9 @@ class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
expected_response_data = {
|
||||
"field_errors": {"thread_id": {"developer_message": "This field is required."}}
|
||||
}
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data, expected_response_data)
|
||||
assert response_data == expected_response_data
|
||||
|
||||
def test_closed_thread(self):
|
||||
self.register_get_user_response(self.user)
|
||||
@@ -1586,7 +1548,7 @@ class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
|
||||
json.dumps(request_data),
|
||||
content_type="application/json"
|
||||
)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1637,29 +1599,23 @@ class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTes
|
||||
self.register_comment({"created_at": "Test Created Date", "updated_at": "Test Updated Date"})
|
||||
request_data = {"raw_body": "Edited body"}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data,
|
||||
self.expected_response_data({
|
||||
"raw_body": "Edited body",
|
||||
"rendered_body": "<p>Edited body</p>",
|
||||
"editable_fields": ["abuse_flagged", "raw_body", "voted"],
|
||||
"created_at": "Test Created Date",
|
||||
"updated_at": "Test Updated Date",
|
||||
})
|
||||
)
|
||||
self.assertEqual(
|
||||
httpretty.last_request().parsed_body, # lint-amnesty, pylint: disable=no-member
|
||||
{
|
||||
"body": ["Edited body"],
|
||||
"course_id": [text_type(self.course.id)],
|
||||
"user_id": [str(self.user.id)],
|
||||
"anonymous": ["False"],
|
||||
"anonymous_to_peers": ["False"],
|
||||
"endorsed": ["False"],
|
||||
}
|
||||
)
|
||||
assert response_data == self.expected_response_data({
|
||||
'raw_body': 'Edited body',
|
||||
'rendered_body': '<p>Edited body</p>',
|
||||
'editable_fields': ['abuse_flagged', 'raw_body', 'voted'],
|
||||
'created_at': 'Test Created Date',
|
||||
'updated_at': 'Test Updated Date'
|
||||
})
|
||||
assert httpretty.last_request().parsed_body == { # lint-amnesty, pylint: disable=no-member
|
||||
'body': ['Edited body'],
|
||||
'course_id': [text_type(self.course.id)],
|
||||
'user_id': [str(self.user.id)],
|
||||
'anonymous': ['False'],
|
||||
'anonymous_to_peers': ['False'],
|
||||
'endorsed': ['False']
|
||||
}
|
||||
|
||||
def test_error(self):
|
||||
self.register_thread()
|
||||
@@ -1669,9 +1625,9 @@ class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTes
|
||||
expected_response_data = {
|
||||
"field_errors": {"raw_body": {"developer_message": "This field may not be blank."}}
|
||||
}
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data, expected_response_data)
|
||||
assert response_data == expected_response_data
|
||||
|
||||
@ddt.data(
|
||||
("abuse_flagged", True),
|
||||
@@ -1684,15 +1640,12 @@ class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTes
|
||||
self.register_flag_response("comment", "test_comment")
|
||||
request_data = {field: value}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data,
|
||||
self.expected_response_data({
|
||||
"abuse_flagged": value,
|
||||
"editable_fields": ["abuse_flagged"],
|
||||
})
|
||||
)
|
||||
assert response_data == self.expected_response_data({
|
||||
'abuse_flagged': value,
|
||||
'editable_fields': ['abuse_flagged']
|
||||
})
|
||||
|
||||
@ddt.data(
|
||||
("raw_body", "Edited body"),
|
||||
@@ -1705,7 +1658,7 @@ class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTes
|
||||
self.register_comment()
|
||||
request_data = {field: value}
|
||||
response = self.request_patch(request_data)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
@@ -1730,17 +1683,14 @@ class ThreadViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase,
|
||||
})
|
||||
self.register_get_thread_response(cs_thread)
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
json.loads(response.content.decode('utf-8')),
|
||||
self.expected_thread_data({"unread_comment_count": 1})
|
||||
)
|
||||
self.assertEqual(httpretty.last_request().method, "GET")
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8')) == self.expected_thread_data({'unread_comment_count': 1})
|
||||
assert httpretty.last_request().method == 'GET'
|
||||
|
||||
def test_retrieve_nonexistent_thread(self):
|
||||
self.register_get_thread_error_response(self.thread_id, 404)
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_profile_image_requested_field(self):
|
||||
"""
|
||||
@@ -1756,10 +1706,10 @@ class ThreadViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase,
|
||||
self.register_get_thread_response(cs_thread)
|
||||
self.create_profile_image(self.user, get_profile_image_storage())
|
||||
response = self.client.get(self.url, {"requested_fields": "profile_image"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
expected_profile_data = self.get_expected_user_profile(self.user.username)
|
||||
response_users = json.loads(response.content.decode('utf-8'))['users']
|
||||
self.assertEqual(expected_profile_data, response_users[self.user.username])
|
||||
assert expected_profile_data == response_users[self.user.username]
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
@@ -1825,13 +1775,13 @@ class CommentViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase
|
||||
}
|
||||
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8'))['results'][0], expected_response_data)
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.content.decode('utf-8'))['results'][0] == expected_response_data
|
||||
|
||||
def test_retrieve_nonexistent_comment(self):
|
||||
self.register_get_comment_error_response(self.comment_id, 404)
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_pagination(self):
|
||||
"""
|
||||
@@ -1876,13 +1826,13 @@ class CommentViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase
|
||||
self.create_profile_image(self.user, get_profile_image_storage())
|
||||
|
||||
response = self.client.get(self.url, {'requested_fields': 'profile_image'})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_comments = json.loads(response.content.decode('utf-8'))['results']
|
||||
|
||||
for response_comment in response_comments:
|
||||
expected_profile_data = self.get_expected_user_profile(response_comment['author'])
|
||||
response_users = response_comment['users']
|
||||
self.assertEqual(expected_profile_data, response_users[response_comment['author']])
|
||||
assert expected_profile_data == response_users[response_comment['author']]
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1959,14 +1909,14 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
def _assert_current_settings(self, expected_response):
|
||||
"""Validate the current discussion settings against the expected response."""
|
||||
response = self.client.get(self.path)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(content, expected_response)
|
||||
assert content == expected_response
|
||||
|
||||
def _assert_patched_settings(self, data, expected_response):
|
||||
"""Validate the patched settings against the expected response."""
|
||||
response = self.patch_request(data)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
assert response.status_code == 204
|
||||
self._assert_current_settings(expected_response)
|
||||
|
||||
@ddt.data('get', 'patch')
|
||||
@@ -1974,7 +1924,7 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
"""Test and verify that authentication is required for this endpoint."""
|
||||
self.client.logout()
|
||||
response = getattr(self.client, method)(self.path)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
assert response.status_code == 401
|
||||
|
||||
@ddt.data(
|
||||
{'is_staff': False, 'get_status': 403, 'put_status': 403},
|
||||
@@ -1988,12 +1938,12 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
self.client.logout()
|
||||
|
||||
response = self.client.get(self.path, **headers)
|
||||
self.assertEqual(response.status_code, get_status)
|
||||
assert response.status_code == get_status
|
||||
|
||||
response = self.patch_request(
|
||||
{'always_divide_inline_discussions': True}, headers
|
||||
)
|
||||
self.assertEqual(response.status_code, put_status)
|
||||
assert response.status_code == put_status
|
||||
|
||||
def test_non_existent_course_id(self):
|
||||
"""Test the response when this endpoint is passed a non-existent course id."""
|
||||
@@ -2003,14 +1953,14 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
'course_id': 'a/b/c'
|
||||
})
|
||||
)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_get_settings(self):
|
||||
"""Test the current discussion settings against the expected response."""
|
||||
divided_inline_discussions, divided_course_wide_discussions = self._create_divided_discussions()
|
||||
self._login_as_staff()
|
||||
response = self.client.get(self.path)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
expected_response = self._get_expected_response()
|
||||
expected_response['divided_course_wide_discussions'] = [
|
||||
topic_name_to_id(self.course, name) for name in divided_course_wide_discussions
|
||||
@@ -2019,7 +1969,7 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
topic_name_to_id(self.course, name) for name in divided_inline_discussions
|
||||
]
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(content, expected_response)
|
||||
assert content == expected_response
|
||||
|
||||
def test_available_schemes(self):
|
||||
"""Test the available division schemes against the expected response."""
|
||||
@@ -2045,10 +1995,10 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
"""Test the response status code on sending a PATCH request with an empty body or missing fields."""
|
||||
self._login_as_staff()
|
||||
response = self.patch_request("")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
response = self.patch_request({})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
@ddt.data(
|
||||
{'abc': 123},
|
||||
@@ -2061,7 +2011,7 @@ class CourseDiscussionSettingsAPIViewTest(APITestCase, UrlResetMixin, ModuleStor
|
||||
"""Test the response status code on sending a PATCH request with parameters having incorrect types."""
|
||||
self._login_as_staff()
|
||||
response = self.patch_request(body)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_update_always_divide_inline_discussion_settings(self):
|
||||
"""Test whether the 'always_divide_inline_discussions' setting is updated."""
|
||||
@@ -2194,17 +2144,17 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
"""Test and verify that authentication is required for this endpoint."""
|
||||
self.client.logout()
|
||||
response = getattr(self.client, method)(self.path())
|
||||
self.assertEqual(response.status_code, 401)
|
||||
assert response.status_code == 401
|
||||
|
||||
def test_oauth(self):
|
||||
"""Test that OAuth authentication works for this endpoint."""
|
||||
oauth_headers = self._get_oauth_headers(self.user)
|
||||
self.client.logout()
|
||||
response = self.client.get(self.path(), **oauth_headers)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
body = {'user_id': 'staff', 'action': 'allow'}
|
||||
response = self.client.post(self.path(), body, format='json', **oauth_headers)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
@ddt.data(
|
||||
{'username': 'u1', 'is_staff': False, 'expected_status': 403},
|
||||
@@ -2216,10 +2166,10 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
UserFactory(username=username, password='edx', is_staff=is_staff)
|
||||
self.client.login(username=username, password='edx')
|
||||
response = self.client.get(self.path())
|
||||
self.assertEqual(response.status_code, expected_status)
|
||||
assert response.status_code == expected_status
|
||||
|
||||
response = self.client.post(self.path(), {'user_id': username, 'action': 'allow'}, format='json')
|
||||
self.assertEqual(response.status_code, expected_status)
|
||||
assert response.status_code == expected_status
|
||||
|
||||
def test_non_existent_course_id(self):
|
||||
"""Test the response when the endpoint URL contains a non-existent course id."""
|
||||
@@ -2227,10 +2177,10 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
path = self.path(course_id='a/b/c')
|
||||
response = self.client.get(path)
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
response = self.client.post(path)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_non_existent_course_role(self):
|
||||
"""Test the response when the endpoint URL contains a non-existent role."""
|
||||
@@ -2238,10 +2188,10 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
path = self.path(role='A')
|
||||
response = self.client.get(path)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
response = self.client.post(path)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
@ddt.data(
|
||||
{'role': 'Moderator', 'count': 0},
|
||||
@@ -2259,22 +2209,22 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
self._login_as_staff()
|
||||
response = self.client.get(self.path(role=role))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(content['course_id'], 'x/y/z')
|
||||
self.assertEqual(len(content['results']), count)
|
||||
assert content['course_id'] == 'x/y/z'
|
||||
assert len(content['results']) == count
|
||||
expected_fields = ('username', 'email', 'first_name', 'last_name', 'group_name')
|
||||
for item in content['results']:
|
||||
for expected_field in expected_fields:
|
||||
self.assertIn(expected_field, item)
|
||||
self.assertEqual(content['division_scheme'], 'cohort')
|
||||
assert expected_field in item
|
||||
assert content['division_scheme'] == 'cohort'
|
||||
|
||||
def test_post_missing_body(self):
|
||||
"""Test the response with a POST request without a body."""
|
||||
self._login_as_staff()
|
||||
response = self.client.post(self.path())
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
@ddt.data(
|
||||
{'a': 1},
|
||||
@@ -2288,10 +2238,10 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
"""
|
||||
self._login_as_staff()
|
||||
response = self.client.post(self.path(), body)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
response = self.client.post(self.path(), body, format='json')
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
@ddt.data(
|
||||
{'action': 'allow', 'user_in_role': False},
|
||||
@@ -2309,7 +2259,7 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe
|
||||
self._add_users_to_role(users, role)
|
||||
|
||||
response = self.post(role, user.username, action)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
assertion = self.assertTrue if action == 'allow' else self.assertFalse
|
||||
assertion(any(user.username in x['username'] for x in content['results']))
|
||||
|
||||
@@ -359,7 +359,7 @@ class CommentsServiceMockMixin(object):
|
||||
"""
|
||||
actual_params = dict(httpretty_request.querystring)
|
||||
actual_params.pop("request_id") # request_id is random
|
||||
self.assertEqual(actual_params, expected_params)
|
||||
assert actual_params == expected_params
|
||||
|
||||
def assert_last_query_params(self, expected_params):
|
||||
"""
|
||||
@@ -519,12 +519,12 @@ class ProfileImageTestMixin(object):
|
||||
"""
|
||||
for size, name in get_profile_image_names(user.username).items():
|
||||
if exist:
|
||||
self.assertTrue(storage.exists(name))
|
||||
assert storage.exists(name)
|
||||
with closing(Image.open(storage.path(name))) as img:
|
||||
self.assertEqual(img.size, (size, size))
|
||||
self.assertEqual(img.format, 'JPEG')
|
||||
assert img.size == (size, size)
|
||||
assert img.format == 'JPEG'
|
||||
else:
|
||||
self.assertFalse(storage.exists(name))
|
||||
assert not storage.exists(name)
|
||||
|
||||
def get_expected_user_profile(self, username):
|
||||
"""
|
||||
|
||||
@@ -41,7 +41,7 @@ class SendMessageHandlerTestCase(TestCase): # lint-amnesty, pylint: disable=mis
|
||||
def test_comment_created_signal_message_not_sent_without_site(self, mock_send_message, mock_get_current_site): # lint-amnesty, pylint: disable=unused-argument
|
||||
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
|
||||
|
||||
self.assertFalse(mock_send_message.called)
|
||||
assert not mock_send_message.called
|
||||
|
||||
@mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site')
|
||||
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
|
||||
@@ -49,7 +49,7 @@ class SendMessageHandlerTestCase(TestCase): # lint-amnesty, pylint: disable=mis
|
||||
mock_get_current_site.return_value = self.site
|
||||
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
|
||||
|
||||
self.assertFalse(mock_send_message.called)
|
||||
assert not mock_send_message.called
|
||||
|
||||
@mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site')
|
||||
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
|
||||
@@ -63,7 +63,7 @@ class SendMessageHandlerTestCase(TestCase): # lint-amnesty, pylint: disable=mis
|
||||
mock_get_current_site.return_value = self.site
|
||||
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
|
||||
|
||||
self.assertFalse(mock_send_message.called)
|
||||
assert not mock_send_message.called
|
||||
|
||||
|
||||
class CoursePublishHandlerTestCase(ModuleStoreTestCase):
|
||||
@@ -78,7 +78,7 @@ class CoursePublishHandlerTestCase(ModuleStoreTestCase):
|
||||
|
||||
# create course
|
||||
course = CourseFactory(emit_signals=True, **course_key_args)
|
||||
self.assertEqual(course.id, course_key)
|
||||
assert course.id == course_key
|
||||
self._assert_discussion_id_map(course_key, {})
|
||||
|
||||
# create discussion block
|
||||
|
||||
@@ -219,13 +219,13 @@ class TaskTestCase(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missin
|
||||
})
|
||||
expected_recipient = Recipient(self.thread_author.username, self.thread_author.email)
|
||||
actual_message = self.mock_ace_send.call_args_list[0][0][0]
|
||||
self.assertEqual(expected_message_context, actual_message.context)
|
||||
self.assertEqual(expected_recipient, actual_message.recipient)
|
||||
self.assertEqual(self.course.language, actual_message.language)
|
||||
assert expected_message_context == actual_message.context
|
||||
assert expected_recipient == actual_message.recipient
|
||||
assert self.course.language == actual_message.language
|
||||
self._assert_rendered_email(actual_message)
|
||||
|
||||
else:
|
||||
self.assertFalse(self.mock_ace_send.called)
|
||||
assert not self.mock_ace_send.called
|
||||
|
||||
def _assert_rendered_email(self, message): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
# check that we can actually render the message
|
||||
@@ -257,8 +257,8 @@ class TaskTestCase(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missin
|
||||
'comment_id': comment_dict['id'],
|
||||
'thread_id': thread['id'],
|
||||
})
|
||||
self.assertEqual(actual_result, False)
|
||||
self.assertFalse(self.mock_ace_send.called)
|
||||
assert actual_result is False
|
||||
assert not self.mock_ace_send.called
|
||||
|
||||
def test_subcomment_should_not_send_email(self):
|
||||
self.run_should_not_send_email_test(self.thread, self.subcomment)
|
||||
|
||||
@@ -123,7 +123,7 @@ class ViewsExceptionTestCase(UrlResetMixin, ModuleStoreTestCase): # lint-amnest
|
||||
url = reverse('user_profile',
|
||||
kwargs={'course_id': text_type(self.course.id), 'user_id': '12345'}) # There is no user 12345
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
@patch('common.djangoapps.student.models.cc.User.from_django_user')
|
||||
@patch('common.djangoapps.student.models.cc.User.subscribed_threads')
|
||||
@@ -140,7 +140,7 @@ class ViewsExceptionTestCase(UrlResetMixin, ModuleStoreTestCase): # lint-amnest
|
||||
url = reverse('followed_threads',
|
||||
kwargs={'course_id': text_type(self.course.id), 'user_id': '12345'}) # There is no user 12345
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def make_mock_thread_data( # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
@@ -331,14 +331,16 @@ class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-amne
|
||||
"test_thread_id"
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
# strip_none is being used to perform the same transform that the
|
||||
# django view performs prior to writing thread data to the response
|
||||
self.assertEqual(
|
||||
response_data["content"],
|
||||
strip_none(make_mock_thread_data(course=self.course, text=text, thread_id=thread_id, num_children=1))
|
||||
)
|
||||
assert response_data['content'] == strip_none(make_mock_thread_data(
|
||||
course=self.course,
|
||||
text=text,
|
||||
thread_id=thread_id,
|
||||
num_children=1
|
||||
))
|
||||
mock_request.assert_called_with(
|
||||
"get",
|
||||
StringEndsWithMatcher(thread_id), # url
|
||||
@@ -367,14 +369,16 @@ class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-amne
|
||||
"dummy_discussion_id",
|
||||
"test_thread_id"
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
# strip_none is being used to perform the same transform that the
|
||||
# django view performs prior to writing thread data to the response
|
||||
self.assertEqual(
|
||||
response_data["content"],
|
||||
strip_none(make_mock_thread_data(course=self.course, text=text, thread_id=thread_id, num_children=1))
|
||||
)
|
||||
assert response_data['content'] == strip_none(make_mock_thread_data(
|
||||
course=self.course,
|
||||
text=text,
|
||||
thread_id=thread_id,
|
||||
num_children=1
|
||||
))
|
||||
mock_request.assert_called_with(
|
||||
"get",
|
||||
StringEndsWithMatcher(thread_id), # url
|
||||
@@ -398,7 +402,7 @@ class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-amne
|
||||
"dummy_discussion_id",
|
||||
"dummy_thread_id"
|
||||
)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
|
||||
def test_not_found(self, mock_request):
|
||||
request = RequestFactory().get("dummy_url")
|
||||
@@ -437,17 +441,14 @@ class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-amne
|
||||
'thread_id': thread_id,
|
||||
})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8')
|
||||
assert response.status_code == 200
|
||||
assert response['Content-Type'] == 'text/html; charset=utf-8'
|
||||
html = response.content.decode('utf-8')
|
||||
# Verify that the access denied error message is in the HTML
|
||||
self.assertIn(
|
||||
'This is a private discussion. You do not have permissions to view this discussion',
|
||||
html
|
||||
)
|
||||
assert 'This is a private discussion. You do not have permissions to view this discussion' in html
|
||||
|
||||
|
||||
class AllowPlusOrMinusOneInt(int):
|
||||
class AllowPlusOrMinusOneInt(int): # pylint: disable=eq-without-hash
|
||||
"""
|
||||
A workaround for the fact that assertNumQueries doesn't let you
|
||||
specify a range or any tolerance. An 'int' that is 'equal to' its value,
|
||||
@@ -535,11 +536,8 @@ class SingleThreadQueryCountTestCase(ForumsEnableMixin, ModuleStoreTestCase):
|
||||
"dummy_discussion_id",
|
||||
test_thread_id
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
len(json.loads(response.content.decode('utf-8'))["content"]["children"]),
|
||||
num_thread_responses
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert len(json.loads(response.content.decode('utf-8'))['content']['children']) == num_thread_responses
|
||||
|
||||
# Test uncached first, then cached now that the cache is warm.
|
||||
cached_calls = [
|
||||
@@ -584,20 +582,17 @@ class SingleCohortedThreadTestCase(CohortedTestCase): # lint-amnesty, pylint: d
|
||||
mock_thread_id
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
response_data["content"],
|
||||
make_mock_thread_data(
|
||||
course=self.course,
|
||||
commentable_id="cohorted_topic",
|
||||
text=mock_text,
|
||||
thread_id=mock_thread_id,
|
||||
num_children=1,
|
||||
group_id=self.student_cohort.id,
|
||||
group_name=self.student_cohort.name,
|
||||
is_commentable_divided=True,
|
||||
)
|
||||
assert response_data['content'] == make_mock_thread_data(
|
||||
course=self.course,
|
||||
commentable_id='cohorted_topic',
|
||||
text=mock_text,
|
||||
thread_id=mock_thread_id,
|
||||
num_children=1,
|
||||
group_id=self.student_cohort.id,
|
||||
group_name=self.student_cohort.name,
|
||||
is_commentable_divided=True
|
||||
)
|
||||
|
||||
def test_html(self, mock_request):
|
||||
@@ -612,8 +607,8 @@ class SingleCohortedThreadTestCase(CohortedTestCase): # lint-amnesty, pylint: d
|
||||
})
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8')
|
||||
assert response.status_code == 200
|
||||
assert response['Content-Type'] == 'text/html; charset=utf-8'
|
||||
html = response.content.decode('utf-8')
|
||||
|
||||
# Verify that the group name is correctly included in the HTML
|
||||
@@ -647,7 +642,7 @@ class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: dis
|
||||
|
||||
def test_student_non_cohorted(self, mock_request):
|
||||
resp = self.call_view(mock_request, "non_cohorted_topic", self.student, self.student_cohort.id)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_student_same_cohort(self, mock_request):
|
||||
resp = self.call_view(
|
||||
@@ -657,7 +652,7 @@ class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: dis
|
||||
self.student_cohort.id,
|
||||
thread_group_id=self.student_cohort.id
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
# this test ensures that a thread response from the cs with group_id: null
|
||||
# behaves the same as a thread response without a group_id (see: TNL-444)
|
||||
@@ -669,23 +664,20 @@ class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: dis
|
||||
self.student_cohort.id,
|
||||
thread_group_id=None
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_student_different_cohort(self, mock_request):
|
||||
self.assertRaises(
|
||||
Http404,
|
||||
lambda: self.call_view(
|
||||
mock_request,
|
||||
"cohorted_topic",
|
||||
self.student,
|
||||
self.student_cohort.id,
|
||||
thread_group_id=self.moderator_cohort.id
|
||||
)
|
||||
)
|
||||
pytest.raises(Http404, (lambda: self.call_view(
|
||||
mock_request,
|
||||
'cohorted_topic',
|
||||
self.student,
|
||||
self.student_cohort.id,
|
||||
thread_group_id=self.moderator_cohort.id
|
||||
)))
|
||||
|
||||
def test_moderator_non_cohorted(self, mock_request):
|
||||
resp = self.call_view(mock_request, "non_cohorted_topic", self.moderator, self.moderator_cohort.id)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_moderator_same_cohort(self, mock_request):
|
||||
resp = self.call_view(
|
||||
@@ -695,7 +687,7 @@ class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: dis
|
||||
self.moderator_cohort.id,
|
||||
thread_group_id=self.moderator_cohort.id
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_moderator_different_cohort(self, mock_request):
|
||||
resp = self.call_view(
|
||||
@@ -705,7 +697,7 @@ class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: dis
|
||||
self.moderator_cohort.id,
|
||||
thread_group_id=self.student_cohort.id
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_private_team_thread(self, mock_request):
|
||||
CourseTeamFactory.create(discussion_topic_id='dummy_discussion_id')
|
||||
@@ -720,11 +712,8 @@ class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: dis
|
||||
user_not_in_team,
|
||||
''
|
||||
)
|
||||
self.assertEqual(403, response.status_code)
|
||||
self.assertEqual(
|
||||
views.TEAM_PERMISSION_MESSAGE,
|
||||
response.content.decode('utf-8'),
|
||||
)
|
||||
assert 403 == response.status_code
|
||||
assert views.TEAM_PERMISSION_MESSAGE == response.content.decode('utf-8')
|
||||
|
||||
|
||||
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)
|
||||
@@ -801,7 +790,7 @@ class ForumFormDiscussionContentGroupTestCase(ForumsEnableMixin, ContentGroupTes
|
||||
cohorts and non-cohorted modules.
|
||||
"""
|
||||
discussion_data = json.loads(response.content.decode('utf-8'))['discussion_data']
|
||||
self.assertEqual(len(discussion_data), expected_discussion_threads)
|
||||
assert len(discussion_data) == expected_discussion_threads
|
||||
|
||||
def call_view(self, mock_request, user): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
mock_request.side_effect = make_mock_request_impl(
|
||||
@@ -880,9 +869,9 @@ class SingleThreadContentGroupTestCase(ForumsEnableMixin, UrlResetMixin, Content
|
||||
)
|
||||
|
||||
if should_have_access:
|
||||
self.assertEqual(call_single_thread().status_code, 200)
|
||||
assert call_single_thread().status_code == 200
|
||||
else:
|
||||
self.assertEqual(call_single_thread().status_code, 404)
|
||||
assert call_single_thread().status_code == 404
|
||||
|
||||
def test_staff_user(self, mock_request):
|
||||
"""
|
||||
@@ -1005,7 +994,7 @@ class InlineDiscussionContextTestCase(ForumsEnableMixin, ModuleStoreTestCase):
|
||||
)
|
||||
|
||||
json_response = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(json_response['discussion_data'][0]['context'], ThreadContext.STANDALONE)
|
||||
assert json_response['discussion_data'][0]['context'] == ThreadContext.STANDALONE
|
||||
|
||||
def test_private_team_discussion(self, mock_request):
|
||||
# First set the team discussion to be private
|
||||
@@ -1026,8 +1015,8 @@ class InlineDiscussionContextTestCase(ForumsEnableMixin, ModuleStoreTestCase):
|
||||
six.text_type(self.course.id),
|
||||
self.discussion_topic_id,
|
||||
)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.content.decode('utf-8'), views.TEAM_PERMISSION_MESSAGE)
|
||||
assert response.status_code == 403
|
||||
assert response.content.decode('utf-8') == views.TEAM_PERMISSION_MESSAGE
|
||||
|
||||
|
||||
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)
|
||||
@@ -1219,14 +1208,14 @@ class UserProfileDiscussionGroupIdTestCase(CohortedTestCase, CohortedTopicGroupI
|
||||
)
|
||||
# Should never have a group_id if course_id was not included in the request.
|
||||
params_without_course_id = get_params_from_user_info_call(False)
|
||||
self.assertNotIn("group_id", params_without_course_id)
|
||||
assert 'group_id' not in params_without_course_id
|
||||
|
||||
params_with_course_id = get_params_from_user_info_call(True)
|
||||
if expect_group_id_in_request:
|
||||
self.assertIn("group_id", params_with_course_id)
|
||||
self.assertEqual(group_id, params_with_course_id["group_id"])
|
||||
assert 'group_id' in params_with_course_id
|
||||
assert group_id == params_with_course_id['group_id']
|
||||
else:
|
||||
self.assertNotIn("group_id", params_with_course_id)
|
||||
assert 'group_id' not in params_with_course_id
|
||||
|
||||
def test_group_id_passed_to_user_profile_student(self, mock_request):
|
||||
"""
|
||||
@@ -1376,7 +1365,7 @@ class InlineDiscussionTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-
|
||||
team.add_user(self.student)
|
||||
|
||||
self.send_request(mock_request)
|
||||
self.assertEqual(mock_request.call_args[1]['params']['context'], ThreadContext.STANDALONE)
|
||||
assert mock_request.call_args[1]['params']['context'] == ThreadContext.STANDALONE
|
||||
|
||||
|
||||
@patch('requests.request', autospec=True)
|
||||
@@ -1425,8 +1414,8 @@ class UserProfileTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
|
||||
def check_html(self, mock_request, **params): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
response = self.get_response(mock_request, params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8')
|
||||
assert response.status_code == 200
|
||||
assert response['Content-Type'] == 'text/html; charset=utf-8'
|
||||
html = response.content.decode('utf-8')
|
||||
self.assertRegex(html, r'data-page="1"')
|
||||
self.assertRegex(html, r'data-num-pages="1"')
|
||||
@@ -1442,19 +1431,16 @@ class UserProfileTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
|
||||
def check_ajax(self, mock_request, **params): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
response = self.get_response(mock_request, params, HTTP_X_REQUESTED_WITH="XMLHttpRequest")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response['Content-Type'], 'application/json; charset=utf-8')
|
||||
assert response.status_code == 200
|
||||
assert response['Content-Type'] == 'application/json; charset=utf-8'
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
sorted(response_data.keys()),
|
||||
["annotated_content_info", "discussion_data", "num_pages", "page"]
|
||||
)
|
||||
self.assertEqual(len(response_data['discussion_data']), 1)
|
||||
self.assertEqual(response_data["page"], 1)
|
||||
self.assertEqual(response_data["num_pages"], 1)
|
||||
self.assertEqual(response_data['discussion_data'][0]['id'], self.TEST_THREAD_ID)
|
||||
self.assertEqual(response_data['discussion_data'][0]['title'], self.TEST_THREAD_TEXT)
|
||||
self.assertEqual(response_data['discussion_data'][0]['body'], self.TEST_THREAD_TEXT)
|
||||
assert sorted(response_data.keys()) == ['annotated_content_info', 'discussion_data', 'num_pages', 'page']
|
||||
assert len(response_data['discussion_data']) == 1
|
||||
assert response_data['page'] == 1
|
||||
assert response_data['num_pages'] == 1
|
||||
assert response_data['discussion_data'][0]['id'] == self.TEST_THREAD_ID
|
||||
assert response_data['discussion_data'][0]['title'] == self.TEST_THREAD_TEXT
|
||||
assert response_data['discussion_data'][0]['body'] == self.TEST_THREAD_TEXT
|
||||
|
||||
def test_html(self, mock_request):
|
||||
self.check_html(mock_request)
|
||||
@@ -1470,7 +1456,7 @@ class UserProfileTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
unenrolled_user = UserFactory.create()
|
||||
request = RequestFactory().get("dummy_url")
|
||||
request.user = self.student
|
||||
with self.assertRaises(Http404):
|
||||
with pytest.raises(Http404):
|
||||
views.user_profile(
|
||||
request,
|
||||
text_type(self.course.id),
|
||||
@@ -1480,7 +1466,7 @@ class UserProfileTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
def test_404_profiled_user(self, _mock_request):
|
||||
request = RequestFactory().get("dummy_url")
|
||||
request.user = self.student
|
||||
with self.assertRaises(Http404):
|
||||
with pytest.raises(Http404):
|
||||
views.user_profile(
|
||||
request,
|
||||
text_type(self.course.id),
|
||||
@@ -1490,7 +1476,7 @@ class UserProfileTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
def test_404_course(self, _mock_request):
|
||||
request = RequestFactory().get("dummy_url")
|
||||
request.user = self.student
|
||||
with self.assertRaises(Http404):
|
||||
with pytest.raises(Http404):
|
||||
views.user_profile(
|
||||
request,
|
||||
"non/existent/course",
|
||||
@@ -1508,7 +1494,7 @@ class UserProfileTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase)
|
||||
text_type(self.course.id),
|
||||
self.profiled_user.id
|
||||
)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
@patch('requests.request', autospec=True)
|
||||
@@ -1528,9 +1514,7 @@ class CommentsServiceRequestHeadersTestCase(ForumsEnableMixin, UrlResetMixin, Mo
|
||||
self.course = CourseFactory.create(discussion_topics={'dummy discussion': {'id': 'dummy_discussion_id'}})
|
||||
self.student = UserFactory.create(username=username, password=password)
|
||||
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
|
||||
self.assertTrue(
|
||||
self.client.login(username=username, password=password)
|
||||
)
|
||||
assert self.client.login(username=username, password=password)
|
||||
|
||||
self.addCleanup(translation.deactivate)
|
||||
|
||||
@@ -1544,7 +1528,7 @@ class CommentsServiceRequestHeadersTestCase(ForumsEnableMixin, UrlResetMixin, Mo
|
||||
timeout=ANY
|
||||
)
|
||||
for actual in mock_request.call_args_list:
|
||||
self.assertEqual(expected, actual)
|
||||
assert expected == actual
|
||||
|
||||
def test_accept_language(self, mock_request):
|
||||
lang = "eo"
|
||||
@@ -1602,10 +1586,10 @@ class InlineDiscussionUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCa
|
||||
response = views.inline_discussion(
|
||||
request, text_type(self.course.id), self.course.discussion_topics['General']['id']
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data["discussion_data"][0]["title"], text)
|
||||
self.assertEqual(response_data["discussion_data"][0]["body"], text)
|
||||
assert response_data['discussion_data'][0]['title'] == text
|
||||
assert response_data['discussion_data'][0]['body'] == text
|
||||
|
||||
|
||||
class ForumFormDiscussionUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
@@ -1631,10 +1615,10 @@ class ForumFormDiscussionUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTes
|
||||
request.META["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" # so request.is_ajax() == True
|
||||
|
||||
response = views.forum_form_discussion(request, text_type(self.course.id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data["discussion_data"][0]["title"], text)
|
||||
self.assertEqual(response_data["discussion_data"][0]["body"], text)
|
||||
assert response_data['discussion_data'][0]['title'] == text
|
||||
assert response_data['discussion_data'][0]['body'] == text
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1651,7 +1635,7 @@ class ForumDiscussionXSSTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTe
|
||||
self.course = CourseFactory.create()
|
||||
self.student = UserFactory.create(username=username, password=password)
|
||||
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
|
||||
self.assertTrue(self.client.login(username=username, password=password))
|
||||
assert self.client.login(username=username, password=password)
|
||||
|
||||
@ddt.data('"><script>alert(1)</script>', '<script>alert(1)</script>', '</script><script>alert(1)</script>')
|
||||
@patch('common.djangoapps.student.models.cc.User.from_django_user')
|
||||
@@ -1719,10 +1703,10 @@ class ForumDiscussionSearchUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreT
|
||||
request.META["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" # so request.is_ajax() == True
|
||||
|
||||
response = views.forum_form_discussion(request, text_type(self.course.id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data["discussion_data"][0]["title"], text)
|
||||
self.assertEqual(response_data["discussion_data"][0]["body"], text)
|
||||
assert response_data['discussion_data'][0]['title'] == text
|
||||
assert response_data['discussion_data'][0]['body'] == text
|
||||
|
||||
|
||||
class SingleThreadUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
@@ -1749,10 +1733,10 @@ class SingleThreadUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase,
|
||||
request.META["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" # so request.is_ajax() == True
|
||||
|
||||
response = views.single_thread(request, text_type(self.course.id), "dummy_discussion_id", thread_id)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data["content"]["title"], text)
|
||||
self.assertEqual(response_data["content"]["body"], text)
|
||||
assert response_data['content']['title'] == text
|
||||
assert response_data['content']['body'] == text
|
||||
|
||||
|
||||
class UserProfileUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
@@ -1778,10 +1762,10 @@ class UserProfileUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, U
|
||||
request.META["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" # so request.is_ajax() == True
|
||||
|
||||
response = views.user_profile(request, text_type(self.course.id), str(self.student.id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data["discussion_data"][0]["title"], text)
|
||||
self.assertEqual(response_data["discussion_data"][0]["body"], text)
|
||||
assert response_data['discussion_data'][0]['title'] == text
|
||||
assert response_data['discussion_data'][0]['body'] == text
|
||||
|
||||
|
||||
class FollowedThreadsUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
@@ -1807,10 +1791,10 @@ class FollowedThreadsUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCas
|
||||
request.META["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" # so request.is_ajax() == True
|
||||
|
||||
response = views.followed_threads(request, text_type(self.course.id), str(self.student.id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
response_data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(response_data["discussion_data"][0]["title"], text)
|
||||
self.assertEqual(response_data["discussion_data"][0]["body"], text)
|
||||
assert response_data['discussion_data'][0]['title'] == text
|
||||
assert response_data['discussion_data'][0]['body'] == text
|
||||
|
||||
|
||||
class EnrollmentTestCase(ForumsEnableMixin, ModuleStoreTestCase):
|
||||
@@ -1831,7 +1815,7 @@ class EnrollmentTestCase(ForumsEnableMixin, ModuleStoreTestCase):
|
||||
mock_request.side_effect = make_mock_request_impl(course=self.course, text='dummy')
|
||||
request = RequestFactory().get('dummy_url')
|
||||
request.user = self.student
|
||||
with self.assertRaises(CourseAccessRedirect):
|
||||
with pytest.raises(CourseAccessRedirect):
|
||||
views.forum_form_discussion(request, course_id=text_type(self.course.id)) # pylint: disable=no-value-for-parameter, unexpected-keyword-arg
|
||||
|
||||
|
||||
@@ -1854,9 +1838,7 @@ class EnterpriseConsentTestCase(EnterpriseTestConsentRequired, ForumsEnableMixin
|
||||
self.course = CourseFactory.create(discussion_topics={'dummy discussion': {'id': self.discussion_id}})
|
||||
self.student = UserFactory.create(username=username, password=password)
|
||||
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
|
||||
self.assertTrue(
|
||||
self.client.login(username=username, password=password)
|
||||
)
|
||||
assert self.client.login(username=username, password=password)
|
||||
|
||||
self.addCleanup(translation.deactivate)
|
||||
|
||||
@@ -1970,7 +1952,7 @@ class CourseDiscussionTopicsTestCase(DividedDiscussionsTestCase):
|
||||
'children': [['Chapter', TYPE_SUBCATEGORY]]
|
||||
}
|
||||
}
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
|
||||
class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
@@ -2012,14 +1994,14 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
|
||||
expected_response = self.get_expected_response()
|
||||
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
expected_response['always_divide_inline_discussions'] = True
|
||||
response = self.patch_handler(
|
||||
self.course, data=expected_response, handler=course_discussions_settings_handler
|
||||
)
|
||||
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
def test_update_course_wide_discussion_settings(self):
|
||||
"""
|
||||
@@ -2036,14 +2018,14 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
response = self.get_handler(self.course, handler=views.course_discussions_settings_handler)
|
||||
|
||||
expected_response = self.get_expected_response()
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
expected_response['divided_course_wide_discussions'] = [topic_name_to_id(self.course, "Topic B")]
|
||||
response = self.patch_handler(
|
||||
self.course, data=expected_response, handler=views.course_discussions_settings_handler
|
||||
)
|
||||
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
def test_update_inline_discussion_settings(self):
|
||||
"""
|
||||
@@ -2054,7 +2036,7 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
response = self.get_handler(self.course, handler=views.course_discussions_settings_handler)
|
||||
|
||||
expected_response = self.get_expected_response()
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
RequestCache.clear_all_namespaces()
|
||||
now = datetime.now()
|
||||
@@ -2073,7 +2055,7 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
self.course, data=expected_response, handler=views.course_discussions_settings_handler
|
||||
)
|
||||
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
def test_get_settings(self):
|
||||
"""
|
||||
@@ -2089,7 +2071,7 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
expected_response['divided_course_wide_discussions'] = [topic_name_to_id(self.course, name)
|
||||
for name in divided_course_wide_discussions]
|
||||
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
def test_update_settings_with_invalid_field_data_type(self):
|
||||
"""
|
||||
@@ -2103,11 +2085,10 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
expected_response_code=400,
|
||||
handler=views.course_discussions_settings_handler
|
||||
)
|
||||
self.assertEqual(
|
||||
u"Incorrect field type for `{}`. Type must be `{}`".format('always_divide_inline_discussions',
|
||||
bool.__name__),
|
||||
response.get("error")
|
||||
)
|
||||
assert u'Incorrect field type for `{}`. Type must be `{}`'.format(
|
||||
'always_divide_inline_discussions',
|
||||
bool.__name__
|
||||
) == response.get('error')
|
||||
|
||||
def test_available_schemes(self):
|
||||
# Cohorts disabled, single enrollment mode.
|
||||
@@ -2115,14 +2096,14 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
response = self.get_handler(self.course, handler=views.course_discussions_settings_handler)
|
||||
expected_response = self.get_expected_response()
|
||||
expected_response['available_division_schemes'] = []
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
# Add 2 enrollment modes
|
||||
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.AUDIT)
|
||||
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.VERIFIED)
|
||||
response = self.get_handler(self.course, handler=views.course_discussions_settings_handler)
|
||||
expected_response['available_division_schemes'] = [CourseDiscussionSettings.ENROLLMENT_TRACK]
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
# Enable cohorts
|
||||
config_course_cohorts(self.course, is_cohorted=True)
|
||||
@@ -2130,7 +2111,7 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase):
|
||||
expected_response['available_division_schemes'] = [
|
||||
CourseDiscussionSettings.COHORT, CourseDiscussionSettings.ENROLLMENT_TRACK
|
||||
]
|
||||
self.assertEqual(response, expected_response)
|
||||
assert response == expected_response
|
||||
|
||||
|
||||
class DefaultTopicIdGetterTestCase(ModuleStoreTestCase):
|
||||
@@ -2147,7 +2128,7 @@ class DefaultTopicIdGetterTestCase(ModuleStoreTestCase):
|
||||
course = CourseFactory.create(discussion_topics=discussion_topics)
|
||||
expected_id = None
|
||||
result = _get_discussion_default_topic_id(course)
|
||||
self.assertEqual(expected_id, result)
|
||||
assert expected_id == result
|
||||
|
||||
def test_default_topic_id(self):
|
||||
discussion_topics = {
|
||||
@@ -2162,7 +2143,7 @@ class DefaultTopicIdGetterTestCase(ModuleStoreTestCase):
|
||||
course = CourseFactory.create(discussion_topics=discussion_topics)
|
||||
expected_id = 'another_discussion_id'
|
||||
result = _get_discussion_default_topic_id(course)
|
||||
self.assertEqual(expected_id, result)
|
||||
assert expected_id == result
|
||||
|
||||
|
||||
class ThreadViewedEventTestCase(EventTestMixin, ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase):
|
||||
@@ -2249,4 +2230,4 @@ class ThreadViewedEventTestCase(EventTestMixin, ForumsEnableMixin, UrlResetMixin
|
||||
self.assert_event_emission_count('edx.forum.thread.viewed', 1)
|
||||
_, event = self.get_latest_call_args()
|
||||
event_items = list(event.items())
|
||||
self.assertTrue(kv_pair in event_items for kv_pair in expected_event_items)
|
||||
assert ((kv_pair in event_items) for kv_pair in expected_event_items)
|
||||
|
||||
Reference in New Issue
Block a user