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
47b3eae7
Commit
47b3eae7
authored
Jan 23, 2015
by
swdanielli
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6470 from edx/danielli/recommender_code_review
code review
parents
78375b79
ed8fea79
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
184 additions
and
182 deletions
+184
-182
lms/djangoapps/courseware/tests/test_recommender.py
+183
-181
requirements/edx/github.txt
+1
-1
No files found.
lms/djangoapps/courseware/tests/test_recommender.py
View file @
47b3eae7
...
...
@@ -161,20 +161,30 @@ class TestRecommender(ModuleStoreTestCase, LoginEnrollmentTestCase):
if
xblock_name
is
None
:
xblock_name
=
TestRecommender
.
XBLOCK_NAMES
[
0
]
url
=
self
.
get_handler_url
(
handler
,
xblock_name
)
resp
=
self
.
client
.
post
(
url
,
json
.
dumps
(
resource
),
''
)
return
json
.
loads
(
resp
.
content
)
return
self
.
client
.
post
(
url
,
json
.
dumps
(
resource
),
''
)
def
check_event_response_by_
element
(
self
,
handler
,
resource
,
resp_key
,
resp_val
,
xblock_name
=
None
):
def
check_event_response_by_
key
(
self
,
handler
,
resource
,
resp_key
,
resp_val
,
xblock_name
=
None
):
"""
Call the event specified by the handler with the resource, and check
whether the
element
(resp_key) in response is as expected (resp_val)
whether the
key
(resp_key) in response is as expected (resp_val)
"""
if
xblock_name
is
None
:
xblock_name
=
TestRecommender
.
XBLOCK_NAMES
[
0
]
resp
=
self
.
call_event
(
handler
,
resource
,
xblock_name
)
resp
=
json
.
loads
(
self
.
call_event
(
handler
,
resource
,
xblock_name
)
.
content
)
self
.
assertEqual
(
resp
[
resp_key
],
resp_val
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
def
check_event_response_by_http_status
(
self
,
handler
,
resource
,
http_status_code
,
xblock_name
=
None
):
"""
Call the event specified by the handler with the resource, and check
whether the http_status in response is as expected
"""
if
xblock_name
is
None
:
xblock_name
=
TestRecommender
.
XBLOCK_NAMES
[
0
]
resp
=
self
.
call_event
(
handler
,
resource
,
xblock_name
)
self
.
assertEqual
(
resp
.
status_code
,
http_status_code
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
class
TestRecommenderCreateFromEmpty
(
TestRecommender
):
"""
...
...
@@ -191,7 +201,6 @@ class TestRecommenderCreateFromEmpty(TestRecommender):
result
=
self
.
call_event
(
'add_resource'
,
resource
,
xblock_name
)
expected_result
=
{
'Success'
:
True
,
'upvotes'
:
0
,
'downvotes'
:
0
,
'id'
:
resource_id
...
...
@@ -199,52 +208,9 @@ class TestRecommenderCreateFromEmpty(TestRecommender):
for
field
in
resource
:
expected_result
[
field
]
=
resource
[
field
]
self
.
assertDictEqual
(
result
,
expected_result
)
self
.
assertDictEqual
(
json
.
loads
(
result
.
content
)
,
expected_result
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
def
test_import_resources_by_student
(
self
):
"""
Test the function for importing all resources into the Recommender
by a student.
"""
self
.
enroll_student
(
self
.
STUDENTS
[
0
][
'email'
],
self
.
STUDENTS
[
0
][
'password'
])
# Preparing imported resources
initial_configuration
=
{
'flagged_accum_resources'
:
{},
'endorsed_recommendation_reasons'
:
[],
'endorsed_recommendation_ids'
:
[],
'deendorsed_recommendations'
:
{},
'recommendations'
:
self
.
test_recommendations
[
self
.
resource_urls
[
0
]]
}
# Importing resources
f_handler
=
StringIO
.
StringIO
(
json
.
dumps
(
initial_configuration
,
sort_keys
=
True
))
f_handler
.
name
=
'import_resources'
url
=
self
.
get_handler_url
(
'import_resources'
)
resp
=
self
.
client
.
post
(
url
,
{
'file'
:
f_handler
})
self
.
assertEqual
(
resp
.
content
,
'NOT_A_STAFF'
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
def
test_import_resources
(
self
):
"""
Test the function for importing all resources into the Recommender.
"""
self
.
enroll_staff
(
self
.
staff_user
)
# Preparing imported resources
initial_configuration
=
{
'flagged_accum_resources'
:
{},
'endorsed_recommendation_reasons'
:
[],
'endorsed_recommendation_ids'
:
[],
'deendorsed_recommendations'
:
{},
'recommendations'
:
self
.
test_recommendations
[
self
.
resource_urls
[
0
]]
}
# Importing resources
f_handler
=
StringIO
.
StringIO
(
json
.
dumps
(
initial_configuration
,
sort_keys
=
True
))
f_handler
.
name
=
'import_resources'
url
=
self
.
get_handler_url
(
'import_resources'
)
resp
=
self
.
client
.
post
(
url
,
{
'file'
:
f_handler
})
self
.
assertEqual
(
resp
.
content
,
json
.
dumps
(
initial_configuration
,
sort_keys
=
True
))
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
class
TestRecommenderWithResources
(
TestRecommender
):
"""
...
...
@@ -287,45 +253,27 @@ class TestRecommenderWithResources(TestRecommender):
for
suffix
in
[
''
,
'#IAmSuffix'
,
'
%23
IAmSuffix'
]:
resource
=
deepcopy
(
self
.
test_recommendations
[
self
.
resource_id
])
resource
[
'url'
]
+=
suffix
result
=
self
.
call_event
(
'add_resource'
,
resource
)
self
.
check_event_response_by_http_status
(
'add_resource'
,
resource
,
409
)
expected_result
=
{
'Success'
:
False
,
'error'
:
(
'The resource you are attempting to '
'provide has already existed'
),
'dup_id'
:
self
.
resource_id
}
for
field
in
resource
:
expected_result
[
field
]
=
resource
[
field
]
expected_result
[
'dup_'
+
field
]
=
self
.
test_recommendations
[
self
.
resource_id
][
field
]
self
.
assertDictEqual
(
result
,
expected_result
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
def
test_add_deendorsed_resource
(
self
):
def
test_add_removed_resource
(
self
):
"""
Verify the addition of a
deendors
ed resource (url) is rejected
Verify the addition of a
remov
ed resource (url) is rejected
"""
self
.
call_event
(
'deendorse_resource'
,
{
"id"
:
self
.
resource_id
,
'reason'
:
''
})
err_msg
=
'The resource you are attempting to provide has been de-endorsed by staff, because: .*'
self
.
call_event
(
'remove_resource'
,
{
"id"
:
self
.
resource_id
,
'reason'
:
''
})
for
suffix
in
[
''
,
'#IAmSuffix'
,
'
%23
IAmSuffix'
]:
resource
=
deepcopy
(
self
.
test_recommendations
[
self
.
resource_id
])
resource
[
'url'
]
+=
suffix
resp
=
self
.
call_event
(
'add_resource'
,
resource
)
self
.
assertRegexpMatches
(
resp
[
'error'
],
err_msg
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
check_event_response_by_http_status
(
'add_resource'
,
resource
,
405
)
def
test_edit_resource_non_existing
(
self
):
"""
Edit a non-existing resource
"""
resp
=
self
.
call_event
(
'edit_resource'
,
self
.
generate_edit_resource
(
self
.
non_existing_resource_id
)
self
.
check_event_response_by_http_status
(
'edit_resource'
,
self
.
generate_edit_resource
(
self
.
non_existing_resource_id
),
400
)
self
.
assertEqual
(
resp
[
'error'
],
'The selected resource is not existing'
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
def
test_edit_redundant_resource
(
self
):
"""
...
...
@@ -335,35 +283,28 @@ class TestRecommenderWithResources(TestRecommender):
for
suffix
in
[
''
,
'#IAmSuffix'
,
'
%23
IAmSuffix'
]:
resource
=
self
.
generate_edit_resource
(
self
.
resource_id
)
resource
[
'url'
]
=
self
.
resource_id_second
+
suffix
resp
=
self
.
call_event
(
'edit_resource'
,
resource
)
self
.
assertEqual
(
resp
[
'error'
],
'The resource you are attempting to provide has already existed'
)
self
.
assertEqual
(
resp
[
'dup_id'
],
self
.
resource_id_second
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
check_event_response_by_http_status
(
'edit_resource'
,
resource
,
409
)
def
test_edit_
deendors
ed_resource
(
self
):
def
test_edit_
remov
ed_resource
(
self
):
"""
Check whether changing the url to the one of a
deendors
ed resource is
Check whether changing the url to the one of a
remov
ed resource is
rejected
"""
self
.
call_event
(
'deendorse_resource'
,
{
"id"
:
self
.
resource_id_second
,
'reason'
:
''
})
err_msg
=
'The resource you are attempting to provide has been de-endorsed by staff, because: .*'
self
.
call_event
(
'remove_resource'
,
{
"id"
:
self
.
resource_id_second
,
'reason'
:
''
})
for
suffix
in
[
''
,
'#IAmSuffix'
,
'
%23
IAmSuffix'
]:
resource
=
self
.
generate_edit_resource
(
self
.
resource_id
)
resource
[
'url'
]
=
self
.
resource_id_second
+
suffix
resp
=
self
.
call_event
(
'edit_resource'
,
resource
)
self
.
assertRegexpMatches
(
resp
[
'error'
],
err_msg
)
self
.
assertEqual
(
resp
[
'dup_id'
],
self
.
resource_id_second
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
check_event_response_by_http_status
(
'edit_resource'
,
resource
,
405
)
def
test_edit_resource
(
self
):
"""
Check whether changing the content of resource is successful
"""
resp
=
self
.
call_event
(
'edit_resource'
,
self
.
generate_edit_resource
(
self
.
resource_id
)
self
.
check_event_response_by_http_status
(
'edit_resource'
,
self
.
generate_edit_resource
(
self
.
resource_id
),
200
)
self
.
assertEqual
(
resp
[
'Success'
],
True
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
def
test_edit_resource_same_url
(
self
):
"""
...
...
@@ -372,9 +313,7 @@ class TestRecommenderWithResources(TestRecommender):
resource
=
self
.
generate_edit_resource
(
self
.
resource_id
)
for
suffix
in
[
''
,
'#IAmSuffix'
,
'
%23
IAmSuffix'
]:
resource
[
'url'
]
=
self
.
resource_id
+
suffix
resp
=
self
.
call_event
(
'edit_resource'
,
resource
)
self
.
assertEqual
(
resp
[
'Success'
],
True
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
check_event_response_by_http_status
(
'edit_resource'
,
resource
,
200
)
def
test_edit_then_add_resource
(
self
):
"""
...
...
@@ -382,9 +321,12 @@ class TestRecommenderWithResources(TestRecommender):
"""
self
.
call_event
(
'edit_resource'
,
self
.
generate_edit_resource
(
self
.
resource_id
))
# Test
resp
=
self
.
call_event
(
'add_resource'
,
self
.
test_recommendations
[
self
.
resource_id
])
self
.
assertEqual
(
resp
[
'id'
],
self
.
resource_id
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
check_event_response_by_key
(
'add_resource'
,
self
.
test_recommendations
[
self
.
resource_id
],
'id'
,
self
.
resource_id
)
def
test_edit_resources_in_different_xblocks
(
self
):
"""
...
...
@@ -393,9 +335,7 @@ class TestRecommenderWithResources(TestRecommender):
"""
resource
=
self
.
generate_edit_resource
(
self
.
resource_id
)
for
xblock_name
in
self
.
XBLOCK_NAMES
:
resp
=
self
.
call_event
(
'edit_resource'
,
resource
,
xblock_name
)
self
.
assertEqual
(
resp
[
'Success'
],
True
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
check_event_response_by_http_status
(
'edit_resource'
,
resource
,
200
,
xblock_name
)
def
test_flag_resource_wo_reason
(
self
):
"""
...
...
@@ -403,7 +343,7 @@ class TestRecommenderWithResources(TestRecommender):
"""
resource
=
{
'id'
:
self
.
resource_id
,
'isProblematic'
:
True
,
'reason'
:
''
}
# Test
self
.
check_event_response_by_
element
(
'flag_resource'
,
resource
,
'reason'
,
''
)
self
.
check_event_response_by_
key
(
'flag_resource'
,
resource
,
'reason'
,
''
)
def
test_flag_resource_w_reason
(
self
):
"""
...
...
@@ -411,7 +351,7 @@ class TestRecommenderWithResources(TestRecommender):
"""
resource
=
{
'id'
:
self
.
resource_id
,
'isProblematic'
:
True
,
'reason'
:
'reason 0'
}
# Test
self
.
check_event_response_by_
element
(
'flag_resource'
,
resource
,
'reason'
,
'reason 0'
)
self
.
check_event_response_by_
key
(
'flag_resource'
,
resource
,
'reason'
,
'reason 0'
)
def
test_flag_resource_change_reason
(
self
):
"""
...
...
@@ -421,7 +361,7 @@ class TestRecommenderWithResources(TestRecommender):
self
.
call_event
(
'flag_resource'
,
resource
)
# Test
resource
[
'reason'
]
=
'reason 1'
resp
=
self
.
call_event
(
'flag_resource'
,
resource
)
resp
=
json
.
loads
(
self
.
call_event
(
'flag_resource'
,
resource
)
.
content
)
self
.
assertEqual
(
resp
[
'oldReason'
],
'reason 0'
)
self
.
assertEqual
(
resp
[
'reason'
],
'reason 1'
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
...
...
@@ -433,7 +373,7 @@ class TestRecommenderWithResources(TestRecommender):
resource
=
{
'id'
:
self
.
resource_id
,
'isProblematic'
:
True
,
'reason'
:
'reason 0'
}
# Test
for
xblock_name
in
self
.
XBLOCK_NAMES
:
self
.
check_event_response_by_
element
(
'flag_resource'
,
resource
,
'reason'
,
'reason 0'
,
xblock_name
)
self
.
check_event_response_by_
key
(
'flag_resource'
,
resource
,
'reason'
,
'reason 0'
,
xblock_name
)
def
test_flag_resources_by_different_users
(
self
):
"""
...
...
@@ -444,7 +384,7 @@ class TestRecommenderWithResources(TestRecommender):
self
.
logout
()
self
.
enroll_student
(
self
.
STUDENTS
[
0
][
'email'
],
self
.
STUDENTS
[
0
][
'password'
])
# Test
resp
=
self
.
call_event
(
'flag_resource'
,
resource
)
resp
=
json
.
loads
(
self
.
call_event
(
'flag_resource'
,
resource
)
.
content
)
# The second user won't see the reason provided by the first user
self
.
assertNotIn
(
'oldReason'
,
resp
)
self
.
assertEqual
(
resp
[
'reason'
],
'reason 0'
)
...
...
@@ -454,15 +394,15 @@ class TestRecommenderWithResources(TestRecommender):
"""
Test the function for exporting all resources from the Recommender.
"""
self
.
call_event
(
'
deendors
e_resource'
,
{
"id"
:
self
.
resource_id
,
'reason'
:
''
})
self
.
call_event
(
'
remov
e_resource'
,
{
"id"
:
self
.
resource_id
,
'reason'
:
''
})
self
.
call_event
(
'endorse_resource'
,
{
"id"
:
self
.
resource_id_second
,
'reason'
:
''
})
# Test
resp
=
self
.
call_event
(
'export_resources'
,
{}
)
resp
=
json
.
loads
(
self
.
call_event
(
'export_resources'
,
{})
.
content
)
self
.
assertIn
(
self
.
resource_id_second
,
resp
[
'export'
][
'recommendations'
])
self
.
assertNotIn
(
self
.
resource_id
,
resp
[
'export'
][
'recommendations'
])
self
.
assertIn
(
self
.
resource_id_second
,
resp
[
'export'
][
'endorsed_recommendation_ids'
])
self
.
assertIn
(
self
.
resource_id
,
resp
[
'export'
][
'
deendors
ed_recommendations'
])
self
.
assertIn
(
self
.
resource_id
,
resp
[
'export'
][
'
remov
ed_recommendations'
])
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
...
...
@@ -484,7 +424,7 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
Vote a non-existing resource
"""
resource
=
{
"id"
:
self
.
non_existing_resource_id
,
'event'
:
test_case
[
'event'
]}
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'error'
,
'The selected resource is not existing'
)
self
.
check_event_response_by_
http_status
(
'handle_vote'
,
resource
,
400
)
@data
(
{
'event'
:
'recommender_upvote'
,
'new_votes'
:
1
},
...
...
@@ -495,7 +435,7 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
Vote a resource
"""
resource
=
{
"id"
:
self
.
resource_id
,
'event'
:
test_case
[
'event'
]}
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
self
.
check_event_response_by_
key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
@data
(
{
'event'
:
'recommender_upvote'
,
'new_votes'
:
0
},
...
...
@@ -508,7 +448,7 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
resource
=
{
"id"
:
self
.
resource_id
,
'event'
:
test_case
[
'event'
]}
self
.
call_event
(
'handle_vote'
,
resource
)
# Test
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
self
.
check_event_response_by_
key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
@data
(
{
'event'
:
'recommender_upvote'
,
'new_votes'
:
1
},
...
...
@@ -522,7 +462,7 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
for
_
in
range
(
0
,
2
):
self
.
call_event
(
'handle_vote'
,
resource
)
# Test
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
self
.
check_event_response_by_
key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
@data
(
{
'event'
:
'recommender_upvote'
,
'event_second'
:
'recommender_downvote'
,
'new_votes'
:
-
1
},
...
...
@@ -536,7 +476,7 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
self
.
call_event
(
'handle_vote'
,
resource
)
# Test
resource
[
'event'
]
=
test_case
[
'event_second'
]
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
self
.
check_event_response_by_
key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
@data
(
{
'event'
:
'recommender_upvote'
,
'new_votes'
:
1
},
...
...
@@ -550,7 +490,7 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
self
.
call_event
(
'handle_vote'
,
resource
)
# Test
resource
[
'id'
]
=
self
.
resource_id_second
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
self
.
check_event_response_by_
key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
@data
(
{
'event'
:
'recommender_upvote'
,
'new_votes'
:
1
},
...
...
@@ -563,7 +503,9 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
resource
=
{
"id"
:
self
.
resource_id
,
'event'
:
test_case
[
'event'
]}
self
.
call_event
(
'handle_vote'
,
resource
)
# Test
self
.
check_event_response_by_element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
],
self
.
XBLOCK_NAMES
[
1
])
self
.
check_event_response_by_key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
],
self
.
XBLOCK_NAMES
[
1
]
)
@data
(
{
'event'
:
'recommender_upvote'
,
'new_votes'
:
2
},
...
...
@@ -578,103 +520,105 @@ class TestRecommenderVoteWithResources(TestRecommenderWithResources):
self
.
logout
()
self
.
enroll_student
(
self
.
STUDENTS
[
0
][
'email'
],
self
.
STUDENTS
[
0
][
'password'
])
# Test
self
.
check_event_response_by_
element
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
self
.
check_event_response_by_
key
(
'handle_vote'
,
resource
,
'newVotes'
,
test_case
[
'new_votes'
])
@ddt
class
TestRecommenderStaffFeedbackWithResources
(
TestRecommenderWithResources
):
"""
Check whether we can
deendors
e/endorse resources correctly
Check whether we can
remov
e/endorse resources correctly
"""
def
setUp
(
self
):
# call the setUp function from the superclass
super
(
TestRecommenderStaffFeedbackWithResources
,
self
)
.
setUp
()
@data
(
'
deendors
e_resource'
,
'endorse_resource'
)
def
test_
deendors
e_or_endorse_resource_non_existing
(
self
,
test_case
):
@data
(
'
remov
e_resource'
,
'endorse_resource'
)
def
test_
remov
e_or_endorse_resource_non_existing
(
self
,
test_case
):
"""
Deendors
e/endorse a non-existing resource
Remov
e/endorse a non-existing resource
"""
resource
=
{
"id"
:
self
.
non_existing_resource_id
,
'reason'
:
''
}
self
.
check_event_response_by_element
(
test_case
,
resource
,
'error'
,
'The selected resource is not existing'
)
@data
(
{
'handler'
:
'deendorse_resource'
,
'key'
:
'Success'
,
'val'
:
True
},
{
'handler'
:
'endorse_resource'
,
'key'
:
'status'
,
'val'
:
'endorsement'
}
)
def
test_deendorse_or_endorse_resource_once
(
self
,
test_case
):
"""
Deendorse/endorse a resource
"""
resource
=
{
"id"
:
self
.
resource_id
,
'reason'
:
''
}
self
.
check_event_response_by_element
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val'
])
self
.
check_event_response_by_http_status
(
test_case
,
resource
,
400
)
@data
(
{
'handler'
:
'deendorse_resource'
,
'key'
:
'error'
,
'val'
:
'The selected resource is not existing'
},
{
'handler'
:
'endorse_resource'
,
'key'
:
'status'
,
'val'
:
'undo endorsement'
}
{
'times'
:
1
,
'key'
:
'status'
,
'val'
:
'endorsement'
},
{
'times'
:
2
,
'key'
:
'status'
,
'val'
:
'undo endorsement'
},
{
'times'
:
3
,
'key'
:
'status'
,
'val'
:
'endorsement'
}
)
def
test_
deendorse_or_endorse_resource_twice
(
self
,
test_case
):
def
test_
endorse_resource_multiple_times
(
self
,
test_case
):
"""
Deendorse/endorse a resource tw
ice
Endorse a resource once/twice/thr
ice
"""
resource
=
{
"id"
:
self
.
resource_id
,
'reason'
:
''
}
self
.
call_event
(
test_case
[
'handler'
],
resource
)
for
_
in
range
(
0
,
test_case
[
'times'
]
-
1
):
self
.
call_event
(
'endorse_resource'
,
resource
)
# Test
self
.
check_event_response_by_
element
(
test_case
[
'handler'
]
,
resource
,
test_case
[
'key'
],
test_case
[
'val'
])
self
.
check_event_response_by_
key
(
'endorse_resource'
,
resource
,
test_case
[
'key'
],
test_case
[
'val'
])
@data
(
{
'handler'
:
'deendorse_resource'
,
'key'
:
'error'
,
'val'
:
'The selected resource is not existing'
},
{
'handler'
:
'endorse_resource'
,
'key'
:
'status'
,
'val'
:
'endorsement'
}
{
'times'
:
1
,
'status'
:
200
},
{
'times'
:
2
,
'status'
:
400
},
{
'times'
:
3
,
'status'
:
400
}
)
def
test_
endorse_resource_thrice
(
self
,
test_case
):
def
test_
remove_resource_multiple_times
(
self
,
test_case
):
"""
Deendorse/endorse a resource
thrice
Remove a resource once/twice/
thrice
"""
resource
=
{
"id"
:
self
.
resource_id
,
'reason'
:
''
}
for
_
in
range
(
0
,
2
):
self
.
call_event
(
test_case
[
'handler'
]
,
resource
)
for
_
in
range
(
0
,
test_case
[
'times'
]
-
1
):
self
.
call_event
(
'remove_resource'
,
resource
)
# Test
self
.
check_event_response_by_
element
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val
'
])
self
.
check_event_response_by_
http_status
(
'remove_resource'
,
resource
,
test_case
[
'status
'
])
@data
(
{
'handler'
:
'
deendorse_resource'
,
'key'
:
'Success'
,
'val'
:
True
},
{
'handler'
:
'
remove_resource'
,
'status'
:
200
},
{
'handler'
:
'endorse_resource'
,
'key'
:
'status'
,
'val'
:
'endorsement'
}
)
def
test_
deendors
e_or_endorse_different_resources
(
self
,
test_case
):
def
test_
remov
e_or_endorse_different_resources
(
self
,
test_case
):
"""
Deendors
e/endorse two different resources
Remov
e/endorse two different resources
"""
self
.
call_event
(
test_case
[
'handler'
],
{
"id"
:
self
.
resource_id
,
'reason'
:
''
})
# Test
resource
=
{
"id"
:
self
.
resource_id_second
,
'reason'
:
''
}
self
.
check_event_response_by_element
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val'
])
if
test_case
[
'handler'
]
==
'remove_resource'
:
self
.
check_event_response_by_http_status
(
test_case
[
'handler'
],
resource
,
test_case
[
'status'
])
else
:
self
.
check_event_response_by_key
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val'
])
@data
(
{
'handler'
:
'
deendorse_resource'
,
'key'
:
'Success'
,
'val'
:
True
},
{
'handler'
:
'
remove_resource'
,
'status'
:
200
},
{
'handler'
:
'endorse_resource'
,
'key'
:
'status'
,
'val'
:
'endorsement'
}
)
def
test_
deendors
e_or_endorse_resources_in_different_xblocks
(
self
,
test_case
):
def
test_
remov
e_or_endorse_resources_in_different_xblocks
(
self
,
test_case
):
"""
Deendors
e/endorse two resources in two different xblocks
Remov
e/endorse two resources in two different xblocks
"""
self
.
call_event
(
test_case
[
'handler'
],
{
"id"
:
self
.
resource_id
,
'reason'
:
''
})
# Test
resource
=
{
"id"
:
self
.
resource_id
,
'reason'
:
''
}
self
.
check_event_response_by_element
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val'
],
self
.
XBLOCK_NAMES
[
1
])
if
test_case
[
'handler'
]
==
'remove_resource'
:
self
.
check_event_response_by_http_status
(
test_case
[
'handler'
],
resource
,
test_case
[
'status'
],
self
.
XBLOCK_NAMES
[
1
]
)
else
:
self
.
check_event_response_by_key
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val'
],
self
.
XBLOCK_NAMES
[
1
]
)
@data
(
{
'handler'
:
'
deendorse_resource'
,
'key'
:
'error'
,
'val'
:
'Deendorse resource without permission'
},
{
'handler'
:
'endorse_resource'
,
'
key'
:
'error'
,
'val'
:
'Endorse resource without permission'
}
{
'handler'
:
'
remove_resource'
,
'status'
:
400
},
{
'handler'
:
'endorse_resource'
,
'
status'
:
400
}
)
def
test_
deendors
e_or_endorse_resource_by_student
(
self
,
test_case
):
def
test_
remov
e_or_endorse_resource_by_student
(
self
,
test_case
):
"""
Deendors
e/endorse resource by a student
Remov
e/endorse resource by a student
"""
self
.
logout
()
self
.
enroll_student
(
self
.
STUDENTS
[
0
][
'email'
],
self
.
STUDENTS
[
0
][
'password'
])
# Test
resource
=
{
"id"
:
self
.
resource_id
,
'reason'
:
''
}
self
.
check_event_response_by_
element
(
test_case
[
'handler'
],
resource
,
test_case
[
'key'
],
test_case
[
'val
'
])
self
.
check_event_response_by_
http_status
(
test_case
[
'handler'
],
resource
,
test_case
[
'status
'
])
@ddt
...
...
@@ -685,21 +629,32 @@ class TestRecommenderFileUploading(TestRecommender):
def
setUp
(
self
):
# call the setUp function from the superclass
super
(
TestRecommenderFileUploading
,
self
)
.
setUp
()
self
.
initial_configuration
=
{
'flagged_accum_resources'
:
{},
'endorsed_recommendation_reasons'
:
[],
'endorsed_recommendation_ids'
:
[],
'removed_recommendations'
:
{},
'recommendations'
:
self
.
test_recommendations
[
self
.
resource_urls
[
0
]]
}
def
attempt_upload_file_and_verify_result
(
self
,
test_case
,
xblock_name
=
None
):
def
attempt_upload_file_and_verify_result
(
self
,
test_case
,
event_name
,
content
=
None
):
"""
Running on a test case, creating a temp file, uploading it by
calling the corresponding ajax event, and verifying that upload
happens or is rejected as expected.
"""
if
xblock_name
is
None
:
xblock_name
=
TestRecommender
.
XBLOCK_NAMES
[
0
]
f_handler
=
StringIO
.
StringIO
(
test_case
[
'magic_number'
]
.
decode
(
'hex'
))
if
'magic_number'
in
test_case
:
f_handler
=
StringIO
.
StringIO
(
test_case
[
'magic_number'
]
.
decode
(
'hex'
))
elif
content
is
not
None
:
f_handler
=
StringIO
.
StringIO
(
json
.
dumps
(
content
,
sort_keys
=
True
))
else
:
f_handler
=
StringIO
.
StringIO
(
''
)
f_handler
.
content_type
=
test_case
[
'mimetypes'
]
f_handler
.
name
=
'file'
+
test_case
[
'suffixes'
]
url
=
self
.
get_handler_url
(
'upload_screenshot'
,
xblock
_name
)
url
=
self
.
get_handler_url
(
event
_name
)
resp
=
self
.
client
.
post
(
url
,
{
'file'
:
f_handler
})
self
.
assert
RegexpMatches
(
resp
.
content
,
test_case
[
'response_regexp
'
])
self
.
assert
Equal
(
resp
.
status_code
,
test_case
[
'status
'
])
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
@data
(
...
...
@@ -707,43 +662,43 @@ class TestRecommenderFileUploading(TestRecommender):
'suffixes'
:
'.csv'
,
'magic_number'
:
'ffff'
,
'mimetypes'
:
'text/plain'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
},
# Upload file with wrong extension name
{
'suffixes'
:
'.gif'
,
'magic_number'
:
'89504e470d0a1a0a'
,
'mimetypes'
:
'image/gif'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
},
# Upload file with wrong magic number
{
'suffixes'
:
'.jpg'
,
'magic_number'
:
'89504e470d0a1a0a'
,
'mimetypes'
:
'image/jpeg'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
},
# Upload file with wrong magic number
{
'suffixes'
:
'.png'
,
'magic_number'
:
'474946383761'
,
'mimetypes'
:
'image/png'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
},
# Upload file with wrong magic number
{
'suffixes'
:
'.jpg'
,
'magic_number'
:
'474946383761'
,
'mimetypes'
:
'image/jpeg'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
},
# Upload file with wrong magic number
{
'suffixes'
:
'.png'
,
'magic_number'
:
'ffd8ffd9'
,
'mimetypes'
:
'image/png'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
},
# Upload file with wrong magic number
{
'suffixes'
:
'.gif'
,
'magic_number'
:
'ffd8ffd9'
,
'mimetypes'
:
'image/gif'
,
'
response_regexp'
:
'FILE_TYPE_ERROR'
'
status'
:
415
}
)
def
test_upload_screenshot_wrong_file_type
(
self
,
test_case
):
...
...
@@ -753,33 +708,32 @@ class TestRecommenderFileUploading(TestRecommender):
"""
self
.
enroll_staff
(
self
.
staff_user
)
# Upload file with wrong extension name or magic number
self
.
attempt_upload_file_and_verify_result
(
test_case
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
attempt_upload_file_and_verify_result
(
test_case
,
'upload_screenshot'
)
@data
(
{
'suffixes'
:
'.png'
,
'magic_number'
:
'89504e470d0a1a0a'
,
'mimetypes'
:
'image/png'
,
'
response_regexp'
:
'fs://.*.png'
'
status'
:
200
},
{
'suffixes'
:
'.gif'
,
'magic_number'
:
'474946383961'
,
'mimetypes'
:
'image/gif'
,
'
response_regexp'
:
'fs://.*.gif'
'
status'
:
200
},
{
'suffixes'
:
'.gif'
,
'magic_number'
:
'474946383761'
,
'mimetypes'
:
'image/gif'
,
'
response_regexp'
:
'fs://.*.gif'
'
status'
:
200
},
{
'suffixes'
:
'.jpg'
,
'magic_number'
:
'ffd8ffd9'
,
'mimetypes'
:
'image/jpeg'
,
'
response_regexp'
:
'fs://.*.jpeg'
'
status'
:
200
}
)
def
test_upload_screenshot_correct_file_type
(
self
,
test_case
):
...
...
@@ -789,5 +743,53 @@ class TestRecommenderFileUploading(TestRecommender):
"""
self
.
enroll_staff
(
self
.
staff_user
)
# Upload file with correct extension name and magic number
self
.
attempt_upload_file_and_verify_result
(
test_case
)
self
.
assert_request_status_code
(
200
,
self
.
course_url
)
self
.
attempt_upload_file_and_verify_result
(
test_case
,
'upload_screenshot'
)
@data
(
{
'suffixes'
:
'.json'
,
'mimetypes'
:
'application/json'
,
'status'
:
403
}
)
def
test_import_resources_by_student
(
self
,
test_case
):
"""
Test the function for importing all resources into the Recommender
by a student.
"""
self
.
enroll_student
(
self
.
STUDENTS
[
0
][
'email'
],
self
.
STUDENTS
[
0
][
'password'
])
self
.
attempt_upload_file_and_verify_result
(
test_case
,
'import_resources'
,
self
.
initial_configuration
)
@data
(
{
'suffixes'
:
'.csv'
,
'mimetypes'
:
'application/json'
,
'status'
:
415
},
# Upload file with wrong extension name
{
'suffixes'
:
'.json'
,
'mimetypes'
:
'application/json'
,
'status'
:
200
}
)
def
test_import_resources
(
self
,
test_case
):
"""
Test the function for importing all resources into the Recommender.
"""
self
.
enroll_staff
(
self
.
staff_user
)
self
.
attempt_upload_file_and_verify_result
(
test_case
,
'import_resources'
,
self
.
initial_configuration
)
@data
(
{
'suffixes'
:
'.json'
,
'mimetypes'
:
'application/json'
,
'status'
:
415
}
)
def
test_import_resources_wrong_format
(
self
,
test_case
):
"""
Test the function for importing empty dictionary into the Recommender.
This should fire an error.
"""
self
.
enroll_staff
(
self
.
staff_user
)
self
.
attempt_upload_file_and_verify_result
(
test_case
,
'import_resources'
,
{})
requirements/edx/github.txt
View file @
47b3eae7
...
...
@@ -34,5 +34,5 @@ git+https://github.com/mitocw/django-cas.git@60a5b8e5a62e63e0d5d224a87f0b489201a
-e git+https://github.com/edx/i18n-tools.git@56f048af9b6868613c14aeae760548834c495011#egg=i18n-tools
-e git+https://github.com/edx/edx-oauth2-provider.git@0.4.0#egg=oauth2-provider
-e git+https://github.com/edx/edx-val.git@ba00a5f2e0571e9a3f37d293a98efe4cbca850d5#egg=edx-val
-e git+https://github.com/pmitros/RecommenderXBlock.git@b41ba8778b98da0ea680ffb8bbc59492d669df2d#egg=recommender-xblock
-e git+https://github.com/edx/edx-milestones.git@4dfe78a2aae9559ccc979746d13a9b67f0ec311e#egg=edx-milestones
-e git+https://github.com/pmitros/RecommenderXBlock.git@a606d00bdf39bd0a4ae9c51773b69b9eb98934ff#egg=recommender-xblock
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