Files
edx-platform/cms/static/js/spec/views/unit_spec.js
2014-06-04 16:14:13 +05:00

273 lines
12 KiB
JavaScript

define(["jquery", "underscore", "jasmine", "coffee/src/views/unit", "js/models/module_info",
"js/spec_helpers/create_sinon", "js/spec_helpers/edit_helpers", "jasmine-stealth"],
function ($, _, jasmine, UnitEditView, ModuleModel, create_sinon, edit_helpers) {
var requests, unitView, initialize, lastRequest, respondWithHtml, verifyComponents, i,
mockXBlockEditorHtml = readFixtures('mock/mock-xblock-editor.underscore');
respondWithHtml = function(html, requestIndex) {
create_sinon.respondWithJson(
requests,
{ html: html, "resources": [] },
requestIndex
);
};
initialize = function(test) {
var mockXBlockHtml = readFixtures('mock/mock-unit-page-xblock.underscore'),
mockChildContainerHtml = readFixtures('mock/mock-unit-page-child-container.underscore'),
model;
requests = create_sinon.requests(test);
model = new ModuleModel({
id: 'unit_locator',
state: 'draft'
});
unitView = new UnitEditView({
el: $('.main-wrapper'),
templates: edit_helpers.mockComponentTemplates,
model: model
});
// Respond with renderings for the two xblocks in the unit (the second is itself a child container)
respondWithHtml(mockXBlockHtml, 0);
respondWithHtml(mockChildContainerHtml, 1);
};
lastRequest = function() { return requests[requests.length - 1]; };
verifyComponents = function (unit, locators) {
var components = unit.$(".component");
expect(components.length).toBe(locators.length);
for (i = 0; i < locators.length; i++) {
expect($(components[i]).data('locator')).toBe(locators[i]);
}
};
beforeEach(function() {
edit_helpers.installMockXBlock();
// needed to stub out the ajax
window.analytics = jasmine.createSpyObj('analytics', ['track']);
window.course_location_analytics = jasmine.createSpy('course_location_analytics');
window.unit_location_analytics = jasmine.createSpy('unit_location_analytics');
});
afterEach(function () {
edit_helpers.uninstallMockXBlock();
});
describe("UnitEditView", function() {
beforeEach(function() {
edit_helpers.installEditTemplates();
appendSetFixtures(readFixtures('mock/mock-unit-page.underscore'));
});
describe('duplicateComponent', function() {
var clickDuplicate;
clickDuplicate = function (index) {
unitView.$(".duplicate-button")[index].click();
};
it('sends the correct JSON to the server', function () {
initialize(this);
clickDuplicate(0);
edit_helpers.verifyXBlockRequest(requests, {
"duplicate_source_locator": "loc_1",
"parent_locator": "unit_locator"
});
});
it('inserts duplicated component immediately after source upon success', function () {
initialize(this);
clickDuplicate(0);
create_sinon.respondWithJson(requests, {"locator": "duplicated_item"});
verifyComponents(unitView, ['loc_1', 'duplicated_item', 'loc_2']);
});
it('inserts duplicated component at end if source at end', function () {
initialize(this);
clickDuplicate(1);
create_sinon.respondWithJson(requests, {"locator": "duplicated_item"});
verifyComponents(unitView, ['loc_1', 'loc_2', 'duplicated_item']);
});
it('shows a notification while duplicating', function () {
var notificationSpy = edit_helpers.createNotificationSpy();
initialize(this);
clickDuplicate(0);
edit_helpers.verifyNotificationShowing(notificationSpy, /Duplicating/);
create_sinon.respondWithJson(requests, {"locator": "new_item"});
edit_helpers.verifyNotificationHidden(notificationSpy);
});
it('does not insert duplicated component upon failure', function () {
initialize(this);
clickDuplicate(0);
create_sinon.respondWithError(requests);
verifyComponents(unitView, ['loc_1', 'loc_2']);
});
});
describe('createNewComponent ', function () {
var clickNewComponent;
clickNewComponent = function () {
unitView.$(".new-component .new-component-type a.single-template").click();
};
it('sends the correct JSON to the server', function () {
initialize(this);
clickNewComponent();
edit_helpers.verifyXBlockRequest(requests, {
"category": "discussion",
"type": "discussion",
"parent_locator": "unit_locator"
});
});
it('inserts new component at end', function () {
initialize(this);
clickNewComponent();
create_sinon.respondWithJson(requests, {"locator": "new_item"});
verifyComponents(unitView, ['loc_1', 'loc_2', 'new_item']);
});
it('shows a notification while creating', function () {
var notificationSpy = edit_helpers.createNotificationSpy();
initialize(this);
clickNewComponent();
edit_helpers.verifyNotificationShowing(notificationSpy, /Adding/);
create_sinon.respondWithJson(requests, {"locator": "new_item"});
edit_helpers.verifyNotificationHidden(notificationSpy);
});
it('does not insert new component upon failure', function () {
initialize(this);
clickNewComponent();
create_sinon.respondWithError(requests);
verifyComponents(unitView, ['loc_1', 'loc_2']);
});
});
describe("Disabled edit/publish links during ajax call", function() {
var link, i,
draft_states = [
{
state: "draft",
selector: ".publish-draft"
},
{
state: "public",
selector: ".create-draft"
}
];
function test_link_disabled_during_ajax_call(draft_state) {
it("re-enables the " + draft_state.selector + " link once the ajax call returns", function() {
initialize(this);
link = $(draft_state.selector);
expect(link).not.toHaveClass('is-disabled');
link.click();
expect(link).toHaveClass('is-disabled');
create_sinon.respondWithError(requests);
expect(link).not.toHaveClass('is-disabled');
});
}
for (i = 0; i < draft_states.length; i++) {
test_link_disabled_during_ajax_call(draft_states[i]);
}
});
describe("Editing an xblock", function() {
var newDisplayName = 'New Display Name';
beforeEach(function () {
edit_helpers.installMockXBlock({
data: "<p>Some HTML</p>",
metadata: {
display_name: newDisplayName
}
});
});
afterEach(function() {
edit_helpers.uninstallMockXBlock();
edit_helpers.cancelModalIfShowing();
});
it('can show an edit modal for a child xblock', function() {
var editButtons;
initialize(this);
editButtons = unitView.$('.edit-button');
// The container renders two mock xblocks
expect(editButtons.length).toBe(2);
editButtons[1].click();
// Make sure that the correct xblock is requested to be edited
expect(lastRequest().url.startsWith('/xblock/loc_2/studio_view')).toBeTruthy();
create_sinon.respondWithJson(requests, {
html: mockXBlockEditorHtml,
resources: []
});
// Expect that a modal is shown with the correct title
expect(edit_helpers.isShowingModal()).toBeTruthy();
expect(edit_helpers.getModalTitle()).toBe('Editing: Test Child Container');
});
});
describe("Editing an xmodule", function() {
var mockXModuleEditor = readFixtures('mock/mock-xmodule-editor.underscore'),
newDisplayName = 'New Display Name';
beforeEach(function () {
edit_helpers.installMockXModule({
data: "<p>Some HTML</p>",
metadata: {
display_name: newDisplayName
}
});
});
afterEach(function() {
edit_helpers.uninstallMockXModule();
edit_helpers.cancelModalIfShowing();
});
it('can save changes to settings', function() {
var editButtons, modal, mockUpdatedXBlockHtml;
mockUpdatedXBlockHtml = readFixtures('mock/mock-updated-xblock.underscore');
initialize(this);
editButtons = unitView.$('.edit-button');
// The container renders two mock xblocks
expect(editButtons.length).toBe(2);
editButtons[1].click();
create_sinon.respondWithJson(requests, {
html: mockXModuleEditor,
resources: []
});
modal = $('.edit-xblock-modal');
// Click on the settings tab
modal.find('.settings-button').click();
// Change the display name's text
modal.find('.setting-input').text("Mock Update");
// Press the save button
modal.find('.action-save').click();
// Respond to the save
create_sinon.respondWithJson(requests, {
id: 'mock-id'
});
// Respond to the request to refresh
respondWithHtml(mockUpdatedXBlockHtml);
// Verify that the xblock was updated
expect(unitView.$('.mock-updated-content').text()).toBe('Mock Update');
});
});
});
});