From 3c55c91c5a566c3b43e71f466be3b33232abca55 Mon Sep 17 00:00:00 2001 From: Usman Khalid <2200617@gmail.com> Date: Tue, 18 Feb 2014 15:14:56 +0500 Subject: [PATCH] Added get_courses_for_wiki(self, wiki_slug) to mongo, xml and mixed modulestores. This method returns a list of courses which use the particular wiki_slug. It is used for checking permissions in the course_wiki app. LMS-2136 --- .../lib/xmodule/xmodule/modulestore/mixed.py | 11 +++++ .../xmodule/xmodule/modulestore/mongo/base.py | 4 +- .../xmodule/modulestore/split_mongo/split.py | 11 +++++ .../tests/test_mixed_modulestore.py | 18 ++++++++ .../xmodule/modulestore/tests/test_mongo.py | 46 +++++++++++++------ .../xmodule/modulestore/tests/test_xml.py | 31 +++++++++++-- common/lib/xmodule/xmodule/modulestore/xml.py | 9 ++++ 7 files changed, 110 insertions(+), 20 deletions(-) diff --git a/common/lib/xmodule/xmodule/modulestore/mixed.py b/common/lib/xmodule/xmodule/modulestore/mixed.py index 5152ea9231..a3757b42d4 100644 --- a/common/lib/xmodule/xmodule/modulestore/mixed.py +++ b/common/lib/xmodule/xmodule/modulestore/mixed.py @@ -417,6 +417,17 @@ class MixedModuleStore(ModuleStoreWriteBase): for course in store.get_courses(): loc_mapper().translate_location(course.location.course_id, course.location) + def get_courses_for_wiki(self, wiki_slug): + """ + Return the list of courses which use this wiki_slug + :param wiki_slug: the course wiki root slug + :return: list of course locations + """ + courses = [] + for modulestore in self.modulestores.values(): + courses.extend(modulestore.get_courses_for_wiki(wiki_slug)) + return courses + def _compare_stores(left, right): """ diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index 587cc69753..116a48b31c 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -880,8 +880,8 @@ class MongoModuleStore(ModuleStoreWriteBase): def get_courses_for_wiki(self, wiki_slug): """ - Return the list of courses which use this wiki - :param wiki_slug: the wiki id + Return the list of courses which use this wiki_slug + :param wiki_slug: the course wiki root slug :return: list of course locations """ courses = self.collection.find({'definition.data.wiki_slug': wiki_slug}) diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py index da61e061a1..cdc12655db 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py @@ -1645,3 +1645,14 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): be a json dict key. """ structure['blocks'][LocMapperStore.encode_key_for_mongo(block_id)] = content + + def get_courses_for_wiki(self, wiki_slug): + """ + Return the list of courses which use this wiki_slug + :param wiki_slug: the course wiki root slug + :return: list of course locations + + Todo: Needs to be implemented. + """ + courses = [] + return courses \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index d2e31cb831..1bc868f982 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -368,6 +368,24 @@ class TestMixedModuleStore(LocMapperSetupSansDjango): orphans = self.store.get_orphans(self.course_locations[self.MONGO_COURSEID], None) self.assertEqual(len(orphans), 0, "unexpected orphans: {}".format(orphans)) + @ddt.data('direct') + def test_get_courses_for_wiki(self, default_ms): + """ + Test the get_courses_for_wiki method + """ + self.initdb(default_ms) + course_locations = self.store.get_courses_for_wiki('toy') + self.assertEqual(len(course_locations), 1) + self.assertIn(Location('i4x', 'edX', 'toy', 'course', '2012_Fall'), course_locations) + + course_locations = self.store.get_courses_for_wiki('simple') + self.assertEqual(len(course_locations), 1) + self.assertIn(Location('i4x', 'edX', 'simple', 'course', '2012_Fall'), course_locations) + + self.assertEqual(len(self.store.get_courses_for_wiki('edX.simple.2012_Fall')), 0) + self.assertEqual(len(self.store.get_courses_for_wiki('no_such_wiki')), 0) + + #============================================================================================================= # General utils for not using django settings #============================================================================================================= diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py index 169405e134..730f700bb7 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py @@ -278,20 +278,38 @@ class TestMongoModuleStore(object): """ Test the get_courses_for_wiki method """ - for course_id in self.courses: - courses = self.store.get_courses_for_wiki(course_id) - assert_equals(len(courses), 1) - assert_equals(Location('i4x', 'edX', course_id, 'course', '2012_Fall'), courses[0]) - course_locs = self.store.get_courses_for_wiki('no_such_wiki') - assert_equals(len(course_locs), 0) - # now set two to have same wiki - course = self.store.get_course('edX/toy/2012_Fall') - course.wiki_slug = 'simple' - self.store.save_xmodule(course) - courses = self.store.get_courses_for_wiki('simple') - assert_equals(len(courses), 2) - for course_id in ['toy', 'simple']: - assert_in(Location('i4x', 'edX', course_id, 'course', '2012_Fall'), courses) + for course_number in self.courses: + course_locations = self.store.get_courses_for_wiki(course_number) + assert_equals(len(course_locations), 1) + assert_equals(Location('i4x', 'edX', course_number, 'course', '2012_Fall'), course_locations[0]) + + course_locations = self.store.get_courses_for_wiki('no_such_wiki') + assert_equals(len(course_locations), 0) + + # set toy course to share the wiki with simple course + toy_course = self.store.get_course('edX/toy/2012_Fall') + toy_course.wiki_slug = 'simple' + self.store.update_item(toy_course) + + # now toy_course should not be retrievable with old wiki_slug + course_locations = self.store.get_courses_for_wiki('toy') + assert_equals(len(course_locations), 0) + + # but there should be two courses with wiki_slug 'simple' + course_locations = self.store.get_courses_for_wiki('simple') + assert_equals(len(course_locations), 2) + for course_number in ['toy', 'simple']: + assert_in(Location('i4x', 'edX', course_number, 'course', '2012_Fall'), course_locations) + + # configure simple course to use unique wiki_slug. + simple_course = self.store.get_course('edX/simple/2012_Fall') + simple_course.wiki_slug = 'edX.simple.2012_Fall' + self.store.update_item(simple_course) + # it should be retrievable with its new wiki_slug + course_locations = self.store.get_courses_for_wiki('edX.simple.2012_Fall') + assert_equals(len(course_locations), 1) + assert_in(Location('i4x', 'edX', 'simple', 'course', '2012_Fall'), course_locations) + class TestMongoKeyValueStore(object): """ diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_xml.py b/common/lib/xmodule/xmodule/modulestore/tests/test_xml.py index 71274aae5f..8cbdbbeffe 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_xml.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_xml.py @@ -7,8 +7,6 @@ import unittest from glob import glob from mock import patch -from nose.tools import assert_raises, assert_equals # pylint: disable=E0611 - from xmodule.course_module import CourseDescriptor from xmodule.modulestore.xml import XMLModuleStore from xmodule.modulestore import Location, XML_MODULESTORE_TYPE @@ -43,7 +41,7 @@ class TestXMLModuleStore(unittest.TestCase): def test_xml_modulestore_type(self): store = XMLModuleStore(DATA_DIR, course_dirs=['toy', 'simple']) - assert_equals(store.get_modulestore_type('foo/bar/baz'), XML_MODULESTORE_TYPE) + self.assertEqual(store.get_modulestore_type('foo/bar/baz'), XML_MODULESTORE_TYPE) def test_unicode_chars_in_xml_content(self): # edX/full/6.002_Spring_2012 has non-ASCII chars, and during @@ -52,7 +50,7 @@ class TestXMLModuleStore(unittest.TestCase): # Ensure that there really is a non-ASCII character in the course. with open(os.path.join(DATA_DIR, "toy/sequential/vertical_sequential.xml")) as xmlf: xml = xmlf.read() - with assert_raises(UnicodeDecodeError): + with self.assertRaises(UnicodeDecodeError): xml.decode('ascii') # Load the course, but don't make error modules. This will succeed, @@ -78,3 +76,28 @@ class TestXMLModuleStore(unittest.TestCase): about_module = course_module[about_location] self.assertIn("GREEN", about_module.data) self.assertNotIn("RED", about_module.data) + + def test_get_courses_for_wiki(self): + """ + Test the get_courses_for_wiki method + """ + store = XMLModuleStore(DATA_DIR, course_dirs=['toy', 'simple']) + for course in store.get_courses(): + course_locations = store.get_courses_for_wiki(course.wiki_slug) + self.assertEqual(len(course_locations), 1) + self.assertIn(Location('i4x', 'edX', course.location.course, 'course', '2012_Fall'), course_locations) + + course_locations = store.get_courses_for_wiki('no_such_wiki') + self.assertEqual(len(course_locations), 0) + + # now set toy course to share the wiki with simple course + toy_course = store.get_course('edX/toy/2012_Fall') + toy_course.wiki_slug = 'simple' + + course_locations = store.get_courses_for_wiki('toy') + self.assertEqual(len(course_locations), 0) + + course_locations = store.get_courses_for_wiki('simple') + self.assertEqual(len(course_locations), 2) + for course_number in ['toy', 'simple']: + self.assertIn(Location('i4x', 'edX', course_number, 'course', '2012_Fall'), course_locations) diff --git a/common/lib/xmodule/xmodule/modulestore/xml.py b/common/lib/xmodule/xmodule/modulestore/xml.py index cdaf446cdc..445ecee039 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml.py +++ b/common/lib/xmodule/xmodule/modulestore/xml.py @@ -790,3 +790,12 @@ class XMLModuleStore(ModuleStoreReadBase): "split" for new-style split MongoDB backed courses. """ return XML_MODULESTORE_TYPE + + def get_courses_for_wiki(self, wiki_slug): + """ + Return the list of courses which use this wiki_slug + :param wiki_slug: the course wiki root slug + :return: list of course locations + """ + courses = self.get_courses() + return [course.location for course in courses if (course.wiki_slug == wiki_slug)]