| 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 '../../../pkg/scheduled_test/lib/scheduled_test.dart'; | 10 import 'test_pub.dart'; |
| 11 import '../../../pkg/scheduled_test/lib/scheduled_server.dart'; | 11 import '../../../pkg/unittest/lib/unittest.dart'; |
| 12 | |
| 13 import '../../pub/exit_codes.dart' as exit_codes; | 12 import '../../pub/exit_codes.dart' as exit_codes; |
| 14 import '../../pub/io.dart'; | 13 import '../../pub/io.dart'; |
| 15 import 'descriptor.dart' as d; | |
| 16 import 'test_pub.dart'; | |
| 17 | 14 |
| 18 void handleUploadForm(ScheduledServer server, [Map body]) { | 15 void handleUploadForm(ScheduledServer server, [Map body]) { |
| 19 server.handle('GET', '/packages/versions/new.json', (request) { | 16 server.handle('GET', '/packages/versions/new.json', (request, response) { |
| 20 return server.url.then((url) { | 17 return server.url.then((url) { |
| 21 expect(request.headers.value('authorization'), | 18 expect(request.headers.value('authorization'), |
| 22 equals('Bearer access token')); | 19 equals('Bearer access token')); |
| 23 | 20 |
| 24 if (body == null) { | 21 if (body == null) { |
| 25 body = { | 22 body = { |
| 26 'url': url.resolve('/upload').toString(), | 23 'url': url.resolve('/upload').toString(), |
| 27 'fields': { | 24 'fields': { |
| 28 'field1': 'value1', | 25 'field1': 'value1', |
| 29 'field2': 'value2' | 26 'field2': 'value2' |
| 30 } | 27 } |
| 31 }; | 28 }; |
| 32 } | 29 } |
| 33 | 30 |
| 34 request.response.headers.contentType = | 31 response.headers.contentType = new ContentType("application", "json"); |
| 35 new ContentType("application", "json"); | 32 response.write(json.stringify(body)); |
| 36 request.response.write(json.stringify(body)); | 33 response.close(); |
| 37 request.response.close(); | |
| 38 }); | 34 }); |
| 39 }); | 35 }); |
| 40 } | 36 } |
| 41 | 37 |
| 42 void handleUpload(ScheduledServer server) { | 38 void handleUpload(ScheduledServer server) { |
| 43 server.handle('POST', '/upload', (request) { | 39 server.handle('POST', '/upload', (request, response) { |
| 44 // 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 |
| 45 // that the request body is correctly formatted. See issue 6952. | 41 // that the request body is correctly formatted. See issue 6952. |
| 46 return drainStream(request).then((_) { | 42 return drainStream(request).then((_) { |
| 47 return server.url; | 43 return server.url; |
| 48 }).then((url) { | 44 }).then((url) { |
| 49 request.response.statusCode = 302; | 45 response.statusCode = 302; |
| 50 request.response.headers.set( | 46 response.headers.set('location', url.resolve('/create').toString()); |
| 51 'location', url.resolve('/create').toString()); | 47 response.close(); |
| 52 request.response.close(); | |
| 53 }); | 48 }); |
| 54 }); | 49 }); |
| 55 } | 50 } |
| 56 | 51 |
| 57 main() { | 52 main() { |
| 58 initConfig(); | 53 initConfig(); |
| 59 setUp(() => d.validPackage.create()); | 54 setUp(() => normalPackage.scheduleCreate()); |
| 60 | 55 |
| 61 integration('archives and uploads a package', () { | 56 integration('archives and uploads a package', () { |
| 62 var server = new ScheduledServer(); | 57 var server = new ScheduledServer(); |
| 63 d.credentialsFile(server, 'access token').create(); | 58 credentialsFile(server, 'access token').scheduleCreate(); |
| 64 var pub = startPublish(server); | 59 var pub = startPubLish(server); |
| 65 | 60 |
| 66 confirmPublish(pub); | 61 confirmPublish(pub); |
| 67 handleUploadForm(server); | 62 handleUploadForm(server); |
| 68 handleUpload(server); | 63 handleUpload(server); |
| 69 | 64 |
| 70 server.handle('GET', '/create', (request) { | 65 server.handle('GET', '/create', (request, response) { |
| 71 request.response.write(json.stringify({ | 66 response.write(json.stringify({ |
| 72 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 67 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
| 73 })); | 68 })); |
| 74 request.response.close(); | 69 response.close(); |
| 75 }); | 70 }); |
| 76 | 71 |
| 77 // 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 |
| 78 // 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 |
| 79 // gets echoed to the terminal. Do something better here? | 74 // gets echoed to the terminal. Do something better here? |
| 80 expect(pub.nextLine(), completion(equals( | 75 expectLater(pub.nextLine(), equals( |
| 81 'Looks great! Are you ready to upload your package (y/n)?' | 76 'Looks great! Are you ready to upload your package (y/n)?' |
| 82 ' Package test_pkg 1.0.0 uploaded!'))); | 77 ' Package test_pkg 1.0.0 uploaded!')); |
| 83 pub.shouldExit(0); | 78 pub.shouldExit(0); |
| 84 }); | 79 }); |
| 85 | 80 |
| 86 // TODO(nweiz): Once a multipart/form-data parser in Dart exists, we should | 81 // TODO(nweiz): Once a multipart/form-data parser in Dart exists, we should |
| 87 // test that "pub lish" chooses the correct files to publish. | 82 // test that "pub lish" chooses the correct files to publish. |
| 88 | 83 |
| 89 integration('package validation has an error', () { | 84 integration('package validation has an error', () { |
| 90 var pkg = packageMap("test_pkg", "1.0.0"); | 85 var pkg = package("test_pkg", "1.0.0"); |
| 91 pkg.remove("homepage"); | 86 pkg.remove("homepage"); |
| 92 d.dir(appPath, [d.pubspec(pkg)]).create(); | 87 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 93 | 88 |
| 94 var server = new ScheduledServer(); | 89 var server = new ScheduledServer(); |
| 95 var pub = startPublish(server); | 90 var pub = startPubLish(server); |
| 96 | 91 |
| 97 pub.shouldExit(0); | 92 pub.shouldExit(0); |
| 98 expect(pub.remainingStderr(), completion(contains( | 93 expectLater(pub.remainingStderr(), |
| 99 "Sorry, your package is missing a requirement and can't be published " | 94 contains("Sorry, your package is missing a requirement and can't be " |
| 100 "yet."))); | 95 "published yet.")); |
| 101 }); | 96 }); |
| 102 | 97 |
| 103 integration('preview package validation has a warning', () { | 98 integration('preview package validation has a warning', () { |
| 104 var pkg = packageMap("test_pkg", "1.0.0"); | 99 var pkg = package("test_pkg", "1.0.0"); |
| 105 pkg["author"] = "Nathan Weizenbaum"; | 100 pkg["author"] = "Nathan Weizenbaum"; |
| 106 d.dir(appPath, [d.pubspec(pkg)]).create(); | 101 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 107 | 102 |
| 108 var server = new ScheduledServer(); | 103 var server = new ScheduledServer(); |
| 109 var pub = startPublish(server, args: ['--dry-run']); | 104 var pub = startPubLish(server, args: ['--dry-run']); |
| 110 | 105 |
| 111 pub.shouldExit(0); | 106 pub.shouldExit(0); |
| 112 expect(pub.remainingStderr(), completion(contains( | 107 expectLater(pub.remainingStderr(), |
| 113 'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml should ' | 108 contains('Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml' |
| 114 'have an email address\n' | 109 ' should have an email address\n' |
| 115 ' (e.g. "name <email>").\n\n' | 110 ' (e.g. "name <email>").\n\n' |
| 116 'Package has 1 warning.'))); | 111 'Package has 1 warning.')); |
| 117 }); | 112 }); |
| 118 | 113 |
| 119 integration('preview package validation has no warnings', () { | 114 integration('preview package validation has no warnings', () { |
| 120 var pkg = packageMap("test_pkg", "1.0.0"); | 115 var pkg = package("test_pkg", "1.0.0"); |
| 121 pkg["author"] = "Nathan Weizenbaum <nweiz@google.com>"; | 116 pkg["author"] = "Nathan Weizenbaum <nweiz@google.com>"; |
| 122 d.dir(appPath, [d.pubspec(pkg)]).create(); | 117 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 123 | 118 |
| 124 var server = new ScheduledServer(); | 119 var server = new ScheduledServer(); |
| 125 var pub = startPublish(server, args: ['--dry-run']); | 120 var pub = startPubLish(server, args: ['--dry-run']); |
| 126 | 121 |
| 127 pub.shouldExit(0); | 122 pub.shouldExit(0); |
| 128 expect(pub.remainingStderr(), | 123 expectLater(pub.remainingStderr(), |
| 129 completion(contains('Package has 0 warnings.'))); | 124 contains('Package has 0 warnings.')); |
| 130 }); | 125 }); |
| 131 | 126 |
| 132 integration('package validation has a warning and is canceled', () { | 127 integration('package validation has a warning and is canceled', () { |
| 133 var pkg = packageMap("test_pkg", "1.0.0"); | 128 var pkg = package("test_pkg", "1.0.0"); |
| 134 pkg["author"] = "Nathan Weizenbaum"; | 129 pkg["author"] = "Nathan Weizenbaum"; |
| 135 d.dir(appPath, [d.pubspec(pkg)]).create(); | 130 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 136 | 131 |
| 137 var server = new ScheduledServer(); | 132 var server = new ScheduledServer(); |
| 138 var pub = startPublish(server); | 133 var pub = startPubLish(server); |
| 139 | 134 |
| 140 pub.writeLine("n"); | 135 pub.writeLine("n"); |
| 141 pub.shouldExit(0); | 136 pub.shouldExit(0); |
| 142 expect(pub.remainingStderr(), | 137 expectLater(pub.remainingStderr(), contains("Package upload canceled.")); |
| 143 completion(contains("Package upload canceled."))); | |
| 144 }); | 138 }); |
| 145 | 139 |
| 146 integration('package validation has a warning and continues', () { | 140 integration('package validation has a warning and continues', () { |
| 147 var pkg = packageMap("test_pkg", "1.0.0"); | 141 var pkg = package("test_pkg", "1.0.0"); |
| 148 pkg["author"] = "Nathan Weizenbaum"; | 142 pkg["author"] = "Nathan Weizenbaum"; |
| 149 d.dir(appPath, [d.pubspec(pkg)]).create(); | 143 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 150 | 144 |
| 151 var server = new ScheduledServer(); | 145 var server = new ScheduledServer(); |
| 152 d.credentialsFile(server, 'access token').create(); | 146 credentialsFile(server, 'access token').scheduleCreate(); |
| 153 var pub = startPublish(server); | 147 var pub = startPubLish(server); |
| 154 pub.writeLine("y"); | 148 pub.writeLine("y"); |
| 155 handleUploadForm(server); | 149 handleUploadForm(server); |
| 156 handleUpload(server); | 150 handleUpload(server); |
| 157 | 151 |
| 158 server.handle('GET', '/create', (request) { | 152 server.handle('GET', '/create', (request, response) { |
| 159 request.response.write(json.stringify({ | 153 response.write(json.stringify({ |
| 160 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 154 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
| 161 })); | 155 })); |
| 162 request.response.close(); | 156 response.close(); |
| 163 }); | 157 }); |
| 164 | 158 |
| 165 pub.shouldExit(0); | 159 pub.shouldExit(0); |
| 166 expect(pub.remainingStdout(), | 160 expectLater(pub.remainingStdout(), |
| 167 completion(contains('Package test_pkg 1.0.0 uploaded!'))); | 161 contains('Package test_pkg 1.0.0 uploaded!')); |
| 168 }); | 162 }); |
| 169 | 163 |
| 170 integration('upload form provides an error', () { | 164 integration('upload form provides an error', () { |
| 171 var server = new ScheduledServer(); | 165 var server = new ScheduledServer(); |
| 172 d.credentialsFile(server, 'access token').create(); | 166 credentialsFile(server, 'access token').scheduleCreate(); |
| 173 var pub = startPublish(server); | 167 var pub = startPubLish(server); |
| 174 | 168 |
| 175 confirmPublish(pub); | 169 confirmPublish(pub); |
| 176 | 170 |
| 177 server.handle('GET', '/packages/versions/new.json', (request) { | 171 server.handle('GET', '/packages/versions/new.json', (request, response) { |
| 178 request.response.statusCode = 400; | 172 response.statusCode = 400; |
| 179 request.response.write(json.stringify({ | 173 response.write(json.stringify({ |
| 180 'error': {'message': 'your request sucked'} | 174 'error': {'message': 'your request sucked'} |
| 181 })); | 175 })); |
| 182 request.response.close(); | 176 response.close(); |
| 183 }); | 177 }); |
| 184 | 178 |
| 185 expect(pub.nextErrLine(), completion(equals('your request sucked'))); | 179 expectLater(pub.nextErrLine(), equals('your request sucked')); |
| 186 pub.shouldExit(1); | 180 pub.shouldExit(1); |
| 187 }); | 181 }); |
| 188 | 182 |
| 189 integration('upload form provides invalid JSON', () { | 183 integration('upload form provides invalid JSON', () { |
| 190 var server = new ScheduledServer(); | 184 var server = new ScheduledServer(); |
| 191 d.credentialsFile(server, 'access token').create(); | 185 credentialsFile(server, 'access token').scheduleCreate(); |
| 192 var pub = startPublish(server); | 186 var pub = startPubLish(server); |
| 193 | 187 |
| 194 confirmPublish(pub); | 188 confirmPublish(pub); |
| 195 | 189 |
| 196 server.handle('GET', '/packages/versions/new.json', (request) { | 190 server.handle('GET', '/packages/versions/new.json', (request, response) { |
| 197 request.response.write('{not json'); | 191 response.write('{not json'); |
| 198 request.response.close(); | 192 response.close(); |
| 199 }); | 193 }); |
| 200 | 194 |
| 201 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 195 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 202 expect(pub.nextErrLine(), completion(equals('{not json'))); | 196 expectLater(pub.nextErrLine(), equals('{not json')); |
| 203 pub.shouldExit(1); | 197 pub.shouldExit(1); |
| 204 }); | 198 }); |
| 205 | 199 |
| 206 integration('upload form is missing url', () { | 200 integration('upload form is missing url', () { |
| 207 var server = new ScheduledServer(); | 201 var server = new ScheduledServer(); |
| 208 d.credentialsFile(server, 'access token').create(); | 202 credentialsFile(server, 'access token').scheduleCreate(); |
| 209 var pub = startPublish(server); | 203 var pub = startPubLish(server); |
| 210 | 204 |
| 211 confirmPublish(pub); | 205 confirmPublish(pub); |
| 212 | 206 |
| 213 var body = { | 207 var body = { |
| 214 'fields': { | 208 'fields': { |
| 215 'field1': 'value1', | 209 'field1': 'value1', |
| 216 'field2': 'value2' | 210 'field2': 'value2' |
| 217 } | 211 } |
| 218 }; | 212 }; |
| 219 | 213 |
| 220 handleUploadForm(server, body); | 214 handleUploadForm(server, body); |
| 221 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 215 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 222 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 216 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 223 pub.shouldExit(1); | 217 pub.shouldExit(1); |
| 224 }); | 218 }); |
| 225 | 219 |
| 226 integration('upload form url is not a string', () { | 220 integration('upload form url is not a string', () { |
| 227 var server = new ScheduledServer(); | 221 var server = new ScheduledServer(); |
| 228 d.credentialsFile(server, 'access token').create(); | 222 credentialsFile(server, 'access token').scheduleCreate(); |
| 229 var pub = startPublish(server); | 223 var pub = startPubLish(server); |
| 230 | 224 |
| 231 confirmPublish(pub); | 225 confirmPublish(pub); |
| 232 | 226 |
| 233 var body = { | 227 var body = { |
| 234 'url': 12, | 228 'url': 12, |
| 235 'fields': { | 229 'fields': { |
| 236 'field1': 'value1', | 230 'field1': 'value1', |
| 237 'field2': 'value2' | 231 'field2': 'value2' |
| 238 } | 232 } |
| 239 }; | 233 }; |
| 240 | 234 |
| 241 handleUploadForm(server, body); | 235 handleUploadForm(server, body); |
| 242 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 236 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 243 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 237 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 244 pub.shouldExit(1); | 238 pub.shouldExit(1); |
| 245 }); | 239 }); |
| 246 | 240 |
| 247 integration('upload form is missing fields', () { | 241 integration('upload form is missing fields', () { |
| 248 var server = new ScheduledServer(); | 242 var server = new ScheduledServer(); |
| 249 d.credentialsFile(server, 'access token').create(); | 243 credentialsFile(server, 'access token').scheduleCreate(); |
| 250 var pub = startPublish(server); | 244 var pub = startPubLish(server); |
| 251 | 245 |
| 252 confirmPublish(pub); | 246 confirmPublish(pub); |
| 253 | 247 |
| 254 var body = {'url': 'http://example.com/upload'}; | 248 var body = {'url': 'http://example.com/upload'}; |
| 255 handleUploadForm(server, body); | 249 handleUploadForm(server, body); |
| 256 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 250 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 257 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 251 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 258 pub.shouldExit(1); | 252 pub.shouldExit(1); |
| 259 }); | 253 }); |
| 260 | 254 |
| 261 integration('upload form fields is not a map', () { | 255 integration('upload form fields is not a map', () { |
| 262 var server = new ScheduledServer(); | 256 var server = new ScheduledServer(); |
| 263 d.credentialsFile(server, 'access token').create(); | 257 credentialsFile(server, 'access token').scheduleCreate(); |
| 264 var pub = startPublish(server); | 258 var pub = startPubLish(server); |
| 265 | 259 |
| 266 confirmPublish(pub); | 260 confirmPublish(pub); |
| 267 | 261 |
| 268 var body = {'url': 'http://example.com/upload', 'fields': 12}; | 262 var body = {'url': 'http://example.com/upload', 'fields': 12}; |
| 269 handleUploadForm(server, body); | 263 handleUploadForm(server, body); |
| 270 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 264 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 271 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 265 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 272 pub.shouldExit(1); | 266 pub.shouldExit(1); |
| 273 }); | 267 }); |
| 274 | 268 |
| 275 integration('upload form fields has a non-string value', () { | 269 integration('upload form fields has a non-string value', () { |
| 276 var server = new ScheduledServer(); | 270 var server = new ScheduledServer(); |
| 277 d.credentialsFile(server, 'access token').create(); | 271 credentialsFile(server, 'access token').scheduleCreate(); |
| 278 var pub = startPublish(server); | 272 var pub = startPubLish(server); |
| 279 | 273 |
| 280 confirmPublish(pub); | 274 confirmPublish(pub); |
| 281 | 275 |
| 282 var body = { | 276 var body = { |
| 283 'url': 'http://example.com/upload', | 277 'url': 'http://example.com/upload', |
| 284 'fields': {'field': 12} | 278 'fields': {'field': 12} |
| 285 }; | 279 }; |
| 286 handleUploadForm(server, body); | 280 handleUploadForm(server, body); |
| 287 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 281 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 288 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 282 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 289 pub.shouldExit(1); | 283 pub.shouldExit(1); |
| 290 }); | 284 }); |
| 291 | 285 |
| 292 integration('cloud storage upload provides an error', () { | 286 integration('cloud storage upload provides an error', () { |
| 293 var server = new ScheduledServer(); | 287 var server = new ScheduledServer(); |
| 294 d.credentialsFile(server, 'access token').create(); | 288 credentialsFile(server, 'access token').scheduleCreate(); |
| 295 var pub = startPublish(server); | 289 var pub = startPubLish(server); |
| 296 | 290 |
| 297 confirmPublish(pub); | 291 confirmPublish(pub); |
| 298 handleUploadForm(server); | 292 handleUploadForm(server); |
| 299 | 293 |
| 300 server.handle('POST', '/upload', (request) { | 294 server.handle('POST', '/upload', (request, response) { |
| 301 return drainStream(request).then((_) { | 295 return drainStream(request).then((_) { |
| 302 request.response.statusCode = 400; | 296 response.statusCode = 400; |
| 303 request.response.headers.contentType = | 297 response.headers.contentType = new ContentType('application', 'xml'); |
| 304 new ContentType('application', 'xml'); | 298 response.write('<Error><Message>Your request sucked.' |
| 305 request.response.write('<Error><Message>Your request sucked.' | |
| 306 '</Message></Error>'); | 299 '</Message></Error>'); |
| 307 request.response.close(); | 300 response.close(); |
| 308 }); | 301 }); |
| 309 }); | 302 }); |
| 310 | 303 |
| 311 // 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 |
| 312 // can parse the XML. | 305 // can parse the XML. |
| 313 expect(pub.nextErrLine(), | 306 expectLater(pub.nextErrLine(), equals('Failed to upload the package.')); |
| 314 completion(equals('Failed to upload the package.'))); | |
| 315 pub.shouldExit(1); | 307 pub.shouldExit(1); |
| 316 }); | 308 }); |
| 317 | 309 |
| 318 integration("cloud storage upload doesn't redirect", () { | 310 integration("cloud storage upload doesn't redirect", () { |
| 319 var server = new ScheduledServer(); | 311 var server = new ScheduledServer(); |
| 320 d.credentialsFile(server, 'access token').create(); | 312 credentialsFile(server, 'access token').scheduleCreate(); |
| 321 var pub = startPublish(server); | 313 var pub = startPubLish(server); |
| 322 | 314 |
| 323 confirmPublish(pub); | 315 confirmPublish(pub); |
| 324 handleUploadForm(server); | 316 handleUploadForm(server); |
| 325 | 317 |
| 326 server.handle('POST', '/upload', (request) { | 318 server.handle('POST', '/upload', (request, response) { |
| 327 return drainStream(request).then((_) { | 319 return drainStream(request).then((_) { |
| 328 // Don't set the location header. | 320 // Don't set the location header. |
| 329 request.response.close(); | 321 response.close(); |
| 330 }); | 322 }); |
| 331 }); | 323 }); |
| 332 | 324 |
| 333 expect(pub.nextErrLine(), | 325 expectLater(pub.nextErrLine(), equals('Failed to upload the package.')); |
| 334 completion(equals('Failed to upload the package.'))); | |
| 335 pub.shouldExit(1); | 326 pub.shouldExit(1); |
| 336 }); | 327 }); |
| 337 | 328 |
| 338 integration('package creation provides an error', () { | 329 integration('package creation provides an error', () { |
| 339 var server = new ScheduledServer(); | 330 var server = new ScheduledServer(); |
| 340 d.credentialsFile(server, 'access token').create(); | 331 credentialsFile(server, 'access token').scheduleCreate(); |
| 341 var pub = startPublish(server); | 332 var pub = startPubLish(server); |
| 342 | 333 |
| 343 confirmPublish(pub); | 334 confirmPublish(pub); |
| 344 handleUploadForm(server); | 335 handleUploadForm(server); |
| 345 handleUpload(server); | 336 handleUpload(server); |
| 346 | 337 |
| 347 server.handle('GET', '/create', (request) { | 338 server.handle('GET', '/create', (request, response) { |
| 348 request.response.statusCode = 400; | 339 response.statusCode = 400; |
| 349 request.response.write(json.stringify({ | 340 response.write(json.stringify({ |
| 350 'error': {'message': 'Your package was too boring.'} | 341 'error': {'message': 'Your package was too boring.'} |
| 351 })); | 342 })); |
| 352 request.response.close(); | 343 response.close(); |
| 353 }); | 344 }); |
| 354 | 345 |
| 355 expect(pub.nextErrLine(), | 346 expectLater(pub.nextErrLine(), equals('Your package was too boring.')); |
| 356 completion(equals('Your package was too boring.'))); | |
| 357 pub.shouldExit(1); | 347 pub.shouldExit(1); |
| 358 }); | 348 }); |
| 359 | 349 |
| 360 integration('package creation provides invalid JSON', () { | 350 integration('package creation provides invalid JSON', () { |
| 361 var server = new ScheduledServer(); | 351 var server = new ScheduledServer(); |
| 362 d.credentialsFile(server, 'access token').create(); | 352 credentialsFile(server, 'access token').scheduleCreate(); |
| 363 var pub = startPublish(server); | 353 var pub = startPubLish(server); |
| 364 | 354 |
| 365 confirmPublish(pub); | 355 confirmPublish(pub); |
| 366 handleUploadForm(server); | 356 handleUploadForm(server); |
| 367 handleUpload(server); | 357 handleUpload(server); |
| 368 | 358 |
| 369 server.handle('GET', '/create', (request) { | 359 server.handle('GET', '/create', (request, response) { |
| 370 request.response.write('{not json'); | 360 response.write('{not json'); |
| 371 request.response.close(); | 361 response.close(); |
| 372 }); | 362 }); |
| 373 | 363 |
| 374 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 364 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 375 expect(pub.nextErrLine(), completion(equals('{not json'))); | 365 expectLater(pub.nextErrLine(), equals('{not json')); |
| 376 pub.shouldExit(1); | 366 pub.shouldExit(1); |
| 377 }); | 367 }); |
| 378 | 368 |
| 379 integration('package creation provides a malformed error', () { | 369 integration('package creation provides a malformed error', () { |
| 380 var server = new ScheduledServer(); | 370 var server = new ScheduledServer(); |
| 381 d.credentialsFile(server, 'access token').create(); | 371 credentialsFile(server, 'access token').scheduleCreate(); |
| 382 var pub = startPublish(server); | 372 var pub = startPubLish(server); |
| 383 | 373 |
| 384 confirmPublish(pub); | 374 confirmPublish(pub); |
| 385 handleUploadForm(server); | 375 handleUploadForm(server); |
| 386 handleUpload(server); | 376 handleUpload(server); |
| 387 | 377 |
| 388 var body = {'error': 'Your package was too boring.'}; | 378 var body = {'error': 'Your package was too boring.'}; |
| 389 server.handle('GET', '/create', (request) { | 379 server.handle('GET', '/create', (request, response) { |
| 390 request.response.statusCode = 400; | 380 response.statusCode = 400; |
| 391 request.response.write(json.stringify(body)); | 381 response.write(json.stringify(body)); |
| 392 request.response.close(); | 382 response.close(); |
| 393 }); | 383 }); |
| 394 | 384 |
| 395 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 385 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 396 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 386 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 397 pub.shouldExit(1); | 387 pub.shouldExit(1); |
| 398 }); | 388 }); |
| 399 | 389 |
| 400 integration('package creation provides a malformed success', () { | 390 integration('package creation provides a malformed success', () { |
| 401 var server = new ScheduledServer(); | 391 var server = new ScheduledServer(); |
| 402 d.credentialsFile(server, 'access token').create(); | 392 credentialsFile(server, 'access token').scheduleCreate(); |
| 403 var pub = startPublish(server); | 393 var pub = startPubLish(server); |
| 404 | 394 |
| 405 confirmPublish(pub); | 395 confirmPublish(pub); |
| 406 handleUploadForm(server); | 396 handleUploadForm(server); |
| 407 handleUpload(server); | 397 handleUpload(server); |
| 408 | 398 |
| 409 var body = {'success': 'Your package was awesome.'}; | 399 var body = {'success': 'Your package was awesome.'}; |
| 410 server.handle('GET', '/create', (request) { | 400 server.handle('GET', '/create', (request, response) { |
| 411 request.response.write(json.stringify(body)); | 401 response.write(json.stringify(body)); |
| 412 request.response.close(); | 402 response.close(); |
| 413 }); | 403 }); |
| 414 | 404 |
| 415 expect(pub.nextErrLine(), completion(equals('Invalid server response:'))); | 405 expectLater(pub.nextErrLine(), equals('Invalid server response:')); |
| 416 expect(pub.nextErrLine(), completion(equals(json.stringify(body)))); | 406 expectLater(pub.nextErrLine(), equals(json.stringify(body))); |
| 417 pub.shouldExit(1); | 407 pub.shouldExit(1); |
| 418 }); | 408 }); |
| 419 | 409 |
| 420 group('--force', () { | 410 group('--force', () { |
| 421 setUp(() => d.validPackage.create()); | 411 setUp(() => normalPackage.scheduleCreate()); |
| 422 | 412 |
| 423 integration('cannot be combined with --dry-run', () { | 413 integration('cannot be combined with --dry-run', () { |
| 424 schedulePub(args: ['lish', '--force', '--dry-run'], | 414 schedulePub(args: ['lish', '--force', '--dry-run'], |
| 425 error: "Cannot use both --force and --dry-run.", | 415 error: "Cannot use both --force and --dry-run.", |
| 426 exitCode: exit_codes.USAGE); | 416 exitCode: exit_codes.USAGE); |
| 427 }); | 417 }); |
| 428 | 418 |
| 429 integration('publishes if there are no warnings or errors', () { | 419 integration('publishes if there are no warnings or errors', () { |
| 430 var server = new ScheduledServer(); | 420 var server = new ScheduledServer(); |
| 431 d.credentialsFile(server, 'access token').create(); | 421 credentialsFile(server, 'access token').scheduleCreate(); |
| 432 var pub = startPublish(server, args: ['--force']); | 422 var pub = startPubLish(server, args: ['--force']); |
| 433 | 423 |
| 434 handleUploadForm(server); | 424 handleUploadForm(server); |
| 435 handleUpload(server); | 425 handleUpload(server); |
| 436 | 426 |
| 437 server.handle('GET', '/create', (request) { | 427 server.handle('GET', '/create', (request, response) { |
| 438 request.response.write(json.stringify({ | 428 response.write(json.stringify({ |
| 439 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 429 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
| 440 })); | 430 })); |
| 441 request.response.close(); | 431 response.close(); |
| 442 }); | 432 }); |
| 443 | 433 |
| 444 pub.shouldExit(0); | 434 pub.shouldExit(0); |
| 445 expect(pub.remainingStdout(), completion(contains( | 435 expectLater(pub.remainingStdout(), contains( |
| 446 'Package test_pkg 1.0.0 uploaded!'))); | 436 'Package test_pkg 1.0.0 uploaded!')); |
| 447 }); | 437 }); |
| 448 | 438 |
| 449 integration('publishes if there are warnings', () { | 439 integration('publishes if there are warnings', () { |
| 450 var pkg = packageMap("test_pkg", "1.0.0"); | 440 var pkg = package("test_pkg", "1.0.0"); |
| 451 pkg["author"] = "Nathan Weizenbaum"; | 441 pkg["author"] = "Nathan Weizenbaum"; |
| 452 d.dir(appPath, [d.pubspec(pkg)]).create(); | 442 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 453 | 443 |
| 454 var server = new ScheduledServer(); | 444 var server = new ScheduledServer(); |
| 455 d.credentialsFile(server, 'access token').create(); | 445 credentialsFile(server, 'access token').scheduleCreate(); |
| 456 var pub = startPublish(server, args: ['--force']); | 446 var pub = startPubLish(server, args: ['--force']); |
| 457 | 447 |
| 458 handleUploadForm(server); | 448 handleUploadForm(server); |
| 459 handleUpload(server); | 449 handleUpload(server); |
| 460 | 450 |
| 461 server.handle('GET', '/create', (request) { | 451 server.handle('GET', '/create', (request, response) { |
| 462 request.response.write(json.stringify({ | 452 response.write(json.stringify({ |
| 463 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} | 453 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} |
| 464 })); | 454 })); |
| 465 request.response.close(); | 455 response.close(); |
| 466 }); | 456 }); |
| 467 | 457 |
| 468 pub.shouldExit(0); | 458 pub.shouldExit(0); |
| 469 expect(pub.remainingStderr(), completion(contains( | 459 expectLater(pub.remainingStderr(), contains( |
| 470 'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml' | 460 'Suggestions:\n* Author "Nathan Weizenbaum" in pubspec.yaml' |
| 471 ' should have an email address\n' | 461 ' should have an email address\n' |
| 472 ' (e.g. "name <email>").'))); | 462 ' (e.g. "name <email>").')); |
| 473 expect(pub.remainingStdout(), completion(contains( | 463 expectLater(pub.remainingStdout(), contains( |
| 474 'Package test_pkg 1.0.0 uploaded!'))); | 464 'Package test_pkg 1.0.0 uploaded!')); |
| 475 }); | 465 }); |
| 476 | 466 |
| 477 integration('does not publish if there are errors', () { | 467 integration('does not publish if there are errors', () { |
| 478 var pkg = packageMap("test_pkg", "1.0.0"); | 468 var pkg = package("test_pkg", "1.0.0"); |
| 479 pkg.remove("homepage"); | 469 pkg.remove("homepage"); |
| 480 d.dir(appPath, [d.pubspec(pkg)]).create(); | 470 dir(appPath, [pubspec(pkg)]).scheduleCreate(); |
| 481 | 471 |
| 482 var server = new ScheduledServer(); | 472 var server = new ScheduledServer(); |
| 483 var pub = startPublish(server, args: ['--force']); | 473 var pub = startPubLish(server, args: ['--force']); |
| 484 | 474 |
| 485 pub.shouldExit(0); | 475 pub.shouldExit(0); |
| 486 expect(pub.remainingStderr(), completion(contains( | 476 expectLater(pub.remainingStderr(), contains( |
| 487 "Sorry, your package is missing a requirement and can't be " | 477 "Sorry, your package is missing a requirement and can't be " |
| 488 "published yet."))); | 478 "published yet.")); |
| 489 }); | 479 }); |
| 490 }); | 480 }); |
| 491 } | 481 } |
| OLD | NEW |