2007-12-18 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System.Security / Test / System.Security.Cryptography.Xml / XmlDsigC14NWithCommentsTransformTest.cs
1 //
2 // XmlDsigC14NWithCommentsTransformTest.cs 
3 //      - NUnit Test Cases for XmlDsigC14NWithCommentsTransform
4 //
5 // Author:
6 //      Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)\r
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)\r
10 //
11
12 using System;
13 using System.IO;\r
14 using System.Security;\r
15 using System.Security.Cryptography.Xml;
16 using System.Text;
17 using System.Xml;
18
19 using NUnit.Framework;
20
21 namespace MonoTests.System.Security.Cryptography.Xml {
22
23         // Note: GetInnerXml is protected in XmlDsigC14NWithCommentsTransform
24         // making it difficult to test properly. This class "open it up" :-)
25         public class UnprotectedXmlDsigC14NWithCommentsTransform : XmlDsigC14NWithCommentsTransform {
26
27                 public XmlNodeList UnprotectedGetInnerXml () {
28                         return base.GetInnerXml ();
29                 }
30         }
31
32         [TestFixture]
33         public class XmlDsigC14NWithCommentsTransformTest : Assertion {
34
35                 protected UnprotectedXmlDsigC14NWithCommentsTransform transform;
36
37                 [SetUp]
38                 protected void SetUp () 
39                 {
40                         transform = new UnprotectedXmlDsigC14NWithCommentsTransform ();
41                 }
42
43                 [TearDown]
44                 protected void CleanUp () 
45                 {
46                         try {
47                                 if (File.Exists ("doc.dtd"))
48                                         File.Delete ("doc.dtd");
49                                 if (File.Exists ("world.txt"))
50                                         File.Delete ("world.txt");
51                         }
52                         catch {}
53                         if (File.Exists ("doc.dtd"))
54                                 throw new Exception ("File.Delete() is not working.");
55                         if (File.Exists ("world.txt"))
56                                 throw new Exception ("File.Delete() is not working.");
57                 }
58
59                 [Test]
60                 public void Properties () 
61                 {
62                         AssertEquals ("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments", transform.Algorithm);
63
64                         Type[] input = transform.InputTypes;
65                         Assert ("Input #", (input.Length == 3));
66                         // check presence of every supported input types
67                         bool istream = false;
68                         bool ixmldoc = false;
69                         bool ixmlnl = false;
70                         foreach (Type t in input) {
71                                 if (t.ToString () == "System.IO.Stream")
72                                         istream = true;
73                                 if (t.ToString () == "System.Xml.XmlDocument")
74                                         ixmldoc = true;
75                                 if (t.ToString () == "System.Xml.XmlNodeList")
76                                         ixmlnl = true;
77                         }
78                         Assert ("Input Stream", istream);
79                         Assert ("Input XmlDocument", ixmldoc);
80                         Assert ("Input XmlNodeList", ixmlnl);
81
82                         Type[] output = transform.OutputTypes;
83                         Assert ("Output #", (output.Length == 1));
84                         // check presence of every supported output types
85                         bool ostream = false;
86                         foreach (Type t in output) {
87                                 if (t.ToString () == "System.IO.Stream")
88                                         ostream = true;
89                         }
90                         Assert ("Output Stream", ostream);
91                 }
92
93                 [Test]
94                 public void GetInnerXml () 
95                 {
96                         XmlNodeList xnl = transform.UnprotectedGetInnerXml ();
97                         AssertEquals ("Default InnerXml", null, xnl);
98                 }
99
100 #if NET_2_0
101                 [ExpectedException (typeof (ArgumentException))]
102 #else
103                 // LAMESPEC: input MUST be one of InputType - but no exception is thrown (not documented)
104 #endif
105                 public void LoadInputWithUnsupportedType () 
106                 {
107                         byte[] bad = { 0xBA, 0xD };
108                         // LAMESPEC: input MUST be one of InputType - but no exception is thrown (not documented)
109                         transform.LoadInput (bad);
110                 }
111
112                 [Test]
113                 [ExpectedException (typeof (ArgumentException))]
114                 public void UnsupportedOutput () 
115                 {
116                         XmlDocument doc = new XmlDocument();
117                         object o = transform.GetOutput (doc.GetType ());
118                 }
119
120                 [Test]
121                 public void C14NSpecExample1 ()
122                 {
123                         using (StreamWriter sw = new StreamWriter ("doc.dtd", false, Encoding.ASCII)) {
124                                 sw.Write ("<!-- presence, not content, required -->");
125                                 sw.Close ();
126                         }
127                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample1Input, true);
128                         AssertEquals ("Example 1 from c14n spec - PIs, Comments, and Outside of Document Element (with comments)", 
129                                         C14NSpecExample1Output, res);
130                 }\r
131 \r
132                 [Test]\r
133 #if NET_2_0\r
134                 [ExpectedException (typeof (SecurityException))]\r
135 #endif\r
136                 public void C14NSpecExample1_WithoutResolver ()\r
137                 {\r
138                         using (StreamWriter sw = new StreamWriter ("doc.dtd", false, Encoding.ASCII)) {\r
139                                 sw.Write ("<!-- presence, not content, required -->");\r
140                                 sw.Close ();\r
141                         }\r
142 #if NET_2_0\r
143                         if (!SecurityManager.SecurityEnabled)\r
144                                 NUnit.Framework.Assert.Ignore ("SecurityManager isn't enabled.");\r
145 #endif\r
146                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample1Input, false);\r
147                         AssertEquals ("Example 1 from c14n spec - PIs, Comments, and Outside of Document Element (with comments)",\r
148                                         C14NSpecExample1Output, res);\r
149                 }
150
151                 [Test]
152                 public void C14NSpecExample2 ()
153                 {
154                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample2Input, false);
155                         AssertEquals ("Example 2 from c14n spec - Whitespace in Document Content (with comments)", 
156                                         C14NSpecExample2Output, res);
157                 }
158
159                 [Test]
160                 public void C14NSpecExample3 ()
161                 {
162                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample3Input, false);
163                         AssertEquals ("Example 3 from c14n spec - Start and End Tags (with comments)", 
164                                         C14NSpecExample3Output, res);
165                 }
166             
167                 [Test]
168                 public void C14NSpecExample4 ()
169                 {
170                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample4Input, false);
171                         AssertEquals ("Example 4 from c14n spec - Character Modifications and Character References (with comments)", 
172                                         C14NSpecExample4Output, res);
173                 }
174             
175                 [Test]
176                 public void C14NSpecExample5 ()
177                 {
178                         if (!File.Exists ("world.txt")) {
179                                 using (StreamWriter sw = new StreamWriter ("world.txt", false, Encoding.ASCII)) {
180                                         sw.Write ("world");
181                                         sw.Close ();
182                                 }
183                         }
184                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample5Input, false);
185                         AssertEquals ("Example 5 from c14n spec - Entity References (with comments)", 
186                                         C14NSpecExample5Output, res);
187                 }
188     
189                 [Test]
190                 public void C14NSpecExample6 ()
191                 {
192                         string res = ExecuteXmlDSigC14NTransform (C14NSpecExample6Input, false);
193                         AssertEquals ("Example 6 from c14n spec - UTF-8 Encoding (with comments)", 
194                                         C14NSpecExample6Output, res);
195                 }
196
197                 private string ExecuteXmlDSigC14NTransform (string InputXml, bool resolver)
198                 {
199                         XmlDocument doc = new XmlDocument ();
200                         doc.PreserveWhitespace = true;
201                         doc.LoadXml (InputXml);
202                 
203                         // Testing default attribute support with
204                         // vreader.ValidationType = ValidationType.None.
205                         UTF8Encoding utf8 = new UTF8Encoding ();
206                         byte[] data = utf8.GetBytes (InputXml.ToString ());
207                         Stream stream = new MemoryStream (data);
208                         XmlTextReader reader = new XmlTextReader (stream);
209                         XmlValidatingReader vreader = new XmlValidatingReader (reader);
210                         vreader.ValidationType = ValidationType.None;
211                         vreader.EntityHandling = EntityHandling.ExpandCharEntities;
212                         doc.Load (vreader);
213 #if NET_2_0\r
214                         if (resolver)\r
215                                 transform.Resolver = new XmlUrlResolver ();
216 #endif
217                         transform.LoadInput (doc);
218                         return Stream2String ((Stream)transform.GetOutput ());
219                 }
220
221                 private string Stream2String (Stream s) 
222                 {
223                         StringBuilder sb = new StringBuilder ();
224                         int b = s.ReadByte ();
225                         while (b != -1) {
226                                 sb.Append (Convert.ToChar (b));
227                                 b = s.ReadByte ();
228                         }
229                         return sb.ToString ();
230                 }
231
232                 //
233                 // Example 1 from C14N spec - PIs, Comments, and Outside of Document Element: 
234                 // http://www.w3.org/TR/xml-c14n#Example-OutsideDoc
235                 //
236                 static string C14NSpecExample1Input =  
237                         "<?xml version=\"1.0\"?>\n" +
238                         "\n" +
239                             "<?xml-stylesheet   href=\"doc.xsl\"\n" +
240                             "   type=\"text/xsl\"   ?>\n" +
241                             "\n" +
242                             "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n" +
243                             "\n" +
244                             "<doc>Hello, world!<!-- Comment 1 --></doc>\n" +
245                             "\n" +
246                             "<?pi-without-data     ?>\n\n" +
247                             "<!-- Comment 2 -->\n\n" +
248                             "<!-- Comment 3 -->\n";
249                 static string C14NSpecExample1Output =   
250                             "<?xml-stylesheet href=\"doc.xsl\"\n" +
251                             "   type=\"text/xsl\"   ?>\n" +
252                             "<doc>Hello, world!<!-- Comment 1 --></doc>\n" +
253                             "<?pi-without-data?>\n" +
254                             "<!-- Comment 2 -->\n" +
255                             "<!-- Comment 3 -->";
256                 
257                 //
258                 // Example 2 from C14N spec - Whitespace in Document Content: 
259                 // http://www.w3.org/TR/xml-c14n#Example-WhitespaceInContent
260                 // 
261                 static string C14NSpecExample2Input =  
262                             "<doc>\n" +
263                             "  <clean>   </clean>\n" +
264                             "   <dirty>   A   B   </dirty>\n" +
265                             "   <mixed>\n" +
266                             "      A\n" +
267                             "      <clean>   </clean>\n" +
268                             "      B\n" +
269                             "      <dirty>   A   B   </dirty>\n" +
270                             "      C\n" +
271                             "   </mixed>\n" +
272                             "</doc>\n";
273                 static string C14NSpecExample2Output =   
274                             "<doc>\n" +
275                             "  <clean>   </clean>\n" +
276                             "   <dirty>   A   B   </dirty>\n" +
277                             "   <mixed>\n" +
278                             "      A\n" +
279                             "      <clean>   </clean>\n" +
280                             "      B\n" +
281                             "      <dirty>   A   B   </dirty>\n" +
282                             "      C\n" +
283                             "   </mixed>\n" +
284                             "</doc>";
285             
286                 //
287                 // Example 3 from C14N spec - Start and End Tags: 
288                 // http://www.w3.org/TR/xml-c14n#Example-SETags
289                 //
290                 static string C14NSpecExample3Input =  
291                             "<!DOCTYPE doc [<!ATTLIST e9 attr CDATA \"default\">]>\n" +
292                             "<doc>\n" +
293                             "   <e1   />\n" +
294                             "   <e2   ></e2>\n" +
295                             "   <e3    name = \"elem3\"   id=\"elem3\"    />\n" +
296                             "   <e4    name=\"elem4\"   id=\"elem4\"    ></e4>\n" +
297                             "   <e5 a:attr=\"out\" b:attr=\"sorted\" attr2=\"all\" attr=\"I\'m\"\n" +
298                             "       xmlns:b=\"http://www.ietf.org\" \n" +
299                             "       xmlns:a=\"http://www.w3.org\"\n" +
300                             "       xmlns=\"http://www.uvic.ca\"/>\n" +
301                             "   <e6 xmlns=\"\" xmlns:a=\"http://www.w3.org\">\n" +
302                             "       <e7 xmlns=\"http://www.ietf.org\">\n" +
303                             "           <e8 xmlns=\"\" xmlns:a=\"http://www.w3.org\">\n" +
304                             "               <e9 xmlns=\"\" xmlns:a=\"http://www.ietf.org\"/>\n" +
305                             "           </e8>\n" +
306                             "       </e7>\n" +
307                             "   </e6>\n" +
308                             "</doc>\n";
309                 static string C14NSpecExample3Output =   
310                             "<doc>\n" +
311                             "   <e1></e1>\n" +
312                             "   <e2></e2>\n" +
313                             "   <e3 id=\"elem3\" name=\"elem3\"></e3>\n" +
314                             "   <e4 id=\"elem4\" name=\"elem4\"></e4>\n" +
315                             "   <e5 xmlns=\"http://www.uvic.ca\" xmlns:a=\"http://www.w3.org\" xmlns:b=\"http://www.ietf.org\" attr=\"I\'m\" attr2=\"all\" b:attr=\"sorted\" a:attr=\"out\"></e5>\n" +
316                             "   <e6 xmlns:a=\"http://www.w3.org\">\n" +
317                             "       <e7 xmlns=\"http://www.ietf.org\">\n" +
318                             "           <e8 xmlns=\"\">\n" +
319                             "               <e9 xmlns:a=\"http://www.ietf.org\" attr=\"default\"></e9>\n" +
320 //                          "               <e9 xmlns:a=\"http://www.ietf.org\"></e9>\n" +
321                             "           </e8>\n" +
322                             "       </e7>\n" +
323                             "   </e6>\n" +
324                             "</doc>";
325             
326             
327                 //
328                 // Example 4 from C14N spec - Character Modifications and Character References: 
329                 // http://www.w3.org/TR/xml-c14n#Example-Chars
330                 //
331                 // Aleksey: 
332                 // This test does not include "normId" element
333                 // because it has an invalid ID attribute "id" which
334                 // should be normalized by XML parser. Currently Mono
335                 // does not support this (see comment after this example
336                 // in the spec).
337                 static string C14NSpecExample4Input =  
338                             "<!DOCTYPE doc [<!ATTLIST normId id ID #IMPLIED>]>\n" +
339                             "<doc>\n" +
340                             "   <text>First line&#x0d;&#10;Second line</text>\n" +
341                             "   <value>&#x32;</value>\n" +
342                             "   <compute><![CDATA[value>\"0\" && value<\"10\" ?\"valid\":\"error\"]]></compute>\n" +
343                             "   <compute expr=\'value>\"0\" &amp;&amp; value&lt;\"10\" ?\"valid\":\"error\"\'>valid</compute>\n" +
344                             "   <norm attr=\' &apos;   &#x20;&#13;&#xa;&#9;   &apos; \'/>\n" +
345                             // "   <normId id=\' &apos;   &#x20;&#13;&#xa;&#9;   &apos; \'/>\n" +
346                             "</doc>\n";
347                 static string C14NSpecExample4Output =   
348                             "<doc>\n" +
349                             "   <text>First line&#xD;\n" +
350                             "Second line</text>\n" +
351                             "   <value>2</value>\n" +
352                             "   <compute>value&gt;\"0\" &amp;&amp; value&lt;\"10\" ?\"valid\":\"error\"</compute>\n" +
353                             "   <compute expr=\"value>&quot;0&quot; &amp;&amp; value&lt;&quot;10&quot; ?&quot;valid&quot;:&quot;error&quot;\">valid</compute>\n" +
354                             "   <norm attr=\" \'    &#xD;&#xA;&#x9;   \' \"></norm>\n" +
355                             // "   <normId id=\"\' &#xD;&#xA;&#x9; \'\"></normId>\n" +
356                             "</doc>";
357                     
358                 //
359                 // Example 5 from C14N spec - Entity References: 
360                 // http://www.w3.org/TR/xml-c14n#Example-Entities
361                 //
362                 static string C14NSpecExample5Input =  
363                             "<!DOCTYPE doc [\n" +
364                             "<!ATTLIST doc attrExtEnt ENTITY #IMPLIED>\n" +
365                             "<!ENTITY ent1 \"Hello\">\n" +
366                             "<!ENTITY ent2 SYSTEM \"world.txt\">\n" +
367                             "<!ENTITY entExt SYSTEM \"earth.gif\" NDATA gif>\n" +
368                             "<!NOTATION gif SYSTEM \"viewgif.exe\">\n" +
369                             "]>\n" +
370                             "<doc attrExtEnt=\"entExt\">\n" +
371                             "   &ent1;, &ent2;!\n" +
372                             "</doc>\n" +
373                             "\n" +
374                             "<!-- Let world.txt contain \"world\" (excluding the quotes) -->\n";
375                 static string C14NSpecExample5Output =  
376                             "<doc attrExtEnt=\"entExt\">\n" +
377                             "   Hello, world!\n" +
378                             "</doc>\n" + 
379                             "<!-- Let world.txt contain \"world\" (excluding the quotes) -->";
380                         
381                 //
382                 // Example 6 from C14N spec - UTF-8 Encoding: 
383                 // http://www.w3.org/TR/xml-c14n#Example-UTF8
384                 // 
385                 static string C14NSpecExample6Input =  
386                             "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" +
387                             "<doc>&#169;</doc>\n";
388                 static string C14NSpecExample6Output =  
389                             "<doc>\xC2\xA9</doc>";
390             
391
392                 //
393                 // Example 7 from C14N spec - Document Subsets: 
394                 // http://www.w3.org/TR/xml-c14n#Example-DocSubsets
395                 // 
396                 // Aleksey:
397                 // Well, XPath support in Mono is far from complete....
398                 // I was not able to simplify the xpath expression from this test
399                 // so it runs on Mono and still makes sense for testing this feature.
400                 // Thus this test is not included in the suite now.
401                 static string C14NSpecExample7Input =  
402                             "<!DOCTYPE doc [\n" +
403                             "<!ATTLIST e2 xml:space (default|preserve) \'preserve\'>\n" +
404                             "<!ATTLIST e3 id ID #IMPLIED>\n" +
405                             "]>\n" +
406                             "<doc xmlns=\"http://www.ietf.org\" xmlns:w3c=\"http://www.w3.org\">\n" +
407                             "   <e1>\n" +
408                             "      <e2 xmlns=\"\">\n" +
409                             "         <e3 id=\"E3\"/>\n" +
410                             "      </e2>\n" +
411                             "   </e1>\n" +
412                             "</doc>\n";
413
414                 static string C14NSpecExample7Xpath =  
415                             "(//.|//@*|//namespace::*)\n" +
416                             "[\n" +
417                             "self::ietf:e1\n" +
418                             "    or\n" +
419                             "(parent::ietf:e1 and not(self::text() or self::e2))\n" +
420                             "    or\n" +
421                             "count(id(\"E3\")|ancestor-or-self::node()) = count(ancestor-or-self::node())\n" +
422                             "]";
423                 static string C14NSpecExample7Output =  
424                             "<e1 xmlns=\"http://www.ietf.org\" xmlns:w3c=\"http://www.w3.org\"><e3 xmlns=\"\" id=\"E3\" xml:space=\"preserve\"></e3></e1>";   
425         }
426 }