summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth.Test
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOAuth.Test')
-rw-r--r--src/DotNetOAuth.Test/DotNetOAuth.Test.csproj8
-rw-r--r--src/DotNetOAuth.Test/Messaging/ChannelTests.cs33
-rw-r--r--src/DotNetOAuth.Test/Messaging/CollectionAssert.cs19
-rw-r--r--src/DotNetOAuth.Test/Messaging/DictionaryXmlReaderTests.cs33
-rw-r--r--src/DotNetOAuth.Test/Messaging/MessageSerializerTests.cs73
-rw-r--r--src/DotNetOAuth.Test/Messaging/MessagingTestBase.cs100
-rw-r--r--src/DotNetOAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs21
-rw-r--r--src/DotNetOAuth.Test/Messaging/Reflection/MessageDictionaryTests.cs347
-rw-r--r--src/DotNetOAuth.Test/Messaging/Reflection/MessagePartTests.cs99
-rw-r--r--src/DotNetOAuth.Test/Messaging/Reflection/ValueMappingTests.cs21
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestBaseMessage.cs16
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestDerivedMessage.cs5
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestDirectedMessage.cs37
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestExpiringMessage.cs5
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestMessage.cs20
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestReplayProtectedMessage.cs5
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestSignedDirectedMessage.cs5
-rw-r--r--src/DotNetOAuth.Test/OAuthChannelTests.cs7
18 files changed, 681 insertions, 173 deletions
diff --git a/src/DotNetOAuth.Test/DotNetOAuth.Test.csproj b/src/DotNetOAuth.Test/DotNetOAuth.Test.csproj
index 09b5974..dfa7fef 100644
--- a/src/DotNetOAuth.Test/DotNetOAuth.Test.csproj
+++ b/src/DotNetOAuth.Test/DotNetOAuth.Test.csproj
@@ -58,13 +58,18 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Messaging\CollectionAssert.cs" />
+ <Compile Include="Messaging\MessageSerializerTests.cs" />
+ <Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" />
+ <Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" />
<Compile Include="Messaging\MessagingTestBase.cs" />
<Compile Include="Messaging\MessagingUtilitiesTests.cs" />
<Compile Include="Messaging\ChannelTests.cs" />
- <Compile Include="Messaging\DictionaryXmlReaderTests.cs" />
<Compile Include="Messaging\HttpRequestInfoTests.cs" />
<Compile Include="Messaging\ProtocolExceptionTests.cs" />
<Compile Include="Messaging\Bindings\StandardExpirationBindingElementTests.cs" />
+ <Compile Include="Messaging\Reflection\MessagePartTests.cs" />
+ <Compile Include="Messaging\Reflection\ValueMappingTests.cs" />
<Compile Include="Mocks\MockTransformationBindingElement.cs" />
<Compile Include="Mocks\MockReplayProtectionBindingElement.cs" />
<Compile Include="Mocks\TestBaseMessage.cs" />
@@ -77,7 +82,6 @@
<Compile Include="Mocks\MockSigningBindingElement.cs" />
<Compile Include="Mocks\TestWebRequestHandler.cs" />
<Compile Include="OAuthChannelTests.cs" />
- <Compile Include="Messaging\MessageSerializerTests.cs" />
<Compile Include="Mocks\TestChannel.cs" />
<Compile Include="Mocks\TestMessage.cs" />
<Compile Include="Mocks\TestMessageTypeProvider.cs" />
diff --git a/src/DotNetOAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
index 5ffd1d6..e8c4514 100644
--- a/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
+++ b/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
@@ -14,6 +14,7 @@ namespace DotNetOAuth.Test.Messaging {
using DotNetOAuth.Messaging.Bindings;
using DotNetOAuth.Test.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using System.Xml;
[TestClass]
public class ChannelTests : MessagingTestBase {
@@ -64,19 +65,21 @@ namespace DotNetOAuth.Test.Messaging {
[TestMethod]
public void SendIndirectMessage301Get() {
- IProtocolMessage message = new TestDirectedMessage(MessageTransport.Indirect) {
- Age = 15,
- Name = "Andrew",
- Location = new Uri("http://host/path"),
- Recipient = new Uri("http://provider/path"),
- };
+ TestDirectedMessage message = new TestDirectedMessage(MessageTransport.Indirect);
+ GetStandardTestMessage(FieldFill.CompleteBeforeBindings, message);
+ message.Recipient = new Uri("http://provider/path");
+ var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
+
this.Channel.Send(message);
Response response = this.Channel.DequeueIndirectOrResponseMessage();
Assert.AreEqual(HttpStatusCode.Redirect, response.Status);
StringAssert.StartsWith(response.Headers[HttpResponseHeader.Location], "http://provider/path");
- StringAssert.Contains(response.Headers[HttpResponseHeader.Location], "age=15");
- StringAssert.Contains(response.Headers[HttpResponseHeader.Location], "Name=Andrew");
- StringAssert.Contains(response.Headers[HttpResponseHeader.Location], "Location=http%3a%2f%2fhost%2fpath");
+ foreach (var pair in expected) {
+ string key = HttpUtility.UrlEncode(pair.Key);
+ string value = HttpUtility.UrlEncode(pair.Value);
+ string substring = string.Format("{0}={1}", key, value);
+ StringAssert.Contains(response.Headers[HttpResponseHeader.Location], substring);
+ }
}
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
@@ -198,12 +201,14 @@ namespace DotNetOAuth.Test.Messaging {
[TestMethod]
public void ReadFromRequestWithContext() {
// TODO: make this a request with a message in it.
- HttpRequest request = new HttpRequest("somefile", "http://someurl", "age=15");
+ var fields = GetStandardTestFields(FieldFill.AllRequired);
+ TestMessage expectedMessage = GetStandardTestMessage(FieldFill.AllRequired);
+ HttpRequest request = new HttpRequest("somefile", "http://someurl", MessagingUtilities.CreateQueryString(fields));
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
IProtocolMessage message = this.Channel.ReadFromRequest();
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(TestMessage));
- Assert.AreEqual(15, ((TestMessage)message).Age);
+ Assert.AreEqual(expectedMessage.Age, ((TestMessage)message).Age);
}
[TestMethod, ExpectedException(typeof(InvalidOperationException))]
@@ -298,5 +303,11 @@ namespace DotNetOAuth.Test.Messaging {
this.Channel = CreateChannel(MessageProtection.None, MessageProtection.TamperProtection);
this.ParameterizedReceiveProtectedTest(DateTime.Now, false);
}
+
+ [TestMethod, ExpectedException(typeof(ProtocolException))]
+ public void IncomingMessageMissingRequiredParameters() {
+ var fields = GetStandardTestFields(FieldFill.IdentifiableButNotAllRequired);
+ this.Channel.ReadFromRequest(CreateHttpRequestInfo("GET", fields));
+ }
}
}
diff --git a/src/DotNetOAuth.Test/Messaging/CollectionAssert.cs b/src/DotNetOAuth.Test/Messaging/CollectionAssert.cs
new file mode 100644
index 0000000..b9f3da5
--- /dev/null
+++ b/src/DotNetOAuth.Test/Messaging/CollectionAssert.cs
@@ -0,0 +1,19 @@
+//-----------------------------------------------------------------------
+// <copyright file="CollectionAssert.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Test.Messaging {
+ using System.Collections;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ internal class CollectionAssert<T> {
+ internal static void AreEquivalent(ICollection<T> expected, ICollection<T> actual) {
+ ICollection expectedNonGeneric = new List<T>(expected);
+ ICollection actualNonGeneric = new List<T>(actual);
+ CollectionAssert.AreEquivalent(expectedNonGeneric, actualNonGeneric);
+ }
+ }
+}
diff --git a/src/DotNetOAuth.Test/Messaging/DictionaryXmlReaderTests.cs b/src/DotNetOAuth.Test/Messaging/DictionaryXmlReaderTests.cs
deleted file mode 100644
index 54c47f0..0000000
--- a/src/DotNetOAuth.Test/Messaging/DictionaryXmlReaderTests.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="DictionaryXmlReaderTests.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.Test.Messaging {
- using System;
- using System.Collections.Generic;
- using System.Xml.Linq;
- using DotNetOAuth.Messaging;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
-
- [TestClass]
- public class DictionaryXmlReaderTests : TestBase {
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void CreateWithNullRootElement() {
- IComparer<string> fieldSorter = new DataContractMemberComparer(typeof(Mocks.TestMessage));
- DictionaryXmlReader.Create(null, fieldSorter, new Dictionary<string, string>());
- }
-
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void CreateWithNullDataContractType() {
- DictionaryXmlReader.Create(XName.Get("name", "ns"), null, new Dictionary<string, string>());
- }
-
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void CreateWithNullFields() {
- IComparer<string> fieldSorter = new DataContractMemberComparer(typeof(Mocks.TestMessage));
- DictionaryXmlReader.Create(XName.Get("name", "ns"), fieldSorter, null);
- }
- }
-}
diff --git a/src/DotNetOAuth.Test/Messaging/MessageSerializerTests.cs b/src/DotNetOAuth.Test/Messaging/MessageSerializerTests.cs
index 162d456..a41753b 100644
--- a/src/DotNetOAuth.Test/Messaging/MessageSerializerTests.cs
+++ b/src/DotNetOAuth.Test/Messaging/MessageSerializerTests.cs
@@ -9,30 +9,19 @@ namespace DotNetOAuth.Test.Messaging {
using System.Collections.Generic;
using DotNetOAuth.Messaging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using System.Xml;
/// <summary>
/// Tests for the <see cref="MessageSerializer"/> class.
/// </summary>
[TestClass()]
- public class MessageSerializerTests : TestBase {
+ public class MessageSerializerTests : MessagingTestBase {
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void SerializeNull() {
var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
serializer.Serialize(null);
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void SerializeNullFields() {
- var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- serializer.Serialize(null, new Mocks.TestMessage());
- }
-
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void SerializeNullMessage() {
- var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- serializer.Serialize(new Dictionary<string, string>(), null);
- }
-
[TestMethod, ExpectedException(typeof(ArgumentException))]
public void GetInvalidMessageType() {
MessageSerializer.Get(typeof(string));
@@ -43,29 +32,11 @@ namespace DotNetOAuth.Test.Messaging {
MessageSerializer.Get(null);
}
- [TestMethod]
- public void GetReturnsSameSerializerTwice() {
- Assert.AreSame(MessageSerializer.Get(typeof(Mocks.TestMessage)), MessageSerializer.Get(typeof(Mocks.TestMessage)));
- }
-
- [TestMethod, ExpectedException(typeof(ProtocolException))]
- public void SerializeInvalidMessage() {
- var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- Dictionary<string, string> fields = new Dictionary<string, string>(StringComparer.Ordinal);
- Mocks.TestMessage message = new Mocks.TestMessage();
- message.EmptyMember = "invalidvalue";
- serializer.Serialize(message);
- }
-
[TestMethod()]
public void SerializeTest() {
var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- var message = new Mocks.TestMessage {
- Age = 15,
- Name = "Andrew",
- Location = new Uri("http://localhost"),
- Timestamp = DateTime.Parse("1/1/1990"),
- };
+ var message = GetStandardTestMessage(FieldFill.CompleteBeforeBindings);
+ var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
IDictionary<string, string> actual = serializer.Serialize(message);
Assert.AreEqual(4, actual.Count);
@@ -74,26 +45,13 @@ namespace DotNetOAuth.Test.Messaging {
Assert.IsTrue(actual.ContainsKey("age"));
// Test contents of dictionary
- Assert.AreEqual("15", actual["age"]);
- Assert.AreEqual("Andrew", actual["Name"]);
- Assert.AreEqual("http://localhost/", actual["Location"]);
- Assert.AreEqual("1990-01-01T00:00:00", actual["Timestamp"]);
+ Assert.AreEqual(expected["age"], actual["age"]);
+ Assert.AreEqual(expected["Name"], actual["Name"]);
+ Assert.AreEqual(expected["Location"], actual["Location"]);
+ Assert.AreEqual(expected["Timestamp"], actual["Timestamp"]);
Assert.IsFalse(actual.ContainsKey("EmptyMember"));
}
- [TestMethod]
- public void SerializeToExistingDictionary() {
- var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- var message = new Mocks.TestMessage { Age = 15, Name = "Andrew" };
- var fields = new Dictionary<string, string>();
- fields["someExtraField"] = "someValue";
- serializer.Serialize(fields, message);
- Assert.AreEqual(4, fields.Count);
- Assert.AreEqual("15", fields["age"]);
- Assert.AreEqual("Andrew", fields["Name"]);
- Assert.AreEqual("someValue", fields["someExtraField"]);
- }
-
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void DeserializeNull() {
var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
@@ -115,7 +73,7 @@ namespace DotNetOAuth.Test.Messaging {
}
/// <summary>
- /// This tests deserialization of a message that is comprised of [DataMember]'s
+ /// This tests deserialization of a message that is comprised of [MessagePart]'s
/// that are defined in multiple places in the inheritance tree.
/// </summary>
/// <remarks>
@@ -151,6 +109,7 @@ namespace DotNetOAuth.Test.Messaging {
Dictionary<string, string> fields = new Dictionary<string, string>(StringComparer.Ordinal);
fields["age"] = "15";
fields["Name"] = "Andrew";
+ fields["Timestamp"] = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc);
// Add some field that is not recognized by the class. This simulates a querystring with
// more parameters than are actually interesting to the protocol message.
fields["someExtraField"] = "asdf";
@@ -161,18 +120,10 @@ namespace DotNetOAuth.Test.Messaging {
}
[TestMethod, ExpectedException(typeof(ProtocolException))]
- public void DeserializeEmpty() {
- var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- var fields = new Dictionary<string, string>(StringComparer.Ordinal);
- serializer.Deserialize(fields);
- }
-
- [TestMethod, ExpectedException(typeof(ProtocolException))]
public void DeserializeInvalidMessage() {
var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
- Dictionary<string, string> fields = new Dictionary<string, string>(StringComparer.Ordinal);
- // Set an disallowed value.
- fields["age"] = "-1";
+ var fields = GetStandardTestFields(FieldFill.AllRequired);
+ fields["age"] = "-1"; // Set an disallowed value.
serializer.Deserialize(fields);
}
}
diff --git a/src/DotNetOAuth.Test/Messaging/MessagingTestBase.cs b/src/DotNetOAuth.Test/Messaging/MessagingTestBase.cs
index a21b000..34cf1df 100644
--- a/src/DotNetOAuth.Test/Messaging/MessagingTestBase.cs
+++ b/src/DotNetOAuth.Test/Messaging/MessagingTestBase.cs
@@ -85,29 +85,89 @@ namespace DotNetOAuth.Test {
return new TestChannel(typeProvider, bindingElements.ToArray());
}
+ internal enum FieldFill {
+ /// <summary>
+ /// An empty dictionary is returned.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Only enough fields for the <see cref="TestMessageTypeProvider"/>
+ /// to identify the message are included.
+ /// </summary>
+ IdentifiableButNotAllRequired,
+
+ /// <summary>
+ /// All fields marked as required are included.
+ /// </summary>
+ AllRequired,
+
+ /// <summary>
+ /// All user-fillable fields in the message, leaving out those whose
+ /// values are to be set by channel binding elements.
+ /// </summary>
+ CompleteBeforeBindings,
+ }
+
+ internal static IDictionary<string, string> GetStandardTestFields(FieldFill fill) {
+ TestMessage expectedMessage = GetStandardTestMessage(fill);
+
+ var fields = new Dictionary<string, string>();
+ if (fill >= FieldFill.IdentifiableButNotAllRequired) {
+ fields.Add("age", expectedMessage.Age.ToString());
+ }
+ if (fill >= FieldFill.AllRequired) {
+ fields.Add("Timestamp", XmlConvert.ToString(expectedMessage.Timestamp, XmlDateTimeSerializationMode.Utc));
+ }
+ if (fill >= FieldFill.CompleteBeforeBindings) {
+ fields.Add("Name", expectedMessage.Name);
+ fields.Add("Location", expectedMessage.Location.AbsoluteUri);
+ }
+
+ return fields;
+ }
+
+ internal static TestMessage GetStandardTestMessage(FieldFill fill) {
+ TestMessage message = new TestMessage();
+ GetStandardTestMessage(fill, message);
+ return message;
+ }
+
+ internal static void GetStandardTestMessage(FieldFill fill, TestMessage message) {
+ if (message == null) {
+ throw new ArgumentNullException("message");
+ }
+
+ if (fill >= FieldFill.IdentifiableButNotAllRequired) {
+ message.Age = 15;
+ }
+ if (fill >= FieldFill.AllRequired) {
+ message.Timestamp = DateTime.SpecifyKind(DateTime.Parse("9/19/2008 8 AM"), DateTimeKind.Utc);
+ }
+ if (fill >= FieldFill.CompleteBeforeBindings) {
+ message.Name = "Andrew";
+ message.Location = new Uri("http://localtest/path");
+ }
+ }
+
internal void ParameterizedReceiveTest(string method) {
- var fields = new Dictionary<string, string> {
- { "age", "15" },
- { "Name", "Andrew" },
- { "Location", "http://hostb/pathB" },
- };
+ var fields = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
+ TestMessage expectedMessage = GetStandardTestMessage(FieldFill.CompleteBeforeBindings); ;
+
IProtocolMessage requestMessage = this.Channel.ReadFromRequest(CreateHttpRequestInfo(method, fields));
Assert.IsNotNull(requestMessage);
Assert.IsInstanceOfType(requestMessage, typeof(TestMessage));
- TestMessage testMessage = (TestMessage)requestMessage;
- Assert.AreEqual(15, testMessage.Age);
- Assert.AreEqual("Andrew", testMessage.Name);
- Assert.AreEqual("http://hostb/pathB", testMessage.Location.AbsoluteUri);
+ TestMessage actualMessage = (TestMessage)requestMessage;
+ Assert.AreEqual(expectedMessage.Age, actualMessage.Age);
+ Assert.AreEqual(expectedMessage.Name, actualMessage.Name);
+ Assert.AreEqual(expectedMessage.Location, actualMessage.Location);
}
internal void ParameterizedReceiveProtectedTest(DateTime? utcCreatedDate, bool invalidSignature) {
- var fields = new Dictionary<string, string> {
- { "age", "15" },
- { "Name", "Andrew" },
- { "Location", "http://hostb/pathB" },
- { "Signature", invalidSignature ? "badsig" : MockSigningBindingElement.MessageSignature },
- { "Nonce", "someNonce" },
- };
+ TestMessage expectedMessage = GetStandardTestMessage(FieldFill.CompleteBeforeBindings); ;
+ var fields = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
+ fields.Add("Signature", invalidSignature ? "badsig" : MockSigningBindingElement.MessageSignature);
+ fields.Add("Nonce", "someNonce");
if (utcCreatedDate.HasValue) {
utcCreatedDate = DateTime.Parse(utcCreatedDate.Value.ToUniversalTime().ToString()); // round off the milliseconds so comparisons work later
fields.Add("created_on", XmlConvert.ToString(utcCreatedDate.Value, XmlDateTimeSerializationMode.Utc));
@@ -115,10 +175,10 @@ namespace DotNetOAuth.Test {
IProtocolMessage requestMessage = this.Channel.ReadFromRequest(CreateHttpRequestInfo("GET", fields));
Assert.IsNotNull(requestMessage);
Assert.IsInstanceOfType(requestMessage, typeof(TestSignedDirectedMessage));
- TestSignedDirectedMessage testMessage = (TestSignedDirectedMessage)requestMessage;
- Assert.AreEqual(15, testMessage.Age);
- Assert.AreEqual("Andrew", testMessage.Name);
- Assert.AreEqual("http://hostb/pathB", testMessage.Location.AbsoluteUri);
+ TestSignedDirectedMessage actualMessage = (TestSignedDirectedMessage)requestMessage;
+ Assert.AreEqual(expectedMessage.Age, actualMessage.Age);
+ Assert.AreEqual(expectedMessage.Name, actualMessage.Name);
+ Assert.AreEqual(expectedMessage.Location, actualMessage.Location);
if (utcCreatedDate.HasValue) {
IExpiringProtocolMessage expiringMessage = (IExpiringProtocolMessage)requestMessage;
Assert.AreEqual(utcCreatedDate.Value, expiringMessage.UtcCreationDate);
diff --git a/src/DotNetOAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs b/src/DotNetOAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs
new file mode 100644
index 0000000..04c1df8
--- /dev/null
+++ b/src/DotNetOAuth.Test/Messaging/Reflection/MessageDescriptionTests.cs
@@ -0,0 +1,21 @@
+namespace DotNetOAuth.Test.Messaging.Reflection {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using DotNetOAuth.Messaging.Reflection;
+
+ [TestClass]
+ public class MessageDescriptionTests : MessagingTestBase {
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void GetNull() {
+ MessageDescription.Get(null);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void GetNonMessageType() {
+ MessageDescription.Get(typeof(string));
+ }
+ }
+}
diff --git a/src/DotNetOAuth.Test/Messaging/Reflection/MessageDictionaryTests.cs b/src/DotNetOAuth.Test/Messaging/Reflection/MessageDictionaryTests.cs
new file mode 100644
index 0000000..b1ae0b6
--- /dev/null
+++ b/src/DotNetOAuth.Test/Messaging/Reflection/MessageDictionaryTests.cs
@@ -0,0 +1,347 @@
+//-----------------------------------------------------------------------
+// <copyright file="MessageDictionaryTest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Test.Messaging.Reflection {
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Reflection;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using System.Xml;
+
+ [TestClass]
+ public class MessageDictionaryTests : MessagingTestBase {
+ private Mocks.TestMessage message;
+
+ [TestInitialize]
+ public override void SetUp() {
+ base.SetUp();
+
+ this.message = new Mocks.TestMessage();
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNull() {
+ new MessageDictionary(null);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String>.Values
+ /// </summary>
+ [TestMethod]
+ public void Values() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ Collection<string> expected = new Collection<string> {
+ this.message.Age.ToString(),
+ XmlConvert.ToString(DateTime.SpecifyKind(this.message.Timestamp, DateTimeKind.Utc), XmlDateTimeSerializationMode.Utc),
+ };
+ CollectionAssert<string>.AreEquivalent(expected, target.Values);
+
+ this.message.Age = 15;
+ this.message.Location = new Uri("http://localtest");
+ this.message.Name = "Andrew";
+ target["extra"] = "a";
+ expected = new Collection<string> {
+ this.message.Age.ToString(),
+ this.message.Location.AbsoluteUri,
+ this.message.Name,
+ XmlConvert.ToString(DateTime.SpecifyKind(this.message.Timestamp, DateTimeKind.Utc), XmlDateTimeSerializationMode.Utc),
+ "a",
+ };
+ CollectionAssert<string>.AreEquivalent(expected, target.Values);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String>.Keys
+ /// </summary>
+ [TestMethod]
+ public void Keys() {
+ // We expect that non-nullable value type fields will automatically have keys
+ // in the dictionary for them.
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ Collection<string> expected = new Collection<string> {
+ "age",
+ "Timestamp",
+ };
+ CollectionAssert<string>.AreEquivalent(expected, target.Keys);
+
+ this.message.Name = "Andrew";
+ expected.Add("Name");
+ target["extraField"] = string.Empty;
+ expected.Add("extraField");
+ CollectionAssert<string>.AreEquivalent(expected, target.Keys);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String>.Item
+ /// </summary>
+ [TestMethod]
+ public void Item() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+
+ // Test setting of declared message properties.
+ this.message.Age = 15;
+ Assert.AreEqual("15", target["age"]);
+ target["age"] = "13";
+ Assert.AreEqual(13, this.message.Age);
+
+ // Test setting extra fields
+ target["extra"] = "fun";
+ Assert.AreEqual("fun", target["extra"]);
+ Assert.AreEqual("fun", ((IProtocolMessage)this.message).ExtraData["extra"]);
+
+ // Test clearing extra fields
+ target["extra"] = null;
+ Assert.IsFalse(target.ContainsKey("extra"));
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.IsReadOnly
+ /// </summary>
+ [TestMethod]
+ public void IsReadOnly() {
+ ICollection<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ Assert.IsFalse(target.IsReadOnly);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.Count
+ /// </summary>
+ [TestMethod]
+ public void Count() {
+ ICollection<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ IDictionary<string, string> targetDictionary = (IDictionary<string, string>)target;
+ Assert.AreEqual(targetDictionary.Keys.Count, target.Count);
+ targetDictionary["extraField"] = "hi";
+ Assert.AreEqual(targetDictionary.Keys.Count, target.Count);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IEnumerable&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.GetEnumerator
+ /// </summary>
+ [TestMethod]
+ public void GetEnumerator() {
+ IEnumerable<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ IDictionary<string, string> targetDictionary = (IDictionary<string, string>)target;
+ var keys = targetDictionary.Keys.GetEnumerator();
+ var values = targetDictionary.Values.GetEnumerator();
+ IEnumerator<KeyValuePair<string, string>> actual = target.GetEnumerator();
+
+ bool keysLast = true, valuesLast = true, actualLast = true;
+ while (true) {
+ keysLast = keys.MoveNext();
+ valuesLast = values.MoveNext();
+ actualLast = actual.MoveNext();
+ if (!keysLast || !valuesLast || !actualLast) {
+ break;
+ }
+
+ Assert.AreEqual(keys.Current, actual.Current.Key);
+ Assert.AreEqual(values.Current, actual.Current.Value);
+ }
+ Assert.IsTrue(keysLast == valuesLast && keysLast == actualLast);
+ }
+
+ [TestMethod]
+ public void GetEnumeratorUntyped() {
+ IEnumerable target = new MessageDictionary(this.message);
+ IDictionary<string, string> targetDictionary = (IDictionary<string, string>)target;
+ var keys = targetDictionary.Keys.GetEnumerator();
+ var values = targetDictionary.Values.GetEnumerator();
+ IEnumerator actual = target.GetEnumerator();
+
+ bool keysLast = true, valuesLast = true, actualLast = true;
+ while (true) {
+ keysLast = keys.MoveNext();
+ valuesLast = values.MoveNext();
+ actualLast = actual.MoveNext();
+ if (!keysLast || !valuesLast || !actualLast) {
+ break;
+ }
+
+ KeyValuePair<string, string> current = (KeyValuePair<string, string>)actual.Current;
+ Assert.AreEqual(keys.Current, current.Key);
+ Assert.AreEqual(values.Current, current.Value);
+ }
+ Assert.IsTrue(keysLast == valuesLast && keysLast == actualLast);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String>.TryGetValue
+ /// </summary>
+ [TestMethod]
+ public void TryGetValue() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ this.message.Name = "andrew";
+ string name;
+ Assert.IsTrue(target.TryGetValue("Name", out name));
+ Assert.AreEqual(this.message.Name, name);
+
+ Assert.IsFalse(target.TryGetValue("name", out name));
+ Assert.IsNull(name);
+
+ target["extra"] = "value";
+ string extra;
+ Assert.IsTrue(target.TryGetValue("extra", out extra));
+ Assert.AreEqual("value", extra);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String>.Remove
+ /// </summary>
+ [TestMethod]
+ public void RemoveTest1() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ this.message.Name = "andrew";
+ Assert.IsTrue(target.Remove("Name"));
+ Assert.IsNull(this.message.Name);
+ Assert.IsFalse(target.Remove("Name"));
+
+ Assert.IsFalse(target.Remove("extra"));
+ target["extra"] = "value";
+ Assert.IsTrue(target.Remove("extra"));
+ Assert.IsFalse(target.ContainsKey("extra"));
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String>.ContainsKey
+ /// </summary>
+ [TestMethod]
+ public void ContainsKey() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ Assert.IsTrue(target.ContainsKey("age"), "Value type declared element should have a key.");
+ Assert.IsFalse(target.ContainsKey("Name"), "Null declared element should NOT have a key.");
+
+ Assert.IsFalse(target.ContainsKey("extra"));
+ target["extra"] = "value";
+ Assert.IsTrue(target.ContainsKey("extra"));
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.IDictionary&lt;System.String,System.String&gt;.Add
+ /// </summary>
+ [TestMethod]
+ public void AddByKeyAndValue() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ target.Add("extra", "value");
+ Assert.IsTrue(target.Contains(new KeyValuePair<string, string>("extra", "value")));
+ target.Add("Name", "Andrew");
+ Assert.AreEqual("Andrew", this.message.Name);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void AddNullValue() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ target.Add("extra", null);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.Add
+ /// </summary>
+ [TestMethod]
+ public void AddByKeyValuePair() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ target.Add(new KeyValuePair<string, string>("extra", "value"));
+ Assert.IsTrue(target.Contains(new KeyValuePair<string, string>("extra", "value")));
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void AddExtraFieldThatAlreadyExists() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ target.Add("extra", "value");
+ target.Add("extra", "value");
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void AddDeclaredValueThatAlreadyExists() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ target.Add("Name", "andrew");
+ target.Add("Name", "andrew");
+ }
+
+ [TestMethod]
+ public void DefaultReferenceTypeDeclaredPropertyHasNoKey() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ Assert.IsFalse(target.ContainsKey("Name"), "A null value should result in no key.");
+ Assert.IsFalse(target.Keys.Contains("Name"), "A null value should result in no key.");
+ }
+
+ [TestMethod]
+ public void RemoveStructDeclaredProperty() {
+ IDictionary<string, string> target = new MessageDictionary(this.message);
+ this.message.Age = 5;
+ Assert.IsTrue(target.ContainsKey("age"));
+ target.Remove("age");
+ Assert.IsTrue(target.ContainsKey("age"));
+ Assert.AreEqual(0, this.message.Age);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.Remove
+ /// </summary>
+ [TestMethod]
+ public void RemoveByKeyValuePair() {
+ ICollection<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ this.message.Name = "Andrew";
+ Assert.IsFalse(target.Remove(new KeyValuePair<string, string>("Name", "andrew")));
+ Assert.AreEqual("Andrew", this.message.Name);
+ Assert.IsTrue(target.Remove(new KeyValuePair<string, string>("Name", "Andrew")));
+ Assert.IsNull(this.message.Name);
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.CopyTo
+ /// </summary>
+ [TestMethod]
+ public void CopyTo() {
+ ICollection<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ IDictionary<string, string> targetAsDictionary = ((IDictionary<string, string>)target);
+ KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[target.Count + 1];
+ int arrayIndex = 1;
+ target.CopyTo(array, arrayIndex);
+ Assert.AreEqual(new KeyValuePair<string, string>(), array[0]);
+ for (int i = 1; i < array.Length; i++) {
+ Assert.IsNotNull(array[i].Key);
+ Assert.AreEqual(targetAsDictionary[array[i].Key], array[i].Value);
+ }
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.Contains
+ /// </summary>
+ [TestMethod]
+ public void ContainsKeyValuePair() {
+ ICollection<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ IDictionary<string, string> targetAsDictionary = ((IDictionary<string, string>)target);
+ Assert.IsFalse(target.Contains(new KeyValuePair<string, string>("age", "1")));
+ Assert.IsTrue(target.Contains(new KeyValuePair<string, string>("age", "0")));
+
+ targetAsDictionary["extra"] = "value";
+ Assert.IsFalse(target.Contains(new KeyValuePair<string, string>("extra", "Value")));
+ Assert.IsTrue(target.Contains(new KeyValuePair<string, string>("extra", "value")));
+ Assert.IsFalse(target.Contains(new KeyValuePair<string, string>("wayoff", "value")));
+ }
+
+ /// <summary>
+ /// A test for System.Collections.Generic.ICollection&lt;System.Collections.Generic.KeyValuePair&lt;System.String,System.String&lt;&lt;.Clear
+ /// </summary>
+ [TestMethod]
+ public void Clear() {
+ ICollection<KeyValuePair<string, string>> target = new MessageDictionary(this.message);
+ IDictionary<string, string> targetAsDictionary = ((IDictionary<string, string>)target);
+ this.message.Name = "Andrew";
+ this.message.Age = 15;
+ targetAsDictionary["extra"] = "value";
+ target.Clear();
+ Assert.AreEqual(2, target.Count, "Clearing should remove all keys except for declared non-nullable structs.");
+ Assert.IsFalse(targetAsDictionary.ContainsKey("extra"));
+ Assert.IsNull(this.message.Name);
+ Assert.AreEqual(0, this.message.Age);
+ }
+ }
+}
diff --git a/src/DotNetOAuth.Test/Messaging/Reflection/MessagePartTests.cs b/src/DotNetOAuth.Test/Messaging/Reflection/MessagePartTests.cs
new file mode 100644
index 0000000..b6c3b9d
--- /dev/null
+++ b/src/DotNetOAuth.Test/Messaging/Reflection/MessagePartTests.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using DotNetOAuth.Messaging.Reflection;
+using System.Reflection;
+using DotNetOAuth.Test.Mocks;
+
+namespace DotNetOAuth.Test.Messaging.Reflection {
+ [TestClass]
+ public class MessagePartTests :MessagingTestBase {
+ class MessageWithNonNullableOptionalStruct : TestMessage {
+ /// <summary>
+ /// Optional structs like int must be nullable for Optional to make sense.
+ /// </summary>
+ [MessagePart(IsRequired = false)]
+ internal int optionalInt = 0;
+ }
+ class MessageWithNonNullableRequiredStruct : TestMessage {
+ /// <summary>
+ /// This should work because a required field will always have a value so it
+ /// need not be nullable.
+ /// </summary>
+ [MessagePart(IsRequired = true)]
+ internal int optionalInt = 0;
+ }
+ class MessageWithNullableOptionalStruct : TestMessage {
+ /// <summary>
+ /// Optional structs like int must be nullable for Optional to make sense.
+ /// </summary>
+ [MessagePart(IsRequired = false)]
+ internal int? optionalInt = 0;
+ }
+ class MessageWithNullableRequiredStruct : TestMessage {
+ [MessagePart(IsRequired = true)]
+ internal int? optionalInt;
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void OptionalNonNullableStruct() {
+ ParameterizedMessageTypeTest(typeof(MessageWithNonNullableOptionalStruct));
+ }
+
+ [TestMethod]
+ public void RequiredNonNullableStruct() {
+ ParameterizedMessageTypeTest(typeof(MessageWithNonNullableRequiredStruct));
+ }
+
+ [TestMethod]
+ public void OptionalNullableStruct() {
+ ParameterizedMessageTypeTest(typeof(MessageWithNullableOptionalStruct));
+ }
+
+ [TestMethod]
+ public void RequiredNullableStruct() {
+ ParameterizedMessageTypeTest(typeof(MessageWithNullableRequiredStruct));
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNullMember() {
+ new MessagePart(null, new MessagePartAttribute());
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNullAttribute() {
+ FieldInfo field = typeof(MessageWithNullableOptionalStruct).GetField("optionalInt", BindingFlags.NonPublic | BindingFlags.Instance);
+ new MessagePart(field, null);
+ }
+
+ [TestMethod]
+ public void SetValue() {
+ var message = new MessageWithNonNullableRequiredStruct();
+ MessagePart part = ParameterizedMessageTypeTest(message.GetType());
+ part.SetValue(message, "5");
+ Assert.AreEqual(5, message.optionalInt);
+ }
+
+ [TestMethod]
+ public void GetValue() {
+ var message = new MessageWithNonNullableRequiredStruct();
+ message.optionalInt = 8;
+ MessagePart part = ParameterizedMessageTypeTest(message.GetType());
+ Assert.AreEqual("8", part.GetValue(message));
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void NonFieldOrPropertyMember() {
+ MemberInfo method = typeof(MessageWithNullableOptionalStruct).GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance);
+ new MessagePart(method, new MessagePartAttribute());
+ }
+
+ private MessagePart ParameterizedMessageTypeTest(Type messageType) {
+ FieldInfo field = messageType.GetField("optionalInt", BindingFlags.NonPublic | BindingFlags.Instance);
+ MessagePartAttribute attribute = field.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType<MessagePartAttribute>().Single();
+ return new MessagePart(field, attribute);
+ }
+ }
+}
diff --git a/src/DotNetOAuth.Test/Messaging/Reflection/ValueMappingTests.cs b/src/DotNetOAuth.Test/Messaging/Reflection/ValueMappingTests.cs
new file mode 100644
index 0000000..9142a0c
--- /dev/null
+++ b/src/DotNetOAuth.Test/Messaging/Reflection/ValueMappingTests.cs
@@ -0,0 +1,21 @@
+namespace DotNetOAuth.Test.Messaging.Reflection {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using DotNetOAuth.Messaging.Reflection;
+
+ [TestClass]
+ public class ValueMappingTests {
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNullToString() {
+ new ValueMapping(null, str => new object());
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNullToObject() {
+ new ValueMapping(obj => obj.ToString(), null);
+ }
+ }
+}
diff --git a/src/DotNetOAuth.Test/Mocks/TestBaseMessage.cs b/src/DotNetOAuth.Test/Mocks/TestBaseMessage.cs
index 29e2809..2a8cb30 100644
--- a/src/DotNetOAuth.Test/Mocks/TestBaseMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestBaseMessage.cs
@@ -6,8 +6,10 @@
namespace DotNetOAuth.Test.Mocks {
using System;
+ using System.Collections.Generic;
using System.Runtime.Serialization;
using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Reflection;
internal interface IBaseMessageExplicitMembers {
string ExplicitProperty { get; set; }
@@ -15,13 +17,15 @@ namespace DotNetOAuth.Test.Mocks {
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
internal class TestBaseMessage : IProtocolMessage, IBaseMessageExplicitMembers {
- [DataMember(Name = "age", IsRequired = true)]
+ private Dictionary<string, string> extraData = new Dictionary<string, string>();
+
+ [MessagePart(Name = "age", IsRequired = true)]
public int Age { get; set; }
- [DataMember]
+ [MessagePart]
public string Name { get; set; }
- [DataMember(Name = "explicit")]
+ [MessagePart(Name = "explicit")]
string IBaseMessageExplicitMembers.ExplicitProperty { get; set; }
Version IProtocolMessage.ProtocolVersion {
@@ -36,12 +40,16 @@ namespace DotNetOAuth.Test.Mocks {
get { return MessageTransport.Indirect; }
}
+ IDictionary<string, string> IProtocolMessage.ExtraData {
+ get { return this.extraData; }
+ }
+
internal string PrivatePropertyAccessor {
get { return this.PrivateProperty; }
set { this.PrivateProperty = value; }
}
- [DataMember(Name = "private")]
+ [MessagePart(Name = "private")]
private string PrivateProperty { get; set; }
void IProtocolMessage.EnsureValidMessage() { }
diff --git a/src/DotNetOAuth.Test/Mocks/TestDerivedMessage.cs b/src/DotNetOAuth.Test/Mocks/TestDerivedMessage.cs
index afd67f6..69e58aa 100644
--- a/src/DotNetOAuth.Test/Mocks/TestDerivedMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestDerivedMessage.cs
@@ -6,6 +6,7 @@
namespace DotNetOAuth.Test.Mocks {
using System.Runtime.Serialization;
+ using DotNetOAuth.Messaging.Reflection;
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
internal class TestDerivedMessage : TestBaseMessage {
@@ -17,7 +18,7 @@ namespace DotNetOAuth.Test.Mocks {
/// due to alphabetical ordering rules, but after all the elements in the
/// base class due to inheritance rules.
/// </remarks>
- [DataMember]
+ [MessagePart]
public string TheFirstDerivedElement { get; set; }
/// <summary>
@@ -27,7 +28,7 @@ namespace DotNetOAuth.Test.Mocks {
/// This element should appear BEFORE <see cref="TheFirstDerivedElement"/>,
/// but after all the elements in the base class.
/// </remarks>
- [DataMember]
+ [MessagePart]
public string SecondDerivedElement { get; set; }
}
}
diff --git a/src/DotNetOAuth.Test/Mocks/TestDirectedMessage.cs b/src/DotNetOAuth.Test/Mocks/TestDirectedMessage.cs
index 7add28b..17317f5 100644
--- a/src/DotNetOAuth.Test/Mocks/TestDirectedMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestDirectedMessage.cs
@@ -6,25 +6,18 @@
namespace DotNetOAuth.Test.Mocks {
using System;
+ using System.Collections.Generic;
using System.Runtime.Serialization;
using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Reflection;
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
- internal class TestDirectedMessage : IDirectedProtocolMessage {
- private MessageTransport transport;
-
- internal TestDirectedMessage(MessageTransport transport) {
- this.transport = transport;
+ internal class TestDirectedMessage : TestMessage, IDirectedProtocolMessage {
+ internal TestDirectedMessage() {
}
- [DataMember(Name = "age", IsRequired = true)]
- public int Age { get; set; }
- [DataMember]
- public string Name { get; set; }
- [DataMember]
- public string EmptyMember { get; set; }
- [DataMember]
- public Uri Location { get; set; }
+ internal TestDirectedMessage(MessageTransport transport) : base(transport) {
+ }
#region IDirectedProtocolMessage Members
@@ -34,32 +27,14 @@ namespace DotNetOAuth.Test.Mocks {
#region IProtocolMessage Properties
- Version IProtocolMessage.ProtocolVersion {
- get { return new Version(1, 0); }
- }
-
MessageProtection IProtocolMessage.RequiredProtection {
get { return this.RequiredProtection; }
}
- MessageTransport IProtocolMessage.Transport {
- get { return this.transport; }
- }
-
#endregion
protected virtual MessageProtection RequiredProtection {
get { return MessageProtection.None; }
}
-
- #region IProtocolMessage Methods
-
- void IProtocolMessage.EnsureValidMessage() {
- if (this.EmptyMember != null || this.Age < 0) {
- throw new ProtocolException();
- }
- }
-
- #endregion
}
}
diff --git a/src/DotNetOAuth.Test/Mocks/TestExpiringMessage.cs b/src/DotNetOAuth.Test/Mocks/TestExpiringMessage.cs
index d51e8ee..1b06969 100644
--- a/src/DotNetOAuth.Test/Mocks/TestExpiringMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestExpiringMessage.cs
@@ -10,19 +10,22 @@ namespace DotNetOAuth.Test.Mocks {
using System.Runtime.Serialization;
using DotNetOAuth.Messaging;
using DotNetOAuth.Messaging.Bindings;
+ using DotNetOAuth.Messaging.Reflection;
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
internal class TestExpiringMessage : TestSignedDirectedMessage, IExpiringProtocolMessage {
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private DateTime utcCreationDate;
+ internal TestExpiringMessage() { }
+
internal TestExpiringMessage(MessageTransport transport)
: base(transport) {
}
#region IExpiringProtocolMessage Members
- [DataMember(Name = "created_on")]
+ [MessagePart(Name = "created_on", IsRequired = true)]
DateTime IExpiringProtocolMessage.UtcCreationDate {
get { return this.utcCreationDate; }
set { this.utcCreationDate = value.ToUniversalTime(); }
diff --git a/src/DotNetOAuth.Test/Mocks/TestMessage.cs b/src/DotNetOAuth.Test/Mocks/TestMessage.cs
index e67b582..aede676 100644
--- a/src/DotNetOAuth.Test/Mocks/TestMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestMessage.cs
@@ -6,29 +6,33 @@
namespace DotNetOAuth.Test.Mocks {
using System;
+ using System.Collections.Generic;
using System.Runtime.Serialization;
using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Reflection;
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
internal class TestMessage : IProtocolMessage {
private MessageTransport transport;
+ private Dictionary<string, string> extraData = new Dictionary<string, string>();
- internal TestMessage() : this(MessageTransport.Direct) {
+ internal TestMessage()
+ : this(MessageTransport.Direct) {
}
internal TestMessage(MessageTransport transport) {
this.transport = transport;
}
- [DataMember(Name = "age", IsRequired = true)]
+ [MessagePart(Name = "age", IsRequired = true)]
public int Age { get; set; }
- [DataMember]
+ [MessagePart("Name")]
public string Name { get; set; }
- [DataMember]
+ [MessagePart]
public string EmptyMember { get; set; }
- [DataMember]
+ [MessagePart(Name = null)] // null name tests that Location is still the name.
public Uri Location { get; set; }
- [DataMember]
+ [MessagePart(IsRequired = true)]
public DateTime Timestamp { get; set; }
#region IProtocolMessage Members
@@ -45,6 +49,10 @@ namespace DotNetOAuth.Test.Mocks {
get { return this.transport; }
}
+ IDictionary<string, string> IProtocolMessage.ExtraData {
+ get { return this.extraData; }
+ }
+
void IProtocolMessage.EnsureValidMessage() {
if (this.EmptyMember != null || this.Age < 0) {
throw new ProtocolException();
diff --git a/src/DotNetOAuth.Test/Mocks/TestReplayProtectedMessage.cs b/src/DotNetOAuth.Test/Mocks/TestReplayProtectedMessage.cs
index b62957b..f6c3b39 100644
--- a/src/DotNetOAuth.Test/Mocks/TestReplayProtectedMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestReplayProtectedMessage.cs
@@ -8,16 +8,19 @@ namespace DotNetOAuth.Test.Mocks {
using System.Runtime.Serialization;
using DotNetOAuth.Messaging;
using DotNetOAuth.Messaging.Bindings;
+ using DotNetOAuth.Messaging.Reflection;
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
internal class TestReplayProtectedMessage : TestExpiringMessage, IReplayProtectedProtocolMessage {
+ internal TestReplayProtectedMessage() { }
+
internal TestReplayProtectedMessage(MessageTransport transport)
: base(transport) {
}
#region IReplayProtectedProtocolMessage Members
- [DataMember(Name = "Nonce")]
+ [MessagePart(Name = "Nonce")]
string IReplayProtectedProtocolMessage.Nonce {
get;
set;
diff --git a/src/DotNetOAuth.Test/Mocks/TestSignedDirectedMessage.cs b/src/DotNetOAuth.Test/Mocks/TestSignedDirectedMessage.cs
index d4d2536..bda4255 100644
--- a/src/DotNetOAuth.Test/Mocks/TestSignedDirectedMessage.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestSignedDirectedMessage.cs
@@ -7,17 +7,20 @@
namespace DotNetOAuth.Test.Mocks {
using System.Runtime.Serialization;
using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Reflection;
using DotNetOAuth.Messaging.Bindings;
[DataContract(Namespace = Protocol.DataContractNamespaceV10)]
internal class TestSignedDirectedMessage : TestDirectedMessage, ITamperResistantProtocolMessage {
+ internal TestSignedDirectedMessage() { }
+
internal TestSignedDirectedMessage(MessageTransport transport)
: base(transport) {
}
#region ISignedProtocolMessage Members
- [DataMember]
+ [MessagePart]
public string Signature {
get;
set;
diff --git a/src/DotNetOAuth.Test/OAuthChannelTests.cs b/src/DotNetOAuth.Test/OAuthChannelTests.cs
index 2d00800..8b7b24b 100644
--- a/src/DotNetOAuth.Test/OAuthChannelTests.cs
+++ b/src/DotNetOAuth.Test/OAuthChannelTests.cs
@@ -15,6 +15,7 @@ namespace DotNetOAuth.Test {
using DotNetOAuth.Messaging;
using DotNetOAuth.Test.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using System.Xml;
[TestClass]
public class OAuthChannelTests : TestBase {
@@ -85,6 +86,7 @@ namespace DotNetOAuth.Test {
{ "age", "15" },
{ "Name", "Andrew" },
{ "Location", "http://hostb/pathB" },
+ { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) },
};
MemoryStream ms = new MemoryStream();
@@ -208,6 +210,7 @@ namespace DotNetOAuth.Test {
Name = "Andrew",
Location = new Uri("http://hostb/pathB"),
Recipient = new Uri("http://localtest"),
+ Timestamp = DateTime.UtcNow,
};
Response rawResponse = null;
@@ -216,14 +219,17 @@ namespace DotNetOAuth.Test {
HttpRequestInfo reqInfo = ConvertToRequestInfo(req, this.webRequestHandler.RequestEntityStream);
Assert.AreEqual(scheme == MessageScheme.PostRequest ? "POST" : "GET", reqInfo.HttpMethod);
var incomingMessage = this.channel.ReadFromRequest(reqInfo) as TestMessage;
+ Assert.IsNotNull(incomingMessage);
Assert.AreEqual(request.Age, incomingMessage.Age);
Assert.AreEqual(request.Name, incomingMessage.Name);
Assert.AreEqual(request.Location, incomingMessage.Location);
+ Assert.AreEqual(request.Timestamp, incomingMessage.Timestamp);
var responseFields = new Dictionary<string, string> {
{ "age", request.Age.ToString() },
{ "Name", request.Name },
{ "Location", request.Location.AbsoluteUri },
+ { "Timestamp", XmlConvert.ToString(request.Timestamp, XmlDateTimeSerializationMode.Utc) },
};
rawResponse = new Response {
Body = MessagingUtilities.CreateQueryString(responseFields),
@@ -246,6 +252,7 @@ namespace DotNetOAuth.Test {
{ "age", "15" },
{ "Name", "Andrew" },
{ "Location", "http://hostb/pathB" },
+ { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) },
};
IProtocolMessage requestMessage = this.channel.ReadFromRequest(CreateHttpRequestInfo(scheme, fields));
Assert.IsNotNull(requestMessage);