| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| |
| import 'package:pub/src/exit_codes.dart' as exit_codes; |
| import 'package:shelf/shelf.dart' as shelf; |
| import 'package:test/test.dart'; |
| import 'package:test_process/test_process.dart'; |
| |
| import 'descriptor.dart' as d; |
| import 'test_pub.dart'; |
| |
| const _usageString = ''' |
| Manage uploaders for a package on pub.dartlang.org. |
| |
| Usage: pub uploader [options] {add/remove} <email> |
| -h, --help Print this usage information. |
| --package The package whose uploaders will be modified. |
| (defaults to the current package) |
| |
| Run "pub help" to see global options. |
| See https://dart.dev/tools/pub/cmd/pub-uploader for detailed documentation. |
| '''; |
| |
| Future<TestProcess> startPubUploader(PackageServer server, List<String> args) { |
| var tokenEndpoint = Uri.parse(server.url).resolve('/token').toString(); |
| var allArgs = ['uploader', ...args]; |
| return startPub( |
| args: allArgs, |
| tokenEndpoint: tokenEndpoint, |
| environment: {'PUB_HOSTED_URL': tokenEndpoint}); |
| } |
| |
| void main() { |
| group('displays usage', () { |
| test('when run with no arguments', () { |
| return runPub( |
| args: ['uploader'], output: _usageString, exitCode: exit_codes.USAGE); |
| }); |
| |
| test('when run with only a command', () { |
| return runPub( |
| args: ['uploader', 'add'], |
| output: _usageString, |
| exitCode: exit_codes.USAGE); |
| }); |
| |
| test('when run with an invalid command', () { |
| return runPub( |
| args: ['uploader', 'foo', 'email'], |
| output: _usageString, |
| exitCode: exit_codes.USAGE); |
| }); |
| }); |
| |
| test('adds an uploader', () async { |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader( |
| globalPackageServer, ['--package', 'pkg', 'add', 'email']); |
| |
| globalPackageServer.expect('POST', '/api/packages/pkg/uploaders', |
| (request) { |
| return request.readAsString().then((body) { |
| expect(body, equals('email=email')); |
| |
| return shelf.Response.ok( |
| jsonEncode({ |
| 'success': {'message': 'Good job!'} |
| }), |
| headers: {'content-type': 'application/json'}); |
| }); |
| }); |
| |
| expect(pub.stdout, emits('Good job!')); |
| await pub.shouldExit(exit_codes.SUCCESS); |
| }); |
| |
| test('removes an uploader', () async { |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader( |
| globalPackageServer, ['--package', 'pkg', 'remove', 'email']); |
| |
| globalPackageServer.expect('DELETE', '/api/packages/pkg/uploaders/email', |
| (request) { |
| return shelf.Response.ok( |
| jsonEncode({ |
| 'success': {'message': 'Good job!'} |
| }), |
| headers: {'content-type': 'application/json'}); |
| }); |
| |
| expect(pub.stdout, emits('Good job!')); |
| await pub.shouldExit(exit_codes.SUCCESS); |
| }); |
| |
| test('defaults to the current package', () async { |
| await d.validPackage.create(); |
| |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader(globalPackageServer, ['add', 'email']); |
| |
| globalPackageServer.expect('POST', '/api/packages/test_pkg/uploaders', |
| (request) { |
| return shelf.Response.ok( |
| jsonEncode({ |
| 'success': {'message': 'Good job!'} |
| }), |
| headers: {'content-type': 'application/json'}); |
| }); |
| |
| expect(pub.stdout, emits('Good job!')); |
| await pub.shouldExit(exit_codes.SUCCESS); |
| }); |
| |
| test('add provides an error', () async { |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader( |
| globalPackageServer, ['--package', 'pkg', 'add', 'email']); |
| |
| globalPackageServer.expect('POST', '/api/packages/pkg/uploaders', |
| (request) { |
| return shelf.Response(400, |
| body: jsonEncode({ |
| 'error': {'message': 'Bad job!'} |
| }), |
| headers: {'content-type': 'application/json'}); |
| }); |
| |
| expect(pub.stderr, emits('Bad job!')); |
| await pub.shouldExit(1); |
| }); |
| |
| test('remove provides an error', () async { |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader( |
| globalPackageServer, ['--package', 'pkg', 'remove', 'e/mail']); |
| |
| globalPackageServer.expect('DELETE', '/api/packages/pkg/uploaders/e%2Fmail', |
| (request) { |
| return shelf.Response(400, |
| body: jsonEncode({ |
| 'error': {'message': 'Bad job!'} |
| }), |
| headers: {'content-type': 'application/json'}); |
| }); |
| |
| expect(pub.stderr, emits('Bad job!')); |
| await pub.shouldExit(1); |
| }); |
| |
| test('add provides invalid JSON', () async { |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader( |
| globalPackageServer, ['--package', 'pkg', 'add', 'email']); |
| |
| globalPackageServer.expect('POST', '/api/packages/pkg/uploaders', |
| (request) => shelf.Response.ok('{not json')); |
| |
| expect( |
| pub.stderr, |
| emitsLines('Invalid server response:\n' |
| '{not json')); |
| await pub.shouldExit(1); |
| }); |
| |
| test('remove provides invalid JSON', () async { |
| await servePackages(); |
| await d.credentialsFile(globalPackageServer, 'access token').create(); |
| var pub = await startPubUploader( |
| globalPackageServer, ['--package', 'pkg', 'remove', 'email']); |
| |
| globalPackageServer.expect('DELETE', '/api/packages/pkg/uploaders/email', |
| (request) => shelf.Response.ok('{not json')); |
| |
| expect( |
| pub.stderr, |
| emitsLines('Invalid server response:\n' |
| '{not json')); |
| await pub.shouldExit(1); |
| }); |
| } |