// Copyright (c) 2012, 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 authorization_code_grant_test;

import 'dart:async';
import 'dart:convert';

import 'package:unittest/unittest.dart';
import 'package:http/http.dart' as http;
import 'package:oauth2/oauth2.dart' as oauth2;

import 'utils.dart';

final redirectUrl = Uri.parse('http://example.com/redirect');

ExpectClient client;

oauth2.AuthorizationCodeGrant grant;

void createGrant() {
  client = new ExpectClient();
  grant = new oauth2.AuthorizationCodeGrant(
      'identifier',
      'secret',
      Uri.parse('https://example.com/authorization'),
      Uri.parse('https://example.com/token'),
      httpClient: client);
}

void expectFutureThrows(future, predicate) {
  future.catchError(expectAsync1((error) {
    expect(predicate(error), isTrue);
  }));
}

void main() {
  group('.getAuthorizationUrl', () {
    setUp(createGrant);

    test('builds the correct URL', () {
      expect(grant.getAuthorizationUrl(redirectUrl).toString(),
          equals('https://example.com/authorization'
              '?response_type=code'
              '&client_id=identifier'
              '&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'));
    });

    test('builds the correct URL with scopes', () {
      var authorizationUrl = grant.getAuthorizationUrl(
          redirectUrl, scopes: ['scope', 'other/scope']);
      expect(authorizationUrl.toString(),
          equals('https://example.com/authorization'
              '?response_type=code'
              '&client_id=identifier'
              '&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'
              '&scope=scope+other%2Fscope'));
    });

    test('builds the correct URL with state', () {
      var authorizationUrl = grant.getAuthorizationUrl(
          redirectUrl, state: 'state');
      expect(authorizationUrl.toString(),
          equals('https://example.com/authorization'
              '?response_type=code'
              '&client_id=identifier'
              '&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'
              '&state=state'));
    });

    test('merges with existing query parameters', () {
      grant = new oauth2.AuthorizationCodeGrant(
          'identifier',
          'secret',
          Uri.parse('https://example.com/authorization?query=value'),
          Uri.parse('https://example.com/token'),
          httpClient: client);

      var authorizationUrl = grant.getAuthorizationUrl(redirectUrl);
      expect(authorizationUrl.toString(),
          equals('https://example.com/authorization'
              '?query=value'
              '&response_type=code'
              '&client_id=identifier'
              '&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'));
    });

    test("can't be called twice", () {
      grant.getAuthorizationUrl(redirectUrl);
      expect(() => grant.getAuthorizationUrl(redirectUrl), throwsStateError);
    });
  });

  group('.handleAuthorizationResponse', () {
    setUp(createGrant);

    test("can't be called before .getAuthorizationUrl", () {
      expectFutureThrows(grant.handleAuthorizationResponse({}),
                         (e) => e is StateError);
    });

    test("can't be called twice", () {
      grant.getAuthorizationUrl(redirectUrl);
      expectFutureThrows(
          grant.handleAuthorizationResponse({'code': 'auth code'}),
          (e) => e is FormatException);
      expectFutureThrows(
          grant.handleAuthorizationResponse({'code': 'auth code'}),
          (e) => e is StateError);
    });

    test('must have a state parameter if the authorization URL did', () {
      grant.getAuthorizationUrl(redirectUrl, state: 'state');
      expectFutureThrows(
          grant.handleAuthorizationResponse({'code': 'auth code'}),
          (e) => e is FormatException);
    });

    test('must have the same state parameter the authorization URL did', () {
      grant.getAuthorizationUrl(redirectUrl, state: 'state');
      expectFutureThrows(grant.handleAuthorizationResponse({
        'code': 'auth code',
        'state': 'other state'
      }), (e) => e is FormatException);
    });

    test('must have a code parameter', () {
      grant.getAuthorizationUrl(redirectUrl);
      expectFutureThrows(grant.handleAuthorizationResponse({}),
                         (e) => e is FormatException);
    });

    test('with an error parameter throws an AuthorizationException', () {
      grant.getAuthorizationUrl(redirectUrl);
      expectFutureThrows(
          grant.handleAuthorizationResponse({'error': 'invalid_request'}),
          (e) => e is oauth2.AuthorizationException);
    });

    test('sends an authorization code request', () {
      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        expect(request.method, equals('POST'));
        expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
        expect(request.bodyFields, equals({
          'grant_type': 'authorization_code',
          'code': 'auth code',
          'redirect_uri': redirectUrl.toString(),
          'client_id': 'identifier',
          'client_secret': 'secret'
        }));

        return new Future.value(new http.Response(JSON.encode({
          'access_token': 'access token',
          'token_type': 'bearer',
        }), 200, headers: {'content-type': 'application/json'}));
      });

      grant.handleAuthorizationResponse({'code': 'auth code'})
          .then(expectAsync1((client) {
            expect(client.credentials.accessToken, equals('access token'));
          }));
    });
  });

  group('.handleAuthorizationCode', () {
    setUp(createGrant);

    test("can't be called before .getAuthorizationUrl", () {
      expectFutureThrows(
          grant.handleAuthorizationCode('auth code'),
          (e) => e is StateError);
    });

    test("can't be called twice", () {
      grant.getAuthorizationUrl(redirectUrl);
      expectFutureThrows(
          grant.handleAuthorizationCode('auth code'),
          (e) => e is FormatException);
      expectFutureThrows(grant.handleAuthorizationCode('auth code'),
                         (e) => e is StateError);
    });

    test('sends an authorization code request', () {
      grant.getAuthorizationUrl(redirectUrl);
      client.expectRequest((request) {
        expect(request.method, equals('POST'));
        expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
        expect(request.bodyFields, equals({
          'grant_type': 'authorization_code',
          'code': 'auth code',
          'redirect_uri': redirectUrl.toString(),
          'client_id': 'identifier',
          'client_secret': 'secret'
        }));

        return new Future.value(new http.Response(JSON.encode({
          'access_token': 'access token',
          'token_type': 'bearer',
        }), 200, headers: {'content-type': 'application/json'}));
      });

      expect(grant.handleAuthorizationCode('auth code'),
          completion(predicate((client) {
            expect(client.credentials.accessToken, equals('access token'));
            return true;
          })));
    });
  });
}
