public void CanGetRefreshToken()
        {
            var restClient = new Mock <IRestClient>();
            var externalTokenRepository = new LocalRepository <ExternalToken>();
            var serverTime    = new Mock <IServerTime>();
            var jsonConverter = new Mock <IJsonConverter>();

            var api = new GoogleAuthentication(restClient.Object,
                                               externalTokenRepository,
                                               serverTime.Object,
                                               jsonConverter.Object);

            var now = new DateTime(2014, 12, 17, 10, 0, 0);

            serverTime.Setup(st => st.RequestStarted).Returns(now);

            var restResponse = new RestResponse();

            restResponse.Content = "{\"access_token\" : \"AccessToken\", \"token_type\" : \"Bearer\", \"expires_in\" : 3600, \"refresh_token\" : \"RefreshToken\"}";
            restClient.Setup(rc => rc.Execute(It.IsAny <RestRequest>()))
            .Returns(restResponse);

            var googleApiTokenResponse = new GoogleApiTokenResponse
            {
                access_token  = "AccessToken",
                expires_in    = 3600,
                token_type    = "Bearer",
                refresh_token = "RefreshToken",
            };

            jsonConverter.Setup(
                jc =>
                jc.Deserilize <GoogleApiTokenResponse>(
                    "{\"access_token\" : \"AccessToken\", \"token_type\" : \"Bearer\", \"expires_in\" : 3600, \"refresh_token\" : \"RefreshToken\"}"))
            .Returns(googleApiTokenResponse);

            var token = api.GetRefreshToken("code", "redirectUrl");

            Assert.AreEqual(2, externalTokenRepository.All().Count());

            Assert.AreEqual("RefreshToken", token.AccessToken);
            Assert.AreEqual("Google_Refresh_Token", token.Type);
            Assert.AreEqual(2114, token.ExpirationDate.Year);

            var hasValidTokenInDb = externalTokenRepository.Any(t => t.Type == "Google_Access_Token" && t.ExpirationDate > now);

            Assert.AreEqual(true, hasValidTokenInDb);
            Assert.AreEqual("AccessToken", externalTokenRepository.Single(t => t.Type == "Google_Access_Token" && t.ExpirationDate > now).AccessToken);
            Assert.AreEqual("Google_Access_Token", externalTokenRepository.Single(t => t.Type == "Google_Access_Token" && t.ExpirationDate > now).Type);
            Assert.AreEqual(11, externalTokenRepository.Single(t => t.Type == "Google_Access_Token" && t.ExpirationDate > now).ExpirationDate.Hour);
        }
        public void CanGetNewAccessTokenIfNotValidInDbOrForcedForNew()
        {
            var restClient = new Mock <IRestClient>();
            var externalTokenRepository = new LocalRepository <ExternalToken>();
            var serverTime    = new Mock <IServerTime>();
            var jsonConverter = new Mock <IJsonConverter>();

            var api = new GoogleAuthentication(restClient.Object,
                                               externalTokenRepository,
                                               serverTime.Object,
                                               jsonConverter.Object);

            var now = new DateTime(2014, 12, 17, 10, 0, 0);

            serverTime.Setup(st => st.RequestStarted).Returns(now);
            var validRefreshToken = new ExternalToken
            {
                AccessToken    = "RefreshToken",
                ExpirationDate = now.AddYears(100),
                Type           = "Google_Refresh_Token"
            };

            var inValidAccessToken = new ExternalToken
            {
                AccessToken    = "AccessToken",
                ExpirationDate = now.AddHours(-2),
                Type           = "Google_Access_Token"
            };

            externalTokenRepository.Add(validRefreshToken);
            externalTokenRepository.Add(inValidAccessToken);

            var restResponse = new RestResponse();

            restResponse.Content = "{ \"access_token\" : \"NewAccessToken\", \"token_type\" : \"Bearer\", \"expires_in\" : 3600}";
            restClient.Setup(rc => rc.Execute(It.IsAny <RestRequest>()))
            .Returns(restResponse);

            var googleApiTokenResponse = new GoogleApiTokenResponse
            {
                access_token = "NewAccessToken",
                expires_in   = 3600,
                token_type   = "Bearer"
            };

            jsonConverter.Setup(
                jc =>
                jc.Deserilize <GoogleApiTokenResponse>(
                    "{ \"access_token\" : \"NewAccessToken\", \"token_type\" : \"Bearer\", \"expires_in\" : 3600}"))
            .Returns(googleApiTokenResponse);

            var hasValidTokenInDb = externalTokenRepository.Any(t => t.Type == "Google_Access_Token" && t.ExpirationDate > now);

            Assert.AreEqual(false, hasValidTokenInDb);

            var token = api.GetAccessToken();

            var gotNewValidToken = externalTokenRepository.Any(t => t.Type == "Google_Access_Token" && t.ExpirationDate > now);

            Assert.AreEqual(true, gotNewValidToken);

            Assert.AreEqual("NewAccessToken", token.AccessToken);
            Assert.AreEqual("Google_Access_Token", token.Type);
            Assert.AreEqual(11, token.ExpirationDate.Hour);
        }