1 // 2 // XmlDsigXPathTransformTest.cs - Test Cases for XmlDsigXPathTransform 3 // 4 // Author: 5 // Sebastien Pouliot <sebastien@ximian.com> 6 // 7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) 8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) 9 // 10 // Licensed to the .NET Foundation under one or more agreements. 11 // See the LICENSE file in the project root for more information. 12 13 using System.IO; 14 using System.Xml; 15 using Xunit; 16 17 namespace System.Security.Cryptography.Xml.Tests 18 { 19 20 // Note: GetInnerXml is protected in XmlDsigXPathTransform making it 21 // difficult to test properly. This class "open it up" :-) 22 public class UnprotectedXmlDsigXPathTransform : XmlDsigXPathTransform 23 { 24 UnprotectedGetInnerXml()25 public XmlNodeList UnprotectedGetInnerXml() 26 { 27 return base.GetInnerXml(); 28 } 29 } 30 31 public class XmlDsigXPathTransformTest 32 { 33 34 protected UnprotectedXmlDsigXPathTransform transform; 35 XmlDsigXPathTransformTest()36 public XmlDsigXPathTransformTest() 37 { 38 transform = new UnprotectedXmlDsigXPathTransform(); 39 } 40 41 [Fact] Properties()42 public void Properties() 43 { 44 Assert.Equal("http://www.w3.org/TR/1999/REC-xpath-19991116", transform.Algorithm); 45 46 Type[] input = transform.InputTypes; 47 Assert.True((input.Length == 3), "Input #"); 48 // check presence of every supported input types 49 bool istream = false; 50 bool ixmldoc = false; 51 bool ixmlnl = false; 52 foreach (Type t in input) 53 { 54 if (t.ToString() == "System.IO.Stream") 55 istream = true; 56 if (t.ToString() == "System.Xml.XmlDocument") 57 ixmldoc = true; 58 if (t.ToString() == "System.Xml.XmlNodeList") 59 ixmlnl = true; 60 } 61 Assert.True(istream, "Input Stream"); 62 Assert.True(ixmldoc, "Input XmlDocument"); 63 Assert.True(ixmlnl, "Input XmlNodeList"); 64 65 Type[] output = transform.OutputTypes; 66 Assert.True((output.Length == 1), "Output #"); 67 // check presence of every supported output types 68 bool oxmlnl = false; 69 foreach (Type t in output) 70 { 71 if (t.ToString() == "System.Xml.XmlNodeList") 72 oxmlnl = true; 73 } 74 Assert.True(oxmlnl, "Output XmlNodeList"); 75 } 76 AreEqual(string msg, XmlNodeList expected, XmlNodeList actual)77 protected void AreEqual(string msg, XmlNodeList expected, XmlNodeList actual) 78 { 79 for (int i = 0; i < expected.Count; i++) 80 { 81 Assert.Equal(expected[i].OuterXml, actual[i].OuterXml); 82 } 83 Assert.Equal(expected.Count, actual.Count); 84 } 85 86 [Fact] GetInnerXml()87 public void GetInnerXml() 88 { 89 XmlNodeList xnl = transform.UnprotectedGetInnerXml(); 90 Assert.Equal(1, xnl.Count); 91 Assert.Equal("<XPath xmlns=\"http://www.w3.org/2000/09/xmldsig#\" />", xnl[0].OuterXml); 92 } 93 94 [Fact] OnlyInner()95 public void OnlyInner() 96 { 97 XmlNodeList inner = InnerXml(""); // empty 98 transform.LoadInnerXml(inner); 99 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 100 Assert.Equal(0, xnl.Count); 101 } 102 GetDoc()103 private XmlDocument GetDoc() 104 { 105 string test = "<catalog><cd><title>Empire Burlesque</title><artist>Bob Dylan</artist><price>10.90</price>"; 106 test += "<year>1985</year></cd><cd><title>Hide your heart</title><artist>Bonnie Tyler</artist><price>9.90</price>"; 107 test += "<year>1988</year></cd><cd><title>Greatest Hits</title><artist>Dolly Parton</artist><price>9.90</price>"; 108 test += "<year>1982</year></cd><cd><title>Still got the blues</title><artist>Gary Moore</artist><price>10.20</price>"; 109 test += "<year>1990</year></cd><cd><title>Eros</title><artist>Eros Ramazzotti</artist><price>9.90</price>"; 110 test += "<year>1997</year></cd></catalog>"; 111 XmlDocument doc = new XmlDocument(); 112 doc.LoadXml(test); 113 return doc; 114 } 115 InnerXml(string xpathExpr)116 private XmlNodeList InnerXml(string xpathExpr) 117 { 118 string xpath = "<XPath xmlns=\"http://www.w3.org/2000/09/xmldsig#\">" + xpathExpr + "</XPath>"; 119 XmlDocument doc = new XmlDocument(); 120 doc.LoadXml(xpath); 121 return doc.ChildNodes; 122 } 123 124 [Fact] LoadInputAsXmlDocument()125 public void LoadInputAsXmlDocument() 126 { 127 XmlDocument doc = GetDoc(); 128 transform.LoadInput(doc); 129 XmlNodeList inner = InnerXml("//*/title"); 130 transform.LoadInnerXml(inner); 131 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 132 Assert.Equal(73, xnl.Count); 133 } 134 135 [Fact] LoadInputAsXmlDocument_EmptyXPath()136 public void LoadInputAsXmlDocument_EmptyXPath() 137 { 138 XmlDocument doc = GetDoc(); 139 transform.LoadInput(doc); 140 // empty means no LoadInnerXml 141 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 142 Assert.Equal(0, xnl.Count); 143 } 144 145 [Fact] LoadInputAsXmlNodeList()146 public void LoadInputAsXmlNodeList() 147 { 148 XmlDocument doc = GetDoc(); 149 transform.LoadInput(doc.ChildNodes); 150 XmlNodeList inner = InnerXml("//*/title"); 151 transform.LoadInnerXml(inner); 152 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 153 Assert.Equal(1, xnl.Count); 154 } 155 156 [Fact] LoadInputAsXmlNodeList_EmptyXPath()157 public void LoadInputAsXmlNodeList_EmptyXPath() 158 { 159 XmlDocument doc = GetDoc(); 160 transform.LoadInput(doc.ChildNodes); 161 // empty means no LoadInnerXml 162 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 163 Assert.Equal(0, xnl.Count); 164 } 165 166 [Fact] LoadInputAsStream()167 public void LoadInputAsStream() 168 { 169 XmlDocument doc = GetDoc(); 170 doc.PreserveWhitespace = true; 171 MemoryStream ms = new MemoryStream(); 172 doc.Save(ms); 173 ms.Position = 0; 174 transform.LoadInput(ms); 175 XmlNodeList inner = InnerXml("//*/title"); 176 transform.LoadInnerXml(inner); 177 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 178 Assert.Equal(73, xnl.Count); 179 } 180 181 [Fact] LoadInputAsStream_EmptyXPath()182 public void LoadInputAsStream_EmptyXPath() 183 { 184 XmlDocument doc = GetDoc(); 185 MemoryStream ms = new MemoryStream(); 186 doc.Save(ms); 187 ms.Position = 0; 188 transform.LoadInput(ms); 189 // empty means no LoadInnerXml 190 XmlNodeList xnl = (XmlNodeList)transform.GetOutput(); 191 Assert.Equal(0, xnl.Count); 192 } 193 194 [Fact] LoadInnerXml()195 public void LoadInnerXml() 196 { 197 XmlNodeList inner = InnerXml("//*"); 198 transform.LoadInnerXml(inner); 199 XmlNodeList xnl = transform.UnprotectedGetInnerXml(); 200 Assert.Equal(inner, xnl); 201 } 202 203 [Fact] UnsupportedInput()204 public void UnsupportedInput() 205 { 206 byte[] bad = { 0xBA, 0xD }; 207 // LAMESPEC: input MUST be one of InputType - but no exception is thrown (not documented) 208 transform.LoadInput(bad); 209 } 210 211 [Fact] UnsupportedOutput()212 public void UnsupportedOutput() 213 { 214 XmlDocument doc = new XmlDocument(); 215 AssertExtensions.Throws<ArgumentException>("type", () => transform.GetOutput(doc.GetType())); 216 } 217 218 [Fact] TransformSimple()219 public void TransformSimple() 220 { 221 XmlDsigXPathTransform t = new XmlDsigXPathTransform(); 222 XmlDocument xpdoc = new XmlDocument(); 223 string ns = "http://www.w3.org/2000/09/xmldsig#"; 224 string xpath = "<XPath xmlns='" + ns + "' xmlns:x='urn:foo'>*|@*|namespace::*</XPath>"; // not absolute path.. so @* and namespace::* does not make sense. 225 xpdoc.LoadXml(xpath); 226 t.LoadInnerXml(xpdoc.ChildNodes); 227 XmlDocument doc = new XmlDocument(); 228 doc.LoadXml("<element xmlns='urn:foo'><foo><bar>test</bar></foo></element>"); 229 t.LoadInput(doc); 230 XmlNodeList nl = (XmlNodeList)t.GetOutput(); 231 Assert.Equal(XmlNodeType.Document, nl[0].NodeType); 232 Assert.Equal(XmlNodeType.Element, nl[1].NodeType); 233 Assert.Equal("element", nl[1].LocalName); 234 Assert.Equal(XmlNodeType.Element, nl[2].NodeType); 235 Assert.Equal("foo", nl[2].LocalName); 236 Assert.Equal(XmlNodeType.Element, nl[3].NodeType); 237 Assert.Equal("bar", nl[3].LocalName); 238 // MS.NET bug - ms.net returns ns node even when the 239 // current node is ns node (it is like returning 240 // attribute from attribute nodes). 241 // Assert.Equal (XmlNodeType.Attribute, nl [4].NodeType); 242 // Assert.Equal ("xmlns", nl [4].LocalName); 243 } 244 245 [Fact] 246 // MS.NET looks incorrect, or something incorrect in this test code; It turned out nothing to do with function here() FunctionHereObsolete()247 public void FunctionHereObsolete() 248 { 249 XmlDsigXPathTransform t = new XmlDsigXPathTransform(); 250 XmlDocument xpdoc = new XmlDocument(); 251 string ns = "http://www.w3.org/2000/09/xmldsig#"; 252 // string xpath = "<XPath xmlns='" + ns + "' xmlns:x='urn:foo'>here()</XPath>"; 253 string xpath = "<XPath xmlns='" + ns + "' xmlns:x='urn:foo'></XPath>"; 254 xpdoc.LoadXml(xpath); 255 t.LoadInnerXml(xpdoc.ChildNodes); 256 XmlDocument doc = new XmlDocument(); 257 258 doc.LoadXml("<element a='b'><foo><bar>test</bar></foo></element>"); 259 t.LoadInput(doc); 260 261 XmlNodeList nl = (XmlNodeList)t.GetOutput(); 262 Assert.Equal(0, nl.Count); 263 264 doc.LoadXml("<element xmlns='urn:foo'><foo><bar>test</bar></foo></element>"); 265 t.LoadInput(doc); 266 nl = (XmlNodeList)t.GetOutput(); 267 Assert.Equal(0, nl.Count); 268 269 doc.LoadXml("<element xmlns='urn:foo'><foo xmlns='urn:bar'><bar>test</bar></foo></element>"); 270 t.LoadInput(doc); 271 nl = (XmlNodeList)t.GetOutput(); 272 Assert.Equal(0, nl.Count); 273 274 doc.LoadXml("<element xmlns='urn:foo' xmlns:x='urn:x'><foo xmlns='urn:bar'><bar>test</bar></foo></element>"); 275 t.LoadInput(doc); 276 nl = (XmlNodeList)t.GetOutput(); 277 Assert.Equal(0, nl.Count); 278 279 doc.LoadXml("<envelope><Signature xmlns='http://www.w3.org/2000/09/xmldsig#'><XPath>blah</XPath></Signature></envelope>"); 280 t.LoadInput(doc); 281 nl = (XmlNodeList)t.GetOutput(); 282 Assert.Equal(0, nl.Count); 283 } 284 } 285 } 286