Files
edx-platform/lms/djangoapps/discussion_api/tests/test_forms.py
christopher lee 5b35ab3668 Added optional mark_as_read field to comments in Discussion API
Currently when GETting comments, the thread of the comment will be
marked as read. This change makes this effect optional as well as
setting the default to not mark the thread as read.
2015-08-12 12:25:06 -04:00

200 lines
6.6 KiB
Python

"""
Tests for Discussion API forms
"""
import itertools
from unittest import TestCase
from urllib import urlencode
import ddt
from django.http import QueryDict
from opaque_keys.edx.locator import CourseLocator
from discussion_api.forms import CommentListGetForm, ThreadListGetForm
class FormTestMixin(object):
"""A mixin for testing forms"""
def get_form(self, expected_valid):
"""
Return a form bound to self.form_data, asserting its validity (or lack
thereof) according to expected_valid
"""
form = self.FORM_CLASS(self.form_data)
self.assertEqual(form.is_valid(), expected_valid)
return form
def assert_error(self, expected_field, expected_message):
"""
Create a form bound to self.form_data, assert its invalidity, and assert
that its error dictionary contains one entry with the expected field and
message
"""
form = self.get_form(expected_valid=False)
self.assertEqual(form.errors, {expected_field: [expected_message]})
def assert_field_value(self, field, expected_value):
"""
Create a form bound to self.form_data, assert its validity, and assert
that the given field in the cleaned data has the expected value
"""
form = self.get_form(expected_valid=True)
self.assertEqual(form.cleaned_data[field], expected_value)
class PaginationTestMixin(object):
"""A mixin for testing forms with pagination fields"""
def test_missing_page(self):
self.form_data.pop("page")
self.assert_field_value("page", 1)
def test_invalid_page(self):
self.form_data["page"] = "0"
self.assert_error("page", "Ensure this value is greater than or equal to 1.")
def test_missing_page_size(self):
self.form_data.pop("page_size")
self.assert_field_value("page_size", 10)
def test_zero_page_size(self):
self.form_data["page_size"] = "0"
self.assert_error("page_size", "Ensure this value is greater than or equal to 1.")
def test_excessive_page_size(self):
self.form_data["page_size"] = "101"
self.assert_field_value("page_size", 100)
@ddt.ddt
class ThreadListGetFormTest(FormTestMixin, PaginationTestMixin, TestCase):
"""Tests for ThreadListGetForm"""
FORM_CLASS = ThreadListGetForm
def setUp(self):
super(ThreadListGetFormTest, self).setUp()
self.form_data = QueryDict(
urlencode(
{
"course_id": "Foo/Bar/Baz",
"page": "2",
"page_size": "13",
}
),
mutable=True
)
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": [],
"text_search": "",
"following": None,
"view": "",
"order_by": "last_activity_at",
"order_direction": "desc",
}
)
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"],
)
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",
)
def test_missing_course_id(self):
self.form_data.pop("course_id")
self.assert_error("course_id", "This field is required.")
def test_invalid_course_id(self):
self.form_data["course_id"] = "invalid course id"
self.assert_error("course_id", "'invalid course id' is not a valid course id")
def test_empty_topic_id(self):
self.form_data.setlist("topic_id", ["", "not empty"])
self.assert_error("topic_id", "This field cannot be empty.")
def test_following_true(self):
self.form_data["following"] = "True"
self.assert_field_value("following", True)
def test_following_false(self):
self.form_data["following"] = "False"
self.assert_error("following", "The value of the 'following' parameter must be true.")
@ddt.data(*itertools.combinations(["topic_id", "text_search", "following"], 2))
def test_mutually_exclusive(self, params):
self.form_data.update({param: "True" for param in params})
self.assert_error(
"__all__",
"The following query parameters are mutually exclusive: topic_id, text_search, following"
)
def test_invalid_view_choice(self):
self.form_data["view"] = "not_a_valid_choice"
self.assert_error("view", "Select a valid choice. not_a_valid_choice is not one of the available choices.")
def test_invalid_sort_by_choice(self):
self.form_data["order_by"] = "not_a_valid_choice"
self.assert_error(
"order_by",
"Select a valid choice. not_a_valid_choice is not one of the available choices."
)
def test_invalid_sort_direction_choice(self):
self.form_data["order_direction"] = "not_a_valid_choice"
self.assert_error(
"order_direction",
"Select a valid choice. not_a_valid_choice is not one of the available choices."
)
class CommentListGetFormTest(FormTestMixin, PaginationTestMixin, TestCase):
"""Tests for CommentListGetForm"""
FORM_CLASS = CommentListGetForm
def setUp(self):
super(CommentListGetFormTest, self).setUp()
self.form_data = {
"thread_id": "deadbeef",
"endorsed": "False",
"page": "2",
"page_size": "13",
}
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,
"mark_as_read": False
}
)
def test_missing_thread_id(self):
self.form_data.pop("thread_id")
self.assert_error("thread_id", "This field is required.")
def test_missing_endorsed(self):
self.form_data.pop("endorsed")
self.assert_field_value("endorsed", None)