upload.spec.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import { createVue, destroyVM } from '../util.js';
  2. import ajax from 'packages/upload/src/ajax';
  3. const noop = () => {};
  4. const option = {
  5. onSuccess: noop,
  6. onProgress: noop,
  7. data: { a: 'abc', b: 'bcd' },
  8. filename: 'file.png',
  9. file: new File([JSON.stringify('foo')], {type: 'image/png'}),
  10. action: '/upload',
  11. headers: { region: 'shanghai' }
  12. };
  13. let requests, xhr;
  14. describe('ajax', () => {
  15. beforeEach(() => {
  16. xhr = sinon.useFakeXMLHttpRequest();
  17. requests = [];
  18. xhr.onCreate = req => requests.push(req);
  19. option.onError = noop;
  20. option.onSuccess = noop;
  21. });
  22. afterEach(() => {
  23. xhr.restore();
  24. });
  25. it('request success', done => {
  26. option.onError = done;
  27. option.onSuccess = ret => {
  28. expect(ret).to.eql({ success: true });
  29. done();
  30. };
  31. ajax(option);
  32. requests[0].respond(200, {}, '{"success": true}');
  33. });
  34. it('request width header', done => {
  35. ajax(option);
  36. expect(requests[0].requestHeaders).to.eql({
  37. region: 'shanghai'
  38. });
  39. done();
  40. });
  41. it('40x code should be error', done => {
  42. option.onError = e => {
  43. expect(e.toString()).to.contain('Not found');
  44. done();
  45. };
  46. option.onSuccess = () => done('404 should throw error');
  47. ajax(option);
  48. requests[0].respond(404, {}, 'Not found');
  49. });
  50. it('2xx code should be success', done => {
  51. option.onError = done;
  52. option.onSuccess = ret => {
  53. expect(ret).to.equal('');
  54. done();
  55. };
  56. ajax(option);
  57. requests[0].respond(204, {});
  58. });
  59. });
  60. describe('Upload', () => {
  61. let requests;
  62. let xhr;
  63. beforeEach(() => {
  64. xhr = sinon.useFakeXMLHttpRequest();
  65. requests = [];
  66. xhr.onCreate = req => requests.push(req);
  67. });
  68. afterEach(() => {
  69. xhr.restore();
  70. });
  71. describe('ajax upload', () => {
  72. let uploader;
  73. let handlers = {};
  74. const props = {
  75. props: {
  76. action: '/upload',
  77. onSuccess(res, file, fileList) {
  78. if (handlers.onSuccess) {
  79. handlers.onSuccess(res, file, fileList);
  80. }
  81. },
  82. onError(err, file, fileList) {
  83. if (handlers.onError) {
  84. handlers.onError(err, file, fileList);
  85. }
  86. },
  87. onPreview(file) {
  88. if (handlers.onPreview) {
  89. handlers.onPreview(file);
  90. }
  91. },
  92. limit: 2,
  93. onExceed(files, fileList) {
  94. if (handlers.onExceed) {
  95. handlers.onExceed(files, fileList);
  96. }
  97. },
  98. beforeUpload(file) {
  99. if (handlers.beforeUpload) {
  100. return handlers.beforeUpload(file);
  101. } else {
  102. return true;
  103. }
  104. },
  105. beforeRemove(file, fileList) {
  106. if (handlers.beforeRemove) {
  107. return handlers.beforeRemove(file);
  108. } else {
  109. return true;
  110. }
  111. }
  112. }
  113. };
  114. beforeEach(() => {
  115. uploader = createVue({
  116. render(h) {
  117. return (
  118. <el-upload {...props} ref="upload">
  119. <el-button size="small" type="primary">点击上传</el-button>
  120. </el-upload>
  121. );
  122. }
  123. }, true).$refs.upload;
  124. });
  125. afterEach(() => {
  126. destroyVM(uploader);
  127. handlers = {};
  128. });
  129. it('upload success', done => {
  130. const file = new Blob([JSON.stringify({}, null, 2)], {
  131. type: 'application/json'
  132. });
  133. file.name = 'success.png';
  134. const files = [file];
  135. handlers.onSuccess = (res, file, fileList) => {
  136. expect(file.name).to.equal('success.png');
  137. expect(fileList.length).to.equal(1);
  138. expect(res).to.equal('success.png');
  139. done();
  140. };
  141. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  142. setTimeout(() => {
  143. requests[0].respond(200, {}, `${files[0].name}`);
  144. }, 100);
  145. });
  146. it('upload fail', done => {
  147. const file = new Blob([JSON.stringify({}, null, 2)], {
  148. type: 'application/json'
  149. });
  150. file.name = 'fail.png';
  151. const files = [file];
  152. handlers.onError = (err, file, fileList) => {
  153. expect(err instanceof Error).to.equal(true);
  154. expect(file.name).to.equal('fail.png');
  155. done();
  156. };
  157. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  158. setTimeout(() => {
  159. requests[0].respond(400, {}, 'error 400');
  160. }, 100);
  161. });
  162. it('preview file', done => {
  163. const file = new Blob([JSON.stringify({}, null, 2)], {
  164. type: 'application/json'
  165. });
  166. file.name = 'success.png';
  167. const files = [file];
  168. handlers.onPreview = (file) => {
  169. expect(file.response).to.equal('success.png');
  170. done();
  171. };
  172. handlers.onSuccess = (res, file, fileList) => {
  173. uploader.$nextTick(_ => {
  174. uploader.$el.querySelector('.el-upload-list .is-success a').click();
  175. });
  176. };
  177. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  178. setTimeout(() => {
  179. requests[0].respond(200, {}, `${files[0].name}`);
  180. }, 100);
  181. });
  182. it('file remove', done => {
  183. const file = new Blob([JSON.stringify({}, null, 2)], {
  184. type: 'application/json'
  185. });
  186. file.name = 'success.png';
  187. const files = [file];
  188. handlers.onSuccess = (res, file, fileList) => {
  189. uploader.$el.querySelector('.el-upload-list .el-icon-close').click();
  190. uploader.$nextTick(_ => {
  191. expect(uploader.fileList.length).to.equal(0);
  192. done();
  193. });
  194. };
  195. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  196. setTimeout(() => {
  197. requests[0].respond(200, {}, `${files[0].name}`);
  198. }, 100);
  199. });
  200. it('clear files', done => {
  201. const file = new Blob([JSON.stringify({}, null, 2)], {
  202. type: 'application/json'
  203. });
  204. file.name = 'success.png';
  205. const files = [file];
  206. handlers.onSuccess = (res, file, fileList) => {
  207. uploader.clearFiles();
  208. uploader.$nextTick(_ => {
  209. expect(uploader.fileList.length).to.equal(0);
  210. done();
  211. });
  212. };
  213. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  214. setTimeout(() => {
  215. requests[0].respond(200, {}, `${files[0].name}`);
  216. }, 100);
  217. });
  218. it('beforeUpload return promise', done => {
  219. const spy = sinon.spy();
  220. const file = new Blob([JSON.stringify({}, null, 2)], {
  221. type: 'application/json'
  222. });
  223. const files = [file];
  224. handlers.onSuccess = () => {
  225. expect(spy.calledOnce).to.equal(true);
  226. done();
  227. };
  228. handlers.beforeUpload = (file) => {
  229. return new window.Promise((resolve) => {
  230. spy();
  231. resolve(file);
  232. });
  233. };
  234. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  235. setTimeout(() => {
  236. requests[0].respond(200, {}, `${files[0].name}`);
  237. }, 100);
  238. });
  239. it('beforeRemove return rejected promise', done => {
  240. const spy = sinon.spy();
  241. handlers.beforeRemove = (file) => {
  242. return new window.Promise((resolve, reject) => {
  243. spy();
  244. reject();
  245. });
  246. };
  247. const file = new Blob([JSON.stringify({}, null, 2)], {
  248. type: 'application/json'
  249. });
  250. file.name = 'success.png';
  251. const files = [file];
  252. handlers.onSuccess = (res, file, fileList) => {
  253. uploader.$el.querySelector('.el-upload-list .el-icon-close').click();
  254. setTimeout(() => {
  255. expect(spy.calledOnce).to.equal(true);
  256. expect(uploader.uploadFiles.length).to.equal(1);
  257. done();
  258. }, 200);
  259. };
  260. uploader.$refs['upload-inner'].handleChange({ target: { files }});
  261. setTimeout(() => {
  262. requests[0].respond(200, {}, `${files[0].name}`);
  263. }, 100);
  264. });
  265. it('limit files', done => {
  266. const files = [{
  267. name: 'exceed2.png',
  268. type: 'xml'
  269. }, {
  270. name: 'exceed3.png',
  271. type: 'xml'
  272. }];
  273. uploader.uploadFiles = [{
  274. name: 'exceed1.png',
  275. type: 'xml'
  276. }];
  277. handlers.onExceed = (files, fileList) => {
  278. uploader.$nextTick(_ => {
  279. expect(uploader.uploadFiles.length).to.equal(1);
  280. done();
  281. });
  282. };
  283. uploader.$nextTick(_ => uploader.$refs['upload-inner'].handleChange({ target: { files }}));
  284. });
  285. });
  286. });