initial commit
[namibia] / public / scripts / blueimp-jQuery-File-Upload / test / test.js
1 /*
2  * jQuery File Upload Plugin Test 6.6
3  * https://github.com/blueimp/jQuery-File-Upload
4  *
5  * Copyright 2010, Sebastian Tschan
6  * https://blueimp.net
7  *
8  * Licensed under the MIT license:
9  * http://www.opensource.org/licenses/MIT
10  */
11
12 /*jslint nomen: true, unparam: true */
13 /*global $, QUnit, document, expect, module, test, asyncTest, start, ok, strictEqual, notStrictEqual */
14
15 $(function () {
16     'use strict';
17
18     QUnit.done = function () {
19         // Delete all uploaded files:
20         var url = $('#fileupload').find('form').prop('action');
21         $.getJSON(url, function (files) {
22             $.each(files, function (index, file) {
23                 $.ajax({
24                     url: url + '?file=' + encodeURIComponent(file.name),
25                     type: 'DELETE'
26                 });
27             });
28         });
29     };
30
31     var lifecycle = {
32             setup: function () {
33                 // Set the .fileupload method to the basic widget method:
34                 $.widget('blueimp.fileupload', $.blueimp.fileupload, {});
35             },
36             teardown: function () {
37                 // De-initialize the file input plugin:
38                 $('#fileupload:blueimp-fileupload').fileupload('destroy');
39                 // Remove all remaining event listeners:
40                 $('#fileupload input').unbind();
41                 $(document).unbind();
42             }
43         },
44         lifecycleUI = {
45             setup: function () {
46                 // Set the .fileupload method to the UI widget method:
47                 $.widget('blueimpUI.fileupload', $.blueimpUI.fileupload, {});
48             },
49             teardown: function () {
50                 // De-initialize the file input plugin:
51                 $('#fileupload:blueimpUI-fileupload').fileupload('destroy');
52                 // Remove all remaining event listeners:
53                 $('#fileupload input, #fileupload button').unbind();
54                 $(document).unbind();
55             }
56         };
57
58     module('Initialization', lifecycle);
59
60     test('Widget initialization', function () {
61         ok($('#fileupload').fileupload().data('fileupload'));
62     });
63
64     test('Data attribute options', function () {
65         $('#fileupload').attr('data-url', 'http://example.org');
66         $('#fileupload').fileupload();
67         strictEqual(
68             $('#fileupload').fileupload('option', 'url'),
69             'http://example.org'
70         );
71     });
72
73     test('File input initialization', function () {
74         var fu = $('#fileupload').fileupload();
75         ok(
76             fu.fileupload('option', 'fileInput').length,
77             'File input field inside of the widget'
78         );
79         ok(
80             fu.fileupload('option', 'fileInput').length,
81             'Widget element as file input field'
82         );
83     });
84
85     test('Drop zone initialization', function () {
86         ok($('#fileupload').fileupload()
87             .fileupload('option', 'dropZone').length);
88     });
89
90     test('Event listeners initialization', function () {
91         var fu = $('#fileupload').fileupload();
92         ok(
93             fu.fileupload('option', 'fileInput')
94                 .data('events').change.length,
95             'Listens to file input change events'
96         );
97         if ($.support.xhrFormDataFileUpload) {
98             ok(
99                 fu.fileupload('option', 'dropZone')
100                     .data('events').drop.length,
101                 'Listens to drop zone drop events'
102             );
103             ok(
104                 fu.fileupload('option', 'dropZone')
105                     .data('events').dragover.length,
106                 'Listens to drop zone dragover events'
107             );
108         }
109     });
110
111     module('API', lifecycle);
112
113     test('destroy', function () {
114         var fu = $('#fileupload').fileupload(),
115             fileInput = fu.fileupload('option', 'fileInput'),
116             dropZone = fu.fileupload('option', 'dropZone');
117         fileInput.change($.noop);
118         dropZone.bind('drop', $.noop);
119         dropZone.bind('dragover', $.noop);
120         fu.fileupload('destroy');
121         strictEqual(
122             fileInput.data('events').change.length,
123             1,
124             'Removes own file input change event listener'
125         );
126         if ($.support.xhrFormDataFileUpload) {
127             strictEqual(
128                 dropZone.data('events').drop.length,
129                 1,
130                 'Removes own drop zone drop event listener'
131             );
132             strictEqual(
133                 dropZone.data('events').dragover.length,
134                 1,
135                 'Removes own drop zone dragover event listener'
136             );
137         }
138     });
139
140     test('disable', function () {
141         var fu = $('#fileupload').fileupload(),
142             fileInput = fu.fileupload('option', 'fileInput'),
143             dropZone = fu.fileupload('option', 'dropZone'),
144             param = {files: [{name: 'test'}]};
145         fileInput.change($.noop);
146         dropZone.bind('drop', $.noop);
147         dropZone.bind('dragover', $.noop);
148         fu.fileupload('disable');
149         strictEqual(
150             fileInput.data('events').change.length,
151             1,
152             'Removes own file input change event listener'
153         );
154         if ($.support.xhrFormDataFileUpload) {
155             strictEqual(
156                 dropZone.data('events').drop.length,
157                 1,
158                 'Removes own drop zone drop event listener'
159             );
160             strictEqual(
161                 dropZone.data('events').dragover.length,
162                 1,
163                 'Removes own drop zone dragover event listener'
164             );
165         }
166         fu.fileupload({
167             add: function (e, data) {
168                 ok(false);
169             }
170         }).fileupload('add', param);
171     });
172
173     test('enable', function () {
174         var fu = $('#fileupload').fileupload(),
175             param = {files: [{name: 'test'}]};
176         fu.fileupload('disable');
177         fu.fileupload('enable');
178         ok(
179             fu.fileupload('option', 'fileInput')
180                 .data('events').change.length,
181             'Listens to file input change events'
182         );
183         if ($.support.xhrFormDataFileUpload) {
184             ok(
185                 fu.fileupload('option', 'dropZone')
186                     .data('events').drop.length,
187                 'Listens to drop zone drop events'
188             );
189             ok(
190                 fu.fileupload('option', 'dropZone')
191                     .data('events').dragover.length,
192                 'Listens to drop zone dragover events'
193             );
194         }
195         $('#fileupload').fileupload({
196             send: function (e, data) {
197                 strictEqual(
198                     data.files[0].name,
199                     'test',
200                     'Triggers send callback'
201                 );
202                 return false;
203             }
204         }).fileupload('send', param);
205     });
206
207     test('option', function () {
208         var fu = $('#fileupload').fileupload(),
209             fileInput = fu.fileupload('option', 'fileInput'),
210             dropZone = fu.fileupload('option', 'dropZone');
211         fu.fileupload('option', 'fileInput', null);
212         fu.fileupload('option', 'dropZone', null);
213         ok(
214             !fileInput.data('events'),
215             'Removes event listener after changing fileInput option'
216         );
217         if ($.support.xhrFormDataFileUpload) {
218             ok(
219                 !dropZone.data('events'),
220                 'Removes event listeners after changing dropZone option'
221             );
222         }
223         fu.fileupload('option', 'fileInput', fileInput);
224         fu.fileupload('option', 'dropZone', dropZone);
225         ok(
226             fileInput.data('events').change.length,
227             'Adds change event listener after setting fileInput option'
228         );
229         if ($.support.xhrFormDataFileUpload) {
230             ok(
231                 dropZone.data('events').drop.length,
232                 'Adds drop event listener after setting dropZone option'
233             );
234             ok(
235                 dropZone.data('events').dragover.length,
236                 'Adds dragover event listener after setting dropZone option'
237             );
238         }
239         fu.fileupload('option', 'dropZone', 'body');
240         strictEqual(
241             fu.fileupload('option', 'dropZone')[0],
242             document.body,
243             'Allow a query string as parameter for the dropZone option'
244         );
245         fu.fileupload('option', 'dropZone', document);
246         strictEqual(
247             fu.fileupload('option', 'dropZone')[0],
248             document,
249             'Allow a document element as parameter for the dropZone option'
250         );
251         fu.fileupload('option', 'fileInput', ':file');
252         strictEqual(
253             fu.fileupload('option', 'fileInput')[0],
254             $(':file')[0],
255             'Allow a query string as parameter for the fileInput option'
256         );
257         fu.fileupload('option', 'fileInput', $(':file')[0]);
258         strictEqual(
259             fu.fileupload('option', 'fileInput')[0],
260             $(':file')[0],
261             'Allow a document element as parameter for the fileInput option'
262         );
263     });
264
265     asyncTest('add', function () {
266         expect(4);
267         var param = {files: [{name: 'test'}]},
268             param2 = {files: [{fileName: 'test', fileSize: 123}]};
269         $('#fileupload').fileupload({
270             add: function (e, data) {
271                 strictEqual(
272                     data.files[0].name,
273                     param.files[0].name,
274                     'Triggers add callback'
275                 );
276             }
277         }).fileupload('add', param).fileupload(
278             'option',
279             'add',
280             function (e, data) {
281                 strictEqual(
282                     data.files[0].name,
283                     param2.files[0].fileName,
284                     'Normalizes fileName'
285                 );
286                 strictEqual(
287                     data.files[0].size,
288                     param2.files[0].fileSize,
289                     'Normalizes fileSize'
290                 );
291                 data.submit().complete(function () {
292                     ok(true, 'data.submit() Returns a jqXHR object');
293                     start();
294                 });
295             }
296         ).fileupload('add', param2);
297     });
298
299     asyncTest('send', function () {
300         expect(3);
301         var param = {files: [{name: 'test'}]};
302         $('#fileupload').fileupload({
303             send: function (e, data) {
304                 strictEqual(
305                     data.files[0].name,
306                     'test',
307                     'Triggers send callback'
308                 );
309             }
310         }).fileupload('send', param).fail(function () {
311             ok(true, 'Allows to abort the request');
312         }).complete(function () {
313             ok(true, 'Returns a jqXHR object');
314             start();
315         }).abort();
316     });
317
318     module('Callbacks', lifecycle);
319
320     asyncTest('add', function () {
321         expect(1);
322         var param = {files: [{name: 'test'}]};
323         $('#fileupload').fileupload({
324             add: function (e, data) {
325                 ok(true, 'Triggers add callback');
326                 start();
327             }
328         }).fileupload('add', param);
329     });
330
331     asyncTest('submit', function () {
332         expect(1);
333         var param = {files: [{name: 'test'}]};
334         $('#fileupload').fileupload({
335             submit: function (e, data) {
336                 ok(true, 'Triggers submit callback');
337                 start();
338                 return false;
339             }
340         }).fileupload('add', param);
341     });
342
343     asyncTest('send', function () {
344         expect(1);
345         var param = {files: [{name: 'test'}]};
346         $('#fileupload').fileupload({
347             send: function (e, data) {
348                 ok(true, 'Triggers send callback');
349                 start();
350                 return false;
351             }
352         }).fileupload('send', param);
353     });
354
355     asyncTest('done', function () {
356         expect(1);
357         var param = {files: [{name: 'test'}]};
358         $('#fileupload').fileupload({
359             done: function (e, data) {
360                 ok(true, 'Triggers done callback');
361                 start();
362             }
363         }).fileupload('send', param);
364     });
365
366     asyncTest('fail', function () {
367         expect(1);
368         var param = {files: [{name: 'test'}]},
369             fu = $('#fileupload').fileupload({
370                 url: '404',
371                 fail: function (e, data) {
372                     ok(true, 'Triggers fail callback');
373                     start();
374                 }
375             });
376         fu.data('fileupload')._isXHRUpload = function () {
377             return true;
378         };
379         fu.fileupload('send', param);
380     });
381
382     asyncTest('always', function () {
383         expect(2);
384         var param = {files: [{name: 'test'}]},
385             counter = 0,
386             fu = $('#fileupload').fileupload({
387                 always: function (e, data) {
388                     ok(true, 'Triggers always callback');
389                     if (counter === 1) {
390                         start();
391                     } else {
392                         counter += 1;
393                     }
394                 }
395             });
396         fu.data('fileupload')._isXHRUpload = function () {
397             return true;
398         };
399         fu.fileupload('add', param).fileupload(
400             'option',
401             'url',
402             '404'
403         ).fileupload('add', param);
404     });
405
406     asyncTest('progress', function () {
407         expect(1);
408         var param = {files: [{name: 'test'}]},
409             counter = 0;
410         $('#fileupload').fileupload({
411             forceIframeTransport: true,
412             progress: function (e, data) {
413                 ok(true, 'Triggers progress callback');
414                 if (counter === 0) {
415                     start();
416                 } else {
417                     counter += 1;
418                 }
419             }
420         }).fileupload('send', param);
421     });
422
423     asyncTest('progressall', function () {
424         expect(1);
425         var param = {files: [{name: 'test'}]},
426             counter = 0;
427         $('#fileupload').fileupload({
428             forceIframeTransport: true,
429             progressall: function (e, data) {
430                 ok(true, 'Triggers progressall callback');
431                 if (counter === 0) {
432                     start();
433                 } else {
434                     counter += 1;
435                 }
436             }
437         }).fileupload('send', param);
438     });
439
440     asyncTest('start', function () {
441         expect(1);
442         var param = {files: [{name: '1'}, {name: '2'}]},
443             active = 0;
444         $('#fileupload').fileupload({
445             send: function (e, data) {
446                 active += 1;
447             },
448             start: function (e, data) {
449                 ok(!active, 'Triggers start callback before uploads');
450                 start();
451             }
452         }).fileupload('send', param);
453     });
454
455     asyncTest('stop', function () {
456         expect(1);
457         var param = {files: [{name: '1'}, {name: '2'}]},
458             active = 0;
459         $('#fileupload').fileupload({
460             send: function (e, data) {
461                 active += 1;
462             },
463             always: function (e, data) {
464                 active -= 1;
465             },
466             stop: function (e, data) {
467                 ok(!active, 'Triggers stop callback after uploads');
468                 start();
469             }
470         }).fileupload('send', param);
471     });
472
473     test('change', function () {
474         var fu = $('#fileupload').fileupload(),
475             fuo = fu.data('fileupload'),
476             fileInput = fu.fileupload('option', 'fileInput');
477         expect(2);
478         fu.fileupload({
479             change: function (e, data) {
480                 ok(true, 'Triggers change callback');
481                 strictEqual(
482                     data.files.length,
483                     1,
484                     'Creates pseudo File object'
485                 );
486             },
487             add: $.noop
488         });
489         fuo._onChange({
490             data: {fileupload: fuo},
491             target: fileInput[0]
492         });
493     });
494
495     test('paste', function () {
496         var fu = $('#fileupload').fileupload(),
497             fuo = fu.data('fileupload');
498         expect(1);
499         fu.fileupload({
500             paste: function (e, data) {
501                 ok(true, 'Triggers paste callback');
502             },
503             add: $.noop
504         });
505         fuo._onPaste({
506             data: {fileupload: fuo},
507             originalEvent: {clipboardData: {}},
508             preventDefault: $.noop
509         });
510     });
511
512     test('drop', function () {
513         var fu = $('#fileupload').fileupload(),
514             fuo = fu.data('fileupload');
515         expect(1);
516         fu.fileupload({
517             drop: function (e, data) {
518                 ok(true, 'Triggers drop callback');
519             },
520             add: $.noop
521         });
522         fuo._onDrop({
523             data: {fileupload: fuo},
524             originalEvent: {dataTransfer: {}},
525             preventDefault: $.noop
526         });
527     });
528
529     test('dragover', function () {
530         var fu = $('#fileupload').fileupload(),
531             fuo = fu.data('fileupload');
532         expect(1);
533         fu.fileupload({
534             dragover: function (e, data) {
535                 ok(true, 'Triggers dragover callback');
536             },
537             add: $.noop
538         });
539         fuo._onDragOver({
540             data: {fileupload: fuo},
541             originalEvent: {dataTransfer: {}},
542             preventDefault: $.noop
543         });
544     });
545
546     module('Options', lifecycle);
547
548     test('paramName', function () {
549         expect(1);
550         var param = {files: [{name: 'test'}]};
551         $('#fileupload').fileupload({
552             paramName: null,
553             send: function (e, data) {
554                 strictEqual(
555                     data.paramName[0],
556                     data.fileInput.prop('name'),
557                     'Takes paramName from file input field if not set'
558                 );
559                 return false;
560             }
561         }).fileupload('send', param);
562     });
563
564     test('url', function () {
565         expect(1);
566         var param = {files: [{name: 'test'}]};
567         $('#fileupload').fileupload({
568             url: null,
569             send: function (e, data) {
570                 strictEqual(
571                     data.url,
572                     $(data.fileInput.prop('form')).prop('action'),
573                     'Takes url from form action if not set'
574                 );
575                 return false;
576             }
577         }).fileupload('send', param);
578     });
579
580     test('type', function () {
581         expect(2);
582         var param = {files: [{name: 'test'}]};
583         $('#fileupload').fileupload({
584             type: null,
585             send: function (e, data) {
586                 strictEqual(
587                     data.type,
588                     'POST',
589                     'Request type is "POST" if not set to "PUT"'
590                 );
591                 return false;
592             }
593         }).fileupload('send', param);
594         $('#fileupload').fileupload({
595             type: 'PUT',
596             send: function (e, data) {
597                 strictEqual(
598                     data.type,
599                     'PUT',
600                     'Request type is "PUT" if set to "PUT"'
601                 );
602                 return false;
603             }
604         }).fileupload('send', param);
605     });
606
607     test('replaceFileInput', function () {
608         var fu = $('#fileupload').fileupload(),
609             fuo = fu.data('fileupload'),
610             fileInput = fu.fileupload('option', 'fileInput'),
611             fileInputElement = fileInput[0];
612         expect(2);
613         fu.fileupload({
614             replaceFileInput: false,
615             change: function (e, data) {
616                 strictEqual(
617                     fu.fileupload('option', 'fileInput')[0],
618                     fileInputElement,
619                     'Keeps file input with replaceFileInput: false'
620                 );
621             },
622             add: $.noop
623         });
624         fuo._onChange({
625             data: {fileupload: fuo},
626             target: fileInput[0]
627         });
628         fu.fileupload({
629             replaceFileInput: true,
630             change: function (e, data) {
631                 notStrictEqual(
632                     fu.fileupload('option', 'fileInput')[0],
633                     fileInputElement,
634                     'Replaces file input with replaceFileInput: true'
635                 );
636             },
637             add: $.noop
638         });
639         fuo._onChange({
640             data: {fileupload: fuo},
641             target: fileInput[0]
642         });
643     });
644
645     asyncTest('forceIframeTransport', function () {
646         expect(1);
647         var param = {files: [{name: 'test'}]};
648         $('#fileupload').fileupload({
649             forceIframeTransport: true,
650             done: function (e, data) {
651                 strictEqual(
652                     data.dataType.substr(0, 6),
653                     'iframe',
654                     'Iframe Transport is used'
655                 );
656                 start();
657             }
658         }).fileupload('send', param);
659     });
660
661     test('singleFileUploads', function () {
662         expect(3);
663         var fu = $('#fileupload').fileupload(),
664             param = {files: [{name: '1'}, {name: '2'}]},
665             index = 1;
666         fu.data('fileupload')._isXHRUpload = function () {
667             return true;
668         };
669         $('#fileupload').fileupload({
670             singleFileUploads: true,
671             add: function (e, data) {
672                 ok(true, 'Triggers callback number ' + index.toString());
673                 index += 1;
674             }
675         }).fileupload('add', param).fileupload(
676             'option',
677             'singleFileUploads',
678             false
679         ).fileupload('add', param);
680     });
681
682     test('limitMultiFileUploads', function () {
683         expect(3);
684         var fu = $('#fileupload').fileupload(),
685             param = {files: [
686                 {name: '1'},
687                 {name: '2'},
688                 {name: '3'},
689                 {name: '4'},
690                 {name: '5'}
691             ]},
692             index = 1;
693         fu.data('fileupload')._isXHRUpload = function () {
694             return true;
695         };
696         $('#fileupload').fileupload({
697             singleFileUploads: false,
698             limitMultiFileUploads: 2,
699             add: function (e, data) {
700                 ok(true, 'Triggers callback number ' + index.toString());
701                 index += 1;
702             }
703         }).fileupload('add', param);
704     });
705
706     asyncTest('sequentialUploads', function () {
707         expect(6);
708         var param = {files: [
709                 {name: '1'},
710                 {name: '2'},
711                 {name: '3'},
712                 {name: '4'},
713                 {name: '5'},
714                 {name: '6'}
715             ]},
716             addIndex = 0,
717             sendIndex = 0,
718             loadIndex = 0,
719             fu = $('#fileupload').fileupload({
720                 sequentialUploads: true,
721                 add: function (e, data) {
722                     addIndex += 1;
723                     if (addIndex === 4) {
724                         data.submit().abort();
725                     } else {
726                         data.submit();
727                     }
728                 },
729                 send: function (e, data) {
730                     sendIndex += 1;
731                 },
732                 done: function (e, data) {
733                     loadIndex += 1;
734                     strictEqual(sendIndex, loadIndex, 'upload in order');
735                 },
736                 fail: function (e, data) {
737                     strictEqual(data.errorThrown, 'abort', 'upload aborted');
738                 },
739                 stop: function (e) {
740                     start();
741                 }
742             });
743         fu.data('fileupload')._isXHRUpload = function () {
744             return true;
745         };
746         fu.fileupload('add', param);
747     });
748
749     asyncTest('limitConcurrentUploads', function () {
750         expect(12);
751         var param = {files: [
752                 {name: '1'},
753                 {name: '2'},
754                 {name: '3'},
755                 {name: '4'},
756                 {name: '5'},
757                 {name: '6'},
758                 {name: '7'},
759                 {name: '8'},
760                 {name: '9'},
761                 {name: '10'},
762                 {name: '11'},
763                 {name: '12'}
764             ]},
765             addIndex = 0,
766             sendIndex = 0,
767             loadIndex = 0,
768             fu = $('#fileupload').fileupload({
769                 limitConcurrentUploads: 3,
770                 add: function (e, data) {
771                     addIndex += 1;
772                     if (addIndex === 4) {
773                         data.submit().abort();
774                     } else {
775                         data.submit();
776                     }
777                 },
778                 send: function (e, data) {
779                     sendIndex += 1;
780                 },
781                 done: function (e, data) {
782                     loadIndex += 1;
783                     ok(sendIndex - loadIndex < 3);
784                 },
785                 fail: function (e, data) {
786                     strictEqual(data.errorThrown, 'abort', 'upload aborted');
787                 },
788                 stop: function (e) {
789                     start();
790                 }
791             });
792         fu.data('fileupload')._isXHRUpload = function () {
793             return true;
794         };
795         fu.fileupload('add', param);
796     });
797
798     if ($.support.xhrFileUpload) {
799         asyncTest('multipart', function () {
800             expect(4);
801             var param = {files: [{
802                     name: 'test.png',
803                     size: 123,
804                     type: 'image/png'
805                 }]},
806                 fu = $('#fileupload').fileupload({
807                     multipart: false,
808                     always: function (e, data) {
809                         strictEqual(
810                             data.contentType,
811                             param.files[0].type,
812                             'non-multipart upload sets file type as contentType'
813                         );
814                         strictEqual(
815                             data.headers['X-File-Name'],
816                             param.files[0].name,
817                             'non-multipart upload sets X-File-Name header'
818                         );
819                         strictEqual(
820                             data.headers['X-File-Type'],
821                             param.files[0].type,
822                             'non-multipart upload sets X-File-Type header'
823                         );
824                         strictEqual(
825                             data.headers['X-File-Size'],
826                             param.files[0].size,
827                             'non-multipart upload sets X-File-Size header'
828                         );
829                         start();
830                     }
831                 });
832             fu.fileupload('send', param);
833         });
834     }
835
836     module('UI Initialization', lifecycleUI);
837
838     test('Widget initialization', function () {
839         ok($('#fileupload').fileupload().data('fileupload'));
840         ok(
841             $('#fileupload').fileupload('option', 'uploadTemplate').length,
842             'Initialized upload template'
843         );
844         ok(
845             $('#fileupload').fileupload('option', 'downloadTemplate').length,
846             'Initialized download template'
847         );
848     });
849
850     test('Buttonbar event listeners', function () {
851         var buttonbar = $('#fileupload .fileupload-buttonbar'),
852             files = [{name: 'test'}];
853         expect(7);
854         $('#fileupload').fileupload({
855             send: function (e, data) {
856                 ok(true, 'Started file upload via global start button');
857             },
858             fail: function (e, data) {
859                 ok(true, 'Canceled file upload via global cancel button');
860                 data.context.remove();
861             },
862             destroy: function (e, data) {
863                 ok(true, 'Delete action called via global delete button');
864             }
865         });
866         ok(
867             buttonbar.find('.start')
868                 .data('events').click.length,
869             'Listens to start button click events'
870         );
871         ok(
872             buttonbar.find('.cancel')
873                 .data('events').click.length,
874             'Listens to cancel button click events'
875         );
876         ok(
877             buttonbar.find('.delete')
878                 .data('events').click.length,
879             'Listens to delete button click events'
880         );
881         $('#fileupload').fileupload('add', {files: files});
882         buttonbar.find('.cancel').click();
883         $('#fileupload').fileupload('add', {files: files});
884         buttonbar.find('.start').click();
885         buttonbar.find('.cancel').click();
886         $('#fileupload').data('fileupload')._renderDownload(files)
887             .appendTo($('#fileupload .files')).show()
888             .find('.delete input').click();
889         buttonbar.find('.delete').click();
890     });
891
892     module('UI API', lifecycleUI);
893
894     test('destroy', function () {
895         var buttonbar = $('#fileupload .fileupload-buttonbar');
896         $('#fileupload').fileupload();
897         buttonbar.find('button').click($.noop);
898         $('#fileupload').fileupload('destroy');
899         strictEqual(
900             buttonbar.find('.start').data('events').click.length,
901             1,
902             'Removes own start button click event listener'
903         );
904         strictEqual(
905             buttonbar.find('.cancel').data('events').click.length,
906             1,
907             'Removes own cancel button click event listener'
908         );
909         strictEqual(
910             buttonbar.find('.delete').data('events').click.length,
911             1,
912             'Removes own delete button click event listener'
913         );
914     });
915
916     test('disable', function () {
917         var buttonbar = $('#fileupload .fileupload-buttonbar');
918         $('#fileupload').fileupload();
919         $('#fileupload').fileupload('disable');
920         strictEqual(
921             buttonbar.find('input[type=file], button').not(':disabled').length,
922             0,
923             'Disables the buttonbar buttons'
924         );
925     });
926
927     test('enable', function () {
928         var buttonbar = $('#fileupload .fileupload-buttonbar');
929         $('#fileupload')
930             .fileupload()
931             .fileupload('disable')
932             .fileupload('enable');
933         strictEqual(
934             buttonbar.find('input[type=file], button').not(':disabled').length,
935             4,
936             'Enables the buttonbar buttons'
937         );
938     });
939
940     module('UI Callbacks', lifecycleUI);
941
942     test('destroy', function () {
943         expect(3);
944         $('#fileupload').fileupload({
945             destroy: function (e, data) {
946                 ok(true, 'Triggers destroy callback');
947                 strictEqual(
948                     data.url,
949                     'test',
950                     'Passes over deletion url parameter'
951                 );
952                 strictEqual(
953                     data.type,
954                     'DELETE',
955                     'Passes over deletion request type parameter'
956                 );
957             }
958         });
959         $('#fileupload').data('fileupload')._renderDownload([{
960             name: 'test',
961             delete_url: 'test',
962             delete_type: 'DELETE'
963         }]).appendTo($('#fileupload .files')).show()
964             .find('.delete input').click();
965         $('#fileupload .fileupload-buttonbar .delete').click();
966     });
967
968     asyncTest('added', function () {
969         expect(1);
970         var param = {files: [{name: 'test'}]};
971         $('#fileupload').fileupload({
972             added: function (e, data) {
973                 start();
974                 strictEqual(
975                     data.files[0].name,
976                     param.files[0].name,
977                     'Triggers added callback'
978                 );
979             },
980             send: function () {
981                 return false;
982             }
983         }).fileupload('add', param);
984     });
985
986     asyncTest('started', function () {
987         expect(1);
988         var param = {files: [{name: 'test'}]};
989         $('#fileupload').fileupload({
990             started: function (e) {
991                 start();
992                 ok('Triggers started callback');
993                 return false;
994             },
995             sent: function (e, data) {
996                 return false;
997             }
998         }).fileupload('send', param);
999     });
1000
1001     asyncTest('sent', function () {
1002         expect(1);
1003         var param = {files: [{name: 'test'}]};
1004         $('#fileupload').fileupload({
1005             sent: function (e, data) {
1006                 start();
1007                 strictEqual(
1008                     data.files[0].name,
1009                     param.files[0].name,
1010                     'Triggers sent callback'
1011                 );
1012                 return false;
1013             }
1014         }).fileupload('send', param);
1015     });
1016
1017     asyncTest('completed', function () {
1018         expect(1);
1019         var param = {files: [{name: 'test'}]};
1020         $('#fileupload').fileupload({
1021             completed: function (e, data) {
1022                 start();
1023                 ok('Triggers completed callback');
1024                 return false;
1025             }
1026         }).fileupload('send', param);
1027     });
1028
1029     asyncTest('failed', function () {
1030         expect(1);
1031         var param = {files: [{name: 'test'}]};
1032         $('#fileupload').fileupload({
1033             failed: function (e, data) {
1034                 start();
1035                 ok('Triggers failed callback');
1036                 return false;
1037             }
1038         }).fileupload('send', param).abort();
1039     });
1040
1041     asyncTest('stopped', function () {
1042         expect(1);
1043         var param = {files: [{name: 'test'}]};
1044         $('#fileupload').fileupload({
1045             stopped: function (e, data) {
1046                 start();
1047                 ok('Triggers stopped callback');
1048                 return false;
1049             }
1050         }).fileupload('send', param);
1051     });
1052
1053     asyncTest('destroyed', function () {
1054         expect(1);
1055         $('#fileupload').fileupload({
1056             destroyed: function (e, data) {
1057                 start();
1058                 ok(true, 'Triggers destroyed callback');
1059             }
1060         });
1061         $('#fileupload').data('fileupload')._renderDownload([{
1062             name: 'test',
1063             delete_url: 'test',
1064             delete_type: 'DELETE'
1065         }]).appendTo($('#fileupload .files')).show()
1066             .find('.delete input').click();
1067         $('#fileupload .fileupload-buttonbar .delete').click();
1068     });
1069
1070     module('UI Options', lifecycleUI);
1071
1072     test('autoUpload', function () {
1073         expect(1);
1074         $('#fileupload')
1075             .fileupload({
1076                 autoUpload: true,
1077                 send: function (e, data) {
1078                     ok(true, 'Started file upload automatically');
1079                     return false;
1080                 }
1081             })
1082             .fileupload('add', {files: [{name: 'test'}]})
1083             .fileupload('option', 'autoUpload', false)
1084             .fileupload('add', {files: [{name: 'test'}]});
1085     });
1086
1087     test('maxNumberOfFiles', function () {
1088         expect(4);
1089         var addIndex = 0,
1090             sendIndex = 0;
1091         $('#fileupload')
1092             .fileupload({
1093                 autoUpload: true,
1094                 maxNumberOfFiles: 1,
1095                 singleFileUploads: false,
1096                 send: function (e, data) {
1097                     strictEqual(
1098                         sendIndex += 1,
1099                         addIndex
1100                     );
1101                 },
1102                 done: $.noop,
1103                 stop: $.noop
1104             })
1105             .fileupload('add', {files: [{name: (addIndex += 1)}]})
1106             .fileupload('add', {files: [{name: 'test'}]})
1107             .fileupload('option', 'maxNumberOfFiles', 1)
1108             .fileupload('add', {files: [{name: 1}, {name: 2}]})
1109             .fileupload({
1110                 maxNumberOfFiles: 1,
1111                 send: function (e, data) {
1112                     strictEqual(
1113                         sendIndex += 1,
1114                         addIndex
1115                     );
1116                     return false;
1117                 }
1118             })
1119             .fileupload('add', {files: [{name: (addIndex += 1)}]})
1120             .fileupload('add', {files: [{name: (addIndex += 1)}]})
1121             .fileupload({
1122                 maxNumberOfFiles: 0,
1123                 send: function (e, data) {
1124                     ok(
1125                         !$.blueimpUI.fileupload.prototype.options
1126                             .send.call(this, e, data)
1127                     );
1128                     return false;
1129                 }
1130             })
1131             .fileupload('send', {files: [{name: 'test'}]});
1132     });
1133
1134     test('maxFileSize', function () {
1135         expect(3);
1136         var addIndex = 0,
1137             sendIndex = 0;
1138         $('#fileupload')
1139             .fileupload({
1140                 autoUpload: true,
1141                 maxFileSize: 1000,
1142                 send: function (e, data) {
1143                     strictEqual(
1144                         sendIndex += 1,
1145                         addIndex
1146                     );
1147                     return false;
1148                 }
1149             })
1150             .fileupload('add', {files: [{
1151                 name: (addIndex += 1)
1152             }]})
1153             .fileupload('add', {files: [{
1154                 name: (addIndex += 1),
1155                 size: 999
1156             }]})
1157             .fileupload('add', {files: [{
1158                 name: 'test',
1159                 size: 1001
1160             }]})
1161             .fileupload({
1162                 send: function (e, data) {
1163                     ok(
1164                         !$.blueimpUI.fileupload.prototype.options
1165                             .send.call(this, e, data)
1166                     );
1167                     return false;
1168                 }
1169             })
1170             .fileupload('send', {files: [{
1171                 name: 'test',
1172                 size: 1001
1173             }]});
1174     });
1175
1176     test('minFileSize', function () {
1177         expect(3);
1178         var addIndex = 0,
1179             sendIndex = 0;
1180         $('#fileupload')
1181             .fileupload({
1182                 autoUpload: true,
1183                 minFileSize: 1000,
1184                 send: function (e, data) {
1185                     strictEqual(
1186                         sendIndex += 1,
1187                         addIndex
1188                     );
1189                     return false;
1190                 }
1191             })
1192             .fileupload('add', {files: [{
1193                 name: (addIndex += 1)
1194             }]})
1195             .fileupload('add', {files: [{
1196                 name: (addIndex += 1),
1197                 size: 1001
1198             }]})
1199             .fileupload('add', {files: [{
1200                 name: 'test',
1201                 size: 999
1202             }]})
1203             .fileupload({
1204                 send: function (e, data) {
1205                     ok(
1206                         !$.blueimpUI.fileupload.prototype.options
1207                             .send.call(this, e, data)
1208                     );
1209                     return false;
1210                 }
1211             })
1212             .fileupload('send', {files: [{
1213                 name: 'test',
1214                 size: 999
1215             }]});
1216     });
1217
1218     test('acceptFileTypes', function () {
1219         expect(3);
1220         var addIndex = 0,
1221             sendIndex = 0;
1222         $('#fileupload')
1223             .fileupload({
1224                 autoUpload: true,
1225                 acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
1226                 previewFileTypes: /none/,
1227                 send: function (e, data) {
1228                     strictEqual(
1229                         sendIndex += 1,
1230                         addIndex
1231                     );
1232                     return false;
1233                 }
1234             })
1235             .fileupload('add', {files: [{
1236                 name: (addIndex += 1) + '.jpg'
1237             }]})
1238             .fileupload('add', {files: [{
1239                 name: (addIndex += 1),
1240                 type: 'image/jpeg'
1241             }]})
1242             .fileupload('add', {files: [{
1243                 name: 'test.txt',
1244                 type: 'text/plain'
1245             }]})
1246             .fileupload({
1247                 send: function (e, data) {
1248                     ok(
1249                         !$.blueimpUI.fileupload.prototype.options
1250                             .send.call(this, e, data)
1251                     );
1252                     return false;
1253                 }
1254             })
1255             .fileupload('send', {files: [{
1256                 name: 'test.txt',
1257                 type: 'text/plain'
1258             }]});
1259     });
1260
1261 });