diff --git a/src/additional/maxfiles.js b/src/additional/maxfiles.js new file mode 100644 index 0000000..0cf53e7 --- /dev/null +++ b/src/additional/maxfiles.js @@ -0,0 +1,14 @@ +// Limit the number of files in a FileList. +$.validator.addMethod( "maxfiles", function( value, element, param ) { + if ( this.optional( element ) ) { + return true; + } + + if ( $( element ).attr( "type" ) === "file" ) { + if ( element.files && element.files.length > param ) { + return false; + } + } + + return true; +}, $.validator.format( "Please select no more than {0} files." ) ); diff --git a/src/additional/maxsize.js b/src/additional/maxsize.js new file mode 100644 index 0000000..0b9db7c --- /dev/null +++ b/src/additional/maxsize.js @@ -0,0 +1,18 @@ +// Limit the size of each individual file in a FileList. +$.validator.addMethod( "maxsize", function( value, element, param ) { + if ( this.optional( element ) ) { + return true; + } + + if ( $( element ).attr( "type" ) === "file" ) { + if ( element.files && element.files.length ) { + for ( var i = 0; i < element.files.length; i++ ) { + if ( element.files[ i ].size > param ) { + return false; + } + } + } + } + + return true; +}, $.validator.format( "File size must not exceed {0} bytes each." ) ); diff --git a/src/additional/maxsizetotal.js b/src/additional/maxsizetotal.js new file mode 100644 index 0000000..c2f990b --- /dev/null +++ b/src/additional/maxsizetotal.js @@ -0,0 +1,22 @@ +// Limit the size of all files in a FileList. +$.validator.addMethod( "maxsizetotal", function( value, element, param ) { + if ( this.optional( element ) ) { + return true; + } + + if ( $( element ).attr( "type" ) === "file" ) { + if ( element.files && element.files.length ) { + var totalSize = 0; + + for ( var i = 0; i < element.files.length; i++ ) { + totalSize += element.files[ i ].size; + if ( totalSize > param ) { + return false; + } + } + } + } + + return true; +}, $.validator.format( "Total size of all files must not exceed {0} bytes." ) ); + diff --git a/test/methods.js b/test/methods.js index 173a228..ce36e89 100644 --- a/test/methods.js +++ b/test/methods.js @@ -42,6 +42,39 @@ function acceptFileDummyInput( filename, mimeType ) { }; } +function fileDummyInput( selectedFiles ) { + var aFiles = [], + oFiles; + + for ( var i = 0; i < selectedFiles.length; i++ ) { + aFiles.push( { + name: selectedFiles[ i ].name, + size: selectedFiles[ i ].size, + type: "image/jpeg" + } ); + } + + //Convert the array of objects to an object. + oFiles = aFiles.reduce( function( acc, cur, i ) { + acc[ i ] = cur; + return acc; + }, {} ); + + //Add the "length" property to the object. + oFiles.length = selectedFiles.length; + + //Add the "item()" method to the object. + oFiles.item = function( i ) { return aFiles[ i ]; }; + + return { + type: "file", + files: oFiles, + nodeName: "INPUT", + value: "/tmp/fake_value", + hasAttribute: function() { return false; } + }; +} + QUnit.module( "methods" ); QUnit.test( "default messages", function( assert ) { @@ -1704,3 +1737,81 @@ QUnit.test( "file accept - invalid mime type", function( assert ) { proxy = $.proxy( $.validator.methods.accept, new $.validator( {}, $form[ 0 ] ), null, input, "application/vnd.google-earth.kml+xml" ); assert.equal( proxy(), false, "the selected file for upload has invalid mime type" ); } ); + +QUnit.test( "file size - below max", function( assert ) { + var input = acceptFileDummyInput( "test.png", "image/png" ), + $form = $( "
" ), + proxy = $.proxy( $.validator.methods.maxsize, new $.validator( {}, $form[ 0 ] ), null, input, "500001" ); + assert.ok( proxy(), "the selected file for upload is smaller than max" ); +} ); + +QUnit.test( "file size - over max", function( assert ) { + var input = acceptFileDummyInput( "test.png", "image/png" ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsize, new $.validator( {}, $form[ 0 ] ), null, input, "500000" ); + assert.equal( proxy(), false, "the selected file for upload is greater than max" ); +} ); + +QUnit.test( "file maxsize - valid size", function( assert ) { + var selectedFiles = [ { name: "test.jpg", size: 500000 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsize, new $.validator( {}, $form[ 0 ] ), null, input, 500000 ); + assert.ok( proxy(), "the size of the file does not exceed the maximum" ); +} ); + +QUnit.test( "file maxsize - valid size for each file", function( assert ) { + var selectedFiles = [ { name: "test1.jpg", size: 500000 }, { name: "test2.jpg", size: 500000 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsize, new $.validator( {}, $form[ 0 ] ), null, input, 500000 ); + assert.ok( proxy(), "the size of the each file does not exceed the maximum" ); +} ); + +QUnit.test( "file maxsize - too big", function( assert ) { + var selectedFiles = [ { name: "test.jpg", size: 500001 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsize, new $.validator( {}, $form[ 0 ] ), null, input, 500000 ); + assert.equal( proxy(), false, "the size of the file exceeds the maximum" ); +} ); + +QUnit.test( "file maxsize - second file too big", function( assert ) { + var selectedFiles = [ { name: "test1.jpg", size: 500000 }, { name: "test2.jpg", size: 500001 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsize, new $.validator( {}, $form[ 0 ] ), null, input, 500000 ); + assert.equal( proxy(), false, "the size of the second file exceeds the maximum" ); +} ); + +QUnit.test( "file maxsizetotal - valid size", function( assert ) { + var selectedFiles = [ { name: "test1.jpg", size: 250000 }, { name: "test2.jpg", size: 250000 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsizetotal, new $.validator( {}, $form[ 0 ] ), null, input, 500000 ); + assert.ok( proxy(), "the size of the files together does not exceed the maximum" ); +} ); + +QUnit.test( "file maxsizetotal - too big", function( assert ) { + var selectedFiles = [ { name: "test1.jpg", size: 250000 }, { name: "test2.jpg", size: 250001 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxsizetotal, new $.validator( {}, $form[ 0 ] ), null, input, 500000 ); + assert.equal( proxy(), false, "the size of the files together exceeds the maximum" ); +} ); + +QUnit.test( "file maxfiles - valid number", function( assert ) { + var selectedFiles = [ { name: "test1.jpg", size: 500000 }, { name: "test2.jpg", size: 500000 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxfiles, new $.validator( {}, $form[ 0 ] ), null, input, 2 ); + assert.ok( proxy(), "the number of files does not exceed the maximum" ); +} ); + +QUnit.test( "file maxfiles - too many", function( assert ) { + var selectedFiles = [ { name: "test1.jpg", size: 500000 }, { name: "test2.jpg", size: 500000 }, { name: "test3.jpg", size: 500000 } ], + input = fileDummyInput( selectedFiles ), + $form = $( "" ), + proxy = $.proxy( $.validator.methods.maxfiles, new $.validator( {}, $form[ 0 ] ), null, input, 2 ); + assert.equal( proxy(), false, "the number of files exceeds the maximum" ); +} );