diff options
Diffstat (limited to 'src/DotNetOpenAuth.Test')
9 files changed, 537 insertions, 4 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index df29b1f..26d870b 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -157,6 +157,7 @@ <Reference Include="System.ServiceModel"> <RequiredTargetFramework>3.0</RequiredTargetFramework> </Reference> + <Reference Include="System.ServiceModel.Web" /> <Reference Include="System.Web" /> <Reference Include="System.Xml" /> <Reference Include="System.Xml.Linq"> @@ -188,6 +189,7 @@ <Compile Include="Messaging\Bindings\StandardExpirationBindingElementTests.cs" /> <Compile Include="Messaging\Reflection\MessagePartTests.cs" /> <Compile Include="Messaging\Reflection\ValueMappingTests.cs" /> + <Compile Include="Messaging\StandardMessageFactoryTests.cs" /> <Compile Include="Mocks\AssociateUnencryptedRequestNoSslCheck.cs" /> <Compile Include="Mocks\CoordinatingChannel.cs" /> <Compile Include="Mocks\CoordinatingHttpRequestInfo.cs" /> @@ -213,6 +215,9 @@ <Compile Include="Mocks\TestChannel.cs" /> <Compile Include="Mocks\TestMessage.cs" /> <Compile Include="Mocks\TestMessageFactory.cs" /> + <Compile Include="OAuthWrap\MessageFactoryTests.cs" /> + <Compile Include="OAuthWrap\OAuthWrapChannelTests.cs" /> + <Compile Include="OAuthWrap\OAuthWrapTestBase.cs" /> <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElementTests.cs" /> <Compile Include="OAuth\ChannelElements\OAuthChannelTests.cs" /> <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElementTest.cs" /> diff --git a/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs index 91cccf1..d07cf32 100644 --- a/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs @@ -7,6 +7,9 @@ namespace DotNetOpenAuth.Test.Messaging { using System; using System.Collections.Generic; + using System.IO; + using System.Runtime.Serialization.Json; + using System.Text; using System.Xml; using DotNetOpenAuth.Messaging; using NUnit.Framework; @@ -52,6 +55,34 @@ namespace DotNetOpenAuth.Test.Messaging { Assert.IsFalse(actual.ContainsKey("EmptyMember")); } + /// <summary> + /// Verifies JSON serialization + /// </summary> + [TestCase] + public void SerializeDeserializeJson() { + var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); + var message = GetStandardTestMessage(FieldFill.CompleteBeforeBindings); + + var ms = new MemoryStream(); + var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8); + serializer.Serialize(this.MessageDescriptions.GetAccessor(message), writer); + writer.Flush(); + + string actual = Encoding.UTF8.GetString(ms.ToArray()); + string expected = @"{""age"":15,""Name"":""Andrew"",""Location"":""http:\/\/localtest\/path"",""Timestamp"":""2008-09-19T08:00:00Z""}"; + Assert.AreEqual(expected, actual); + + ms.Position = 0; + var deserialized = new Mocks.TestDirectedMessage(); + var reader = JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max); + serializer.Deserialize(this.MessageDescriptions.GetAccessor(deserialized), reader); + Assert.AreEqual(message.Age, deserialized.Age); + Assert.AreEqual(message.EmptyMember, deserialized.EmptyMember); + Assert.AreEqual(message.Location, deserialized.Location); + Assert.AreEqual(message.Name, deserialized.Name); + Assert.AreEqual(message.Timestamp, deserialized.Timestamp); + } + [TestCase, ExpectedException(typeof(ArgumentNullException))] public void DeserializeNull() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs index 2b0e8f9..1e0ede5 100644 --- a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs @@ -4,8 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test.Messaging -{ +namespace DotNetOpenAuth.Test.Messaging { using System; using System.Collections.Generic; using System.Collections.Specialized; @@ -216,5 +215,17 @@ namespace DotNetOpenAuth.Test.Messaging public void GetHttpDeliveryMethodOutOfRangeTest() { MessagingUtilities.GetHttpDeliveryMethod("UNRECOGNIZED"); } + + [TestCase] + public void EncryptDecrypt() { + const string PlainText = "Hi folks!"; + byte[] key = MessagingUtilities.GetCryptoRandomData(128 / 8); + var cipher = MessagingUtilities.Encrypt(PlainText, key); + + Console.WriteLine("Encrypted \"{0}\" ({1} length) to {2} encrypted bytes.", PlainText, PlainText.Length, cipher.Length); + + string roundTripped = MessagingUtilities.Decrypt(cipher, key); + Assert.AreEqual(PlainText, roundTripped); + } } } diff --git a/src/DotNetOpenAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs b/src/DotNetOpenAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs index e57df65..92f39cc 100644 --- a/src/DotNetOpenAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs @@ -73,6 +73,16 @@ namespace DotNetOpenAuth.Test.Messaging.Reflection { Assert.IsTrue(v30.Mapping["OptionalIn10RequiredIn25AndLater"].IsRequired); } + /// <summary> + /// Verifies that the constructors cache is properly initialized. + /// </summary> + [TestCase] + public void CtorsCache() { + var message = new MessageDescription(typeof(MultiVersionMessage), new Version(1, 0)); + Assert.IsNotNull(message.Constructors); + Assert.AreEqual(1, message.Constructors.Length); + } + private class MultiVersionMessage : Mocks.TestBaseMessage { #pragma warning disable 0649 // these fields are never written to, but part of the test [MessagePart] diff --git a/src/DotNetOpenAuth.Test/Messaging/StandardMessageFactoryTests.cs b/src/DotNetOpenAuth.Test/Messaging/StandardMessageFactoryTests.cs new file mode 100644 index 0000000..2b0b4e7 --- /dev/null +++ b/src/DotNetOpenAuth.Test/Messaging/StandardMessageFactoryTests.cs @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------- +// <copyright file="StandardMessageFactoryTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Messaging { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.Test.Mocks; + using NUnit.Framework; + + [TestFixture] + public class StandardMessageFactoryTests : MessagingTestBase { + private static readonly Version V1 = new Version(1, 0); + private static readonly MessageReceivingEndpoint receiver = new MessageReceivingEndpoint("http://receiver", HttpDeliveryMethods.PostRequest); + + private StandardMessageFactory factory; + + public override void SetUp() { + base.SetUp(); + + this.factory = new StandardMessageFactory(); + } + + /// <summary> + /// Verifies that AddMessageTypes throws the appropriate exception on null input. + /// </summary> + [TestCase, ExpectedException(typeof(ArgumentNullException))] + public void AddMessageTypesNull() { + this.factory.AddMessageTypes(null); + } + + /// <summary> + /// Verifies that AddMessageTypes throws the appropriate exception on null input. + /// </summary> + [TestCase, ExpectedException(typeof(ArgumentException))] + public void AddMessageTypesNullMessageDescription() { + this.factory.AddMessageTypes(new MessageDescription[] { null }); + } + + /// <summary> + /// Verifies very simple recognition of a single message type + /// </summary> + [TestCase] + public void SingleRequestMessageType() { + this.factory.AddMessageTypes(new MessageDescription[] { MessageDescriptions.Get(typeof(RequestMessageMock), V1) }); + var fields = new Dictionary<string, string> { + { "random", "bits" }, + }; + Assert.IsNull(this.factory.GetNewRequestMessage(receiver, fields)); + fields["Age"] = "18"; + Assert.IsInstanceOf(typeof(RequestMessageMock), this.factory.GetNewRequestMessage(receiver, fields)); + } + + /// <summary> + /// Verifies very simple recognition of a single message type + /// </summary> + [TestCase] + public void SingleResponseMessageType() { + this.factory.AddMessageTypes(new MessageDescription[] { MessageDescriptions.Get(typeof(DirectResponseMessageMock), V1) }); + var fields = new Dictionary<string, string> { + { "random", "bits" }, + }; + IDirectedProtocolMessage request = new RequestMessageMock(receiver.Location, V1); + Assert.IsNull(this.factory.GetNewResponseMessage(request, fields)); + fields["Age"] = "18"; + IDirectResponseProtocolMessage response = this.factory.GetNewResponseMessage(request, fields); + Assert.IsInstanceOf<DirectResponseMessageMock>(response); + Assert.AreSame(request, response.OriginatingRequest); + + // Verify that we can instantiate a response with a derived-type of an expected request message. + request = new TestSignedDirectedMessage(); + response = this.factory.GetNewResponseMessage(request, fields); + Assert.IsInstanceOf<DirectResponseMessageMock>(response); + Assert.AreSame(request, response.OriginatingRequest); + } + + private class DirectResponseMessageMock : IDirectResponseProtocolMessage { + internal DirectResponseMessageMock(RequestMessageMock request) { + this.OriginatingRequest = request; + } + + internal DirectResponseMessageMock(TestDirectedMessage request) { + this.OriginatingRequest = request; + } + + [MessagePart(IsRequired = true)] + public int Age { get; set; } + + #region IDirectResponseProtocolMessage Members + + public IDirectedProtocolMessage OriginatingRequest { get; private set; } + + #endregion + + #region IProtocolMessage Members + + public MessageProtections RequiredProtection { + get { throw new NotImplementedException(); } + } + + public MessageTransport Transport { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IMessage Members + + public Version Version { + get { throw new NotImplementedException(); } + } + + public System.Collections.Generic.IDictionary<string, string> ExtraData { + get { throw new NotImplementedException(); } + } + + public void EnsureValidMessage() { + throw new NotImplementedException(); + } + + #endregion + } + + private class RequestMessageMock : IDirectedProtocolMessage { + internal RequestMessageMock(Uri recipient, Version version) { + } + + [MessagePart(IsRequired = true)] + public int Age { get; set; } + + #region IDirectedProtocolMessage Members + + public HttpDeliveryMethods HttpMethods { + get { throw new NotImplementedException(); } + } + + public Uri Recipient { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IProtocolMessage Members + + public MessageProtections RequiredProtection { + get { throw new NotImplementedException(); } + } + + public MessageTransport Transport { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IMessage Members + + public Version Version { + get { throw new NotImplementedException(); } + } + + public System.Collections.Generic.IDictionary<string, string> ExtraData { + get { throw new NotImplementedException(); } + } + + public void EnsureValidMessage() { + throw new NotImplementedException(); + } + + #endregion + } + } +} diff --git a/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs b/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs index d692320..20fd6c4 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; using System.Linq; + using System.Net; using System.Text; using DotNetOpenAuth.Messaging; @@ -23,8 +24,15 @@ namespace DotNetOpenAuth.Test.Mocks { /// <summary> /// Gets or sets the HTTP status code that the direct respones should be sent with. /// </summary> - /// <value></value> - public System.Net.HttpStatusCode HttpStatusCode { get; set; } + public HttpStatusCode HttpStatusCode { get; set; } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + public WebHeaderCollection Headers { + get { return new WebHeaderCollection(); } + } #endregion } diff --git a/src/DotNetOpenAuth.Test/OAuthWrap/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuthWrap/MessageFactoryTests.cs new file mode 100644 index 0000000..827027e --- /dev/null +++ b/src/DotNetOpenAuth.Test/OAuthWrap/MessageFactoryTests.cs @@ -0,0 +1,254 @@ +//----------------------------------------------------------------------- +// <copyright file="MessageFactoryTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.OAuthWrap { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuthWrap; + using DotNetOpenAuth.OAuthWrap.ChannelElements; + using DotNetOpenAuth.OAuthWrap.Messages; + using NUnit.Framework; + + /// <summary> + /// Verifies that the WRAP message types are recognized. + /// </summary> + public class MessageFactoryTests : OAuthWrapTestBase { + private readonly MessageReceivingEndpoint recipient = new MessageReceivingEndpoint("http://who", HttpDeliveryMethods.PostRequest); + private OAuthWrapAuthorizationServerChannel channel; + private IMessageFactory messageFactory; + + public override void SetUp() { + base.SetUp(); + + this.channel = new OAuthWrapAuthorizationServerChannel(); + this.messageFactory = OAuthWrapAuthorizationServerChannel_Accessor.AttachShadow(this.channel).MessageFactory; + } + + #region Refresh Access Token messages + + [TestCase] + public void RefreshAccessTokenRequest() { + var fields = new Dictionary<string, string> { + { Protocol.refresh_token, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(RefreshAccessTokenRequest), request); + } + + [TestCase] + public void RefreshAccessTokenSuccessResponse() { + var fields = new Dictionary<string, string> { + { Protocol.access_token, "abc" }, + }; + var request = new RefreshAccessTokenRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(AccessTokenSuccessResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + [TestCase] + public void RefreshAccessTokenFailedResponse() { + var fields = new Dictionary<string, string> { + }; + var request = new RefreshAccessTokenRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(AccessTokenFailedResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + #endregion + + #region Web App profile messages + + [TestCase] + public void WebAppRequestRequest() { + var fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + { Protocol.redirect_uri, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(WebServerRequest), request); + } + + [TestCase] + public void WebAppFailedResponse() { + var fields = new Dictionary<string, string> { + { Protocol.error, "user_denied" }, + }; + var request = new WebServerRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(WebServerFailedResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + [TestCase] + public void WebAppSuccessResponse() { + var fields = new Dictionary<string, string> { + { Protocol.code, "abc" }, + }; + var request = new WebServerRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(WebServerSuccessResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + [TestCase] + public void WebAppAccessTokenRequest() { + var fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + { Protocol.client_secret, "abc" }, + { Protocol.code, "abc" }, + { Protocol.redirect_uri, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(WebServerAccessTokenRequest), request); + } + + [TestCase, Ignore("Not implemented")] + public void WebAppAccessTokenFailedResponse() { + // HTTP 400 Bad Request + } + + [TestCase, Ignore("Not implemented")] + public void WebAppAccessTokenBadClientResponse() { + // HTTP 401 Unauthorized + // WWW-Authenticate: WRAP + } + + #endregion + + #region Username and Password profile messages + + [TestCase] + public void UserNamePasswordRequest() { + var fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + { Protocol.client_secret, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(UserNamePasswordRequest), request); + } + + [TestCase] + public void UserNamePasswordSuccessResponse() { + var fields = new Dictionary<string, string> { + { Protocol.access_token, "abc" }, + }; + var request = new UserNamePasswordRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(UserNamePasswordSuccessResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + [TestCase] + public void UserNamePasswordVerificationResponse() { + // HTTP 400 Bad Request + var fields = new Dictionary<string, string> { + { Protocol.code, "abc" }, + }; + var request = new UserNamePasswordRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(UserNamePasswordVerificationResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + [TestCase, Ignore("Not implemented")] + public void UserNamePasswordFailedResponse() { + // HTTP 401 Unauthorized + // WWW-Authenticate: WRAP + } + + [TestCase] + public void UsernamePasswordCaptchaResponse() { + // HTTP 400 Bad Request + var fields = new Dictionary<string, string> { + { Protocol.wrap_captcha_url, "abc" }, + }; + var request = new UserNamePasswordRequest(this.recipient.Location, Protocol.Default.Version); + Assert.IsInstanceOf( + typeof(UsernamePasswordCaptchaResponse), + this.messageFactory.GetNewResponseMessage(request, fields)); + } + + #endregion + + #region Rich App profile messages + + [TestCase] + public void RichAppRequest() { + // include just required parameters + var fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(DeviceRequest), request); + + // including optional parts + fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + { Protocol.redirect_uri, "abc" }, + { Protocol.state, "abc" }, + { Protocol.scope, "abc" }, + }; + request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(DeviceRequest), request); + } + + [TestCase] + public void RichAppResponse() { + var fields = new Dictionary<string, string> { + { Protocol.refresh_token, "abc" }, + { Protocol.access_token, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(DeviceResponse), request); + } + + [TestCase] + public void RichAppAccessTokenRequest() { + // include just required parameters + var fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + { Protocol.code, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(DeviceAccessTokenRequest), request); + } + + #endregion + + #region Client Account and Password profile messages + + [TestCase] + public void ClientCredentialsRequest() { + var fields = new Dictionary<string, string> { + { Protocol.client_id, "abc" }, + { Protocol.client_secret, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(ClientCredentialsRequest), request); + } + + #endregion + + #region Assertion profile messages + + [TestCase] + public void AssertionRequest() { + var fields = new Dictionary<string, string> { + { Protocol.format, "abc" }, + { Protocol.assertion, "abc" }, + }; + IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + Assert.IsInstanceOf(typeof(AssertionRequest), request); + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth.Test/OAuthWrap/OAuthWrapChannelTests.cs b/src/DotNetOpenAuth.Test/OAuthWrap/OAuthWrapChannelTests.cs new file mode 100644 index 0000000..c7fe48f --- /dev/null +++ b/src/DotNetOpenAuth.Test/OAuthWrap/OAuthWrapChannelTests.cs @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------- +// <copyright file="OAuthWrapChannelTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.OAuthWrap { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuthWrap; + using DotNetOpenAuth.OAuthWrap.ChannelElements; + using DotNetOpenAuth.OAuthWrap.Messages; + using NUnit.Framework; + + [TestFixture] + public class OAuthWrapChannelTests : OAuthWrapTestBase { + } +} diff --git a/src/DotNetOpenAuth.Test/OAuthWrap/OAuthWrapTestBase.cs b/src/DotNetOpenAuth.Test/OAuthWrap/OAuthWrapTestBase.cs new file mode 100644 index 0000000..08c9da6 --- /dev/null +++ b/src/DotNetOpenAuth.Test/OAuthWrap/OAuthWrapTestBase.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------- +// <copyright file="OAuthWrapTestBase.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.OAuthWrap { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + public class OAuthWrapTestBase : TestBase { + } +} |