273 lines
12 KiB
JavaScript
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');
|
|
});
|
|
});
|
|
|
|
});
|
|
});
|