Merge branch 'master' into config-checks-ipv6
[mono.git] / mcs / class / System / Test / System / UriBuilderTest.cs
1 //
2 // UriBuilderTest.cs - NUnit Test Cases for System.UriBuilder
3 //
4 // Authors:
5 //   Lawrence Pit (loz@cable.a2000.nl)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //
8 // (C) 2003 Martin Willemoes Hansen
9 // Copyright (C) 2010 Novell, Inc (http://www.novell.com)
10 //
11
12 using NUnit.Framework;
13 using System;
14 using System.Reflection;
15
16 namespace MonoTests.System
17 {
18         [TestFixture]
19         public class UriBuilderTest
20         {
21                 private UriBuilder b, b2, b3;
22                 public bool IriParsing;
23                 
24                 [SetUp]
25                 public void GetReady()
26                 {
27                         b = new UriBuilder ("http", "www.ximian.com", 80, "foo/bar/index.html");
28
29                         //Make sure Uri static constructor is called
30                         Uri.EscapeDataString ("");
31
32                         FieldInfo iriParsingField = typeof (Uri).GetField ("s_IriParsing",
33                                 BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic);
34                         if (iriParsingField != null)
35                                 IriParsing = (bool) iriParsingField.GetValue (null);
36                 }
37
38                 [Test] // ctor ()
39                 public void Constructor_Empty ()
40                 {
41                         b = new UriBuilder ();
42                         Assert.AreEqual ("http", b.Scheme, "#1");
43                         Assert.AreEqual ("localhost", b.Host, "#2");
44                         Assert.AreEqual (-1, b.Port, "#4");
45                         Assert.AreEqual (string.Empty, b.Query, "#5");
46                         Assert.AreEqual (string.Empty, b.Fragment, "#6");
47                 }
48
49                 [Test] // ctor (string)
50                 public void Constructor1 ()
51                 {
52                         b = new UriBuilder ("http://www.ximian.com:8001#test?name=50");
53                         Assert.AreEqual ("#test?name=50", b.Fragment, "#A1");
54                         Assert.AreEqual ("www.ximian.com", b.Host, "#A2");
55                         Assert.AreEqual (string.Empty, b.Password, "#A3");
56                         Assert.AreEqual ("/", b.Path, "#A4");
57                         Assert.AreEqual (8001, b.Port, "#A5");
58                         Assert.AreEqual (string.Empty, b.Query, "#A5");
59                         Assert.AreEqual ("http", b.Scheme, "#A6");
60                         Assert.AreEqual ("http://www.ximian.com:8001/#test?name=50", b.Uri.ToString (), "#A7");
61                         Assert.AreEqual (string.Empty, b.UserName, "#A8");
62
63                         b = new UriBuilder ("http://www.ximian.com?name=50#test");
64                         Assert.AreEqual ("#test", b.Fragment, "#B1");
65                         Assert.AreEqual ("www.ximian.com", b.Host, "#B2");
66                         Assert.AreEqual (string.Empty, b.Password, "#B3");
67                         Assert.AreEqual ("/", b.Path, "#B4");
68                         Assert.AreEqual (80, b.Port, "#B5");
69                         Assert.AreEqual ("?name=50", b.Query, "#B5");
70                         Assert.AreEqual ("http", b.Scheme, "#B6");
71                         Assert.AreEqual ("http://www.ximian.com/?name=50#test", b.Uri.ToString (), "#B7");
72                         Assert.AreEqual (string.Empty, b.UserName, "#B8");
73                 }
74
75                 [Test] // ctor (string)
76                 public void Constructor1_Uri_Null ()
77                 {
78                         try {
79                                 new UriBuilder ((string) null);
80                                 Assert.Fail ("#1");
81                         } catch (ArgumentNullException ex) {
82                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
83                                 Assert.IsNull (ex.InnerException, "#3");
84                                 Assert.IsNotNull (ex.Message, "#4");
85                                 Assert.IsNotNull (ex.ParamName, "#5");
86                                 Assert.AreEqual ("uriString", ex.ParamName, "#6");
87                         }
88                 }
89
90                 [Test] // ctor (Uri)
91                 [ExpectedException (typeof (ArgumentNullException))]
92                 public void Constructor2_Uri_Null ()
93                 {
94                         new UriBuilder ((Uri) null);
95                 }
96
97                 [Test]
98                 public void Constructor_5 ()
99                 {
100                         b = new UriBuilder ("http", "www.ximian.com", 80, "foo/bar/index.html", "#extras");
101                 }
102
103                 [Test]
104                 [ExpectedException (typeof (ArgumentException))]
105                 public void Constructor_5_BadExtraValue ()
106                 {
107                         b = new UriBuilder ("http", "www.ximian.com", 80, "foo/bar/index.html", "extras");
108                         // should have thrown an ArgumentException because extraValue must start with '?' or '#' character.
109                 }
110                 
111                 [Test]
112                 public void Constructor_StringStringInt ()
113                 {
114                         UriBuilder ub = new UriBuilder ("http", "www.mono-project.com", 80);
115                         Assert.AreEqual ("http://www.mono-project.com/", ub.Uri.AbsoluteUri, "Uri.AbsoluteUri");
116                 }
117
118                 [Test]
119                 [ExpectedException (typeof (InvalidOperationException))]
120                 public void Constructor_RelativeUri ()
121                 {
122                         Uri relative = new Uri ("../dir/subdir/file", UriKind.RelativeOrAbsolute);
123                         UriBuilder ub = new UriBuilder (relative);
124                 }
125
126                 [Test]
127                 public void UserInfo ()
128                 {
129                         string s = "mailto://myname:mypwd@contoso.com?subject=hello";
130                         b = new UriBuilder (s);
131                         Assert.AreEqual (s, b.ToString (), "1.ToString");
132                         Assert.AreEqual (string.Empty, b.UserName, "1.UserName");
133                         Assert.AreEqual (string.Empty, b.Password, "1.Password");
134                         Assert.AreEqual ("//myname:mypwd@contoso.com", b.Uri.LocalPath, "1.Uri.LocalPath");
135
136                         // weird ?caching? issue, UserInfo is not updated if we look at the value of UserName before setting Password
137                         b = new UriBuilder ("mailto", "contoso.com");
138                         b.UserName = "myname";
139                         Assert.AreEqual ("myname", b.Uri.UserInfo, "2.UserName");
140                         b.Password = "mypwd";
141                         Assert.AreEqual ("myname:mypwd", b.Uri.UserInfo, "2.Password");
142                         Assert.AreEqual ("/", b.Uri.LocalPath, "2.Uri.LocalPath");
143
144                         b = new UriBuilder ("mailto", "contoso.com");
145                         b.UserName = "myname";
146                         b.Password = "mypwd";
147                         Assert.AreEqual ("myname:mypwd", b.Uri.UserInfo, "3.Uri.UserInfo");
148                         Assert.AreEqual ("/", b.Uri.LocalPath, "3.Uri.LocalPath");
149                 }
150
151                 [Test]
152                 public void Path ()
153                 {
154                         b.Path = ((char) 0xa9) + " 2002";
155                         Assert.AreEqual ("%C2%A9%202002", b.Path);
156                 }
157                 
158                 [Test]
159                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
160                 public void BadPort1 ()
161                 {
162                         b.Port = -12345;
163                 }
164
165                 [Test]
166                 public void DefaultPort ()
167                 {
168                         b.Port = -1;
169                         Assert.AreEqual (-1, b.Port, "#1");
170                         Assert.AreEqual ("http://www.ximian.com/foo/bar/index.html", b.ToString (), "#2");
171                 }
172
173                 [Test]
174                 public void Query ()
175                 {
176                         b.Query = ((char) 0xa9) + " 2002";
177                         Assert.AreEqual ("?\xA9 2002", b.Query, "#1");
178                         Assert.AreEqual (string.Empty, b.Fragment, "#2");
179                         b.Query = "?test";
180                         Assert.AreEqual ("?test", b.Query, "#3");
181                         b.Query = null;
182                         Assert.AreEqual (string.Empty, b.Query, "#4");
183                         b.Fragment = "test";
184                         Assert.AreEqual ("#test", b.Fragment, "#5");
185                         b.Query = "name";
186                         Assert.AreEqual ("#test", b.Fragment, "#6");
187                         Assert.AreEqual ("?name", b.Query, "#7");
188                         b.Fragment = "run";
189                         Assert.AreEqual ("#run", b.Fragment, "#8");
190                         b.Query = null;
191                         Assert.AreEqual ("#run", b.Fragment, "#9");
192                         Assert.AreEqual (string.Empty, b.Query, "#10");
193                 }
194                 
195                 [Test]
196                 public void Fragment ()
197                 {
198                         b.Fragment = ((char) 0xa9) + " 2002";
199                         Assert.AreEqual ("#\xA9 2002", b.Fragment, "#1");
200                         Assert.AreEqual (string.Empty, b.Query, "#2");
201                         b.Fragment = "#test";
202                         Assert.AreEqual ("#test", b.Fragment, "#3");
203                         b.Fragment = null;
204                         Assert.AreEqual (String.Empty, b.Fragment, "#4");
205                         b.Query = "name";
206                         Assert.AreEqual ("?name", b.Query, "#5");
207                         b.Fragment = null;
208                         Assert.AreEqual ("?name", b.Query, "#6");
209                         Assert.AreEqual (string.Empty, b.Fragment, "#7");
210                 }
211                 
212                 [Test]
213                 public void Scheme ()
214                 {
215                         b.Scheme = "http";
216                         Assert.AreEqual ("http", b.Scheme, "#1");
217                         b.Scheme = "http:";
218                         Assert.AreEqual ("http", b.Scheme, "#2");
219                         b.Scheme = "http://";
220                         Assert.AreEqual ("http", b.Scheme, "#3");
221                         b.Scheme = "http://foo/bar";
222                         Assert.AreEqual ("http", b.Scheme, "#4");
223                         b.Scheme = "mailto:";
224                         Assert.AreEqual ("mailto", b.Scheme, "#5");
225                         b.Scheme = "unknown";
226                         Assert.AreEqual ("unknown", b.Scheme, "#6");
227                         b.Scheme = "unknown://";
228                         Assert.AreEqual ("unknown", b.Scheme, "#7");
229                 }
230                 
231                 [Test]
232                 public void Equals ()
233                 {
234                         b = new UriBuilder ("http://", "www.ximian.com", 80, "foo/bar/index.html?item=1");
235                         Assert.AreEqual ("foo/bar/index.html%3Fitem=1", b.Path, "1.Path");
236                         Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html%3Fitem=1", b.ToString (), "1.ToString");
237
238                         b2 = new UriBuilder ("http", "www.ximian.com", 80, "/foo/bar/index.html", "?item=1");
239                         Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html?item=1", b2.ToString (), "2.ToString");
240
241                         b3 = new UriBuilder (new Uri ("http://www.ximian.com/foo/bar/index.html?item=1"));
242                         Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html?item=1", b3.ToString (), "3.ToString");
243
244                         Assert.IsFalse (b.Equals (b2), "#1");
245                         Assert.IsFalse (b.Uri.Equals (b2.Uri), "#2");
246                         Assert.IsFalse (b.Equals (b3), "#3");
247                         Assert.IsFalse (b3.Equals (b), "#4");
248                         Assert.IsTrue (b2.Equals (b3), "#5");
249                 }
250                 
251                 [Test]
252                 public void ToStringTest ()
253                 {
254                         Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html", b.ToString (), "#1");
255                         Assert.AreEqual ("http://www.ximian.com/foo/bar/index.html", b.Uri.ToString (), "#2");
256                 }
257
258                 [Test]
259                 public void EmptyQuery () // bug 57082
260                 {
261                         b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", null);
262                         string noquery = "http://www.ximian.com/lalala/lelele.aspx";
263                         Assert.AreEqual (noquery, b.Uri.ToString (), "#1");
264                         b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", "?");
265                         Assert.AreEqual (noquery, b.Uri.ToString (), "#2");
266                         b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", "??");
267                         Assert.AreEqual (noquery + "?", b.Uri.ToString (), "#3");
268                         b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", "?something");
269                         Assert.AreEqual (noquery + "?something", b.Uri.ToString (), "#4");
270                 }
271
272                 [Test] // bug #76501
273                 public void TestToString76501 ()
274                 {
275                         UriBuilder ub = new UriBuilder (
276                                 "http://mondomaine/trucmuche/login.aspx");
277                         ub.Query = ub.Query.TrimStart (new char [] {'?'}) + "&ticket=bla";
278                         Assert.IsTrue (ub.ToString ().IndexOf ("80//") < 0);
279                 }
280
281                 [Test]
282                 public void TestAppendFragment ()
283                 {
284                         UriBuilder uri = new UriBuilder ("http://www.mono-project.com/Main_Page");
285                         uri.Fragment = "Features";
286                         Assert.AreEqual ("#Features", uri.Fragment, "#1");
287                         Assert.AreEqual ("http://www.mono-project.com/Main_Page#Features", uri.Uri.ToString (), "#2");
288                 }
289
290                 [Test]
291                 public void IPv6_Host ()
292                 {
293                         UriBuilder ub = new UriBuilder ("http", "[1:2:3:4:5:6:7:8]", 8080, "/dir/subdir/file");
294                         Assert.AreEqual ("[1:2:3:4:5:6:7:8]", ub.Host, "Host.1");
295                         if (IriParsing)
296                                 Assert.AreEqual ("[1:2:3:4:5:6:7:8]", ub.Uri.Host, "Uri.Host");
297                         else {
298                                 Assert.AreEqual ("[0001:0002:0003:0004:0005:0006:0007:0008]", ub.Uri.Host, "Uri.Host");
299                                 // once the Uri is created then some builder properties may change
300                                 Assert.AreEqual ("[0001:0002:0003:0004:0005:0006:0007:0008]", ub.Host, "Host.2");
301                         }
302                 }
303
304                 [Test]
305                 public void IPv6_Host_IncompleteAddress ()
306                 {
307                         UriBuilder ub = new UriBuilder ("http", "1:2:3:4:5:6:7:8", 8080, "/dir/subdir/file");
308                         Assert.AreEqual ("[1:2:3:4:5:6:7:8]", ub.Host, "1.Host");
309                         Assert.AreEqual ("http://[1:2:3:4:5:6:7:8]:8080/dir/subdir/file", ub.ToString (), "1.ToString ()");
310
311                         ub = new UriBuilder ("http", "1:", 8080, "/dir/subdir/file");
312                         Assert.AreEqual ("[1:]", ub.Host, "2.Host");
313                         Assert.AreEqual ("http://[1:]:8080/dir/subdir/file", ub.ToString (), "2.ToString ()");
314
315                         ub = new UriBuilder ("http", "[1:", 8080, "/dir/subdir/file");
316                         Assert.AreEqual ("[1:", ub.Host, "3.Host");
317                         Assert.AreEqual ("http://[1::8080/dir/subdir/file", ub.ToString (), "3.ToString ()");
318
319                         ub = new UriBuilder ("http", "1:2]", 8080, "/dir/subdir/file");
320                         Assert.AreEqual ("[1:2]]", ub.Host, "4.Host");
321                         Assert.AreEqual ("http://[1:2]]:8080/dir/subdir/file", ub.ToString (), "4.ToString ()");
322                 }
323
324                 [Test]
325                 public void Path_UriAbsolutePath_Path ()
326                 {
327                         UriBuilder ub = new UriBuilder ("http", "127.0.0.1", 80, "dir/subdir/file");
328                         Assert.AreEqual ("dir/subdir/file", ub.Path, "Path.1");
329                         Assert.AreEqual ("/dir/subdir/file", ub.Uri.AbsolutePath, "Uri.AbsolutePath");
330                         // once the Uri is created then some builder properties may change
331                         Assert.AreEqual ("/dir/subdir/file", ub.Path, "Path.2");
332                 }
333
334                 [Test]
335                 public void UnparsableUri ()
336                 {
337                         // some URI can't be parsed by System.Uri but are accepted by UriBuilder
338                         Uri u = null;
339                         string uri = "www.mono-project.com";
340                         Assert.IsFalse (Uri.TryCreate (uri, UriKind.Absolute, out u), "1.Uri.TryCreate");
341                         UriBuilder ub = new UriBuilder (uri);
342                         Assert.AreEqual ("www.mono-project.com", ub.Host, "1.Host");
343                         Assert.AreEqual ("http", ub.Scheme, "1.Scheme");
344                         Assert.AreEqual (80, ub.Port, "1.Port");
345                         Assert.AreEqual ("/", ub.Path, "1.Path");
346
347                         // always assume http, port 80
348                         uri = "ftp.novell.com/dir/subdir/file";
349                         ub = new UriBuilder (uri);
350                         Assert.IsFalse (Uri.TryCreate (uri, UriKind.Absolute, out u), "2.Uri.TryCreate");
351                         Assert.AreEqual ("ftp.novell.com", ub.Host, "2.Host");
352                         Assert.AreEqual ("http", ub.Scheme, "2.Scheme");
353                         Assert.AreEqual (80, ub.Port, "2.Port");
354                         Assert.AreEqual ("/dir/subdir/file", ub.Path, "2.Path");
355                 }
356
357                 [Test]
358                 public void AspNetRedirectUsage_Old ()
359                 {
360                         Uri uri = new Uri ("http://192.168.0.21:80/WebResource.axd?d=AAAAAAAAAAEAAAAAAAAAAA2");
361                         UriBuilder ub = new UriBuilder (uri);
362                         ub.Path = "error404.aspx?aspxerrorpath=/WebResource.axd";
363                         ub.Fragment = null;
364                         ub.Password = null;
365                         ub.Query = null;
366                         ub.UserName = null;
367                         // a bug in older UriBuilder did not encode the ? - existing ASP.NET depends on buggy behavior
368                         Assert.AreEqual ("http://192.168.0.21/error404.aspx%3Faspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
369                 }
370
371                 [Test]
372                 public void AspNetRedirectUsage_New ()
373                 {
374                         string path = "error404.aspx?aspxerrorpath=/WebResource.axd";
375                         Uri uri = new Uri ("http://192.168.0.21:80/WebResource.axd?d=AAAAAAAAAAEAAAAAAAAAAA2");
376                         UriBuilder ub = new UriBuilder (uri);
377                         int qpos = path.IndexOf ('?');
378                         ub.Path = path.Substring (0, qpos);
379                         ub.Fragment = null;
380                         ub.Password = null;
381                         ub.Query = path.Substring (qpos + 1);
382                         ub.UserName = null;
383                         // this is what ASP.NET really means (the ?)
384                         Assert.AreEqual ("http://192.168.0.21/error404.aspx?aspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
385                 }
386
387                 [Test]
388                 public void NoHostname ()
389                 {
390                         UriBuilder ub = new UriBuilder ("about", null, -1, "config");
391                         Assert.AreEqual ("about:config", ub.ToString ());
392                 }
393         }
394 }
395