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