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
8e3a77fa
Commit
8e3a77fa
authored
11 years ago
by
Greg Price
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add acceptance tests for forum response pagination
parent
02a233b7
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
245 additions
and
1 deletions
+245
-1
common/djangoapps/terrain/stubs/comments.py
+79
-0
common/djangoapps/terrain/stubs/http.py
+7
-0
common/djangoapps/terrain/stubs/start.py
+3
-1
common/test/acceptance/pages/lms/discussion_single_thread.py
+70
-0
common/test/acceptance/tests/test_discussion.py
+81
-0
rakelib/bok_choy.rake
+5
-0
No files found.
common/djangoapps/terrain/stubs/comments.py
0 → 100644
View file @
8e3a77fa
"""
Stub implementation of cs_comments_service for acceptance tests
"""
from
datetime
import
datetime
import
re
import
urlparse
from
.http
import
StubHttpRequestHandler
,
StubHttpService
class
StubCommentsServiceHandler
(
StubHttpRequestHandler
):
def
do_GET
(
self
):
pattern_handlers
=
{
"/api/v1/users/(?P<user_id>
\\
d+)$"
:
self
.
do_user
,
"/api/v1/threads$"
:
self
.
do_threads
,
"/api/v1/threads/(?P<thread_id>
\\
w+)$"
:
self
.
do_thread
,
}
path
=
urlparse
.
urlparse
(
self
.
path
)
.
path
for
pattern
in
pattern_handlers
:
match
=
re
.
match
(
pattern
,
path
)
if
match
:
pattern_handlers
[
pattern
](
**
match
.
groupdict
())
return
self
.
send_response
(
404
,
content
=
"404 Not Found"
)
def
do_PUT
(
self
):
self
.
send_response
(
204
,
""
)
def
do_user
(
self
,
user_id
):
self
.
send_json_response
({
"id"
:
user_id
,
"upvoted_ids"
:
[],
"downvoted_ids"
:
[],
"subscribed_thread_ids"
:
[],
})
def
do_thread
(
self
,
thread_id
):
match
=
re
.
search
(
"(?P<num>
\\
d+)_responses"
,
thread_id
)
resp_total
=
int
(
match
.
group
(
"num"
))
if
match
else
0
thread
=
{
"id"
:
thread_id
,
"commentable_id"
:
"dummy"
,
"type"
:
"thread"
,
"title"
:
"Thread title"
,
"body"
:
"Thread body"
,
"created_at"
:
datetime
.
utcnow
()
.
isoformat
(),
"unread_comments_count"
:
0
,
"comments_count"
:
resp_total
,
"votes"
:
{
"up_count"
:
0
},
"abuse_flaggers"
:
[],
"closed"
:
"closed"
in
thread_id
,
}
params
=
urlparse
.
parse_qs
(
urlparse
.
urlparse
(
self
.
path
)
.
query
)
if
"recursive"
in
params
and
params
[
"recursive"
][
0
]
==
"True"
:
thread
[
"resp_total"
]
=
resp_total
thread
[
"children"
]
=
[]
resp_skip
=
int
(
params
.
get
(
"resp_skip"
,
[
"0"
])[
0
])
resp_limit
=
int
(
params
.
get
(
"resp_limit"
,
[
"10000"
])[
0
])
num_responses
=
min
(
resp_limit
,
resp_total
-
resp_skip
)
self
.
log_message
(
"Generating {} children; resp_limit={} resp_total={} resp_skip={}"
.
format
(
num_responses
,
resp_limit
,
resp_total
,
resp_skip
))
for
i
in
range
(
num_responses
):
response_id
=
str
(
resp_skip
+
i
)
thread
[
"children"
]
.
append
({
"id"
:
str
(
response_id
),
"type"
:
"comment"
,
"body"
:
response_id
,
"created_at"
:
datetime
.
utcnow
()
.
isoformat
(),
"votes"
:
{
"up_count"
:
0
},
"abuse_flaggers"
:
[],
})
self
.
send_json_response
(
thread
)
def
do_threads
(
self
):
self
.
send_json_response
({
"collection"
:
[],
"page"
:
1
,
"num_pages"
:
1
})
class
StubCommentsService
(
StubHttpService
):
HANDLER_CLASS
=
StubCommentsServiceHandler
This diff is collapsed.
Click to expand it.
common/djangoapps/terrain/stubs/http.py
View file @
8e3a77fa
...
...
@@ -202,6 +202,13 @@ class StubHttpRequestHandler(BaseHTTPRequestHandler, object):
if
content
is
not
None
:
self
.
wfile
.
write
(
content
)
def
send_json_response
(
self
,
content
):
"""
Send a response with status code 200, the given content serialized as
JSON, and the Content-Type header set appropriately
"""
self
.
send_response
(
200
,
json
.
dumps
(
content
),
{
"Content-Type"
:
"application/json"
})
def
_format_msg
(
self
,
format_str
,
*
args
):
"""
Format message for logging.
...
...
This diff is collapsed.
Click to expand it.
common/djangoapps/terrain/stubs/start.py
View file @
8e3a77fa
...
...
@@ -4,6 +4,7 @@ Command-line utility to start a stub service.
import
sys
import
time
import
logging
from
.comments
import
StubCommentsService
from
.xqueue
import
StubXQueueService
from
.youtube
import
StubYouTubeService
from
.ora
import
StubOraService
...
...
@@ -14,7 +15,8 @@ USAGE = "USAGE: python -m stubs.start SERVICE_NAME PORT_NUM [CONFIG_KEY=CONFIG_V
SERVICES
=
{
'xqueue'
:
StubXQueueService
,
'youtube'
:
StubYouTubeService
,
'ora'
:
StubOraService
'ora'
:
StubOraService
,
'comments'
:
StubCommentsService
,
}
# Log to stdout, including debug messages
...
...
This diff is collapsed.
Click to expand it.
common/test/acceptance/pages/lms/discussion_single_thread.py
0 → 100644
View file @
8e3a77fa
from
bok_choy.page_object
import
unguarded
from
bok_choy.promise
import
EmptyPromise
,
fulfill
from
.course_page
import
CoursePage
class
DiscussionSingleThreadPage
(
CoursePage
):
def
__init__
(
self
,
browser
,
course_id
,
thread_id
):
super
(
DiscussionSingleThreadPage
,
self
)
.
__init__
(
browser
,
course_id
)
self
.
thread_id
=
thread_id
def
is_browser_on_page
(
self
):
return
self
.
is_css_present
(
"body.discussion .discussion-article[data-id='{thread_id}']"
.
format
(
thread_id
=
self
.
thread_id
)
)
@property
@unguarded
def
url_path
(
self
):
return
"discussion/forum/dummy/threads/"
+
self
.
thread_id
def
_get_element_text
(
self
,
selector
):
"""
Returns the text of the first element matching the given selector, or
None if no such element exists
"""
text_list
=
self
.
css_text
(
selector
)
return
text_list
[
0
]
if
text_list
else
None
def
get_response_total_text
(
self
):
"""Returns the response count text, or None if not present"""
return
self
.
_get_element_text
(
".response-count"
)
def
get_num_displayed_responses
(
self
):
"""Returns the number of responses actually rendered"""
return
self
.
css_count
(
".discussion-response"
)
def
get_shown_responses_text
(
self
):
"""Returns the shown response count text, or None if not present"""
return
self
.
_get_element_text
(
".response-display-count"
)
def
get_load_responses_button_text
(
self
):
"""Returns the load more responses button text, or None if not present"""
return
self
.
_get_element_text
(
".load-response-button"
)
def
load_more_responses
(
self
):
"""Clicks the laod more responses button and waits for responses to load"""
self
.
css_click
(
".load-response-button"
)
fulfill
(
EmptyPromise
(
lambda
:
not
self
.
is_css_present
(
".loading"
),
"Loading more responses completed"
))
def
has_add_response_button
(
self
):
"""Returns true if the add response button is visible, false otherwise"""
return
(
self
.
is_css_present
(
".add-response-btn"
)
and
self
.
css_map
(
".add-response-btn"
,
lambda
el
:
el
.
visible
)[
0
]
)
def
click_add_response_button
(
self
):
"""
Clicks the add response button and ensures that the response text
field receives focus
"""
self
.
css_click
(
".add-response-btn"
)
fulfill
(
EmptyPromise
(
lambda
:
self
.
is_css_present
(
"#wmd-input-reply-body-{thread_id}:focus"
.
format
(
thread_id
=
self
.
thread_id
)),
"Response field received focus"
))
This diff is collapsed.
Click to expand it.
common/test/acceptance/tests/test_discussion.py
0 → 100644
View file @
8e3a77fa
"""
Tests for discussion pages
"""
from
.helpers
import
UniqueCourseTest
from
..pages.studio.auto_auth
import
AutoAuthPage
from
..pages.lms.discussion_single_thread
import
DiscussionSingleThreadPage
from
..fixtures.course
import
CourseFixture
class
DiscussionSingleThreadTest
(
UniqueCourseTest
):
"""
Tests for the discussion page displaying a single thread
"""
def
setUp
(
self
):
super
(
DiscussionSingleThreadTest
,
self
)
.
setUp
()
# Create a course to register for
CourseFixture
(
**
self
.
course_info
)
.
install
()
AutoAuthPage
(
self
.
browser
,
course_id
=
self
.
course_id
)
.
visit
()
def
test_no_responses
(
self
):
page
=
DiscussionSingleThreadPage
(
self
.
browser
,
self
.
course_id
,
"0_responses"
)
page
.
visit
()
self
.
assertEqual
(
page
.
get_response_total_text
(),
"0 responses"
)
self
.
assertFalse
(
page
.
has_add_response_button
())
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
0
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
None
)
self
.
assertIsNone
(
page
.
get_load_responses_button_text
())
def
test_few_responses
(
self
):
page
=
DiscussionSingleThreadPage
(
self
.
browser
,
self
.
course_id
,
"5_responses"
)
page
.
visit
()
self
.
assertEqual
(
page
.
get_response_total_text
(),
"5 responses"
)
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
5
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
"Showing all responses"
)
self
.
assertIsNone
(
page
.
get_load_responses_button_text
())
def
test_two_response_pages
(
self
):
page
=
DiscussionSingleThreadPage
(
self
.
browser
,
self
.
course_id
,
"50_responses"
)
page
.
visit
()
self
.
assertEqual
(
page
.
get_response_total_text
(),
"50 responses"
)
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
25
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
"Showing first 25 responses"
)
self
.
assertEqual
(
page
.
get_load_responses_button_text
(),
"Load all responses"
)
page
.
load_more_responses
()
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
50
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
"Showing all responses"
)
self
.
assertEqual
(
page
.
get_load_responses_button_text
(),
None
)
def
test_three_response_pages
(
self
):
page
=
DiscussionSingleThreadPage
(
self
.
browser
,
self
.
course_id
,
"150_responses"
)
page
.
visit
()
self
.
assertEqual
(
page
.
get_response_total_text
(),
"150 responses"
)
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
25
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
"Showing first 25 responses"
)
self
.
assertEqual
(
page
.
get_load_responses_button_text
(),
"Load next 100 responses"
)
page
.
load_more_responses
()
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
125
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
"Showing first 125 responses"
)
self
.
assertEqual
(
page
.
get_load_responses_button_text
(),
"Load all responses"
)
page
.
load_more_responses
()
self
.
assertEqual
(
page
.
get_num_displayed_responses
(),
150
)
self
.
assertEqual
(
page
.
get_shown_responses_text
(),
"Showing all responses"
)
self
.
assertEqual
(
page
.
get_load_responses_button_text
(),
None
)
def
test_add_response_button
(
self
):
page
=
DiscussionSingleThreadPage
(
self
.
browser
,
self
.
course_id
,
"5_responses"
)
page
.
visit
()
self
.
assertTrue
(
page
.
has_add_response_button
())
page
.
click_add_response_button
()
def
test_add_response_button_closed_thread
(
self
):
page
=
DiscussionSingleThreadPage
(
self
.
browser
,
self
.
course_id
,
"5_responses_closed"
)
page
.
visit
()
self
.
assertFalse
(
page
.
has_add_response_button
())
This diff is collapsed.
Click to expand it.
rakelib/bok_choy.rake
View file @
8e3a77fa
...
...
@@ -41,6 +41,11 @@ BOK_CHOY_STUBS = {
:port
=>
8041
,
:log
=>
File
.
join
(
BOK_CHOY_LOG_DIR
,
"bok_choy_ora.log"
),
:config
=>
''
},
:comments
=>
{
:port
=>
4567
,
:log
=>
File
.
join
(
BOK_CHOY_LOG_DIR
,
"bok_choy_comments.log"
)
}
}
...
...
This diff is collapsed.
Click to expand it.
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