comunicationLeap/node_modules/formidable/test/legacy/simple/test-incoming-form.js
node_modules/formidable/test/legacy/simple/test-incoming-form.jsRaw
1var common = require('../common');
2var MultipartParserStub = GENTLY.stub('./multipart_parser', 'MultipartParser'),
3 QuerystringParserStub = GENTLY.stub('./querystring_parser', 'QuerystringParser'),
4 EventEmitterStub = GENTLY.stub('events', 'EventEmitter'),
5 StreamStub = GENTLY.stub('stream', 'Stream'),
6 FileStub = GENTLY.stub('./file');
7
8var formidable = require(common.lib + '/index'),
9 IncomingForm = formidable.IncomingForm,
10 events = require('events'),
11 fs = require('fs'),
12 path = require('path'),
13 Buffer = require('buffer').Buffer,
14 fixtures = require(TEST_FIXTURES + '/multipart'),
15 form,
16 gently;
17
18function test(test) {
19 gently = new Gently();
20 gently.expect(EventEmitterStub, 'call');
21 form = new IncomingForm();
22 test();
23 gently.verify(test.name);
24}
25
26test(function constructor() {
27 assert.strictEqual(form.error, null);
28 assert.strictEqual(form.ended, false);
29 assert.strictEqual(form.type, null);
30 assert.strictEqual(form.headers, null);
31 assert.strictEqual(form.keepExtensions, false);
32 // Can't assume dir === '/tmp' for portability
33 // assert.strictEqual(form.uploadDir, '/tmp');
34 // Make sure it is a directory instead
35 assert.doesNotThrow(function () {
36 assert(fs.statSync(form.uploadDir).isDirectory());
37 });
38 assert.strictEqual(form.encoding, 'utf-8');
39 assert.strictEqual(form.bytesReceived, null);
40 assert.strictEqual(form.bytesExpected, null);
41 assert.strictEqual(form.maxFieldsSize, 2 * 1024 * 1024);
42 assert.strictEqual(form._parser, null);
43 assert.strictEqual(form._flushing, 0);
44 assert.strictEqual(form._fieldsSize, 0);
45 assert.ok(form instanceof EventEmitterStub);
46 assert.equal(form.constructor.name, 'IncomingForm');
47
48 (function testSimpleConstructor() {
49 gently.expect(EventEmitterStub, 'call');
50 var form = IncomingForm();
51 assert.ok(form instanceof IncomingForm);
52 })();
53
54 (function testSimpleConstructorShortcut() {
55 gently.expect(EventEmitterStub, 'call');
56 var form = formidable();
57 assert.ok(form instanceof IncomingForm);
58 })();
59});
60
61test(function parse() {
62 var REQ = {headers: {}}
63 , emit = {};
64
65 gently.expect(form, 'writeHeaders', function(headers) {
66 assert.strictEqual(headers, REQ.headers);
67 });
68
69 var EVENTS = ['error', 'aborted', 'data', 'end'];
70 gently.expect(REQ, 'on', EVENTS.length, function(event, fn) {
71 assert.equal(event, EVENTS.shift());
72 emit[event] = fn;
73 return this;
74 });
75
76 form.parse(REQ);
77
78 (function testPause() {
79 gently.expect(REQ, 'pause');
80 assert.strictEqual(form.pause(), true);
81 })();
82
83 (function testPauseCriticalException() {
84 form.ended = false;
85
86 var ERR = new Error('dasdsa');
87 gently.expect(REQ, 'pause', function() {
88 throw ERR;
89 });
90
91 gently.expect(form, '_error', function(err) {
92 assert.strictEqual(err, ERR);
93 });
94
95 assert.strictEqual(form.pause(), false);
96 })();
97
98 (function testPauseHarmlessException() {
99 form.ended = true;
100
101 var ERR = new Error('dasdsa');
102 gently.expect(REQ, 'pause', function() {
103 throw ERR;
104 });
105
106 assert.strictEqual(form.pause(), false);
107 })();
108
109 (function testResume() {
110 gently.expect(REQ, 'resume');
111 assert.strictEqual(form.resume(), true);
112 })();
113
114 (function testResumeCriticalException() {
115 form.ended = false;
116
117 var ERR = new Error('dasdsa');
118 gently.expect(REQ, 'resume', function() {
119 throw ERR;
120 });
121
122 gently.expect(form, '_error', function(err) {
123 assert.strictEqual(err, ERR);
124 });
125
126 assert.strictEqual(form.resume(), false);
127 })();
128
129 (function testResumeHarmlessException() {
130 form.ended = true;
131
132 var ERR = new Error('dasdsa');
133 gently.expect(REQ, 'resume', function() {
134 throw ERR;
135 });
136
137 assert.strictEqual(form.resume(), false);
138 })();
139
140 (function testEmitError() {
141 var ERR = new Error('something bad happened');
142 gently.expect(form, '_error',function(err) {
143 assert.strictEqual(err, ERR);
144 });
145 emit.error(ERR);
146 })();
147
148 (function testEmitAborted() {
149 gently.expect(form, 'emit',function(event) {
150 assert.equal(event, 'aborted');
151 });
152 gently.expect(form, '_error');
153
154 emit.aborted();
155 })();
156
157
158 (function testEmitData() {
159 var BUFFER = [1, 2, 3];
160 gently.expect(form, 'write', function(buffer) {
161 assert.strictEqual(buffer, BUFFER);
162 });
163 emit.data(BUFFER);
164 })();
165
166 (function testEmitEnd() {
167 form._parser = {};
168
169 (function testWithError() {
170 var ERR = new Error('haha');
171 gently.expect(form._parser, 'end', function() {
172 return ERR;
173 });
174
175 gently.expect(form, '_error', function(err) {
176 assert.strictEqual(err, ERR);
177 });
178
179 emit.end();
180 })();
181
182 (function testWithoutError() {
183 gently.expect(form._parser, 'end');
184 emit.end();
185 })();
186
187 (function testAfterError() {
188 form.error = true;
189 emit.end();
190 })();
191 })();
192
193 (function testWithCallback() {
194 gently.expect(EventEmitterStub, 'call');
195 var form = new IncomingForm(),
196 REQ = {headers: {}},
197 parseCalled = 0;
198
199 gently.expect(form, 'on', 4, function(event, fn) {
200 if (event == 'field') {
201 fn('field1', 'foo');
202 fn('field1', 'bar');
203 fn('field2', 'nice');
204 }
205
206 if (event == 'file') {
207 fn('file1', '1');
208 fn('file1', '2');
209 fn('file2', '3');
210 }
211
212 if (event == 'end') {
213 fn();
214 }
215 return this;
216 });
217
218 gently.expect(form, 'writeHeaders');
219
220 gently.expect(REQ, 'on', 4, function() {
221 return this;
222 });
223
224 var parseCbOk = function (err, fields, files) {
225 assert.deepEqual(fields, {field1: 'bar', field2: 'nice'});
226 assert.deepEqual(files, {file1: '2', file2: '3'});
227 };
228 form.parse(REQ, parseCbOk);
229
230 var ERR = new Error('test');
231 gently.expect(form, 'on', 3, function(event, fn) {
232 if (event == 'field') {
233 fn('foo', 'bar');
234 }
235
236 if (event == 'error') {
237 fn(ERR);
238 gently.expect(form, 'on');
239 gently.expect(form, 'writeHeaders');
240 gently.expect(REQ, 'on', 4, function() {
241 return this;
242 });
243 }
244 return this;
245 });
246
247 form.parse(REQ, function parseCbErr(err, fields, files) {
248 assert.strictEqual(err, ERR);
249 assert.deepEqual(fields, {foo: 'bar'});
250 });
251 })();
252
253 (function testWriteOrder() {
254 gently.expect(EventEmitterStub, 'call');
255 var form = new IncomingForm();
256 var REQ = new events.EventEmitter();
257 var BUF = {};
258 var DATACB = null;
259
260 REQ.on('newListener', function(event, fn) {
261 if ('data' === event) fn(BUF);
262 });
263
264 gently.expect(form, 'writeHeaders');
265 gently.expect(form, 'write', function(buf) {
266 assert.strictEqual(buf, BUF);
267 });
268
269 form.parse(REQ);
270 })();
271});
272
273test(function pause() {
274 assert.strictEqual(form.pause(), false);
275});
276
277test(function resume() {
278 assert.strictEqual(form.resume(), false);
279});
280
281
282test(function writeHeaders() {
283 var HEADERS = {};
284 gently.expect(form, '_parseContentLength');
285 gently.expect(form, '_parseContentType');
286
287 form.writeHeaders(HEADERS);
288 assert.strictEqual(form.headers, HEADERS);
289});
290
291test(function write() {
292 var parser = {},
293 BUFFER = [1, 2, 3];
294
295 form._parser = parser;
296 form.bytesExpected = 523423;
297
298 (function testBasic() {
299 gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
300 assert.equal(event, 'progress');
301 assert.equal(bytesReceived, BUFFER.length);
302 assert.equal(bytesExpected, form.bytesExpected);
303 });
304
305 gently.expect(parser, 'write', function(buffer) {
306 assert.strictEqual(buffer, BUFFER);
307 return buffer.length;
308 });
309
310 assert.equal(form.write(BUFFER), BUFFER.length);
311 assert.equal(form.bytesReceived, BUFFER.length);
312 })();
313
314 (function testParserError() {
315 gently.expect(form, 'emit');
316
317 gently.expect(parser, 'write', function(buffer) {
318 assert.strictEqual(buffer, BUFFER);
319 return buffer.length - 1;
320 });
321
322 gently.expect(form, '_error', function(err) {
323 assert.ok(err.message.match(/parser error/i));
324 });
325
326 assert.equal(form.write(BUFFER), BUFFER.length - 1);
327 assert.equal(form.bytesReceived, BUFFER.length + BUFFER.length);
328 })();
329
330 (function testUninitialized() {
331 delete form._parser;
332
333 gently.expect(form, '_error', function(err) {
334 assert.ok(err.message.match(/unintialized parser/i));
335 });
336 form.write(BUFFER);
337 })();
338});
339
340test(function parseContentType() {
341 var HEADERS = {};
342
343 form.headers = {'content-type': 'application/x-www-form-urlencoded'};
344 gently.expect(form, '_initUrlencoded');
345 form._parseContentType();
346
347 // accept anything that has 'urlencoded' in it
348 form.headers = {'content-type': 'broken-client/urlencoded-stupid'};
349 gently.expect(form, '_initUrlencoded');
350 form._parseContentType();
351
352 var BOUNDARY = '---------------------------57814261102167618332366269';
353 form.headers = {'content-type': 'multipart/form-data; boundary='+BOUNDARY};
354
355 gently.expect(form, '_initMultipart', function(boundary) {
356 assert.equal(boundary, BOUNDARY);
357 });
358 form._parseContentType();
359
360 (function testQuotedBoundary() {
361 form.headers = {'content-type': 'multipart/form-data; boundary="' + BOUNDARY + '"'};
362
363 gently.expect(form, '_initMultipart', function(boundary) {
364 assert.equal(boundary, BOUNDARY);
365 });
366 form._parseContentType();
367 })();
368
369 (function testNoBoundary() {
370 form.headers = {'content-type': 'multipart/form-data'};
371
372 gently.expect(form, '_error', function(err) {
373 assert.ok(err.message.match(/no multipart boundary/i));
374 });
375 form._parseContentType();
376 })();
377
378 (function testNoContentType() {
379 form.headers = {};
380
381 gently.expect(form, '_error', function(err) {
382 assert.ok(err.message.match(/no content-type/i));
383 });
384 form._parseContentType();
385 })();
386
387 (function testUnknownContentType() {
388 form.headers = {'content-type': 'invalid'};
389
390 gently.expect(form, '_error', function(err) {
391 assert.ok(err.message.match(/unknown content-type/i));
392 });
393 form._parseContentType();
394 })();
395});
396
397test(function parseContentLength() {
398 var HEADERS = {};
399
400 form.headers = {};
401 gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
402 assert.equal(event, 'progress');
403 assert.equal(bytesReceived, 0);
404 assert.equal(bytesExpected, 0);
405 });
406 form._parseContentLength();
407
408 form.headers['content-length'] = '8';
409 gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
410 assert.equal(event, 'progress');
411 assert.equal(bytesReceived, 0);
412 assert.equal(bytesExpected, 8);
413 });
414 form._parseContentLength();
415 assert.strictEqual(form.bytesReceived, 0);
416 assert.strictEqual(form.bytesExpected, 8);
417
418 // JS can be evil, lets make sure we are not
419 form.headers['content-length'] = '08';
420 gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
421 assert.equal(event, 'progress');
422 assert.equal(bytesReceived, 0);
423 assert.equal(bytesExpected, 8);
424 });
425 form._parseContentLength();
426 assert.strictEqual(form.bytesExpected, 8);
427});
428
429test(function _initMultipart() {
430 var BOUNDARY = '123',
431 PARSER;
432
433 gently.expect(MultipartParserStub, 'new', function() {
434 PARSER = this;
435 });
436
437 gently.expect(MultipartParserStub.prototype, 'initWithBoundary', function(boundary) {
438 assert.equal(boundary, BOUNDARY);
439 });
440
441 form._initMultipart(BOUNDARY);
442 assert.equal(form.type, 'multipart');
443 assert.strictEqual(form._parser, PARSER);
444
445 (function testRegularField() {
446 var PART;
447 gently.expect(StreamStub, 'new', function() {
448 PART = this;
449 });
450
451 gently.expect(form, 'onPart', function(part) {
452 assert.strictEqual(part, PART);
453 assert.deepEqual
454 ( part.headers
455 , { 'content-disposition': 'form-data; name="field1"'
456 , 'foo': 'bar'
457 }
458 );
459 assert.equal(part.name, 'field1');
460
461 var strings = ['hello', ' world'];
462 gently.expect(part, 'emit', 2, function(event, b) {
463 assert.equal(event, 'data');
464 assert.equal(b.toString(), strings.shift());
465 });
466
467 gently.expect(part, 'emit', function(event, b) {
468 assert.equal(event, 'end');
469 });
470 });
471
472 PARSER.onPartBegin();
473 PARSER.onHeaderField(new Buffer('content-disposition'), 0, 10);
474 PARSER.onHeaderField(new Buffer('content-disposition'), 10, 19);
475 PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 0, 14);
476 PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 14, 24);
477 PARSER.onHeaderEnd();
478 PARSER.onHeaderField(new Buffer('foo'), 0, 3);
479 PARSER.onHeaderValue(new Buffer('bar'), 0, 3);
480 PARSER.onHeaderEnd();
481 PARSER.onHeadersEnd();
482 PARSER.onPartData(new Buffer('hello world'), 0, 5);
483 PARSER.onPartData(new Buffer('hello world'), 5, 11);
484 PARSER.onPartEnd();
485 })();
486
487 (function testFileField() {
488 var PART;
489 gently.expect(StreamStub, 'new', function() {
490 PART = this;
491 });
492
493 gently.expect(form, 'onPart', function(part) {
494 assert.deepEqual
495 ( part.headers
496 , { 'content-disposition': 'form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'
497 , 'content-type': 'text/plain'
498 }
499 );
500 assert.equal(part.name, 'field2');
501 assert.equal(part.filename, 'Sun"et.jpg');
502 assert.equal(part.mime, 'text/plain');
503
504 gently.expect(part, 'emit', function(event, b) {
505 assert.equal(event, 'data');
506 assert.equal(b.toString(), '... contents of file1.txt ...');
507 });
508
509 gently.expect(part, 'emit', function(event, b) {
510 assert.equal(event, 'end');
511 });
512 });
513
514 PARSER.onPartBegin();
515 PARSER.onHeaderField(new Buffer('content-disposition'), 0, 19);
516 PARSER.onHeaderValue(new Buffer('form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'), 0, 85);
517 PARSER.onHeaderEnd();
518 PARSER.onHeaderField(new Buffer('Content-Type'), 0, 12);
519 PARSER.onHeaderValue(new Buffer('text/plain'), 0, 10);
520 PARSER.onHeaderEnd();
521 PARSER.onHeadersEnd();
522 PARSER.onPartData(new Buffer('... contents of file1.txt ...'), 0, 29);
523 PARSER.onPartEnd();
524 })();
525
526 (function testEnd() {
527 gently.expect(form, '_maybeEnd');
528 PARSER.onEnd();
529 assert.ok(form.ended);
530 })();
531});
532
533test(function _fileName() {
534 // TODO
535 return;
536});
537
538test(function _initUrlencoded() {
539 var PARSER;
540
541 gently.expect(QuerystringParserStub, 'new', function() {
542 PARSER = this;
543 });
544
545 form._initUrlencoded();
546 assert.equal(form.type, 'urlencoded');
547 assert.strictEqual(form._parser, PARSER);
548
549 (function testOnField() {
550 var KEY = 'KEY', VAL = 'VAL';
551 gently.expect(form, 'emit', function(field, key, val) {
552 assert.equal(field, 'field');
553 assert.equal(key, KEY);
554 assert.equal(val, VAL);
555 });
556
557 PARSER.onField(KEY, VAL);
558 })();
559
560 (function testOnEnd() {
561 gently.expect(form, '_maybeEnd');
562
563 PARSER.onEnd();
564 assert.equal(form.ended, true);
565 })();
566});
567
568test(function _error() {
569 var ERR = new Error('bla');
570
571 gently.expect(form, 'pause');
572 gently.expect(form, 'emit', function(event, err) {
573 assert.equal(event, 'error');
574 assert.strictEqual(err, ERR);
575 });
576
577 form._error(ERR);
578 assert.strictEqual(form.error, ERR);
579
580 // make sure _error only does its thing once
581 form._error(ERR);
582});
583
584test(function onPart() {
585 var PART = {};
586 gently.expect(form, 'handlePart', function(part) {
587 assert.strictEqual(part, PART);
588 });
589
590 form.onPart(PART);
591});
592
593test(function handlePart() {
594 (function testUtf8Field() {
595 var PART = new events.EventEmitter();
596 PART.name = 'my_field';
597
598 gently.expect(form, 'emit', function(event, field, value) {
599 assert.equal(event, 'field');
600 assert.equal(field, 'my_field');
601 assert.equal(value, 'hello world: €');
602 });
603
604 form.handlePart(PART);
605 PART.emit('data', new Buffer('hello'));
606 PART.emit('data', new Buffer(' world: '));
607 PART.emit('data', new Buffer([0xE2]));
608 PART.emit('data', new Buffer([0x82, 0xAC]));
609 PART.emit('end');
610 })();
611
612 (function testBinaryField() {
613 var PART = new events.EventEmitter();
614 PART.name = 'my_field2';
615
616 gently.expect(form, 'emit', function(event, field, value) {
617 assert.equal(event, 'field');
618 assert.equal(field, 'my_field2');
619 assert.equal(value, 'hello world: '+new Buffer([0xE2, 0x82, 0xAC]).toString('binary'));
620 });
621
622 form.encoding = 'binary';
623 form.handlePart(PART);
624 PART.emit('data', new Buffer('hello'));
625 PART.emit('data', new Buffer(' world: '));
626 PART.emit('data', new Buffer([0xE2]));
627 PART.emit('data', new Buffer([0x82, 0xAC]));
628 PART.emit('end');
629 })();
630
631 (function testFieldSize() {
632 form.maxFieldsSize = 8;
633 var PART = new events.EventEmitter();
634 PART.name = 'my_field';
635
636 gently.expect(form, '_error', function(err) {
637 assert.equal(err.message, 'maxFieldsSize exceeded, received 9 bytes of field data');
638 });
639
640 form.handlePart(PART);
641 form._fieldsSize = 1;
642 PART.emit('data', new Buffer(7));
643 PART.emit('data', new Buffer(1));
644 })();
645
646 (function testFilePart() {
647 var PART = new events.EventEmitter(),
648 FILE = new events.EventEmitter(),
649 PATH = '/foo/bar';
650
651 PART.name = 'my_file';
652 PART.filename = 'sweet.txt';
653 PART.mime = 'sweet.txt';
654
655 gently.expect(form, '_uploadPath', function(filename) {
656 assert.equal(filename, PART.filename);
657 return PATH;
658 });
659
660 gently.expect(FileStub, 'new', function(properties) {
661 assert.equal(properties.path, PATH);
662 assert.equal(properties.name, PART.filename);
663 assert.equal(properties.type, PART.mime);
664 FILE = this;
665
666 gently.expect(form, 'emit', function (event, field, file) {
667 assert.equal(event, 'fileBegin');
668 assert.strictEqual(field, PART.name);
669 assert.strictEqual(file, FILE);
670 });
671
672 gently.expect(FILE, 'open');
673 });
674
675 form.handlePart(PART);
676 assert.equal(form._flushing, 1);
677
678 var BUFFER;
679 gently.expect(form, 'pause');
680 gently.expect(FILE, 'write', function(buffer, cb) {
681 assert.strictEqual(buffer, BUFFER);
682 gently.expect(form, 'resume');
683 // @todo handle cb(new Err)
684 cb();
685 });
686
687 PART.emit('data', BUFFER = new Buffer('test'));
688
689 gently.expect(FILE, 'end', function(cb) {
690 gently.expect(form, 'emit', function(event, field, file) {
691 assert.equal(event, 'file');
692 assert.strictEqual(file, FILE);
693 });
694
695 gently.expect(form, '_maybeEnd');
696
697 cb();
698 assert.equal(form._flushing, 0);
699 });
700
701 PART.emit('end');
702 })();
703});
704
705test(function _uploadPath() {
706 (function testUniqueId() {
707 var UUID_A, UUID_B;
708 gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
709 assert.equal(uploadDir, form.uploadDir);
710 UUID_A = uuid;
711 });
712 form._uploadPath();
713
714 gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
715 UUID_B = uuid;
716 });
717 form._uploadPath();
718
719 assert.notEqual(UUID_A, UUID_B);
720 })();
721
722 (function testFileExtension() {
723 form.keepExtensions = true;
724 var FILENAME = 'foo.jpg',
725 EXT = '.bar';
726
727 gently.expect(GENTLY.hijacked.path, 'extname', function(filename) {
728 assert.equal(filename, FILENAME);
729 gently.restore(path, 'extname');
730
731 return EXT;
732 });
733
734 gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, name) {
735 assert.equal(path.extname(name), EXT);
736 });
737 form._uploadPath(FILENAME);
738 })();
739});
740
741test(function _maybeEnd() {
742 gently.expect(form, 'emit', 0);
743 form._maybeEnd();
744
745 form.ended = true;
746 form._flushing = 1;
747 form._maybeEnd();
748
749 gently.expect(form, 'emit', function(event) {
750 assert.equal(event, 'end');
751 });
752
753 form.ended = true;
754 form._flushing = 0;
755 form._maybeEnd();
756});