Index: Src/GoogleApis.Auth.Tests/OAuth2/AuthorizationCodeFlowTests.cs
===================================================================
new file mode 100644
--- /dev/null
+++ b/Src/GoogleApis.Auth.Tests/OAuth2/AuthorizationCodeFlowTests.cs
@@ -0,0 +1,425 @@
+/*
+Copyright 2013 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Moq;
+using NUnit.Framework;
+
+using Google.Apis.Auth.OAuth2.Requests;
+using Google.Apis.Auth.OAuth2.Responses;
+using Google.Apis.Http;
+using Google.Apis.Json;
+using Google.Apis.Testing;
+using Google.Apis.Tests;
+using Google.Apis.Util;
+using Google.Apis.Util.Store;
+
+namespace Google.Apis.Auth.OAuth2
+{
+ /// Tests for .
+ [TestFixture]
+ public class AuthorizationCodeFlowTests
+ {
+ private const string TokenUrl = "https://token.com";
+ private const string AuthorizationCodeUrl = "https://authorization.com";
+
+ #region Constructor
+
+ [Test]
+ public void TestConstructor_ArgumentException()
+ {
+ // ClientSecrets are missing.
+ try
+ {
+ new AuthorizationCodeFlow(new AuthorizationCodeFlow.Initializer(
+ "https://authorization_code.com", "https://token.com"));
+ Assert.Fail();
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.True(ex.Message.Contains("You MUST set ClientSecret or ClientSecretStream"));
+ }
+ }
+
+ [Test]
+ public void TestConstructor_DefaultValues()
+ {
+ var flow = CreateFlow();
+ Assert.NotNull(flow.AccessMethod);
+ Assert.That(flow.AccessMethod, Is.InstanceOf());
+ Assert.That(flow.AuthorizationServerUrl, Is.EqualTo("https://authorization.com"));
+ Assert.NotNull(flow.ClientSecrets);
+ Assert.That(flow.ClientSecrets.ClientId, Is.EqualTo("id"));
+ Assert.That(flow.ClientSecrets.ClientSecret, Is.EqualTo("secret"));
+ Assert.That(flow.Clock, Is.InstanceOf());
+ Assert.Null(flow.DataStore);
+ Assert.NotNull(flow.HttpClient);
+ Assert.NotNull(flow.Scopes);
+ Assert.That(flow.TokenServerUrl, Is.EqualTo("https://token.com"));
+
+ Assert.That(flow.HttpClient.MessageHandler.UnsuccessfulResponseHandlers.Count(), Is.EqualTo(1));
+ Assert.That(flow.HttpClient.MessageHandler.UnsuccessfulResponseHandlers.First(),
+ Is.InstanceOf());
+ }
+
+ #endregion
+
+ #region LoadToken
+
+ [Test]
+ public void LoadTokenAsync_NoDataStore()
+ {
+ var flow = CreateFlow();
+ Assert.Null(flow.LoadTokenAsync("user", CancellationToken.None).Result);
+ }
+
+ [Test]
+ public void LoadTokenAsync_NullResponse()
+ {
+ TaskCompletionSource tcs = new TaskCompletionSource();
+ tcs.SetResult(null);
+ Assert.Null(SubtestLoadTokenAsync(tcs));
+ }
+
+ [Test]
+ public void LoadTokenAsync_TokenResponse()
+ {
+ TokenResponse response = new TokenResponse
+ {
+ AccessToken = "access"
+ };
+
+ TaskCompletionSource tcs = new TaskCompletionSource();
+ tcs.SetResult(response);
+ var result = SubtestLoadTokenAsync(tcs);
+ Assert.That(result, Is.EqualTo(response));
+ }
+
+ private TokenResponse SubtestLoadTokenAsync(TaskCompletionSource tcs)
+ {
+ var mock = new Mock();
+ mock.Setup(ds => ds.GetAsync("user")).Returns(tcs.Task);
+ var flow = CreateFlow(dataStore: mock.Object);
+ var result = flow.LoadTokenAsync("user", CancellationToken.None).Result;
+ mock.Verify(ds => ds.GetAsync("user"));
+ return result;
+ }
+
+ #endregion
+
+ #region CreateAuthorizationCodeRequest
+
+ [Test]
+ public void TestCreateAuthorizationCodeRequest()
+ {
+ var request = CreateFlow(scopes: new[] { "a", "b" }).CreateAuthorizationCodeRequest("redirect");
+ Assert.That(request.AuthorizationServerUrl, Is.EqualTo(new Uri(AuthorizationCodeUrl)));
+ Assert.That(request.ClientId, Is.EqualTo("id"));
+ Assert.That(request.RedirectUri, Is.EqualTo("redirect"));
+ Assert.That(request.ResponseType, Is.EqualTo("code"));
+ Assert.That(request.Scope, Is.EqualTo("a b"));
+ Assert.Null(request.State);
+ }
+
+ #endregion
+
+ [Test]
+ public void TestExchangeCodeForTokenAsync()
+ {
+ var mock = new Mock();
+ var handler = new FetchTokenMessageHandler();
+ handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRequest()
+ {
+ Code = "c0de",
+ RedirectUri = "redIrect",
+ Scope = "a"
+ };
+ MockHttpClientFactory mockFactory = new MockHttpClientFactory(handler);
+
+ TaskCompletionSource