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

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

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

import 'utils.dart';

final Uri tokenEndpoint = Uri.parse('http://example.com/token');

ExpectClient httpClient;

void main() {
  setUp(() => httpClient = new ExpectClient());

  test('is not expired if no expiration exists', () {
    var credentials = new oauth2.Credentials('access token');
    expect(credentials.isExpired, isFalse);
  });

  test('is not expired if the expiration is in the future', () {
    var expiration = new DateTime.now().add(new Duration(hours: 1));
    var credentials = new oauth2.Credentials(
        'access token', null, null, null, expiration);
    expect(credentials.isExpired, isFalse);
  });

  test('is expired if the expiration is in the past', () {
    var expiration = new DateTime.now().subtract(new Duration(hours: 1));
    var credentials = new oauth2.Credentials(
        'access token', null, null, null, expiration);
    expect(credentials.isExpired, isTrue);
  });

  test("can't refresh without a refresh token", () {
    var credentials = new oauth2.Credentials(
        'access token', null, tokenEndpoint);
    expect(credentials.canRefresh, false);
    credentials.refresh('identifier', 'secret', httpClient: httpClient)
        .catchError(expectAsync1((error) {
          expect(error is StateError, isTrue);
        }));
  });

  test("can't refresh without a token endpoint", () {
    var credentials = new oauth2.Credentials('access token', 'refresh token');
    expect(credentials.canRefresh, false);
    credentials.refresh('identifier', 'secret', httpClient: httpClient)
        .catchError(expectAsync1((error) {
          expect(error is StateError, isTrue);
        }));
  });

  test("can refresh with a refresh token and a token endpoint", () {
    var credentials = new oauth2.Credentials(
        'access token', 'refresh token', tokenEndpoint, ['scope1', 'scope2']);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(request.bodyFields, equals({
        "grant_type": "refresh_token",
        "refresh_token": "refresh token",
        "scope": "scope1 scope2",
        "client_id": "identifier",
        "client_secret": "secret"
      }));

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


    expect(credentials.refresh('identifier', 'secret', httpClient: httpClient)
        .then((credentials) {
      expect(credentials.accessToken, equals('new access token'));
      expect(credentials.refreshToken, equals('new refresh token'));
    }), completes);
  });

  test("uses the old refresh token if a new one isn't provided", () {
    var credentials = new oauth2.Credentials(
        'access token', 'refresh token', tokenEndpoint);
    expect(credentials.canRefresh, true);

    httpClient.expectRequest((request) {
      expect(request.method, equals('POST'));
      expect(request.url.toString(), equals(tokenEndpoint.toString()));
      expect(request.bodyFields, equals({
        "grant_type": "refresh_token",
        "refresh_token": "refresh token",
        "client_id": "identifier",
        "client_secret": "secret"
      }));

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


    expect(credentials.refresh('identifier', 'secret', httpClient: httpClient)
        .then((credentials) {
      expect(credentials.accessToken, equals('new access token'));
      expect(credentials.refreshToken, equals('refresh token'));
    }), completes);
  });

  group("fromJson", () {
    oauth2.Credentials fromMap(Map map) =>
      new oauth2.Credentials.fromJson(JSON.encode(map));

    test("should load the same credentials from toJson", () {
      var expiration = new DateTime.now().subtract(new Duration(hours: 1));
      var credentials = new oauth2.Credentials(
          'access token', 'refresh token', tokenEndpoint, ['scope1', 'scope2'],
          expiration);
      var reloaded = new oauth2.Credentials.fromJson(credentials.toJson());

      expect(reloaded.accessToken, equals(credentials.accessToken));
      expect(reloaded.refreshToken, equals(credentials.refreshToken));
      expect(reloaded.tokenEndpoint.toString(),
          equals(credentials.tokenEndpoint.toString()));
      expect(reloaded.scopes, equals(credentials.scopes));
      expect(reloaded.expiration, equals(credentials.expiration));
    });

    test("should throw a FormatException for invalid JSON", () {
      expect(() => new oauth2.Credentials.fromJson("foo bar"),
          throwsFormatException);
    });

    test("should throw a FormatException for JSON that's not a map", () {
      expect(() => new oauth2.Credentials.fromJson("null"),
          throwsFormatException);
    });

    test("should throw a FormatException if there is no accessToken", () {
      expect(() => fromMap({}), throwsFormatException);
    });

    test("should throw a FormatException if accessToken is not a string", () {
      expect(() => fromMap({"accessToken": 12}), throwsFormatException);
    });

    test("should throw a FormatException if refreshToken is not a string", () {
      expect(() => fromMap({"accessToken": "foo", "refreshToken": 12}),
          throwsFormatException);
    });

    test("should throw a FormatException if tokenEndpoint is not a string", () {
      expect(() => fromMap({"accessToken": "foo", "tokenEndpoint": 12}),
          throwsFormatException);
    });

    test("should throw a FormatException if scopes is not a list", () {
      expect(() => fromMap({"accessToken": "foo", "scopes": 12}),
          throwsFormatException);
    });

    test("should throw a FormatException if expiration is not an int", () {
      expect(() => fromMap({"accessToken": "foo", "expiration": "12"}),
          throwsFormatException);
    });
  });
}
