// 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.

library pub_uploader_test;

import 'dart:convert';

import 'package:scheduled_test/scheduled_process.dart';
import 'package:scheduled_test/scheduled_server.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'package:shelf/shelf.dart' as shelf;

import '../lib/src/exit_codes.dart' as exit_codes;
import '../lib/src/utils.dart';
import 'descriptor.dart' as d;
import 'test_pub.dart';

final USAGE_STRING = '''
Manage uploaders for a package on pub.dartlang.org.

Usage: pub uploader [options] {add/remove} <email>
-h, --help       Print this usage information.
    --server     The package server on which the package is hosted.
                 (defaults to "https://pub.dartlang.org")

    --package    The package whose uploaders will be modified.
                 (defaults to the current package)

Run "pub help" to see global options.
See http://dartlang.org/tools/pub/cmd/pub-uploader.html for detailed documentation.
''';

ScheduledProcess startPubUploader(ScheduledServer server, List<String> args) {
  var tokenEndpoint = server.url.then((url) =>
      url.resolve('/token').toString());
  args = flatten(['uploader', '--server', tokenEndpoint, args]);
  return startPub(args: args, tokenEndpoint: tokenEndpoint);
}

main() {
  initConfig();
  group('displays usage', () {
    integration('when run with no arguments', () {
      schedulePub(args: ['uploader'],
          output: USAGE_STRING, exitCode: exit_codes.USAGE);
    });

    integration('when run with only a command', () {
      schedulePub(args: ['uploader', 'add'],
          output: USAGE_STRING, exitCode: exit_codes.USAGE);
    });

    integration('when run with an invalid command', () {
      schedulePub(args: ['uploader', 'foo', 'email'],
          output: USAGE_STRING, exitCode: exit_codes.USAGE);
    });
  });

  integration('adds an uploader', () {
    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);

    server.handle('POST', '/api/packages/pkg/uploaders', (request) {
      return request.readAsString().then((body) {
        expect(body, equals('email=email'));

        return new shelf.Response.ok(JSON.encode({
          'success': {'message': 'Good job!'}
        }), headers: {'content-type': 'application/json'});
      });
    });

    pub.stdout.expect('Good job!');
    pub.shouldExit(exit_codes.SUCCESS);
  });

  integration('removes an uploader', () {
    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server, ['--package', 'pkg', 'remove', 'email']);

    server.handle('DELETE', '/api/packages/pkg/uploaders/email', (request) {
      return new shelf.Response.ok(JSON.encode({
        'success': {'message': 'Good job!'}
      }), headers: {'content-type': 'application/json'});
    });

    pub.stdout.expect('Good job!');
    pub.shouldExit(exit_codes.SUCCESS);
  });

  integration('defaults to the current package', () {
    d.validPackage.create();

    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server, ['add', 'email']);

    server.handle('POST', '/api/packages/test_pkg/uploaders', (request) {
      return new shelf.Response.ok(JSON.encode({
        'success': {'message': 'Good job!'}
      }), headers: {'content-type': 'application/json'});
    });

    pub.stdout.expect('Good job!');
    pub.shouldExit(exit_codes.SUCCESS);
  });

  integration('add provides an error', () {
    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);

    server.handle('POST', '/api/packages/pkg/uploaders', (request) {
      return new shelf.Response(400,
          body: JSON.encode({'error': {'message': 'Bad job!'}}),
          headers: {'content-type': 'application/json'});
    });

    pub.stderr.expect('Bad job!');
    pub.shouldExit(1);
  });

  integration('remove provides an error', () {
    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server,
        ['--package', 'pkg', 'remove', 'e/mail']);

    server.handle('DELETE', '/api/packages/pkg/uploaders/e%2Fmail', (request) {
      return new shelf.Response(400,
          body: JSON.encode({'error': {'message': 'Bad job!'}}),
          headers: {'content-type': 'application/json'});
    });

    pub.stderr.expect('Bad job!');
    pub.shouldExit(1);
  });

  integration('add provides invalid JSON', () {
    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);

    server.handle('POST', '/api/packages/pkg/uploaders',
        (request) => new shelf.Response.ok("{not json"));

    pub.stderr.expect(emitsLines(
        'Invalid server response:\n'
        '{not json'));
    pub.shouldExit(1);
  });

  integration('remove provides invalid JSON', () {
    var server = new ScheduledServer();
    d.credentialsFile(server, 'access token').create();
    var pub = startPubUploader(server, ['--package', 'pkg', 'remove', 'email']);

    server.handle('DELETE', '/api/packages/pkg/uploaders/email',
        (request) => new shelf.Response.ok("{not json"));

    pub.stderr.expect(emitsLines(
        'Invalid server response:\n'
        '{not json'));
    pub.shouldExit(1);
  });
}
