OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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 pub_lish_test; | 5 library pub_lish_test; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'dart:json' as json; | 8 import 'dart:json' as json; |
9 | 9 |
10 import 'test_pub.dart'; | 10 import 'test_pub.dart'; |
(...skipping 11 matching lines...) Expand all Loading... |
22 body = { | 22 body = { |
23 'url': url.resolve('/upload').toString(), | 23 'url': url.resolve('/upload').toString(), |
24 'fields': { | 24 'fields': { |
25 'field1': 'value1', | 25 'field1': 'value1', |
26 'field2': 'value2' | 26 'field2': 'value2' |
27 } | 27 } |
28 }; | 28 }; |
29 } | 29 } |
30 | 30 |
31 response.headers.contentType = new ContentType("application", "json"); | 31 response.headers.contentType = new ContentType("application", "json"); |
32 response.outputStream.writeString(json.stringify(body)); | 32 response.addString(json.stringify(body)); |
33 response.outputStream.close(); | 33 response.close(); |
34 }); | 34 }); |
35 }); | 35 }); |
36 } | 36 } |
37 | 37 |
38 void handleUpload(ScheduledServer server) { | 38 void handleUpload(ScheduledServer server) { |
39 server.handle('POST', '/upload', (request, response) { | 39 server.handle('POST', '/upload', (request, response) { |
40 // TODO(nweiz): Once a multipart/form-data parser in Dart exists, validate | 40 // TODO(nweiz): Once a multipart/form-data parser in Dart exists, validate |
41 // that the request body is correctly formatted. See issue 6952. | 41 // that the request body is correctly formatted. See issue 6952. |
42 return drainInputStream(request.inputStream).then((_) { | 42 return drainStream(request).then((_) { |
43 return server.url; | 43 return server.url; |
44 }).then((url) { | 44 }).then((url) { |
45 response.statusCode = 302; | 45 response.statusCode = 302; |
46 response.headers.set('location', url.resolve('/create').toString()); | 46 response.headers.set('location', url.resolve('/create').toString()); |
47 response.outputStream.close(); | 47 response.close(); |
48 }); | 48 }); |
49 }); | 49 }); |
50 } | 50 } |
51 | 51 |
52 main() { | 52 main() { |
53 initConfig(); | 53 initConfig(); |
54 setUp(() => normalPackage.scheduleCreate()); | 54 setUp(() => normalPackage.scheduleCreate()); |
55 | 55 |
56 integration('archives and uploads a package', () { | 56 integration('archives and uploads a package', () { |
57 var server = new ScheduledServer(); | 57 var server = new ScheduledServer(); |
58 credentialsFile(server, 'access token').scheduleCreate(); | 58 credentialsFile(server, 'access token').scheduleCreate(); |
59 var pub = startPubLish(server); | 59 var pub = startPubLish(server); |
60 | 60 |
61 confirmPublish(pub); | 61 confirmPublish(pub); |
62 handleUploadForm(server); | 62 handleUploadForm(server); |
63 handleUpload(server); | 63 handleUpload(server); |
64 | 64 |
65 server.handle('GET', '/create', (request, response) { | 65 server.handle('GET', '/create', (request, response) { |
66 response.outputStream.writeString(json.stringify({ | 66 response.addString(json.stringify({ |
67 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 67 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
68 })); | 68 })); |
69 response.outputStream.close(); | 69 response.close(); |
70 }); | 70 }); |
71 | 71 |
72 // TODO(rnystrom): The confirm line is run together with this one because | 72 // TODO(rnystrom): The confirm line is run together with this one because |
73 // in normal usage, the user will have entered a newline on stdin which | 73 // in normal usage, the user will have entered a newline on stdin which |
74 // gets echoed to the terminal. Do something better here? | 74 // gets echoed to the terminal. Do something better here? |
75 expectLater(pub.nextLine(), equals( | 75 expectLater(pub.nextLine(), equals( |
76 'Looks great! Are you ready to upload your package (y/n)?' | 76 'Looks great! Are you ready to upload your package (y/n)?' |
77 ' Package test_pkg 1.0.0 uploaded!')); | 77 ' Package test_pkg 1.0.0 uploaded!')); |
78 pub.shouldExit(0); | 78 pub.shouldExit(0); |
79 }); | 79 }); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 dir(appPath, [pubspec(pkg)]).scheduleCreate(); | 143 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
144 | 144 |
145 var server = new ScheduledServer(); | 145 var server = new ScheduledServer(); |
146 credentialsFile(server, 'access token').scheduleCreate(); | 146 credentialsFile(server, 'access token').scheduleCreate(); |
147 var pub = startPubLish(server); | 147 var pub = startPubLish(server); |
148 pub.writeLine("y"); | 148 pub.writeLine("y"); |
149 handleUploadForm(server); | 149 handleUploadForm(server); |
150 handleUpload(server); | 150 handleUpload(server); |
151 | 151 |
152 server.handle('GET', '/create', (request, response) { | 152 server.handle('GET', '/create', (request, response) { |
153 response.outputStream.writeString(json.stringify({ | 153 response.addString(json.stringify({ |
154 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 154 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
155 })); | 155 })); |
156 response.outputStream.close(); | 156 response.close(); |
157 }); | 157 }); |
158 | 158 |
159 pub.shouldExit(0); | 159 pub.shouldExit(0); |
160 expectLater(pub.remainingStdout(), | 160 expectLater(pub.remainingStdout(), |
161 contains('Package test_pkg 1.0.0 uploaded!')); | 161 contains('Package test_pkg 1.0.0 uploaded!')); |
162 }); | 162 }); |
163 | 163 |
164 integration('upload form provides an error', () { | 164 integration('upload form provides an error', () { |
165 var server = new ScheduledServer(); | 165 var server = new ScheduledServer(); |
166 credentialsFile(server, 'access token').scheduleCreate(); | 166 credentialsFile(server, 'access token').scheduleCreate(); |
167 var pub = startPubLish(server); | 167 var pub = startPubLish(server); |
168 | 168 |
169 confirmPublish(pub); | 169 confirmPublish(pub); |
170 | 170 |
171 server.handle('GET', '/packages/versions/new.json', (request, response) { | 171 server.handle('GET', '/packages/versions/new.json', (request, response) { |
172 response.statusCode = 400; | 172 response.statusCode = 400; |
173 response.outputStream.writeString(json.stringify({ | 173 response.addString(json.stringify({ |
174 'error': {'message': 'your request sucked'} | 174 'error': {'message': 'your request sucked'} |
175 })); | 175 })); |
176 response.outputStream.close(); | 176 response.close(); |
177 }); | 177 }); |
178 | 178 |
179 expectLater(pub.nextErrLine(), equals('your request sucked')); | 179 expectLater(pub.nextErrLine(), equals('your request sucked')); |
180 pub.shouldExit(1); | 180 pub.shouldExit(1); |
181 }); | 181 }); |
182 | 182 |
183 integration('upload form provides invalid JSON', () { | 183 integration('upload form provides invalid JSON', () { |
184 var server = new ScheduledServer(); | 184 var server = new ScheduledServer(); |
185 credentialsFile(server, 'access token').scheduleCreate(); | 185 credentialsFile(server, 'access token').scheduleCreate(); |
186 var pub = startPubLish(server); | 186 var pub = startPubLish(server); |
187 | 187 |
188 confirmPublish(pub); | 188 confirmPublish(pub); |
189 | 189 |
190 server.handle('GET', '/packages/versions/new.json', (request, response) { | 190 server.handle('GET', '/packages/versions/new.json', (request, response) { |
191 response.outputStream.writeString('{not json'); | 191 response.addString('{not json'); |
192 response.outputStream.close(); | 192 response.close(); |
193 }); | 193 }); |
194 | 194 |
195 expectLater(pub.nextErrLine(), equals('Invalid server response:')); | 195 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
196 expectLater(pub.nextErrLine(), equals('{not json')); | 196 expectLater(pub.nextErrLine(), equals('{not json')); |
197 pub.shouldExit(1); | 197 pub.shouldExit(1); |
198 }); | 198 }); |
199 | 199 |
200 integration('upload form is missing url', () { | 200 integration('upload form is missing url', () { |
201 var server = new ScheduledServer(); | 201 var server = new ScheduledServer(); |
202 credentialsFile(server, 'access token').scheduleCreate(); | 202 credentialsFile(server, 'access token').scheduleCreate(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 285 |
286 integration('cloud storage upload provides an error', () { | 286 integration('cloud storage upload provides an error', () { |
287 var server = new ScheduledServer(); | 287 var server = new ScheduledServer(); |
288 credentialsFile(server, 'access token').scheduleCreate(); | 288 credentialsFile(server, 'access token').scheduleCreate(); |
289 var pub = startPubLish(server); | 289 var pub = startPubLish(server); |
290 | 290 |
291 confirmPublish(pub); | 291 confirmPublish(pub); |
292 handleUploadForm(server); | 292 handleUploadForm(server); |
293 | 293 |
294 server.handle('POST', '/upload', (request, response) { | 294 server.handle('POST', '/upload', (request, response) { |
295 return drainInputStream(request.inputStream).then((_) { | 295 return drainStream(request).then((_) { |
296 response.statusCode = 400; | 296 response.statusCode = 400; |
297 response.headers.contentType = new ContentType('application', 'xml'); | 297 response.headers.contentType = new ContentType('application', 'xml'); |
298 response.outputStream.writeString('<Error><Message>Your request sucked.' | 298 response.addString('<Error><Message>Your request sucked.' |
299 '</Message></Error>'); | 299 '</Message></Error>'); |
300 response.outputStream.close(); | 300 response.close(); |
301 }); | 301 }); |
302 }); | 302 }); |
303 | 303 |
304 // TODO(nweiz): This should use the server's error message once the client | 304 // TODO(nweiz): This should use the server's error message once the client |
305 // can parse the XML. | 305 // can parse the XML. |
306 expectLater(pub.nextErrLine(), equals('Failed to upload the package.')); | 306 expectLater(pub.nextErrLine(), equals('Failed to upload the package.')); |
307 pub.shouldExit(1); | 307 pub.shouldExit(1); |
308 }); | 308 }); |
309 | 309 |
310 integration("cloud storage upload doesn't redirect", () { | 310 integration("cloud storage upload doesn't redirect", () { |
311 var server = new ScheduledServer(); | 311 var server = new ScheduledServer(); |
312 credentialsFile(server, 'access token').scheduleCreate(); | 312 credentialsFile(server, 'access token').scheduleCreate(); |
313 var pub = startPubLish(server); | 313 var pub = startPubLish(server); |
314 | 314 |
315 confirmPublish(pub); | 315 confirmPublish(pub); |
316 handleUploadForm(server); | 316 handleUploadForm(server); |
317 | 317 |
318 server.handle('POST', '/upload', (request, response) { | 318 server.handle('POST', '/upload', (request, response) { |
319 return drainInputStream(request.inputStream).then((_) { | 319 return drainStream(request).then((_) { |
320 // Don't set the location header. | 320 // Don't set the location header. |
321 response.outputStream.close(); | 321 response.close(); |
322 }); | 322 }); |
323 }); | 323 }); |
324 | 324 |
325 expectLater(pub.nextErrLine(), equals('Failed to upload the package.')); | 325 expectLater(pub.nextErrLine(), equals('Failed to upload the package.')); |
326 pub.shouldExit(1); | 326 pub.shouldExit(1); |
327 }); | 327 }); |
328 | 328 |
329 integration('package creation provides an error', () { | 329 integration('package creation provides an error', () { |
330 var server = new ScheduledServer(); | 330 var server = new ScheduledServer(); |
331 credentialsFile(server, 'access token').scheduleCreate(); | 331 credentialsFile(server, 'access token').scheduleCreate(); |
332 var pub = startPubLish(server); | 332 var pub = startPubLish(server); |
333 | 333 |
334 confirmPublish(pub); | 334 confirmPublish(pub); |
335 handleUploadForm(server); | 335 handleUploadForm(server); |
336 handleUpload(server); | 336 handleUpload(server); |
337 | 337 |
338 server.handle('GET', '/create', (request, response) { | 338 server.handle('GET', '/create', (request, response) { |
339 response.statusCode = 400; | 339 response.statusCode = 400; |
340 response.outputStream.writeString(json.stringify({ | 340 response.addString(json.stringify({ |
341 'error': {'message': 'Your package was too boring.'} | 341 'error': {'message': 'Your package was too boring.'} |
342 })); | 342 })); |
343 response.outputStream.close(); | 343 response.close(); |
344 }); | 344 }); |
345 | 345 |
346 expectLater(pub.nextErrLine(), equals('Your package was too boring.')); | 346 expectLater(pub.nextErrLine(), equals('Your package was too boring.')); |
347 pub.shouldExit(1); | 347 pub.shouldExit(1); |
348 }); | 348 }); |
349 | 349 |
350 integration('package creation provides invalid JSON', () { | 350 integration('package creation provides invalid JSON', () { |
351 var server = new ScheduledServer(); | 351 var server = new ScheduledServer(); |
352 credentialsFile(server, 'access token').scheduleCreate(); | 352 credentialsFile(server, 'access token').scheduleCreate(); |
353 var pub = startPubLish(server); | 353 var pub = startPubLish(server); |
354 | 354 |
355 confirmPublish(pub); | 355 confirmPublish(pub); |
356 handleUploadForm(server); | 356 handleUploadForm(server); |
357 handleUpload(server); | 357 handleUpload(server); |
358 | 358 |
359 server.handle('GET', '/create', (request, response) { | 359 server.handle('GET', '/create', (request, response) { |
360 response.outputStream.writeString('{not json'); | 360 response.addString('{not json'); |
361 response.outputStream.close(); | 361 response.close(); |
362 }); | 362 }); |
363 | 363 |
364 expectLater(pub.nextErrLine(), equals('Invalid server response:')); | 364 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
365 expectLater(pub.nextErrLine(), equals('{not json')); | 365 expectLater(pub.nextErrLine(), equals('{not json')); |
366 pub.shouldExit(1); | 366 pub.shouldExit(1); |
367 }); | 367 }); |
368 | 368 |
369 integration('package creation provides a malformed error', () { | 369 integration('package creation provides a malformed error', () { |
370 var server = new ScheduledServer(); | 370 var server = new ScheduledServer(); |
371 credentialsFile(server, 'access token').scheduleCreate(); | 371 credentialsFile(server, 'access token').scheduleCreate(); |
372 var pub = startPubLish(server); | 372 var pub = startPubLish(server); |
373 | 373 |
374 confirmPublish(pub); | 374 confirmPublish(pub); |
375 handleUploadForm(server); | 375 handleUploadForm(server); |
376 handleUpload(server); | 376 handleUpload(server); |
377 | 377 |
378 var body = {'error': 'Your package was too boring.'}; | 378 var body = {'error': 'Your package was too boring.'}; |
379 server.handle('GET', '/create', (request, response) { | 379 server.handle('GET', '/create', (request, response) { |
380 response.statusCode = 400; | 380 response.statusCode = 400; |
381 response.outputStream.writeString(json.stringify(body)); | 381 response.addString(json.stringify(body)); |
382 response.outputStream.close(); | 382 response.close(); |
383 }); | 383 }); |
384 | 384 |
385 expectLater(pub.nextErrLine(), equals('Invalid server response:')); | 385 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
386 expectLater(pub.nextErrLine(), equals(json.stringify(body))); | 386 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
387 pub.shouldExit(1); | 387 pub.shouldExit(1); |
388 }); | 388 }); |
389 | 389 |
390 integration('package creation provides a malformed success', () { | 390 integration('package creation provides a malformed success', () { |
391 var server = new ScheduledServer(); | 391 var server = new ScheduledServer(); |
392 credentialsFile(server, 'access token').scheduleCreate(); | 392 credentialsFile(server, 'access token').scheduleCreate(); |
393 var pub = startPubLish(server); | 393 var pub = startPubLish(server); |
394 | 394 |
395 confirmPublish(pub); | 395 confirmPublish(pub); |
396 handleUploadForm(server); | 396 handleUploadForm(server); |
397 handleUpload(server); | 397 handleUpload(server); |
398 | 398 |
399 var body = {'success': 'Your package was awesome.'}; | 399 var body = {'success': 'Your package was awesome.'}; |
400 server.handle('GET', '/create', (request, response) { | 400 server.handle('GET', '/create', (request, response) { |
401 response.outputStream.writeString(json.stringify(body)); | 401 response.addString(json.stringify(body)); |
402 response.outputStream.close(); | 402 response.close(); |
403 }); | 403 }); |
404 | 404 |
405 expectLater(pub.nextErrLine(), equals('Invalid server response:')); | 405 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
406 expectLater(pub.nextErrLine(), equals(json.stringify(body))); | 406 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
407 pub.shouldExit(1); | 407 pub.shouldExit(1); |
408 }); | 408 }); |
409 | 409 |
410 group('--force', () { | 410 group('--force', () { |
411 setUp(() => normalPackage.scheduleCreate()); | 411 setUp(() => normalPackage.scheduleCreate()); |
412 | 412 |
413 integration('cannot be combined with --dry-run', () { | 413 integration('cannot be combined with --dry-run', () { |
414 schedulePub(args: ['lish', '--force', '--dry-run'], | 414 schedulePub(args: ['lish', '--force', '--dry-run'], |
415 error: "Cannot use both --force and --dry-run.", | 415 error: "Cannot use both --force and --dry-run.", |
416 exitCode: exit_codes.USAGE); | 416 exitCode: exit_codes.USAGE); |
417 }); | 417 }); |
418 | 418 |
419 integration('publishes if there are no warnings or errors', () { | 419 integration('publishes if there are no warnings or errors', () { |
420 var server = new ScheduledServer(); | 420 var server = new ScheduledServer(); |
421 credentialsFile(server, 'access token').scheduleCreate(); | 421 credentialsFile(server, 'access token').scheduleCreate(); |
422 var pub = startPubLish(server, args: ['--force']); | 422 var pub = startPubLish(server, args: ['--force']); |
423 | 423 |
424 handleUploadForm(server); | 424 handleUploadForm(server); |
425 handleUpload(server); | 425 handleUpload(server); |
426 | 426 |
427 server.handle('GET', '/create', (request, response) { | 427 server.handle('GET', '/create', (request, response) { |
428 response.outputStream.writeString(json.stringify({ | 428 response.addString(json.stringify({ |
429 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 429 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
430 })); | 430 })); |
431 response.outputStream.close(); | 431 response.close(); |
432 }); | 432 }); |
433 | 433 |
434 pub.shouldExit(0); | 434 pub.shouldExit(0); |
435 expectLater(pub.remainingStdout(), contains( | 435 expectLater(pub.remainingStdout(), contains( |
436 'Package test_pkg 1.0.0 uploaded!')); | 436 'Package test_pkg 1.0.0 uploaded!')); |
437 }); | 437 }); |
438 | 438 |
439 integration('publishes if there are warnings', () { | 439 integration('publishes if there are warnings', () { |
440 var pkg = package("test_pkg", "1.0.0"); | 440 var pkg = package("test_pkg", "1.0.0"); |
441 pkg["author"] = "Nathan Weizenbaum"; | 441 pkg["author"] = "Nathan Weizenbaum"; |
442 dir(appPath, [pubspec(pkg)]).scheduleCreate(); | 442 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
443 | 443 |
444 var server = new ScheduledServer(); | 444 var server = new ScheduledServer(); |
445 credentialsFile(server, 'access token').scheduleCreate(); | 445 credentialsFile(server, 'access token').scheduleCreate(); |
446 var pub = startPubLish(server, args: ['--force']); | 446 var pub = startPubLish(server, args: ['--force']); |
447 | 447 |
448 handleUploadForm(server); | 448 handleUploadForm(server); |
449 handleUpload(server); | 449 handleUpload(server); |
450 | 450 |
451 server.handle('GET', '/create', (request, response) { | 451 server.handle('GET', '/create', (request, response) { |
452 response.outputStream.writeString(json.stringify({ | 452 response.addString(json.stringify({ |
453 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 453 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
454 })); | 454 })); |
455 response.outputStream.close(); | 455 response.close(); |
456 }); | 456 }); |
457 | 457 |
458 pub.shouldExit(0); | 458 pub.shouldExit(0); |
459 expectLater(pub.remainingStderr(), contains( | 459 expectLater(pub.remainingStderr(), contains( |
460 'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml' | 460 'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml' |
461 ' should have an email address\n' | 461 ' should have an email address\n' |
462 ' (e.g. "name <email>").')); | 462 ' (e.g. "name <email>").')); |
463 expectLater(pub.remainingStdout(), contains( | 463 expectLater(pub.remainingStdout(), contains( |
464 'Package test_pkg 1.0.0 uploaded!')); | 464 'Package test_pkg 1.0.0 uploaded!')); |
465 }); | 465 }); |
466 | 466 |
467 integration('does not publish if there are errors', () { | 467 integration('does not publish if there are errors', () { |
468 var pkg = package("test_pkg", "1.0.0"); | 468 var pkg = package("test_pkg", "1.0.0"); |
469 pkg.remove("homepage"); | 469 pkg.remove("homepage"); |
470 dir(appPath, [pubspec(pkg)]).scheduleCreate(); | 470 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
471 | 471 |
472 var server = new ScheduledServer(); | 472 var server = new ScheduledServer(); |
473 var pub = startPubLish(server, args: ['--force']); | 473 var pub = startPubLish(server, args: ['--force']); |
474 | 474 |
475 pub.shouldExit(0); | 475 pub.shouldExit(0); |
476 expectLater(pub.remainingStderr(), contains( | 476 expectLater(pub.remainingStderr(), contains( |
477 "Sorry, your package is missing a requirement and can't be " | 477 "Sorry, your package is missing a requirement and can't be " |
478 "published yet.")); | 478 "published yet.")); |
479 }); | 479 }); |
480 }); | 480 }); |
481 } | 481 } |
OLD | NEW |