From f2b3e8e32b8b9118ba7a19a3d3c878b2af6ee0d5 Mon Sep 17 00:00:00 2001
From: dbuechel <damian.buechel@let.ethz.ch>
Date: Wed, 20 Feb 2019 13:02:12 +0100
Subject: [PATCH] SEBWIN-296: Extended unit tests for XML parser.

---
 .../DataFormats/XmlParserTests.cs             | 67 +++++++++++++++++++
 .../DataFormats/XmlTestData.xml               |  4 +-
 .../DataFormats/XmlParser.cs                  |  1 -
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs b/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs
index 55e78fba..82ff4b35 100644
--- a/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs
+++ b/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs
@@ -41,6 +41,7 @@ namespace SafeExamBrowser.Configuration.UnitTests.DataFormats
 			Assert.IsFalse(sut.CanParse(null));
 			Assert.IsFalse(sut.CanParse(new MemoryStream(Encoding.UTF8.GetBytes("<key>someKey</key><value>1</value>"))));
 			Assert.IsFalse(sut.CanParse(new MemoryStream(Encoding.UTF8.GetBytes("<html></html>"))));
+			Assert.IsFalse(sut.CanParse(new MemoryStream(Encoding.UTF8.GetBytes("<?x"))));
 			Assert.IsTrue(sut.CanParse(new MemoryStream(Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"))));
 		}
 
@@ -59,6 +60,7 @@ namespace SafeExamBrowser.Configuration.UnitTests.DataFormats
 			Assert.AreEqual(9876, result.RawData["someInteger"]);
 			Assert.IsTrue(Convert.FromBase64String("/5vlF76sb+5vgkhjiNTOn7l1SN3Ho2UAMJD3TtLo49M=").SequenceEqual(result.RawData["someData"] as IEnumerable<byte>));
 			Assert.AreEqual(true, result.RawData["someBoolean"]);
+			Assert.AreEqual(false, result.RawData["anotherBoolean"]);
 			Assert.AreEqual(12.34, result.RawData["someReal"]);
 			Assert.AreEqual(new DateTime(2019, 02, 20, 12, 30, 00, 123), result.RawData["someDate"]);
 
@@ -78,6 +80,71 @@ namespace SafeExamBrowser.Configuration.UnitTests.DataFormats
 			Assert.AreEqual(4, (dictThree["dictThreeKeyTwo"] as List<object>)[3]);
 		}
 
+		[TestMethod]
+		public void MustCheckForRootDictionary()
+		{
+			var xml = "<?xml version=\"1.0\"?><plist></plist>";
+			var xml2 = "<?xml version=\"1.0\"?><plist><key>someKey</key><integer>5</integer></plist>";
+			var xml3 = "<?xml version=\"1.0\"?><plist><dictionary></dictionary></plist>";
+			var result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
+
+			Assert.AreEqual(LoadStatus.InvalidData, result.Status);
+
+			result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml2)));
+			Assert.AreEqual(LoadStatus.InvalidData, result.Status);
+
+			result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml3)));
+			Assert.AreEqual(LoadStatus.InvalidData, result.Status);
+		}
+
+		[TestMethod]
+		public void MustParseEmptyXml()
+		{
+			var xml = "<?xml version=\"1.0\"?><plist><dict></dict></plist>";
+			var result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
+
+			Assert.AreEqual(LoadStatus.Success, result.Status);
+			Assert.AreEqual(0, result.RawData.Count);
+		}
+
+		[TestMethod]
+		public void MustDetectInvalidKey()
+		{
+			var xml = "<?xml version=\"1.0\"?><plist><dict><nokey>blubb</nokey><true /></dict></plist>";
+			var result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
+
+			Assert.AreEqual(LoadStatus.InvalidData, result.Status);
+		}
+
+		[TestMethod]
+		public void MustDetectInvalidValueType()
+		{
+			var xml = "<?xml version=\"1.0\"?><plist><dict><key>blubb</key><globb>1234</globb></dict></plist>";
+			var result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
+
+			Assert.AreEqual(LoadStatus.InvalidData, result.Status);
+		}
+
+		[TestMethod]
+		public void MustAllowEmptyArray()
+		{
+			var xml = "<?xml version=\"1.0\"?><plist><dict><key>value</key><array /></dict></plist>";
+			var result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
+
+			Assert.AreEqual(LoadStatus.Success, result.Status);
+			Assert.IsInstanceOfType(result.RawData["value"], typeof(IList<object>));
+		}
+
+		[TestMethod]
+		public void MustAllowEmptyDictionary()
+		{
+			var xml = "<?xml version=\"1.0\"?><plist><dict><key>value</key><dict /></dict></plist>";
+			var result = sut.TryParse(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
+
+			Assert.AreEqual(LoadStatus.Success, result.Status);
+			Assert.IsInstanceOfType(result.RawData["value"], typeof(IDictionary<string, object>));
+		}
+
 		private Stream LoadTestData()
 		{
 			var path = $"{nameof(SafeExamBrowser)}.{nameof(Configuration)}.{nameof(UnitTests)}.{nameof(DataFormats)}.XmlTestData.xml";
diff --git a/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlTestData.xml b/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlTestData.xml
index 97098a4d..10dcebae 100644
--- a/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlTestData.xml
+++ b/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlTestData.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" ?>
+<?xml version="1.0" encoding="utf-8"?>
 <plist>
   <dict>
     <key>someString</key>
@@ -35,6 +35,8 @@
     </array>
     <key>someBoolean</key>
     <true />
+    <key>anotherBoolean</key>
+    <false />
     <key>someReal</key>
     <real>12.34</real>
     <key>someDate</key>
diff --git a/SafeExamBrowser.Configuration/DataFormats/XmlParser.cs b/SafeExamBrowser.Configuration/DataFormats/XmlParser.cs
index 96873661..43639898 100644
--- a/SafeExamBrowser.Configuration/DataFormats/XmlParser.cs
+++ b/SafeExamBrowser.Configuration/DataFormats/XmlParser.cs
@@ -176,7 +176,6 @@ namespace SafeExamBrowser.Configuration.DataFormats
 				return LoadStatus.InvalidData;
 			}
 
-			reader.Read();
 			reader.MoveToContent();
 
 			var status = ParseElement(reader, out object value);