2 // System.Web.SiteMapProviderTest.cs - Unit tests for System.Web.SiteMapProvider
5 // Marek Habersack <mhabersack@novell.com>
7 // Copyright (C) 2009 Novell, Inc (http://novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
31 using System.Collections.Generic;
32 using System.Collections.Specialized;
33 using System.Configuration;
34 using System.Configuration.Provider;
35 using System.Diagnostics;
36 using System.Reflection;
40 using System.Web.Hosting;
41 using NUnit.Framework;
43 using MonoTests.stand_alone.WebHarness;
44 using MonoTests.SystemWeb.Framework;
48 namespace MonoTests.System.Web
51 public class XmlSiteMapProviderTest
57 Type myType = GetType ();
58 WebTest.CopyResource (myType, "test_map_01.sitemap", "test_map_01.sitemap");
59 WebTest.CopyResource (myType, "test_map_02.sitemap", "test_map_02.sitemap");
60 WebTest.CopyResource (myType, "test_map_03.sitemap", "test_map_03.sitemap");
61 WebTest.CopyResource (myType, "test_map_04.sitemap", "test_map_04.sitemap");
62 WebTest.CopyResource (myType, "test_map_05.sitemap", "test_map_05.sitemap");
63 WebTest.CopyResource (myType, "test_map_06.sitemap", "test_map_06.sitemap");
64 WebTest.CopyResource (myType, "test_map_07.sitemap", "test_map_07.sitemap");
65 WebTest.CopyResource (myType, "test_map_08.sitemap", "test_map_08.sitemap");
66 WebTest.CopyResource (myType, "test_map_09.sitemap", "test_map_09.sitemap");
67 WebTest.CopyResource (myType, "sub_map_01.sitemap", "sub_map_01.sitemap");
71 [ExpectedException (typeof (ArgumentNullException))]
72 public void AddNode_Null_1 ()
74 var provider = new XmlSiteMapProviderPoker ();
75 var node = new SiteMapNode (provider, "/test.aspx");
77 provider.DoAddNode (null, node);
81 [ExpectedException (typeof (ArgumentNullException))]
82 public void AddNode_Null_2 ()
84 var provider = new XmlSiteMapProviderPoker ();
85 var node = new SiteMapNode (provider, "/test.aspx");
87 provider.DoAddNode (node, null);
91 [ExpectedException (typeof (ArgumentException))]
92 public void AddNode_DifferentProviders_01 ()
94 var provider = new XmlSiteMapProviderPoker ();
95 var node = new SiteMapNode (new TestSiteMapProvider (), "/test.aspx");
96 var parentNode = new SiteMapNode (provider, "/test2.aspx");
98 // SiteMapNode cannot be found in current provider, only nodes in the same provider can be added.
99 provider.DoAddNode (node, parentNode);
103 [ExpectedException (typeof (ArgumentException))]
104 public void AddNode_DifferentProviders_02 ()
106 var provider = new XmlSiteMapProviderPoker ();
107 var node = new SiteMapNode (provider, "/test.aspx");
108 var parentNode = new SiteMapNode (new TestSiteMapProvider (), "/test2.aspx");
110 // SiteMapNode cannot be found in current provider, only nodes in the same provider can be added.
111 provider.DoAddNode (node, parentNode);
115 [ExpectedException (typeof (HttpException))]
116 public void AddNode_01 ()
118 var provider = new XmlSiteMapProviderPoker ();
119 var node = new SiteMapNode (provider, "/test.aspx");
120 var parentNode = new SiteMapNode (provider, "/test2.aspx");
122 var nvc = new NameValueCollection ();
123 nvc.Add ("siteMapFile", "~/test_map_01.sitemap");
124 provider.Initialize ("TestMap", nvc);
126 // The application relative virtual path '~/test_map_01.sitemap' cannot be made absolute, because the path to the application is not known.
127 provider.DoAddNode (node, parentNode);
131 public void AddNode_02 ()
133 new WebTest (PageInvoker.CreateOnLoad (AddNode_02_OnLoad)).Run ();
136 public static void AddNode_02_OnLoad (Page p)
138 var provider = new XmlSiteMapProviderPoker ();
139 provider.CallTrace = null;
140 var nvc = new NameValueCollection ();
141 nvc.Add ("siteMapFile", "~/test_map_01.sitemap");
142 provider.Initialize ("TestMap", nvc);
144 SiteMapNode rootNode = provider.RootNode;
145 provider.CallTrace = null;
147 var node = new SiteMapNode (provider, "test3.aspx", "~/test3.aspx");
148 provider.DoAddNode (node, rootNode);
150 Assert.IsNotNull (provider.CallTrace, "#A1");
151 Assert.Greater (provider.CallTrace.Length, 1, "#A1-1");
152 Assert.AreEqual (provider.CallTrace[0].Name, "BuildSiteMap", "#A1-2");
156 public void Initialize_1 ()
158 var provider = new XmlSiteMapProviderPoker ();
160 provider.Initialize ("TestMap", null);
161 Assert.AreEqual ("TestMap", provider.Name, "#A1");
165 public void Initialize_2 ()
167 var provider = new XmlSiteMapProviderPoker ();
169 provider.Initialize ("TestMap", new NameValueCollection ());
170 Assert.AreEqual ("TestMap", provider.Name, "#A1");
174 public void Initialize_3 ()
176 var provider = new XmlSiteMapProviderPoker ();
177 var nvc = new NameValueCollection ();
178 nvc.Add ("siteMapFile", "test.sitemap");
179 provider.Initialize ("TestMap", nvc);
180 Assert.AreEqual ("TestMap", provider.Name, "#A1");
184 public void Initialize_4 ()
186 var provider = new XmlSiteMapProviderPoker ();
187 var nvc = new NameValueCollection ();
188 nvc.Add ("siteMapFile", "test.sitemap");
189 nvc.Add ("description", "Test XML provider");
190 provider.Initialize ("TestMap", nvc);
191 Assert.AreEqual ("TestMap", provider.Name, "#A1");
192 Assert.AreEqual ("Test XML provider", provider.Description, "#A2");
196 [ExpectedException (typeof (ConfigurationErrorsException))]
197 public void Initialize_5 ()
199 var provider = new XmlSiteMapProviderPoker ();
200 var nvc = new NameValueCollection ();
201 nvc.Add ("siteMapFile", "test.sitemap");
202 nvc.Add ("description", "Test XML provider");
204 // The attribute 'acme' is unexpected in the configuration of the 'TestMap' provider.
205 nvc.Add ("acme", "test provider");
206 provider.Initialize ("TestMap", nvc);
210 [ExpectedException (typeof (InvalidOperationException))]
211 public void Initialize_6 ()
213 var provider = new XmlSiteMapProviderPoker ();
215 provider.Initialize ("TestMap", null);
217 // XmlSiteMapProvider cannot be initialized twice
218 provider.Initialize ("TestMap2", null);
222 [ExpectedException (typeof (ArgumentException))]
223 public void RootNode_1 ()
225 var provider = new XmlSiteMapProviderPoker ();
227 // Thrown from internal GetConfigDocument ():
228 // The siteMapFile attribute must be specified on the XmlSiteMapProvider
229 provider.Initialize ("TestMap", null);
230 var rn = provider.RootNode;
234 public void RootNode_2 ()
236 new WebTest (PageInvoker.CreateOnLoad (RootNode_2_OnLoad)).Run ();
239 public static void RootNode_2_OnLoad (Page p)
241 var provider = new XmlSiteMapProviderPoker ();
242 provider.CallTrace = null;
243 var nvc = new NameValueCollection ();
244 nvc.Add ("siteMapFile", "~/test_map_01.sitemap");
245 provider.CallTrace = null;
246 provider.Initialize ("TestMap", nvc);
247 Assert.IsNotNull (provider.RootNode, "#A1");
248 Assert.AreEqual (provider.RootNode.Provider, provider, "#A2");
249 Assert.IsNotNull (provider.CallTrace, "#A3");
250 Assert.Greater (provider.CallTrace.Length, 1, "#A3-1");
251 Assert.AreEqual ("BuildSiteMap", provider.CallTrace[0].Name, "#A3-2");
252 Assert.AreEqual ("get_RootNode", provider.CallTrace[1].Name, "#A3-3");
256 [ExpectedException (typeof (InvalidOperationException))]
257 public void InvalidFileExtension ()
259 // The file /NunitWeb/test_map_01.extension has an invalid extension, only .sitemap files are allowed in XmlSiteMapProvider.
260 new WebTest (PageInvoker.CreateOnLoad (InvalidFileExtension_OnLoad)).Run ();
263 public static void InvalidFileExtension_OnLoad (Page p)
265 var provider = new XmlSiteMapProviderPoker ();
266 var nvc = new NameValueCollection ();
267 nvc.Add ("siteMapFile", "~/test_map_01.extension");
269 provider.Initialize ("TestMap", nvc);
270 var rn = provider.RootNode;
274 [ExpectedException (typeof (InvalidOperationException))]
275 public void MissingMapFile ()
277 new WebTest (PageInvoker.CreateOnLoad (MissingMapFile_OnLoad)).Run ();
280 public static void MissingMapFile_OnLoad (Page p)
282 var provider = new XmlSiteMapProviderPoker ();
283 var nvc = new NameValueCollection ();
284 nvc.Add ("siteMapFile", "~/missing_map_file.sitemap");
286 provider.Initialize ("TestMap", nvc);
287 var rn = provider.RootNode;
291 public void NodeWithSiteMapFile_01 ()
293 var test = new WebTest (PageInvoker.CreateOnLoad (NodeWithSiteMapFile_01_OnLoad)).Run ();
296 public static void NodeWithSiteMapFile_01_OnLoad (Page p)
298 var provider = new XmlSiteMapProviderPoker ();
299 var nvc = new NameValueCollection ();
300 nvc.Add ("siteMapFile", "~/test_map_02.sitemap");
302 provider.Initialize ("TestMap", nvc);
303 var rn = provider.RootNode;
305 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]";
306 string treeString = provider.GetTreeString ();
308 Assert.AreEqual (expectedTreeString, treeString, "#A1");
312 public void NodeWithProvider_01 ()
314 var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
315 NodeWithProvider_OnLoad ("~/test_map_07.sitemap", p);
320 [ExpectedException (typeof (ProviderException))]
321 public void NodeWithProvider_02 ()
323 new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
324 NodeWithProvider_OnLoad ("~/test_map_08.sitemap", p);
328 public static void NodeWithProvider_OnLoad (string filePath, Page p)
330 var provider = new XmlSiteMapProviderPoker ();
331 var nvc = new NameValueCollection ();
332 nvc.Add ("siteMapFile", filePath);
334 provider.Initialize ("TestMap", nvc);
335 var rn = provider.RootNode;
337 string expectedTreeString = "UNTITLED_0[0]; Test 1[1]; Test [TestSiteMapProvider][1]";
338 string treeString = provider.GetTreeString ();
339 Assert.AreEqual (expectedTreeString, treeString, "#A1");
341 SiteMapNode node = provider.FindSiteMapNode ("default.aspx");
342 Assert.IsNotNull (node, "#B1");
343 Assert.AreEqual ("Test", node.Title, "#B1-1");
347 [ExpectedException (typeof (ConfigurationErrorsException))]
348 public void InvalidMapFile_01 ()
350 // Top element must be siteMap.
351 new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
352 InvalidMapFile_OnLoad ("~/test_map_03.sitemap", p);
357 [ExpectedException (typeof (ConfigurationErrorsException))]
358 public void InvalidMapFile_02 ()
360 // Only <siteMapNode> elements are allowed at this location.
361 var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
362 InvalidMapFile_OnLoad ("~/test_map_04.sitemap", p);
367 [ExpectedException (typeof (ConfigurationErrorsException))]
368 public void InvalidMapFile_03 ()
370 // Only <siteMapNode> elements are allowed at this location.
371 var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
372 InvalidMapFile_OnLoad ("~/test_map_05.sitemap", p);
377 [ExpectedException (typeof (ConfigurationErrorsException))]
378 public void InvalidMapFile_04 ()
380 // Only <siteMapNode> elements are allowed at this location.
381 var test = new WebTest (PageInvoker.CreateOnLoad ((Page p) => {
382 InvalidMapFile_OnLoad ("~/test_map_06.sitemap", p);
386 public static void InvalidMapFile_OnLoad (string filePath, Page p)
388 var provider = new XmlSiteMapProviderPoker ();
389 var nvc = new NameValueCollection ();
390 nvc.Add ("siteMapFile", filePath);
392 provider.Initialize ("TestMap", nvc);
393 var rn = provider.RootNode;
397 public void MapFileWithNonStandardAttributes ()
399 // Only <siteMapNode> elements are allowed at this location.
400 new WebTest (PageInvoker.CreateOnLoad (MapFileWithNonStandardAttributes_OnLoad)).Run ();
403 public static void MapFileWithNonStandardAttributes_OnLoad (Page p)
405 var provider = new XmlSiteMapProviderPoker ();
406 var nvc = new NameValueCollection ();
407 nvc.Add ("siteMapFile", "~/test_map_09.sitemap");
409 provider.Initialize ("TestMap", nvc);
410 var rn = provider.RootNode;
412 //TODO: find out what happens to non-standard attributes
413 //SiteMapNode node = rn.ChildNodes[0];
414 //Assert.IsNotNull (node, "#A1");
415 //Assert.AreEqual ("some, keyword, another, one", node["keywords"], "#A1-1");
417 //node = rn.ChildNodes[1];
418 //Assert.IsNotNull (node, "#B1");
419 //Assert.AreEqual("value", node["someattribute"], "#B1-1");
423 class XmlSiteMapProviderPoker : XmlSiteMapProvider
425 public MethodBase[] CallTrace { get; set; }
427 public void DoAddNode (SiteMapNode node, SiteMapNode parentNode)
429 AddNode (node, parentNode);
432 public override SiteMapNode BuildSiteMap ()
435 return base.BuildSiteMap ();
438 public string GetTreeString ()
440 var sb = new StringBuilder ();
441 int untitled_counter = 0;
442 BuildTreeString (RootNode, sb, 0, ref untitled_counter);
443 return sb.ToString ();
446 void BuildTreeString (SiteMapNode top, StringBuilder sb, int level, ref int untitled_counter)
448 string title = top.Title;
450 if (String.IsNullOrEmpty (title))
451 title = "UNTITLED_" + untitled_counter++;
453 SiteMapProvider provider = top.Provider;
454 if (provider != this) {
455 if (provider == null)
456 title += " [NULL_PROVIDER]";
458 string name = provider.Name;
459 if (String.IsNullOrEmpty (name))
460 title += " [" + provider.GetType () + "]";
462 title += " [" + name + "]";
468 sb.Append (title + "[" + level + "]");
469 SiteMapNodeCollection childNodes = top.ChildNodes;
470 if (childNodes != null && childNodes.Count > 0) {
471 foreach (SiteMapNode child in childNodes)
472 BuildTreeString (child, sb, level + 1, ref untitled_counter);
476 void StoreCallTrace ()
479 StackFrame[] frames = new StackTrace (1).GetFrames ();
480 var frameMethods = new List<MethodBase> ();
483 foreach (StackFrame sf in frames)
484 frameMethods.Add (sf.GetMethod ());
485 CallTrace = frameMethods.ToArray ();