Topic teams actions (#24336)
* modern eslint allowances * update topic teams to request team membership per local teamset * update tests for topic_teams change * cleanup Co-authored-by: Ben Warzeski <benwarzeski@edX-C02CD0HCLVDM.cable.rcn.com>
This commit is contained in:
7
lms/djangoapps/teams/static/teams/js/.eslintrc.json
Normal file
7
lms/djangoapps/teams/static/teams/js/.eslintrc.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
"comma-dangle": "off",
|
||||||
|
"object-curly-spacing": "off",
|
||||||
|
"no-underscore-dangle": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,14 +38,14 @@ define([
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
var createTeamsTabView = function(test, options) {
|
var createTeamsTabView = function(options) {
|
||||||
var teamsTabView = new TeamsTabView(
|
var teamsTabView = new TeamsTabView(
|
||||||
{
|
{
|
||||||
el: $('.teams-content'),
|
el: $('.teams-content'),
|
||||||
context: TeamSpecHelpers.createMockContext(options)
|
context: TeamSpecHelpers.createMockContext(options)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
requests = AjaxHelpers.requests(test);
|
requests = AjaxHelpers.requests();
|
||||||
PageHelpers.preventBackboneChangingUrl();
|
PageHelpers.preventBackboneChangingUrl();
|
||||||
teamsTabView.start();
|
teamsTabView.start();
|
||||||
return teamsTabView;
|
return teamsTabView;
|
||||||
@@ -65,7 +65,7 @@ define([
|
|||||||
|
|
||||||
describe('Navigation', function() {
|
describe('Navigation', function() {
|
||||||
it('does not render breadcrumbs for the top level tabs', function() {
|
it('does not render breadcrumbs for the top level tabs', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
var teamsTabView = createTeamsTabView();
|
||||||
teamsTabView.router.navigate('#my-teams', {trigger: true});
|
teamsTabView.router.navigate('#my-teams', {trigger: true});
|
||||||
expect(teamsTabView.$('.breadcrumbs').length).toBe(0);
|
expect(teamsTabView.$('.breadcrumbs').length).toBe(0);
|
||||||
teamsTabView.router.navigate('#browse', {trigger: true});
|
teamsTabView.router.navigate('#browse', {trigger: true});
|
||||||
@@ -73,20 +73,20 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not interfere with anchor links to #main', function() {
|
it('does not interfere with anchor links to #main', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
var teamsTabView = createTeamsTabView();
|
||||||
teamsTabView.router.navigate('#main', {trigger: true});
|
teamsTabView.router.navigate('#main', {trigger: true});
|
||||||
expect(teamsTabView.$('.wrapper-msg')).toHaveClass('is-hidden');
|
expect(teamsTabView.$('.wrapper-msg')).toHaveClass('is-hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays and focuses an error message when trying to navigate to a nonexistent page', function() {
|
it('displays and focuses an error message when trying to navigate to a nonexistent page', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
var teamsTabView = createTeamsTabView();
|
||||||
teamsTabView.router.navigate('no_such_page', {trigger: true});
|
teamsTabView.router.navigate('no_such_page', {trigger: true});
|
||||||
expectError(teamsTabView, 'The page "no_such_page" could not be found.');
|
expectError(teamsTabView, 'The page "no_such_page" could not be found.');
|
||||||
expectFocus(teamsTabView.$('.warning'));
|
expectFocus(teamsTabView.$('.warning'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays and focuses an error message when trying to navigate to a nonexistent topic', function() {
|
it('displays and focuses an error message when trying to navigate to a nonexistent topic', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
var teamsTabView = createTeamsTabView();
|
||||||
teamsTabView.router.navigate('topics/no_such_topic', {trigger: true});
|
teamsTabView.router.navigate('topics/no_such_topic', {trigger: true});
|
||||||
AjaxHelpers.expectRequest(requests, 'GET', '/api/team/v0/topics/no_such_topic,course/1', null);
|
AjaxHelpers.expectRequest(requests, 'GET', '/api/team/v0/topics/no_such_topic,course/1', null);
|
||||||
AjaxHelpers.respondWithError(requests, 404);
|
AjaxHelpers.respondWithError(requests, 404);
|
||||||
@@ -95,7 +95,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('displays and focuses an error message when trying to navigate to a nonexistent team', function() {
|
it('displays and focuses an error message when trying to navigate to a nonexistent team', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
var teamsTabView = createTeamsTabView();
|
||||||
teamsTabView.router.navigate('teams/' + TeamSpecHelpers.testTopicID + '/no_such_team', {trigger: true});
|
teamsTabView.router.navigate('teams/' + TeamSpecHelpers.testTopicID + '/no_such_team', {trigger: true});
|
||||||
AjaxHelpers.expectRequest(requests, 'GET', '/api/team/v0/teams/no_such_team?expand=user', null);
|
AjaxHelpers.expectRequest(requests, 'GET', '/api/team/v0/teams/no_such_team?expand=user', null);
|
||||||
AjaxHelpers.respondWithError(requests, 404);
|
AjaxHelpers.respondWithError(requests, 404);
|
||||||
@@ -104,7 +104,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('displays and focuses an error message when it receives a 401 AJAX response', function() {
|
it('displays and focuses an error message when it receives a 401 AJAX response', function() {
|
||||||
var teamsTabView = createTeamsTabView(this).render();
|
var teamsTabView = createTeamsTabView().render();
|
||||||
teamsTabView.router.navigate('topics/' + TeamSpecHelpers.testTopicID, {trigger: true});
|
teamsTabView.router.navigate('topics/' + TeamSpecHelpers.testTopicID, {trigger: true});
|
||||||
AjaxHelpers.respondWithError(requests, 401);
|
AjaxHelpers.respondWithError(requests, 401);
|
||||||
expectError(teamsTabView, 'Your request could not be completed. Reload the page and try again.');
|
expectError(teamsTabView, 'Your request could not be completed. Reload the page and try again.');
|
||||||
@@ -112,7 +112,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('displays and focuses an error message when it receives a 500 AJAX response', function() {
|
it('displays and focuses an error message when it receives a 500 AJAX response', function() {
|
||||||
var teamsTabView = createTeamsTabView(this).render();
|
var teamsTabView = createTeamsTabView().render();
|
||||||
teamsTabView.router.navigate('topics/' + TeamSpecHelpers.testTopicID, {trigger: true});
|
teamsTabView.router.navigate('topics/' + TeamSpecHelpers.testTopicID, {trigger: true});
|
||||||
AjaxHelpers.respondWithError(requests, 500);
|
AjaxHelpers.respondWithError(requests, 500);
|
||||||
expectError(
|
expectError(
|
||||||
@@ -124,7 +124,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not navigate to the topics page when syncing its collection if not on search page', function() {
|
it('does not navigate to the topics page when syncing its collection if not on search page', function() {
|
||||||
var teamsTabView = createTeamsTabView(this),
|
var teamsTabView = createTeamsTabView(),
|
||||||
collection = TeamSpecHelpers.createMockTeams();
|
collection = TeamSpecHelpers.createMockTeams();
|
||||||
teamsTabView.createTeamsListView({
|
teamsTabView.createTeamsListView({
|
||||||
collection: collection,
|
collection: collection,
|
||||||
@@ -179,7 +179,7 @@ define([
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, function(url, expectedEvent) {
|
}, function(url, expectedEvent) {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({staff: true})
|
userInfo: TeamSpecHelpers.createMockUserInfo({staff: true})
|
||||||
});
|
});
|
||||||
teamsTabView.teamsCollection = TeamSpecHelpers.createMockTeams();
|
teamsTabView.teamsCollection = TeamSpecHelpers.createMockTeams();
|
||||||
@@ -193,7 +193,7 @@ define([
|
|||||||
|
|
||||||
describe('Discussion privileges', function() {
|
describe('Discussion privileges', function() {
|
||||||
it('allows privileged access to any team', function() {
|
it('allows privileged access to any team', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true})
|
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true})
|
||||||
});
|
});
|
||||||
// Note: using `undefined` here to ensure that we
|
// Note: using `undefined` here to ensure that we
|
||||||
@@ -203,7 +203,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('allows access to a team which an unprivileged user is a member of', function() {
|
it('allows access to a team which an unprivileged user is a member of', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({
|
userInfo: TeamSpecHelpers.createMockUserInfo({
|
||||||
username: TeamSpecHelpers.testUser,
|
username: TeamSpecHelpers.testUser,
|
||||||
privileged: false
|
privileged: false
|
||||||
@@ -221,7 +221,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not allow access if the user is neither privileged nor a team member', function() {
|
it('does not allow access if the user is neither privileged nor a team member', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: false, staff: true})
|
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: false, staff: true})
|
||||||
});
|
});
|
||||||
expect(teamsTabView.readOnlyDiscussion({
|
expect(teamsTabView.readOnlyDiscussion({
|
||||||
@@ -233,7 +233,7 @@ define([
|
|||||||
describe('Manage Tab', function() {
|
describe('Manage Tab', function() {
|
||||||
var manageTabSelector = '.page-content-nav>.nav-item[data-url=manage]';
|
var manageTabSelector = '.page-content-nav>.nav-item[data-url=manage]';
|
||||||
it('is not visible to unprivileged users', function() {
|
it('is not visible to unprivileged users', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: false}),
|
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: false}),
|
||||||
hasManagedTopic: true
|
hasManagedTopic: true
|
||||||
});
|
});
|
||||||
@@ -241,7 +241,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('is not visible when there are no managed topics', function() {
|
it('is not visible when there are no managed topics', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true}),
|
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true}),
|
||||||
hasManagedTopic: false
|
hasManagedTopic: false
|
||||||
});
|
});
|
||||||
@@ -249,7 +249,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('is visible to privileged users when there is a managed topic', function() {
|
it('is visible to privileged users when there is a managed topic', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true}),
|
userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true}),
|
||||||
hasManagedTopic: true
|
hasManagedTopic: true
|
||||||
});
|
});
|
||||||
@@ -260,7 +260,7 @@ define([
|
|||||||
describe('Browse Tab', function() {
|
describe('Browse Tab', function() {
|
||||||
var browseTabSelector = '.page-content-nav>.nav-item[data-url=browse]';
|
var browseTabSelector = '.page-content-nav>.nav-item[data-url=browse]';
|
||||||
it('is not visible if there are no open and no public teamsets', function() {
|
it('is not visible if there are no open and no public teamsets', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
hasOpenTopic: false,
|
hasOpenTopic: false,
|
||||||
hasPublicManagedTopic: false
|
hasPublicManagedTopic: false
|
||||||
});
|
});
|
||||||
@@ -268,7 +268,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('is visible if there are open teamsets', function() {
|
it('is visible if there are open teamsets', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
hasOpenTopic: true,
|
hasOpenTopic: true,
|
||||||
hasPublicManagedTopic: false
|
hasPublicManagedTopic: false
|
||||||
});
|
});
|
||||||
@@ -276,7 +276,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('is visible if there are public teamsets', function() {
|
it('is visible if there are public teamsets', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
hasOpenTopic: false,
|
hasOpenTopic: false,
|
||||||
hasPublicManagedTopic: true
|
hasPublicManagedTopic: true
|
||||||
});
|
});
|
||||||
@@ -284,7 +284,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('is visible if there are both public and open teamsets', function() {
|
it('is visible if there are both public and open teamsets', function() {
|
||||||
var teamsTabView = createTeamsTabView(this, {
|
var teamsTabView = createTeamsTabView({
|
||||||
hasOpenTopic: true,
|
hasOpenTopic: true,
|
||||||
hasPublicManagedTopic: true
|
hasPublicManagedTopic: true
|
||||||
});
|
});
|
||||||
@@ -293,39 +293,46 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Search', function() {
|
describe('Search', function() {
|
||||||
var performSearch = function(reqs, teamsTabView) {
|
var teamsTabView;
|
||||||
|
|
||||||
|
var performSearch = function() {
|
||||||
teamsTabView.$('.search-field').val('foo');
|
teamsTabView.$('.search-field').val('foo');
|
||||||
teamsTabView.$('.action-search').click();
|
teamsTabView.$('.action-search').click();
|
||||||
verifyTeamsRequest({
|
verifyTeamsRequest({
|
||||||
order_by: '',
|
order_by: '',
|
||||||
text_search: 'foo'
|
text_search: 'foo'
|
||||||
});
|
});
|
||||||
AjaxHelpers.respondWithJson(reqs, TeamSpecHelpers.createMockTeamsResponse({results: []}));
|
AjaxHelpers.respondWithJson(
|
||||||
|
requests,
|
||||||
|
TeamSpecHelpers.createMockTeamsResponse({ results: [] }
|
||||||
|
));
|
||||||
|
AjaxHelpers.respondWithJson(requests, { count: 0 });
|
||||||
|
|
||||||
// Expect exactly one search request to be fired
|
// Expect exactly one search request to be fired, and one request to see if the user is
|
||||||
AjaxHelpers.expectNoRequests(reqs);
|
// in a team in the current teamset
|
||||||
|
AjaxHelpers.expectNoRequests(requests);
|
||||||
};
|
};
|
||||||
|
|
||||||
it('can search teams', function() {
|
beforeEach(function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
teamsTabView = createTeamsTabView();
|
||||||
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
|
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
|
||||||
verifyTeamsRequest({
|
verifyTeamsRequest({
|
||||||
order_by: 'last_activity_at',
|
order_by: 'last_activity_at',
|
||||||
text_search: ''
|
text_search: ''
|
||||||
});
|
});
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
AjaxHelpers.respondWithJson(requests, {});
|
||||||
performSearch(requests, teamsTabView);
|
AjaxHelpers.respondWithJson(requests, { count: 0 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can search teams', function() {
|
||||||
|
performSearch();
|
||||||
expect(teamsTabView.$('.page-title').text()).toBe('Team Search');
|
expect(teamsTabView.$('.page-title').text()).toBe('Team Search');
|
||||||
expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"');
|
expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can clear a search', function() {
|
it('can clear a search', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
|
||||||
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
|
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
|
||||||
|
|
||||||
// Perform a search
|
// Perform a search
|
||||||
performSearch(requests, teamsTabView);
|
performSearch();
|
||||||
|
|
||||||
// Clear the search and submit it again
|
// Clear the search and submit it again
|
||||||
teamsTabView.$('.search-field').val('');
|
teamsTabView.$('.search-field').val('');
|
||||||
@@ -335,17 +342,14 @@ define([
|
|||||||
order_by: 'last_activity_at'
|
order_by: 'last_activity_at'
|
||||||
});
|
});
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
AjaxHelpers.respondWithJson(requests, {});
|
||||||
|
AjaxHelpers.respondWithJson(requests, { count: 0 });
|
||||||
expect(teamsTabView.$('.page-title').text()).toBe('Test Topic 1');
|
expect(teamsTabView.$('.page-title').text()).toBe('Test Topic 1');
|
||||||
expect(teamsTabView.$('.page-description').text()).toBe('Test description 1');
|
expect(teamsTabView.$('.page-description').text()).toBe('Test description 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can navigate back to all teams from a search', function() {
|
it('can navigate back to all teams from a search', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
|
||||||
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
|
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
|
||||||
|
|
||||||
// Perform a search
|
// Perform a search
|
||||||
performSearch(requests, teamsTabView);
|
performSearch();
|
||||||
|
|
||||||
// Verify the breadcrumbs have a link back to the teams list, and click on it
|
// Verify the breadcrumbs have a link back to the teams list, and click on it
|
||||||
expect(teamsTabView.$('.breadcrumbs a').length).toBe(2);
|
expect(teamsTabView.$('.breadcrumbs a').length).toBe(2);
|
||||||
@@ -355,15 +359,12 @@ define([
|
|||||||
text_search: ''
|
text_search: ''
|
||||||
});
|
});
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
AjaxHelpers.respondWithJson(requests, {});
|
||||||
|
AjaxHelpers.respondWithJson(requests, { count: 0 });
|
||||||
expect(teamsTabView.$('.page-title').text()).toBe('Test Topic 1');
|
expect(teamsTabView.$('.page-title').text()).toBe('Test Topic 1');
|
||||||
expect(teamsTabView.$('.page-description').text()).toBe('Test description 1');
|
expect(teamsTabView.$('.page-description').text()).toBe('Test description 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not switch to showing results when the search returns an error', function() {
|
it('does not switch to showing results when the search returns an error', function() {
|
||||||
var teamsTabView = createTeamsTabView(this);
|
|
||||||
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
|
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
|
||||||
|
|
||||||
// Perform a search but respond with a 500
|
// Perform a search but respond with a 500
|
||||||
teamsTabView.$('.search-field').val('foo');
|
teamsTabView.$('.search-field').val('foo');
|
||||||
teamsTabView.$('.action-search').click();
|
teamsTabView.$('.action-search').click();
|
||||||
|
|||||||
@@ -2,33 +2,69 @@ define([
|
|||||||
'backbone',
|
'backbone',
|
||||||
'underscore',
|
'underscore',
|
||||||
'teams/js/views/topic_teams',
|
'teams/js/views/topic_teams',
|
||||||
|
'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
|
||||||
'teams/js/spec_helpers/team_spec_helpers',
|
'teams/js/spec_helpers/team_spec_helpers',
|
||||||
'common/js/spec_helpers/page_helpers'
|
'common/js/spec_helpers/page_helpers'
|
||||||
], function(Backbone, _, TopicTeamsView, TeamSpecHelpers, PageHelpers) {
|
], function(Backbone, _, TopicTeamsView, AjaxHelpers, TeamSpecHelpers, PageHelpers) {
|
||||||
'use strict';
|
'use strict';
|
||||||
describe('Topic Teams View', function() {
|
describe('Topic Teams View', function() {
|
||||||
var createTopicTeamsView = function(options, isInstructorManagedTopic) {
|
var requests, teamsView;
|
||||||
options = options || {}; // eslint-disable-line no-param-reassign
|
|
||||||
return new TopicTeamsView({
|
var verifyTeamsetTeamsRequest = function(hasTeams) {
|
||||||
|
AjaxHelpers.expectRequestURL(
|
||||||
|
requests,
|
||||||
|
TeamSpecHelpers.testContext.teamMembershipsUrl,
|
||||||
|
{
|
||||||
|
username: TeamSpecHelpers.testUser,
|
||||||
|
course_id: TeamSpecHelpers.testCourseID,
|
||||||
|
teamset_id: TeamSpecHelpers.testTopicID,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
AjaxHelpers.respondWithJson(
|
||||||
|
requests,
|
||||||
|
{ count: hasTeams ? 1 : 0 }
|
||||||
|
);
|
||||||
|
AjaxHelpers.expectNoRequests(requests);
|
||||||
|
};
|
||||||
|
|
||||||
|
var createTopicTeamsView = function(_options) {
|
||||||
|
var options = _options || {};
|
||||||
|
var onTeamInTeamset = options.onTeamInTeamset || false,
|
||||||
|
isInstructorManagedTopic = options.isInstructorManagedTopic || false;
|
||||||
|
|
||||||
|
var result, topicTeamsView;
|
||||||
|
|
||||||
|
requests = AjaxHelpers.requests(this);
|
||||||
|
topicTeamsView = new TopicTeamsView({
|
||||||
el: '.teams-container',
|
el: '.teams-container',
|
||||||
model: isInstructorManagedTopic ?
|
model: isInstructorManagedTopic ?
|
||||||
TeamSpecHelpers.createMockInstructorManagedTopic() : TeamSpecHelpers.createMockTopic(),
|
TeamSpecHelpers.createMockInstructorManagedTopic() : TeamSpecHelpers.createMockTopic(),
|
||||||
collection: options.teams || TeamSpecHelpers.createMockTeams({results: []}),
|
collection: options.teams || TeamSpecHelpers.createMockTeams({results: []}),
|
||||||
myTopicTeamsCollection: (
|
|
||||||
options.myTopicTeamsCollection || TeamSpecHelpers.createMockTeams({results: []})
|
|
||||||
),
|
|
||||||
context: _.extend({}, TeamSpecHelpers.testContext, options)
|
context: _.extend({}, TeamSpecHelpers.testContext, options)
|
||||||
}).render();
|
});
|
||||||
|
result = topicTeamsView.render();
|
||||||
|
|
||||||
|
if (
|
||||||
|
topicTeamsView.context.userInfo.staff ||
|
||||||
|
topicTeamsView.context.userInfo.privileged ||
|
||||||
|
isInstructorManagedTopic
|
||||||
|
) {
|
||||||
|
AjaxHelpers.expectNoRequests(requests);
|
||||||
|
} else {
|
||||||
|
verifyTeamsetTeamsRequest(onTeamInTeamset);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var verifyActions = function(teamsView, options) {
|
var verifyActions = function(showActions) {
|
||||||
var expectedTitle = 'Are you having trouble finding a team to join?',
|
var expectedTitle = 'Are you having trouble finding a team to join?',
|
||||||
expectedMessage = 'Browse teams in other topics or search teams in this topic. ' +
|
expectedMessage = 'Browse teams in other topics or search teams in this topic. ' +
|
||||||
'If you still can\'t find a team to join, create a new team in this topic.',
|
'If you still can\'t find a team to join, create a new team in this topic.',
|
||||||
title = teamsView.$('.title').text().trim(),
|
title = teamsView.$('.title').text().trim(),
|
||||||
message = teamsView.$('.copy').text().trim();
|
message = teamsView.$('.copy').text().trim(),
|
||||||
options = options || {showActions: true}; // eslint-disable-line no-param-reassign
|
_showActions = showActions === undefined ? true : showActions;
|
||||||
if (options.showActions) {
|
|
||||||
|
if (_showActions) {
|
||||||
expect(title).toBe(expectedTitle);
|
expect(title).toBe(expectedTitle);
|
||||||
expect(message).toBe(expectedMessage);
|
expect(message).toBe(expectedMessage);
|
||||||
} else {
|
} else {
|
||||||
@@ -49,32 +85,35 @@ define([
|
|||||||
results: testTeamData
|
results: testTeamData
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
var teamsView = createTopicTeamsView(options);
|
var footerEl;
|
||||||
var footerEl = teamsView.$('.teams-paging-footer');
|
|
||||||
|
teamsView = createTopicTeamsView(options);
|
||||||
|
footerEl = teamsView.$('.teams-paging-footer');
|
||||||
|
|
||||||
expect(teamsView.$('.teams-paging-header').text()).toMatch('Showing 1-5 out of 6 total');
|
expect(teamsView.$('.teams-paging-header').text()).toMatch('Showing 1-5 out of 6 total');
|
||||||
expect(footerEl.text()).toMatch('1\\s+out of\\s+\/\\s+2'); // eslint-disable-line no-useless-escape
|
expect(footerEl.text()).toMatch('1\\s+out of\\s+\/\\s+2'); // eslint-disable-line no-useless-escape
|
||||||
expect(footerEl).not.toHaveClass('hidden');
|
expect(footerEl).not.toHaveClass('hidden');
|
||||||
|
|
||||||
TeamSpecHelpers.verifyCards(teamsView, testTeamData);
|
TeamSpecHelpers.verifyCards(teamsView, testTeamData);
|
||||||
verifyActions(teamsView);
|
verifyActions();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can browse all teams', function() {
|
it('can browse all teams', function() {
|
||||||
var teamsView = createTopicTeamsView();
|
teamsView = createTopicTeamsView();
|
||||||
spyOn(Backbone.history, 'navigate');
|
spyOn(Backbone.history, 'navigate');
|
||||||
teamsView.$('.browse-teams').click();
|
teamsView.$('.browse-teams').click();
|
||||||
expect(Backbone.history.navigate.calls.mostRecent().args[0]).toBe('browse');
|
expect(Backbone.history.navigate.calls.mostRecent().args[0]).toBe('browse');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gives the search field focus when clicking on the search teams link', function() {
|
it('gives the search field focus when clicking on the search teams link', function() {
|
||||||
var teamsView = createTopicTeamsView();
|
teamsView = createTopicTeamsView();
|
||||||
spyOn($.fn, 'focus').and.callThrough();
|
spyOn($.fn, 'focus').and.callThrough();
|
||||||
teamsView.$('.search-teams').click();
|
teamsView.$('.search-teams').click();
|
||||||
expect(teamsView.$('.search-field').first().focus).toHaveBeenCalled();
|
expect(teamsView.$('.search-field').first().focus).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can show the create team modal', function() {
|
it('can show the create team modal', function() {
|
||||||
var teamsView = createTopicTeamsView();
|
teamsView = createTopicTeamsView();
|
||||||
spyOn(Backbone.history, 'navigate');
|
spyOn(Backbone.history, 'navigate');
|
||||||
teamsView.$('a.create-team').click();
|
teamsView.$('a.create-team').click();
|
||||||
expect(Backbone.history.navigate.calls.mostRecent().args[0]).toBe(
|
expect(Backbone.history.navigate.calls.mostRecent().args[0]).toBe(
|
||||||
@@ -83,14 +122,13 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not show actions for a user already in a team in the teamset', function() {
|
it('does not show actions for a user already in a team in the teamset', function() {
|
||||||
var options = {myTopicTeamsCollection: TeamSpecHelpers.createMockTeams()};
|
teamsView = createTopicTeamsView({ onTeamInTeamset: true });
|
||||||
var teamsView = createTopicTeamsView(options);
|
verifyActions(false);
|
||||||
verifyActions(teamsView, {showActions: false});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show actions for a student in an instructor managed topic', function() {
|
it('does not show actions for a student in an instructor managed topic', function() {
|
||||||
var teamsView = createTopicTeamsView({}, true);
|
teamsView = createTopicTeamsView({ isInstructorManagedTopic: true });
|
||||||
verifyActions(teamsView, {showActions: false});
|
verifyActions(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows actions for a privileged user already in a team', function() {
|
it('shows actions for a privileged user already in a team', function() {
|
||||||
@@ -99,10 +137,10 @@ define([
|
|||||||
privileged: true,
|
privileged: true,
|
||||||
staff: false
|
staff: false
|
||||||
},
|
},
|
||||||
myTopicTeamsCollection: TeamSpecHelpers.createMockTeams()
|
onTeamInTeamset: true,
|
||||||
};
|
};
|
||||||
var teamsView = createTopicTeamsView(options);
|
teamsView = createTopicTeamsView(options);
|
||||||
verifyActions(teamsView, {showActions: true});
|
verifyActions();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows actions for a staff user already in a team', function() {
|
it('shows actions for a staff user already in a team', function() {
|
||||||
@@ -111,10 +149,10 @@ define([
|
|||||||
privileged: false,
|
privileged: false,
|
||||||
staff: true
|
staff: true
|
||||||
},
|
},
|
||||||
myTopicTeamsCollection: TeamSpecHelpers.createMockTeams()
|
onTeamInTeamset: true,
|
||||||
};
|
};
|
||||||
var teamsView = createTopicTeamsView(options);
|
teamsView = createTopicTeamsView(options);
|
||||||
verifyActions(teamsView, {showActions: true});
|
verifyActions();
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -123,7 +161,7 @@ define([
|
|||||||
var requests = AjaxHelpers.requests(this),
|
var requests = AjaxHelpers.requests(this),
|
||||||
teamMemberships = TeamSpecHelpers.createMockTeamMemberships([]),
|
teamMemberships = TeamSpecHelpers.createMockTeamMemberships([]),
|
||||||
teamsView = createTopicTeamsView({ teamMemberships: teamMemberships });
|
teamsView = createTopicTeamsView({ teamMemberships: teamMemberships });
|
||||||
verifyActions(teamsView, {showActions: true});
|
verifyActions({showActions: true});
|
||||||
teamMemberships.teamEvents.trigger('teams:update', { action: 'create' });
|
teamMemberships.teamEvents.trigger('teams:update', { action: 'create' });
|
||||||
teamsView.render();
|
teamsView.render();
|
||||||
AjaxHelpers.expectRequestURL(
|
AjaxHelpers.expectRequestURL(
|
||||||
@@ -138,7 +176,7 @@ define([
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
AjaxHelpers.respondWithJson(requests, {});
|
AjaxHelpers.respondWithJson(requests, {});
|
||||||
verifyActions(teamsView, {showActions: false});
|
verifyActions({showActions: false});
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -380,24 +380,11 @@
|
|||||||
createTeamsListView: function(options) {
|
createTeamsListView: function(options) {
|
||||||
var topic = options.topic,
|
var topic = options.topic,
|
||||||
collection = options.collection,
|
collection = options.collection,
|
||||||
myTopicTeamsCollection = new TeamCollection(
|
|
||||||
this.context.userInfo.teams,
|
|
||||||
{
|
|
||||||
teamEvents: this.teamEvents,
|
|
||||||
course_id: this.context.courseID,
|
|
||||||
username: this.context.userInfo.username,
|
|
||||||
topic_id: topic.get('id'),
|
|
||||||
perPage: 5,
|
|
||||||
parse: true,
|
|
||||||
url: this.context.myTeamsUrl
|
|
||||||
}
|
|
||||||
),
|
|
||||||
teamsView = new TopicTeamsView({
|
teamsView = new TopicTeamsView({
|
||||||
router: this.router,
|
router: this.router,
|
||||||
context: this.context,
|
context: this.context,
|
||||||
model: topic,
|
model: topic,
|
||||||
collection: collection,
|
collection: collection,
|
||||||
myTopicTeamsCollection: myTopicTeamsCollection,
|
|
||||||
showSortControls: options.showSortControls
|
showSortControls: options.showSortControls
|
||||||
}),
|
}),
|
||||||
searchFieldView = new SearchFieldView({
|
searchFieldView = new SearchFieldView({
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
'use strict';
|
'use strict';
|
||||||
define([
|
define([
|
||||||
|
'jquery',
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'gettext',
|
'gettext',
|
||||||
@@ -9,7 +10,34 @@
|
|||||||
'common/js/components/views/paging_header',
|
'common/js/components/views/paging_header',
|
||||||
'text!teams/templates/team-actions.underscore',
|
'text!teams/templates/team-actions.underscore',
|
||||||
'teams/js/views/team_utils'
|
'teams/js/views/team_utils'
|
||||||
], function(_, Backbone, gettext, HtmlUtils, TeamsView, PagingHeader, teamActionsTemplate, TeamUtils) {
|
], function($, _, Backbone, gettext, HtmlUtils, TeamsView, PagingHeader, teamActionsTemplate, TeamUtils) {
|
||||||
|
// Translators: this string is shown at the bottom of the teams page
|
||||||
|
// to find a team to join or else to create a new one. There are three
|
||||||
|
// links that need to be included in the message:
|
||||||
|
// 1. Browse teams in other topics
|
||||||
|
// 2. search teams
|
||||||
|
// 3. create a new team
|
||||||
|
// Be careful to start each link with the appropriate start indicator
|
||||||
|
// (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
||||||
|
var actionMessage = interpolate_text( // eslint-disable-line no-undef
|
||||||
|
_.escape(gettext(
|
||||||
|
'{browse_span_start}Browse teams in other ' +
|
||||||
|
'topics{span_end} or {search_span_start}search teams{span_end} ' +
|
||||||
|
'in this topic. If you still can\'t find a team to join, ' +
|
||||||
|
'{create_span_start}create a new team in this topic{span_end}.'
|
||||||
|
)),
|
||||||
|
{
|
||||||
|
browse_span_start: '<a class="browse-teams" href="">',
|
||||||
|
search_span_start: '<a class="search-teams" href="">',
|
||||||
|
create_span_start: '<a class="create-team" href="">',
|
||||||
|
span_end: '</a>'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var canUserCreateTeamErrorMessage = gettext(
|
||||||
|
'An error occurred while looking up team membership. Try refreshing the page.'
|
||||||
|
);
|
||||||
|
|
||||||
var TopicTeamsView = TeamsView.extend({
|
var TopicTeamsView = TeamsView.extend({
|
||||||
events: {
|
events: {
|
||||||
'click a.browse-teams': 'browseTeams',
|
'click a.browse-teams': 'browseTeams',
|
||||||
@@ -24,51 +52,48 @@
|
|||||||
TeamsView.prototype.initialize.call(this, options);
|
TeamsView.prototype.initialize.call(this, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
canUserCreateTeam: function() {
|
checkIfUserCanCreateTeam: function() {
|
||||||
// Note: non-staff and non-privileged users are automatically added to any team
|
var deferred = $.Deferred();
|
||||||
// that they create. This means that if multiple team membership is
|
if (this.context.userInfo.staff || this.context.userInfo.privileged) {
|
||||||
// disabled that they cannot create a new team when they already
|
deferred.resolve(true);
|
||||||
// belong to one.
|
} else if (TeamUtils.isInstructorManagedTopic(this.model.attributes.type)) {
|
||||||
return this.context.userInfo.staff
|
deferred.resolve(false);
|
||||||
|| this.context.userInfo.privileged
|
} else {
|
||||||
|| (!TeamUtils.isInstructorManagedTopic(this.model.attributes.type)
|
$.ajax({
|
||||||
&& this.options.myTopicTeamsCollection.length === 0);
|
type: 'GET',
|
||||||
|
url: this.context.teamMembershipsUrl,
|
||||||
|
data: {
|
||||||
|
username: this.context.userInfo.username,
|
||||||
|
course_id: this.context.courseID,
|
||||||
|
teamset_id: this.model.get('id')
|
||||||
|
}
|
||||||
|
}).done(function(data) {
|
||||||
|
deferred.resolve(data.count === 0);
|
||||||
|
}).fail(function(data) {
|
||||||
|
TeamUtils.parseAndShowMessage(data, canUserCreateTeamErrorMessage);
|
||||||
|
deferred.resolve(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return deferred.promise();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
showActions: function() {
|
||||||
|
HtmlUtils.append(
|
||||||
|
this.$el,
|
||||||
|
HtmlUtils.template(teamActionsTemplate)({message: actionMessage})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var self = this;
|
this.collection.refresh().done(_.bind(function() {
|
||||||
this.collection.refresh().done(function() {
|
TeamsView.prototype.render.call(this);
|
||||||
var message;
|
this.checkIfUserCanCreateTeam().done(_.bind(function(canUserCreateTeam) {
|
||||||
TeamsView.prototype.render.call(self);
|
if (canUserCreateTeam) {
|
||||||
if (self.canUserCreateTeam()) {
|
this.showActions();
|
||||||
message = interpolate_text( // eslint-disable-line no-undef
|
}
|
||||||
// Translators: this string is shown at the bottom of the teams page
|
}, this));
|
||||||
// to find a team to join or else to create a new one. There are three
|
}, this));
|
||||||
// links that need to be included in the message:
|
|
||||||
// 1. Browse teams in other topics
|
|
||||||
// 2. search teams
|
|
||||||
// 3. create a new team
|
|
||||||
// Be careful to start each link with the appropriate start indicator
|
|
||||||
// (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
|
||||||
_.escape(gettext(
|
|
||||||
'{browse_span_start}Browse teams in other ' +
|
|
||||||
'topics{span_end} or {search_span_start}search teams{span_end} ' +
|
|
||||||
'in this topic. If you still can\'t find a team to join, ' +
|
|
||||||
'{create_span_start}create a new team in this topic{span_end}.'
|
|
||||||
)),
|
|
||||||
{
|
|
||||||
browse_span_start: '<a class="browse-teams" href="">',
|
|
||||||
search_span_start: '<a class="search-teams" href="">',
|
|
||||||
create_span_start: '<a class="create-team" href="">',
|
|
||||||
span_end: '</a>'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
HtmlUtils.append(
|
|
||||||
self.$el,
|
|
||||||
HtmlUtils.template(teamActionsTemplate)({message: message})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user