Add forum utility code unit test coverage

This is in preparation for significant refactoring of the code in
question.
This commit is contained in:
Greg Price
2013-10-25 17:16:37 -04:00
parent 54ad411078
commit 545701d520
2 changed files with 424 additions and 128 deletions

View File

@@ -1,9 +1,14 @@
from datetime import datetime
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.utils import override_settings
from student.tests.factories import UserFactory, CourseEnrollmentFactory
from django_comment_common.models import Role, Permission
from factories import RoleFactory
import django_comment_client.utils as utils
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
class DictionaryTestCase(TestCase):
def test_extract(self):
@@ -29,128 +34,6 @@ class DictionaryTestCase(TestCase):
self.assertEqual(utils.merge_dict(d1, d2), expected)
class CategorySortTestCase(TestCase):
def setUp(self):
self.category_map = {
'entries': {
u'General': {
'sort_key': u'General'
}
},
'subcategories': {
u'Tests': {
'sort_key': u'Tests',
'subcategories': {},
'entries': {
u'Quizzes': {
'sort_key': None
}, u'All': {
'sort_key': None
}, u'Final Exam': {
'sort_key': None
},
}
},
u'Assignments': {
'sort_key': u'Assignments',
'subcategories': {},
'entries': {
u'Homework': {
'sort_key': None
},
u'All': {
'sort_key': None
},
}
}
}
}
def test_alpha_sort_true(self):
expected_true = {
'entries': {
u'General': {
'sort_key': u'General'
}
},
'children': [u'Assignments', u'General', u'Tests'],
'subcategories': {
u'Tests': {
'sort_key': u'Tests',
'subcategories': {},
'children': [u'All', u'Final Exam', u'Quizzes'],
'entries': {
u'All': {
'sort_key': 'All'
}, u'Final Exam': {
'sort_key': 'Final Exam'
}, u'Quizzes': {
'sort_key': 'Quizzes'
}
}
},
u'Assignments': {
'sort_key': u'Assignments',
'subcategories': {},
'children': [u'All', u'Homework'],
'entries': {
u'Homework': {
'sort_key': 'Homework'
},
u'All': {
'sort_key': 'All'
},
}
}
}
}
utils.sort_map_entries(self.category_map, True)
self.assertEqual(self.category_map, expected_true)
def test_alpha_sort_false(self):
expected_false = {
'entries': {
u'General': {
'sort_key': u'General'
}
},
'children': [u'Assignments', u'General', u'Tests'],
'subcategories': {
u'Tests': {
'sort_key': u'Tests',
'subcategories': {},
'children': [u'Quizzes', u'All', u'Final Exam'],
'entries': {
u'Quizzes': {
'sort_key': None
}, u'All': {
'sort_key': None
}, u'Final Exam': {
'sort_key': None
},
}
},
u'Assignments': {
'sort_key': u'Assignments',
'subcategories': {},
'children': [u'All', u'Homework'],
'entries': {
u'Homework': {
'sort_key': None
},
u'All': {
'sort_key': None
},
}
}
}
}
utils.sort_map_entries(self.category_map, False)
self.assertEqual(self.category_map, expected_false)
class AccessUtilsTestCase(TestCase):
def setUp(self):
self.course_id = 'edX/toy/2012_Fall'
@@ -179,3 +62,416 @@ class AccessUtilsTestCase(TestCase):
ret = utils.has_forum_access('student', self.course_id, 'NotARole')
self.assertFalse(ret)
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class CoursewareContextTestCase(ModuleStoreTestCase):
def setUp(self):
self.course = CourseFactory.create(org="TestX", number="101", display_name="Test Course")
self.discussion1 = ItemFactory.create(
parent_location=self.course.location,
category="discussion",
discussion_id="discussion1",
discussion_category="Chapter",
discussion_target="Discussion 1"
)
self.discussion2 = ItemFactory.create(
parent_location=self.course.location,
category="discussion",
discussion_id="discussion2",
discussion_category="Chapter / Section / Subsection",
discussion_target="Discussion 2"
)
def test_missing_commentable_id(self):
thread = {"commentable_id": "non-inline"}
self.assertEqual(utils.get_courseware_context(thread, self.course), None)
def test_basic(self):
def test_discussion(discussion, expected_title):
thread = {"commentable_id": discussion.discussion_id}
courseware_context = utils.get_courseware_context(thread, self.course)
self.assertEqual(set(courseware_context.keys()), set(["courseware_url", "courseware_title"]))
self.assertEqual(
courseware_context["courseware_url"],
reverse(
"jump_to",
kwargs={
"course_id": self.course.location.course_id,
"location": discussion.location
}
)
)
self.assertEqual(
courseware_context["courseware_title"],
expected_title
)
test_discussion(self.discussion1, "Chapter / Discussion 1")
test_discussion(self.discussion2, " Subsection / Discussion 2")
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class CategoryMapTestCase(ModuleStoreTestCase):
def setUp(self):
self.course = CourseFactory.create(org="TestX", number="101", display_name="Test Course")
# Courses get a default discussion topic on creation, so remove it
self.course.discussion_topics = {}
self.course.save()
self.discussion_num = 0
self.maxDiff = None #pylint: disable=C0103
def create_discussion(self, discussion_category, discussion_target, **kwargs):
self.discussion_num += 1
ItemFactory.create(
parent_location=self.course.location,
category="discussion",
discussion_id="discussion{}".format(self.discussion_num),
discussion_category=discussion_category,
discussion_target=discussion_target,
**kwargs
)
def assertCategoryMapEquals(self, expected):
self.assertEqual(
utils.get_discussion_category_map(self.course),
expected
)
def test_empty(self):
self.assertEqual(
utils.get_discussion_category_map(self.course),
{"entries": {}, "subcategories": {}, "children": []}
)
def test_configured_topics(self):
self.course.discussion_topics = {
"Topic A": {"id": "Topic_A"},
"Topic B": {"id": "Topic_B"},
"Topic C": {"id": "Topic_C"}
}
self.assertCategoryMapEquals(
{
"entries": {
"Topic A": {"id": "Topic_A", "sort_key": "Topic A"},
"Topic B": {"id": "Topic_B", "sort_key": "Topic B"},
"Topic C": {"id": "Topic_C", "sort_key": "Topic C"},
},
"subcategories": {},
"children": ["Topic A", "Topic B", "Topic C"]
}
)
def test_single_inline(self):
self.create_discussion("Chapter", "Discussion")
self.assertCategoryMapEquals(
{
"entries": {},
"subcategories": {
"Chapter": {
"entries": {
"Discussion": {
"id": "discussion1",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion"]
}
},
"children": ["Chapter"]
}
)
def test_tree(self):
self.create_discussion("Chapter 1", "Discussion 1")
self.create_discussion("Chapter 1", "Discussion 2")
self.create_discussion("Chapter 2", "Discussion")
self.create_discussion("Chapter 2 / Section 1 / Subsection 1", "Discussion")
self.create_discussion("Chapter 2 / Section 1 / Subsection 2", "Discussion")
self.create_discussion("Chapter 3 / Section 1", "Discussion")
self.assertCategoryMapEquals(
{
"entries": {},
"subcategories": {
"Chapter 1": {
"entries": {
"Discussion 1": {
"id": "discussion1",
"sort_key": None
},
"Discussion 2": {
"id": "discussion2",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion 1", "Discussion 2"]
},
"Chapter 2": {
"entries": {
"Discussion": {
"id": "discussion3",
"sort_key": None
}
},
"subcategories": {
"Section 1": {
"entries": {},
"subcategories": {
"Subsection 1": {
"entries": {
"Discussion": {
"id": "discussion4",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion"]
},
"Subsection 2": {
"entries": {
"Discussion": {
"id": "discussion5",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion"]
}
},
"children": ["Subsection 1", "Subsection 2"]
}
},
"children": ["Discussion", "Section 1"]
},
"Chapter 3": {
"entries": {},
"subcategories": {
"Section 1": {
"entries": {
"Discussion": {
"id": "discussion6",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion"]
}
},
"children": ["Section 1"]
}
},
"children": ["Chapter 1", "Chapter 2", "Chapter 3"]
}
)
def test_start_date_filter(self):
now = datetime.now()
later = datetime.max
self.create_discussion("Chapter 1", "Discussion 1", start=now)
self.create_discussion("Chapter 1", "Discussion 2", start=later)
self.create_discussion("Chapter 2", "Discussion", start=now)
self.create_discussion("Chapter 2 / Section 1 / Subsection 1", "Discussion", start=later)
self.create_discussion("Chapter 2 / Section 1 / Subsection 2", "Discussion", start=later)
self.create_discussion("Chapter 3 / Section 1", "Discussion", start=later)
self.assertCategoryMapEquals(
{
"entries": {},
"subcategories": {
"Chapter 1": {
"entries": {
"Discussion 1": {
"id": "discussion1",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion 1"]
},
"Chapter 2": {
"entries": {
"Discussion": {
"id": "discussion3",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion"]
}
},
"children": ["Chapter 1", "Chapter 2"]
}
)
def test_sort_inline_explicit(self):
self.create_discussion("Chapter", "Discussion 1", sort_key="D")
self.create_discussion("Chapter", "Discussion 2", sort_key="A")
self.create_discussion("Chapter", "Discussion 3", sort_key="E")
self.create_discussion("Chapter", "Discussion 4", sort_key="C")
self.create_discussion("Chapter", "Discussion 5", sort_key="B")
self.assertCategoryMapEquals(
{
"entries": {},
"subcategories": {
"Chapter": {
"entries": {
"Discussion 1": {
"id": "discussion1",
"sort_key": "D"
},
"Discussion 2": {
"id": "discussion2",
"sort_key": "A"
},
"Discussion 3": {
"id": "discussion3",
"sort_key": "E"
},
"Discussion 4": {
"id": "discussion4",
"sort_key": "C"
},
"Discussion 5": {
"id": "discussion5",
"sort_key": "B"
}
},
"subcategories": {},
"children": [
"Discussion 2",
"Discussion 5",
"Discussion 4",
"Discussion 1",
"Discussion 3"
]
}
},
"children": ["Chapter"]
}
)
def test_sort_configured_topics_explicit(self):
self.course.discussion_topics = {
"Topic A": {"id": "Topic_A", "sort_key": "B"},
"Topic B": {"id": "Topic_B", "sort_key": "C"},
"Topic C": {"id": "Topic_C", "sort_key": "A"}
}
self.assertCategoryMapEquals(
{
"entries": {
"Topic A": {"id": "Topic_A", "sort_key": "B"},
"Topic B": {"id": "Topic_B", "sort_key": "C"},
"Topic C": {"id": "Topic_C", "sort_key": "A"},
},
"subcategories": {},
"children": ["Topic C", "Topic A", "Topic B"]
}
)
def test_sort_alpha(self):
self.course.discussion_sort_alpha = True
self.course.save()
self.create_discussion("Chapter", "Discussion D")
self.create_discussion("Chapter", "Discussion A")
self.create_discussion("Chapter", "Discussion E")
self.create_discussion("Chapter", "Discussion C")
self.create_discussion("Chapter", "Discussion B")
self.assertCategoryMapEquals(
{
"entries": {},
"subcategories": {
"Chapter": {
"entries": {
"Discussion D": {
"id": "discussion1",
"sort_key": "Discussion D"
},
"Discussion A": {
"id": "discussion2",
"sort_key": "Discussion A"
},
"Discussion E": {
"id": "discussion3",
"sort_key": "Discussion E"
},
"Discussion C": {
"id": "discussion4",
"sort_key": "Discussion C"
},
"Discussion B": {
"id": "discussion5",
"sort_key": "Discussion B"
}
},
"subcategories": {},
"children": [
"Discussion A",
"Discussion B",
"Discussion C",
"Discussion D",
"Discussion E"
]
}
},
"children": ["Chapter"]
}
)
def test_sort_intermediates(self):
self.create_discussion("Chapter B", "Discussion 2")
self.create_discussion("Chapter C", "Discussion")
self.create_discussion("Chapter A", "Discussion 1")
self.create_discussion("Chapter B", "Discussion 1")
self.create_discussion("Chapter A", "Discussion 2")
self.assertCategoryMapEquals(
{
"entries": {},
"subcategories": {
"Chapter A": {
"entries": {
"Discussion 1": {
"id": "discussion3",
"sort_key": None
},
"Discussion 2": {
"id": "discussion5",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion 1", "Discussion 2"]
},
"Chapter B": {
"entries": {
"Discussion 1": {
"id": "discussion4",
"sort_key": None
},
"Discussion 2": {
"id": "discussion1",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion 1", "Discussion 2"]
},
"Chapter C": {
"entries": {
"Discussion": {
"id": "discussion2",
"sort_key": None
}
},
"subcategories": {},
"children": ["Discussion"]
}
},
"children": ["Chapter A", "Chapter B", "Chapter C"]
}
)

View File

@@ -70,10 +70,10 @@ def get_discussion_id_map(course):
def get_discussion_category_map(course):
initialize_discussion_info(course)
return filter_unstarted_categories(_DISCUSSIONINFO[course.id]['category_map'])
return _filter_unstarted_categories(_DISCUSSIONINFO[course.id]['category_map'])
def filter_unstarted_categories(category_map):
def _filter_unstarted_categories(category_map):
now = datetime.now(UTC())
@@ -111,7 +111,7 @@ def filter_unstarted_categories(category_map):
return result_map
def sort_map_entries(category_map, sort_alpha):
def _sort_map_entries(category_map, sort_alpha):
things = []
for title, entry in category_map["entries"].items():
if entry["sort_key"] == None and sort_alpha:
@@ -119,7 +119,7 @@ def sort_map_entries(category_map, sort_alpha):
things.append((title, entry))
for title, category in category_map["subcategories"].items():
things.append((title, category))
sort_map_entries(category_map["subcategories"][title], sort_alpha)
_sort_map_entries(category_map["subcategories"][title], sort_alpha)
category_map["children"] = [x[0] for x in sorted(things, key=lambda x: x[1]["sort_key"])]
@@ -199,7 +199,7 @@ def initialize_discussion_info(course):
"sort_key": entry.get("sort_key", topic),
"start_date": datetime.now(UTC())}
sort_map_entries(category_map, course.discussion_sort_alpha)
_sort_map_entries(category_map, course.discussion_sort_alpha)
_DISCUSSIONINFO[course.id]['id_map'] = discussion_id_map
_DISCUSSIONINFO[course.id]['category_map'] = category_map