Added tests for Task.WhenAll w/ empty list
[mono.git] / mcs / class / System.ServiceModel.Web / Test / System.ServiceModel.Description / WebHttpBehaviorTest.cs
1 using System;
2 using System.IO;
3 using System.Runtime.Serialization;
4 using System.ServiceModel;
5 using System.ServiceModel.Channels;
6 using System.ServiceModel.Description;
7 using System.ServiceModel.Dispatcher;
8 using System.ServiceModel.Web;
9 using System.Text;
10 using NUnit.Framework;
11
12 namespace MonoTests.System.ServiceModel.Description
13 {
14         public class WebHttpBehaviorExt : WebHttpBehavior
15         {
16                 public IClientMessageFormatter DoGetReplyClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
17                 {
18                         return GetReplyClientFormatter (operationDescription, endpoint);
19                 }
20
21                 public IClientMessageFormatter DoGetRequestClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
22                 {
23                         return GetRequestClientFormatter (operationDescription, endpoint);
24                 }
25
26                 public IDispatchMessageFormatter DoGetReplyDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
27                 {
28                         return GetReplyDispatchFormatter (operationDescription, endpoint);
29                 }
30
31                 public IDispatchMessageFormatter DoGetRequestDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
32                 {
33                         return GetRequestDispatchFormatter (operationDescription, endpoint);
34                 }
35
36                 public event Action<ServiceEndpoint, ClientRuntime> ApplyClientBehaviorInvoked;
37
38                 public override void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime client)
39                 {
40                         base.ApplyClientBehavior (endpoint, client);
41                         if (ApplyClientBehaviorInvoked != null)
42                                 ApplyClientBehaviorInvoked (endpoint, client);
43                 }
44         }
45
46         [TestFixture]
47         public class WebHttpBehaviorTest
48         {
49                 ServiceEndpoint CreateEndpoint ()
50                 {
51                         return new ServiceEndpoint (ContractDescription.GetContract (typeof (IMyService)), new WebHttpBinding (),
52                                                     new EndpointAddress ("http://localhost:37564"));
53                 }
54
55                 [Test]
56                 public void DefaultValues ()
57                 {
58                         var b = new WebHttpBehavior ();
59                         Assert.AreEqual (WebMessageBodyStyle.Bare, b.DefaultBodyStyle, "#1");
60                         Assert.AreEqual (WebMessageFormat.Xml, b.DefaultOutgoingRequestFormat, "#2");
61                         Assert.AreEqual (WebMessageFormat.Xml, b.DefaultOutgoingResponseFormat, "#3");
62 #if NET_4_0
63                         Assert.IsFalse (b.AutomaticFormatSelectionEnabled, "#11");
64                         Assert.IsFalse (b.FaultExceptionEnabled, "#12");
65                         Assert.IsFalse (b.HelpEnabled, "#13");
66 #endif
67                 }
68
69                 [Test]
70                 public void AddBiningParameters ()
71                 {
72                         var se = CreateEndpoint ();
73                         var b = new WebHttpBehavior ();
74                         var pl = new BindingParameterCollection ();
75                         b.AddBindingParameters (se, pl);
76                         Assert.AreEqual (0, pl.Count, "#1");
77                 }
78
79                 [Test]
80                 public void ApplyDispatchBehavior ()
81                 {
82                         var se = CreateEndpoint ();
83                         var od = se.Contract.Operations [0];
84                         // in .NET 3.5 it adds "OperationSelectorBehavior"
85                         int initCB = ContractDescription.GetContract (typeof (IMyService)).Behaviors.Count;
86                         // in .NET 3.5 it adds
87                         // - OperationInvokeBehavior, 
88                         // - OperationBehaviorAttribute, 
89                         // - DataContractSerializerOperationBehavior and 
90                         // - DataContractSerializerOperationGenerator
91                         int initOB = od.Behaviors.Count;
92                         // Assert.AreEqual (1, initCB, "#0-1");
93                         // Assert.AreEqual (4, initOB, "#0-2");
94
95                         var b = new WebHttpBehavior ();
96                         se.Behaviors.Add (b);
97                         var ed = new EndpointDispatcher (se.Address, se.Contract.Name, se.Contract.Namespace);
98                         IChannelListener l = new WebHttpBinding ().BuildChannelListener<IReplyChannel> (new BindingParameterCollection ());
99                         var cd = new ChannelDispatcher (l);
100                         cd.Endpoints.Add (ed); // without it this test results in NRE (it blindly adds IErrorHandler).
101                         Assert.AreEqual (0, cd.ErrorHandlers.Count, "#1-1");
102                         Assert.IsNull (ed.DispatchRuntime.OperationSelector, "#1-2");
103                         Assert.AreEqual (1, se.Behaviors.Count, "#1-3-1");
104                         Assert.AreEqual (initCB, se.Contract.Behaviors.Count, "#1-3-2");
105                         Assert.AreEqual (initOB, od.Behaviors.Count, "#1-3-3");
106
107                         Assert.IsTrue (ed.AddressFilter is EndpointAddressMessageFilter, "#1-4");
108
109                         b.ApplyDispatchBehavior (se, ed);
110                         // FIXME: implement and enable it later
111                         //Assert.AreEqual (1, cd.ErrorHandlers.Count, "#2-1");
112                         Assert.AreEqual (typeof (WebHttpDispatchOperationSelector),
113                                          ed.DispatchRuntime.OperationSelector.GetType (), "#2-2");
114                         Assert.AreEqual (1, se.Behaviors.Count, "#3-1");
115                         Assert.AreEqual (initCB, se.Contract.Behaviors.Count, "#3-2");
116                         Assert.AreEqual (initOB, od.Behaviors.Count, "#3-3");
117                         // ... i.e. nothing is added.
118
119                         Assert.IsTrue (ed.AddressFilter is PrefixEndpointAddressMessageFilter, "#3-4");
120
121                         Assert.AreEqual (0, ed.DispatchRuntime.Operations.Count, "#4-0"); // hmm... really?
122                 }
123
124                 [Test]
125                 public void GetMessageFormatters ()
126                 {
127                         var se = CreateEndpoint ();
128                         var od = se.Contract.Operations [0];
129                         var b = new WebHttpBehaviorExt ();
130                         Assert.IsNotNull (b.DoGetRequestClientFormatter (od, se), "#1");
131                         Assert.IsNotNull (b.DoGetReplyClientFormatter (od, se), "#2");
132                         Assert.IsNotNull (b.DoGetRequestDispatchFormatter (od, se), "#3");
133                         Assert.IsNotNull (b.DoGetReplyDispatchFormatter (od, se), "#4");
134                 }
135
136                 [Test]
137                 public void RequestClientFormatter ()
138                 {
139                         var se = CreateEndpoint ();
140                         var od = se.Contract.Operations [0];
141                         var b = new WebHttpBehaviorExt ();
142                         var rcf = b.DoGetRequestClientFormatter (od, se);
143                         var msg = rcf.SerializeRequest (MessageVersion.None, new object [] {"foo"});
144                         var hp = msg.Properties [HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
145                         Assert.IsNotNull (hp, "#1");
146                         Assert.IsTrue (msg.IsEmpty, "#2");
147                         Assert.AreEqual (String.Empty, hp.QueryString, "#3");
148                         var mb = msg.CreateBufferedCopy (1000);
149                         try {
150                                 rcf.DeserializeReply (mb.CreateMessage (), new object [0]);
151                                 Assert.Fail ("It should not support reply deserialization");
152                         } catch (NotSupportedException) {
153                         }
154                 }
155
156                 [Test]
157                 public void RequestClientFormatter2 ()
158                 {
159                         var se = CreateEndpoint ();
160                         var od = se.Contract.Operations [0];
161                         var b = new WebHttpBehaviorExt ();
162                         IClientMessageFormatter rcf = null;
163                         b.ApplyClientBehaviorInvoked += delegate (ServiceEndpoint e, ClientRuntime cr) {
164                                 rcf = cr.Operations [0].Formatter;
165                         };
166                         se.Behaviors.Add (b);
167                         var ch = new WebChannelFactory<IMyServiceClient> (se).CreateChannel ();
168                         var msg = rcf.SerializeRequest (MessageVersion.None, new object [] {"foo"});
169                         var hp = msg.Properties [HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
170                         Assert.IsNotNull (hp, "#1");
171                         Assert.IsTrue (msg.IsEmpty, "#2");
172                         Assert.AreEqual (String.Empty, hp.QueryString, "#3");
173                         //var mb = msg.CreateBufferedCopy (1000);
174
175                         // TODO: test DeserializeReply too (it is supported unlike above).
176                 }
177
178                 [ServiceContract]
179                 public interface IMyService
180                 {
181                         [OperationContract]
182                         [WebGet]
183                         string Echo (string input);
184                 }
185
186                 public interface IMyServiceClient : IMyService, IClientChannel
187                 {
188                 }
189
190                 public class MyService: IMyService
191                 {
192                         [OperationBehavior]
193                         public string Echo (string input)
194                         {
195                                 return input;
196                         }
197                 }
198                 
199                 [Test]
200                 public void TestWebGetExists()
201                 {
202                         ContractDescription cd = ContractDescription.GetContract (typeof(IMyService), typeof (MyService));
203                         OperationDescription od = cd.Operations[0];
204                         Assert.IsTrue (od.Behaviors.Contains (typeof (WebGetAttribute)), "Operation is recognized as WebGet");
205                 }
206
207                 [Test]
208                 public void MessageFormatterSupportsRaw ()
209                 {
210                         // serializing reply
211                         var ms = new MemoryStream ();
212                         var bytes = new byte [] {0, 1, 2, 0xFF};
213                         ms.Write (bytes, 0, bytes.Length);
214                         ms.Position = 0;
215                         var cd = ContractDescription.GetContract (typeof (ITestService));
216                         var od = cd.Operations [0];
217                         var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:37564/"));
218                         var formatter = new WebHttpBehaviorExt ().DoGetReplyDispatchFormatter (od, se);
219
220                         var msg = formatter.SerializeReply (MessageVersion.None, null, ms);
221                         var wp = msg.Properties ["WebBodyFormatMessageProperty"] as WebBodyFormatMessageProperty;
222                         Assert.IsNotNull (wp, "#1");
223                         Assert.AreEqual (WebContentFormat.Raw, wp.Format, "#2");
224
225                         var wmebe = new WebMessageEncodingBindingElement ();
226                         var wme = wmebe.CreateMessageEncoderFactory ().Encoder;
227                         var ms2 = new MemoryStream ();
228                         wme.WriteMessage (msg, ms2);
229                         Assert.AreEqual (bytes, ms2.ToArray (), "#3");
230                 }
231
232                 [Test]
233                 public void MessageFormatterSupportsRaw2 ()
234                 {
235                         // deserializing request
236                         var ms = new MemoryStream ();
237                         ms.Write (new byte [] {0, 1, 2, 0xFF}, 0, 4);
238                         ms.Position = 0;
239                         var cd = ContractDescription.GetContract (typeof (ITestService));
240                         var od = cd.Operations [0];
241                         var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
242                         var wmebe = new WebMessageEncodingBindingElement ();
243                         var wme = wmebe.CreateMessageEncoderFactory ().Encoder;
244                         var msg = wme.ReadMessage (ms, 100, null); // "application/xml" causes error.
245                         var formatter = new WebHttpBehaviorExt ().DoGetRequestDispatchFormatter (od, se);
246                         object [] pars = new object [1];
247                         formatter.DeserializeRequest (msg, pars);
248                         Assert.IsTrue (pars [0] is Stream, "ret");
249                 }
250
251                 [ServiceContract]
252                 public interface IMultipleParametersGet
253                 {
254                         [OperationContract]
255                         [WebGet (UriTemplate = "get")]
256                         void Get (string p1, string p2);
257                 }
258
259                 [ServiceContract]
260                 public interface IMultipleParameters
261                 {
262                         [OperationContract]
263                         [WebInvoke (UriTemplate = "posturi?p1={p1}&p2={p2}")]
264                         string PostUri (string p1, string p2);
265
266                         [OperationContract]
267                         [WebInvoke (UriTemplate = "postone?p1={p1}")]
268                         string PostOne (string p1, string p2);
269
270                         [OperationContract]
271                         [WebInvoke (UriTemplate = "postwrapped", BodyStyle=WebMessageBodyStyle.WrappedRequest)]
272                         string PostWrapped (string p1, string p2);
273
274                         [OperationContract]
275                         [WebInvoke (UriTemplate = "out?p1={p1}&p2={p2}", BodyStyle=WebMessageBodyStyle.WrappedResponse)]
276                         void PostOut (string p1, string p2, out string ret);
277                 }
278
279                 [Test]
280                 public void MultipleParameters ()
281                 {
282                         var behavior = new WebHttpBehaviorExt ();
283                         var cd = ContractDescription.GetContract (typeof (IMultipleParameters));
284                         var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
285                         behavior.Validate (se);
286
287                         foreach (var od in cd.Operations)
288                                 behavior.DoGetRequestClientFormatter (od, se);
289                 }
290
291                 [Test]
292                 [Category ("NotWorking")]
293                 public void MultipleParameters2 ()
294                 {
295                         var behavior = new WebHttpBehaviorExt ();
296                         var cd = ContractDescription.GetContract (typeof (IMultipleParametersGet));
297                         var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
298                         behavior.Validate (se);
299
300                         try {
301                                 foreach (var od in cd.Operations)
302                                         behavior.DoGetRequestClientFormatter (od, se);
303                                 Assert.Fail ("Should result in invalid operation");
304                         } catch (InvalidOperationException) {
305                         }
306                 }
307         }
308
309         [ServiceContract]
310         public interface ITestService
311         {
312                 [OperationContract]
313                 Stream Receive (Stream input);
314         }
315 }