Commit 545701d5 by Greg Price

Add forum utility code unit test coverage

This is in preparation for significant refactoring of the code in
question.
parent 54ad4110
from datetime import datetime
from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from student.tests.factories import UserFactory, CourseEnrollmentFactory from student.tests.factories import UserFactory, CourseEnrollmentFactory
from django_comment_common.models import Role, Permission from django_comment_common.models import Role, Permission
from factories import RoleFactory from factories import RoleFactory
import django_comment_client.utils as utils 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): class DictionaryTestCase(TestCase):
def test_extract(self): def test_extract(self):
...@@ -29,153 +34,444 @@ class DictionaryTestCase(TestCase): ...@@ -29,153 +34,444 @@ class DictionaryTestCase(TestCase):
self.assertEqual(utils.merge_dict(d1, d2), expected) self.assertEqual(utils.merge_dict(d1, d2), expected)
class CategorySortTestCase(TestCase): class AccessUtilsTestCase(TestCase):
def setUp(self):
self.course_id = 'edX/toy/2012_Fall'
self.student_role = RoleFactory(name='Student', course_id=self.course_id)
self.moderator_role = RoleFactory(name='Moderator', course_id=self.course_id)
self.student1 = UserFactory(username='student', email='student@edx.org')
self.student1_enrollment = CourseEnrollmentFactory(user=self.student1)
self.student_role.users.add(self.student1)
self.student2 = UserFactory(username='student2', email='student2@edx.org')
self.student2_enrollment = CourseEnrollmentFactory(user=self.student2)
self.moderator = UserFactory(username='moderator', email='staff@edx.org', is_staff=True)
self.moderator_enrollment = CourseEnrollmentFactory(user=self.moderator)
self.moderator_role.users.add(self.moderator)
def test_get_role_ids(self):
ret = utils.get_role_ids(self.course_id)
expected = {u'Moderator': [3], u'Student': [1, 2], 'Staff': [3]}
self.assertEqual(ret, expected)
def test_has_forum_access(self):
ret = utils.has_forum_access('student', self.course_id, 'Student')
self.assertTrue(ret)
ret = utils.has_forum_access('not_a_student', self.course_id, 'Student')
self.assertFalse(ret)
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): def setUp(self):
self.category_map = { self.course = CourseFactory.create(org="TestX", number="101", display_name="Test Course")
'entries': { self.discussion1 = ItemFactory.create(
u'General': { parent_location=self.course.location,
'sort_key': u'General' 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
} }
}, )
'subcategories': { )
u'Tests': { self.assertEqual(
'sort_key': u'Tests', courseware_context["courseware_title"],
'subcategories': {}, expected_title
'entries': { )
u'Quizzes': {
'sort_key': None test_discussion(self.discussion1, "Chapter / Discussion 1")
}, u'All': { test_discussion(self.discussion2, " Subsection / Discussion 2")
'sort_key': None
}, u'Final Exam': {
'sort_key': None @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"},
}, },
u'Assignments': { "subcategories": {},
'sort_key': u'Assignments', "children": ["Topic A", "Topic B", "Topic C"]
'subcategories': {},
'entries': {
u'Homework': {
'sort_key': None
},
u'All': {
'sort_key': None
},
} }
)
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_alpha_sort_true(self): def test_tree(self):
expected_true = { self.create_discussion("Chapter 1", "Discussion 1")
'entries': { self.create_discussion("Chapter 1", "Discussion 2")
u'General': { self.create_discussion("Chapter 2", "Discussion")
'sort_key': u'General' 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
} }
}, },
'children': [u'Assignments', u'General', u'Tests'], "subcategories": {},
'subcategories': { "children": ["Discussion 1", "Discussion 2"]
u'Tests': { },
'sort_key': u'Tests', "Chapter 2": {
'subcategories': {}, "entries": {
'children': [u'All', u'Final Exam', u'Quizzes'], "Discussion": {
'entries': { "id": "discussion3",
u'All': { "sort_key": None
'sort_key': 'All'
}, u'Final Exam': {
'sort_key': 'Final Exam'
}, u'Quizzes': {
'sort_key': 'Quizzes'
} }
},
"subcategories": {
"Section 1": {
"entries": {},
"subcategories": {
"Subsection 1": {
"entries": {
"Discussion": {
"id": "discussion4",
"sort_key": None
} }
}, },
u'Assignments': { "subcategories": {},
'sort_key': u'Assignments', "children": ["Discussion"]
'subcategories': {},
'children': [u'All', u'Homework'],
'entries': {
u'Homework': {
'sort_key': 'Homework'
}, },
u'All': { "Subsection 2": {
'sort_key': 'All' "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"]
} }
)
utils.sort_map_entries(self.category_map, True) def test_start_date_filter(self):
self.assertEqual(self.category_map, expected_true) 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)
def test_alpha_sort_false(self): self.assertCategoryMapEquals(
expected_false = { {
'entries': { "entries": {},
u'General': { "subcategories": {
'sort_key': u'General' "Chapter 1": {
"entries": {
"Discussion 1": {
"id": "discussion1",
"sort_key": None
} }
}, },
'children': [u'Assignments', u'General', u'Tests'], "subcategories": {},
'subcategories': { "children": ["Discussion 1"]
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
}, },
"Chapter 2": {
"entries": {
"Discussion": {
"id": "discussion3",
"sort_key": None
} }
}, },
u'Assignments': { "subcategories": {},
'sort_key': u'Assignments', "children": ["Discussion"]
'subcategories': {}, }
'children': [u'All', u'Homework'],
'entries': {
u'Homework': {
'sort_key': None
},
u'All': {
'sort_key': None
}, },
"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"]
} }
)
utils.sort_map_entries(self.category_map, False) def test_sort_configured_topics_explicit(self):
self.assertEqual(self.category_map, expected_false) 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")
class AccessUtilsTestCase(TestCase): self.assertCategoryMapEquals(
def setUp(self): {
self.course_id = 'edX/toy/2012_Fall' "entries": {},
self.student_role = RoleFactory(name='Student', course_id=self.course_id) "subcategories": {
self.moderator_role = RoleFactory(name='Moderator', course_id=self.course_id) "Chapter": {
self.student1 = UserFactory(username='student', email='student@edx.org') "entries": {
self.student1_enrollment = CourseEnrollmentFactory(user=self.student1) "Discussion D": {
self.student_role.users.add(self.student1) "id": "discussion1",
self.student2 = UserFactory(username='student2', email='student2@edx.org') "sort_key": "Discussion D"
self.student2_enrollment = CourseEnrollmentFactory(user=self.student2) },
self.moderator = UserFactory(username='moderator', email='staff@edx.org', is_staff=True) "Discussion A": {
self.moderator_enrollment = CourseEnrollmentFactory(user=self.moderator) "id": "discussion2",
self.moderator_role.users.add(self.moderator) "sort_key": "Discussion A"
},
def test_get_role_ids(self): "Discussion E": {
ret = utils.get_role_ids(self.course_id) "id": "discussion3",
expected = {u'Moderator': [3], u'Student': [1, 2], 'Staff': [3]} "sort_key": "Discussion E"
self.assertEqual(ret, expected) },
"Discussion C": {
def test_has_forum_access(self): "id": "discussion4",
ret = utils.has_forum_access('student', self.course_id, 'Student') "sort_key": "Discussion C"
self.assertTrue(ret) },
"Discussion B": {
"id": "discussion5",
"sort_key": "Discussion B"
}
},
"subcategories": {},
"children": [
"Discussion A",
"Discussion B",
"Discussion C",
"Discussion D",
"Discussion E"
]
}
},
"children": ["Chapter"]
}
)
ret = utils.has_forum_access('not_a_student', self.course_id, 'Student') def test_sort_intermediates(self):
self.assertFalse(ret) 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")
ret = utils.has_forum_access('student', self.course_id, 'NotARole') self.assertCategoryMapEquals(
self.assertFalse(ret) {
"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"]
}
)
...@@ -70,10 +70,10 @@ def get_discussion_id_map(course): ...@@ -70,10 +70,10 @@ def get_discussion_id_map(course):
def get_discussion_category_map(course): def get_discussion_category_map(course):
initialize_discussion_info(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()) now = datetime.now(UTC())
...@@ -111,7 +111,7 @@ def filter_unstarted_categories(category_map): ...@@ -111,7 +111,7 @@ def filter_unstarted_categories(category_map):
return result_map return result_map
def sort_map_entries(category_map, sort_alpha): def _sort_map_entries(category_map, sort_alpha):
things = [] things = []
for title, entry in category_map["entries"].items(): for title, entry in category_map["entries"].items():
if entry["sort_key"] == None and sort_alpha: if entry["sort_key"] == None and sort_alpha:
...@@ -119,7 +119,7 @@ def sort_map_entries(category_map, sort_alpha): ...@@ -119,7 +119,7 @@ def sort_map_entries(category_map, sort_alpha):
things.append((title, entry)) things.append((title, entry))
for title, category in category_map["subcategories"].items(): for title, category in category_map["subcategories"].items():
things.append((title, category)) 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"])] 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): ...@@ -199,7 +199,7 @@ def initialize_discussion_info(course):
"sort_key": entry.get("sort_key", topic), "sort_key": entry.get("sort_key", topic),
"start_date": datetime.now(UTC())} "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]['id_map'] = discussion_id_map
_DISCUSSIONINFO[course.id]['category_map'] = category_map _DISCUSSIONINFO[course.id]['category_map'] = category_map
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment