test.js 41 KB

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