aboutsummaryrefslogtreecommitdiff
path: root/js/tests
diff options
context:
space:
mode:
authorGijs Boddeus <[email protected]>2017-09-13 16:46:14 +0200
committerGitHub <[email protected]>2017-09-13 16:46:14 +0200
commitcf004433e0312482a8c4918d559f38c19a3e14d9 (patch)
tree56fd67d5a60a1fe5442c969d29918db4f463b827 /js/tests
parent4356d08abb4d94785af15f3cc9be0e553f1c1c03 (diff)
parent75d435f76e48b19007495a02e79b0d41f2690361 (diff)
downloadbootstrap-cf004433e0312482a8c4918d559f38c19a3e14d9.tar.xz
bootstrap-cf004433e0312482a8c4918d559f38c19a3e14d9.zip
Merge pull request #4 from twbs/v4-dev
update forked v4-dev
Diffstat (limited to 'js/tests')
-rw-r--r--js/tests/.eslintrc.json1
-rw-r--r--js/tests/unit/modal.js78
-rw-r--r--js/tests/visual/modal.html4
3 files changed, 82 insertions, 1 deletions
diff --git a/js/tests/.eslintrc.json b/js/tests/.eslintrc.json
index a05a3a390..b03980144 100644
--- a/js/tests/.eslintrc.json
+++ b/js/tests/.eslintrc.json
@@ -28,6 +28,7 @@
"global-require": "off",
"no-process-env": "off",
"no-process-exit": "off",
+ "no-sync": "off",
// Stylistic Issues
"brace-style": "off",
diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js
index 3b028dc10..e026cd7f1 100644
--- a/js/tests/unit/modal.js
+++ b/js/tests/unit/modal.js
@@ -21,6 +21,8 @@ $(function () {
document.body.removeChild(scrollDiv)
return scrollbarWidth
}
+ // Simulate scrollbars in PhantomJS
+ $('html').css('padding-right', '16px')
},
beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
@@ -349,6 +351,20 @@ $(function () {
$toggleBtn.trigger('click')
})
+ QUnit.test('should adjust the inline padding of the modal when opening', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ $('<div id="modal-test"/>')
+ .on('shown.bs.modal', function () {
+ var expectedPadding = $(this).getScrollbarWidth() + 'px'
+ var currentPadding = $(this).css('padding-right')
+ assert.strictEqual(currentPadding, expectedPadding, 'modal padding should be adjusted while opening')
+ done()
+ })
+ .bootstrapModal('show')
+ })
+
QUnit.test('should adjust the inline body padding when opening and restore when closing', function (assert) {
assert.expect(2)
var done = assert.async()
@@ -391,6 +407,30 @@ $(function () {
.bootstrapModal('show')
})
+ QUnit.test('should not adjust the inline body padding when it does not overflow', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+ var $body = $(document.body)
+ var originalPadding = $body.css('padding-right')
+
+ // Hide scrollbars to prevent the body overflowing
+ $body.css('overflow', 'hidden') // real scrollbar (for in-browser testing)
+ $('html').css('padding-right', '0px') // simulated scrollbar (for PhantomJS)
+
+ $('<div id="modal-test"/>')
+ .on('shown.bs.modal', function () {
+ var currentPadding = $body.css('padding-right')
+ assert.strictEqual(currentPadding, originalPadding, 'body padding should not be adjusted')
+ $(this).bootstrapModal('hide')
+
+ // restore scrollbars
+ $body.css('overflow', 'auto')
+ $('html').css('padding-right', '16px')
+ done()
+ })
+ .bootstrapModal('show')
+ })
+
QUnit.test('should adjust the inline padding of fixed elements when opening and restore when closing', function (assert) {
assert.expect(2)
var done = assert.async()
@@ -525,7 +565,7 @@ $(function () {
$('<div id="modal-test"/>')
.on('hidden.bs.modal', function () {
- assert.ok(!$body.attr('style'), 'body does not have inline padding set')
+ assert.strictEqual($body.attr('style').indexOf('padding-right'), -1, 'body does not have inline padding set')
$style.remove()
done()
})
@@ -597,4 +637,40 @@ $(function () {
})
.trigger('click')
})
+
+ QUnit.test('should not parse target as html', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ var $toggleBtn = $('<button data-toggle="modal" data-target="&lt;div id=&quot;modal-test&quot;&gt;&lt;div class=&quot;contents&quot;&lt;div&lt;div id=&quot;close&quot; data-dismiss=&quot;modal&quot;/&gt;&lt;/div&gt;&lt;/div&gt;"/>')
+ .appendTo('#qunit-fixture')
+
+ $toggleBtn.trigger('click')
+ setTimeout(function () {
+ assert.strictEqual($('#modal-test').length, 0, 'target has not been parsed and added to the document')
+ done()
+ }, 1)
+ })
+
+ QUnit.test('should not execute js from target', function (assert) {
+ assert.expect(0)
+ var done = assert.async()
+
+ // This toggle button contains XSS payload in its data-target
+ // Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
+ // a script element works in manual tests though, so here it is likely blocked by the qunit framework
+ var $toggleBtn = $('<button data-toggle="modal" data-target="&lt;div&gt;&lt;image src=&quot;missing.png&quot; onerror=&quot;$(&apos;#qunit-fixture button.control&apos;).trigger(&apos;click&apos;)&quot;&gt;&lt;/div&gt;"/>')
+ .appendTo('#qunit-fixture')
+ // The XSS payload above does not have a closure over this function and cannot access the assert object directly
+ // However, it can send a click event to the following control button, which will then fail the assert
+ $('<button>')
+ .addClass('control')
+ .on('click', function () {
+ assert.notOk(true, 'XSS payload is not executed as js')
+ })
+ .appendTo('#qunit-fixture')
+
+ $toggleBtn.trigger('click')
+ setTimeout(done, 500)
+ })
})
diff --git a/js/tests/visual/modal.html b/js/tests/visual/modal.html
index c9a950b8c..da9bbf93a 100644
--- a/js/tests/visual/modal.html
+++ b/js/tests/visual/modal.html
@@ -167,6 +167,10 @@
<div class="bg-dark text-white p-2" id="tall" style="display: none;">
Tall body content to force the page to have a scrollbar.
</div>
+
+ <button type="button" class="btn btn-secondary btn-lg" data-toggle="modal" data-target="&#x3C;div class=&#x22;modal fade the-bad&#x22; tabindex=&#x22;-1&#x22; role=&#x22;dialog&#x22;&#x3E;&#x3C;div class=&#x22;modal-dialog&#x22; role=&#x22;document&#x22;&#x3E;&#x3C;div class=&#x22;modal-content&#x22;&#x3E;&#x3C;div class=&#x22;modal-header&#x22;&#x3E;&#x3C;button type=&#x22;button&#x22; class=&#x22;close&#x22; data-dismiss=&#x22;modal&#x22; aria-label=&#x22;Close&#x22;&#x3E;&#x3C;span aria-hidden=&#x22;true&#x22;&#x3E;&#x26;times;&#x3C;/span&#x3E;&#x3C;/button&#x3E;&#x3C;h4 class=&#x22;modal-title&#x22;&#x3E;The Bad Modal&#x3C;/h4&#x3E;&#x3C;/div&#x3E;&#x3C;div class=&#x22;modal-body&#x22;&#x3E;This modal&#x27;s HTTML source code is declared inline, inside the data-target attribute of it&#x27;s show-button&#x3C;/div&#x3E;&#x3C;/div&#x3E;&#x3C;/div&#x3E;&#x3C;/div&#x3E;">
+ Modal with an XSS inside the data-target
+ </button>
</div>
<script src="../../../assets/js/vendor/jquery-slim.min.js"></script>