| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- import EventHandler from '../../src/dom/event-handler.js'
- import Popover from '../../src/popover.js'
- import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
- describe('Popover', () => {
- let fixtureEl
- beforeAll(() => {
- fixtureEl = getFixture()
- })
- afterEach(() => {
- clearFixture()
- const popoverList = document.querySelectorAll('.popover')
- for (const popoverEl of popoverList) {
- popoverEl.remove()
- }
- })
- describe('VERSION', () => {
- it('should return plugin version', () => {
- expect(Popover.VERSION).toEqual(jasmine.any(String))
- })
- })
- describe('Default', () => {
- it('should return plugin default config', () => {
- expect(Popover.Default).toEqual(jasmine.any(Object))
- })
- })
- describe('NAME', () => {
- it('should return plugin name', () => {
- expect(Popover.NAME).toEqual(jasmine.any(String))
- })
- })
- describe('DATA_KEY', () => {
- it('should return plugin data key', () => {
- expect(Popover.DATA_KEY).toEqual('bs.popover')
- })
- })
- describe('EVENT_KEY', () => {
- it('should return plugin event key', () => {
- expect(Popover.EVENT_KEY).toEqual('.bs.popover')
- })
- })
- describe('DefaultType', () => {
- it('should return plugin default type', () => {
- expect(Popover.DefaultType).toEqual(jasmine.any(Object))
- })
- })
- describe('show', () => {
- it('should toggle a popover after show', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- popoverEl.addEventListener('shown.bs.popover', () => {
- expect(document.querySelector('.popover')).not.toBeNull()
- popover.toggle()
- })
- popoverEl.addEventListener('hidden.bs.popover', () => {
- expect(document.querySelector('.popover')).toBeNull()
- resolve()
- })
- popover.show()
- })
- })
- it('should show a popover', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- popoverEl.addEventListener('shown.bs.popover', () => {
- expect(document.querySelector('.popover')).not.toBeNull()
- resolve()
- })
- popover.show()
- })
- })
- it('should set title and content from functions', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, {
- title: () => 'Bootstrap',
- content: () => 'loves writing tests (╯°□°)╯︵ ┻━┻'
- })
- popoverEl.addEventListener('shown.bs.popover', () => {
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('Bootstrap')
- expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('loves writing tests (╯°□°)╯︵ ┻━┻')
- resolve()
- })
- popover.show()
- })
- })
- it('should call content and title functions with trigger element', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" data-foo="bar">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, {
- title(el) {
- return el.dataset.foo
- },
- content(el) {
- return el.dataset.foo
- }
- })
- popoverEl.addEventListener('shown.bs.popover', () => {
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('bar')
- expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('bar')
- resolve()
- })
- popover.show()
- })
- })
- it('should call content and title functions with correct this value', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" data-foo="bar">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, {
- title() {
- return this.dataset.foo
- },
- content() {
- return this.dataset.foo
- }
- })
- popoverEl.addEventListener('shown.bs.popover', () => {
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('bar')
- expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('bar')
- resolve()
- })
- popover.show()
- })
- })
- it('should show a popover with just content without having header', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#">Nice link</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, {
- content: 'Some beautiful content :)'
- })
- popoverEl.addEventListener('shown.bs.popover', () => {
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-header')).toBeNull()
- expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('Some beautiful content :)')
- resolve()
- })
- popover.show()
- })
- })
- it('should show a popover with just title without having body', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#">Nice link</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, {
- title: 'Title which does not require content'
- })
- popoverEl.addEventListener('shown.bs.popover', () => {
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-body')).toBeNull()
- expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('Title which does not require content')
- resolve()
- })
- popover.show()
- })
- })
- it('should show a popover with just title without having body using data-attribute to get config', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" data-bs-content="" title="Title which does not require content">Nice link</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- popoverEl.addEventListener('shown.bs.popover', () => {
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-body')).toBeNull()
- expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('Title which does not require content')
- resolve()
- })
- popover.show()
- })
- })
- it('should NOT show a popover without `title` and `content`', () => {
- fixtureEl.innerHTML = '<a href="#" data-bs-content="" title="">Nice link</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, { animation: false })
- const spy = spyOn(EventHandler, 'trigger').and.callThrough()
- popover.show()
- expect(spy).not.toHaveBeenCalledWith(popoverEl, Popover.eventName('show'))
- expect(document.querySelector('.popover')).toBeNull()
- })
- it('"setContent" should keep the initial template', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap" data-bs-custom-class="custom-class">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- popover.setContent({ '.tooltip-inner': 'foo' })
- const tip = popover._getTipElement()
- expect(tip).toHaveClass('popover')
- expect(tip).toHaveClass('bs-popover-auto')
- expect(tip.querySelector('.popover-arrow')).not.toBeNull()
- expect(tip.querySelector('.popover-header')).not.toBeNull()
- expect(tip.querySelector('.popover-body')).not.toBeNull()
- })
- it('should call setContent once', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl, {
- content: 'Popover content'
- })
- expect(popover._templateFactory).toBeNull()
- let spy = null
- let times = 1
- popoverEl.addEventListener('hidden.bs.popover', () => {
- popover.show()
- })
- popoverEl.addEventListener('shown.bs.popover', () => {
- spy = spy || spyOn(popover._templateFactory, 'constructor').and.callThrough()
- const popoverDisplayed = document.querySelector('.popover')
- expect(popoverDisplayed).not.toBeNull()
- expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('Popover content')
- expect(spy).toHaveBeenCalledTimes(0)
- if (times > 1) {
- resolve()
- }
- times++
- popover.hide()
- })
- popover.show()
- })
- })
- it('should show a popover with provided custom class', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap" data-bs-custom-class="custom-class">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- popoverEl.addEventListener('shown.bs.popover', () => {
- const tip = document.querySelector('.popover')
- expect(tip).not.toBeNull()
- expect(tip).toHaveClass('custom-class')
- resolve()
- })
- popover.show()
- })
- })
- })
- describe('hide', () => {
- it('should hide a popover', () => {
- return new Promise(resolve => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- popoverEl.addEventListener('shown.bs.popover', () => {
- popover.hide()
- })
- popoverEl.addEventListener('hidden.bs.popover', () => {
- expect(document.querySelector('.popover')).toBeNull()
- resolve()
- })
- popover.show()
- })
- })
- })
- describe('jQueryInterface', () => {
- it('should create a popover', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- jQueryMock.fn.popover = Popover.jQueryInterface
- jQueryMock.elements = [popoverEl]
- jQueryMock.fn.popover.call(jQueryMock)
- expect(Popover.getInstance(popoverEl)).not.toBeNull()
- })
- it('should create a popover with a config object', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- jQueryMock.fn.popover = Popover.jQueryInterface
- jQueryMock.elements = [popoverEl]
- jQueryMock.fn.popover.call(jQueryMock, {
- content: 'Popover content'
- })
- expect(Popover.getInstance(popoverEl)).not.toBeNull()
- })
- it('should not re create a popover', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- jQueryMock.fn.popover = Popover.jQueryInterface
- jQueryMock.elements = [popoverEl]
- jQueryMock.fn.popover.call(jQueryMock)
- expect(Popover.getInstance(popoverEl)).toEqual(popover)
- })
- it('should throw error on undefined method', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const action = 'undefinedMethod'
- jQueryMock.fn.popover = Popover.jQueryInterface
- jQueryMock.elements = [popoverEl]
- expect(() => {
- jQueryMock.fn.popover.call(jQueryMock, action)
- }).toThrowError(TypeError, `No method named "${action}"`)
- })
- it('should should call show method', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- jQueryMock.fn.popover = Popover.jQueryInterface
- jQueryMock.elements = [popoverEl]
- const spy = spyOn(popover, 'show')
- jQueryMock.fn.popover.call(jQueryMock, 'show')
- expect(spy).toHaveBeenCalled()
- })
- })
- describe('getInstance', () => {
- it('should return popover instance', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- const popover = new Popover(popoverEl)
- expect(Popover.getInstance(popoverEl)).toEqual(popover)
- expect(Popover.getInstance(popoverEl)).toBeInstanceOf(Popover)
- })
- it('should return null when there is no popover instance', () => {
- fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
- const popoverEl = fixtureEl.querySelector('a')
- expect(Popover.getInstance(popoverEl)).toBeNull()
- })
- })
- describe('getOrCreateInstance', () => {
- it('should return popover instance', () => {
- fixtureEl.innerHTML = '<div></div>'
- const div = fixtureEl.querySelector('div')
- const popover = new Popover(div)
- expect(Popover.getOrCreateInstance(div)).toEqual(popover)
- expect(Popover.getInstance(div)).toEqual(Popover.getOrCreateInstance(div, {}))
- expect(Popover.getOrCreateInstance(div)).toBeInstanceOf(Popover)
- })
- it('should return new instance when there is no popover instance', () => {
- fixtureEl.innerHTML = '<div></div>'
- const div = fixtureEl.querySelector('div')
- expect(Popover.getInstance(div)).toBeNull()
- expect(Popover.getOrCreateInstance(div)).toBeInstanceOf(Popover)
- })
- it('should return new instance when there is no popover instance with given configuration', () => {
- fixtureEl.innerHTML = '<div></div>'
- const div = fixtureEl.querySelector('div')
- expect(Popover.getInstance(div)).toBeNull()
- const popover = Popover.getOrCreateInstance(div, {
- placement: 'top'
- })
- expect(popover).toBeInstanceOf(Popover)
- expect(popover._config.placement).toEqual('top')
- })
- it('should return the instance when exists without given configuration', () => {
- fixtureEl.innerHTML = '<div></div>'
- const div = fixtureEl.querySelector('div')
- const popover = new Popover(div, {
- placement: 'top'
- })
- expect(Popover.getInstance(div)).toEqual(popover)
- const popover2 = Popover.getOrCreateInstance(div, {
- placement: 'bottom'
- })
- expect(popover).toBeInstanceOf(Popover)
- expect(popover2).toEqual(popover)
- expect(popover2._config.placement).toEqual('top')
- })
- })
- })
|