Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
6be33844
Commit
6be33844
authored
Jul 21, 2014
by
Sarina Canelake
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4431 from edx/split/get_wiki_courses
Split get_courses_for_wiki impl
parents
c7d88deb
d0449cdf
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
197 additions
and
46 deletions
+197
-46
cms/djangoapps/contentstore/tests/test_crud.py
+2
-0
cms/djangoapps/contentstore/tests/utils.py
+21
-5
common/lib/xmodule/xmodule/course_module.py
+1
-4
common/lib/xmodule/xmodule/modulestore/__init__.py
+9
-0
common/lib/xmodule/xmodule/modulestore/mixed.py
+1
-1
common/lib/xmodule/xmodule/modulestore/mongo/base.py
+13
-3
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+53
-9
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+72
-8
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
+3
-3
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
+6
-2
common/lib/xmodule/xmodule/modulestore/tests/test_xml.py
+2
-2
common/lib/xmodule/xmodule/modulestore/xml.py
+1
-1
lms/djangoapps/course_wiki/utils.py
+13
-8
No files found.
cms/djangoapps/contentstore/tests/test_crud.py
View file @
6be33844
...
...
@@ -204,6 +204,8 @@ class TemplateTests(unittest.TestCase):
# course root only updated 2x
version_history
=
self
.
split_store
.
get_block_generations
(
test_course
.
location
)
# create course causes 2 versions for the time being; skip the first.
version_history
=
version_history
.
children
[
0
]
self
.
assertEqual
(
version_history
.
locator
.
version_guid
,
test_course
.
location
.
version_guid
)
self
.
assertEqual
(
len
(
version_history
.
children
),
1
)
self
.
assertEqual
(
version_history
.
children
[
0
]
.
children
,
[])
...
...
cms/djangoapps/contentstore/tests/utils.py
View file @
6be33844
...
...
@@ -262,11 +262,23 @@ class CourseTestCase(ModuleStoreTestCase):
self
.
store
.
compute_publish_state
(
course2_item
)
)
except
AssertionError
:
# old mongo calls things draft if draft exists even if it's != published; so, do more work
self
.
assertEqual
(
self
.
compute_real_state
(
course1_item
),
self
.
compute_real_state
(
course2_item
)
)
# TODO LMS-11017 "Studio auto-publish course-wide features and settings"
# Temporary hack until autopublish implemented - right now, because we call
# update_item within create_course to set the wiki & other course-wide settings,
# the publish version does not necessarily equal the draft version in split.
# So if either item is in Split, just continue on
if
not
isinstance
(
course1_item
.
runtime
.
modulestore
,
SplitMongoModuleStore
)
and
\
not
isinstance
(
course2_item
.
runtime
.
modulestore
,
SplitMongoModuleStore
):
# old mongo calls things draft if draft exists even if it's != published; so, do more work
c1_state
=
self
.
compute_real_state
(
course1_item
)
c2_state
=
self
.
compute_real_state
(
course2_item
)
self
.
assertEqual
(
c1_state
,
c2_state
,
"Course item {} in state {} != course item {} in state {}"
.
format
(
course1_item
,
c1_state
,
course2_item
,
c2_state
)
)
# compare data
self
.
assertEqual
(
hasattr
(
course1_item
,
'data'
),
hasattr
(
course2_item
,
'data'
))
...
...
@@ -329,11 +341,15 @@ class CourseTestCase(ModuleStoreTestCase):
# see if the draft differs from the published
published
=
self
.
store
.
get_item
(
item
.
location
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
published_only
)
if
item
.
get_explicitly_set_fields_by_scope
()
!=
published
.
get_explicitly_set_fields_by_scope
():
# checking content: if published differs from item, return draft
return
supposed_state
if
item
.
get_explicitly_set_fields_by_scope
(
Scope
.
settings
)
!=
published
.
get_explicitly_set_fields_by_scope
(
Scope
.
settings
):
# checking settings: if published differs from item, return draft
return
supposed_state
if
item
.
has_children
and
item
.
children
!=
published
.
children
:
# checking children: if published differs from item, return draft
return
supposed_state
# published == item in all respects, so return public
return
PublishState
.
public
elif
supposed_state
==
PublishState
.
public
and
item
.
location
.
category
in
mongo
.
base
.
DIRECT_ONLY_CATEGORIES
:
if
not
all
([
...
...
common/lib/xmodule/xmodule/course_module.py
View file @
6be33844
...
...
@@ -556,10 +556,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
_
=
self
.
runtime
.
service
(
self
,
"i18n"
)
.
ugettext
if
self
.
wiki_slug
is
None
:
if
isinstance
(
self
.
location
,
UsageKey
):
self
.
wiki_slug
=
self
.
location
.
course
elif
isinstance
(
self
.
location
,
CourseLocator
):
self
.
wiki_slug
=
self
.
id
.
offering
or
self
.
display_name
self
.
wiki_slug
=
self
.
location
.
course
if
self
.
due_date_display_format
is
None
and
self
.
show_timezone
is
False
:
# For existing courses with show_timezone set to False (and no due_date_display_format specified),
...
...
common/lib/xmodule/xmodule/modulestore/__init__.py
View file @
6be33844
...
...
@@ -287,6 +287,15 @@ class ModuleStoreRead(object):
pass
@abstractmethod
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 keys
"""
pass
@abstractmethod
def
compute_publish_state
(
self
,
xblock
):
"""
Returns whether this xblock is draft, public, or private.
...
...
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
6be33844
...
...
@@ -414,7 +414,7 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
"""
Return the list of courses which use this wiki_slug
:param wiki_slug: the course wiki root slug
:return: list of course
location
s
:return: list of course
key
s
"""
courses
=
[]
for
modulestore
in
self
.
modulestores
:
...
...
common/lib/xmodule/xmodule/modulestore/mongo/base.py
View file @
6be33844
...
...
@@ -60,6 +60,10 @@ BLOCK_TYPES_WITH_CHILDREN = list(set(
name
for
name
,
class_
in
XBlock
.
load_classes
()
if
getattr
(
class_
,
'has_children'
,
False
)
))
# Allow us to call _from_deprecated_(son|string) throughout the file
# pylint: disable=protected-access
class
MongoRevisionKey
(
object
):
"""
Key Revision constants to use for Location and Usage Keys in the Mongo modulestore
...
...
@@ -1252,11 +1256,17 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
"""
Return the list of courses which use this wiki_slug
:param wiki_slug: the course wiki root slug
:return: list of course
location
s
:return: list of course
key
s
"""
courses
=
self
.
collection
.
find
({
'_id.category'
:
'course'
,
'definition.data.wiki_slug'
:
wiki_slug
})
courses
=
self
.
collection
.
find
(
{
'_id.category'
:
'course'
,
'definition.data.wiki_slug'
:
wiki_slug
},
{
'_id'
:
True
}
)
# the course's run == its name. It's the only xblock for which that's necessarily true.
return
[
Location
.
_from_deprecated_son
(
course
[
'_id'
],
course
[
'_id'
][
'name'
])
for
course
in
courses
]
return
[
Location
.
_from_deprecated_son
(
course
[
'_id'
],
course
[
'_id'
][
'name'
])
.
course_key
for
course
in
courses
]
def
_create_new_field_data
(
self
,
_category
,
_location
,
definition_data
,
metadata
):
"""
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
6be33844
...
...
@@ -10,6 +10,8 @@ Representation:
** 'edited_by': user_id of user who created the original entry,
** 'edited_on': the datetime of the original creation,
** 'versions': versions_dict: {branch_id: structure_id, ...}
** 'search_targets': a dict of search key and value. For example, wiki_slug. Add any fields whose edits
should change the search targets to SplitMongoModuleStore.SEARCH_TARGET dict
* structure:
** '_id': an ObjectId (guid),
** 'root': root_block_id (string of key in 'blocks' for the root of this structure,
...
...
@@ -106,6 +108,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
SCHEMA_VERSION
=
1
reference_type
=
Locator
# a list of field names to store in course index search_targets. Note, this will
# only record one value per key. If branches disagree, the last one set wins.
# It won't recompute the value on operations such as update_course_index (e.g., to revert to a prev
# version) but those functions will have an optional arg for setting these.
SEARCH_TARGET_DICT
=
[
'wiki_slug'
]
def
__init__
(
self
,
contentstore
,
doc_store_config
,
fs_root
,
render_template
,
default_class
=
None
,
...
...
@@ -871,6 +878,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# update the index entry if appropriate
if
index_entry
is
not
None
:
# see if any search targets changed
if
fields
is
not
None
:
self
.
_update_search_targets
(
index_entry
,
fields
)
if
not
continue_version
:
self
.
_update_head
(
index_entry
,
course_key
.
branch
,
new_id
)
item_loc
=
BlockUsageLocator
(
...
...
@@ -945,12 +955,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
source_index
=
self
.
get_course_index_info
(
source_course_id
)
return
self
.
create_course
(
dest_course_id
.
org
,
dest_course_id
.
course
,
dest_course_id
.
run
,
user_id
,
fields
=
None
,
# override start_date?
versions_dict
=
source_index
[
'versions'
]
versions_dict
=
source_index
[
'versions'
]
,
search_targets
=
source_index
[
'search_targets'
]
)
def
create_course
(
self
,
org
,
course
,
run
,
user_id
,
master_branch
=
None
,
fields
=
None
,
versions_dict
=
None
,
root_category
=
'course'
,
versions_dict
=
None
,
search_targets
=
None
,
root_category
=
'course'
,
root_block_id
=
'course'
,
**
kwargs
):
"""
...
...
@@ -987,6 +997,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
master_branch: the tag (key) for the version name in the dict which is the DRAFT version. Not the actual
version guid, but what to call it.
search_targets: a dict of search key and value. For example, wiki_slug. Add any fields whose edits
should change the search targets to SplitMongoModuleStore.SEARCH_TARGET dict
versions_dict: the starting version ids where the keys are the tags such as DRAFT and PUBLISHED
and the values are structure guids. If provided, the new course will reuse this version (unless you also
provide any fields overrides, see above). if not provided, will create a mostly empty course
...
...
@@ -1073,9 +1086,14 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
'edited_on'
:
datetime
.
datetime
.
now
(
UTC
),
'versions'
:
versions_dict
,
'schema_version'
:
self
.
SCHEMA_VERSION
,
'search_targets'
:
search_targets
or
{},
}
if
fields
is
not
None
:
self
.
_update_search_targets
(
index_entry
,
fields
)
self
.
db_connection
.
insert_course_index
(
index_entry
)
return
self
.
get_course
(
locator
)
# expensive hack to persist default field values set in __init__ method (e.g., wiki_slug)
course
=
self
.
get_course
(
locator
)
return
self
.
update_item
(
course
,
user_id
)
def
update_item
(
self
,
descriptor
,
user_id
,
allow_not_found
=
False
,
force
=
False
):
"""
...
...
@@ -1095,8 +1113,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
original_structure
=
self
.
_lookup_course
(
descriptor
.
location
)[
'structure'
]
index_entry
=
self
.
_get_index_if_valid
(
descriptor
.
location
,
force
)
definition_fields
=
descriptor
.
get_explicitly_set_fields_by_scope
(
Scope
.
content
)
descriptor
.
definition_locator
,
is_updated
=
self
.
update_definition_from_data
(
descriptor
.
definition_locator
,
descriptor
.
get_explicitly_set_fields_by_scope
(
Scope
.
content
),
user_id
)
descriptor
.
definition_locator
,
definition_fields
,
user_id
)
original_entry
=
self
.
_get_block_from_structure
(
original_structure
,
descriptor
.
location
.
block_id
)
# check metadata
...
...
@@ -1130,6 +1150,8 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
self
.
db_connection
.
insert_structure
(
new_structure
)
# update the index entry if appropriate
if
index_entry
is
not
None
:
self
.
_update_search_targets
(
index_entry
,
definition_fields
)
self
.
_update_search_targets
(
index_entry
,
settings
)
self
.
_update_head
(
index_entry
,
descriptor
.
location
.
branch
,
new_id
)
course_key
=
CourseLocator
(
org
=
index_entry
[
'org'
],
...
...
@@ -1657,6 +1679,17 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return
True
return
False
def
_update_search_targets
(
self
,
index_entry
,
fields
):
"""
Update the index entry if any of the given fields are in SEARCH_TARGET_DICT. (doesn't save
the changes, just changes them in the entry dict)
:param index_entry:
:param fields: a dictionary of fields and values usually only those explicitly set and already
ready for persisting (e.g., references converted to block_ids)
"""
for
field_name
,
field_value
in
fields
.
iteritems
():
if
field_name
in
self
.
SEARCH_TARGET_DICT
:
index_entry
.
setdefault
(
'search_targets'
,
{})[
field_name
]
=
field_value
def
_update_head
(
self
,
index_entry
,
branch
,
new_id
):
"""
...
...
@@ -1853,16 +1886,27 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
"""
structure
[
'blocks'
][
encode_key_for_mongo
(
block_id
)]
=
content
def
find_courses_by_search_target
(
self
,
field_name
,
field_value
):
"""
Find all the courses which cached that they have the given field with the given value.
Returns: list of branch-agnostic course_keys
"""
entries
=
self
.
db_connection
.
find_matching_course_indexes
(
{
'search_targets.{}'
.
format
(
field_name
):
field_value
}
)
return
[
CourseLocator
(
entry
[
'org'
],
entry
[
'course'
],
entry
[
'run'
])
# Branch agnostic
for
entry
in
entries
]
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.
:return: list of course keys
"""
courses
=
[]
return
courses
return
self
.
find_courses_by_search_target
(
'wiki_slug'
,
wiki_slug
)
def
heartbeat
(
self
):
"""
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
6be33844
...
...
@@ -641,19 +641,28 @@ class TestMixedModuleStore(unittest.TestCase):
orphans
=
self
.
store
.
get_orphans
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
)
self
.
assertEqual
(
len
(
orphans
),
0
,
"unexpected orphans: {}"
.
format
(
orphans
))
@ddt.data
(
'draft'
)
@ddt.data
(
'draft'
,
'split'
)
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
(
self
.
course_locations
[
self
.
XML_COURSEID1
],
course_locations
)
course_locations
=
self
.
store
.
get_courses_for_wiki
(
'simple'
)
self
.
assertEqual
(
len
(
course_locations
),
1
)
self
.
assertIn
(
self
.
course_locations
[
self
.
XML_COURSEID2
],
course_locations
)
# Test XML wikis
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'toy'
)
self
.
assertEqual
(
len
(
wiki_courses
),
1
)
self
.
assertIn
(
self
.
course_locations
[
self
.
XML_COURSEID1
]
.
course_key
,
wiki_courses
)
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'simple'
)
self
.
assertEqual
(
len
(
wiki_courses
),
1
)
self
.
assertIn
(
self
.
course_locations
[
self
.
XML_COURSEID2
]
.
course_key
,
wiki_courses
)
# Test Mongo wiki
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'999'
)
self
.
assertEqual
(
len
(
wiki_courses
),
1
)
self
.
assertIn
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
.
replace
(
branch
=
None
),
# Branch agnostic
wiki_courses
)
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
)
...
...
@@ -738,6 +747,61 @@ class TestMixedModuleStore(unittest.TestCase):
self
.
assertTrue
(
self
.
store
.
has_changes
(
item
.
location
))
self
.
assertEquals
(
self
.
store
.
compute_publish_state
(
item
),
PublishState
.
draft
)
@ddt.data
(
'draft'
,
'split'
)
def
test_get_courses_for_wiki_shared
(
self
,
default_ms
):
"""
Test two courses sharing the same wiki
"""
self
.
initdb
(
default_ms
)
# verify initial state - initially, we should have a wiki for the Mongo course
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'999'
)
self
.
assertIn
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
.
replace
(
branch
=
None
),
# Branch agnostic
wiki_courses
)
# set Mongo course to share the wiki with simple course
mongo_course
=
self
.
store
.
get_course
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
)
mongo_course
.
wiki_slug
=
'simple'
self
.
store
.
update_item
(
mongo_course
,
self
.
user_id
)
# now mongo_course should not be retrievable with old wiki_slug
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'999'
)
self
.
assertEqual
(
len
(
wiki_courses
),
0
)
# but there should be two courses with wiki_slug 'simple'
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'simple'
)
self
.
assertEqual
(
len
(
wiki_courses
),
2
)
self
.
assertIn
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
.
replace
(
branch
=
None
),
wiki_courses
)
self
.
assertIn
(
self
.
course_locations
[
self
.
XML_COURSEID2
]
.
course_key
,
wiki_courses
)
# configure mongo course to use unique wiki_slug.
mongo_course
=
self
.
store
.
get_course
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
)
mongo_course
.
wiki_slug
=
'MITx.999.2013_Spring'
self
.
store
.
update_item
(
mongo_course
,
self
.
user_id
)
# it should be retrievable with its new wiki_slug
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'MITx.999.2013_Spring'
)
self
.
assertEqual
(
len
(
wiki_courses
),
1
)
self
.
assertIn
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
.
replace
(
branch
=
None
),
wiki_courses
)
# and NOT retriveable with its old wiki_slug
wiki_courses
=
self
.
store
.
get_courses_for_wiki
(
'simple'
)
self
.
assertEqual
(
len
(
wiki_courses
),
1
)
self
.
assertNotIn
(
self
.
course_locations
[
self
.
MONGO_COURSEID
]
.
course_key
.
replace
(
branch
=
None
),
wiki_courses
)
self
.
assertIn
(
self
.
course_locations
[
self
.
XML_COURSEID2
]
.
course_key
,
wiki_courses
)
#=============================================================================================================
# General utils for not using django settings
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
View file @
6be33844
...
...
@@ -351,7 +351,7 @@ class TestMongoModuleStore(unittest.TestCase):
for
course_number
in
self
.
courses
:
course_locations
=
self
.
draft_store
.
get_courses_for_wiki
(
course_number
)
assert_equals
(
len
(
course_locations
),
1
)
assert_equals
(
Location
(
'edX'
,
course_number
,
'2012_Fall'
,
'course'
,
'2012_Fall'
),
course_locations
[
0
])
assert_equals
(
SlashSeparatedCourseKey
(
'edX'
,
course_number
,
'2012_Fall'
),
course_locations
[
0
])
course_locations
=
self
.
draft_store
.
get_courses_for_wiki
(
'no_such_wiki'
)
assert_equals
(
len
(
course_locations
),
0
)
...
...
@@ -369,7 +369,7 @@ class TestMongoModuleStore(unittest.TestCase):
course_locations
=
self
.
draft_store
.
get_courses_for_wiki
(
'simple'
)
assert_equals
(
len
(
course_locations
),
2
)
for
course_number
in
[
'toy'
,
'simple'
]:
assert_in
(
Location
(
'edX'
,
course_number
,
'2012_Fall'
,
'course'
,
'2012_Fall'
),
course_locations
)
assert_in
(
SlashSeparatedCourseKey
(
'edX'
,
course_number
,
'2012_Fall'
),
course_locations
)
# configure simple course to use unique wiki_slug.
simple_course
=
self
.
draft_store
.
get_course
(
SlashSeparatedCourseKey
(
'edX'
,
'simple'
,
'2012_Fall'
))
...
...
@@ -378,7 +378,7 @@ class TestMongoModuleStore(unittest.TestCase):
# it should be retrievable with its new wiki_slug
course_locations
=
self
.
draft_store
.
get_courses_for_wiki
(
'edX.simple.2012_Fall'
)
assert_equals
(
len
(
course_locations
),
1
)
assert_in
(
Location
(
'edX'
,
'simple'
,
'2012_Fall'
,
'cours
e'
,
'2012_Fall'
),
course_locations
)
assert_in
(
SlashSeparatedCourseKey
(
'edX'
,
'simpl
e'
,
'2012_Fall'
),
course_locations
)
@Plugin.register_temp_plugin
(
ReferenceTestXBlock
,
'ref_test'
)
def
test_reference_converters
(
self
):
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
View file @
6be33844
...
...
@@ -1395,8 +1395,12 @@ class TestCourseCreation(SplitModuleTest):
self
.
assertEqual
(
index_info
[
'edited_by'
],
'create_user'
)
# check structure info
structure_info
=
modulestore
()
.
get_course_history_info
(
new_locator
)
self
.
assertEqual
(
structure_info
[
'original_version'
],
index_info
[
'versions'
][
BRANCH_NAME_DRAFT
])
self
.
assertIsNone
(
structure_info
[
'previous_version'
])
# TODO LMS-11098 "Implement bulk_write in Split"
# Right now, these assertions will not pass because create_course calls update_item,
# resulting in two versions. Bulk updater will fix this.
# self.assertEqual(structure_info['original_version'], index_info['versions'][BRANCH_NAME_DRAFT])
# self.assertIsNone(structure_info['previous_version'])
self
.
assertEqual
(
structure_info
[
'edited_by'
],
'create_user'
)
# check the returned course object
self
.
assertIsInstance
(
new_course
,
CourseDescriptor
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_xml.py
View file @
6be33844
...
...
@@ -81,7 +81,7 @@ class TestXMLModuleStore(unittest.TestCase):
for
course
in
store
.
get_courses
():
course_locations
=
store
.
get_courses_for_wiki
(
course
.
wiki_slug
)
self
.
assertEqual
(
len
(
course_locations
),
1
)
self
.
assertIn
(
course
.
location
,
course_locations
)
self
.
assertIn
(
course
.
location
.
course_key
,
course_locations
)
course_locations
=
store
.
get_courses_for_wiki
(
'no_such_wiki'
)
self
.
assertEqual
(
len
(
course_locations
),
0
)
...
...
@@ -96,7 +96,7 @@ class TestXMLModuleStore(unittest.TestCase):
course_locations
=
store
.
get_courses_for_wiki
(
'simple'
)
self
.
assertEqual
(
len
(
course_locations
),
2
)
for
course_number
in
[
'toy'
,
'simple'
]:
self
.
assertIn
(
Location
(
'edX'
,
course_number
,
'2012_Fall'
,
'course'
,
'2012_Fall'
),
course_locations
)
self
.
assertIn
(
SlashSeparatedCourseKey
(
'edX'
,
course_number
,
'2012_Fall'
),
course_locations
)
def
test_has_course
(
self
):
"""
...
...
common/lib/xmodule/xmodule/modulestore/xml.py
View file @
6be33844
...
...
@@ -815,7 +815,7 @@ class XMLModuleStore(ModuleStoreReadBase):
:return: list of course locations
"""
courses
=
self
.
get_courses
()
return
[
course
.
location
for
course
in
courses
if
(
course
.
wiki_slug
==
wiki_slug
)]
return
[
course
.
location
.
course_key
for
course
in
courses
if
(
course
.
wiki_slug
==
wiki_slug
)]
def
heartbeat
(
self
):
"""
...
...
lms/djangoapps/course_wiki/utils.py
View file @
6be33844
...
...
@@ -27,20 +27,25 @@ def user_is_article_course_staff(user, article):
if
wiki_slug
is
None
:
return
False
modstore
=
modulestore
.
django
.
modulestore
()
return
_has_wiki_staff_access
(
user
,
wiki_slug
,
modstore
)
def
_has_wiki_staff_access
(
user
,
wiki_slug
,
modstore
):
"""Returns whether the user has staff access to the wiki represented by wiki_slug"""
course_keys
=
modstore
.
get_courses_for_wiki
(
wiki_slug
)
# The wiki expects article slugs to contain at least one non-digit so if
# the course number is just a number the course wiki root slug is set to
# be '<course_number>_'. This means slug '202_' can belong to either
# course numbered '202_' or '202' and so we need to consider both.
if
wiki_slug
.
endswith
(
'_'
)
and
slug_is_numerical
(
wiki_slug
[:
-
1
]):
course_keys
.
extend
(
modstore
.
get_courses_for_wiki
(
wiki_slug
[:
-
1
]))
courses
=
modulestore
.
django
.
modulestore
()
.
get_courses_for_wiki
(
wiki_slug
)
if
any
(
courseware
.
access
.
has_access
(
user
,
'staff'
,
course
,
course
.
course_key
)
for
course
in
courses
):
return
True
if
(
wiki_slug
.
endswith
(
'_'
)
and
slug_is_numerical
(
wiki_slug
[:
-
1
])):
courses
=
modulestore
.
django
.
modulestore
()
.
get_courses_for_wiki
(
wiki_slug
[:
-
1
])
if
any
(
courseware
.
access
.
has_access
(
user
,
'staff'
,
course
,
course
.
course_key
)
for
course
in
courses
):
for
course_key
in
course_keys
:
course
=
modstore
.
get_course
(
course_key
)
if
courseware
.
access
.
has_access
(
user
,
'staff'
,
course
,
course_key
):
return
True
return
False
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment