2009-05-26 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.Web.Routing / Test / System.Web.Routing / RouteCollectionTest.cs
1 //
2 // RouteCollectionTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2008 Novell Inc. http://novell.com
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.Web;
32 using System.Web.Routing;
33 using NUnit.Framework;
34
35 namespace MonoTests.System.Web.Routing
36 {
37         [TestFixture]
38         public class RouteCollectionTest
39         {
40                 [Test]
41                 public void ConstructorNullArgs ()
42                 {
43                         // allowed
44                         new RouteCollection (null);
45                 }
46
47                 [Test]
48                 public void RouteExistingFiles ()
49                 {
50                         var c = new RouteCollection ();
51                         Assert.IsFalse (c.RouteExistingFiles);
52                 }
53
54                 [Test]
55                 public void AddNullMame ()
56                 {
57                         var c = new RouteCollection ();
58                         // when name is null, no duplicate check is done.
59                         c.Add (null, new Route (null, null));
60                         c.Add (null, new Route (null, null));
61                 }
62
63                 [Test]
64                 public void AddDuplicateEmpty ()
65                 {
66                         var c = new RouteCollection ();
67                         // when name is "", no duplicate check is done.
68                         c.Add ("", new Route (null, null));
69                         c.Add ("", new Route (null, null));
70                 }
71
72                 [Test]
73                 [ExpectedException (typeof (ArgumentException))]
74                 public void AddDuplicateName ()
75                 {
76                         var c = new RouteCollection ();
77                         c.Add ("x", new Route (null, null));
78                         c.Add ("x", new Route (null, null));
79                 }
80
81                 [Test]
82                 public void IndexForNonExistent ()
83                 {
84                         Assert.IsNull (new RouteCollection () [null]);
85                 }
86
87                 [Test]
88                 public void IndexForExistent ()
89                 {
90                         var c = new RouteCollection ();
91                         var r = new Route (null, null);
92                         c.Add ("x", r);
93                         Assert.AreEqual (r, c ["x"]);
94                 }
95
96                 [Test]
97                 public void IndexForNonExistentAfterRemoval ()
98                 {
99                         var c = new RouteCollection ();
100                         var r = new Route (null, null);
101                         c.Add ("x", r);
102                         c.Remove (r);
103                         Assert.IsNull(c ["x"]);
104                 }
105
106                 [Test]
107                 [ExpectedException (typeof (ArgumentNullException))]
108                 public void GetRouteDataNullArg ()
109                 {
110                         new RouteCollection ().GetRouteData (null);
111                 }
112
113                 [Test]
114                 public void GetRouteDataForNonExistent ()
115                 {
116                         var rd = new RouteCollection ().GetRouteData (new HttpContextStub ("~/foo"));
117                         Assert.IsNull (rd);
118                 }
119
120                 [Test]
121                 public void GetRouteDataForNonExistent2 ()
122                 {
123                         var rd = new RouteCollection () { RouteExistingFiles = true }.GetRouteData (new HttpContextStub2 (null, null, null));
124                         Assert.IsNull (rd);
125                         try {
126                                 new RouteCollection ().GetRouteData (new HttpContextStub2 (null, null, null));
127                                 Assert.Fail ("#1");
128                         } catch (NotImplementedException) {
129                                 // it should fail due to the NIE on AppRelativeCurrentExecutionFilePath.
130                         }
131                 }
132
133                 [Test]
134                 public void GetRouteDataWrongPathNoRoute ()
135                 {
136                         new RouteCollection ().GetRouteData (new HttpContextStub (String.Empty, String.Empty));
137                 }
138
139                 /*
140                 comment out those tests; I cannot explain those tests.
141
142                 [Test]
143                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
144                 public void GetRouteDataWrongPathOneRoute ()
145                 {
146                         var c = new RouteCollection ();
147                         var r = new Route ("foo", null);
148                         c.Add (null, r);
149                         // it somehow causes ArgumentOutOfRangeException for 
150                         // Request.AppRelativeCurrentExecutionFilePath.
151                         c.GetRouteData (new HttpContextStub (String.Empty, String.Empty));
152                 }
153
154                 [Test]
155                 public void GetRouteDataWrongPathOneRoute2 ()
156                 {
157                         var c = new RouteCollection ();
158                         var r = new Route ("foo", null);
159                         c.Add (null, r);
160                         c.GetRouteData (new HttpContextStub ("/~", String.Empty));
161                 }
162                 */
163
164                 [Test]
165                 [ExpectedException (typeof (NotImplementedException))]
166                 public void GetRouteDataForPathInfoNIE ()
167                 {
168                         var c = new RouteCollection ();
169                         var r = new Route ("foo", null);
170                         c.Add (null, r);
171                         // it retrieves PathInfo and then dies.
172                         var rd = c.GetRouteData (new HttpContextStub ("~/foo"));
173                 }
174
175                 [Test]
176                 public void GetRouteDataForNullHandler ()
177                 {
178                         var c = new RouteCollection ();
179                         var r = new Route ("foo", null); // allowed
180                         c.Add (null, r);
181                         var rd = c.GetRouteData (new HttpContextStub ("~/foo", String.Empty));
182                         Assert.IsNotNull (rd, "#1");
183                         Assert.AreEqual (r, rd.Route, "#2");
184                 }
185
186                 // below tests in RouteCollection, unlike Route, do some additional checks than Route.GetVirtualPath().
187
188                 [Test]
189                 [ExpectedException (typeof (NotImplementedException))]
190                 public void GetVirtualPathNoApplicationPath ()
191                 {
192                         var c = new RouteCollection ();
193                         c.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
194                         var hc = new HttpContextStub2 ("~/x/y", String.Empty);
195                         var rd = c.GetRouteData (hc);
196                         // it tries to get HttpContextBase.Request.ApplicationPath and then throws NIE.
197                         var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
198                 }
199
200                 [Test]
201                 [ExpectedException (typeof (NotImplementedException))]
202                 public void GetVirtualPathNoApplyAppPathModifier ()
203                 {
204                         var c = new RouteCollection ();
205                         c.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
206                         var hc = new HttpContextStub2 ("~/x/y", String.Empty, "apppath");
207                         // it tries to call HttpContextBase.Response.ApplyAppPathModifier() and then causes NIE.
208                         hc.SetResponse (new HttpResponseStub ());
209                         var rd = c.GetRouteData (hc);
210                         var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
211                 }
212
213                 [Test]
214                 public void GetVirtualPathCheckVirtualPathToModify ()
215                 {
216                         var c = new RouteCollection ();
217                         c.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
218                         var hc = new HttpContextStub2 ("~/x/y", String.Empty, "apppath");
219                         // it tries to get HttpContextBase.Response, so set it.
220                         hc.SetResponse (new HttpResponseStub (1));
221                         var rd = c.GetRouteData (hc);
222                         try {
223                                 var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
224                                 Assert.Fail ("#1");
225                         } catch (ApplicationException ex) {
226                                 Assert.AreEqual ("apppath/x/y", ex.Message, "#2");
227                         }
228                 }
229
230                 [Test]
231                 public void GetVirtualPath ()
232                 {
233                         var c = new RouteCollection ();
234                         c.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
235                         var hc = new HttpContextStub2 ("~/x/y", String.Empty, "apppath");
236                         // it tries to get HttpContextBase.Response, so set it.
237                         hc.SetResponse (new HttpResponseStub (2));
238                         var rd = c.GetRouteData (hc);
239                         Assert.IsNotNull (rd, "#1");
240                         
241                         var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
242                         Assert.IsNotNull (vpd, "#2");
243                         Assert.AreEqual ("apppath/x/y_modified", vpd.VirtualPath, "#3");
244                         Assert.AreEqual (0, vpd.DataTokens.Count, "#4");
245                 }
246
247                 [Test (Description = "Bug #502555")]
248                 public void GetVirtualPath2 ()
249                 {
250                         var c = new RouteCollection ();
251                         
252                         c.Add ("Summary",
253                                new MyRoute ("summary/{action}-{type}/{page}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Summary", action = "Index", page = 1}) }
254                         );
255                                
256                         c.Add ("Apis",
257                                new MyRoute ("apis/{apiname}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Apis", action = "Index" }) }
258                         );
259                                                             
260                         c.Add ("Single Report",
261                                new MyRoute ("report/{guid}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Reports", action = "SingleReport" }) }
262                         );
263                         
264                         c.Add ("Reports",
265                                new MyRoute ("reports/{page}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Reports", action = "Index", page = 1 }) }
266                         );
267
268                         c.Add ("Default",
269                                new MyRoute ("{controller}/{action}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Home", action = "Index"}) }
270                         );
271
272                         var hc = new HttpContextStub2 ("~/Home/About", String.Empty, String.Empty);
273                         hc.SetResponse (new HttpResponseStub (2));
274                         var rd = c.GetRouteData (hc);
275                         var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
276                         Assert.IsNotNull (vpd, "#A1");
277                         Assert.AreEqual ("/Home/About_modified", vpd.VirtualPath, "#A2");
278                         Assert.AreEqual (0, vpd.DataTokens.Count, "#A3");
279
280                         hc = new HttpContextStub2 ("~/Home/Index", String.Empty, String.Empty);
281                         hc.SetResponse (new HttpResponseStub (2));
282                         rd = c.GetRouteData (hc);
283                         vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
284                         Assert.IsNotNull (vpd, "#B1");
285                         Assert.AreEqual ("/_modified", vpd.VirtualPath, "#B2");
286                         Assert.AreEqual (0, vpd.DataTokens.Count, "#B3");
287
288                         hc = new HttpContextStub2 ("~/Account/LogOn", String.Empty, String.Empty);
289                         hc.SetResponse (new HttpResponseStub (2));
290                         rd = c.GetRouteData (hc);
291                         vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
292                         Assert.IsNotNull (vpd, "#C1");
293                         Assert.AreEqual ("/Account/LogOn_modified", vpd.VirtualPath, "#C2");
294                         Assert.AreEqual (0, vpd.DataTokens.Count, "#C3");
295                 }
296
297                 [Test]
298                 public void GetVirtualPath3 ()
299                 {
300                         var c = new RouteCollection ();
301
302                         c.Add ("todo-route",
303                                new MyRoute ("todo/{action}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new {controller = "todo", action="list", page=0}) }
304                         );
305
306                         c.Add ("another-route",
307                                new MyRoute ("{controller}/{action}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new {controller = "home", action="list", page=0}) }
308                         );
309
310                         var hc = new HttpContextStub2 ("~/home/list", String.Empty, String.Empty);
311                         hc.SetResponse (new HttpResponseStub (3));
312                         var rd = c.GetRouteData (hc);
313                         Assert.IsNotNull (rd, "#1");
314                         Assert.AreEqual (3, rd.Values.Count, "#1-1");
315                         Assert.AreEqual ("home", rd.Values["controller"], "#1-2");
316                         Assert.AreEqual ("list", rd.Values["action"], "#1-3");
317                         Assert.AreEqual (0, rd.Values["page"], "#1-4");
318                         
319                         var vp = c.GetVirtualPath (new RequestContext (hc, rd), "todo-route", new RouteValueDictionary ());
320                         Assert.IsNotNull (vp, "#2");
321                         Assert.AreEqual ("/todo", vp.VirtualPath, "#2-1");
322
323                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary ());
324                         Assert.IsNotNull (vp, "#3");
325                         Assert.AreEqual ("/todo", vp.VirtualPath, "#3-1");
326
327                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary (new { controller = "home" }));
328                         Assert.IsNotNull (vp, "#4");
329                         Assert.AreEqual ("/", vp.VirtualPath, "#4-1");
330
331                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary (new { controller = "home", extra="stuff" }));
332                         Assert.IsNotNull (vp, "#5");
333                         Assert.AreEqual ("/?extra=stuff", vp.VirtualPath, "#5-1");
334                 }
335
336                 [Test]
337                 public void GetVirtualPath4 ()
338                 {
339                         var c = new RouteCollection ();
340
341                         c.Add (new MyRoute ("blog/{user}/{action}", new MyRouteHandler ()) {
342                                         Defaults = new RouteValueDictionary {
343                                                         { "controller", "blog" },
344                                                         { "user", "admin" }
345                                                 }
346                                 }
347                         );
348
349                         c.Add (new MyRoute ("forum/{user}/{action}", new MyRouteHandler ()) {
350                                         Defaults = new RouteValueDictionary {
351                                                         { "controller", "forum" },
352                                                         { "user", "admin" }
353                                                 }
354                                 }
355                         );
356
357                         var hc = new HttpContextStub2 ("~/forum/admin/Index", String.Empty, String.Empty);
358                         hc.SetResponse (new HttpResponseStub (3));
359                         var rd = c.GetRouteData (hc);
360                         Assert.IsNotNull (rd, "#1");
361
362                         var vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary (new { action="Index", controller="forum"}));
363                         Assert.IsNotNull (vp, "#2");
364                         Assert.AreEqual ("/forum/admin/Index", vp.VirtualPath, "#2-1");
365                         
366                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary (new { action="Index", controller="blah"}));
367                         Assert.IsNull (vp, "#3");
368                 }
369
370                 [Test]
371                 public void GetVirtualPath5 ()
372                 {
373                         var c = new RouteCollection ();
374
375                         c.Add (new MyRoute ("reports/{year}/{month}/{day}", new MyRouteHandler ()) {
376                                         Defaults = new RouteValueDictionary {
377                                                         { "day", 1 }
378                                                 }
379                                 }
380                         );
381
382                         var hc = new HttpContextStub2 ("~/reports/2009/05", String.Empty, String.Empty);
383                         hc.SetResponse (new HttpResponseStub (3));
384                         var rd = c.GetRouteData (hc);
385                         Assert.IsNotNull (rd, "#1");
386
387                         var vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
388                                         { "year", 2007 },
389                                         { "month", 1 },
390                                         { "day", 12 },
391                                 }
392                         );
393                         Assert.IsNotNull (vp, "#2");
394                         Assert.AreEqual ("/reports/2007/1/12", vp.VirtualPath, "#2-1");
395                         
396                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
397                                         { "year", 2007 },
398                                         { "month", 1 }
399                                 }
400                         );
401                         Assert.IsNotNull (vp, "#3");
402                         Assert.AreEqual ("/reports/2007/1", vp.VirtualPath, "#3-1");
403
404                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
405                                         { "year", 2007 },
406                                         { "month", 1 },
407                                         { "day", 12 },
408                                         { "category", 123 }
409                                 }
410                         );
411                         Assert.IsNotNull (vp, "#4");
412                         Assert.AreEqual ("/reports/2007/1/12?category=123", vp.VirtualPath, "#4-1");
413
414                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
415                                         { "year", 2007 },
416                                 }
417                         );
418                         Assert.IsNull (vp, "#5");
419                 }
420
421                 [Test]
422                 public void GetVirtualPath6 ()
423                 {
424                         var c = new RouteCollection ();
425
426                         c.Add (new MyRoute ("reports/{year}/{month}/{day}", new MyRouteHandler ()) {
427                                         Defaults = new RouteValueDictionary {
428                                                         { "day", 1 }
429                                                 }
430                                 }
431                         );
432
433                         var hc = new HttpContextStub2 ("~/reports/2009/05", String.Empty, "/myapp");
434                         hc.SetResponse (new HttpResponseStub (3));
435                         var rd = c.GetRouteData (hc);
436                         Assert.IsNotNull (rd, "#1");
437
438                         var vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
439                                         { "year", 2007 },
440                                         { "month", 1 },
441                                         { "day", 12 },
442                                 }
443                         );
444                         Assert.IsNotNull (vp, "#2");
445                         Assert.AreEqual ("/myapp/reports/2007/1/12", vp.VirtualPath, "#2-1");
446                         
447                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
448                                         { "year", 2007 },
449                                         { "month", 1 }
450                                 }
451                         );
452                         Assert.IsNotNull (vp, "#3");
453                         Assert.AreEqual ("/myapp/reports/2007/1", vp.VirtualPath, "#3-1");
454
455                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
456                                         { "year", 2007 },
457                                         { "month", 1 },
458                                         { "day", 12 },
459                                         { "category", 123 }
460                                 }
461                         );
462                         Assert.IsNotNull (vp, "#4");
463                         Assert.AreEqual ("/myapp/reports/2007/1/12?category=123", vp.VirtualPath, "#4-1");
464                         
465                         vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary {
466                                         { "year", 2007 },
467                                 }
468                         );
469                         Assert.IsNull (vp, "#5");
470                 }
471                 
472                 [Test]
473                 [Ignore ("looks like RouteExistingFiles ( = false) does not affect... so this test needs more investigation")]
474                 public void GetVirtualPathToExistingFile ()
475                 {
476                         var c = new RouteCollection ();
477                         c.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
478                         var hc = new HttpContextStub2 ("~/Test/test.html", String.Empty, ".");
479                         // it tries to get HttpContextBase.Response, so set it.
480                         hc.SetResponse (new HttpResponseStub (3));
481                         var rd = c.GetRouteData (hc);
482                         var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
483                         Assert.AreEqual ("./Test/test.html", vpd.VirtualPath, "#1");
484                         Assert.AreEqual (0, vpd.DataTokens.Count, "#2");
485                 }
486         }
487 }