| 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 utils; | 5 library utils; |
| 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 import "package:unittest/unittest.dart"; | 10 import "package:unittest/unittest.dart"; |
| 11 | 11 |
| 12 import 'package:http_server/http_server.dart'; | 12 import 'package:http_server/http_server.dart'; |
| 13 | 13 |
| 14 import 'http_mock.dart'; |
| 15 |
| 16 /** |
| 17 * Used to flag a given test case as being a mock or not. |
| 18 */ |
| 19 final _isMockTestExpando = new Expando<bool>('isMockTest'); |
| 20 |
| 14 void testVirtualDir(String name, Future func(Directory dir)) { | 21 void testVirtualDir(String name, Future func(Directory dir)) { |
| 22 _testVirtualDir(name, false, func); |
| 23 _testVirtualDir(name, true, func); |
| 24 } |
| 25 |
| 26 void _testVirtualDir(String name, bool useMocks, Future func(Directory dir)) { |
| 27 if(useMocks) { |
| 28 name = '$name, with mocks'; |
| 29 } |
| 30 |
| 15 test(name, () { | 31 test(name, () { |
| 32 // see subsequent access to this expando below |
| 33 _isMockTestExpando[currentTestCase] = useMocks; |
| 34 |
| 16 var dir = Directory.systemTemp.createTempSync('http_server_virtual_'); | 35 var dir = Directory.systemTemp.createTempSync('http_server_virtual_'); |
| 17 | 36 |
| 18 return func(dir) | 37 return func(dir) |
| 19 .whenComplete(() { | 38 .whenComplete(() { |
| 20 return dir.delete(recursive: true); | 39 return dir.delete(recursive: true); |
| 21 }); | 40 }); |
| 22 }); | 41 }); |
| 23 } | 42 } |
| 24 | 43 |
| 25 Future<int> getStatusCodeForVirtDir(VirtualDirectory virtualDir, | 44 Future<int> getStatusCodeForVirtDir(VirtualDirectory virtualDir, |
| 26 String path, | 45 String path, |
| 27 {String host, | 46 {String host, |
| 28 bool secure: false, | 47 bool secure: false, |
| 29 DateTime ifModifiedSince, | 48 DateTime ifModifiedSince, |
| 30 bool rawPath: false, | 49 bool rawPath: false, |
| 31 bool followRedirects: true}) { | 50 bool followRedirects: true}) { |
| 32 return _withServer((server) { | |
| 33 | 51 |
| 34 virtualDir.serve(server); | 52 // if this is a mock test, then run the mock code path |
| 35 return getStatusCode(server.port, path, host: host, secure: secure, | 53 if(_isMockTestExpando[currentTestCase]) { |
| 54 var uri = _getUri(0, path, secure: secure, rawPath: rawPath); |
| 55 |
| 56 var request = new MockHttpRequest(uri, followRedirects: followRedirects, |
| 57 ifModifiedSince: ifModifiedSince); |
| 58 |
| 59 return _withMockRequest(virtualDir, request) |
| 60 .then((response) { |
| 61 return response.statusCode; |
| 62 }); |
| 63 }; |
| 64 |
| 65 assert(_isMockTestExpando[currentTestCase] == false); |
| 66 |
| 67 return _withServer(virtualDir, (port) { |
| 68 return getStatusCode(port, path, host: host, secure: secure, |
| 36 ifModifiedSince: ifModifiedSince, rawPath: rawPath, | 69 ifModifiedSince: ifModifiedSince, rawPath: rawPath, |
| 37 followRedirects: followRedirects); | 70 followRedirects: followRedirects); |
| 38 }); | 71 }); |
| 39 } | 72 } |
| 40 | 73 |
| 41 Future<int> getStatusCode(int port, | 74 Future<int> getStatusCode(int port, |
| 42 String path, | 75 String path, |
| 43 {String host, | 76 {String host, |
| 44 bool secure: false, | 77 bool secure: false, |
| 45 DateTime ifModifiedSince, | 78 DateTime ifModifiedSince, |
| 46 bool rawPath: false, | 79 bool rawPath: false, |
| 47 bool followRedirects: true}) { | 80 bool followRedirects: true}) { |
| 48 Uri uri; | 81 var uri = _getUri(port, path, secure: secure, rawPath: rawPath); |
| 49 if (rawPath) { | |
| 50 uri = new Uri(scheme: secure ? 'https' : 'http', | |
| 51 host: 'localhost', | |
| 52 port: port, | |
| 53 path: path); | |
| 54 } else { | |
| 55 uri = (secure ? | |
| 56 new Uri.https('localhost:$port', path) : | |
| 57 new Uri.http('localhost:$port', path)); | |
| 58 } | |
| 59 | 82 |
| 60 return new HttpClient().getUrl(uri) | 83 return new HttpClient().getUrl(uri) |
| 61 .then((request) { | 84 .then((request) { |
| 62 if (!followRedirects) request.followRedirects = false; | 85 if (!followRedirects) request.followRedirects = false; |
| 63 if (host != null) request.headers.host = host; | 86 if (host != null) request.headers.host = host; |
| 64 if (ifModifiedSince != null) { | 87 if (ifModifiedSince != null) { |
| 65 request.headers.ifModifiedSince = ifModifiedSince; | 88 request.headers.ifModifiedSince = ifModifiedSince; |
| 66 } | 89 } |
| 67 return request.close(); | 90 return request.close(); |
| 68 }) | 91 }) |
| 69 .then((response) => response.drain().then( | 92 .then((response) => response.drain().then( |
| 70 (_) => response.statusCode)); | 93 (_) => response.statusCode)); |
| 71 } | 94 } |
| 72 | 95 |
| 73 Future<HttpHeaders> getHeaders(VirtualDirectory virDir, String path) { | 96 Future<HttpHeaders> getHeaders(VirtualDirectory virDir, String path) { |
| 74 return _withServer((server) { | |
| 75 virDir.serve(server); | |
| 76 | 97 |
| 77 return new HttpClient() | 98 // if this is a mock test, then run the mock code path |
| 78 .get('localhost', server.port, path) | 99 if(_isMockTestExpando[currentTestCase]) { |
| 79 .then((request) => request.close()) | 100 var uri = _getUri(0, path); |
| 80 .then((response) => response.drain().then((_) => response.headers)); | 101 |
| 102 var request = new MockHttpRequest(uri); |
| 103 |
| 104 return _withMockRequest(virDir, request) |
| 105 .then((response) { |
| 106 return response.headers; |
| 107 }); |
| 108 } |
| 109 |
| 110 assert(_isMockTestExpando[currentTestCase] == false); |
| 111 |
| 112 return _withServer(virDir, (port) { |
| 113 return _getHeaders(port, path); |
| 81 }); | 114 }); |
| 82 } | 115 } |
| 83 | 116 |
| 84 Future<String> getAsString(VirtualDirectory virtualDir, String path) { | 117 Future<String> getAsString(VirtualDirectory virtualDir, String path) { |
| 85 return _withServer((server) { | |
| 86 virtualDir.serve(server); | |
| 87 | 118 |
| 88 return new HttpClient() | 119 // if this is a mock test, then run the mock code path |
| 89 .get('localhost', server.port, path) | 120 if(_isMockTestExpando[currentTestCase]) { |
| 90 .then((request) => request.close()) | 121 var uri = _getUri(0, path); |
| 91 .then((response) => UTF8.decodeStream(response)); | 122 |
| 123 var request = new MockHttpRequest(uri); |
| 124 |
| 125 return _withMockRequest(virtualDir, request) |
| 126 .then((response) { |
| 127 return response.mockContent; |
| 128 }); |
| 129 }; |
| 130 |
| 131 assert(_isMockTestExpando[currentTestCase] == false); |
| 132 |
| 133 return _withServer(virtualDir, (int port) { |
| 134 return _getAsString(port, path); |
| 92 }); | 135 }); |
| 93 } | 136 } |
| 94 | 137 |
| 95 Future _withServer(Future func(HttpServer server)) { | 138 Future<MockHttpResponse> _withMockRequest(VirtualDirectory virDir, |
| 139 MockHttpRequest request) { |
| 140 return virDir.serveRequest(request).then((value) { |
| 141 expect(value, isNull); |
| 142 expect(request.response.mockDone, isTrue); |
| 143 return request.response; |
| 144 }) |
| 145 .then((HttpResponse response) { |
| 146 if(response.statusCode == HttpStatus.MOVED_PERMANENTLY || |
| 147 response.statusCode == HttpStatus.MOVED_TEMPORARILY) { |
| 148 if(request.followRedirects == true) { |
| 149 var uri = Uri.parse(response.headers.value(HttpHeaders.LOCATION)); |
| 150 var newMock = new MockHttpRequest(uri, followRedirects: true); |
| 151 |
| 152 return _withMockRequest(virDir, newMock); |
| 153 } |
| 154 } |
| 155 return response; |
| 156 }); |
| 157 } |
| 158 |
| 159 Future _withServer(VirtualDirectory virDir, Future func(int port)) { |
| 96 HttpServer server; | 160 HttpServer server; |
| 97 return HttpServer.bind('localhost', 0) | 161 return HttpServer.bind('localhost', 0) |
| 98 .then((value) { | 162 .then((value) { |
| 99 server = value; | 163 server = value; |
| 100 return func(server); | 164 virDir.serve(server); |
| 165 return func(server.port); |
| 101 }) | 166 }) |
| 102 .whenComplete(() => server.close()); | 167 .whenComplete(() => server.close()); |
| 103 } | 168 } |
| 104 | 169 |
| 170 Future<HttpHeaders> _getHeaders(int port, String path) => |
| 171 new HttpClient() |
| 172 .get('localhost', port, path) |
| 173 .then((request) => request.close()) |
| 174 .then((response) => response.drain().then( |
| 175 (_) => response.headers)); |
| 176 |
| 177 Future<String> _getAsString(int port, String path) => |
| 178 new HttpClient() |
| 179 .get('localhost', port, path) |
| 180 .then((request) => request.close()) |
| 181 .then((response) => UTF8.decodeStream(response)); |
| 182 |
| 183 Uri _getUri(int port, |
| 184 String path, |
| 185 {bool secure: false, |
| 186 bool rawPath: false}) { |
| 187 if (rawPath) { |
| 188 return new Uri(scheme: secure ? 'https' : 'http', |
| 189 host: 'localhost', |
| 190 port: port, |
| 191 path: path); |
| 192 } else { |
| 193 return (secure ? |
| 194 new Uri.https('localhost:$port', path) : |
| 195 new Uri.http('localhost:$port', path)); |
| 196 } |
| 197 } |
| 105 | 198 |
| 106 const CERTIFICATE = "localhost_cert"; | 199 const CERTIFICATE = "localhost_cert"; |
| 107 | 200 |
| 108 | 201 |
| 109 void setupSecure() { | 202 void setupSecure() { |
| 110 String certificateDatabase = Platform.script.resolve('pkcert').toFilePath(); | 203 String certificateDatabase = Platform.script.resolve('pkcert').toFilePath(); |
| 111 SecureSocket.initialize(database: certificateDatabase, | 204 SecureSocket.initialize(database: certificateDatabase, |
| 112 password: 'dartdart'); | 205 password: 'dartdart'); |
| 113 } | 206 } |
| OLD | NEW |