toast.spec.js 10.33 KiB
import Toast from '../../src/toast'
/** Test helpers */
import { getFixture, clearFixture, jQueryMock } from '../helpers/fixture'
describe('Toast', () => {
  let fixtureEl
  beforeAll(() => {
    fixtureEl = getFixture()
  afterEach(() => {
    clearFixture()
  describe('VERSION', () => {
    it('should return plugin version', () => {
      expect(Toast.VERSION).toEqual(jasmine.any(String))
  describe('constructor', () => {
    it('should allow to config in js', done => {
      fixtureEl.innerHTML = [
        '<div class="toast">',
        '  <div class="toast-body">',
        '    a simple toast',
        '  </div>',
        '</div>'
      ].join('')
      const toastEl = fixtureEl.querySelector('div')
      const toast = new Toast(toastEl, {
        delay: 1
      toastEl.addEventListener('shown.bs.toast', () => {
        expect(toastEl.classList.contains('show')).toEqual(true)
        done()
      toast.show()
    it('should close toast when close element with data-dismiss attribute is set', done => {
      fixtureEl.innerHTML = [
        '<div class="toast" data-delay="1" data-autohide="false" data-animation="false">',
        '  <button type="button" class="ml-2 mb-1 close" data-dismiss="toast">',
        '    close',
        '  </button>',
        '</div>'
      ].join('')
      const toastEl = fixtureEl.querySelector('div')
      const toast = new Toast(toastEl)
      toastEl.addEventListener('shown.bs.toast', () => {
        expect(toastEl.classList.contains('show')).toEqual(true)
        const button = toastEl.querySelector('.close')
        button.click()
      toastEl.addEventListener('hidden.bs.toast', () => {
        expect(toastEl.classList.contains('show')).toEqual(false)
        done()
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
toast.show() }) }) describe('Default', () => { it('should expose default setting to allow to override them', () => { const defaultDelay = 1000 Toast.Default.delay = defaultDelay fixtureEl.innerHTML = [ '<div class="toast" data-autohide="false" data-animation="false">', ' <button type="button" class="ml-2 mb-1 close" data-dismiss="toast">', ' close', ' </button>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('div') const toast = new Toast(toastEl) expect(toast._config.delay).toEqual(defaultDelay) }) }) describe('DefaultType', () => { it('should expose default setting types for read', () => { expect(Toast.DefaultType).toEqual(jasmine.any(Object)) }) }) describe('show', () => { it('should auto hide', done => { fixtureEl.innerHTML = [ '<div class="toast" data-delay="1">', ' <div class="toast-body">', ' a simple toast', ' </div>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('.toast') const toast = new Toast(toastEl) toastEl.addEventListener('hidden.bs.toast', () => { expect(toastEl.classList.contains('show')).toEqual(false) done() }) toast.show() }) it('should not add fade class', done => { fixtureEl.innerHTML = [ '<div class="toast" data-delay="1" data-animation="false">', ' <div class="toast-body">', ' a simple toast', ' </div>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('.toast') const toast = new Toast(toastEl) toastEl.addEventListener('shown.bs.toast', () => { expect(toastEl.classList.contains('fade')).toEqual(false) done() }) toast.show()
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
}) it('should not trigger shown if show is prevented', done => { fixtureEl.innerHTML = [ '<div class="toast" data-delay="1" data-animation="false">', ' <div class="toast-body">', ' a simple toast', ' </div>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('.toast') const toast = new Toast(toastEl) const assertDone = () => { setTimeout(() => { expect(toastEl.classList.contains('show')).toEqual(false) done() }, 20) } toastEl.addEventListener('show.bs.toast', event => { event.preventDefault() assertDone() }) toastEl.addEventListener('shown.bs.toast', () => { throw new Error('shown event should not be triggered if show is prevented') }) toast.show() }) it('should clear timeout if toast is shown again before it is hidden', done => { fixtureEl.innerHTML = [ '<div class="toast">', ' <div class="toast-body">', ' a simple toast', ' </div>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('.toast') const toast = new Toast(toastEl) setTimeout(() => { toast._config.autohide = false toastEl.addEventListener('shown.bs.toast', () => { expect(toast._clearTimeout).toHaveBeenCalled() expect(toast._timeout).toBeNull() done() }) toast.show() }, toast._config.delay / 2) spyOn(toast, '_clearTimeout').and.callThrough() toast.show() }) }) describe('hide', () => { it('should allow to hide toast manually', done => { fixtureEl.innerHTML = [ '<div class="toast" data-delay="1" data-autohide="false">', ' <div class="toast-body">', ' a simple toast', ' </div>', ' </div>' ].join('')
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
const toastEl = fixtureEl.querySelector('.toast') const toast = new Toast(toastEl) toastEl.addEventListener('shown.bs.toast', () => { toast.hide() }) toastEl.addEventListener('hidden.bs.toast', () => { expect(toastEl.classList.contains('show')).toEqual(false) done() }) toast.show() }) it('should do nothing when we call hide on a non shown toast', () => { fixtureEl.innerHTML = '<div></div>' const toastEl = fixtureEl.querySelector('div') const toast = new Toast(toastEl) spyOn(toastEl.classList, 'contains') toast.hide() expect(toastEl.classList.contains).toHaveBeenCalled() }) it('should not trigger hidden if hide is prevented', done => { fixtureEl.innerHTML = [ '<div class="toast" data-delay="1" data-animation="false">', ' <div class="toast-body">', ' a simple toast', ' </div>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('.toast') const toast = new Toast(toastEl) const assertDone = () => { setTimeout(() => { expect(toastEl.classList.contains('show')).toEqual(true) done() }, 20) } toastEl.addEventListener('shown.bs.toast', () => { toast.hide() }) toastEl.addEventListener('hide.bs.toast', event => { event.preventDefault() assertDone() }) toastEl.addEventListener('hidden.bs.toast', () => { throw new Error('hidden event should not be triggered if hide is prevented') }) toast.show() }) }) describe('dispose', () => { it('should allow to destroy toast', () => { fixtureEl.innerHTML = '<div></div>' const toastEl = fixtureEl.querySelector('div')
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
const toast = new Toast(toastEl) expect(Toast.getInstance(toastEl)).toBeDefined() toast.dispose() expect(Toast.getInstance(toastEl)).toBeNull() }) it('should allow to destroy toast and hide it before that', done => { fixtureEl.innerHTML = [ '<div class="toast" data-delay="0" data-autohide="false">', ' <div class="toast-body">', ' a simple toast', ' </div>', '</div>' ].join('') const toastEl = fixtureEl.querySelector('div') const toast = new Toast(toastEl) const expected = () => { expect(toastEl.classList.contains('show')).toEqual(true) expect(Toast.getInstance(toastEl)).toBeDefined() toast.dispose() expect(Toast.getInstance(toastEl)).toBeNull() expect(toastEl.classList.contains('show')).toEqual(false) done() } toastEl.addEventListener('shown.bs.toast', () => { setTimeout(expected, 1) }) toast.show() }) }) describe('jQueryInterface', () => { it('should create a toast', () => { fixtureEl.innerHTML = '<div></div>' const div = fixtureEl.querySelector('div') jQueryMock.fn.toast = Toast.jQueryInterface jQueryMock.elements = [div] jQueryMock.fn.toast.call(jQueryMock) expect(Toast.getInstance(div)).toBeDefined() }) it('should not re create a toast', () => { fixtureEl.innerHTML = '<div></div>' const div = fixtureEl.querySelector('div') const toast = new Toast(div) jQueryMock.fn.toast = Toast.jQueryInterface jQueryMock.elements = [div] jQueryMock.fn.toast.call(jQueryMock) expect(Toast.getInstance(div)).toEqual(toast) }) it('should call a toast method', () => { fixtureEl.innerHTML = '<div></div>'
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
const div = fixtureEl.querySelector('div') const toast = new Toast(div) spyOn(toast, 'show') jQueryMock.fn.toast = Toast.jQueryInterface jQueryMock.elements = [div] jQueryMock.fn.toast.call(jQueryMock, 'show') expect(Toast.getInstance(div)).toEqual(toast) expect(toast.show).toHaveBeenCalled() }) it('should throw error on undefined method', () => { fixtureEl.innerHTML = '<div></div>' const div = fixtureEl.querySelector('div') const action = 'undefinedMethod' jQueryMock.fn.toast = Toast.jQueryInterface jQueryMock.elements = [div] try { jQueryMock.fn.toast.call(jQueryMock, action) } catch (error) { expect(error.message).toEqual(`No method named "${action}"`) } }) }) describe('getInstance', () => { it('should return collapse instance', () => { fixtureEl.innerHTML = '<div></div>' const div = fixtureEl.querySelector('div') const toast = new Toast(div) expect(Toast.getInstance(div)).toEqual(toast) }) it('should return null when there is no collapse instance', () => { fixtureEl.innerHTML = '<div></div>' const div = fixtureEl.querySelector('div') expect(Toast.getInstance(div)).toEqual(null) }) }) })