summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs
blob: f44f94a32674b7c570888e4a934c0aaa091bdd61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//-----------------------------------------------------------------------
// <copyright file="MessageSerializerTests.cs" company="Outercurve Foundation">
//     Copyright (c) Outercurve Foundation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

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;

	/// <summary>
	/// Tests for the <see cref="MessageSerializer"/> class.
	/// </summary>
	[TestFixture()]
	public class MessageSerializerTests : MessagingTestBase {
		[TestCase, ExpectedException(typeof(ArgumentNullException))]
		public void SerializeNull() {
			var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
			serializer.Serialize(null);
		}

		[TestCase, ExpectedException(typeof(ArgumentException))]
		public void GetInvalidMessageType() {
			MessageSerializer.Get(typeof(string));
		}

		[TestCase, ExpectedException(typeof(ArgumentNullException))]
		public void GetNullType() {
			MessageSerializer.Get(null);
		}

		[TestCase()]
		public void SerializeTest() {
			var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
			var message = GetStandardTestMessage(FieldFill.CompleteBeforeBindings);
			var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
			IDictionary<string, string> 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"));
		}

		/// <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);
			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-19T08: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);
		}

		[TestCase, ExpectedException(typeof(ArgumentNullException))]
		public void DeserializeNull() {
			var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
			MessageSerializer.Deserialize(null, null);
		}

		[TestCase]
		public void DeserializeSimple() {
			var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
			Dictionary<string, string> fields = new Dictionary<string, string>(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);
		}

		/// <summary>
		/// This tests deserialization of a message that is comprised of [MessagePart]'s
		/// that are defined in multiple places in the inheritance tree.
		/// </summary>
		/// <remarks>
		/// The element sorting rules are first inheritance order, then alphabetical order.
		/// This test validates correct behavior on both.
		/// </remarks>
		[TestCase]
		public void DeserializeVerifyElementOrdering() {
			var serializer = MessageSerializer.Get(typeof(Mocks.TestDerivedMessage));
			Dictionary<string, string> fields = new Dictionary<string, string>(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);
		}

		[TestCase]
		public void DeserializeWithExtraFields() {
			var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage));
			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";
			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);
		}

		[TestCase, 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));
		}
	}
}