'use strict'; import CMS, { Helpers, KEYS } from '../../../static/cms/js/modules/cms.base'; import Sideframe from '../../../static/cms/js/modules/cms.sideframe'; import Messages from '../../../static/cms/js/modules/cms.messages'; import $ from 'jquery'; import Toolbar from '../../../static/cms/js/modules/cms.toolbar'; import Modal from '../../../static/cms/js/modules/cms.modal'; import { rewire, resetRewire } from './helpers/rewire'; vi.mock('../../../static/cms/js/modules/loader', async () => { const { lazyMock, registerActual } = await import('./helpers/rewire'); registerActual('loader', await vi.importActual('../../../static/cms/js/modules/loader')); return lazyMock('loader', { showLoader: 'showLoader', hideLoader: 'hideLoader' }); }); vi.mock('../../../static/cms/js/modules/cms.modal', async () => { const { lazyMock, registerActual } = await import('./helpers/rewire'); registerActual('cms.modal', await vi.importActual('../../../static/cms/js/modules/cms.modal')); return lazyMock('cms.modal', { default: 'Modal' }); }); vi.mock('../../../static/cms/js/modules/cms.sideframe', async () => { const { lazyMock, registerActual } = await import('./helpers/rewire'); registerActual('cms.sideframe', await vi.importActual('../../../static/cms/js/modules/cms.sideframe')); return lazyMock('cms.sideframe', { default: 'Sideframe' }); }); vi.mock('../../../static/cms/js/modules/cms.navigation', async () => { const { lazyMock, registerActual } = await import('./helpers/rewire'); registerActual('cms.navigation', await vi.importActual('../../../static/cms/js/modules/cms.navigation')); return lazyMock('cms.navigation', { default: 'Navigation' }); }); vi.mock('../../../static/cms/js/modules/dom-diff', async () => { const { lazyMock, registerActual } = await import('./helpers/rewire'); registerActual('dom-diff', await vi.importActual('../../../static/cms/js/modules/dom-diff')); return lazyMock('dom-diff', { DiffDOM: 'DiffDOM', nodeToObj: 'nodeToObj' }); }); CMS.API = CMS.API || {}; CMS.API.Helpers = Helpers; CMS.KEYS = KEYS; window.CMS = CMS; CMS.Toolbar = Toolbar; CMS.Modal = Modal; CMS.Sideframe = Sideframe; CMS.Messages = Messages; var showLoader; var hideLoader; class Navigation {} describe('CMS.Toolbar', function () { fixture.setBase('cms/tests/frontend/unit/fixtures'); beforeEach(() => { showLoader = jasmine.createSpy(); hideLoader = jasmine.createSpy(); rewire('showLoader', showLoader); rewire('hideLoader', hideLoader); rewire('Navigation', Navigation); }); afterEach(() => { resetRewire('Navigation'); resetRewire('showLoader'); resetRewire('hideLoader'); }); it('creates a Toolbar class', function () { expect(CMS.Toolbar).toBeDefined(); }); it('has public API', function () { expect(CMS.Toolbar.prototype.showLoader).toEqual(jasmine.any(Function)); expect(CMS.Toolbar.prototype.hideLoader).toEqual(jasmine.any(Function)); expect(CMS.Toolbar.prototype.openAjax).toEqual(jasmine.any(Function)); }); describe('instance', function () { var toolbar; beforeEach(function (done) { fixture.load('toolbar.html'); $(function () { spyOn(CMS.Toolbar.prototype, '_initialStates'); toolbar = new CMS.Toolbar(); spyOn(toolbar, 'setSettings').and.callFake(function (input) { return $.extend(true, CMS.settings, input); }); done(); }); }); afterEach(function () { fixture.cleanup(); }); it('has ui', function () { expect(toolbar.ui).toEqual(jasmine.any(Object)); expect(Object.keys(toolbar.ui)).toContain('container'); expect(Object.keys(toolbar.ui)).toContain('body'); expect(Object.keys(toolbar.ui)).toContain('window'); expect(Object.keys(toolbar.ui)).toContain('document'); expect(Object.keys(toolbar.ui)).toContain('toolbar'); expect(Object.keys(toolbar.ui)).toContain('navigations'); expect(Object.keys(toolbar.ui)).toContain('buttons'); expect(Object.keys(toolbar.ui)).toContain('messages'); expect(Object.keys(toolbar.ui)).toContain('structureBoard'); expect(Object.keys(toolbar.ui)).toContain('revert'); expect(Object.keys(toolbar.ui).length).toEqual(11); }); it('has options', function () { expect(toolbar.options).toEqual({ toolbarDuration: 200 }); var toolbar2 = new CMS.Toolbar({ toolbarDuration: 250, nonExistent: true }); expect(toolbar2.options).toEqual({ toolbarDuration: 250, nonExistent: true }); }); // this spec can be thoroughly expanded, but for the moment just checking for the // class and event is sufficient it('initializes the states', function (done) { CMS.Toolbar.prototype._initialStates.and.callThrough(); CMS.Toolbar.prototype._initialStates.calls.reset(); CMS.settings = { sideframe_enabled: true, sideframe: {}, version: 'fake' }; CMS.config = { settings: { version: 'fake' }, auth: true }; toolbar.ui.document.on('cms-ready', function () { // expect this to happen done(); }); toolbar = new CMS.Toolbar(); expect(CMS.Toolbar.prototype._initialStates).toHaveBeenCalled(); expect(toolbar.ui.body).toHaveClass('cms-ready'); }); it('sets the "ready" data on the toolbar ui', function () { expect(toolbar.ui.toolbar.data('ready')).toEqual(true); toolbar.ui.toolbar.data('ready', false); new CMS.Toolbar(); expect(toolbar.ui.toolbar.data('ready')).toEqual(true); }); }); describe('.openAjax()', function () { var toolbar; beforeEach(function (done) { // the module reaches for CMS.API.StructureBoard; karma had it left over // from another spec file CMS.API.StructureBoard = { invalidateState: jasmine.createSpy() }; fixture.load('toolbar.html'); CMS.config = {}; CMS.settings = $.extend(CMS.settings, { toolbar: 'expanded' }); jasmine.Ajax.install(); $(function () { spyOn(CMS.Toolbar.prototype, '_initialStates'); toolbar = new CMS.Toolbar(); spyOn(toolbar, 'setSettings').and.callFake(function (input) { return $.extend(true, CMS.settings, input); }); done(); }); }); afterEach(function () { jasmine.Ajax.uninstall(); fixture.cleanup(); }); it('makes the request', function () { expect(toolbar.openAjax({ url: '/url' })).toEqual(jasmine.any(Object)); var request = jasmine.Ajax.requests.mostRecent(); expect(request.url).toEqual('/url'); }); it('does not make the request if there is a confirmation that is not succeeded', function () { spyOn(CMS.API.Helpers, 'secureConfirm').and.callFake(function (question) { expect(question).toEqual('Are you sure?'); return false; }); expect(toolbar.openAjax({ url: '/url', text: 'Are you sure?' })).toEqual(false); }); it('shows the loader before making the request', function () { expect(toolbar.openAjax({ url: '/url' })).toEqual(jasmine.any(Object)); expect(showLoader).toHaveBeenCalled(); }); it('uses custom callback after request succeeds and hides the loader', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback('response'); return { fail: $.noop }; } }; }); var callback = jasmine.createSpy(); toolbar.openAjax({ url: '/url', callback: callback }); expect(callback).toHaveBeenCalled(); expect(callback).toHaveBeenCalledWith(toolbar, 'response'); expect(hideLoader).toHaveBeenCalled(); }); it('does not hide the loader if no callback provided', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback('response'); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); toolbar.openAjax({ url: '/url', onSuccess: '/another-url' }); expect(showLoader).toHaveBeenCalled(); expect(hideLoader).not.toHaveBeenCalled(); }); it('uses custom onSuccess url from request success', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback({ url: '/redirect-url' }); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); toolbar.openAjax({ url: '/url', onSuccess: 'FOLLOW_REDIRECT' }); expect(CMS.API.Helpers.reloadBrowser).toHaveBeenCalledWith('/redirect-url'); }); it('uses custom onSuccess url after request succeeds', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback('response'); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); toolbar.openAjax({ url: '/url', onSuccess: '/another-url' }); expect(CMS.API.Helpers.reloadBrowser).toHaveBeenCalledWith('/another-url'); }); it('reloads the page if no callback or onSuccess passed', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback('response'); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); toolbar.openAjax({ url: '/url' }); expect(CMS.API.Helpers.reloadBrowser).toHaveBeenCalledWith(); }); it('evaluates a JSON data bridge from the response instead of reloading', function () { var dataBridge = { action: 'edit', plugin_id: 1 }; spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback(dataBridge); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); spyOn(CMS.API.Helpers, 'onPluginSave'); toolbar.openAjax({ url: '/url' }); expect(CMS.API.StructureBoard.invalidateState).toHaveBeenCalled(); expect(CMS.API.Helpers.reloadBrowser).not.toHaveBeenCalled(); expect(hideLoader).toHaveBeenCalled(); }); it('evaluates an HTML data bridge from the response instead of reloading', function () { var dataBridge = { action: 'delete', plugin_id: 2 }; var html = '' + ''; spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback(html); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); spyOn(CMS.API.Helpers, 'onPluginSave'); toolbar.openAjax({ url: '/url' }); expect(CMS.API.StructureBoard.invalidateState).toHaveBeenCalled(); expect(CMS.API.Helpers.reloadBrowser).not.toHaveBeenCalled(); }); it('reloads if the response is a JSON object without a valid data bridge', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback({ foo: 'bar' }); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); spyOn(CMS.API.Helpers, 'onPluginSave'); toolbar.openAjax({ url: '/url' }); expect(CMS.API.Helpers.onPluginSave).not.toHaveBeenCalled(); expect(CMS.API.Helpers.reloadBrowser).toHaveBeenCalledWith(); }); it('reloads if the HTML response does not contain a data bridge', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback('no bridge here'); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); spyOn(CMS.API.Helpers, 'onPluginSave'); toolbar.openAjax({ url: '/url' }); expect(CMS.API.Helpers.onPluginSave).not.toHaveBeenCalled(); expect(CMS.API.Helpers.reloadBrowser).toHaveBeenCalledWith(); }); it('handles parameters', function () { spyOn($, 'ajax').and.callFake(function (param) { expect(param.data).toEqual({ param1: true, param2: false, param3: 150, param4: 'alala' }); return { done: function () { return { fail: $.noop }; } }; }); toolbar.openAjax({ url: '/whatever', post: JSON.stringify({ param1: true, param2: false, param3: 150, param4: 'alala' }) }); }); it('opens an error message if request failed', function () { CMS.API.Messages = new CMS.Messages(); spyOn(CMS.API.Messages, 'open'); spyOn($, 'ajax').and.callFake(function () { return { done: function () { return { fail: function (callback) { callback({ responseText: 'An error occurred', status: 418, statusText: "I'm a teapot" }); } }; } }; }); toolbar.openAjax({ url: '/whatever' }); expect(CMS.API.Messages.open).toHaveBeenCalledWith({ message: "An error occurred | 418 I'm a teapot", error: true }); }); it('unlocks the toolbar if request succeeds', function () { spyOn($, 'ajax').and.callFake(function () { return { done: function (callback) { callback('response'); return { fail: $.noop }; } }; }); spyOn(CMS.API.Helpers, 'reloadBrowser'); CMS.API.locked = true; toolbar.openAjax({ url: '/url' }); expect(CMS.API.locked).toEqual(false); CMS.API.locked = true; toolbar.openAjax({ url: '/url', callback: $.noop }); expect(CMS.API.locked).toEqual(false); CMS.API.locked = true; toolbar.openAjax({ url: '/url', onSuccess: '/another-url' }); expect(CMS.API.locked).toEqual(false); }); it('unlocks the toolbar if request fails', function () { CMS.API.Messages = new CMS.Messages(); spyOn(CMS.API.Messages, 'open'); spyOn($, 'ajax').and.callFake(function () { return { done: function () { return { fail: function (callback) { callback({ responseText: 'An error occurred', status: 418, statusText: "I'm a teapot" }); } }; } }; }); CMS.API.locked = true; toolbar.openAjax({ url: '/whatever' }); expect(CMS.API.locked).toEqual(false); }); }); describe('._events()', function () { var toolbar; beforeEach(function (done) { fixture.load('toolbar.html'); CMS.config = { lang: { publish: 'publish?' } }; CMS.settings = $.extend(CMS.settings, { toolbar: 'expanded' }); $(function () { spyOn(CMS.Toolbar.prototype, '_initialStates'); toolbar = new CMS.Toolbar(); spyOn(toolbar, 'setSettings').and.callFake(function (input) { return $.extend(true, CMS.settings, input); }); done(); }); }); afterEach(function () { fixture.cleanup(); }); it('attaches event handlers to navigation menu links', function () { spyOn(toolbar, '_delegate'); var emptyLink = $(toolbar.ui.navigations[0]).find('a').eq(0); var pagesLink = $(toolbar.ui.navigations[0]).find('a').eq(1); emptyLink.trigger('click'); expect(toolbar._delegate).not.toHaveBeenCalled(); pagesLink.trigger('click'); expect(toolbar._delegate).toHaveBeenCalledTimes(1); expect(toolbar._delegate).toHaveBeenCalledWith(pagesLink); }); it('attaches event handlers to navigation menu links (to open in new window)', function () { var fakeWindow = { open: jasmine.createSpy() }; spyOn(toolbar, '_delegate'); spyOn(CMS.API.Helpers, '_getWindow').and.callFake(function () { return fakeWindow; }); var emptyLink = $(toolbar.ui.navigations[0]).find('a').eq(0); var pagesLink = $(toolbar.ui.navigations[0]).find('a').eq(1); emptyLink.trigger(new $.Event('keydown', { keyCode: CMS.KEYS.CTRL })); emptyLink.trigger('click'); expect(toolbar._delegate).not.toHaveBeenCalled(); expect(fakeWindow.open).not.toHaveBeenCalled(); emptyLink.trigger(new $.Event('keydown', { keyCode: CMS.KEYS.CTRL })); pagesLink.trigger('click'); expect(toolbar._delegate).not.toHaveBeenCalledTimes(1); expect(fakeWindow.open).toHaveBeenCalledWith(jasmine.stringMatching('cms/page'), '_blank'); pagesLink.trigger('keyup'); }); it('attaches event handlers to navigation menu lists', function () { var firstMenuItem = $(toolbar.ui.navigations.find('> li')[0]); toolbar.ui.structureBoard = $('
'); expect(toolbar.ui.document).not.toHandle(toolbar.click); expect(toolbar.ui.structureBoard).not.toHandle(toolbar.click); expect(toolbar.ui.toolbar).not.toHandle(toolbar.click); expect(toolbar.ui.window).not.toHandle(toolbar.resize + '.menu.reset'); firstMenuItem.trigger('click'); expect(toolbar.ui.document).toHandle(toolbar.click); expect(toolbar.ui.structureBoard).toHandle(toolbar.click); expect(toolbar.ui.toolbar).toHandle(toolbar.click); expect(toolbar.ui.window).toHandle(toolbar.resize + '.menu.reset'); }); it('handles mousemove over top level toolbar items', function () { var firstMenuItem = $(toolbar.ui.navigations.find('> li')[0]); var secondMenuItem = $(toolbar.ui.navigations.find('> li')[1]); var thirdMenuItem = $(toolbar.ui.navigations.find('> li')[2]); firstMenuItem.trigger('click'); var clickFirstMenuItem = spyOnEvent(firstMenuItem, toolbar.click); var clickSecondMenuItem = spyOnEvent(secondMenuItem, toolbar.click); var clickThirdMenuItem = spyOnEvent(thirdMenuItem, toolbar.click); firstMenuItem.trigger('mouseenter'); expect(clickFirstMenuItem).not.toHaveBeenTriggered(); secondMenuItem.trigger('mouseenter'); expect(clickSecondMenuItem).toHaveBeenTriggered(); thirdMenuItem.trigger('mouseenter'); expect(clickThirdMenuItem).toHaveBeenTriggered(); }); it('does not care for mouse over top level items if touch is enabled', function () { var firstMenuItem = $(toolbar.ui.navigations.find('> li')[0]); var secondMenuItem = $(toolbar.ui.navigations.find('> li')[1]); firstMenuItem.find('a').trigger('touchstart'); firstMenuItem.trigger('click'); var clickFirstMenuItem = spyOnEvent(firstMenuItem, toolbar.click); var clickSecondMenuItem = spyOnEvent(secondMenuItem, toolbar.click); firstMenuItem.trigger('mouseenter'); expect(clickFirstMenuItem).not.toHaveBeenTriggered(); secondMenuItem.trigger('mouseenter'); expect(clickSecondMenuItem).not.toHaveBeenTriggered(); }); it('closes the menu item if it is open', function () { var firstMenuItem = $(toolbar.ui.navigations.find('> li')[0]); firstMenuItem.trigger('click'); expect(firstMenuItem).toHaveClass('cms-toolbar-item-navigation-hover'); firstMenuItem.trigger('click'); expect(firstMenuItem).not.toHaveClass('cms-toolbar-item-navigation-hover'); }); it('handles mousemove over nested toolbar items', function () { var menuItem = $(toolbar.ui.navigations.find('> li')[1]); var subMenu = menuItem.find('> ul'); var childrenSubMenuItem = subMenu.find('> li').eq(0); spyOn($.fn, 'show').and.callThrough(); expect(childrenSubMenuItem.find('> ul')).not.toBeVisible(); childrenSubMenuItem.trigger('pointerover'); expect($.fn.show).toHaveBeenCalledTimes(1); expect($.fn.show.calls.mostRecent().object).toEqual(childrenSubMenuItem.find('> ul')); }); it('attaches event handlers to buttons with data-rel', function () { spyOn(toolbar, '_delegate'); var createButton = toolbar.ui.buttons.eq(0).find('a'); createButton.trigger(toolbar.click); expect(toolbar._delegate).toHaveBeenCalled(); }); it('attaches event handlers to buttons without data-rel', function () { var createButton = toolbar.ui.buttons.eq(1).find('a:first'); spyOn($.Event.prototype, 'stopPropagation'); createButton.trigger(toolbar.click); expect($.Event.prototype.stopPropagation).toHaveBeenCalled(); }); }); describe('._delegate()', function () { var toolbar; var fakeWindow; class FakeModal { constructor() {} } class FakeSideframe { constructor(opts) { this.constructorOpts = opts; } open() {} } beforeEach(function (done) { fixture.load('toolbar.html'); CMS.config = {}; CMS.settings = $.extend(CMS.settings, { toolbar: 'expanded' }); fakeWindow = { location: { href: '', pathname: '/context.html', search: '' } }; $(function () { spyOn(CMS.Toolbar.prototype, '_initialStates'); toolbar = new CMS.Toolbar(); rewire('Modal', FakeModal); rewire('Sideframe', FakeSideframe); spyOn(toolbar, 'openAjax'); spyOn(CMS.API.Helpers, '_getWindow').and.returnValue(fakeWindow); spyOn(CMS.API.Messages, 'open'); spyOn(toolbar, 'setSettings').and.callFake(function (input) { return $.extend(true, CMS.settings, input); }); done(); }); }); afterEach(function (done) { resetRewire('Modal'); resetRewire('Sideframe'); fixture.cleanup(); setTimeout(function () { done(); }, 200); }); it('return false if item is disabled', function () { expect(toolbar._delegate($('
'))).toEqual(false); }); it('opens modal if item is "modal"', function () { var modalOpen = jasmine.createSpy(); FakeModal.prototype.open = modalOpen; toolbar._delegate($('
')); expect(modalOpen).toHaveBeenCalledWith({ url: 'href?cms_path=%2Fcontext.html&_popup=1', title: 'modal' }); }); it('opens sideframe if item is "sideframe"', function () { var sideframeOpen = jasmine.createSpy(); spyOn(FakeSideframe.prototype, 'open').and.callFake(sideframeOpen); toolbar._delegate( $('
') ); // Check that a Sideframe was constructed with onClose option // (we can't easily check this with the spy, but we can verify open was called) expect(sideframeOpen).toHaveBeenCalledWith({ url: 'href2', animate: true }); }); it('sideframe disabled defaults to redirecting to the url', function () { // Set the switch to disable the sideframe CMS.settings = $.extend(true, CMS.settings, { sideframe_enabled: false }); expect(fakeWindow.location.href).toEqual(''); toolbar._delegate( $('
') ); expect(fakeWindow.location.href).toEqual('disabled-sideframe-href'); // Reset the switch to enable the sideframe for other tests CMS.settings = $.extend(true, CMS.settings, { sideframe_enabled: true }); }); it('opens message if item is "message"', function () { toolbar._delegate($('
')); expect(CMS.API.Messages.open).toHaveBeenCalledWith({ message: 'message!' }); }); it('opens ajax request if item is "ajax"', function () { toolbar._delegate( $('
') ); expect(toolbar.openAjax).toHaveBeenCalledWith({ url: 'href', post: '{"test":"shmest"}', text: 'text', method: undefined, onSuccess: 'REFRESH' }); }); it('just redirects to the page if nothing else', function () { expect(fakeWindow.location.href).toEqual(''); toolbar._delegate( $('
') ); expect(fakeWindow.location.href).toEqual('href'); }); describe('POST requests', function () { var hostileToken = '">'; var hostileHref = '/publish/">'; beforeEach(function () { fakeWindow.document = document; CMS.config.csrf = 'fallback-token'; // Has to be the first form in the document so that the token // lookup picks it up. $('
') .prependTo('body') .find('input') .val(hostileToken); spyOn(window.HTMLFormElement.prototype, 'submit'); }); afterEach(function () { $('form.cms-post-request-test').remove(); }); it('treats href and token as values, not as markup', function () { toolbar._sendPostRequest($('').attr('href', hostileHref)); var form = $('body > form').last().addClass('cms-post-request-test'); expect(window.HTMLFormElement.prototype.submit).toHaveBeenCalled(); expect(form.attr('action')).toEqual(hostileHref); expect(form.attr('method')).toEqual('POST'); expect(form.find('input[name="csrfmiddlewaretoken"]').val()).toEqual(hostileToken); // Nothing was parsed as HTML, so no elements were injected. expect(form.find('img').length).toEqual(0); expect($('img.injected-href, img.injected-token').length).toEqual(0); }); }); }); describe('._debug()', function () { var toolbar; beforeEach(function (done) { fixture.load('toolbar.html'); CMS.config = { lang: { debug: 'DEBUG!' } }; CMS.settings = $.extend(CMS.settings, { toolbar: 'expanded' }); $(function () { spyOn(CMS.Toolbar.prototype, '_initialStates'); toolbar = new CMS.Toolbar(); toolbar.ui.container.append('
'); spyOn(toolbar, 'setSettings').and.callFake(function (input) { return $.extend(true, CMS.settings, input); }); spyOn(CMS.API.Messages, 'open'); jasmine.clock().install(); done(); }); }); afterEach(function (done) { jasmine.clock().uninstall(); fixture.cleanup(); setTimeout(function () { done(); }, 200); }); it('shows debug information after timeout', function () { toolbar._debug(); toolbar.ui.container.find('.cms-debug-bar').trigger(toolbar.mouseEnter); jasmine.clock().tick(10000); expect(CMS.API.Messages.open).toHaveBeenCalledWith({ message: 'DEBUG!' }); }); it('does not show debug information if not hovering after timeout', function () { toolbar._debug(); toolbar.ui.container.find('.cms-debug-bar').trigger(toolbar.mouseEnter); jasmine.clock().tick(500); toolbar.ui.container.find('.cms-debug-bar').trigger(toolbar.mouseLeave); jasmine.clock().tick(10000); expect(CMS.API.Messages.open).not.toHaveBeenCalled(); }); }); describe('_refreshMarkup', () => { const diffDOMConstructor = jasmine.createSpy(); const newToolbar = $('
'); let toolbar; class DiffDOM { constructor() { diffDOMConstructor(); } } DiffDOM.prototype.diff = jasmine.createSpy(); DiffDOM.prototype.apply = jasmine.createSpy(); const trigger = jasmine.createSpy(); class FakeNavigation { constructor() { this.ui = { window: { trigger } }; } } beforeEach(function (done) { fixture.load('toolbar.html'); CMS.config = { lang: { debug: 'DEBUG!' } }; CMS.settings = $.extend(CMS.settings, { toolbar: 'expanded' }); $(function () { rewire('Navigation', FakeNavigation); rewire('DiffDOM', DiffDOM); spyOn(CMS.Toolbar.prototype, '_initialStates'); toolbar = new CMS.Toolbar(); spyOn(toolbar, 'setSettings').and.callFake(function (input) { return $.extend(true, CMS.settings, input); }); spyOn(toolbar, '_setupUI'); spyOn(toolbar, '_events'); CMS.API.Clipboard = { ui: {}, _toolbarEvents: jasmine.createSpy() }; jasmine.clock().install(); done(); }); }); afterEach(function (done) { jasmine.clock().uninstall(); resetRewire('Navigation'); resetRewire('DiffDOM'); fixture.cleanup(); setTimeout(function () { done(); }, 200); }); it('refreshes markup', () => { toolbar.navigation = null; toolbar._refreshMarkup(newToolbar); expect(toolbar._setupUI).toHaveBeenCalledTimes(1); expect(toolbar._events).toHaveBeenCalledTimes(1); expect(toolbar.navigation instanceof FakeNavigation).toEqual(true); expect(trigger).toHaveBeenCalledWith('resize'); expect(CMS.API.Clipboard._toolbarEvents).toHaveBeenCalledTimes(1); }); it('only takes markup from the first matched toolbar', () => { // Callers search a whole refreshed page for .cms-toolbar, so the // collection can contain an element authored in editable content. const toolbars = $( '
' + '
' ); toolbar._refreshMarkup(toolbars); expect(toolbar.ui.toolbar.find('.official-item').length).toEqual(1); expect(toolbar.ui.toolbar.find('.injected-item').length).toEqual(0); }); }); });