I've changed the logic so that AjaxHelpers keeps track of which requests have not yet had mock responses sent. This ensures that every response is handled before moving on to the next one, rather than always handling the last request. My intention is that this won't allow bugs to creep in where a request isn't fired and instead the test responds to an old request. It also should ensure that extra events aren't accidentally fired.
393 lines
18 KiB
JavaScript
393 lines
18 KiB
JavaScript
define([
|
|
"jquery",
|
|
"common/js/spec_helpers/ajax_helpers",
|
|
"URI",
|
|
"js/views/paging",
|
|
"js/views/paging_header",
|
|
"common/js/components/collections/paging_collection"
|
|
], function ($, AjaxHelpers, URI, PagingView, PagingHeader, PagingCollection) {
|
|
|
|
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,
|
|
current_page: 0,
|
|
count: 4,
|
|
page: 0,
|
|
start: 0
|
|
};
|
|
var mockSecondPage = {
|
|
results: [
|
|
createPageableItem(4)
|
|
],
|
|
num_pages: 2,
|
|
page_size: 3,
|
|
current_page: 1,
|
|
count: 4,
|
|
page: 1,
|
|
start: 3
|
|
};
|
|
var mockEmptyPage = {
|
|
results: [],
|
|
num_pages: 1,
|
|
page_size: 3,
|
|
current_page: 0,
|
|
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;
|
|
|
|
beforeEach(function () {
|
|
var collection = new PagingCollection();
|
|
collection.isZeroIndexed = true;
|
|
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.currentPage).toBe(0);
|
|
pagingView.setPage(2);
|
|
respondWithMockItems(requests);
|
|
expect(pagingView.collection.currentPage).toBe(1);
|
|
});
|
|
|
|
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);
|
|
expect(pagingView.collection.currentPage).toBe(0);
|
|
});
|
|
});
|
|
|
|
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.currentPage).toBe(0);
|
|
});
|
|
|
|
it('can move to the next page', function () {
|
|
var requests = AjaxHelpers.requests(this);
|
|
pagingView.setPage(1);
|
|
respondWithMockItems(requests);
|
|
pagingView.nextPage();
|
|
respondWithMockItems(requests);
|
|
expect(pagingView.collection.currentPage).toBe(1);
|
|
});
|
|
|
|
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.currentPage).toBe(0);
|
|
});
|
|
|
|
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.currentPage).toBe(1);
|
|
});
|
|
});
|
|
|
|
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.currentPage).toBe(0);
|
|
});
|
|
|
|
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.currentPage).toBe(1);
|
|
});
|
|
|
|
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(0);
|
|
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.currentPage).toBe(1);
|
|
});
|
|
|
|
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.currentPage).toBe(0);
|
|
});
|
|
|
|
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');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|