From 58b5cbda25288c29ed699a632c7d294f5f709a43 Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Sat, 28 Jan 2017 10:48:57 -0500 Subject: [PATCH] Add ability to pass a title and show the close button on a modal (#10069) * Add ability to pass a title and show the close button on a modal * address code review comments - Clean up tests and add some new ones - Default onClose to onCancel if nothing is supplied. --- .../public/modals/__tests__/confirm_modal.js | 186 ++++++++++++++++++ src/ui/public/modals/confirm_modal.html | 12 ++ src/ui/public/modals/confirm_modal.js | 23 ++- 3 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 src/ui/public/modals/__tests__/confirm_modal.js diff --git a/src/ui/public/modals/__tests__/confirm_modal.js b/src/ui/public/modals/__tests__/confirm_modal.js new file mode 100644 index 0000000000000..3332028848e69 --- /dev/null +++ b/src/ui/public/modals/__tests__/confirm_modal.js @@ -0,0 +1,186 @@ +import angular from 'angular'; +import expect from 'expect.js'; +import ngMock from 'ng_mock'; +import sinon from 'sinon'; +import _ from 'lodash'; + +describe('ui/modals/confirm_modal', function () { + let confirmModal; + let $rootScope; + + beforeEach(function () { + ngMock.module('kibana'); + ngMock.inject(function ($injector) { + confirmModal = $injector.get('confirmModal'); + $rootScope = $injector.get('$rootScope'); + }); + }); + + function findByDataTestSubj(dataTestSubj) { + return angular.element(document.body).find(`[data-test-subj=${dataTestSubj}]`); + } + + afterEach(function () { + const confirmButton = findByDataTestSubj('confirmModalConfirmButton'); + if (confirmButton) { + angular.element(confirmButton).click(); + } + }); + + describe('throws an exception', function () { + it('when no custom confirm button passed', function () { + expect(() => confirmModal('hi', { onConfirm: _.noop })).to.throwError(); + }); + + it('when no custom noConfirm function is passed', function () { + expect(() => confirmModal('hi', { confirmButtonText: 'bye' })).to.throwError(); + }); + + it('when showClose is on but title is not given', function () { + const options = { customConfirmButton: 'b', onConfirm: _.noop, showClose: true }; + expect(() => confirmModal('hi', options)).to.throwError(); + }); + }); + + it('shows the message', function () { + const myMessage = 'Hi, how are you?'; + confirmModal(myMessage, { confirmButtonText: 'GREAT!', onConfirm: _.noop }); + + $rootScope.$digest(); + const message = findByDataTestSubj('confirmModalBodyText')[0].innerText; + expect(message).to.equal(myMessage); + }); + + describe('shows custom text', function () { + const confirmModalOptions = { + confirmButtonText: 'Troodon', + cancelButtonText: 'Dilophosaurus', + title: 'Dinosaurs', + onConfirm: _.noop + }; + + it('for confirm button', () => { + confirmModal('What\'s your favorite dinosaur?', confirmModalOptions); + $rootScope.$digest(); + const confirmButtonText = findByDataTestSubj('confirmModalConfirmButton')[0].innerText; + expect(confirmButtonText).to.equal('Troodon'); + }); + + it('for cancel button', () => { + confirmModal('What\'s your favorite dinosaur?', confirmModalOptions); + $rootScope.$digest(); + const cancelButtonText = findByDataTestSubj('confirmModalCancelButton')[0].innerText; + expect(cancelButtonText).to.equal('Dilophosaurus'); + }); + + it('for title text', () => { + confirmModal('What\'s your favorite dinosaur?', confirmModalOptions); + $rootScope.$digest(); + const titleText = findByDataTestSubj('confirmModalTitleText')[0].innerText; + expect(titleText).to.equal('Dinosaurs'); + }); + }); + + describe('x icon', function () { + it('is visible when showClose is true', function () { + const confirmModalOptions = { + confirmButtonText: 'bye', + onConfirm: _.noop, + showClose: true, + title: 'hi' + }; + confirmModal('hi', confirmModalOptions); + + $rootScope.$digest(); + const xIcon = findByDataTestSubj('confirmModalCloseButton'); + expect(xIcon.length).to.be(1); + }); + + it('is not visible when showClose is false', function () { + const confirmModalOptions = { + confirmButtonText: 'bye', + onConfirm: _.noop, + title: 'hi', + showClose: false + }; + confirmModal('hi', confirmModalOptions); + + $rootScope.$digest(); + const xIcon = findByDataTestSubj('confirmModalCloseButton'); + expect(xIcon.length).to.be(0); + }); + }); + + describe('callbacks are called:', function () { + const confirmCallback = sinon.spy(); + const closeCallback = sinon.spy(); + const cancelCallback = sinon.spy(); + + const confirmModalOptions = { + confirmButtonText: 'bye', + onConfirm: confirmCallback, + onCancel: cancelCallback, + onClose: closeCallback, + title: 'hi', + showClose: true + }; + + function resetSpyCounts() { + confirmCallback.reset(); + closeCallback.reset(); + cancelCallback.reset(); + } + + it('onClose', function () { + resetSpyCounts(); + confirmModal('hi', confirmModalOptions); + $rootScope.$digest(); + findByDataTestSubj('confirmModalCloseButton').click(); + + expect(closeCallback.called).to.be(true); + expect(confirmCallback.called).to.be(false); + expect(cancelCallback.called).to.be(false); + }); + + it('onCancel', function () { + resetSpyCounts(); + confirmModal('hi', confirmModalOptions); + $rootScope.$digest(); + findByDataTestSubj('confirmModalCancelButton').click(); + + expect(closeCallback.called).to.be(false); + expect(confirmCallback.called).to.be(false); + expect(cancelCallback.called).to.be(true); + }); + + it('onConfirm', function () { + resetSpyCounts(); + confirmModal('hi', confirmModalOptions); + $rootScope.$digest(); + findByDataTestSubj('confirmModalConfirmButton').click(); + + expect(closeCallback.called).to.be(false); + expect(confirmCallback.called).to.be(true); + expect(cancelCallback.called).to.be(false); + }); + + + it('onClose defaults to onCancel if not specified', function () { + resetSpyCounts(); + const confirmModalOptions = { + confirmButtonText: 'bye', + onConfirm: confirmCallback, + onCancel: cancelCallback, + title: 'hi', + showClose: true + }; + + confirmModal('hi', confirmModalOptions); + $rootScope.$digest(); + findByDataTestSubj('confirmModalCloseButton').click(); + + expect(confirmCallback.called).to.be(false); + expect(cancelCallback.called).to.be(true); + }); + }); +}); diff --git a/src/ui/public/modals/confirm_modal.html b/src/ui/public/modals/confirm_modal.html index 0b53b00051072..ad1b05dcd5b11 100644 --- a/src/ui/public/modals/confirm_modal.html +++ b/src/ui/public/modals/confirm_modal.html @@ -1,4 +1,16 @@
+
+
+ {{title}} +
+ +
+
{ destroy(); options.onConfirm(); @@ -49,6 +66,10 @@ module.factory('confirmModal', function ($rootScope, $compile) { destroy(); options.onCancel(); }; + confirmScope.onClose = () => { + destroy(); + options.onClose(); + }; const modalInstance = $compile(template)(confirmScope); modalPopover = new ModalOverlay(modalInstance);