//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- 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; /// /// Tests for the class. /// [TestFixture] public class MessageSerializerTests : MessagingTestBase { [Test, ExpectedException(typeof(ArgumentNullException))] public void SerializeNull() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); serializer.Serialize(null); } [Test, ExpectedException(typeof(ArgumentException))] public void GetInvalidMessageType() { MessageSerializer.Get(typeof(string)); } [Test, ExpectedException(typeof(ArgumentNullException))] public void GetNullType() { MessageSerializer.Get(null); } [Test] public void SerializeTest() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); var message = GetStandardTestMessage(FieldFill.CompleteBeforeBindings); var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings); IDictionary actual = serializer.Serialize(this.MessageDescriptions.GetAccessor(message)); Assert.AreEqual(4, actual.Count); // Test case sensitivity of generated dictionary Assert.IsFalse(actual.ContainsKey("Age")); Assert.IsTrue(actual.ContainsKey("age")); // Test contents of dictionary 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")); } /// /// Verifies JSON serialization /// [Test] 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); MessageSerializer.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-09T08:00:00Z""}"; Assert.AreEqual(expected, actual); ms.Position = 0; var deserialized = new Mocks.TestDirectedMessage(); var reader = JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max); MessageSerializer.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); } [Test, ExpectedException(typeof(ArgumentNullException))] public void DeserializeNull() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); MessageSerializer.Deserialize(null, null); } [Test] public void DeserializeSimple() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); Dictionary fields = new Dictionary(StringComparer.Ordinal); fields["Name"] = "Andrew"; fields["age"] = "15"; fields["Timestamp"] = "1990-01-01T00:00:00"; var actual = new Mocks.TestDirectedMessage(); serializer.Deserialize(fields, this.MessageDescriptions.GetAccessor(actual)); Assert.AreEqual(15, actual.Age); Assert.AreEqual("Andrew", actual.Name); Assert.AreEqual(DateTime.Parse("1/1/1990"), actual.Timestamp); Assert.IsNull(actual.EmptyMember); } /// /// This tests deserialization of a message that is comprised of [MessagePart]'s /// that are defined in multiple places in the inheritance tree. /// /// /// The element sorting rules are first inheritance order, then alphabetical order. /// This test validates correct behavior on both. /// [Test] public void DeserializeVerifyElementOrdering() { var serializer = MessageSerializer.Get(typeof(Mocks.TestDerivedMessage)); Dictionary fields = new Dictionary(StringComparer.Ordinal); // We deliberately do this OUT of order, // since DataContractSerializer demands elements to be in // 1) inheritance then 2) alphabetical order. // Proper xml element order would be: Name, age, Second..., TheFirst... fields["TheFirstDerivedElement"] = "first"; fields["age"] = "15"; fields["Name"] = "Andrew"; fields["SecondDerivedElement"] = "second"; fields["explicit"] = "explicitValue"; fields["private"] = "privateValue"; var actual = new Mocks.TestDerivedMessage(); serializer.Deserialize(fields, this.MessageDescriptions.GetAccessor(actual)); Assert.AreEqual(15, actual.Age); Assert.AreEqual("Andrew", actual.Name); Assert.AreEqual("first", actual.TheFirstDerivedElement); Assert.AreEqual("second", actual.SecondDerivedElement); Assert.AreEqual("explicitValue", ((Mocks.IBaseMessageExplicitMembers)actual).ExplicitProperty); Assert.AreEqual("privateValue", actual.PrivatePropertyAccessor); } [Test] public void DeserializeWithExtraFields() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); Dictionary fields = new Dictionary(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"; var actual = new Mocks.TestDirectedMessage(); serializer.Deserialize(fields, this.MessageDescriptions.GetAccessor(actual)); Assert.AreEqual(15, actual.Age); Assert.AreEqual("Andrew", actual.Name); Assert.IsNull(actual.EmptyMember); } [Test, ExpectedException(typeof(ProtocolException))] public void DeserializeInvalidMessage() { IProtocolMessage message = new Mocks.TestDirectedMessage(); var serializer = MessageSerializer.Get(message.GetType()); var fields = GetStandardTestFields(FieldFill.AllRequired); fields["age"] = "-1"; // Set an disallowed value. serializer.Deserialize(fields, this.MessageDescriptions.GetAccessor(message)); } } }