[resgen] Implement conditional resources (#if/#ifdef)
[mono.git] / mcs / class / System.Web / Test / System.Web / HttpResponseTest.cs
1 //
2 // System.Web.HttpResponseTest.cs - Unit tests for System.Web.HttpResponse
3 //
4 // Author:
5 //      Miguel de Icaza  <miguel@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.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.Specialized;
32 using System.Configuration.Provider;
33 using System.IO;
34 using System.Text;
35 using System.Web;
36 #if NET_4_0
37 using System.Web.Routing;
38 using System.Web.Caching;
39 #endif
40
41 using NUnit.Framework;
42
43 using MonoTests.Common;
44
45 namespace MonoTests.System.Web {
46
47         public class FakeHttpWorkerRequest2 : HttpWorkerRequest {
48                 public Hashtable KnownResponseHeaders;
49                 public Hashtable UnknownResponseHeaders;
50                 public int return_kind;
51                 
52                 public FakeHttpWorkerRequest2 (int re)
53                 {
54                         KnownResponseHeaders = CollectionsUtil.CreateCaseInsensitiveHashtable();
55                         UnknownResponseHeaders = CollectionsUtil.CreateCaseInsensitiveHashtable();
56                         return_kind = re;
57                 }
58                 
59                 public override string GetUriPath()
60                 {
61                         return "/fake";
62                 }
63                 
64                 public override string GetQueryString()
65                 {
66                         return "GetQueryString";
67                 }
68                 
69                 public override string GetRawUrl()
70                 {
71                         return "/GetRawUrl";
72                 }
73                 
74                 public override string GetHttpVerbName()
75                 {
76                         return "GET";
77                 }
78                 
79                 public override string GetHttpVersion()
80                 {
81                         if (return_kind == 1)
82                                 return "HTTP/1.0";
83                         else
84                                 return "HTTP/1.1";
85                 }
86                 
87                 public override string GetRemoteAddress()
88                 {
89                         return "__GetRemoteAddress";
90                         }
91         
92                 public override int GetRemotePort()
93                 {
94                         return 1010;
95                 }
96                 
97                 public override string GetLocalAddress()
98                 {
99                         return "GetLocalAddress";
100                 }
101                 
102                 public override string GetAppPath ()
103                 {
104                         return "AppPath";
105                 }
106                 
107                 public override int GetLocalPort()
108                 {
109                         return 2020;
110                 }
111
112                 public bool status_sent;
113                 public int status_code;
114                 public string status_string;
115                 
116                 public override void SendStatus(int s, string x)
117                 {
118                         status_sent = true;
119                         status_code = s;
120                         status_string = x;
121                 }
122
123                 void AddHeader (Hashtable table, string header_name, object header)
124                 {
125                         object o = table [header_name];
126                         if (o == null)
127                                 table.Add (header_name, header);
128                         else {
129                                 ArrayList al = o as ArrayList;
130                                 if (al == null) {
131                                         al = new ArrayList ();
132                                         al.Add (o);
133                                         table [header_name] = al;
134                                 } else
135                                         al = o as ArrayList;
136                                 
137                                 al.Add (header);
138                         }
139                 }
140                 
141                 bool headers_sent;
142                 public override void SendKnownResponseHeader(int x, string j)
143                 {
144                         string header_name = HttpWorkerRequest.GetKnownRequestHeaderName (x);
145                         AddHeader (KnownResponseHeaders, header_name, new KnownResponseHeader (x, j));
146                         headers_sent = true;
147                 }
148                 
149                 public override void SendUnknownResponseHeader(string a, string b)
150                 {
151                         AddHeader (UnknownResponseHeaders, a, new UnknownResponseHeader (a, b));
152                         headers_sent = true;
153                 }
154
155                 bool data_sent;
156                 public byte [] data;
157                 public int data_len;
158                 public int total = 0;
159                 
160                 public override void SendResponseFromMemory(byte[] arr, int x)
161                 {
162                         data_sent = true;
163                         if (data != null) {
164                                 byte [] tmp = new byte [data.Length + x];
165                                 Array.Copy (data, tmp, data.Length);
166                                 Array.Copy (arr, 0, tmp, data.Length, x);
167                                 data = tmp;
168                                 data_len = data.Length;
169                         } else {
170                                 data = new byte [x];
171                                 for (int i = 0; i < x; i++)
172                                         data [i] = arr [i];
173                                 data_len = x;
174                         }
175                         total += x;
176                 }
177                 
178                 public override void SendResponseFromFile(string a, long b , long c)
179                 {
180                         data_sent = true;
181                 }
182                 
183                 public override void SendResponseFromFile (IntPtr a, long b, long c)
184                 {
185                         data_sent = true;
186                 }
187                 
188                 public override void FlushResponse(bool x)
189                 {
190                 }
191                 
192                 public override void EndOfRequest() {
193                 }
194                 
195                 public override string GetKnownRequestHeader (int index)
196                 {
197                         return null;
198                 }
199
200                 public bool OutputProduced {
201                         get {
202                                 return headers_sent || data_sent;
203                         }
204                 }
205         }
206
207         class KnownResponseHeader
208         {
209                 private int index;
210                 private string value;
211
212                 public KnownResponseHeader (int index, string value)
213                 {
214                         this.index = index;
215                         this.value = value;
216                 }
217
218                 public int Index {
219                         get { return index; }
220                 }
221
222                 public string Value {
223                         get { return value; }
224                 }
225         }
226
227         class UnknownResponseHeader
228         {
229                 private string name;
230                 private string value;
231
232                 public UnknownResponseHeader (string name, string value)
233                 {
234                         this.name = name;
235                         this.value = value;
236                 }
237
238                 public string Name {
239                         get { return name; }
240                 }
241
242                 public string Value {
243                         get { return value; }
244                 }
245         }
246
247         [TestFixture]
248         public class HttpResponseTest {
249                 public static HttpContext Cook (int re, out FakeHttpWorkerRequest2 f)
250                 {
251                         f = new FakeHttpWorkerRequest2 (re);
252                         HttpContext c = new HttpContext (f);
253
254                         return c;
255                 }
256
257                 [SetUp]
258                 public void SetUp ()
259                 {
260                         AppDomain.CurrentDomain.SetData (".appPath", AppDomain.CurrentDomain.BaseDirectory);
261                 }
262
263                 [Test]
264                 public void Test_Response ()
265                 {
266                         FakeHttpWorkerRequest2 f;
267                         HttpContext c = Cook (1, out f);
268
269                         c.Response.Write ("a");
270                         Assert.AreEqual (false, f.OutputProduced, "T1");
271                         c.Response.Flush ();
272                         Assert.AreEqual (1, f.data_len, "T2");
273                         c.Response.Write ("Hola");
274                         Assert.AreEqual (1, f.data_len, "T3");
275                         c.Response.Flush ();
276                         Assert.AreEqual (5, f.data_len, "T4");
277                         Assert.AreEqual ((byte) 'a', f.data [0], "T5");
278                         Assert.AreEqual ((byte) 'H', f.data [1], "T6");
279                         Assert.AreEqual ((byte) 'o', f.data [2], "T7");
280                         Assert.AreEqual ((byte) 'l', f.data [3], "T8");
281                         Assert.AreEqual ((byte) 'a', f.data [4], "T9");
282                 }
283
284                 [Test]
285                 public void TestResponse_Chunked ()
286                 {
287                         FakeHttpWorkerRequest2 f;
288                         HttpContext c = Cook (2, out f);
289
290                         c.Response.Write ("a");
291                         Assert.AreEqual (false, f.OutputProduced, "CT1");
292                         c.Response.Flush ();
293                         Assert.AreEqual (6, f.total, "CT2");
294                         c.Response.Write ("Hola");
295                         Assert.AreEqual (6, f.total, "CT3");
296                         c.Response.Flush ();
297                         
298                 }
299
300                 [Test]
301                 public void Status1 ()
302                 {
303                         FakeHttpWorkerRequest2 f;
304                         HttpContext c = Cook (2, out f);
305
306                         HttpResponse resp = c.Response;
307                         resp.Status = "200 Lalala";
308                         Assert.AreEqual (200, resp.StatusCode, "ST1");
309                         Assert.AreEqual ("Lalala", resp.StatusDescription, "ST2");
310
311                         resp.Status = "10000 La la la";
312                         Assert.AreEqual (10000, resp.StatusCode, "ST3");
313                         Assert.AreEqual ("La la la", resp.StatusDescription, "ST4");
314
315                         resp.Status = "-1 La la la";
316                         Assert.AreEqual (-1, resp.StatusCode, "ST5");
317                         Assert.AreEqual ("La la la", resp.StatusDescription, "ST6");
318
319                         resp.Status = "-200 La la la";
320                         Assert.AreEqual (-200, resp.StatusCode, "ST7");
321                         Assert.AreEqual ("La la la", resp.StatusDescription, "ST8");
322
323                         resp.Status = "200 ";
324                         Assert.AreEqual (200, resp.StatusCode, "ST7");
325                         Assert.AreEqual ("", resp.StatusDescription, "ST8");
326                 }
327
328                 [Test]
329                 public void Status2 ()
330                 {
331                         FakeHttpWorkerRequest2 f;
332                         HttpContext c = Cook (2, out f);
333
334                         HttpResponse resp = c.Response;
335                         try {
336                                 resp.Status = "200";
337                                 Assert.Fail ("#1");
338                         } catch (HttpException) {
339                         }
340                 }
341
342                 [Test]
343                 public void Status3 ()
344                 {
345                         FakeHttpWorkerRequest2 f;
346                         HttpContext c = Cook (2, out f);
347
348                         HttpResponse resp = c.Response;
349                         try {
350                                 resp.Status = "200\t";
351                                 Assert.Fail ("#1");
352                         } catch (HttpException) {
353                         }
354                 }
355
356                 [Test]
357                 public void Status4 ()
358                 {
359                         FakeHttpWorkerRequest2 f;
360                         HttpContext c = Cook (2, out f);
361
362                         HttpResponse resp = c.Response;
363
364                         Assert.AreEqual (200, resp.StatusCode, "STT1");
365                         Assert.AreEqual (HttpWorkerRequest.GetStatusDescription (200), resp.StatusDescription, "STT2");
366
367                         resp.StatusCode = 400;
368                         Assert.AreEqual (400, resp.StatusCode, "STT3");
369                         Assert.AreEqual (HttpWorkerRequest.GetStatusDescription (400), resp.StatusDescription, "STT4");
370
371                         resp.StatusDescription = "Something else";
372                         Assert.AreEqual (400, resp.StatusCode, "STT5");
373                         Assert.AreEqual ("Something else", resp.StatusDescription, "STT6");
374
375                         resp.StatusDescription = null;
376                         Assert.AreEqual (400, resp.StatusCode, "STT7");
377                         Assert.AreEqual (HttpWorkerRequest.GetStatusDescription (400), resp.StatusDescription, "STT8");
378                 }
379
380                 //
381                 // TODO: Add test for BinaryWrite and the various writes to check for Chunked Mode
382                 //`
383
384                 [Test]
385                 public void SetCacheability ()
386                 {
387                         FakeHttpWorkerRequest2 f;
388                         HttpContext c = Cook (1, out f);
389
390                         //
391                         // Basically the values from CacheControl are useless once Response.Cache is used
392                         //
393                         c.Response.Cache.SetCacheability (HttpCacheability.ServerAndNoCache);
394                         Assert.AreEqual ("private", c.Response.CacheControl, "C1");
395                         
396                         c.Response.Cache.SetCacheability (HttpCacheability.ServerAndPrivate);
397                         Assert.AreEqual ("private", c.Response.CacheControl, "C2");
398                         
399                         c.Response.Cache.SetCacheability (HttpCacheability.NoCache);
400                         Assert.AreEqual ("private", c.Response.CacheControl, "C3");
401                         
402                         c.Response.Cache.SetCacheability (HttpCacheability.Private);
403                         Assert.AreEqual ("private", c.Response.CacheControl, "C4");
404                         
405                         c.Response.Cache.SetCacheability (HttpCacheability.Server);
406                         Assert.AreEqual ("private", c.Response.CacheControl, "C5");
407                         
408                         c.Response.Cache.SetCacheability (HttpCacheability.Public);
409                         Assert.AreEqual ("private", c.Response.CacheControl, "C6");
410                 }
411
412                 //
413                 // Test the values allowed;  .NET only documents private and public, but
414                 // "no-cache" from the spec is also allowed
415                 //
416                 [Test]
417                 public void CacheControl ()
418                 {
419                         FakeHttpWorkerRequest2 f;
420                         HttpContext c = Cook (1, out f);
421
422                         // Default value.
423                         Assert.AreEqual ("private", c.Response.CacheControl, "D1");
424                                          
425                         c.Response.CacheControl = "private";
426                         Assert.AreEqual ("private", c.Response.CacheControl, "D2");
427
428                         c.Response.CacheControl = "public";
429                         Assert.AreEqual ("public", c.Response.CacheControl, "D3");
430                         
431                         c.Response.CacheControl = "no-cache";
432                         Assert.AreEqual ("no-cache", c.Response.CacheControl, "D4");
433
434                         c.Response.CacheControl = null;
435                         Assert.AreEqual ("private", c.Response.CacheControl, "D5");
436
437                         c.Response.CacheControl = "";
438                         Assert.AreEqual ("private", c.Response.CacheControl, "D6");
439                 }
440
441                 //
442                 // Just checks if the AddFileDepend* methods accept values, added after bug #342511
443                 [Test]
444                 public void AddFileDependencies ()
445                 {
446                         FakeHttpWorkerRequest2 f;
447                         HttpContext c = Cook (1, out f);
448
449                         ArrayList a = new ArrayList (1);
450                         a.Add ("somefile.txt");
451                         c.Response.AddFileDependencies (a);
452
453                         string[] sa = new string [1] {"somefile.txt"};
454                         c = Cook (1, out f);
455                         c.Response.AddFileDependencies (sa);
456
457                         c = Cook (1, out f);
458                         c.Response.AddFileDependency ("somefile.txt");
459                 }
460
461                 [Test] // bug #488702
462                 public void WriteHeaders ()
463                 {
464                         FakeHttpWorkerRequest2 f;
465                         HttpContext c = Cook (2, out f);
466
467                         HttpResponse resp = c.Response;
468                         resp.CacheControl = "public";
469                         resp.Cache.SetCacheability (HttpCacheability.NoCache);
470                         resp.ContentType = "text/xml";
471                         resp.AppendHeader ("Content-Disposition", "inline");
472                         resp.AppendHeader ("Content-Type", "application/ms-word");
473                         resp.AppendHeader ("Content-Length", "40");
474                         resp.AppendHeader ("Transfer-Encoding", "compress");
475                         resp.AppendHeader ("My-Custom-Header", "never");
476                         resp.AppendHeader ("My-Custom-Header", "always");
477
478                         Assert.AreEqual ("public", resp.CacheControl, "#A1");
479                         Assert.AreEqual ("application/ms-word", resp.ContentType, "#A2");
480                         Assert.AreEqual (0, f.KnownResponseHeaders.Count, "#A3");
481                         Assert.AreEqual (0, f.UnknownResponseHeaders.Count, "#A4");
482
483                         resp.Flush ();
484
485                         KnownResponseHeader known;
486
487                         Assert.AreEqual (6, f.KnownResponseHeaders.Count, "#B1");
488                         
489                         known = (KnownResponseHeader)f.KnownResponseHeaders ["Content-Length"];
490                         Assert.AreEqual (HttpWorkerRequest.HeaderContentLength, known.Index, "#B2");
491                         Assert.AreEqual ("40", known.Value, "#B3");
492                         
493                         known = (KnownResponseHeader)f.KnownResponseHeaders["Transfer-Encoding"];
494                         Assert.AreEqual (HttpWorkerRequest.HeaderTransferEncoding, known.Index, "#B4");
495                         Assert.AreEqual ("compress", known.Value, "#B5");
496                         
497                         known = (KnownResponseHeader)f.KnownResponseHeaders["Cache-Control"];
498                         Assert.AreEqual (HttpWorkerRequest.HeaderCacheControl, known.Index, "#B6");
499                         Assert.AreEqual ("no-cache", known.Value, "#B7");
500                         
501                         known = (KnownResponseHeader)f.KnownResponseHeaders["Pragma"];
502                         Assert.AreEqual (HttpWorkerRequest.HeaderPragma, known.Index, "#B8");
503                         Assert.AreEqual ("no-cache", known.Value, "#B9");
504                         
505                         known = (KnownResponseHeader)f.KnownResponseHeaders["Expires"];
506                         Assert.AreEqual (HttpWorkerRequest.HeaderExpires, known.Index, "#B10");
507                         Assert.AreEqual ("-1", known.Value, "#B11");
508                         
509                         known = (KnownResponseHeader)f.KnownResponseHeaders["Content-Type"];
510                         Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B12");
511                         Assert.AreEqual ("application/ms-word", known.Value, "#B13");
512
513                         UnknownResponseHeader unknown;
514
515                         Assert.AreEqual (3, f.UnknownResponseHeaders.Count, "#C1");
516
517                         unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["X-AspNet-Version"];
518                         Assert.AreEqual ("X-AspNet-Version", unknown.Name, "#C2");
519                         Assert.AreEqual (Environment.Version.ToString (3), unknown.Value, "#C3");
520
521                         unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["Content-Disposition"];
522                         Assert.AreEqual ("Content-Disposition", unknown.Name, "#C4");
523                         Assert.AreEqual ("inline", unknown.Value, "#C5");
524
525                         ArrayList al = f.UnknownResponseHeaders ["My-Custom-Header"] as ArrayList;
526                         Assert.AreEqual (2, al.Count, "#C6");
527
528                         unknown = (UnknownResponseHeader) al [0];
529                         Assert.AreEqual ("My-Custom-Header", unknown.Name, "#C7");
530                         Assert.AreEqual ("never", unknown.Value, "#C8");
531
532                         unknown = (UnknownResponseHeader) al [1];
533                         Assert.AreEqual ("My-Custom-Header", unknown.Name, "#C9");
534                         Assert.AreEqual ("always", unknown.Value, "#C10");
535                 }
536
537                 [Test] // pull #866
538                 public void WriteHeadersNoCharset ()
539                 {
540                         FakeHttpWorkerRequest2 f;
541                         HttpContext c = Cook (2, out f);
542
543                         HttpResponse resp = c.Response;
544                         resp.ContentType = "text/plain";
545
546                         Assert.AreEqual ("text/plain", resp.ContentType, "#A1");
547
548                         resp.Flush ();
549
550                         KnownResponseHeader known;
551
552                         Assert.LessOrEqual (1, f.KnownResponseHeaders.Count, "#B1");
553
554                         known = (KnownResponseHeader)f.KnownResponseHeaders ["Content-Type"];
555                         Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B2");
556                         Assert.AreEqual ("text/plain", known.Value, "#B3");
557                 }
558
559                 [Test] // pull #866
560                 public void WriteHeadersHasCharset ()
561                 {
562                         FakeHttpWorkerRequest2 f;
563                         HttpContext c = Cook (2, out f);
564
565                         HttpResponse resp = c.Response;
566                         resp.ContentType = "text/plain";
567                         resp.Charset = "big5";
568
569                         Assert.AreEqual ("text/plain", resp.ContentType, "#A1");
570                         Assert.AreEqual ("big5", resp.Charset, "#A2");
571
572                         resp.Flush ();
573
574                         KnownResponseHeader known;
575
576                         Assert.LessOrEqual (1, f.KnownResponseHeaders.Count, "#B1");
577
578                         known = (KnownResponseHeader)f.KnownResponseHeaders ["Content-Type"];
579                         Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B2");
580                         Assert.AreEqual ("text/plain; charset=big5", known.Value, "#B3");
581                 }
582
583                 [Test] // bug #485557
584                 [Category ("NotWorking")] // bug #488702
585                 public void ClearHeaders ()
586                 {
587                         FakeHttpWorkerRequest2 f;
588                         HttpContext c = Cook (2, out f);
589
590                         HttpResponse resp = c.Response;
591                         resp.CacheControl = "public";
592                         resp.Cache.SetCacheability (HttpCacheability.NoCache);
593                         resp.ContentType = "text/xml";
594                         resp.AppendHeader ("Content-Disposition", "inline");
595                         resp.AppendHeader ("Content-Type", "application/ms-word");
596                         resp.AppendHeader ("Content-Length", "40");
597                         resp.AppendHeader ("Transfer-Encoding", "compress");
598                         resp.AppendHeader ("My-Custom-Header", "never");
599                         resp.AppendHeader ("My-Custom-Header", "always");
600                         resp.ClearHeaders ();
601
602                         Assert.AreEqual ("private", resp.CacheControl, "#A1");
603                         Assert.AreEqual ("text/html", resp.ContentType, "#A2");
604                         Assert.AreEqual (0, f.KnownResponseHeaders.Count, "#A3");
605                         Assert.AreEqual (0, f.UnknownResponseHeaders.Count, "#A4");
606
607                         resp.Flush ();
608
609                         KnownResponseHeader known;
610
611                         Assert.AreEqual (3, f.KnownResponseHeaders.Count, "#B1");
612                         
613                         known = (KnownResponseHeader) f.KnownResponseHeaders ["Transfer-Encoding"];
614                         Assert.AreEqual (HttpWorkerRequest.HeaderTransferEncoding, known.Index, "#B2");
615                         Assert.AreEqual ("chunked", known.Value, "#B3");
616                         
617                         known = (KnownResponseHeader) f.KnownResponseHeaders ["Cache-Control"];
618                         Assert.AreEqual (HttpWorkerRequest.HeaderCacheControl, known.Index, "#B4");
619                         Assert.AreEqual ("private", known.Value, "#B5");
620                         
621                         known = (KnownResponseHeader) f.KnownResponseHeaders ["Content-Type"];
622                         Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B6");
623                         Assert.AreEqual ("text/html", known.Value, "#B7");
624
625                         Assert.AreEqual (1, f.UnknownResponseHeaders.Count, "#C1");
626                         UnknownResponseHeader unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["X-AspNet-Version"];
627                         Assert.AreEqual ("X-AspNet-Version", unknown.Name, "#C2");
628                         Assert.AreEqual (Environment.Version.ToString (3), unknown.Value, "#C3");
629                 }
630
631                 [Test]
632                 public void Constructor ()
633                 {
634                         var resp = new HttpResponse (null);
635                         Assert.IsNull (resp.Output, "#A1");
636                 }
637 #if NET_4_0
638                 [Test]
639                 public void RedirectPermanent ()
640                 {
641                         FakeHttpWorkerRequest2 request;
642                         HttpContext context = Cook (1, out request);
643                         AssertExtensions.Throws<ArgumentNullException> (() => {
644                                 context.Response.RedirectPermanent (null);
645                         }, "#A1");
646
647                         AssertExtensions.Throws<ArgumentException> (() => {
648                                 context.Response.RedirectPermanent ("http://invalid\nurl.com");
649                         }, "#A2");
650
651                         AssertExtensions.Throws<ArgumentNullException> (() => {
652                                 context.Response.RedirectPermanent (null, true);
653                         }, "#A3");
654
655                         AssertExtensions.Throws<ArgumentException> (() => {
656                                 context.Response.RedirectPermanent ("http://invalid\nurl.com", true);
657                         }, "#A4");
658                 }
659
660                 [Test]
661                 public void RedirectToRoute ()
662                 {
663                         var resp = new HttpResponse (new StringWriter ());
664                         // Ho, ho, ho!
665                         AssertExtensions.Throws<NullReferenceException> (() => {
666                                 resp.RedirectToRoute ("SomeRoute");
667                         }, "#A1");
668
669                         FakeHttpWorkerRequest2 request;
670                         HttpContext context = Cook (1, out request);
671
672                         // From RouteCollection.GetVirtualPath
673                         AssertExtensions.Throws<ArgumentException> (() => {
674                                 context.Response.RedirectToRoute ("SomeRoute");
675                         }, "#A2");
676
677                         AssertExtensions.Throws<InvalidOperationException> (() => {
678                                 context.Response.RedirectToRoute (new { productId = "1", category = "widgets" });
679                         }, "#A3");
680                 }
681
682                 [Test]
683                 public void RemoveOutputCacheItem ()
684                 {
685                         AssertExtensions.Throws<ArgumentNullException> (() => {
686                                 HttpResponse.RemoveOutputCacheItem (null, "MyProvider");
687                         }, "#A1");
688
689                         AssertExtensions.Throws<ArgumentException> (() => {
690                                 HttpResponse.RemoveOutputCacheItem ("badPath", null);
691                         }, "#A2");
692
693                         Assert.IsNull (OutputCache.Providers, "#A3");
694                         HttpResponse.RemoveOutputCacheItem ("/Path", null);
695
696                         AssertExtensions.Throws<ProviderException> (() => {
697                                 HttpResponse.RemoveOutputCacheItem ("/Path", String.Empty);
698                         }, "#A3");
699
700                         AssertExtensions.Throws<ProviderException> (() => {
701                                 HttpResponse.RemoveOutputCacheItem ("/Path", "MyProvider");
702                         }, "#A4");
703                 }
704
705                 [Test]
706                 public void OutputSetter ()
707                 {
708                         FakeHttpWorkerRequest2 request;
709                         HttpContext context = Cook (1, out request);
710
711                         Assert.IsNotNull (context.Response.Output, "#A1");
712                         context.Response.Output = null;
713                         Assert.IsNull (context.Response.Output, "#A2");
714
715                         // Classy...
716                         AssertExtensions.Throws<NullReferenceException> (() => {
717                                 context.Response.Write ('t');
718                         }, "#A3-1");
719
720                         AssertExtensions.Throws<NullReferenceException> (() => {
721                                 context.Response.Write ((object) 5);
722                         }, "#A3-2");
723
724                         AssertExtensions.Throws<NullReferenceException> (() => {
725                                 context.Response.Write ("string");
726                         }, "#A3-3");
727
728                         AssertExtensions.Throws<NullReferenceException> (() => {
729                                 context.Response.Write (new char [] { '1' }, 0, 1);
730                         }, "#A3-4");
731
732                         AssertExtensions.Throws<NullReferenceException> (() => {
733                                 context.Response.Write ((object) null);
734                         }, "#A3-5");
735                 }
736 #endif
737         }
738
739         [TestFixture]
740         public class HttpResponseOutputStreamTest
741         {
742                 FakeHttpWorkerRequest2 worker;
743                 HttpContext context;
744                 HttpResponse response;
745                 Stream out_stream;
746
747                 [SetUp]
748                 public void Setup ()
749                 {
750                         context = Cook (2, out worker);
751                         response = context.Response;
752                         out_stream = response.OutputStream;
753                 }
754
755                 [TearDown]
756                 public void TearDown ()
757                 {
758                         if (response != null)
759                                 response.Close ();
760                 }
761
762                 [Test]
763                 public void CanRead ()
764                 {
765                         Assert.IsFalse (out_stream.CanRead, "#1");
766                         out_stream.Close ();
767                         Assert.IsFalse (out_stream.CanRead, "#2");
768                 }
769
770                 [Test]
771                 public void CanSeek ()
772                 {
773                         Assert.IsFalse (out_stream.CanSeek, "#1");
774                         out_stream.Close ();
775                         Assert.IsFalse (out_stream.CanSeek, "#2");
776                 }
777
778                 [Test]
779                 public void CanWrite ()
780                 {
781                         Assert.IsTrue (out_stream.CanWrite, "#1");
782                         out_stream.Close ();
783                         Assert.IsTrue (out_stream.CanWrite, "#2");
784                 }
785
786                 [Test]
787                 public void Flush ()
788                 {
789                         byte [] buffer = Encoding.UTF8.GetBytes ("mono");
790                         out_stream.Write (buffer, 0, buffer.Length);
791                         out_stream.Flush ();
792                         Assert.AreEqual (0, worker.data_len);
793                 }
794
795                 [Test]
796                 public void Length ()
797                 {
798                         try {
799                                 long len = out_stream.Length;
800                                 Assert.Fail ("#1:" + len);
801                         } catch (NotSupportedException ex) {
802                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
803                                 Assert.IsNull (ex.InnerException, "#3");
804                                 Assert.IsNotNull (ex.Message, "#4");
805                         }
806                 }
807
808                 [Test]
809                 public void Position ()
810                 {
811                         try {
812                                 long pos = out_stream.Position;
813                                 Assert.Fail ("#A1:" + pos);
814                         } catch (NotSupportedException ex) {
815                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
816                                 Assert.IsNull (ex.InnerException, "#A3");
817                                 Assert.IsNotNull (ex.Message, "#A4");
818                         }
819
820                         try {
821                                 out_stream.Position = 0;
822                                 Assert.Fail ("#B1");
823                         } catch (NotSupportedException ex) {
824                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
825                                 Assert.IsNull (ex.InnerException, "#B3");
826                                 Assert.IsNotNull (ex.Message, "#B4");
827                         }
828                 }
829
830                 [Test]
831                 public void Read ()
832                 {
833                         byte [] buffer = new byte [5];
834
835                         try {
836                                 out_stream.Read (buffer, 0, buffer.Length);
837                                 Assert.Fail ("#1");
838                         } catch (NotSupportedException ex) {
839                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
840                                 Assert.IsNull (ex.InnerException, "#3");
841                                 Assert.IsNotNull (ex.Message, "#4");
842                         }
843                 }
844
845                 [Test]
846                 public void Seek ()
847                 {
848                         try {
849                                 out_stream.Seek (5, SeekOrigin.Begin);
850                                 Assert.Fail ("#1");
851                         } catch (NotSupportedException ex) {
852                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
853                                 Assert.IsNull (ex.InnerException, "#3");
854                                 Assert.IsNotNull (ex.Message, "#4");
855                         }
856                 }
857
858                 [Test]
859                 public void SetLength ()
860                 {
861                         try {
862                                 out_stream.SetLength (5L);
863                                 Assert.Fail ("#1");
864                         } catch (NotSupportedException ex) {
865                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
866                                 Assert.IsNull (ex.InnerException, "#3");
867                                 Assert.IsNotNull (ex.Message, "#4");
868                         }
869                 }
870
871                 [Test]
872                 public void Write ()
873                 {
874                         byte [] buffer;
875
876                         buffer = Encoding.UTF8.GetBytes ("mono");
877                         out_stream.Write (buffer, 0, buffer.Length);
878                         buffer = Encoding.UTF8.GetBytes ("just rocks!!");
879                         out_stream.Write (buffer, 5, 6);
880                         out_stream.Write (buffer, 0, 4);
881                         Assert.IsFalse (worker.OutputProduced, "#1");
882                         response.Flush ();
883                         Assert.IsTrue (worker.OutputProduced, "#2");
884
885                         string output = Encoding.UTF8.GetString (worker.data);
886                         Assert.AreEqual ("e\r\nmonorocks!just\r\n", output);
887                 }
888
889                 [Test]
890                 public void Write_Buffer_Null ()
891                 {
892                         try {
893                                 out_stream.Write ((byte []) null, 0, 0);
894                                 Assert.Fail ("#1");
895                         } catch (ArgumentNullException ex) {
896                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
897                                 Assert.IsNull (ex.InnerException, "#3");
898                                 Assert.IsNotNull (ex.Message, "#4");
899                                 Assert.AreEqual ("buffer", ex.ParamName, "#5");
900                         }
901                 }
902
903                 [Test]
904                 public void Write_Count_Negative ()
905                 {
906                         byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
907
908                         // offset < 0
909                         try {
910                                 out_stream.Write (buffer, 1, -1);
911                                 Assert.Fail ("#1");
912                         } catch (ArgumentOutOfRangeException ex) {
913                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
914                                 Assert.IsNull (ex.InnerException, "#3");
915                                 Assert.IsNotNull (ex.Message, "#4");
916                                 Assert.AreEqual ("count", ex.ParamName, "#5");
917                         }
918                 }
919
920                 [Test]
921                 public void Write_Count_Overflow ()
922                 {
923                         byte [] buffer;
924
925                         buffer = Encoding.UTF8.GetBytes ("Mono");
926                         out_stream.Write (buffer, 0, buffer.Length + 5);
927                         buffer = Encoding.UTF8.GetBytes ("Just Rocks!!");
928                         out_stream.Write (buffer, 5, buffer.Length - 2);
929                         response.Flush ();
930
931                         string output = Encoding.UTF8.GetString (worker.data);
932                         Assert.AreEqual ("b\r\nMonoRocks!!\r\n", output);
933                 }
934
935                 [Test]
936                 public void Write_Offset_Negative ()
937                 {
938                         byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
939
940                         // offset < 0
941                         try {
942                                 out_stream.Write (buffer, -1, 0);
943                                 Assert.Fail ("#1");
944                         } catch (ArgumentOutOfRangeException ex) {
945                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
946                                 Assert.IsNull (ex.InnerException, "#3");
947                                 Assert.IsNotNull (ex.Message, "#4");
948                                 Assert.AreEqual ("offset", ex.ParamName, "#5");
949                         }
950                 }
951
952                 [Test]
953                 public void Write_Offset_Overflow ()
954                 {
955                         byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
956
957                         // offset == buffer length
958                         try {
959                                 out_stream.Write (buffer, buffer.Length, 0);
960                                 Assert.Fail ("#A1");
961                         } catch (ArgumentOutOfRangeException ex) {
962                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
963                                 Assert.IsNull (ex.InnerException, "#A3");
964                                 Assert.IsNotNull (ex.Message, "#A4");
965                                 Assert.AreEqual ("offset", ex.ParamName, "#A5");
966                         }
967
968                         // offset > buffer length
969                         try {
970                                 out_stream.Write (buffer, buffer.Length + 1, 0);
971                                 Assert.Fail ("#B1");
972                         } catch (ArgumentOutOfRangeException ex) {
973                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#B2");
974                                 Assert.IsNull (ex.InnerException, "#B3");
975                                 Assert.IsNotNull (ex.Message, "#B4");
976                                 Assert.AreEqual ("offset", ex.ParamName, "#B5");
977                         }
978
979                         response.Flush ();
980                         Assert.AreEqual (0, worker.data_len);
981                 }
982
983                 [Test]
984                 public void Write_Stream_Closed ()
985                 {
986                         byte [] buffer = Encoding.UTF8.GetBytes ("mono");
987                         out_stream.Close ();
988                         out_stream.Write (buffer, 0, buffer.Length);
989                         response.Flush ();
990
991                         string output = Encoding.UTF8.GetString (worker.data);
992                         Assert.AreEqual ("4\r\nmono\r\n", output);
993                 }
994
995                 HttpContext Cook (int re, out FakeHttpWorkerRequest2 f)
996                 {
997                         f = new FakeHttpWorkerRequest2 (re);
998                         return new HttpContext (f);
999                 }
1000         }
1001 }