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
382909b7
Commit
382909b7
authored
Aug 24, 2015
by
Peter Fogg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add sorting controls on Teams topics page.
TNL-1936
parent
f01fd6e7
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
151 additions
and
15 deletions
+151
-15
common/static/common/js/components/collections/paging_collection.js
+1
-1
common/static/common/js/components/views/paging_header.js
+15
-2
common/static/common/js/spec/components/paging_header_spec.js
+20
-1
common/static/common/templates/components/paging-header.underscore
+15
-2
common/test/acceptance/pages/lms/teams.py
+18
-0
common/test/acceptance/tests/lms/test_teams.py
+71
-6
lms/djangoapps/teams/static/teams/js/collections/base.js
+1
-1
lms/djangoapps/teams/static/teams/js/views/topics.js
+10
-2
No files found.
common/static/common/js/components/collections/paging_collection.js
View file @
382909b7
...
...
@@ -82,7 +82,7 @@
setPage
:
function
(
page
)
{
var
oldPage
=
this
.
currentPage
,
self
=
this
;
this
.
goTo
(
page
-
(
this
.
isZeroIndexed
?
1
:
0
),
{
reset
:
true
}).
then
(
return
this
.
goTo
(
page
-
(
this
.
isZeroIndexed
?
1
:
0
),
{
reset
:
true
}).
then
(
function
()
{
self
.
trigger
(
'page_changed'
);
},
...
...
common/static/common/js/components/views/paging_header.js
View file @
382909b7
...
...
@@ -9,12 +9,16 @@
var
PagingHeader
=
Backbone
.
View
.
extend
({
initialize
:
function
(
options
)
{
this
.
srInfo
=
options
.
srInfo
;
this
.
collections
=
options
.
collection
;
this
.
showSortControls
=
options
.
showSortControls
;
this
.
collection
.
bind
(
'add'
,
_
.
bind
(
this
.
render
,
this
));
this
.
collection
.
bind
(
'remove'
,
_
.
bind
(
this
.
render
,
this
));
this
.
collection
.
bind
(
'reset'
,
_
.
bind
(
this
.
render
,
this
));
},
events
:
{
'change #paging-header-select'
:
'sortCollection'
},
render
:
function
()
{
var
message
,
start
=
_
.
isUndefined
(
this
.
collection
.
start
)
?
0
:
this
.
collection
.
start
,
...
...
@@ -31,9 +35,18 @@
}
this
.
$el
.
html
(
_
.
template
(
headerTemplate
,
{
message
:
message
,
srInfo
:
this
.
srInfo
srInfo
:
this
.
srInfo
,
sortableFields
:
this
.
collection
.
sortableFields
,
sortOrder
:
this
.
sortOrder
,
showSortControls
:
this
.
showSortControls
}));
return
this
;
},
sortCollection
:
function
()
{
var
selected
=
this
.
$
(
'#paging-header-select option:selected'
);
this
.
sortOrder
=
selected
.
attr
(
'value'
);
this
.
collection
.
setSortField
(
this
.
sortOrder
);
}
});
return
PagingHeader
;
...
...
common/static/common/js/spec/components/paging_header_spec.js
View file @
382909b7
...
...
@@ -8,7 +8,7 @@ define([
var
pagingHeader
,
newCollection
=
function
(
size
,
perPage
)
{
var
pageSize
=
5
,
results
=
_
.
map
(
_
.
range
(
size
),
function
(
)
{
return
{
};
});
results
=
_
.
map
(
_
.
range
(
size
),
function
(
i
)
{
return
{
foo
:
i
};
});
var
collection
=
new
PagingCollection
(
{
count
:
results
.
length
,
...
...
@@ -22,6 +22,14 @@ define([
collection
.
start
=
0
;
collection
.
totalCount
=
results
.
length
;
return
collection
;
},
sortableHeader
=
function
(
sortable
)
{
var
collection
=
newCollection
(
5
,
4
);
collection
.
registerSortableField
(
'foo'
,
'Display Name'
);
return
new
PagingHeader
({
collection
:
collection
,
showSortControls
:
_
.
isUndefined
(
sortable
)
?
true
:
sortable
});
};
it
(
'correctly displays which items are being viewed'
,
function
()
{
...
...
@@ -47,5 +55,16 @@ define([
expect
(
pagingHeader
.
$el
.
find
(
'.search-count'
).
text
())
.
toContain
(
'Showing 1 out of 1 total'
);
});
it
(
'optionally shows sorting controls'
,
function
()
{
pagingHeader
=
sortableHeader
().
render
();
expect
(
pagingHeader
.
$el
.
find
(
'.listing-sort'
).
text
())
.
toMatch
(
/Sorted by
\s
+Display Name/
);
});
it
(
'does not show sorting controls if the `showSortControls` option is not passed'
,
function
()
{
pagingHeader
=
sortableHeader
(
false
).
render
();
expect
(
pagingHeader
.
$el
.
text
()).
not
.
toContain
(
'Sorted by'
);
});
});
});
common/static/common/templates/components/paging-header.underscore
View file @
382909b7
<% if (!_.isUndefined(srInfo)) { %>
<h2 class="sr" id="<%= srInfo.id %>"><%- srInfo.text %></h2>
<% } %>
<div class="search-tools">
<span class="search-count">
<div class="search-tools
listing-tools
">
<span class="search-count
listing-count
">
<%= message %>
</span>
<% if (showSortControls) { %>
|
<span class="field listing-sort">
<label class="field-label" for="paging-header-select"><%- gettext("Sorted by") %></label>
<select id="paging-header-select" name="paging-header-select" class="field-input input-select listing-sort-select">
<% _.each(sortableFields, function (option, key) { %>
<option value="<%= key %>" <% if (key === sortOrder) { %> selected="true" <% } %>>
<%- option.displayName %>
</option>
<% }) %>
</select>
</span>
<% } %>
</div>
common/test/acceptance/pages/lms/teams.py
View file @
382909b7
...
...
@@ -11,6 +11,7 @@ from .fields import FieldsMixin
TOPIC_CARD_CSS
=
'div.wrapper-card-core'
CARD_TITLE_CSS
=
'h3.card-title'
MY_TEAMS_BUTTON_CSS
=
'a.nav-item[data-index="0"]'
BROWSE_BUTTON_CSS
=
'a.nav-item[data-index="1"]'
TEAMS_LINK_CSS
=
'.action-view'
...
...
@@ -121,6 +122,11 @@ class BrowseTopicsPage(CoursePage, PaginatedUIMixin):
"""Return a list of the topic cards present on the page."""
return
self
.
q
(
css
=
TOPIC_CARD_CSS
)
.
results
@property
def
topic_names
(
self
):
"""Return a list of the topic names present on the page."""
return
self
.
q
(
css
=
CARD_TITLE_CSS
)
.
map
(
lambda
e
:
e
.
text
)
.
results
def
browse_teams_for_topic
(
self
,
topic_name
):
"""
Show the teams list for `topic_name`.
...
...
@@ -130,6 +136,13 @@ class BrowseTopicsPage(CoursePage, PaginatedUIMixin):
)[
0
]
.
click
()
self
.
wait_for_ajax
()
def
sort_topics_by
(
self
,
sort_order
):
"""Sort the list of topics by the given `sort_order`."""
self
.
q
(
css
=
'#paging-header-select option[value={sort_order}]'
.
format
(
sort_order
=
sort_order
)
)
.
click
()
self
.
wait_for_ajax
()
class
BrowseTeamsPage
(
CoursePage
,
PaginatedUIMixin
):
"""
...
...
@@ -388,3 +401,8 @@ class TeamPage(CoursePage, PaginatedUIMixin):
def
new_post_button_present
(
self
):
""" Returns True if New Post button is present else False """
return
self
.
q
(
css
=
'.discussion-module .new-post-btn'
)
.
present
def
click_all_topics_breadcrumb
(
self
):
"""Navigate to the 'All Topics' page."""
self
.
q
(
css
=
'.breadcrumbs a'
)
.
results
[
0
]
.
click
()
self
.
wait_for_ajax
()
common/test/acceptance/tests/lms/test_teams.py
View file @
382909b7
...
...
@@ -2,6 +2,7 @@
Acceptance tests for the teams feature.
"""
import
json
import
random
import
ddt
from
flaky
import
flaky
...
...
@@ -22,6 +23,9 @@ from ...pages.lms.tab_nav import TabNavPage
from
...pages.lms.teams
import
TeamsPage
,
MyTeamsPage
,
BrowseTopicsPage
,
BrowseTeamsPage
,
CreateTeamPage
,
TeamPage
TOPICS_PER_PAGE
=
12
class
TeamsTabBase
(
UniqueCourseTest
):
"""Base class for Teams Tab tests"""
def
setUp
(
self
):
...
...
@@ -274,6 +278,7 @@ class MyTeamsTest(TeamsTabBase):
@attr
(
'shard_5'
)
@ddt.ddt
class
BrowseTopicsTest
(
TeamsTabBase
):
"""
Tests for the Browse tab of the Teams page.
...
...
@@ -283,6 +288,66 @@ class BrowseTopicsTest(TeamsTabBase):
super
(
BrowseTopicsTest
,
self
)
.
setUp
()
self
.
topics_page
=
BrowseTopicsPage
(
self
.
browser
,
self
.
course_id
)
@ddt.data
((
'name'
,
False
),
(
'team_count'
,
True
))
@ddt.unpack
def
test_sort_topics
(
self
,
sort_order
,
reverse
):
"""
Scenario: the user should be able to sort the list of topics by name or team count
Given I am enrolled in a course with team configuration and topics
When I visit the Teams page
And I browse topics
Then I should see a list of topics for the course
When I choose a sort order
Then I should see the paginated list of topics in that order
"""
topics
=
self
.
create_topics
(
TOPICS_PER_PAGE
+
1
)
self
.
set_team_configuration
({
u"max_team_size"
:
100
,
u"topics"
:
topics
})
for
i
,
topic
in
enumerate
(
random
.
sample
(
topics
,
len
(
topics
))):
self
.
create_teams
(
topic
,
i
)
topic
[
'team_count'
]
=
i
self
.
topics_page
.
visit
()
self
.
topics_page
.
sort_topics_by
(
sort_order
)
topic_names
=
self
.
topics_page
.
topic_names
self
.
assertEqual
(
len
(
topic_names
),
TOPICS_PER_PAGE
)
self
.
assertEqual
(
topic_names
,
[
t
[
'name'
]
for
t
in
sorted
(
topics
,
key
=
lambda
t
:
t
[
sort_order
],
reverse
=
reverse
)][:
TOPICS_PER_PAGE
]
)
def
test_sort_topics_update
(
self
):
"""
Scenario: the list of topics should remain sorted after updates
Given I am enrolled in a course with team configuration and topics
When I visit the Teams page
And I browse topics and choose a sort order
Then I should see the paginated list of topics in that order
When I create a team in one of those topics
And I return to the topics list
Then I should see the topics in the correct sorted order
"""
topics
=
self
.
create_topics
(
3
)
self
.
set_team_configuration
({
u"max_team_size"
:
100
,
u"topics"
:
topics
})
self
.
topics_page
.
visit
()
self
.
topics_page
.
sort_topics_by
(
'team_count'
)
topic_name
=
self
.
topics_page
.
topic_names
[
-
1
]
topic
=
[
t
for
t
in
topics
if
t
[
'name'
]
==
topic_name
][
0
]
self
.
topics_page
.
browse_teams_for_topic
(
topic_name
)
browse_teams_page
=
BrowseTeamsPage
(
self
.
browser
,
self
.
course_id
,
topic
)
self
.
assertTrue
(
browse_teams_page
.
is_browser_on_page
())
browse_teams_page
.
click_create_team_link
()
create_team_page
=
CreateTeamPage
(
self
.
browser
,
self
.
course_id
,
topic
)
create_team_page
.
value_for_text_field
(
field_id
=
'name'
,
value
=
'Team Name'
,
press_enter
=
False
)
create_team_page
.
value_for_textarea_field
(
field_id
=
'description'
,
value
=
'Team description.'
)
create_team_page
.
submit_form
()
team_page
=
TeamPage
(
self
.
browser
,
self
.
course_id
)
self
.
assertTrue
(
team_page
.
is_browser_on_page
)
team_page
.
click_all_topics_breadcrumb
()
self
.
assertTrue
(
self
.
topics_page
.
is_browser_on_page
())
self
.
assertEqual
(
topic_name
,
self
.
topics_page
.
topic_names
[
0
])
def
test_list_topics
(
self
):
"""
Scenario: a list of topics should be visible in the "Browse" tab
...
...
@@ -294,7 +359,7 @@ class BrowseTopicsTest(TeamsTabBase):
self
.
set_team_configuration
({
u"max_team_size"
:
10
,
u"topics"
:
self
.
create_topics
(
2
)})
self
.
topics_page
.
visit
()
self
.
assertEqual
(
len
(
self
.
topics_page
.
topic_cards
),
2
)
self
.
assert
Equal
(
self
.
topics_page
.
get_pagination_header_text
(),
'Showing 1-2 out of 2 total'
)
self
.
assert
True
(
self
.
topics_page
.
get_pagination_header_text
()
.
startswith
(
'Showing 1-2 out of 2 total'
)
)
self
.
assertFalse
(
self
.
topics_page
.
pagination_controls_visible
())
self
.
assertFalse
(
self
.
topics_page
.
is_previous_page_button_enabled
())
self
.
assertFalse
(
self
.
topics_page
.
is_next_page_button_enabled
())
...
...
@@ -309,8 +374,8 @@ class BrowseTopicsTest(TeamsTabBase):
"""
self
.
set_team_configuration
({
u"max_team_size"
:
10
,
u"topics"
:
self
.
create_topics
(
20
)})
self
.
topics_page
.
visit
()
self
.
assertEqual
(
len
(
self
.
topics_page
.
topic_cards
),
12
)
self
.
assert
Equal
(
self
.
topics_page
.
get_pagination_header_text
(),
'Showing 1-12 out of 20 total'
)
self
.
assertEqual
(
len
(
self
.
topics_page
.
topic_cards
),
TOPICS_PER_PAGE
)
self
.
assert
True
(
self
.
topics_page
.
get_pagination_header_text
()
.
startswith
(
'Showing 1-12 out of 20 total'
)
)
self
.
assertTrue
(
self
.
topics_page
.
pagination_controls_visible
())
self
.
assertFalse
(
self
.
topics_page
.
is_previous_page_button_enabled
())
self
.
assertTrue
(
self
.
topics_page
.
is_next_page_button_enabled
())
...
...
@@ -360,10 +425,10 @@ class BrowseTopicsTest(TeamsTabBase):
self
.
topics_page
.
visit
()
self
.
topics_page
.
press_next_page_button
()
self
.
assertEqual
(
len
(
self
.
topics_page
.
topic_cards
),
1
)
self
.
assert
Equal
(
self
.
topics_page
.
get_pagination_header_text
(),
'Showing 13-13 out of 13 total'
)
self
.
assert
True
(
self
.
topics_page
.
get_pagination_header_text
()
.
startswith
(
'Showing 13-13 out of 13 total'
)
)
self
.
topics_page
.
press_previous_page_button
()
self
.
assertEqual
(
len
(
self
.
topics_page
.
topic_cards
),
12
)
self
.
assert
Equal
(
self
.
topics_page
.
get_pagination_header_text
(),
'Showing 1-12 out of 13 total'
)
self
.
assertEqual
(
len
(
self
.
topics_page
.
topic_cards
),
TOPICS_PER_PAGE
)
self
.
assert
True
(
self
.
topics_page
.
get_pagination_header_text
()
.
startswith
(
'Showing 1-12 out of 13 total'
)
)
def
test_topic_description_truncation
(
self
):
"""
...
...
lms/djangoapps/teams/static/teams/js/collections/base.js
View file @
382909b7
...
...
@@ -27,7 +27,7 @@
var
self
=
this
,
deferred
=
$
.
Deferred
();
if
(
force
||
this
.
isStale
)
{
this
.
fetch
(
)
this
.
setPage
(
1
)
.
done
(
function
()
{
self
.
isStale
=
false
;
deferred
.
resolve
();
...
...
lms/djangoapps/teams/static/teams/js/views/topics.js
View file @
382909b7
...
...
@@ -3,8 +3,9 @@
define
([
'gettext'
,
'teams/js/views/topic_card'
,
'common/js/components/views/paging_header'
,
'common/js/components/views/paginated_view'
],
function
(
gettext
,
TopicCardView
,
PaginatedView
)
{
],
function
(
gettext
,
TopicCardView
,
Pagin
gHeader
,
Pagin
atedView
)
{
var
TopicsView
=
PaginatedView
.
extend
({
type
:
'topics'
,
...
...
@@ -21,11 +22,18 @@
PaginatedView
.
prototype
.
initialize
.
call
(
this
);
},
createHeaderView
:
function
()
{
return
new
PagingHeader
({
collection
:
this
.
options
.
collection
,
srInfo
:
this
.
srInfo
,
showSortControls
:
true
});
},
render
:
function
()
{
var
self
=
this
;
this
.
collection
.
refresh
()
.
done
(
function
()
{
self
.
collection
.
isStale
=
false
;
PaginatedView
.
prototype
.
render
.
call
(
self
);
});
return
this
;
...
...
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