// 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 handle_access_token_response_test;

import 'dart:convert';

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

import 'utils.dart';

final Uri tokenEndpoint = Uri.parse("https://example.com/token");

final DateTime startTime = new DateTime.now();

oauth2.Credentials handle(http.Response response) =>
  handleAccessTokenResponse(response, tokenEndpoint, startTime, ["scope"]);

void main() {
  group('an error response', () {
    oauth2.Credentials handleError(
        {String body: '{"error": "invalid_request"}',
         int statusCode: 400,
         Map<String, String> headers:
             const {"content-type": "application/json"}}) =>
      handle(new http.Response(body, statusCode, headers: headers));

    test('causes an AuthorizationException', () {
      expect(() => handleError(), throwsAuthorizationException);
    });

    test('with a 401 code causes an AuthorizationException', () {
      expect(() => handleError(statusCode: 401), throwsAuthorizationException);
    });

    test('with an unexpected code causes a FormatException', () {
      expect(() => handleError(statusCode: 500), throwsFormatException);
    });

    test('with no content-type causes a FormatException', () {
      expect(() => handleError(headers: {}), throwsFormatException);
    });

    test('with a non-JSON content-type causes a FormatException', () {
      expect(() => handleError(headers: {
        'content-type': 'text/plain'
      }), throwsFormatException);
    });

    test('with a JSON content-type and charset causes an '
        'AuthorizationException', () {
      expect(() => handleError(headers: {
        'content-type': 'application/json; charset=UTF-8'
      }), throwsAuthorizationException);
    });

    test('with invalid JSON causes a FormatException', () {
      expect(() => handleError(body: 'not json'), throwsFormatException);
    });

    test('with a non-string error causes a FormatException', () {
      expect(() => handleError(body: '{"error": 12}'), throwsFormatException);
    });

    test('with a non-string error_description causes a FormatException', () {
      expect(() => handleError(body: JSON.encode({
        "error": "invalid_request",
        "error_description": 12
      })), throwsFormatException);
    });

    test('with a non-string error_uri causes a FormatException', () {
      expect(() => handleError(body: JSON.encode({
        "error": "invalid_request",
        "error_uri": 12
      })), throwsFormatException);
    });

    test('with a string error_description causes a AuthorizationException', () {
      expect(() => handleError(body: JSON.encode({
        "error": "invalid_request",
        "error_description": "description"
      })), throwsAuthorizationException);
    });

    test('with a string error_uri causes a AuthorizationException', () {
      expect(() => handleError(body: JSON.encode({
        "error": "invalid_request",
        "error_uri": "http://example.com/error"
      })), throwsAuthorizationException);
    });
  });

  group('a success response', () {
    oauth2.Credentials handleSuccess(
        {String contentType: "application/json",
         accessToken: 'access token',
         tokenType: 'bearer',
         expiresIn,
         refreshToken,
         scope}) {
      return handle(new http.Response(JSON.encode({
        'access_token': accessToken,
        'token_type': tokenType,
        'expires_in': expiresIn,
        'refresh_token': refreshToken,
        'scope': scope
      }), 200, headers: {'content-type': contentType}));
    }

    test('returns the correct credentials', () {
      var credentials = handleSuccess();
      expect(credentials.accessToken, equals('access token'));
      expect(credentials.tokenEndpoint.toString(),
          equals(tokenEndpoint.toString()));
    });

    test('with no content-type causes a FormatException', () {
      expect(() => handleSuccess(contentType: null), throwsFormatException);
    });

    test('with a non-JSON content-type causes a FormatException', () {
      expect(() => handleSuccess(contentType: 'text/plain'),
          throwsFormatException);
    });

    test('with a JSON content-type and charset returns the correct '
        'credentials', () {
      var credentials = handleSuccess(
          contentType: 'application/json; charset=UTF-8');
      expect(credentials.accessToken, equals('access token'));
    });

    test('with a JavScript content-type returns the correct credentials', () {
      var credentials = handleSuccess(contentType: 'text/javascript');
      expect(credentials.accessToken, equals('access token'));
    });

    test('with a null access token throws a FormatException', () {
      expect(() => handleSuccess(accessToken: null), throwsFormatException);
    });

    test('with a non-string access token throws a FormatException', () {
      expect(() => handleSuccess(accessToken: 12), throwsFormatException);
    });

    test('with a null token type throws a FormatException', () {
      expect(() => handleSuccess(tokenType: null), throwsFormatException);
    });

    test('with a non-string token type throws a FormatException', () {
      expect(() => handleSuccess(tokenType: 12), throwsFormatException);
    });

    test('with a non-"bearer" token type throws a FormatException', () {
      expect(() => handleSuccess(tokenType: "mac"), throwsFormatException);
    });

    test('with a non-int expires-in throws a FormatException', () {
      expect(() => handleSuccess(expiresIn: "whenever"), throwsFormatException);
    });

    test('with expires-in sets the expiration to ten seconds earlier than the '
        'server says', () {
      var credentials = handleSuccess(expiresIn: 100);
      expect(credentials.expiration.millisecondsSinceEpoch,
          startTime.millisecondsSinceEpoch + 90 * 1000);
    });

    test('with a non-string refresh token throws a FormatException', () {
      expect(() => handleSuccess(refreshToken: 12), throwsFormatException);
    });

    test('with a refresh token sets the refresh token', () {
      var credentials = handleSuccess(refreshToken: "refresh me");
      expect(credentials.refreshToken, equals("refresh me"));
    });

    test('with a non-string scope throws a FormatException', () {
      expect(() => handleSuccess(scope: 12), throwsFormatException);
    });

    test('with a scope sets the scopes', () {
      var credentials = handleSuccess(scope: "scope1 scope2");
      expect(credentials.scopes, equals(["scope1", "scope2"]));
    });
  });
}
