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

Side by Side Diff: pkg/gcloud/test/common.dart

Issue 804973002: Add appengine/gcloud/mustache dependencies. (Closed) Base URL: git@github.com:dart-lang/pub-dartlang-dart.git@master
Patch Set: Added AUTHORS/LICENSE/PATENTS files Created 6 years 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
« no previous file with comments | « pkg/gcloud/pubspec.yaml ('k') | pkg/gcloud/test/common_e2e.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, 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 import 'dart:async';
6 import 'dart:convert';
7
8 import 'package:crypto/crypto.dart' as crypto;
9 import 'package:http/http.dart' as http;
10 import 'package:http/testing.dart' as http_testing;
11 import 'package:http_parser/http_parser.dart' as http_parser;
12 import 'package:mime/mime.dart' as mime;
13 import 'package:unittest/unittest.dart';
14
15 const CONTENT_TYPE_JSON_UTF8 = 'application/json; charset=utf-8';
16
17 const RESPONSE_HEADERS = const {
18 'content-type': CONTENT_TYPE_JSON_UTF8
19 };
20
21 class MockClient extends http.BaseClient {
22 final String rootPath;
23 final Uri rootUri;
24
25 Map<String, Map<Pattern, Function>> mocks = {};
26 http_testing.MockClient client;
27
28 MockClient(String rootPath) :
29 rootPath = rootPath,
30 rootUri = Uri.parse('https://www.googleapis.com${rootPath}') {
31 client = new http_testing.MockClient(handler);
32 }
33
34 void register(String method, Pattern path,
35 http_testing.MockClientHandler handler) {
36 var map = mocks.putIfAbsent(method, () => new Map());
37 if (path is RegExp) {
38 map[new RegExp('$rootPath${path.pattern}')] = handler;
39 } else {
40 map['$rootPath$path'] = handler;
41 }
42 }
43
44 void registerUpload(String method, Pattern path,
45 http_testing.MockClientHandler handler) {
46 var map = mocks.putIfAbsent(method, () => new Map());
47 map['/upload$rootPath$path'] = handler;
48 }
49
50 void registerResumableUpload(String method, Pattern path,
51 http_testing.MockClientHandler handler) {
52 var map = mocks.putIfAbsent(method, () => new Map());
53 map['/resumable/upload$rootPath$path'] = handler;
54 }
55
56 void clear() {
57 mocks = {};
58 }
59
60 Future<http.Response> handler(http.Request request) {
61 expect(request.url.host, 'www.googleapis.com');
62 var path = request.url.path;
63 if (mocks[request.method] == null) {
64 throw 'No mock handler for method ${request.method} found. '
65 'Request URL was: ${request.url}';
66 }
67 var mockHandler;
68 mocks[request.method].forEach((pattern, handler) {
69 if (pattern.matchAsPrefix(path) != null) {
70 mockHandler = handler;
71 }
72 });
73 if (mockHandler == null) {
74 throw 'No mock handler for method ${request.method} and path '
75 '[$path] found. Request URL was: ${request.url}';
76 }
77 return mockHandler(request);
78 }
79
80 Future<http.StreamedResponse> send(http.BaseRequest request) {
81 return client.send(request);
82 }
83
84 Future<http.Response> respond(response) {
85 return new Future.value(
86 new http.Response(
87 JSON.encode(response.toJson()),
88 200,
89 headers: RESPONSE_HEADERS));
90 }
91
92 Future<http.Response> respondEmpty() {
93 return new Future.value(
94 new http.Response('', 200, headers: RESPONSE_HEADERS));
95 }
96
97 Future<http.Response> respondInitiateResumableUpload(project) {
98 Map headers = new Map.from(RESPONSE_HEADERS);
99 headers['location'] =
100 'https://www.googleapis.com/resumable/upload$rootPath'
101 'b/$project/o?uploadType=resumable&alt=json&'
102 'upload_id=AEnB2UqucpaWy7d5cr5iVQzmbQcQlLDIKiClrm0SAX3rJ7UN'
103 'Mu5bEoC9b4teJcJUKpqceCUeqKzuoP_jz2ps_dV0P0nT8OTuZQ';
104 return new Future.value(
105 new http.Response('', 200, headers: headers));
106 }
107
108 Future<http.Response> respondContinueResumableUpload() {
109 return new Future.value(
110 new http.Response('', 308, headers: RESPONSE_HEADERS));
111 }
112
113 Future<http.Response> respondBytes(List<int> bytes) {
114 return new Future.value(
115 new http.Response.bytes(bytes, 200, headers: RESPONSE_HEADERS));
116 }
117
118 Future<http.Response> respondError(statusCode) {
119 var error = {
120 'error': {
121 'code': statusCode,
122 'message': 'error'
123 }
124 };
125 return new Future.value(
126 new http.Response(
127 JSON.encode(error), statusCode, headers: RESPONSE_HEADERS));
128 }
129
130 Future processNormalMediaUpload(http.Request request) {
131 var completer = new Completer();
132
133 var contentType = new http_parser.MediaType.parse(
134 request.headers['content-type']);
135 expect(contentType.mimeType, 'multipart/related');
136 var boundary = contentType.parameters['boundary'];
137
138 var partCount = 0;
139 var json;
140 new Stream.fromIterable([request.bodyBytes, [13, 10]])
141 .transform(new mime.MimeMultipartTransformer(boundary))
142 .listen(
143 ((mime.MimeMultipart mimeMultipart) {
144 var contentType = mimeMultipart.headers['content-type'];
145 partCount++;
146 if (partCount == 1) {
147 // First part in the object JSON.
148 expect(contentType, 'application/json; charset=utf-8');
149 mimeMultipart
150 .transform(UTF8.decoder)
151 .fold('', (p, e) => '$p$e')
152 .then((j) => json = j);
153 } else if (partCount == 2) {
154 // Second part is the base64 encoded bytes.
155 mimeMultipart
156 .transform(ASCII.decoder)
157 .fold('', (p, e) => '$p$e')
158 .then(crypto.CryptoUtils.base64StringToBytes)
159 .then((bytes) {
160 completer.complete(
161 new NormalMediaUpload(json, bytes, contentType));
162 });
163 } else {
164 // Exactly two parts expected.
165 throw 'Unexpected part count';
166 }
167 }));
168
169 return completer.future;
170 }
171 }
172
173 class NormalMediaUpload {
174 final String json;
175 final List<int> bytes;
176 final String contentType;
177 NormalMediaUpload(this.json, this.bytes, this.contentType);
178 }
179
180 // Implementation of http.Client which traces all requests and responses.
181 // Mainly useful for local testing.
182 class TraceClient extends http.BaseClient {
183 final http.Client client;
184
185 TraceClient(this.client);
186
187 Future<http.StreamedResponse> send(http.BaseRequest request) {
188 print(request);
189 return request.finalize().toBytes().then((body) {
190 print('--- START REQUEST ---');
191 print(UTF8.decode(body));
192 print('--- END REQUEST ---');
193 var r = new RequestImpl(request.method, request.url, body);
194 r.headers.addAll(request.headers);
195 return client.send(r).then((http.StreamedResponse rr) {
196 return rr.stream.toBytes().then((body) {
197 print('--- START RESPONSE ---');
198 print(UTF8.decode(body));
199 print('--- END RESPONSE ---');
200 return new http.StreamedResponse(
201 new http.ByteStream.fromBytes(body),
202 rr.statusCode,
203 headers: rr.headers);
204
205 });
206 });
207 });
208 }
209
210 void close() {
211 client.close();
212 }
213 }
214
215 // http.BaseRequest implementationn used by the TraceClient.
216 class RequestImpl extends http.BaseRequest {
217 final List<int> _body;
218
219 RequestImpl(String method, Uri url, this._body)
220 : super(method, url);
221
222 http.ByteStream finalize() {
223 super.finalize();
224 return new http.ByteStream.fromBytes(_body);
225 }
226 }
OLDNEW
« no previous file with comments | « pkg/gcloud/pubspec.yaml ('k') | pkg/gcloud/test/common_e2e.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698