Files
edx-platform/cms/static/js/spec/views/paging_spec.js
2023-05-09 13:53:54 +05:00

401 lines
17 KiB
JavaScript

define([
'jquery',
'URI',
'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
'edx-ui-toolkit/js/pagination/paging-collection',
'js/views/paging',
'js/views/paging_header'
],
function($, URI, AjaxHelpers, PagingCollection, PagingView, PagingHeader) {
'use strict';
var createPageableItem = function(index) {
var id = 'item_' + index;
return {
id: id,
display_name: id,
url: id
};
};
var mockFirstPage = {
results: [
createPageableItem(1),
createPageableItem(2),
createPageableItem(3)
],
num_pages: 2,
page_size: 3,
count: 4,
page: 0,
start: 0
};
var mockSecondPage = {
results: [
createPageableItem(4)
],
num_pages: 2,
page_size: 3,
page: 1,
count: 4,
start: 3
};
var mockEmptyPage = {
results: [],
num_pages: 1,
page_size: 3,
count: 0,
page: 0,
start: 0
};
var respondWithMockItems = function(requests) {
var request = AjaxHelpers.currentRequest(requests);
var url = new URI(request.url);
var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value
var page = queryParameters.page;
var response = page === '0' ? mockFirstPage : mockSecondPage;
AjaxHelpers.respondWithJson(requests, response);
};
var MockPagingView = PagingView.extend({
renderPageItems: function() {},
initialize: function() {
this.registerSortableColumn('name-col', 'Name', 'name', 'asc');
this.registerSortableColumn('date-col', 'Date', 'date', 'desc');
this.setInitialSortColumn('date-col');
}
});
describe('Paging', function() {
var pagingView,
TestPagingCollection = PagingCollection.extend({
state: {
firstPage: 0,
currentPage: null,
pageSize: 3
}
});
beforeEach(function() {
var collection = new TestPagingCollection();
collection.url = '/dummy/';
pagingView = new MockPagingView({collection: collection});
});
describe('PagingView', function() {
describe('setPage', function() {
it('can set the current page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
expect(pagingView.collection.getPageNumber()).toBe(1);
pagingView.setPage(2);
respondWithMockItems(requests);
expect(pagingView.collection.getPageNumber()).toBe(2);
});
it('should not change page after a server error', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
pagingView.setPage(2);
requests[1].respond(500);
/* PagingCollection sets the currentPage to the old page in case of failure */
expect(pagingView.collection.getPageNumber()).toBe(1);
});
});
describe('nextPage', function() {
it('does not move forward after a server error', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
pagingView.nextPage();
requests[1].respond(500);
expect(pagingView.collection.getPageNumber()).toBe(1);
});
it('can move to the next page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
pagingView.nextPage();
respondWithMockItems(requests);
/* PagingCollection now returns the normalized page number; adds one if zero indexed */
expect(pagingView.collection.getPageNumber()).toBe(2);
});
it('can not move forward from the final page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
pagingView.nextPage();
AjaxHelpers.expectNoRequests(requests);
});
});
describe('previousPage', function() {
it('can move back a page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
pagingView.previousPage();
respondWithMockItems(requests);
expect(pagingView.collection.getPageNumber()).toBe(1);
});
it('can not move back from the first page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
pagingView.previousPage();
AjaxHelpers.expectNoRequests(requests);
});
it('does not move back after a server error', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
pagingView.previousPage();
requests[1].respond(500);
expect(pagingView.collection.getPageNumber()).toBe(2);
});
});
describe('toggleSortOrder', function() {
it('can toggle direction of the current sort', function() {
var requests = AjaxHelpers.requests(this);
expect(pagingView.collection.sortDirection).toBe('desc');
pagingView.toggleSortOrder('date-col');
respondWithMockItems(requests);
expect(pagingView.collection.sortDirection).toBe('asc');
pagingView.toggleSortOrder('date-col');
respondWithMockItems(requests);
expect(pagingView.collection.sortDirection).toBe('desc');
});
it('sets the correct default sort direction for a column', function() {
var requests = AjaxHelpers.requests(this);
pagingView.toggleSortOrder('name-col');
respondWithMockItems(requests);
expect(pagingView.sortDisplayName()).toBe('Name');
expect(pagingView.collection.sortDirection).toBe('asc');
pagingView.toggleSortOrder('date-col');
respondWithMockItems(requests);
expect(pagingView.sortDisplayName()).toBe('Date');
expect(pagingView.collection.sortDirection).toBe('desc');
});
});
describe('sortableColumnInfo', function() {
it('returns the registered info for a column', function() {
pagingView.registerSortableColumn('test-col', 'Test Column', 'testField', 'asc');
var sortInfo = pagingView.sortableColumnInfo('test-col');
expect(sortInfo.displayName).toBe('Test Column');
expect(sortInfo.fieldName).toBe('testField');
expect(sortInfo.defaultSortDirection).toBe('asc');
});
it('throws an exception for an unregistered column', function() {
expect(function() {
pagingView.sortableColumnInfo('no-such-column');
}).toThrow();
});
});
});
describe('PagingHeader', function() {
var pagingHeader;
beforeEach(function() {
pagingHeader = new PagingHeader({view: pagingView});
});
describe('Next page button', function() {
beforeEach(function() {
// Render the page and header so that they can react to events
pagingView.render();
pagingHeader.render();
});
it('does not move forward if a server error occurs', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
pagingHeader.$('.next-page-link').click();
requests[1].respond(500);
expect(pagingView.collection.state.currentPage).toBe(0);
expect(pagingView.collection.getPageNumber()).toBe(1);
});
it('can move to the next page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
pagingHeader.$('.next-page-link').click();
respondWithMockItems(requests);
expect(pagingView.collection.getPageNumber()).toBe(2);
});
it('should be enabled when there is at least one more page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
expect(pagingHeader.$('.next-page-link')).not.toHaveClass('is-disabled');
});
it('should be disabled on the final page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
expect(pagingHeader.$('.next-page-link')).toHaveClass('is-disabled');
});
it('should be disabled on an empty page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
AjaxHelpers.respondWithJson(requests, mockEmptyPage);
expect(pagingHeader.$('.next-page-link')).toHaveClass('is-disabled');
});
});
describe('Previous page button', function() {
beforeEach(function() {
// Render the page and header so that they can react to events
pagingView.render();
pagingHeader.render();
});
it('does not move back if a server error occurs', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
pagingHeader.$('.previous-page-link').click();
requests[1].respond(500);
expect(pagingView.collection.getPageNumber()).toBe(2);
});
it('can go back a page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
pagingHeader.$('.previous-page-link').click();
respondWithMockItems(requests);
expect(pagingView.collection.getPageNumber()).toBe(1);
});
it('should be disabled on the first page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
expect(pagingHeader.$('.previous-page-link')).toHaveClass('is-disabled');
});
it('should be enabled on the second page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
expect(pagingHeader.$('.previous-page-link')).not.toHaveClass('is-disabled');
});
it('should be disabled for an empty page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
AjaxHelpers.respondWithJson(requests, mockEmptyPage);
expect(pagingHeader.$('.previous-page-link')).toHaveClass('is-disabled');
});
});
describe('Page metadata section', function() {
it('shows the correct metadata for the current page', function() {
var requests = AjaxHelpers.requests(this),
message;
pagingView.setPage(1);
respondWithMockItems(requests);
message = pagingHeader.$('.meta').html().trim();
expect(message).toBe('<p>Showing <span class="count-current-shown">1-3</span>'
+ ' out of <span class="count-total">4 total</span>, '
+ 'sorted by <span class="sort-order">Date</span> descending</p>');
});
it('shows the correct metadata when sorted ascending', function() {
var requests = AjaxHelpers.requests(this),
message;
pagingView.setPage(1);
pagingView.toggleSortOrder('name-col');
respondWithMockItems(requests);
message = pagingHeader.$('.meta').html().trim();
expect(message).toBe('<p>Showing <span class="count-current-shown">1-3</span>'
+ ' out of <span class="count-total">4 total</span>, '
+ 'sorted by <span class="sort-order">Name</span> ascending</p>');
});
});
describe('Item count label', function() {
it('should show correct count on first page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
expect(pagingHeader.$('.count-current-shown')).toHaveHtml('1-3');
});
it('should show correct count on second page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
expect(pagingHeader.$('.count-current-shown')).toHaveHtml('4-4');
});
it('should show correct count for an empty collection', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
AjaxHelpers.respondWithJson(requests, mockEmptyPage);
expect(pagingHeader.$('.count-current-shown')).toHaveHtml('0-0');
});
});
describe('Item total label', function() {
it('should show correct total on the first page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
expect(pagingHeader.$('.count-total')).toHaveText('4 total');
});
it('should show correct total on the second page', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(2);
respondWithMockItems(requests);
expect(pagingHeader.$('.count-total')).toHaveText('4 total');
});
it('should show zero total for an empty collection', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
AjaxHelpers.respondWithJson(requests, mockEmptyPage);
expect(pagingHeader.$('.count-total')).toHaveText('0 total');
});
});
describe('Sort order label', function() {
it('should show correct initial sort order', function() {
var requests = AjaxHelpers.requests(this);
pagingView.setPage(1);
respondWithMockItems(requests);
expect(pagingHeader.$('.sort-order')).toHaveText('Date');
});
it('should show updated sort order', function() {
var requests = AjaxHelpers.requests(this);
pagingView.toggleSortOrder('name-col');
respondWithMockItems(requests);
expect(pagingHeader.$('.sort-order')).toHaveText('Name');
});
});
});
});
});