Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: pkg/http/test/multipart_test.dart

Issue 11363094: Add a multipart HTTP request class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library multipart_test;
6
7 import 'dart:io';
8 import 'dart:utf';
9
10 // TODO(nweiz): get rid of this import before packaging this
11 import '../../../tests/utils/test_utils.dart';
12 // TODO(nweiz): make these package: imports
13 import '../../unittest/lib/unittest.dart';
14 import '../lib/http.dart' as http;
15 import '../lib/src/utils.dart';
16
17 import 'utils.dart';
18
19 /// A matcher that validates the body of a multipart request after finalization.
20 /// The string "{{boundary}}" in [pattern] will be replaced by the boundary
21 /// string for the request, and LF newlines will be replaced with CRLF.
22 /// Indentation will be normalized.
23 Matcher bodyMatches(String pattern) => new _BodyMatches(pattern);
24
25 class _BodyMatches extends BaseMatcher {
26 final String _pattern;
27
28 _BodyMatches(this._pattern);
29
30 bool matches(item, MatchState matchState) {
31 if (item is! http.MultipartRequest) return false;
32
33 var future = consumeInputStream(item.finalize()).transform((bodyBytes) {
34 var body = decodeUtf8(bodyBytes);
35 var contentType = new ContentType.fromString(
36 item.headers['content-type']);
37 var boundary = contentType.parameters['boundary'];
38 var expected = cleanUpLiteral(_pattern)
39 .replaceAll("\n", "\r\n")
40 .replaceAll("{{boundary}}", boundary);
41
42 expect(body, equals(expected));
43 expect(item.contentLength, equals(bodyBytes.length));
44 });
45
46 return completes.matches(future, matchState);
47 }
48
49 Description describe(Description description) {
50 return description.add('has a body that matches "$_pattern"');
51 }
52 }
53
54 void main() {
55 test('empty', () {
56 var request = new http.MultipartRequest('POST', dummyUrl);
57 expect(request, bodyMatches('''
58 --{{boundary}}--
59 '''));
60 });
61
62 test('with fields and files', () {
63 var request = new http.MultipartRequest('POST', dummyUrl);
64 request.fields['field1'] = 'value1';
65 request.fields['field2'] = 'value2';
66 request.files.add(new http.MultipartFile.fromString("file1", "contents1",
67 filename: "filename1.txt"));
68 request.files.add(new http.MultipartFile.fromString("file2", "contents2"));
69
70 expect(request, bodyMatches('''
71 --{{boundary}}
72 content-disposition: form-data; name="field1"
73
74 value1
75 --{{boundary}}
76 content-disposition: form-data; name="field2"
77
78 value2
79 --{{boundary}}
80 content-type: text/plain; charset=UTF-8
81 content-disposition: form-data; name="file1"; filename="filename1.txt"
82
83 contents1
84 --{{boundary}}
85 content-type: text/plain; charset=UTF-8
86 content-disposition: form-data; name="file2"
87
88 contents2
89 --{{boundary}}--
90 '''));
91 });
92
93 test('with a unicode field name', () {
94 var request = new http.MultipartRequest('POST', dummyUrl);
95 request.fields['fïēld'] = 'value';
96
97 expect(request, bodyMatches('''
98 --{{boundary}}
99 content-disposition: form-data; name="f%C3%AF%C4%93ld"
100
101 value
102 --{{boundary}}--
103 '''));
104 });
105
106 test('with a unicode field value', () {
107 var request = new http.MultipartRequest('POST', dummyUrl);
108 request.fields['field'] = 'vⱥlūe';
109
110 expect(request, bodyMatches('''
111 --{{boundary}}
112 content-disposition: form-data; name="field"
113 content-type: text/plain; charset=UTF-8
114
115 vⱥlūe
116 --{{boundary}}--
117 '''));
118 });
119
120 test('with a unicode filename', () {
121 var request = new http.MultipartRequest('POST', dummyUrl);
122 request.files.add(new http.MultipartFile.fromString('file', 'contents',
123 filename: 'fïlēname.txt'));
124
125 expect(request, bodyMatches('''
126 --{{boundary}}
127 content-type: text/plain; charset=UTF-8
128 content-disposition: form-data; name="file"; filename="f%C3%AFl%C4%93nam e.txt"
129
130 contents
131 --{{boundary}}--
132 '''));
133 });
134
135 test('with a string file with a content-type but no charset', () {
136 var request = new http.MultipartRequest('POST', dummyUrl);
137 var file = new http.MultipartFile.fromString('file', '{"hello": "world"}',
138 contentType: new ContentType('application', 'json'));
139 request.files.add(file);
140
141 expect(request, bodyMatches('''
142 --{{boundary}}
143 content-type: application/json; charset=UTF-8
144 content-disposition: form-data; name="file"
145
146 {"hello": "world"}
147 --{{boundary}}--
148 '''));
149 });
150
151 // TODO(nweiz): test creating a multipart file with a charset other than UTF-8
152 // once issue 6284 is fixed.
153
154 // TODO(nweiz): test creating a string with a unicode body once issue 6284 is
155 // fixed.
156
157 test('with a stream file', () {
158 var request = new http.MultipartRequest('POST', dummyUrl);
159 var stream = new ListInputStream();
160 request.files.add(new http.MultipartFile('file', stream, 5));
161
162 expect(request, bodyMatches('''
163 --{{boundary}}
164 content-type: application/octet-stream
165 content-disposition: form-data; name="file"
166
167 hello
168 --{{boundary}}--
169 '''));
170
171 stream.write([104, 101, 108, 108, 111]);
172 stream.markEndOfStream();
173 });
174
175 test('with an empty stream file', () {
176 var request = new http.MultipartRequest('POST', dummyUrl);
177 var stream = new ListInputStream();
178 stream.markEndOfStream();
179 request.files.add(new http.MultipartFile('file', stream, 0));
180
181 expect(request, bodyMatches('''
182 --{{boundary}}
183 content-type: application/octet-stream
184 content-disposition: form-data; name="file"
185
186
187 --{{boundary}}--
188 '''));
189 });
190
191 test('with a byte file', () {
192 var request = new http.MultipartRequest('POST', dummyUrl);
193 var file = new http.MultipartFile.fromBytes(
194 'file', [104, 101, 108, 108, 111]);
195 request.files.add(file);
196
197 expect(request, bodyMatches('''
198 --{{boundary}}
199 content-type: application/octet-stream
200 content-disposition: form-data; name="file"
201
202 hello
203 --{{boundary}}--
204 '''));
205 });
206 }
OLDNEW
« pkg/http/lib/src/multipart_file.dart ('K') | « pkg/http/lib/src/utils.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698