upload.spec.js 8.2 KB

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