diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index faec60f3e8..1d3fca1bcc 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -94,6 +94,33 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): return cnt + def test_get_items(self): + ''' + This verifies a bug we had where the None setting in get_items() meant 'wildcard' + Unfortunately, None = published for the revision field, so get_items() would return + both draft and non-draft copies. + ''' + store = modulestore() + draft_store = modulestore('draft') + import_from_xml(store, 'common/test/data/', ['simple']) + + html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None]) + + draft_store.clone_item(html_module.location, html_module.location) + + # now query get_items() to get this location with revision=None, this should just + # return back a single item (not 2) + + items = store.get_items(['i4x', 'edX', 'simple', 'html', 'test_html', None]) + self.assertEqual(len(items), 1) + self.assertFalse(getattr(items[0], 'is_draft', False)) + + # now refetch from the draft store. Note that even though we pass + # None in the revision field, the draft store will replace that with 'draft' + items = draft_store.get_items(['i4x', 'edX', 'simple', 'html', 'test_html', None]) + self.assertEqual(len(items), 1) + self.assertTrue(getattr(items[0], 'is_draft', False)) + def test_draft_metadata(self): ''' This verifies a bug we had where inherited metadata was getting written to the diff --git a/common/lib/xmodule/xmodule/modulestore/mongo.py b/common/lib/xmodule/xmodule/modulestore/mongo.py index 653a7ca22a..dd51be3bf6 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo.py @@ -203,7 +203,9 @@ def location_to_query(location, wildcard=True): if wildcard: for key, value in query.items(): - if value is None: + # don't allow wildcards on revision, since public is set as None, so + # its ambiguous between None as a real value versus None=wildcard + if value is None and key != '_id.revision': del query[key] return query