define(['jquery', 'URI', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/js/components/utils/view_utils', 'js/views/xblock', 'js/models/xblock_info', 'xmodule', 'cms/js/main', 'xblock/cms.runtime.v1'], function($, URI, AjaxHelpers, ViewUtils, XBlockView, XBlockInfo) { 'use strict'; describe('XBlockView', function() { var model, xblockView, mockXBlockHtml; beforeEach(function() { model = new XBlockInfo({ id: 'testCourse/branch/draft/block/verticalFFF', display_name: 'Test Unit', category: 'vertical' }); xblockView = new XBlockView({ model: model }); }); mockXBlockHtml = readFixtures('mock/mock-xblock.underscore'); it('can render a nested xblock', function() { var requests = AjaxHelpers.requests(this); xblockView.render(); AjaxHelpers.respondWithJson(requests, { html: mockXBlockHtml, resources: [] }); expect(xblockView.$el.select('.xblock-header')).toBeTruthy(); }); describe('XBlock rendering', function() { var postXBlockRequest; postXBlockRequest = function(requests, resources) { var promise; $.ajax({ url: 'test_url', type: 'GET', success: function(fragment) { promise = xblockView.renderXBlockFragment(fragment, this.$el); } }); // Note: this mock response will call the AJAX success function synchronously // so the promise variable defined above will be available. AjaxHelpers.respondWithJson(requests, { html: mockXBlockHtml, resources: resources }); expect(xblockView.$el.select('.xblock-header')).toBeTruthy(); return promise; }; it('can render an xblock with no CSS or JavaScript', function() { var requests = AjaxHelpers.requests(this); postXBlockRequest(requests, []); }); it('can render an xblock with required CSS', function() { var requests = AjaxHelpers.requests(this), mockCssText = '// Just a comment', mockCssUrl = 'mock.css', headHtml; postXBlockRequest(requests, [ ['xblock_spec_hash1', {mimetype: 'text/css', kind: 'text', data: mockCssText}], ['xblock_spec_hash2', {mimetype: 'text/css', kind: 'url', data: mockCssUrl}] ]); headHtml = $('head').html(); expect(headHtml).toContain(mockCssText); expect(headHtml).toContain(mockCssUrl); }); it('can render an xblock with required JavaScript', function() { var requests = AjaxHelpers.requests(this); postXBlockRequest(requests, [ ['xblock_spec_hash3', { mimetype: 'application/javascript', kind: 'text', data: 'window.test = 100;' }] ]); expect(window.test).toBe(100); }); it('can render an xblock with required HTML', function() { var requests = AjaxHelpers.requests(this), mockHeadTag = 'Test Title'; postXBlockRequest(requests, [ ['xblock_spec_hash4', {mimetype: 'text/html', placement: 'head', data: mockHeadTag}] ]); expect($('head').html()).toContain(mockHeadTag); }); it('aborts rendering when a dependent script fails to load', function() { var requests = AjaxHelpers.requests(this), missingJavaScriptUrl = 'no_such_file.js', promise; spyOn(ViewUtils, 'loadJavaScript').and.returnValue($.Deferred().reject().promise()); promise = postXBlockRequest(requests, [ ['xblock_spec_hash5', { mimetype: 'application/javascript', kind: 'url', data: missingJavaScriptUrl }] ]); expect(promise.state()).toBe('rejected'); }); it('Triggers an event to the runtime when a notification-action-button is clicked', function() { var notifySpy = spyOn(xblockView, 'notifyRuntime').and.callThrough(); postXBlockRequest(AjaxHelpers.requests(this), []); xblockView.$el.find('.notification-action-button').click(); expect(notifySpy).toHaveBeenCalledWith('add-missing-groups', model.get('id')); }); }); }); });