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
d34c6a07
Commit
d34c6a07
authored
Mar 23, 2015
by
E. Kolpakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Filtering using search index + tests
parent
2f03b976
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
94 additions
and
15 deletions
+94
-15
cms/djangoapps/contentstore/tests/test_libraries.py
+1
-0
common/lib/xmodule/xmodule/library_tools.py
+17
-5
common/lib/xmodule/xmodule/tests/test_library_content.py
+49
-7
common/test/acceptance/tests/helpers.py
+14
-0
common/test/acceptance/tests/lms/test_library.py
+13
-3
No files found.
cms/djangoapps/contentstore/tests/test_libraries.py
View file @
d34c6a07
...
@@ -386,6 +386,7 @@ class TestLibraries(LibraryTestCase):
...
@@ -386,6 +386,7 @@ class TestLibraries(LibraryTestCase):
html_block
=
modulestore
()
.
get_item
(
lc_block
.
children
[
0
])
html_block
=
modulestore
()
.
get_item
(
lc_block
.
children
[
0
])
self
.
assertEqual
(
html_block
.
data
,
data2
)
self
.
assertEqual
(
html_block
.
data
,
data2
)
@patch
(
"xmodule.library_tools.SearchEngine.get_search_engine"
,
Mock
(
return_value
=
None
))
def
test_refreshes_children_if_capa_type_change
(
self
):
def
test_refreshes_children_if_capa_type_change
(
self
):
""" Tests that children are automatically refreshed if capa type field changes """
""" Tests that children are automatically refreshed if capa type field changes """
name1
,
name2
=
"Option Problem"
,
"Multiple Choice Problem"
name1
,
name2
=
"Option Problem"
,
"Multiple Choice Problem"
...
...
common/lib/xmodule/xmodule/library_tools.py
View file @
d34c6a07
...
@@ -2,7 +2,8 @@
...
@@ -2,7 +2,8 @@
XBlock runtime services for LibraryContentModule
XBlock runtime services for LibraryContentModule
"""
"""
from
django.core.exceptions
import
PermissionDenied
from
django.core.exceptions
import
PermissionDenied
from
opaque_keys.edx.locator
import
LibraryLocator
from
opaque_keys.edx.locator
import
LibraryLocator
,
LibraryUsageLocator
from
search.search_engine_base
import
SearchEngine
from
xmodule.library_content_module
import
ANY_CAPA_TYPE_VALUE
from
xmodule.library_content_module
import
ANY_CAPA_TYPE_VALUE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
...
@@ -86,13 +87,24 @@ class LibraryToolsService(object):
...
@@ -86,13 +87,24 @@ class LibraryToolsService(object):
result_json
.
append
(
info
)
result_json
.
append
(
info
)
return
result_json
return
result_json
def
_problem_type_filter
(
self
,
library
,
capa_type
):
""" Filters library children by capa type"""
search_engine
=
SearchEngine
.
get_search_engine
(
index
=
"library_index"
)
if
search_engine
:
filter_clause
=
{
"content_type"
:
CapaDescriptor
.
INDEX_CONTENT_TYPE
,
"problem_types"
:
capa_type
}
search_result
=
search_engine
.
search
(
field_dictionary
=
filter_clause
)
results
=
search_result
.
get
(
'results'
,
[])
return
[
LibraryUsageLocator
.
from_string
(
item
[
'data'
][
'id'
])
for
item
in
results
]
else
:
return
[
key
for
key
in
library
.
children
if
self
.
_filter_child
(
key
,
capa_type
)]
def
_filter_child
(
self
,
usage_key
,
capa_type
):
def
_filter_child
(
self
,
usage_key
,
capa_type
):
"""
"""
Filters children by CAPA problem type, if configured
Filters children by CAPA problem type, if configured
"""
"""
if
capa_type
==
ANY_CAPA_TYPE_VALUE
:
return
True
if
usage_key
.
block_type
!=
"problem"
:
if
usage_key
.
block_type
!=
"problem"
:
return
False
return
False
...
@@ -137,7 +149,7 @@ class LibraryToolsService(object):
...
@@ -137,7 +149,7 @@ class LibraryToolsService(object):
filter_children
=
(
dest_block
.
capa_type
!=
ANY_CAPA_TYPE_VALUE
)
filter_children
=
(
dest_block
.
capa_type
!=
ANY_CAPA_TYPE_VALUE
)
if
filter_children
:
if
filter_children
:
# Apply simple filtering based on CAPA problem types:
# Apply simple filtering based on CAPA problem types:
source_blocks
.
extend
(
[
key
for
key
in
library
.
children
if
self
.
_filter_child
(
key
,
dest_block
.
capa_type
)]
)
source_blocks
.
extend
(
self
.
_problem_type_filter
(
library
,
dest_block
.
capa_type
)
)
else
:
else
:
source_blocks
.
extend
(
library
.
children
)
source_blocks
.
extend
(
library
.
children
)
...
...
common/lib/xmodule/xmodule/tests/test_library_content.py
View file @
d34c6a07
...
@@ -18,6 +18,7 @@ from xmodule.modulestore.tests.utils import MixedSplitTestCase
...
@@ -18,6 +18,7 @@ from xmodule.modulestore.tests.utils import MixedSplitTestCase
from
xmodule.tests
import
get_test_system
from
xmodule.tests
import
get_test_system
from
xmodule.validation
import
StudioValidationMessage
from
xmodule.validation
import
StudioValidationMessage
from
xmodule.x_module
import
AUTHOR_VIEW
from
xmodule.x_module
import
AUTHOR_VIEW
from
search.search_engine_base
import
SearchEngine
dummy_render
=
lambda
block
,
_
:
Fragment
(
block
.
data
)
# pylint: disable=invalid-name
dummy_render
=
lambda
block
,
_
:
Fragment
(
block
.
data
)
# pylint: disable=invalid-name
...
@@ -66,10 +67,17 @@ class LibraryContentTest(MixedSplitTestCase):
...
@@ -66,10 +67,17 @@ class LibraryContentTest(MixedSplitTestCase):
module
.
xmodule_runtime
=
module_system
module
.
xmodule_runtime
=
module_system
class
TestLibraryContentModule
(
LibraryContentTes
t
):
class
LibraryContentModuleTestMixin
(
objec
t
):
"""
"""
Basic unit tests for LibraryContentModule
Basic unit tests for LibraryContentModule
"""
"""
problem_types
=
[
[
"multiplechoiceresponse"
],
[
"optionresponse"
],
[
"optionresponse"
,
"coderesponse"
],
[
"coderesponse"
,
"optionresponse"
]
]
problem_type_lookup
=
{}
def
_get_capa_problem_type_xml
(
self
,
*
args
):
def
_get_capa_problem_type_xml
(
self
,
*
args
):
""" Helper function to create empty CAPA problem definition """
""" Helper function to create empty CAPA problem definition """
problem
=
"<problem>"
problem
=
"<problem>"
...
@@ -84,12 +92,10 @@ class TestLibraryContentModule(LibraryContentTest):
...
@@ -84,12 +92,10 @@ class TestLibraryContentModule(LibraryContentTest):
Creates four blocks total.
Creates four blocks total.
"""
"""
problem_types
=
[
self
.
problem_type_lookup
=
{}
[
"multiplechoiceresponse"
],
[
"optionresponse"
],
[
"optionresponse"
,
"coderesponse"
],
for
problem_type
in
self
.
problem_types
:
[
"coderesponse"
,
"optionresponse"
]
block
=
self
.
make_block
(
"problem"
,
self
.
library
,
data
=
self
.
_get_capa_problem_type_xml
(
*
problem_type
))
]
self
.
problem_type_lookup
[
block
.
location
]
=
problem_type
for
problem_type
in
problem_types
:
self
.
make_block
(
"problem"
,
self
.
library
,
data
=
self
.
_get_capa_problem_type_xml
(
*
problem_type
))
def
test_lib_content_block
(
self
):
def
test_lib_content_block
(
self
):
"""
"""
...
@@ -236,6 +242,42 @@ class TestLibraryContentModule(LibraryContentTest):
...
@@ -236,6 +242,42 @@ class TestLibraryContentModule(LibraryContentTest):
self
.
assertNotIn
(
LibraryContentDescriptor
.
display_name
,
non_editable_metadata_fields
)
self
.
assertNotIn
(
LibraryContentDescriptor
.
display_name
,
non_editable_metadata_fields
)
@patch
(
'xmodule.library_tools.SearchEngine.get_search_engine'
,
Mock
(
return_value
=
None
))
class
TestLibraryContentModuleNoSearchIndex
(
LibraryContentModuleTestMixin
,
LibraryContentTest
):
"""
Tests for library container when no search index is available.
Tests fallback low-level CAPA problem introspection
"""
pass
search_index_mock
=
Mock
(
spec
=
SearchEngine
)
# pylint: disable=invalid-name
@patch
(
'xmodule.library_tools.SearchEngine.get_search_engine'
,
Mock
(
return_value
=
search_index_mock
))
class
TestLibraryContentModuleWithSearchIndex
(
LibraryContentModuleTestMixin
,
LibraryContentTest
):
"""
Tests for library container with mocked search engine response.
"""
def
_get_search_response
(
self
,
field_dictionary
=
None
):
""" Mocks search response as returned by search engine """
target_type
=
field_dictionary
.
get
(
'problem_types'
)
matched_block_locations
=
[
key
for
key
,
problem_types
in
self
.
problem_type_lookup
.
items
()
if
target_type
in
problem_types
]
return
{
'results'
:
[
{
'data'
:
{
'id'
:
str
(
location
)}}
for
location
in
matched_block_locations
]
}
def
setUp
(
self
):
""" Sets up search engine mock """
super
(
TestLibraryContentModuleWithSearchIndex
,
self
)
.
setUp
()
search_index_mock
.
search
=
Mock
(
side_effect
=
self
.
_get_search_response
)
@patch
(
@patch
(
'xmodule.modulestore.split_mongo.caching_descriptor_system.CachingDescriptorSystem.render'
,
VanillaRuntime
.
render
'xmodule.modulestore.split_mongo.caching_descriptor_system.CachingDescriptorSystem.render'
,
VanillaRuntime
.
render
)
)
...
...
common/test/acceptance/tests/helpers.py
View file @
d34c6a07
...
@@ -417,3 +417,17 @@ def create_user_partition_json(partition_id, name, description, groups, scheme="
...
@@ -417,3 +417,17 @@ def create_user_partition_json(partition_id, name, description, groups, scheme="
return
UserPartition
(
return
UserPartition
(
partition_id
,
name
,
description
,
groups
,
MockUserPartitionScheme
(
scheme
)
partition_id
,
name
,
description
,
groups
,
MockUserPartitionScheme
(
scheme
)
)
.
to_json
()
)
.
to_json
()
class
TestWithSearchIndexMixin
(
object
):
""" Mixin encapsulating search index creation """
TEST_INDEX_FILENAME
=
"test_root/index_file.dat"
def
_create_search_index
(
self
):
""" Creates search index backing file """
with
open
(
self
.
TEST_INDEX_FILENAME
,
"w+"
)
as
index_file
:
json
.
dump
({},
index_file
)
def
_cleanup_index_file
(
self
):
""" Removes search index backing file """
os
.
remove
(
self
.
TEST_INDEX_FILENAME
)
common/test/acceptance/tests/lms/test_library.py
View file @
d34c6a07
...
@@ -6,7 +6,7 @@ import ddt
...
@@ -6,7 +6,7 @@ import ddt
import
textwrap
import
textwrap
from
nose.plugins.attrib
import
attr
from
nose.plugins.attrib
import
attr
from
..helpers
import
UniqueCourseTest
from
..helpers
import
UniqueCourseTest
,
TestWithSearchIndexMixin
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.studio.overview
import
CourseOutlinePage
from
...pages.studio.overview
import
CourseOutlinePage
from
...pages.studio.library
import
StudioLibraryContentEditor
,
StudioLibraryContainerXBlockWrapper
from
...pages.studio.library
import
StudioLibraryContentEditor
,
StudioLibraryContainerXBlockWrapper
...
@@ -196,10 +196,19 @@ class LibraryContentTest(LibraryContentTestBase):
...
@@ -196,10 +196,19 @@ class LibraryContentTest(LibraryContentTestBase):
@ddt.ddt
@ddt.ddt
@attr
(
'shard_3'
)
@attr
(
'shard_3'
)
class
StudioLibraryContainerCapaFilterTest
(
LibraryContentTestBase
):
class
StudioLibraryContainerCapaFilterTest
(
LibraryContentTestBase
,
TestWithSearchIndexMixin
):
"""
"""
Test Library Content block in LMS
Test Library Content block in LMS
"""
"""
def
setUp
(
self
):
""" SetUp method """
self
.
_create_search_index
()
super
(
StudioLibraryContainerCapaFilterTest
,
self
)
.
setUp
()
def
tearDown
(
self
):
self
.
_cleanup_index_file
()
super
(
StudioLibraryContainerCapaFilterTest
,
self
)
.
tearDown
()
def
_get_problem_choice_group_text
(
self
,
name
,
items
):
def
_get_problem_choice_group_text
(
self
,
name
,
items
):
""" Generates Choice Group CAPA problem XML """
""" Generates Choice Group CAPA problem XML """
items_text
=
"
\n
"
.
join
([
items_text
=
"
\n
"
.
join
([
...
@@ -231,7 +240,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
...
@@ -231,7 +240,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
"""
"""
Populates library fixture with XBlock Fixtures
Populates library fixture with XBlock Fixtures
"""
"""
library_fixture
.
add_children
(
items
=
(
XBlockFixtureDesc
(
XBlockFixtureDesc
(
"problem"
,
"Problem Choice Group 1"
,
"problem"
,
"Problem Choice Group 1"
,
data
=
self
.
_get_problem_choice_group_text
(
"Problem Choice Group 1 Text"
,
[(
"1"
,
False
),
(
'2'
,
True
)])
data
=
self
.
_get_problem_choice_group_text
(
"Problem Choice Group 1 Text"
,
[(
"1"
,
False
),
(
'2'
,
True
)])
...
@@ -249,6 +258,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
...
@@ -249,6 +258,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
data
=
self
.
_get_problem_select_text
(
"Problem Select 2 Text"
,
[
"Option 3"
,
"Option 4"
],
"Option 4"
)
data
=
self
.
_get_problem_select_text
(
"Problem Select 2 Text"
,
[
"Option 3"
,
"Option 4"
],
"Option 4"
)
),
),
)
)
library_fixture
.
add_children
(
*
items
)
@property
@property
def
_problem_headers
(
self
):
def
_problem_headers
(
self
):
...
...
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