modal.js 16.1 KB
Newer Older
1
$(function () {
2
  'use strict'
3

fat's avatar
fat committed
4
  QUnit.module('modal plugin')
XhmikosR's avatar
XhmikosR committed
5

fat's avatar
fat committed
6
7
8
  QUnit.test('should be defined on jquery object', function (assert) {
    assert.expect(1)
    assert.ok($(document.body).modal, 'modal method is defined')
XhmikosR's avatar
XhmikosR committed
9
10
  })

fat's avatar
fat committed
11
12
  QUnit.module('modal', {
    beforeEach: function () {
13
14
15
      // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
      $.fn.bootstrapModal = $.fn.modal.noConflict()
    },
fat's avatar
fat committed
16
    afterEach: function () {
17
18
19
20
21
      $.fn.modal = $.fn.bootstrapModal
      delete $.fn.bootstrapModal
    }
  })

fat's avatar
fat committed
22
23
24
  QUnit.test('should provide no conflict', function (assert) {
    assert.expect(1)
    assert.strictEqual($.fn.modal, undefined, 'modal was set back to undefined (orig value)')
25
26
  })

27
28
29
30
31
32
33
34
35
36
37
38
  QUnit.test('should throw explicit error on undefined method', function (assert) {
    assert.expect(1)
    var $el = $('<div id="modal-test"/>')
    $el.bootstrapModal()
    try {
      $el.bootstrapModal('noMethod')
    }
    catch (err) {
      assert.strictEqual(err.message, 'No method named "noMethod"')
    }
  })

fat's avatar
fat committed
39
40
  QUnit.test('should return jquery collection containing the element', function (assert) {
    assert.expect(2)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
41
42
    var $el = $('<div id="modal-test"/>')
    var $modal = $el.bootstrapModal()
fat's avatar
fat committed
43
44
    assert.ok($modal instanceof $, 'returns jquery collection')
    assert.strictEqual($modal[0], $el[0], 'collection contains element')
XhmikosR's avatar
XhmikosR committed
45
46
  })

fat's avatar
fat committed
47
48
  QUnit.test('should expose defaults var for settings', function (assert) {
    assert.expect(1)
49
    assert.ok($.fn.bootstrapModal.Constructor.Default, 'default object exposed')
XhmikosR's avatar
XhmikosR committed
50
51
  })

fat's avatar
fat committed
52
53
  QUnit.test('should insert into dom when show method is called', function (assert) {
    assert.expect(1)
54
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
55
56

    $('<div id="modal-test"/>')
XhmikosR's avatar
XhmikosR committed
57
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
58
        assert.notEqual($('#modal-test').length, 0, 'modal inserted into dom')
59
        done()
XhmikosR's avatar
XhmikosR committed
60
      })
61
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
62
63
  })

fat's avatar
fat committed
64
65
  QUnit.test('should fire show event', function (assert) {
    assert.expect(1)
66
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
67
68

    $('<div id="modal-test"/>')
XhmikosR's avatar
XhmikosR committed
69
      .on('show.bs.modal', function () {
fat's avatar
fat committed
70
        assert.ok(true, 'show event fired')
71
        done()
XhmikosR's avatar
XhmikosR committed
72
      })
73
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
74
75
  })

fat's avatar
fat committed
76
77
  QUnit.test('should not fire shown when show was prevented', function (assert) {
    assert.expect(1)
78
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
79
80

    $('<div id="modal-test"/>')
XhmikosR's avatar
XhmikosR committed
81
82
      .on('show.bs.modal', function (e) {
        e.preventDefault()
fat's avatar
fat committed
83
        assert.ok(true, 'show event fired')
84
        done()
XhmikosR's avatar
XhmikosR committed
85
86
      })
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
87
        assert.ok(false, 'shown event fired')
XhmikosR's avatar
XhmikosR committed
88
      })
89
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
90
91
  })

fat's avatar
fat committed
92
93
  QUnit.test('should hide modal when hide is called', function (assert) {
    assert.expect(3)
94
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
95

Heinrich Fenkart's avatar
Heinrich Fenkart committed
96
    $('<div id="modal-test"/>')
XhmikosR's avatar
XhmikosR committed
97
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
98
99
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
        assert.notEqual($('#modal-test').length, 0, 'modal inserted into dom')
100
        $(this).bootstrapModal('hide')
XhmikosR's avatar
XhmikosR committed
101
102
      })
      .on('hidden.bs.modal', function () {
fat's avatar
fat committed
103
        assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
104
        done()
XhmikosR's avatar
XhmikosR committed
105
      })
106
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
107
108
  })

fat's avatar
fat committed
109
110
  QUnit.test('should toggle when toggle is called', function (assert) {
    assert.expect(3)
111
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
112
113

    $('<div id="modal-test"/>')
XhmikosR's avatar
XhmikosR committed
114
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
115
116
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
        assert.notEqual($('#modal-test').length, 0, 'modal inserted into dom')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
117
        $(this).bootstrapModal('toggle')
XhmikosR's avatar
XhmikosR committed
118
119
      })
      .on('hidden.bs.modal', function () {
fat's avatar
fat committed
120
        assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
121
        done()
XhmikosR's avatar
XhmikosR committed
122
      })
123
      .bootstrapModal('toggle')
XhmikosR's avatar
XhmikosR committed
124
125
  })

fat's avatar
fat committed
126
127
  QUnit.test('should remove from dom when click [data-dismiss="modal"]', function (assert) {
    assert.expect(3)
128
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
129
130

    $('<div id="modal-test"><span class="close" data-dismiss="modal"/></div>')
XhmikosR's avatar
XhmikosR committed
131
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
132
133
134
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
        assert.notEqual($('#modal-test').length, 0, 'modal inserted into dom')
        $(this).find('.close').trigger('click')
XhmikosR's avatar
XhmikosR committed
135
136
      })
      .on('hidden.bs.modal', function () {
fat's avatar
fat committed
137
        assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
138
        done()
XhmikosR's avatar
XhmikosR committed
139
      })
140
      .bootstrapModal('toggle')
XhmikosR's avatar
XhmikosR committed
141
142
  })

fat's avatar
fat committed
143
144
  QUnit.test('should allow modal close with "backdrop:false"', function (assert) {
    assert.expect(2)
145
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
146
147

    $('<div id="modal-test" data-backdrop="false"/>')
XhmikosR's avatar
XhmikosR committed
148
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
149
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
150
        $(this).bootstrapModal('hide')
XhmikosR's avatar
XhmikosR committed
151
152
      })
      .on('hidden.bs.modal', function () {
fat's avatar
fat committed
153
        assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
154
        done()
XhmikosR's avatar
XhmikosR committed
155
      })
156
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
157
158
  })

fat's avatar
fat committed
159
160
  QUnit.test('should close modal when clicking outside of modal-content', function (assert) {
    assert.expect(3)
161
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
162
163

    $('<div id="modal-test"><div class="contents"/></div>')
164
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
165
166
167
168
        assert.notEqual($('#modal-test').length, 0, 'modal inserted into dom')
        $('.contents').trigger('click')
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
        $('#modal-test').trigger('click')
XhmikosR's avatar
XhmikosR committed
169
      })
170
      .on('hidden.bs.modal', function () {
fat's avatar
fat committed
171
        assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
172
        done()
XhmikosR's avatar
XhmikosR committed
173
      })
174
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
175
176
  })

177
178
179
180
181
182
183
184
185
186
187
188
189
  QUnit.test('should not close modal when clicking outside of modal-content if data-backdrop="true"', function (assert) {
    assert.expect(1)
    var done = assert.async()

    $('<div id="modal-test" data-backdrop="false"><div class="contents"/></div>')
      .on('shown.bs.modal', function () {
        $('#modal-test').trigger('click')
        assert.ok($('#modal-test').is(':visible'), 'modal not hidden')
        done()
      })
      .bootstrapModal('show')
  })

fat's avatar
fat committed
190
191
  QUnit.test('should close modal when escape key is pressed via keydown', function (assert) {
    assert.expect(3)
192
    var done = assert.async()
193

fat's avatar
fat committed
194
195
    var $div = $('<div id="modal-test"/>')
    $div
196
      .on('shown.bs.modal', function () {
197
        assert.ok($('#modal-test').length, 'modal inserted into dom')
fat's avatar
fat committed
198
199
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
        $div.trigger($.Event('keydown', { which: 27 }))
200
201

        setTimeout(function () {
fat's avatar
fat committed
202
203
          assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
          $div.remove()
204
          done()
205
206
207
208
209
        }, 0)
      })
      .bootstrapModal('show')
  })

fat's avatar
fat committed
210
211
  QUnit.test('should not close modal when escape key is pressed via keyup', function (assert) {
    assert.expect(3)
212
    var done = assert.async()
213

fat's avatar
fat committed
214
215
    var $div = $('<div id="modal-test"/>')
    $div
216
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
217
218
219
        assert.ok($('#modal-test').length, 'modal inserted into dom')
        assert.ok($('#modal-test').is(':visible'), 'modal visible')
        $div.trigger($.Event('keyup', { which: 27 }))
220
221

        setTimeout(function () {
fat's avatar
fat committed
222
223
          assert.ok($div.is(':visible'), 'modal still visible')
          $div.remove()
224
          done()
225
226
227
228
229
        }, 0)
      })
      .bootstrapModal('show')
  })

fat's avatar
fat committed
230
231
  QUnit.test('should trigger hide event once when clicking outside of modal-content', function (assert) {
    assert.expect(1)
232
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
233
234
235

    var triggered

Heinrich Fenkart's avatar
Heinrich Fenkart committed
236
    $('<div id="modal-test"><div class="contents"/></div>')
237
      .on('shown.bs.modal', function () {
XhmikosR's avatar
XhmikosR committed
238
        triggered = 0
fat's avatar
fat committed
239
        $('#modal-test').trigger('click')
XhmikosR's avatar
XhmikosR committed
240
      })
241
      .on('hide.bs.modal', function () {
XhmikosR's avatar
XhmikosR committed
242
        triggered += 1
fat's avatar
fat committed
243
        assert.strictEqual(triggered, 1, 'modal hide triggered once')
244
        done()
XhmikosR's avatar
XhmikosR committed
245
      })
246
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
247
248
  })

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  QUnit.test('should remove aria-hidden attribute when shown, add it back when hidden', function (assert) {
    assert.expect(3)
    var done = assert.async()

    $('<div id="modal-test" aria-hidden="true"/>')
      .on('shown.bs.modal', function () {
        assert.notOk($('#modal-test').is('[aria-hidden]'), 'aria-hidden attribute removed')
        $(this).bootstrapModal('hide')
      })
      .on('hidden.bs.modal', function () {
        assert.ok($('#modal-test').is('[aria-hidden]'), 'aria-hidden attribute added')
        assert.strictEqual($('#modal-test').attr('aria-hidden'), 'true', 'correct aria-hidden="true" added')
        done()
      })
      .bootstrapModal('show')
  })

fat's avatar
fat committed
266
267
  QUnit.test('should close reopened modal with [data-dismiss="modal"] click', function (assert) {
    assert.expect(2)
268
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
269
270

    $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div></div>')
271
      .one('shown.bs.modal', function () {
fat's avatar
fat committed
272
        $('#close').trigger('click')
XhmikosR's avatar
XhmikosR committed
273
274
      })
      .one('hidden.bs.modal', function () {
275
        // after one open-close cycle
fat's avatar
fat committed
276
        assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
277
        $(this)
278
          .one('shown.bs.modal', function () {
fat's avatar
fat committed
279
            $('#close').trigger('click')
280
          })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
281
          .one('hidden.bs.modal', function () {
fat's avatar
fat committed
282
            assert.ok(!$('#modal-test').is(':visible'), 'modal hidden')
283
            done()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
284
285
          })
          .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
286
      })
287
      .bootstrapModal('show')
XhmikosR's avatar
XhmikosR committed
288
  })
Chris Rebert's avatar
Chris Rebert committed
289

fat's avatar
fat committed
290
291
  QUnit.test('should restore focus to toggling element when modal is hidden after having been opened via data-api', function (assert) {
    assert.expect(1)
292
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
293
294
295
296

    var $toggleBtn = $('<button data-toggle="modal" data-target="#modal-test"/>').appendTo('#qunit-fixture')

    $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div></div>')
Chris Rebert's avatar
Chris Rebert committed
297
      .on('hidden.bs.modal', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
298
        setTimeout(function () {
fat's avatar
fat committed
299
          assert.ok($(document.activeElement).is($toggleBtn), 'toggling element is once again focused')
300
          done()
Chris Rebert's avatar
Chris Rebert committed
301
302
303
        }, 0)
      })
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
304
        $('#close').trigger('click')
Chris Rebert's avatar
Chris Rebert committed
305
306
      })
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
307

fat's avatar
fat committed
308
    $toggleBtn.trigger('click')
Chris Rebert's avatar
Chris Rebert committed
309
310
  })

fat's avatar
fat committed
311
312
  QUnit.test('should not restore focus to toggling element if the associated show event gets prevented', function (assert) {
    assert.expect(1)
313
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
314
315
316
317
    var $toggleBtn = $('<button data-toggle="modal" data-target="#modal-test"/>').appendTo('#qunit-fixture')
    var $otherBtn = $('<button id="other-btn"/>').appendTo('#qunit-fixture')

    $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div>')
Chris Rebert's avatar
Chris Rebert committed
318
319
      .one('show.bs.modal', function (e) {
        e.preventDefault()
fat's avatar
fat committed
320
        $otherBtn.trigger('focus')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
321
322
323
        setTimeout($.proxy(function () {
          $(this).bootstrapModal('show')
        }, this), 0)
Chris Rebert's avatar
Chris Rebert committed
324
325
      })
      .on('hidden.bs.modal', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
326
        setTimeout(function () {
fat's avatar
fat committed
327
          assert.ok($(document.activeElement).is($otherBtn), 'focus returned to toggling element')
328
          done()
Chris Rebert's avatar
Chris Rebert committed
329
330
331
        }, 0)
      })
      .on('shown.bs.modal', function () {
fat's avatar
fat committed
332
        $('#close').trigger('click')
Chris Rebert's avatar
Chris Rebert committed
333
334
      })
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
335

fat's avatar
fat committed
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    $toggleBtn.trigger('click')
  })

  QUnit.test('should restore inline body padding after closing', function (assert) {
    assert.expect(2)
    var done = assert.async()
    var originalBodyPad = 0
    var $body = $(document.body)

    $body.css('padding-right', originalBodyPad)

    $('<div id="modal-test"/>')
      .on('hidden.bs.modal', function () {
        var currentBodyPad = parseInt($body.css('padding-right'), 10)
        assert.notStrictEqual($body.attr('style'), '', 'body has non-empty style attribute')
        assert.strictEqual(currentBodyPad, originalBodyPad, 'original body padding was not changed')
        $body.removeAttr('style')
        done()
      })
      .on('shown.bs.modal', function () {
        $(this).bootstrapModal('hide')
      })
      .bootstrapModal('show')
  })

  QUnit.test('should ignore values set via CSS when trying to restore body padding after closing', function (assert) {
    assert.expect(1)
    var done = assert.async()
    var $body = $(document.body)
    var $style = $('<style>body { padding-right: 42px; }</style>').appendTo('head')

    $('<div id="modal-test"/>')
      .on('hidden.bs.modal', function () {
        assert.ok(!$body.attr('style'), 'body does not have inline padding set')
        $style.remove()
        done()
      })
      .on('shown.bs.modal', function () {
        $(this).bootstrapModal('hide')
      })
      .bootstrapModal('show')
  })

379
380
381
  QUnit.test('should have a paddingRight when the modal is taller than the viewport', function (assert) {
    assert.expect(2)
    var done = assert.async()
Mark Otto's avatar
Mark Otto committed
382
383
    $('<div class="fixed-top fixed-bottom sticky-top is-fixed">@Johann-S</div>').appendTo('#qunit-fixture')
    $('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top').css('padding-right', '10px')
384
385
386
387
388
389

    $('<div id="modal-test"/>')
      .on('shown.bs.modal', function () {
        var paddingRight = parseInt($(document.body).css('padding-right'), 10)
        assert.strictEqual(isNaN(paddingRight), false)
        assert.strictEqual(paddingRight !== 0, true)
390
        $(document.body).css('padding-right', '') // Because test case "should ignore other inline styles when trying to restore body padding after closing" fail if not
391
392
393
394
395
396
397
398
        done()
      })
      .bootstrapModal('show')
  })

  QUnit.test('should remove padding-right on modal after closing', function (assert) {
    assert.expect(3)
    var done = assert.async()
Mark Otto's avatar
Mark Otto committed
399
400
    $('<div class="fixed-top fixed-bottom is-fixed sticky-top">@Johann-S</div>').appendTo('#qunit-fixture')
    $('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top').css('padding-right', '10px')
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

    $('<div id="modal-test"/>')
      .on('shown.bs.modal', function () {
        var paddingRight = parseInt($(document.body).css('padding-right'), 10)
        assert.strictEqual(isNaN(paddingRight), false)
        assert.strictEqual(paddingRight !== 0, true)
        $(this).bootstrapModal('hide')
      })
      .on('hidden.bs.modal', function () {
        var paddingRight = parseInt($(document.body).css('padding-right'), 10)
        assert.strictEqual(paddingRight, 0)
        done()
      })
      .bootstrapModal('show')
  })

fat's avatar
fat committed
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  QUnit.test('should ignore other inline styles when trying to restore body padding after closing', function (assert) {
    assert.expect(2)
    var done = assert.async()
    var $body = $(document.body)
    var $style = $('<style>body { padding-right: 42px; }</style>').appendTo('head')

    $body.css('color', 'red')

    $('<div id="modal-test"/>')
      .on('hidden.bs.modal', function () {
        assert.strictEqual($body[0].style.paddingRight, '', 'body does not have inline padding set')
        assert.strictEqual($body[0].style.color, 'red', 'body still has other inline styles set')
        $body.removeAttr('style')
        $style.remove()
        done()
      })
      .on('shown.bs.modal', function () {
        $(this).bootstrapModal('hide')
      })
      .bootstrapModal('show')
  })

  QUnit.test('should properly restore non-pixel inline body padding after closing', function (assert) {
    assert.expect(1)
    var done = assert.async()
    var $body = $(document.body)

    $body.css('padding-right', '5%')

    $('<div id="modal-test"/>')
      .on('hidden.bs.modal', function () {
        assert.strictEqual($body[0].style.paddingRight, '5%', 'body does not have inline padding set')
        $body.removeAttr('style')
        done()
      })
      .on('shown.bs.modal', function () {
        $(this).bootstrapModal('hide')
      })
      .bootstrapModal('show')
Chris Rebert's avatar
Chris Rebert committed
456
  })
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

  QUnit.test('should not follow link in area tag', function (assert) {
    assert.expect(2)
    var done = assert.async()

    $('<map><area id="test" shape="default" data-toggle="modal" data-target="#modal-test" href="demo.html"/></map>')
      .appendTo('#qunit-fixture')

    $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div></div>')
      .appendTo('#qunit-fixture')

    $('#test')
      .on('click.bs.modal.data-api', function (event) {
        assert.notOk(event.isDefaultPrevented(), 'navigating to href will happen')

        setTimeout(function () {
          assert.ok(event.isDefaultPrevented(), 'model shown instead of navigating to href')
          done()
        }, 1)
      })
      .trigger('click')
  })
479
})