2009-05-21 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.Web.Routing / Test / System.Web.Routing / RouteTest.cs
1 //
2 // RouteTest.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 RouteTest
39         {
40                 [Test]
41                 public void ConstructorNullArgs ()
42                 {
43                         var r = new Route (null, null);
44                         Assert.AreEqual (String.Empty, r.Url);
45                         Assert.IsNull (r.RouteHandler);
46                 }
47
48                 [Test]
49                 public void SetNullUrl ()
50                 {
51                         var r = new Route (null, null);
52                         r.Url = "urn:foo";
53                         r.Url = null;
54                         Assert.AreEqual (String.Empty, r.Url);
55                 }
56
57                 [Test]
58                 [ExpectedException (typeof (ArgumentException))]
59                 public void InvalidUrl ()
60                 {
61                         new Route ("~", null); // cannot start with '~'
62                 }
63
64                 [Test]
65                 [ExpectedException (typeof (ArgumentException))]
66                 public void InvalidUrl2 ()
67                 {
68                         new Route ("/", null); // cannot start with '/'
69                 }
70
71                 [Test]
72                 [ExpectedException (typeof (ArgumentException))]
73                 public void InvalidUrl3 ()
74                 {
75                         new Route ("foo?bar", null); // cannot contain '?'
76                 }
77
78                 [Test]
79                 [ExpectedException (typeof (ArgumentException))]
80                 public void InvalidUrl4 ()
81                 {
82                         new Route ("foo/{bar", null); // unmatched '{'
83                 }
84
85                 [Test]
86                 [ExpectedException (typeof (ArgumentException))]
87                 public void InvalidUrl5 ()
88                 {
89                         new Route ("foo/bar}", null); // unmatched '}'
90                 }
91
92                 [Test]
93                 [ExpectedException (typeof (ArgumentException))]
94                 public void InvalidUrl6 ()
95                 {
96                         new Route ("foo/{}", null); // "" is an invalid parameter name.
97                 }
98
99                 [Test]
100                 [ExpectedException (typeof (ArgumentException))]
101                 public void InvalidUrl7 ()
102                 {
103                         new Route ("foo/{x/y/z}", null); // incomplete parameter in path segment.
104                 }
105
106                 [Test]
107                 [ExpectedException (typeof (ArgumentException))]
108                 public void InvalidUrl8 ()
109                 {
110                         new Route ("foo/{a{{b}}c}", null); // regarded as an incomplete parameter
111                 }
112
113                 [Test]
114                 [ExpectedException (typeof (ArgumentException))]
115                 public void InvalidUrl9 ()
116                 {
117                         new Route ("foo/{a}{b}", null); // consecutive parameters are not allowed
118                 }
119
120                 [Test]
121                 [ExpectedException (typeof (ArgumentException))]
122                 public void InvalidUrl10 ()
123                 {
124                         new Route ("foo//bar", null); // consecutive segment separators '/' are not allowed
125                 }
126
127                 [Test]
128                 public void ValidUrl ()
129                 {
130                         var r = new Route ("{foo}/{bar}", null);
131                         Assert.AreEqual ("{foo}/{bar}", r.Url, "#1");
132                         Assert.IsNull (r.DataTokens, "#2");
133                         Assert.IsNull (r.Defaults, "#3");
134                         Assert.IsNull (r.Constraints, "#4");
135                 }
136
137                 [Test]
138                 public void ValidUrl2 ()
139                 {
140                         new Route ("a~c", null);
141                 }
142
143                 [Test]
144                 public void ValidUrl3 ()
145                 {
146                         new Route ("foo/", null);
147                 }
148
149                 [Test]
150                 public void RoutingHandler ()
151                 {
152                         var r = new Route (null, new StopRoutingHandler ());
153                         Assert.AreEqual (typeof (StopRoutingHandler), r.RouteHandler.GetType (), "#1");
154                 }
155
156                 [Test]
157                 public void GetRouteDataNoTemplate ()
158                 {
159                         var r = new Route ("foo/bar", null);
160                         var hc = new HttpContextStub ("~/foo/bar", String.Empty);
161                         var rd = r.GetRouteData (hc);
162                         Assert.IsNotNull (rd, "#1");
163                         Assert.AreEqual (r, rd.Route, "#2");
164                         Assert.AreEqual (0, rd.DataTokens.Count, "#3");
165                         Assert.AreEqual (0, rd.Values.Count, "#4");
166                 }
167
168                 [Test]
169                 [ExpectedException (typeof (InvalidOperationException))]
170                 public void InvalidConstraint ()
171                 {
172                         var r = new Route ("{foo}/{bar}", new StopRoutingHandler ());
173                         var c = new RouteValueDictionary ();
174                         c ["foo"] = Guid.NewGuid ();
175                         r.Constraints = c;
176                         var hc = new HttpContextStub ("~/x/y", String.Empty);
177                         var rd = r.GetRouteData (hc);
178                 }
179
180                 [Test]
181                 public void GetRouteData ()
182                 {
183                         var r = new Route ("{foo}/{bar}", null);
184                         var hc = new HttpContextStub ("~/x/y", String.Empty);
185                         var rd = r.GetRouteData (hc);
186                         Assert.IsNotNull (rd, "#1");
187                         Assert.AreEqual (r, rd.Route, "#2");
188                         Assert.AreEqual (0, rd.DataTokens.Count, "#3");
189                         Assert.AreEqual (2, rd.Values.Count, "#4");
190                         Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
191                         Assert.AreEqual ("y", rd.Values ["bar"], "#4-2");
192                 }
193
194                 [Test]
195                 public void GetRouteData2 ()
196                 {
197                         // {} matches and substitutes even at partial state ...
198                         var r = new Route ("{foo}/bar{baz}", null);
199                         var hc = new HttpContextStub ("~/x/bart", String.Empty);
200                         var rd = r.GetRouteData (hc);
201                         Assert.IsNotNull (rd, "#1");
202                         Assert.AreEqual (r, rd.Route, "#2");
203                         Assert.AreEqual (0, rd.DataTokens.Count, "#3");
204                         Assert.AreEqual (2, rd.Values.Count, "#4");
205                         Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
206                         Assert.AreEqual ("t", rd.Values ["baz"], "#4-2");
207                 }
208
209                 [Test]
210                 public void GetRouteData3 ()
211                 {
212                         var r = new Route ("{foo}/{bar}", null);
213                         var hc = new HttpContextStub ("~/x/y/z", String.Empty);
214                         var rd = r.GetRouteData (hc);
215                         Assert.IsNull (rd); // mismatch
216                 }
217
218                 [Test]
219                 public void GetRouteData4 ()
220                 {
221                         var r = new Route ("{foo}/{bar}", null);
222                         var hc = new HttpContextStub ("~/x", String.Empty);
223                         var rd = r.GetRouteData (hc);
224                         Assert.IsNull (rd); // mismatch
225                 }
226
227                 [Test]
228                 public void GetRouteData5 ()
229                 {
230                         var r = new Route ("{foo}/{bar}", new StopRoutingHandler ());
231                         var rd = r.GetRouteData (new HttpContextStub ("x/y", String.Empty));
232                         Assert.IsNull (rd, "#1");
233                         rd = r.GetRouteData (new HttpContextStub ("~/x/y", String.Empty));
234                         Assert.IsNotNull (rd, "#2");
235                         rd = r.GetRouteData (new HttpContextStub ("~/x/y/z", String.Empty));
236                         Assert.IsNull (rd, "#3");
237                         rd = r.GetRouteData (new HttpContextStub ("~x/y", String.Empty));
238                         Assert.IsNull (rd, "#4");
239                         rd = r.GetRouteData (new HttpContextStub ("/x/y", String.Empty));
240                         Assert.IsNull (rd, "#5");
241
242                         rd = r.GetRouteData (new HttpContextStub ("{foo}/{bar}/baz", String.Empty));
243                         Assert.IsNull (rd, "#6");
244                         rd = r.GetRouteData (new HttpContextStub ("{foo}/{bar}", String.Empty));
245                         Assert.IsNotNull (rd, "#7");
246                         Assert.AreEqual (0, rd.DataTokens.Count, "#7-2");
247                         Assert.AreEqual (2, rd.Values.Count, "#7-3");
248                 }
249
250                 [Test]
251                 public void GetRouteData6 ()
252                 {
253                         var r = new Route ("{table}/{action}.aspx", null);
254                         var rd = r.GetRouteData (new HttpContextStub ("~/FooTable/List.aspx", String.Empty));
255                         Assert.IsNotNull (rd, "#1");
256                         Assert.AreEqual ("FooTable", rd.Values ["table"], "#2");
257                         Assert.AreEqual ("List", rd.Values ["action"], "#3");
258                 }
259
260                 [Test]
261                 [Ignore ("Pending testing - might be invalid test")]
262                 public void GetRouteData7 ()
263                 {
264                         var r = new Route ("{table}/{action}.aspx", null);
265                         var rd = r.GetRouteData (new HttpContextStub ("~/FooTable/", String.Empty));
266                         Assert.IsNull (rd, "#1");
267                 }
268
269                 [Test]
270                 [ExpectedException (typeof (ArgumentNullException))]
271                 public void GetVirtualPathNullContext ()
272                 {
273                         try {
274                                 var r = new Route (null, null);
275                                 r.GetVirtualPath (null, new RouteValueDictionary ());
276                         } catch (NullReferenceException) {
277                                 // .NET lacks null arg check here. (No need to mimic silly behavior here.)
278                                 throw new ArgumentNullException ();
279                         }
280                 }
281
282                 [Test]
283                 public void GetVirtualPathNullValues ()
284                 {
285                         // null values is allowed.
286                         var r = new Route (null, null);
287                         var rd = new RouteData ();
288                         var vp = r.GetVirtualPath (new RequestContext (new HttpContextStub (), rd), null);
289                         Assert.AreEqual (String.Empty, vp.VirtualPath, "#1");
290                         Assert.AreEqual (r, vp.Route, "#2");
291                 }
292
293                 [Test]
294                 public void GetVirtualPath ()
295                 {
296                         var r = new Route ("foo/bar", null);
297                         var rd = new RouteData ();
298                         var vp = r.GetVirtualPath (new RequestContext (new HttpContextStub ("~/foo/bar"), rd), null);
299                         Assert.AreEqual ("foo/bar", vp.VirtualPath, "#1");
300                         Assert.AreEqual (r, vp.Route, "#2");
301
302                         vp = r.GetVirtualPath (new RequestContext (new HttpContextStub ("~/foo/bar/baz"), rd), null);
303                         Assert.AreEqual ("foo/bar", vp.VirtualPath, "#3");
304                         Assert.AreEqual (r, vp.Route, "#4");
305                 }
306
307                 [Test]
308                 public void GetVirtualPath2 ()
309                 {
310                         var r = new Route ("{foo}/{bar}", null);
311                         var hc = new HttpContextStub ("~/x/y", String.Empty);
312                         var rd = r.GetRouteData (hc);
313                         var vp = r.GetVirtualPath (new RequestContext (hc, rd), null);
314                         Assert.IsNotNull (vp, "#1");
315                         Assert.AreEqual ("x/y", vp.VirtualPath, "#2");
316                         Assert.AreEqual (r, vp.Route, "#3");
317                         Assert.AreEqual (0, vp.DataTokens.Count, "#4");
318                 }
319
320                 [Test]
321                 public void GetVirtualPath3 ()
322                 {
323                         var r = new MyRoute ("{foo}/{bar}", new MyRouteHandler ());
324                         var hc = new HttpContextStub2 ("~/x/y", String.Empty);
325                         var rd = r.GetRouteData (hc);
326                         var vp = r.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
327
328                         Assert.IsNotNull (vp, "#1");
329                         Assert.AreEqual ("x/y", vp.VirtualPath, "#2");
330                         Assert.AreEqual (r, vp.Route, "#3");
331                         Assert.AreEqual (0, vp.DataTokens.Count, "#4");
332                 }
333
334                 [Test]
335                 public void GetVirtualPath4 ()
336                 {
337                         var r = new MyRoute ("{foo}/{bar}", new MyRouteHandler ());
338                         var hc = new HttpContextStub2 ("~/x/y", String.Empty);
339                         var rd = r.GetRouteData (hc);
340
341                         // override a value incompletely
342                         var values = new RouteValueDictionary ();
343                         values ["foo"] = "A";
344
345                         var vp = r.GetVirtualPath (new RequestContext (hc, rd), values);
346                         Assert.IsNull (vp);
347                 }
348
349                 [Test]
350                 public void GetVirtualPath5 ()
351                 {
352                         var r = new MyRoute ("{foo}/{bar}", new MyRouteHandler ());
353                         var hc = new HttpContextStub2 ("~/x/y", String.Empty);
354                         var rd = r.GetRouteData (hc);
355
356                         // override values completely.
357                         var values = new RouteValueDictionary ();
358                         values ["foo"] = "A";
359                         values ["bar"] = "B";
360
361                         var vp = r.GetVirtualPath (new RequestContext (hc, rd), values);
362
363                         Assert.IsNotNull (vp, "#1");
364                         Assert.AreEqual ("A/B", vp.VirtualPath, "#2");
365                         Assert.AreEqual (r, vp.Route, "#3");
366                         Assert.AreEqual (0, vp.DataTokens.Count, "#4");
367                 }
368
369                 // Bug #500739
370                 [Test]
371                 public void RouteGetRequiredStringWithDefaults ()
372                 {
373                         var routes = new RouteValueDictionary ();
374                         var route = new Route ("Hello/{name}", new MyRouteHandler ()) {
375                                         Defaults = new RouteValueDictionary (new {controller = "Home", action = "Hello"})
376                                 };
377                         routes.Add ("Name", route);
378
379                         var hc = new HttpContextStub2 ("~/Hello/World", String.Empty);
380                         var rd = route.GetRouteData (hc);
381
382                         Assert.IsNotNull (rd, "#A1");
383                         Assert.AreEqual ("Home", rd.GetRequiredString ("controller"), "#A2");
384                         Assert.AreEqual ("Hello", rd.GetRequiredString ("action"), "#A3");
385                         Assert.AreEqual ("World", rd.Values ["name"], "#A4");
386                 }
387         }
388 }