Merge pull request #2720 from mono/fix-39325
[mono.git] / mcs / class / System.ServiceModel.Web / Test / System.ServiceModel.Web / WebOperationContextTest.cs
1 //
2 // WebOperationContextTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2009 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 using System;
29 using System.IO;
30 using System.Runtime.Serialization;
31 using System.ServiceModel;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Description;
34 #if !MOBILE
35 using System.ServiceModel.Syndication;
36 #endif
37 using System.ServiceModel.Web;
38 using System.Xml;
39 using NUnit.Framework;
40
41 using CategoryAttribute = NUnit.Framework.CategoryAttribute;
42
43 using MonoTests.Helpers;
44
45 namespace MonoTests.System.ServiceModel.Web
46 {
47         [TestFixture]
48         public class WebOperationContextTest
49         {
50 // MonoTouch does not support dynamic proxy code generation.
51 #if !MONOTOUCH
52                 [Test]
53 #endif
54                 public void Current ()
55                 {
56 #if !MOBILE
57                         Assert.IsNull (WebOperationContext.Current, "#1");
58 #endif
59                         var binding = new WebHttpBinding ();
60                         var address = new EndpointAddress ("http://localhost:" + NetworkHelpers.FindFreePort ());
61                         var ch = (IContextChannel) WebChannelFactory<IHogeService>.CreateChannel (binding, address);
62                         using (var ocs = new OperationContextScope (ch)) {
63 #if !MOBILE
64                                 Assert.IsNotNull (WebOperationContext.Current, "#2");
65                                 Assert.IsNotNull (WebOperationContext.Current.OutgoingRequest, "#3");
66                                 Assert.IsNotNull (WebOperationContext.Current.IncomingRequest, "#4");
67                                 Assert.IsNotNull (WebOperationContext.Current.IncomingResponse, "#5");
68                                 Assert.IsNotNull (WebOperationContext.Current.OutgoingResponse, "#6"); // pointless though.
69
70                                 Assert.IsNotNull (WebOperationContext.Current.OutgoingRequest.Headers, "#7");
71                                 Assert.AreEqual (0, WebOperationContext.Current.OutgoingRequest.Headers.Count, "#8");
72 #endif
73                         }
74                         ch.Close ();
75                 }
76
77 #if !MOBILE
78                 [Test]
79                 public void CreateAtom10Response ()
80                 {
81                         CreateResponseTest (ch => ch.Join ("foo", "bar"));
82                 }
83
84                 [Test]
85                 public void CreateJsonResponse ()
86                 {
87                         CreateResponseTest (ch => ch.TestJson ("foo", "bar"));
88                 }
89
90                 [Test]
91                 [Category ("NotWorking")] // .NET rejects HogeData as an unkown  type.
92                 public void CreateJsonResponse2 ()
93                 {
94                         CreateResponseTest (ch => ch.TestJson2 ("foo", "bar"));
95                 }
96
97                 [Test]
98                 public void CreateJsonResponse3 ()
99                 {
100                         CreateResponseTest (ch => ch.TestJson3 ("foo", "bar"));
101                 }
102
103                 void CreateResponseTest (Action<IHogeService> a)
104                 {
105                         var host = new WebServiceHost (typeof (HogeService));
106                         var port = NetworkHelpers.FindFreePort ();
107                         host.AddServiceEndpoint (typeof (IHogeService), new WebHttpBinding (), new Uri ("http://localhost:" + port));
108                         host.Description.Behaviors.Find<ServiceDebugBehavior> ().IncludeExceptionDetailInFaults = true;
109                         host.Open ();
110                         try {
111                                 using (var cf = new ChannelFactory<IHogeService> (new WebHttpBinding (), new EndpointAddress ("http://localhost:" + port))) {
112                                         cf.Endpoint.Behaviors.Add (new WebHttpBehavior ());
113                                         cf.Open ();
114                                         var ch = cf.CreateChannel ();
115                                         a (ch);
116                                 }
117                         } finally {
118                                 host.Close ();
119                         }
120                 }
121 #endif
122         }
123
124         [ServiceContract]
125         public interface IHogeService
126         {
127                 [WebGet]
128                 [OperationContract]
129                 string Join (string s1, string s2);
130
131                 [WebGet (ResponseFormat = WebMessageFormat.Json)]
132                 [OperationContract]
133                 string TestJson (string s1, string s2);
134
135                 [WebGet (ResponseFormat = WebMessageFormat.Json)]
136                 [OperationContract]
137                 string TestJson2 (string s1, string s2);
138
139                 [WebGet (ResponseFormat = WebMessageFormat.Json)]
140                 [OperationContract]
141                 string TestJson3 (string s1, string s2);
142         }
143
144 #if !MOBILE
145         public class HogeService : IHogeService
146         {
147                 static XmlWriterSettings settings = new XmlWriterSettings () { OmitXmlDeclaration = true };
148
149                 static string GetXml (Message msg)
150                 {
151                         var sw = new StringWriter ();
152                         using (var xw = XmlWriter.Create (sw, settings))
153                                 msg.WriteMessage (xw);
154                         return sw.ToString ();
155                 }
156
157                 public string Join (string s1, string s2)
158                 {
159                         try {
160                                 // ServiceDocument
161                                 var woc = WebOperationContext.Current;
162                                 var sd = new ServiceDocument ();
163                                 var msg = woc.CreateAtom10Response (sd);
164                                 var xml = "<service xmlns:a10='http://www.w3.org/2005/Atom' xmlns='http://www.w3.org/2007/app' />";
165                         
166                                 Assert.AreEqual (xml.Replace ('\'', '"'), GetXml (msg), "#1");
167                                 // Feed
168                                 var uid = new UniqueId ().ToString ();
169                                 var updatedTime = DateTime.SpecifyKind (new DateTime (2011, 4, 8, 11, 46, 12), DateTimeKind.Utc);
170                                 var feed = new SyndicationFeed () { Id = uid, LastUpdatedTime = updatedTime };
171                                 msg = woc.CreateAtom10Response (feed);
172                                 xml = @"<feed xmlns='http://www.w3.org/2005/Atom'><title type='text'></title><id>" + uid + @"</id><updated>2011-04-08T11:46:12Z</updated></feed>";
173                                 Assert.AreEqual (xml.Replace ('\'', '"'), GetXml (msg), "#2");
174
175                                 // Item
176                                 var item = new SyndicationItem () { Id = uid, LastUpdatedTime = updatedTime };
177                                 msg = woc.CreateAtom10Response (item);
178                                 xml = @"<entry xmlns='http://www.w3.org/2005/Atom'><id>" + uid + "</id><title type='text'></title><updated>2011-04-08T11:46:12Z</updated></entry>";
179                                 Assert.AreEqual (xml.Replace ('\'', '"'), GetXml (msg), "#2");
180                         } catch (Exception ex) {
181                                 Console.Error.WriteLine (ex);
182                                 throw;
183                         }
184                         return s1 + s2;
185                 }
186
187                 public string TestJson (string s1, string s2)
188                 {
189                         try {
190                                 var woc = WebOperationContext.Current;
191                                 var msg = woc.CreateJsonResponse<HogeData> (new HogeData () {Foo = "foo", Bar = "bar" });
192                                 Assert.AreEqual ("<root type=\"object\"><Bar>bar</Bar><Foo>foo</Foo></root>", GetXml (msg), "#1");
193                         } catch (Exception ex) {
194                                 Console.Error.WriteLine (ex);
195                                 throw;
196                         }
197                         return s1 + s2;
198                 }
199                 
200                 public string TestJson2 (string s1, string s2)
201                 {
202                         try {
203                                 var woc = WebOperationContext.Current;
204                                 // passed <object> -> unknown type error
205                                 var msg = woc.CreateJsonResponse<object> (new HogeData () {Foo = "foo", Bar = "bar" });
206                                 Assert.AreEqual ("<root type=\"object\"><Bar>bar</Bar><Foo>foo</Foo></root>", GetXml (msg), "#1");
207
208                                 Assert.Fail ("Test2 server should fail");
209                         } catch (SerializationException ex) {
210                         } catch (Exception ex) {
211                                 Console.Error.WriteLine (ex);
212                                 throw;
213                         }
214                         return s1 + s2;
215                 }
216                 
217                 public string TestJson3 (string s1, string s2)
218                 {
219                         try {
220                                 var woc = WebOperationContext.Current;
221                                 var msg = woc.CreateJsonResponse<HogeData2> (new HogeData2 () {Foo = "foo", Bar = "bar" });
222                                 Assert.AreEqual ("<root type=\"object\"><Bar>bar</Bar><Foo>foo</Foo></root>", GetXml (msg), "#1");
223                         } catch (Exception ex) {
224                                 Console.Error.WriteLine (ex);
225                                 throw;
226                         }
227                         return s1 + s2;
228                 }
229         }
230
231         [DataContract]
232         public class HogeData
233         {
234                 [DataMember]
235                 public string Foo { get; set; }
236                 [DataMember]
237                 public string Bar { get; set; }
238         }
239
240         // non-contract
241         public class HogeData2
242         {
243                 public string Foo { get; set; }
244                 public string Bar { get; set; }
245         }
246 #endif
247 }