2009-09-07 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / Test / System.Web / XmlSiteMapProviderTest.cs
1 //
2 // System.Web.SiteMapProviderTest.cs - Unit tests for System.Web.SiteMapProvider
3 //
4 // Author:
5 //      Marek Habersack <mhabersack@novell.com>
6 //
7 // Copyright (C) 2009 Novell, Inc (http://novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_2_0
30
31 using System;
32 using System.Collections.Generic;
33 using System.Collections.Specialized;
34 using System.Configuration;
35 using System.Configuration.Provider;
36 using System.Diagnostics;
37 using System.Reflection;
38 using System.Text;
39 using System.Web;
40 using System.Web.UI;
41 using System.Web.Hosting;
42 using NUnit.Framework;
43
44 using MonoTests.stand_alone.WebHarness;
45 using MonoTests.SystemWeb.Framework;
46
47 using Tests;
48
49 namespace MonoTests.System.Web
50 {
51         [TestFixture]
52         public class XmlSiteMapProviderTest
53         {
54
55                 [TestFixtureSetUp]
56                 public void SetUp ()
57                 {
58                         Type myType = GetType ();
59 #if VISUAL_STUDIO
60                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_01.sitemap", "test_map_01.sitemap");
61                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_02.sitemap", "test_map_02.sitemap");
62                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_03.sitemap", "test_map_03.sitemap");
63                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_04.sitemap", "test_map_04.sitemap");
64                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_05.sitemap", "test_map_05.sitemap");
65                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_06.sitemap", "test_map_06.sitemap");
66                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_07.sitemap", "test_map_07.sitemap");
67                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_08.sitemap", "test_map_08.sitemap");
68                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.test_map_09.sitemap", "test_map_09.sitemap");
69                         WebTest.CopyResource (myType, "System.Web_test.mainsoft.NunitWeb.NunitWeb.Resources.sub_map_01.sitemap", "sub_map_01.sitemap");
70 #else
71                         WebTest.CopyResource (myType, "test_map_01.sitemap", "test_map_01.sitemap");
72                         WebTest.CopyResource (myType, "test_map_02.sitemap", "test_map_02.sitemap");
73                         WebTest.CopyResource (myType, "test_map_03.sitemap", "test_map_03.sitemap");
74                         WebTest.CopyResource (myType, "test_map_04.sitemap", "test_map_04.sitemap");
75                         WebTest.CopyResource (myType, "test_map_05.sitemap", "test_map_05.sitemap");
76                         WebTest.CopyResource (myType, "test_map_06.sitemap", "test_map_06.sitemap");
77                         WebTest.CopyResource (myType, "test_map_07.sitemap", "test_map_07.sitemap");
78                         WebTest.CopyResource (myType, "test_map_08.sitemap", "test_map_08.sitemap");
79                         WebTest.CopyResource (myType, "test_map_09.sitemap", "test_map_09.sitemap");
80                         WebTest.CopyResource (myType, "sub_map_01.sitemap", "sub_map_01.sitemap");
81 #endif
82                 }
83
84                 [Test]
85                 [ExpectedException (typeof (ArgumentNullException))]
86                 public void AddNode_Null_1 ()
87                 {
88                         var provider = new XmlSiteMapProviderPoker ();
89                         var node = new SiteMapNode (provider, "/test.aspx");
90
91                         provider.DoAddNode (null, node);
92                 }
93
94                 [Test]
95                 [ExpectedException (typeof (ArgumentNullException))]
96                 public void AddNode_Null_2 ()
97                 {
98                         var provider = new XmlSiteMapProviderPoker ();
99                         var node = new SiteMapNode (provider, "/test.aspx");
100
101                         provider.DoAddNode (node, null);
102                 }
103
104                 [Test]
105                 [ExpectedException (typeof (ArgumentException))]
106                 public void AddNode_DifferentProviders_01 ()
107                 {
108                         var provider = new XmlSiteMapProviderPoker ();
109                         var node = new SiteMapNode (new TestSiteMapProvider (), "/test.aspx");
110                         var parentNode = new SiteMapNode (provider, "/test2.aspx");
111
112                         // SiteMapNode  cannot be found in current provider, only nodes in the same provider can be added.
113                         provider.DoAddNode (node, parentNode);
114                 }
115
116                 [Test]
117                 [ExpectedException (typeof (ArgumentException))]
118                 public void AddNode_DifferentProviders_02 ()
119                 {
120                         var provider = new XmlSiteMapProviderPoker ();
121                         var node = new SiteMapNode (provider, "/test.aspx");
122                         var parentNode = new SiteMapNode (new TestSiteMapProvider (), "/test2.aspx");
123
124                         // SiteMapNode  cannot be found in current provider, only nodes in the same provider can be added.
125                         provider.DoAddNode (node, parentNode);
126                 }
127
128                 [Test]
129                 [ExpectedException (typeof (HttpException))]
130                 public void AddNode_01 ()
131                 {
132                         var provider = new XmlSiteMapProviderPoker ();
133                         var node = new SiteMapNode (provider, "/test.aspx");
134                         var parentNode = new SiteMapNode (provider, "/test2.aspx");
135
136                         var nvc = new NameValueCollection ();
137                         nvc.Add ("siteMapFile", "~/test_map_01.sitemap");
138                         provider.Initialize ("TestMap", nvc);
139
140                         // The application relative virtual path '~/test_map_01.sitemap' cannot be made absolute, because the path to the application is not known.
141                         provider.DoAddNode (node, parentNode);
142                 }
143
144                 [Test]
145                 public void AddNode_02 ()
146                 {
147                         new WebTest (PageInvoker.CreateOnLoad (AddNode_02_OnLoad)).Run ();
148                 }
149
150                 public static void AddNode_02_OnLoad (Page p)
151                 {
152                         var provider = new XmlSiteMapProviderPoker ();
153                         provider.CallTrace = null;
154                         var nvc = new NameValueCollection ();
155                         nvc.Add ("siteMapFile", "~/test_map_01.sitemap");
156                         provider.Initialize ("TestMap", nvc);
157
158                         SiteMapNode rootNode = provider.RootNode;
159                         provider.CallTrace = null;
160
161                         var node = new SiteMapNode (provider, "test3.aspx", "~/test3.aspx");
162                         provider.DoAddNode (node, rootNode);
163
164                         Assert.IsNotNull (provider.CallTrace, "#A1");
165                         Assert.Greater (provider.CallTrace.Length, 1, "#A1-1");
166                         Assert.AreEqual (provider.CallTrace[0].Name, "BuildSiteMap", "#A1-2");
167                 }
168
169                 [Test]
170                 public void Initialize_1 ()
171                 {
172                         var provider = new XmlSiteMapProviderPoker ();
173
174                         provider.Initialize ("TestMap", null);
175                         Assert.AreEqual ("TestMap", provider.Name, "#A1");
176                 }
177
178                 [Test]
179                 public void Initialize_2 ()
180                 {
181                         var provider = new XmlSiteMapProviderPoker ();
182
183                         provider.Initialize ("TestMap", new NameValueCollection ());
184                         Assert.AreEqual ("TestMap", provider.Name, "#A1");
185                 }
186
187                 [Test]
188                 public void Initialize_3 ()
189                 {
190                         var provider = new XmlSiteMapProviderPoker ();
191                         var nvc = new NameValueCollection ();
192                         nvc.Add ("siteMapFile", "test.sitemap");
193                         provider.Initialize ("TestMap", nvc);
194                         Assert.AreEqual ("TestMap", provider.Name, "#A1");
195                 }
196
197                 [Test]
198                 public void Initialize_4 ()
199                 {
200                         var provider = new XmlSiteMapProviderPoker ();
201                         var nvc = new NameValueCollection ();
202                         nvc.Add ("siteMapFile", "test.sitemap");
203                         nvc.Add ("description", "Test XML provider");
204                         provider.Initialize ("TestMap", nvc);
205                         Assert.AreEqual ("TestMap", provider.Name, "#A1");
206                         Assert.AreEqual ("Test XML provider", provider.Description, "#A2");
207                 }
208
209                 [Test]
210                 [ExpectedException (typeof (ConfigurationErrorsException))]
211                 public void Initialize_5 ()
212                 {
213                         var provider = new XmlSiteMapProviderPoker ();
214                         var nvc = new NameValueCollection ();
215                         nvc.Add ("siteMapFile", "test.sitemap");
216                         nvc.Add ("description", "Test XML provider");
217
218                         // The attribute 'acme' is unexpected in the configuration of the 'TestMap' provider.
219                         nvc.Add ("acme", "test provider");
220                         provider.Initialize ("TestMap", nvc);
221                 }
222
223                 [Test]
224                 [ExpectedException (typeof (InvalidOperationException))]
225                 public void Initialize_6 ()
226                 {
227                         var provider = new XmlSiteMapProviderPoker ();
228
229                         provider.Initialize ("TestMap", null);
230
231                         // XmlSiteMapProvider cannot be initialized twice
232                         provider.Initialize ("TestMap2", null);
233                 }
234
235                 [Test]
236                 [ExpectedException (typeof (ArgumentException))]
237                 public void RootNode_1 ()
238                 {
239                         var provider = new XmlSiteMapProviderPoker ();
240
241                         // Thrown from internal GetConfigDocument ():
242                         // The siteMapFile attribute must be specified on the XmlSiteMapProvider
243                         provider.Initialize ("TestMap", null);
244                         var rn = provider.RootNode;
245                 }
246
247                 [Test]
248                 public void RootNode_2 ()
249                 {
250                         new WebTest (PageInvoker.CreateOnLoad (RootNode_2_OnLoad)).Run ();
251                 }
252
253                 public static void RootNode_2_OnLoad (Page p)
254                 {
255                         var provider = new XmlSiteMapProviderPoker ();
256                         provider.CallTrace = null;
257                         var nvc = new NameValueCollection ();
258                         nvc.Add ("siteMapFile", "~/test_map_01.sitemap");
259                         provider.CallTrace = null;
260                         provider.Initialize ("TestMap", nvc);
261                         Assert.IsNotNull (provider.RootNode, "#A1");
262                         Assert.AreEqual (provider.RootNode.Provider, provider, "#A2");
263                         Assert.IsNotNull (provider.CallTrace, "#A3");
264                         Assert.Greater (provider.CallTrace.Length, 1, "#A3-1");
265                         Assert.AreEqual (provider.CallTrace[0].Name, "BuildSiteMap", "#A3-2");
266                         Assert.AreEqual (provider.CallTrace[1].Name, "get_RootNode", "#A3-3");
267                 }
268
269                 [Test]
270                 [ExpectedException (typeof (InvalidOperationException))]
271                 public void InvalidFileExtension ()
272                 {
273                         // The file /NunitWeb/test_map_01.extension has an invalid extension, only .sitemap files are allowed in XmlSiteMapProvider.
274                         new WebTest (PageInvoker.CreateOnLoad (InvalidFileExtension_OnLoad)).Run ();
275                 }
276
277                 public static void InvalidFileExtension_OnLoad (Page p)
278                 {
279                         var provider = new XmlSiteMapProviderPoker ();
280                         var nvc = new NameValueCollection ();
281                         nvc.Add ("siteMapFile", "~/test_map_01.extension");
282
283                         provider.Initialize ("TestMap", nvc);
284                         var rn = provider.RootNode;
285                 }
286
287                 [Test]
288                 [ExpectedException (typeof (InvalidOperationException))]
289                 public void MissingMapFile ()
290                 {
291                         new WebTest (PageInvoker.CreateOnLoad (MissingMapFile_OnLoad)).Run ();
292                 }
293
294                 public static void MissingMapFile_OnLoad (Page p)
295                 {
296                         var provider = new XmlSiteMapProviderPoker ();
297                         var nvc = new NameValueCollection ();
298                         nvc.Add ("siteMapFile", "~/missing_map_file.sitemap");
299
300                         provider.Initialize ("TestMap", nvc);
301                         var rn = provider.RootNode;
302                 }
303
304                 [Test]
305                 public void NodeWithSiteMapFile_01 ()
306                 {
307                         var test = new WebTest (PageInvoker.CreateOnLoad (NodeWithSiteMapFile_01_OnLoad)).Run ();
308                 }
309
310                 public static void NodeWithSiteMapFile_01_OnLoad (Page p)
311                 {
312                         var provider = new XmlSiteMapProviderPoker ();
313                         var nvc = new NameValueCollection ();
314                         nvc.Add ("siteMapFile", "~/test_map_02.sitemap");
315
316                         provider.Initialize ("TestMap", nvc);
317                         var rn = provider.RootNode;
318
319                         string expectedTreeString = "UNTITLED_0[0]; Test 1[1]; Sub 1 [/NunitWeb/sub_map_01.sitemap][1]; Sub Sub 1 [/NunitWeb/sub_map_01.sitemap][2]";
320                         string treeString = provider.GetTreeString ();
321
322                         Assert.AreEqual (expectedTreeString, treeString, "#A1");
323                 }
324
325                 [Test]
326                 public void NodeWithProvider_01 ()
327                 {
328                         var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
329                                 NodeWithProvider_OnLoad ("~/test_map_07.sitemap", p);
330                         })).Run ();
331                 }
332
333                 [Test]
334                 [ExpectedException (typeof (ProviderException))]
335                 public void NodeWithProvider_02 ()
336                 {
337                         new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
338                                 NodeWithProvider_OnLoad ("~/test_map_08.sitemap", p);
339                         })).Run ();
340                 }
341
342                 public static void NodeWithProvider_OnLoad (string filePath, Page p)
343                 {
344                         var provider = new XmlSiteMapProviderPoker ();
345                         var nvc = new NameValueCollection ();
346                         nvc.Add ("siteMapFile", filePath);
347
348                         provider.Initialize ("TestMap", nvc);
349                         var rn = provider.RootNode;
350
351                         string expectedTreeString = "UNTITLED_0[0]; Test 1[1]; Test [TestSiteMapProvider][1]";
352                         string treeString = provider.GetTreeString ();
353                         Assert.AreEqual (expectedTreeString, treeString, "#A1");
354
355                         SiteMapNode node = provider.FindSiteMapNode ("default.aspx");
356                         Assert.IsNotNull (node, "#B1");
357                         Assert.AreEqual ("Test", node.Title, "#B1-1");
358                 }
359
360                 [Test]
361                 [ExpectedException (typeof (ConfigurationErrorsException))]
362                 public void InvalidMapFile_01 ()
363                 {
364                         // Top element must be siteMap.
365                         new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
366                                 InvalidMapFile_OnLoad ("~/test_map_03.sitemap", p);
367                         })).Run ();
368                 }
369
370                 [Test]
371                 [ExpectedException (typeof (ConfigurationErrorsException))]
372                 public void InvalidMapFile_02 ()
373                 {
374                         // Only <siteMapNode> elements are allowed at this location.
375                         var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
376                                 InvalidMapFile_OnLoad ("~/test_map_04.sitemap", p);
377                         })).Run ();
378                 }
379
380                 [Test]
381                 [ExpectedException (typeof (ConfigurationErrorsException))]
382                 public void InvalidMapFile_03 ()
383                 {
384                         // Only <siteMapNode> elements are allowed at this location.
385                         var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
386                                 InvalidMapFile_OnLoad ("~/test_map_05.sitemap", p);
387                         })).Run ();
388                 }
389
390                 [Test]
391                 [ExpectedException (typeof (ConfigurationErrorsException))]
392                 public void InvalidMapFile_04 ()
393                 {
394                         // Only <siteMapNode> elements are allowed at this location.
395                         var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
396                                 InvalidMapFile_OnLoad ("~/test_map_06.sitemap", p);
397                         })).Run ();
398                 }
399
400                 public static void InvalidMapFile_OnLoad (string filePath, Page p)
401                 {
402                         var provider = new XmlSiteMapProviderPoker ();
403                         var nvc = new NameValueCollection ();
404                         nvc.Add ("siteMapFile", filePath);
405
406                         provider.Initialize ("TestMap", nvc);
407                         var rn = provider.RootNode;
408                 }
409
410                 [Test]
411                 public void MapFileWithNonStandardAttributes ()
412                 {
413                         // Only <siteMapNode> elements are allowed at this location.
414                         new WebTest (PageInvoker.CreateOnLoad (MapFileWithNonStandardAttributes_OnLoad)).Run ();
415                 }
416
417                 public static void MapFileWithNonStandardAttributes_OnLoad (Page p)
418                 {
419                         var provider = new XmlSiteMapProviderPoker ();
420                         var nvc = new NameValueCollection ();
421                         nvc.Add ("siteMapFile", "~/test_map_09.sitemap");
422
423                         provider.Initialize ("TestMap", nvc);
424                         var rn = provider.RootNode;
425
426                         //TODO: find out what happens to non-standard attributes
427                         //SiteMapNode node = rn.ChildNodes[0];
428                         //Assert.IsNotNull (node, "#A1");
429                         //Assert.AreEqual ("some, keyword, another, one", node["keywords"], "#A1-1");
430
431                         //node = rn.ChildNodes[1];
432                         //Assert.IsNotNull (node, "#B1");
433                         //Assert.AreEqual("value", node["someattribute"], "#B1-1");
434                 }
435         }
436
437         class XmlSiteMapProviderPoker : XmlSiteMapProvider
438         {
439                 public MethodBase[] CallTrace { get; set; }
440
441                 public void DoAddNode (SiteMapNode node, SiteMapNode parentNode)
442                 {
443                         AddNode (node, parentNode);
444                 }
445
446                 public override SiteMapNode BuildSiteMap ()
447                 {
448                         StoreCallTrace ();
449                         return base.BuildSiteMap ();
450                 }
451
452                 public string GetTreeString ()
453                 {
454                         var sb = new StringBuilder ();
455                         int untitled_counter = 0;
456                         BuildTreeString (RootNode, sb, 0, ref untitled_counter);
457                         return sb.ToString ();
458                 }
459
460                 void BuildTreeString (SiteMapNode top, StringBuilder sb, int level, ref int untitled_counter)
461                 {
462                         string title = top.Title;
463
464                         if (String.IsNullOrEmpty (title))
465                                 title = "UNTITLED_" + untitled_counter++;
466
467                         SiteMapProvider provider = top.Provider;
468                         if (provider != this) {
469                                 if (provider == null)
470                                         title += " [NULL_PROVIDER]";
471                                 else {
472                                         string name = provider.Name;
473                                         if (String.IsNullOrEmpty (name))
474                                                 title += " [" + provider.GetType () + "]";
475                                         else
476                                                 title += " [" + name + "]";
477                                 }
478                         }
479
480                         if (sb.Length > 0)
481                                 sb.Append ("; ");
482                         sb.Append (title + "[" + level + "]");
483                         SiteMapNodeCollection childNodes = top.ChildNodes;
484                         if (childNodes != null && childNodes.Count > 0) {
485                                 foreach (SiteMapNode child in childNodes)
486                                         BuildTreeString (child, sb, level + 1, ref untitled_counter);
487                         }
488                 }
489
490                 void StoreCallTrace ()
491                 {
492                         CallTrace = null;
493                         StackFrame[] frames = new StackTrace (1).GetFrames ();
494                         var frameMethods = new List<MethodBase> ();
495
496                         int i = 0;
497                         foreach (StackFrame sf in frames)
498                                 frameMethods.Add (sf.GetMethod ());
499                         CallTrace = frameMethods.ToArray ();
500                 }
501         }
502 }
503 #endif