diff options
| author | Patrick H. Lauke <[email protected]> | 2021-05-04 12:46:06 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-05-04 12:46:06 +0100 |
| commit | 8865a8ab1c7157ab81bf49afa62b75f36daee46d (patch) | |
| tree | 97ef78f2ea8e07aab50014176d061fe3c1d49134 /js/tests/unit/modal.spec.js | |
| parent | 018ee6a3b50b958ddb49657086cd9168abf5a485 (diff) | |
| parent | 7ea6578773cb1b7f5cfb8fb41321b3fa10349daf (diff) | |
| download | bootstrap-jo-docs-thanks-page.tar.xz bootstrap-jo-docs-thanks-page.zip | |
Merge branch 'main' into jo-docs-thanks-pagejo-docs-thanks-page
Diffstat (limited to 'js/tests/unit/modal.spec.js')
| -rw-r--r-- | js/tests/unit/modal.spec.js | 159 |
1 files changed, 98 insertions, 61 deletions
diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js index f645e9892..a09711b34 100644 --- a/js/tests/unit/modal.spec.js +++ b/js/tests/unit/modal.spec.js @@ -1,47 +1,30 @@ import Modal from '../../src/modal' import EventHandler from '../../src/dom/event-handler' +import { getWidth as getScrollBarWidth } from '../../src/util/scrollbar' /** Test helpers */ -import { getFixture, clearFixture, createEvent, jQueryMock } from '../helpers/fixture' +import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture' describe('Modal', () => { let fixtureEl - let style beforeAll(() => { fixtureEl = getFixture() - - // Enable the scrollbar measurer - const css = '.modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; }' - - style = document.createElement('style') - style.type = 'text/css' - style.appendChild(document.createTextNode(css)) - - document.head.appendChild(style) - - // Simulate scrollbars - document.documentElement.style.paddingRight = '16px' }) afterEach(() => { clearFixture() - + clearBodyAndDocument() document.body.classList.remove('modal-open') - document.body.removeAttribute('style') - document.body.removeAttribute('data-bs-padding-right') document.querySelectorAll('.modal-backdrop') .forEach(backdrop => { document.body.removeChild(backdrop) }) - - document.body.style.paddingRight = '0px' }) - afterAll(() => { - document.head.removeChild(style) - document.documentElement.style.paddingRight = '0px' + beforeEach(() => { + clearBodyAndDocument() }) describe('VERSION', () => { @@ -56,10 +39,30 @@ describe('Modal', () => { }) }) + describe('DATA_KEY', () => { + it('should return plugin data key', () => { + expect(Modal.DATA_KEY).toEqual('bs.modal') + }) + }) + + describe('constructor', () => { + it('should take care of element either passed as a CSS selector or DOM element', () => { + fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' + + const modalEl = fixtureEl.querySelector('.modal') + const modalBySelector = new Modal('.modal') + const modalByElement = new Modal(modalEl) + + expect(modalBySelector._element).toEqual(modalEl) + expect(modalByElement._element).toEqual(modalEl) + }) + }) + describe('toggle', () => { it('should toggle a modal', done => { fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' + document.documentElement.style.overflowY = 'scroll' const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl) const originalPadding = '0px' @@ -74,6 +77,7 @@ describe('Modal', () => { modalEl.addEventListener('hidden.bs.modal', () => { expect(document.body.getAttribute('data-bs-padding-right')).toBeNull() expect().nothing() + document.documentElement.style.overflowY = 'auto' done() }) @@ -86,25 +90,28 @@ describe('Modal', () => { '<div class="modal"><div class="modal-dialog"></div></div>' ].join('') + document.documentElement.style.overflowY = 'scroll' const fixedEl = fixtureEl.querySelector('.fixed-top') const originalPadding = Number.parseInt(window.getComputedStyle(fixedEl).paddingRight, 10) const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl) + const scrollBarWidth = getScrollBarWidth() modalEl.addEventListener('shown.bs.modal', () => { - const expectedPadding = originalPadding + modal._getScrollbarWidth() - const currentPadding = Number.parseInt(window.getComputedStyle(modalEl).paddingRight, 10) + const expectedPadding = originalPadding + scrollBarWidth + const currentPadding = Number.parseInt(window.getComputedStyle(fixedEl).paddingRight, 10) - expect(fixedEl.getAttribute('data-bs-padding-right')).toEqual('0px', 'original fixed element padding should be stored in data-bs-padding-right') + expect(fixedEl.getAttribute('data-bs-padding-right')).toEqual(`${originalPadding}px`, 'original fixed element padding should be stored in data-bs-padding-right') expect(currentPadding).toEqual(expectedPadding, 'fixed element padding should be adjusted while opening') modal.toggle() }) modalEl.addEventListener('hidden.bs.modal', () => { - const currentPadding = Number.parseInt(window.getComputedStyle(modalEl).paddingRight, 10) + const currentPadding = Number.parseInt(window.getComputedStyle(fixedEl).paddingRight, 10) - expect(fixedEl.getAttribute('data-bs-padding-right')).toEqual(null, 'data-bs-padding-right should be cleared after closing') + expect(fixedEl.hasAttribute('data-bs-padding-right')).toEqual(false, 'data-bs-padding-right should be cleared after closing') expect(currentPadding).toEqual(originalPadding, 'fixed element padding should be reset after closing') + document.documentElement.style.overflowY = 'auto' done() }) @@ -117,16 +124,19 @@ describe('Modal', () => { '<div class="modal"><div class="modal-dialog"></div></div>' ].join('') + document.documentElement.style.overflowY = 'scroll' + const stickyTopEl = fixtureEl.querySelector('.sticky-top') const originalMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10) const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl) + const scrollBarWidth = getScrollBarWidth() modalEl.addEventListener('shown.bs.modal', () => { - const expectedMargin = originalMargin - modal._getScrollbarWidth() + const expectedMargin = originalMargin - scrollBarWidth const currentMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10) - expect(stickyTopEl.getAttribute('data-bs-margin-right')).toEqual('0px', 'original sticky element margin should be stored in data-bs-margin-right') + expect(stickyTopEl.getAttribute('data-bs-margin-right')).toEqual(`${originalMargin}px`, 'original sticky element margin should be stored in data-bs-margin-right') expect(currentMargin).toEqual(expectedMargin, 'sticky element margin should be adjusted while opening') modal.toggle() }) @@ -134,14 +144,40 @@ describe('Modal', () => { modalEl.addEventListener('hidden.bs.modal', () => { const currentMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10) - expect(stickyTopEl.getAttribute('data-bs-margin-right')).toEqual(null, 'data-bs-margin-right should be cleared after closing') + expect(stickyTopEl.hasAttribute('data-bs-margin-right')).toEqual(false, 'data-bs-margin-right should be cleared after closing') expect(currentMargin).toEqual(originalMargin, 'sticky element margin should be reset after closing') + + document.documentElement.style.overflowY = 'auto' done() }) modal.toggle() }) + it('should not adjust the inline margin and padding of sticky and fixed elements when element do not have full width', done => { + fixtureEl.innerHTML = [ + '<div class="sticky-top" style="margin-right: 0px; padding-right: 0px; width: calc(100vw - 50%)"></div>', + '<div class="modal"><div class="modal-dialog"></div></div>' + ].join('') + + const stickyTopEl = fixtureEl.querySelector('.sticky-top') + const originalMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10) + const originalPadding = Number.parseInt(window.getComputedStyle(stickyTopEl).paddingRight, 10) + const modalEl = fixtureEl.querySelector('.modal') + const modal = new Modal(modalEl) + + modalEl.addEventListener('shown.bs.modal', () => { + const currentMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10) + const currentPadding = Number.parseInt(window.getComputedStyle(stickyTopEl).paddingRight, 10) + + expect(currentMargin).toEqual(originalMargin, 'sticky element\'s margin should not be adjusted while opening') + expect(currentPadding).toEqual(originalPadding, 'sticky element\'s padding should not be adjusted while opening') + done() + }) + + modal.show() + }) + it('should ignore values set via CSS when trying to restore body padding after closing', done => { fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' const styleTest = document.createElement('style') @@ -195,27 +231,6 @@ describe('Modal', () => { modal.toggle() }) - - it('should properly restore non-pixel inline body padding after closing', done => { - fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' - - document.body.style.paddingRight = '5%' - - const modalEl = fixtureEl.querySelector('.modal') - const modal = new Modal(modalEl) - - modalEl.addEventListener('shown.bs.modal', () => { - modal.toggle() - }) - - modalEl.addEventListener('hidden.bs.modal', () => { - expect(document.body.style.paddingRight).toEqual('5%') - document.body.removeAttribute('style') - done() - }) - - modal.toggle() - }) }) describe('show', () => { @@ -542,7 +557,7 @@ describe('Modal', () => { }) it('should not close modal when clicking outside of modal-content if backdrop = static', done => { - fixtureEl.innerHTML = '<div class="modal" data-bs-backdrop="static" ><div class="modal-dialog"></div></div>' + fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl, { @@ -569,7 +584,7 @@ describe('Modal', () => { }) it('should close modal when escape key is pressed with keyboard = true and backdrop is static', done => { - fixtureEl.innerHTML = '<div class="modal" data-bs-backdrop="static"><div class="modal-dialog"></div></div>' + fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl, { @@ -626,7 +641,7 @@ describe('Modal', () => { }) it('should not overflow when clicking outside of modal-content if backdrop = static', done => { - fixtureEl.innerHTML = '<div class="modal" data-bs-backdrop="static"><div class="modal-dialog" style="transition-duration: 20ms;"></div></div>' + fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog" style="transition-duration: 20ms;"></div></div>' const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl, { @@ -662,7 +677,6 @@ describe('Modal', () => { // Restore scrollbars document.body.style.overflow = 'auto' - document.documentElement.style.paddingRight = '16px' done() }) @@ -694,7 +708,6 @@ describe('Modal', () => { // Restore overridden css document.body.style.removeProperty('margin') document.body.style.removeProperty('overflow') - document.documentElement.style.paddingRight = '16px' done() }) @@ -870,7 +883,7 @@ describe('Modal', () => { }) describe('data-api', () => { - it('should open modal', done => { + it('should toggle modal', done => { fixtureEl.innerHTML = [ '<button type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"></button>', '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>' @@ -885,6 +898,15 @@ describe('Modal', () => { expect(modalEl.getAttribute('aria-hidden')).toEqual(null) expect(modalEl.style.display).toEqual('block') expect(document.querySelector('.modal-backdrop')).toBeDefined() + setTimeout(() => trigger.click(), 10) + }) + + modalEl.addEventListener('hidden.bs.modal', () => { + expect(modalEl.getAttribute('aria-modal')).toEqual(null) + expect(modalEl.getAttribute('role')).toEqual(null) + expect(modalEl.getAttribute('aria-hidden')).toEqual('true') + expect(modalEl.style.display).toEqual('none') + expect(document.querySelector('.modal-backdrop')).toEqual(null) done() }) @@ -1038,6 +1060,23 @@ describe('Modal', () => { expect(Modal.getInstance(div)).toBeDefined() }) + it('should create a modal with given config', () => { + fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' + + const div = fixtureEl.querySelector('div') + + jQueryMock.fn.modal = Modal.jQueryInterface + jQueryMock.elements = [div] + + jQueryMock.fn.modal.call(jQueryMock, { keyboard: false }) + spyOn(Modal.prototype, 'constructor') + expect(Modal.prototype.constructor).not.toHaveBeenCalledWith(div, { keyboard: false }) + + const modal = Modal.getInstance(div) + expect(modal).toBeDefined() + expect(modal._config.keyboard).toBe(false) + }) + it('should not re create a modal', () => { fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' @@ -1061,11 +1100,9 @@ describe('Modal', () => { jQueryMock.fn.modal = Modal.jQueryInterface jQueryMock.elements = [div] - try { + expect(() => { jQueryMock.fn.modal.call(jQueryMock, action) - } catch (error) { - expect(error.message).toEqual(`No method named "${action}"`) - } + }).toThrowError(TypeError, `No method named "${action}"`) }) it('should call show method', () => { |
