| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library multipart_test; | 5 library multipart_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| 11 import 'package:http/http.dart' as http; | 11 import 'package:http/http.dart' as http; |
| 12 import 'package:http_parser/http_parser.dart'; |
| 12 import 'package:path/path.dart' as path; | 13 import 'package:path/path.dart' as path; |
| 13 import 'package:unittest/unittest.dart'; | 14 import 'package:unittest/unittest.dart'; |
| 14 | 15 |
| 15 import 'utils.dart'; | 16 import 'utils.dart'; |
| 16 | 17 |
| 17 /// A matcher that validates the body of a multipart request after finalization. | 18 /// A matcher that validates the body of a multipart request after finalization. |
| 18 /// The string "{{boundary}}" in [pattern] will be replaced by the boundary | 19 /// The string "{{boundary}}" in [pattern] will be replaced by the boundary |
| 19 /// string for the request, and LF newlines will be replaced with CRLF. | 20 /// string for the request, and LF newlines will be replaced with CRLF. |
| 20 /// Indentation will be normalized. | 21 /// Indentation will be normalized. |
| 21 Matcher bodyMatches(String pattern) => new _BodyMatches(pattern); | 22 Matcher bodyMatches(String pattern) => new _BodyMatches(pattern); |
| 22 | 23 |
| 23 class _BodyMatches extends Matcher { | 24 class _BodyMatches extends Matcher { |
| 24 final String _pattern; | 25 final String _pattern; |
| 25 | 26 |
| 26 _BodyMatches(this._pattern); | 27 _BodyMatches(this._pattern); |
| 27 | 28 |
| 28 bool matches(item, Map matchState) { | 29 bool matches(item, Map matchState) { |
| 29 if (item is! http.MultipartRequest) return false; | 30 if (item is! http.MultipartRequest) return false; |
| 30 | 31 |
| 31 var future = item.finalize().toBytes().then((bodyBytes) { | 32 var future = item.finalize().toBytes().then((bodyBytes) { |
| 32 var body = UTF8.decode(bodyBytes); | 33 var body = UTF8.decode(bodyBytes); |
| 33 var contentType = ContentType.parse(item.headers['content-type']); | 34 var contentType = new MediaType.parse(item.headers['content-type']); |
| 34 var boundary = contentType.parameters['boundary']; | 35 var boundary = contentType.parameters['boundary']; |
| 35 var expected = cleanUpLiteral(_pattern) | 36 var expected = cleanUpLiteral(_pattern) |
| 36 .replaceAll("\n", "\r\n") | 37 .replaceAll("\n", "\r\n") |
| 37 .replaceAll("{{boundary}}", boundary); | 38 .replaceAll("{{boundary}}", boundary); |
| 38 | 39 |
| 39 expect(body, equals(expected)); | 40 expect(body, equals(expected)); |
| 40 expect(item.contentLength, equals(bodyBytes.length)); | 41 expect(item.contentLength, equals(bodyBytes.length)); |
| 41 }); | 42 }); |
| 42 | 43 |
| 43 return completes.matches(future, matchState); | 44 return completes.matches(future, matchState); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 content-disposition: form-data; name="file"; filename="foo%22bar" | 182 content-disposition: form-data; name="file"; filename="foo%22bar" |
| 182 | 183 |
| 183 contents | 184 contents |
| 184 --{{boundary}}-- | 185 --{{boundary}}-- |
| 185 ''')); | 186 ''')); |
| 186 }); | 187 }); |
| 187 | 188 |
| 188 test('with a string file with a content-type but no charset', () { | 189 test('with a string file with a content-type but no charset', () { |
| 189 var request = new http.MultipartRequest('POST', dummyUrl); | 190 var request = new http.MultipartRequest('POST', dummyUrl); |
| 190 var file = new http.MultipartFile.fromString('file', '{"hello": "world"}', | 191 var file = new http.MultipartFile.fromString('file', '{"hello": "world"}', |
| 191 contentType: new ContentType('application', 'json')); | 192 contentType: new MediaType('application', 'json')); |
| 192 request.files.add(file); | 193 request.files.add(file); |
| 193 | 194 |
| 194 expect(request, bodyMatches(''' | 195 expect(request, bodyMatches(''' |
| 195 --{{boundary}} | 196 --{{boundary}} |
| 196 content-type: application/json; charset=utf-8 | 197 content-type: application/json; charset=utf-8 |
| 197 content-disposition: form-data; name="file" | 198 content-disposition: form-data; name="file" |
| 198 | 199 |
| 199 {"hello": "world"} | 200 {"hello": "world"} |
| 200 --{{boundary}}-- | 201 --{{boundary}}-- |
| 201 ''')); | 202 ''')); |
| 202 }); | 203 }); |
| 203 | 204 |
| 204 test('with a file with a iso-8859-1 body', () { | 205 test('with a file with a iso-8859-1 body', () { |
| 205 var request = new http.MultipartRequest('POST', dummyUrl); | 206 var request = new http.MultipartRequest('POST', dummyUrl); |
| 206 // "Ã¥" encoded as ISO-8859-1 and then read as UTF-8 results in "å". | 207 // "Ã¥" encoded as ISO-8859-1 and then read as UTF-8 results in "å". |
| 207 var file = new http.MultipartFile.fromString('file', 'non-ascii: "Ã¥"', | 208 var file = new http.MultipartFile.fromString('file', 'non-ascii: "Ã¥"', |
| 208 contentType: new ContentType('text', 'plain', charset: 'iso-8859-1')); | 209 contentType: new MediaType('text', 'plain', {'charset': 'iso-8859-1'})); |
| 209 request.files.add(file); | 210 request.files.add(file); |
| 210 | 211 |
| 211 expect(request, bodyMatches(''' | 212 expect(request, bodyMatches(''' |
| 212 --{{boundary}} | 213 --{{boundary}} |
| 213 content-type: text/plain; charset=iso-8859-1 | 214 content-type: text/plain; charset=iso-8859-1 |
| 214 content-disposition: form-data; name="file" | 215 content-disposition: form-data; name="file" |
| 215 | 216 |
| 216 non-ascii: "å" | 217 non-ascii: "å" |
| 217 --{{boundary}}-- | 218 --{{boundary}}-- |
| 218 ''')); | 219 ''')); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 content-type: application/octet-stream | 292 content-type: application/octet-stream |
| 292 content-disposition: form-data; name="file"; filename="test-file" | 293 content-disposition: form-data; name="file"; filename="test-file" |
| 293 | 294 |
| 294 hello | 295 hello |
| 295 --{{boundary}}-- | 296 --{{boundary}}-- |
| 296 ''')); | 297 ''')); |
| 297 }), completes); | 298 }), completes); |
| 298 }); | 299 }); |
| 299 }); | 300 }); |
| 300 } | 301 } |
| OLD | NEW |