BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / System.Net.Http / Test / System.Net.Http / HttpResponseMessageTest.cs
1 //
2 // HttpResponseMessageTest.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.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 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using NUnit.Framework;
33 using System.Net.Http;
34 using System.Net;
35 using System.Net.Http.Headers;
36 using System.Linq;
37
38 namespace MonoTests.System.Net.Http
39 {
40         [TestFixture]
41         public class HttpResponseMessageTest
42         {
43                 [Test]
44                 public void Ctor_Invalid ()
45                 {
46                         try {
47                                 new HttpResponseMessage ((HttpStatusCode) (-1));
48                                 Assert.Fail ("#1");
49                         } catch (ArgumentOutOfRangeException) {
50                         }
51                 }
52
53                 [Test]
54                 public void Ctor_Default ()
55                 {
56                         var m = new HttpResponseMessage ();
57                         Assert.IsNull (m.Content, "#1");
58                         Assert.IsNotNull (m.Headers, "#2");
59                         Assert.IsTrue (m.IsSuccessStatusCode, "#3");
60                         Assert.AreEqual ("OK", m.ReasonPhrase, "#4");
61                         Assert.IsNull (m.RequestMessage, "#5");
62                         Assert.AreEqual (HttpStatusCode.OK, m.StatusCode, "#6");
63                         Assert.AreEqual (new Version (1, 1), m.Version, "#7");
64                         Assert.IsNull (m.Headers.CacheControl, "#8");
65
66                         Assert.AreEqual ("StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: <null>, Headers:\r\n{\r\n}", m.ToString (), "#9");
67                 }
68
69                 [Test]
70                 public void Headers ()
71                 {
72                         HttpResponseMessage message = new HttpResponseMessage ();
73                         HttpResponseHeaders headers = message.Headers;
74
75                         headers.AcceptRanges.Add ("ac-v");
76                         headers.Age = TimeSpan.MaxValue;
77                         headers.CacheControl = new CacheControlHeaderValue () {
78                                 MaxStale = true
79                         };
80                         headers.Connection.Add ("test-value");
81                         headers.ConnectionClose = true;
82                         headers.Date = new DateTimeOffset (DateTime.Today);
83                         headers.ETag = new EntityTagHeaderValue ("\"tag\"", true);
84                         headers.Location = new Uri ("http://xamarin.com");
85                         headers.Pragma.Add (new NameValueHeaderValue ("name", "value"));
86                         headers.ProxyAuthenticate.Add (new AuthenticationHeaderValue ("proxy", "par"));
87                         headers.RetryAfter = new RetryConditionHeaderValue (TimeSpan.MinValue);
88                         headers.Server.Add (new ProductInfoHeaderValue ("(comment)"));
89                         headers.Trailer.Add ("trailer-vvv");
90                         headers.TransferEncoding.Add (new TransferCodingHeaderValue ("tchv"));
91                         headers.TransferEncodingChunked = true;
92                         headers.Upgrade.Add (new ProductHeaderValue ("prod", "ver"));
93                         headers.Vary.Add ("vary");
94                         headers.Via.Add (new ViaHeaderValue ("protocol", "rec-by"));
95                         headers.Warning.Add (new WarningHeaderValue (5, "agent", "\"txt\""));
96                         headers.WwwAuthenticate.Add (new AuthenticationHeaderValue ("www", "par"));
97
98                         try {
99                                 headers.Add ("age", "");
100                                 Assert.Fail ("age");
101                         } catch (FormatException) {
102                         }
103
104                         try {
105                                 headers.Add ("date", "");
106                                 Assert.Fail ("date");
107                         } catch (FormatException) {
108                         }
109
110                         try {
111                                 headers.Add ("etag", "");
112                                 Assert.Fail ("etag");
113                         } catch (FormatException) {
114                         }
115
116                         try {
117                                 headers.Add ("location", "extra");
118                                 Assert.Fail ("location");
119                         } catch (FormatException) {
120                         }
121
122                         try {
123                                 headers.Add ("retry-after", "extra");
124                                 Assert.Fail ("retry-after");
125                         } catch (FormatException) {
126                         }
127
128                         headers.Add ("accept-ranges", "achs");
129 // TODO:                        headers.Add ("cache-control", "cache-value");
130                         headers.Add ("connection", "ccc");
131                         headers.Add ("pragma", "p");
132                         headers.Add ("proxy-authenticate", "ttt");
133                         headers.Add ("server", "server");
134                         headers.Add ("trailer", "tt-r");
135                         headers.Add ("transfer-encoding", "ttt");
136                         headers.Add ("upgrade", "uuu");
137                         headers.Add ("upgrade", "vvvvaa");
138                         headers.Add ("vary", "vvaar");
139                         headers.Add ("via", "prot v");
140                         headers.Add ("warning", "4 ww \"t\"");
141                         headers.Add ("www-Authenticate", "ww");
142
143                         Assert.IsTrue (headers.AcceptRanges.SequenceEqual (
144                                 new[] {
145                                         "ac-v",
146                                         "achs"
147                                 }
148                         ));
149
150                         Assert.AreEqual (TimeSpan.MaxValue, headers.Age);
151
152                         Assert.AreEqual (
153                                 new CacheControlHeaderValue () {
154                                                 MaxStale = true,
155 // TODO                                         Extensions = { new NameValueHeaderValue ("cache-value") }
156                                         }, headers.CacheControl);
157
158                         Assert.IsTrue (headers.Connection.SequenceEqual (
159                                 new string[] { "test-value", "close", "ccc" }));
160
161                         Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.Date);
162
163                         Assert.AreEqual (new EntityTagHeaderValue ("\"tag\"", true), headers.ETag);
164
165                         Assert.AreEqual (new Uri ("http://xamarin.com"), headers.Location);
166
167                         Assert.IsTrue (headers.Pragma.SequenceEqual (
168                                 new [] {
169                                         new NameValueHeaderValue ("name", "value"),
170                                         new NameValueHeaderValue ("p"),
171                                 }));
172
173                         Assert.IsTrue (headers.ProxyAuthenticate.SequenceEqual (
174                                 new [] {
175                                         new AuthenticationHeaderValue ("proxy", "par"),
176                                         new AuthenticationHeaderValue ("ttt")
177                                 }
178                         ));
179
180                         Assert.AreEqual (new RetryConditionHeaderValue (TimeSpan.MinValue), headers.RetryAfter);
181
182                         Assert.IsTrue (headers.Server.SequenceEqual (
183                                 new [] {
184                                         new ProductInfoHeaderValue ("(comment)"),
185                                         new ProductInfoHeaderValue (new ProductHeaderValue ("server"))
186                                 }
187                         ));
188
189                         Assert.IsTrue (headers.Trailer.SequenceEqual (
190                                 new [] {
191                                         "trailer-vvv",
192                                         "tt-r"
193                                 }));
194
195                         Assert.IsTrue (headers.TransferEncoding.SequenceEqual (
196                                 new[] {
197                                         new TransferCodingHeaderValue ("tchv"),
198                                         new TransferCodingHeaderValue ("chunked"),
199                                         new TransferCodingHeaderValue ("ttt")
200                                 }
201                         ));
202
203                         Assert.IsTrue (headers.Upgrade.SequenceEqual (
204                                 new[] {
205                                         new ProductHeaderValue ("prod", "ver"),
206                                         new ProductHeaderValue ("uuu"),
207                                         new ProductHeaderValue ("vvvvaa")
208                                 }
209                         ));
210
211                         Assert.IsTrue (headers.Vary.SequenceEqual (
212                                 new[] {
213                                         "vary",
214                                         "vvaar"
215                                 }
216                         ));
217
218                         Assert.IsTrue (headers.Via.SequenceEqual (
219                                 new[] {
220                                         new ViaHeaderValue ("protocol", "rec-by"),
221                                         new ViaHeaderValue ("prot", "v")
222                                 }
223                         ));
224
225                         Assert.IsTrue (headers.Warning.SequenceEqual (
226                                 new[] {
227                                         new WarningHeaderValue (5, "agent", "\"txt\""),
228                                         new WarningHeaderValue (4, "ww", "\"t\"")
229                                 }
230                         ));
231
232                         Assert.IsTrue (headers.WwwAuthenticate.SequenceEqual (
233                                 new[] {
234                                         new AuthenticationHeaderValue ("www", "par"),
235                                         new AuthenticationHeaderValue ("ww")
236                                 }
237                         ));
238                 }
239
240                 [Test]
241                 public void EnsureSuccessStatusCode ()
242                 {
243                         HttpResponseMessage message = new HttpResponseMessage ();
244                         Assert.AreSame (message, message.EnsureSuccessStatusCode (), "#1");
245
246                         message = new HttpResponseMessage (HttpStatusCode.BadRequest);
247                         message.ReasonPhrase = "test reason";
248                         try {
249                                 message.EnsureSuccessStatusCode ();
250                                 Assert.Fail ("#2");
251                         } catch (HttpRequestException e) {
252                                 Assert.IsTrue (e.Message.Contains ("400 (test reason)"), "#3");
253                         }
254                 }
255
256                 [Test]
257                 public void Headers_GetEnumerator ()
258                 {
259                         HttpResponseMessage message = new HttpResponseMessage ();
260                         HttpResponseHeaders headers = message.Headers;
261
262                         headers.Add ("a", new[] { "v1", "v2" });
263                         headers.Add ("cache-control", "audio");
264                         headers.Age = new TimeSpan (4444, 2, 3, 4, 5);
265
266                         int i = 0;
267                         List<string> values;
268                         foreach (var entry in headers) {
269                                 switch (i) {
270                                 case 0:
271                                         Assert.AreEqual ("a", entry.Key);
272                                         values = entry.Value.ToList ();
273                                         Assert.AreEqual (2, values.Count);
274                                         Assert.AreEqual ("v1", values[0]);
275                                         break;
276                                 case 1:
277                                         Assert.AreEqual ("cache-control", entry.Key);
278                                         values = entry.Value.ToList ();
279                                         Assert.AreEqual (1, values.Count);
280                                         Assert.AreEqual ("audio", values[0]);
281                                         break;
282                                 case 2:
283                                         Assert.AreEqual ("Age", entry.Key);
284                                         values = entry.Value.ToList ();
285                                         Assert.AreEqual (1, values.Count);
286                                         Assert.AreEqual ("383968984", values[0]);
287                                         break;
288                                 }
289
290                                 ++i;
291                         }
292
293                         Assert.AreEqual (3, i, "#10");
294                 }
295
296                 [Test]
297                 public void Header_BaseImplementation ()
298                 {
299                         HttpResponseMessage message = new HttpResponseMessage ();
300                         HttpResponseHeaders headers = message.Headers;
301
302                         headers.Add ("a", "a-value");
303                         headers.Add ("b", new List<string> { "v1", "v2" });
304                         headers.Add ("c", null as string);
305                         headers.Add ("d", new string[0]);
306
307                         headers.AddWithoutValidation ("cache-control", "audio");
308
309                         Assert.IsFalse (headers.Contains ("nn"), "#1a");
310                         Assert.IsTrue (headers.Contains ("b"), "#1b");
311
312                         var values = headers.GetValues ("b").ToList ();
313                         Assert.AreEqual ("v1", values[0], "#2a");
314                         Assert.AreEqual ("v2", values[1], "#2b");
315
316                         Assert.IsFalse (headers.Remove ("p"), "#3a");
317                         Assert.IsTrue (headers.Remove ("b"), "#3b");
318                         Assert.IsFalse (headers.Contains ("b"), "#3b-c");
319
320                         IEnumerable<string> values2;
321                         Assert.IsTrue (headers.TryGetValues ("c", out values2));
322                         values = values2.ToList ();
323                         Assert.AreEqual ("", values[0], "#4a");
324
325                         int counter = 0;
326                         foreach (var i in headers) {
327                                 ++counter;
328                         }
329
330                         Assert.AreEqual (3, counter, "#5");
331
332                         headers.Clear ();
333                 }
334
335                 [Test]
336                 public void Headers_Invalid ()
337                 {
338                         HttpResponseMessage message = new HttpResponseMessage ();
339                         HttpResponseHeaders headers = message.Headers;
340
341                         try {
342                                 headers.Add ("age", "");
343                                 Assert.Fail ("#1");
344                         } catch (FormatException) {
345                         }
346
347                         try {
348                                 headers.Add (null, "");
349                                 Assert.Fail ("#2");
350                         } catch (ArgumentException) {
351                         }
352
353                         try {
354                                 headers.Add ("mm", null as IEnumerable<string>);
355                                 Assert.Fail ("#2b");
356                         } catch (ArgumentNullException) {
357                         }
358
359                         try {
360                                 headers.Add ("Allow", "audio");
361                                 Assert.Fail ("#2c");
362                         } catch (InvalidOperationException) {
363                         }
364
365                         try {
366                                 headers.AddWithoutValidation ("Allow", "");
367                                 Assert.Fail ("#3");
368                         } catch (InvalidOperationException) {
369                         }
370
371                         try {
372                                 headers.AddWithoutValidation (null, "");
373                                 Assert.Fail ("#4");
374                         } catch (ArgumentException) {
375                         }
376
377                         try {
378                                 headers.Contains (null);
379                                 Assert.Fail ("#5");
380                         } catch (ArgumentException) {
381                         }
382
383                         try {
384                                 headers.GetValues (null);
385                                 Assert.Fail ("#6a");
386                         } catch (ArgumentException) {
387                         }
388
389                         try {
390                                 headers.GetValues ("bbbb");
391                                 Assert.Fail ("#6b");
392                         } catch (InvalidOperationException) {
393                         }
394
395                         try {
396                                 headers.Add ("location", new[] { "google.com", "xamarin.com" });
397                                 Assert.Fail ("#7a");
398                         } catch (FormatException) {
399                         }
400
401                         headers.AddWithoutValidation ("location", "a@a.com");
402                         try {
403                                 headers.Add ("location", "w3.org");
404                                 Assert.Fail ("#7b");
405                         } catch (FormatException) {
406                         }
407                 }
408
409                 [Test]
410                 public void Headers_Request ()
411                 {
412                         HttpResponseMessage message = new HttpResponseMessage ();
413                         HttpResponseHeaders headers = message.Headers;
414
415                         headers.Add ("accept", "audio");
416                         Assert.AreEqual ("audio", headers.GetValues ("Accept").First (), "#1");
417
418                         headers.Clear ();
419                         headers.AddWithoutValidation ("accept", "audio");
420                         Assert.AreEqual ("audio", headers.GetValues ("Accept").First (), "#2");
421                 }
422
423                 [Test]
424                 public void Headers_ConnectionClose ()
425                 {
426                         HttpResponseMessage message = new HttpResponseMessage ();
427                         HttpResponseHeaders headers = message.Headers;
428                         Assert.IsNull (headers.ConnectionClose, "#1");
429
430                         headers.ConnectionClose = false;
431                         Assert.IsFalse (headers.ConnectionClose.Value, "#2");
432
433                         headers.Clear ();
434
435                         headers.ConnectionClose = true;
436                         Assert.IsTrue (headers.ConnectionClose.Value, "#3");
437
438                         headers.Clear ();
439                         headers.Connection.Add ("Close");
440                         Assert.IsTrue (headers.ConnectionClose.Value, "#4");
441
442                         Assert.AreEqual ("StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: <null>, Headers:\r\n{\r\nConnection: Close\r\n}", message.ToString (), "#5");
443                 }
444
445                 [Test]
446                 public void Headers_Location ()
447                 {
448                         HttpResponseMessage message = new HttpResponseMessage ();
449                         HttpResponseHeaders headers = message.Headers;
450                         headers.AddWithoutValidation ("location", "http://w3.org");
451                         Assert.AreEqual (new Uri ("http://w3.org"), headers.Location);
452                 }
453
454                 [Test]
455                 public void Headers_TransferEncoding ()
456                 {
457                         HttpResponseMessage message = new HttpResponseMessage ();
458                         HttpResponseHeaders headers = message.Headers;
459                         headers.AddWithoutValidation ("Transfer-Encoding", "mmm");
460                         headers.AddWithoutValidation ("Transfer-Encoding", "▀");
461                         headers.AddWithoutValidation ("Transfer-Encoding", "zz");
462
463                         var a = headers.TransferEncoding;
464                         Assert.AreEqual (2, a.Count, "#1");
465
466                         // Assert.AreEqual ("mmm, zz, ▀", a.ToString (), "#2");
467                 }
468
469                 [Test]
470                 public void Headers_TransferEncodingChunked ()
471                 {
472                         HttpResponseMessage message = new HttpResponseMessage ();
473                         HttpResponseHeaders headers = message.Headers;
474                         Assert.IsNull (headers.TransferEncodingChunked, "#1");
475
476                         headers.TransferEncodingChunked = false;
477                         Assert.IsFalse (headers.TransferEncodingChunked.Value, "#2");
478
479                         headers.Clear ();
480
481                         headers.TransferEncodingChunked = true;
482                         Assert.IsTrue (headers.TransferEncodingChunked.Value, "#3");
483                         Assert.AreEqual (1, headers.TransferEncoding.Count, "#3b");
484
485                         headers.Clear ();
486                         headers.AddWithoutValidation ("Transfer-Encoding", "value");
487 //                      Assert.AreEqual (false, headers.TransferEncodingChunked, "#4");
488
489                         headers.Clear ();
490                         headers.AddWithoutValidation ("Transfer-Encoding", "chunked");
491                         Assert.AreEqual (true, headers.TransferEncodingChunked, "#5");
492
493                         message = new HttpResponseMessage ();
494                         headers = message.Headers;
495                         headers.AddWithoutValidation ("Transfer-Encoding", "ß");
496                         Assert.IsNull (headers.TransferEncodingChunked, "#6");
497                 }
498
499                 [Test]
500                 public void Properties ()
501                 {
502                         var c = new HttpResponseMessage ();
503                         c.Content = null;
504                         c.ReasonPhrase = "rphr";
505                         c.RequestMessage = new HttpRequestMessage ();
506                         c.RequestMessage.Properties.Add ("a", "test");
507                         c.StatusCode = HttpStatusCode.UnsupportedMediaType;
508                         c.Version = HttpVersion.Version10;
509
510                         Assert.IsNull (c.Content, "#1");
511                         Assert.AreEqual ("rphr", c.ReasonPhrase, "#2");
512                         Assert.AreEqual ("test", c.RequestMessage.Properties["a"], "#3");
513                         Assert.AreEqual (HttpStatusCode.UnsupportedMediaType, c.StatusCode, "#4");
514                         Assert.AreEqual (HttpVersion.Version10, c.Version, "#5");
515                         Assert.IsFalse (c.IsSuccessStatusCode, "#6");
516                 }
517
518                 [Test]
519                 public void Properties_Invalid ()
520                 {
521                         var c = new HttpResponseMessage ();
522
523                         try {
524                                 c.StatusCode = (HttpStatusCode) (-1);
525                                 Assert.Fail ("#1");
526                         } catch (ArgumentException) {
527                         }
528
529                         try {
530                                 c.Version = null;
531                                 Assert.Fail ("#2");
532                         } catch (ArgumentNullException) {
533                         }
534                 }
535         }
536 }