Merge pull request #1804 from esdrubal/processmodule
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Channels / HttpTransportBindingElementTest.cs
1 //
2 // HttpTransportBindingElementTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@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 using System;
29 using System.Collections.ObjectModel;
30 using System.IO;
31 using System.Net;
32 using System.Net.Security;
33 using System.Reflection;
34 using System.ServiceModel;
35 using System.ServiceModel.Channels;
36 using System.ServiceModel.Description;
37 using System.Threading;
38 using System.Xml;
39 using NUnit.Framework;
40
41 using MonoTests.Helpers;
42
43 #if NET_4_0
44 using System.Security.Authentication.ExtendedProtection;
45 #endif
46
47 namespace MonoTests.System.ServiceModel.Channels
48 {
49         [TestFixture]
50         public class HttpTransportBindingElementTest
51         {
52                 static BindingParameterCollection empty_params =
53                         new BindingParameterCollection ();
54
55                 [Test]
56                 public void DefaultValues ()
57                 {
58                         HttpTransportBindingElement be =
59                                 new HttpTransportBindingElement ();
60                         Assert.AreEqual (false, be.AllowCookies, "#1");
61                         Assert.AreEqual (AuthenticationSchemes.Anonymous,
62                                 be.AuthenticationScheme, "#2");
63                         Assert.AreEqual (false, be.BypassProxyOnLocal, "#3");
64                         Assert.AreEqual (default (HostNameComparisonMode),
65                                 be.HostNameComparisonMode, "#4");
66                         Assert.AreEqual (0x10000, be.MaxBufferSize, "#6");
67                         Assert.IsNull (be.ProxyAddress, "#7");
68                         Assert.AreEqual (AuthenticationSchemes.Anonymous,
69                                 be.ProxyAuthenticationScheme, "#8");
70                         Assert.AreEqual (String.Empty, be.Realm, "#9");
71                         Assert.AreEqual ("http", be.Scheme, "#10");
72                         Assert.AreEqual (default (TransferMode),
73                                 be.TransferMode, "#11");
74                         Assert.AreEqual (false,
75                                 be.UnsafeConnectionNtlmAuthentication, "#12");
76                         Assert.AreEqual (true, be.UseDefaultWebProxy, "#13");
77                 }
78
79                 [Test]
80                 public void CanBuildChannelFactory ()
81                 {
82                         HttpTransportBindingElement be =
83                                 new HttpTransportBindingElement ();
84                         BindingContext ctx = new BindingContext (
85                                 new CustomBinding (), empty_params);
86                         Assert.IsTrue (be.CanBuildChannelFactory<IRequestChannel> (ctx), "#1");
87                         Assert.IsFalse (be.CanBuildChannelFactory<IInputChannel> (ctx), "#2");
88                         Assert.IsFalse (be.CanBuildChannelFactory<IReplyChannel> (ctx), "#3");
89                         Assert.IsFalse (be.CanBuildChannelFactory<IOutputChannel> (ctx), "#4");
90                         // seems like it does not support session channels by itself ?
91                         Assert.IsFalse (be.CanBuildChannelFactory<IRequestSessionChannel> (ctx), "#5");
92                         Assert.IsFalse (be.CanBuildChannelFactory<IInputSessionChannel> (ctx), "#6");
93                         Assert.IsFalse (be.CanBuildChannelFactory<IReplySessionChannel> (ctx), "#7");
94                         Assert.IsFalse (be.CanBuildChannelFactory<IOutputSessionChannel> (ctx), "#8");
95
96                         // IServiceChannel is not supported
97                         Assert.IsFalse (be.CanBuildChannelListener<IServiceChannel> (ctx), "#9");
98                 }
99
100                 [Test]
101                 public void CanBuildChannelListener ()
102                 {
103                         HttpTransportBindingElement be =
104                                 new HttpTransportBindingElement ();
105                         BindingContext ctx = new BindingContext (
106                                 new CustomBinding (), empty_params);
107                         Assert.IsTrue (be.CanBuildChannelListener<IReplyChannel> (ctx), "#1");
108                         Assert.IsFalse (be.CanBuildChannelListener<IOutputChannel> (ctx), "#2");
109                         Assert.IsFalse (be.CanBuildChannelListener<IRequestChannel> (ctx), "#3");
110                         Assert.IsFalse (be.CanBuildChannelListener<IInputChannel> (ctx), "#4");
111                         // seems like it does not support session channels by itself ?
112                         Assert.IsFalse (be.CanBuildChannelListener<IReplySessionChannel> (ctx), "#5");
113                         Assert.IsFalse (be.CanBuildChannelListener<IOutputSessionChannel> (ctx), "#6");
114                         Assert.IsFalse (be.CanBuildChannelListener<IRequestSessionChannel> (ctx), "#7");
115                         Assert.IsFalse (be.CanBuildChannelListener<IInputSessionChannel> (ctx), "#8");
116
117                         // IServiceChannel is not supported
118                         Assert.IsFalse (be.CanBuildChannelListener<IServiceChannel> (ctx), "#9");
119                 }
120
121                 [Test]
122                 public void BuildChannelFactory ()
123                 {
124                         BindingContext ctx = new BindingContext (
125                                 new CustomBinding (
126                                         new HttpTransportBindingElement ()),
127                                 empty_params);
128                         // returns HttpChannelFactory
129                         IChannelFactory<IRequestChannel> f =
130                                 ctx.BuildInnerChannelFactory<IRequestChannel> ();
131                         f.Open (); // required
132                         IChannel c = f.CreateChannel (new EndpointAddress (
133                                 "http://www.mono-project.com"));
134                 }
135
136                 [Test]
137                 [ExpectedException (typeof (InvalidOperationException))]
138                 public void CreateChannelWithoutOpen ()
139                 {
140                         BindingContext ctx = new BindingContext (
141                                 new CustomBinding (
142                                         new HttpTransportBindingElement ()),
143                                 empty_params);
144                         // returns HttpChannelFactory
145                         IChannelFactory<IRequestChannel> f =
146                                 ctx.BuildInnerChannelFactory<IRequestChannel> ();
147                         IChannel c = f.CreateChannel (new EndpointAddress (
148                                 "http://www.mono-project.com"));
149                 }
150
151                 [Test]
152                 public void BuildChannelFactoryTwoHttp ()
153                 {
154                         BindingContext ctx = new BindingContext (
155                                 new CustomBinding (
156                                         new HttpTransportBindingElement (),
157                                         new HttpTransportBindingElement ()),
158                                 empty_params);
159                         ctx.BuildInnerChannelFactory<IRequestChannel> ();
160                 }
161
162                 [Test]
163                 public void BuildChannelFactoryHttpThenMessage ()
164                 {
165                         BindingContext ctx = new BindingContext (
166                                 new CustomBinding (
167                                         new HttpTransportBindingElement (),
168                                         new BinaryMessageEncodingBindingElement ()),
169                                 empty_params);
170                         IChannelFactory<IRequestChannel> cf =
171                                 ctx.BuildInnerChannelFactory<IRequestChannel> ();
172                         cf.Open ();
173                 }
174
175                 [Test]
176                 // with July CTP it still works ...
177                 public void BuildChannelFactoryHttpNoMessage ()
178                 {
179                         BindingContext ctx = new BindingContext (
180                                 new CustomBinding (
181                                         new HttpTransportBindingElement ()),
182                                 empty_params);
183                         IChannelFactory<IRequestChannel> cf =
184                                 ctx.BuildInnerChannelFactory<IRequestChannel> ();
185                         cf.Open ();
186                 }
187
188                 [Test]
189                 public void BuildChannelFactoryIgnoresRemaining ()
190                 {
191                         BindingContext ctx = new BindingContext (
192                                 new CustomBinding (
193                                         new HttpTransportBindingElement (),
194                                         new InvalidBindingElement ()),
195                                 empty_params);
196                         ctx.BuildInnerChannelFactory<IRequestChannel> ();
197                 }
198
199                 // Disable this test anytime when HttpTransportBindingElement.BuildChannelFactory() doesn't return ChannelFactoryBase`1 anymore. It's not an API requirement.
200                 [Test]
201                 [ExpectedException (typeof (ArgumentNullException))]
202                 public void BuildChannelFactory_CreateChannelNullVia ()
203                 {
204                         var ctx = new BindingContext (new CustomBinding (), empty_params);
205                         var cf = new HttpTransportBindingElement ().BuildChannelFactory<IRequestChannel> (ctx);
206                         Assert.IsTrue (cf is ChannelFactoryBase<IRequestChannel>, "#1");
207                         cf.Open ();
208                         cf.CreateChannel (new EndpointAddress ("http://localhost:" + NetworkHelpers.FindFreePort ()), null);
209                 }
210
211                 [Test]
212                 [ExpectedException (typeof (ArgumentException))]
213                 public void CreateChannelInvalidScheme ()
214                 {
215                         IChannelFactory<IRequestChannel> f = new BasicHttpBinding ().BuildChannelFactory<IRequestChannel> (new BindingParameterCollection ());
216                         f.Open ();
217                         f.CreateChannel (new EndpointAddress ("stream:dummy"));
218                 }
219
220                 [Test]
221                 public void BuildChannelListenerWithoutListenUri ()
222                 {
223                         new BasicHttpBinding ().BuildChannelListener<IReplyChannel> (new BindingParameterCollection ());
224                 }
225
226                 // when AddressingVersion is None (in MessageVersion), then
227                 // EndpointAddress.Uri and via URIs must match.
228                 [Test]
229                 [ExpectedException (typeof (ArgumentException))]
230                 public void EndpointAddressAndViaMustMatchOnAddressingNone ()
231                 {
232                         try {
233                                 var ch = ChannelFactory<IFoo>.CreateChannel (new BasicHttpBinding (), new EndpointAddress ("http://localhost:" + NetworkHelpers.FindFreePort () + "/"), new Uri ("http://localhost:" + NetworkHelpers.FindFreePort () + "/HogeService"));
234                                 ((ICommunicationObject) ch).Close ();
235                         } catch (TargetInvocationException) {
236                                 // we throw this exception so far. Since it is
237                                 // very internal difference (channel is created
238                                 // inside ClientRuntimeChannel.ctor() while .NET
239                                 // does it in ChannelFactory<T>.CreateChannel(),
240                                 // there is no point of treating it as failure).
241                                 throw new ArgumentException ();
242                         }
243                 }
244
245                 [Test]
246                 public void GetPropertyMessageVersion ()
247                 {
248                         var be = new HttpTransportBindingElement ();
249                         var mv = be.GetProperty<MessageVersion> (new BindingContext (new CustomBinding (), empty_params));
250                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, mv, "#1");
251                 }
252
253                 [Test]
254                 public void GetPrpertyBindingDeliveryCapabilities ()
255                 {
256                         var be = new HttpTransportBindingElement ();
257                         var dc = be.GetProperty<IBindingDeliveryCapabilities> (new BindingContext (new CustomBinding (), empty_params));
258                         Assert.IsFalse (dc.AssuresOrderedDelivery, "#1");
259                         Assert.IsFalse (dc.QueuedDelivery, "#2");
260                 }
261
262                 [Test]
263                 public void GetPrpertySecurityCapabilities ()
264                 {
265                         var be = new HttpTransportBindingElement ();
266                         var sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
267                         Assert.IsNotNull (sec, "#1.1");
268                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#1.2");
269                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#1.3");
270                         Assert.IsFalse (sec.SupportsClientAuthentication, "#1.4");
271                         Assert.IsFalse (sec.SupportsClientWindowsIdentity, "#1.5");
272                         Assert.IsFalse (sec.SupportsServerAuthentication , "#1.6");
273
274                         be = new HttpTransportBindingElement ();
275                         be.AuthenticationScheme = AuthenticationSchemes.Negotiate;
276                         sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
277                         Assert.IsNotNull (sec, "#2.1");
278                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#2.2");
279                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#2.3");
280                         Assert.IsTrue (sec.SupportsClientAuthentication, "#2.4");
281                         Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#2.5");
282                         Assert.IsTrue (sec.SupportsServerAuthentication , "#2.6");
283
284                         // almost the same, only differ at SupportsServerAuth
285                         be = new HttpTransportBindingElement ();
286                         be.AuthenticationScheme = AuthenticationSchemes.Ntlm;
287                         sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
288                         Assert.IsNotNull (sec, "#3.1");
289                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#3.2");
290                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#3.3");
291                         Assert.IsTrue (sec.SupportsClientAuthentication, "#3.4");
292                         Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#3.5");
293                         Assert.IsFalse (sec.SupportsServerAuthentication , "#3.6");
294
295                         be = new HttpTransportBindingElement ();
296                         be.AuthenticationScheme = AuthenticationSchemes.Basic;
297                         sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
298                         Assert.IsNotNull (sec, "#4.1");
299                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#4.2");
300                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#4.3");
301                         Assert.IsTrue (sec.SupportsClientAuthentication, "#4.4");
302                         Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#4.5");
303                         Assert.IsFalse (sec.SupportsServerAuthentication , "#4.6");
304
305                         be = new HttpTransportBindingElement ();
306                         be.AuthenticationScheme = AuthenticationSchemes.Digest;
307                         sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
308                         Assert.IsNotNull (sec, "#5.1");
309                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#5.2");
310                         Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#5.3");
311                         Assert.IsTrue (sec.SupportsClientAuthentication, "#5.4");
312                         Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#5.5");
313                         Assert.IsFalse (sec.SupportsServerAuthentication , "#5.6");
314                 }
315
316                 #region contracts
317
318                 [ServiceContract]
319                 interface IFoo
320                 {
321                         [OperationContract]
322                         string DoWork (string s1, string s2);
323                 }
324
325                 #endregion
326
327                 #region connection test
328
329                 string svcret;
330
331                 [Test]
332                 [Ignore ("It somehow fails...")]
333                 // It is almost identical to http-low-level-binding
334                 public void LowLevelHttpConnection ()
335                 {
336                         HttpTransportBindingElement lel =
337                                 new HttpTransportBindingElement ();
338
339                         // Service
340                         BindingContext lbc = new BindingContext (
341                                 new CustomBinding (),
342                                 new BindingParameterCollection (),
343                                 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()),
344                                 String.Empty, ListenUriMode.Explicit);
345                         listener = lel.BuildChannelListener<IReplyChannel> (lbc);
346
347                         try {
348
349                         listener.Open ();
350
351                         svcret = "";
352
353                         Thread svc = new Thread (delegate () {
354                                 try {
355                                         svcret = LowLevelHttpConnection_SetupService ();
356                                 } catch (Exception ex) {
357                                         svcret = ex.ToString ();
358                                 }
359                         });
360                         svc.Start ();
361
362                         // Client code goes here.
363
364                         HttpTransportBindingElement el =
365                                 new HttpTransportBindingElement ();
366                         BindingContext ctx = new BindingContext (
367                                 new CustomBinding (),
368                                 new BindingParameterCollection ());
369                         IChannelFactory<IRequestChannel> factory =
370                                 el.BuildChannelFactory<IRequestChannel> (ctx);
371
372                         factory.Open ();
373
374                         IRequestChannel request = factory.CreateChannel (
375                                 new EndpointAddress ("http://localhost:" + NetworkHelpers.FindFreePort ()));
376
377                         request.Open ();
378
379                         try {
380                         try {
381                                 Message reqmsg = Message.CreateMessage (
382                                         MessageVersion.Default, "Echo");
383                                 // sync version does not work here.
384                                 Message msg = request.Request (reqmsg, TimeSpan.FromSeconds (5));
385
386                                 using (XmlWriter w = XmlWriter.Create (TextWriter.Null)) {
387                                         msg.WriteMessage (w);
388                                 }
389
390                                 if (svcret != null)
391                                         Assert.Fail (svcret.Length > 0 ? svcret : "service code did not finish until this test expected.");
392                         } finally {
393                                 if (request.State == CommunicationState.Opened)
394                                         request.Close ();
395                         }
396                         } finally {
397                                 if (factory.State == CommunicationState.Opened)
398                                         factory.Close ();
399                         }
400                         } finally {
401                                 if (listener.State == CommunicationState.Opened)
402                                         listener.Close ();
403                         }
404                 }
405
406                 IChannelListener<IReplyChannel> listener;
407
408                 string LowLevelHttpConnection_SetupService ()
409                 {
410                         IReplyChannel reply = listener.AcceptChannel ();
411                         reply.Open ();
412                         if (!reply.WaitForRequest (TimeSpan.FromSeconds (10)))
413                                 return "No request reached here.";
414
415                         svcret = "Receiving request ...";
416                         RequestContext ctx = reply.ReceiveRequest ();
417                         if (ctx == null)
418                                 return "No request context returned.";
419
420                         svcret = "Starting reply ...";
421                         ctx.Reply (Message.CreateMessage (MessageVersion.Default, "Ack"));
422                         return null; // OK
423                 }
424
425                 #endregion
426
427                 #region metadata
428
429                 [Test]
430                 public void ExportPolicyDefault ()
431                 {
432                         IPolicyExportExtension binding_element = new HttpTransportBindingElement ();
433                         PolicyConversionContext conversion_context = new CustomPolicyConversionContext ();
434                         binding_element.ExportPolicy (new WsdlExporter (), conversion_context);
435
436                         PolicyAssertionCollection binding_assertions = conversion_context.GetBindingAssertions ();
437                         BindingElementCollection binding_elements = conversion_context.BindingElements;
438                         Assert.AreEqual (1, binding_assertions.Count, "#A0");
439                         Assert.AreEqual (0, binding_elements.Count, "#A1");
440
441                         // wsaw:UsingAddressing
442                         XmlNode using_addressing_node = FindAssertion (binding_assertions, "wsaw:UsingAddressing");
443                         Assert.AreEqual (true, using_addressing_node != null, "#B0");
444                         Assert.AreEqual ("UsingAddressing", using_addressing_node.LocalName, "#B1");
445                         Assert.AreEqual ("http://www.w3.org/2006/05/addressing/wsdl", using_addressing_node.NamespaceURI, "#B2");
446                         Assert.AreEqual (0, using_addressing_node.Attributes.Count, "#B3");
447                         Assert.AreEqual (0, using_addressing_node.ChildNodes.Count, "#B4");
448                         Assert.AreEqual (String.Empty, using_addressing_node.InnerText, "#B5");
449                 }
450
451                 [Test]
452                 public void ExportPolicy ()
453                 {
454                         HttpTransportBindingElement http_binding_element = new HttpTransportBindingElement ();
455
456                         //
457                         // Specify some non-default values
458                         //
459                         http_binding_element.AllowCookies = !http_binding_element.AllowCookies;
460                         http_binding_element.AuthenticationScheme = AuthenticationSchemes.Ntlm;
461                         http_binding_element.BypassProxyOnLocal = !http_binding_element.BypassProxyOnLocal;
462                         http_binding_element.HostNameComparisonMode = HostNameComparisonMode.WeakWildcard;
463                         http_binding_element.KeepAliveEnabled = !http_binding_element.KeepAliveEnabled;
464                         http_binding_element.ManualAddressing = !http_binding_element.ManualAddressing;
465                         http_binding_element.MaxBufferPoolSize = http_binding_element.MaxBufferPoolSize / 2;
466                         http_binding_element.MaxBufferSize = http_binding_element.MaxBufferSize / 2;
467                         http_binding_element.MaxReceivedMessageSize = http_binding_element.MaxReceivedMessageSize / 2;
468                         http_binding_element.ProxyAddress = new Uri ("http://proxyaddress.com");
469                         http_binding_element.ProxyAuthenticationScheme = AuthenticationSchemes.Basic;
470                         http_binding_element.Realm = "RandomRealm";
471                         http_binding_element.TransferMode = TransferMode.Streamed;
472                         http_binding_element.UnsafeConnectionNtlmAuthentication = !http_binding_element.UnsafeConnectionNtlmAuthentication;
473                         http_binding_element.UseDefaultWebProxy = !http_binding_element.UseDefaultWebProxy;
474 #if NET_4_0
475                         http_binding_element.DecompressionEnabled = !http_binding_element.DecompressionEnabled;
476                         http_binding_element.ExtendedProtectionPolicy = new ExtendedProtectionPolicy (PolicyEnforcement.WhenSupported);
477 #endif
478
479                         // 
480                         // Actual call to ExportPolicy
481                         //
482                         IPolicyExportExtension binding_element = http_binding_element as IPolicyExportExtension;
483                         PolicyConversionContext conversion_context = new CustomPolicyConversionContext ();
484                         binding_element.ExportPolicy (new WsdlExporter (), conversion_context);
485
486                         PolicyAssertionCollection binding_assertions = conversion_context.GetBindingAssertions ();
487                         BindingElementCollection binding_elements = conversion_context.BindingElements;
488                         Assert.AreEqual (2, binding_assertions.Count, "#A0");
489                         Assert.AreEqual (0, binding_elements.Count, "#A1");
490
491                         // AuthenticationScheme - the only property that causes information to be exported.
492                         XmlNode authentication_node = FindAssertion (binding_assertions, "http:NtlmAuthentication");
493                         Assert.AreEqual (true, authentication_node != null, "#B0");
494                         Assert.AreEqual ("NtlmAuthentication", authentication_node.LocalName, "#B1");
495                         Assert.AreEqual ("http://schemas.microsoft.com/ws/06/2004/policy/http", authentication_node.NamespaceURI, "#B2");
496                         Assert.AreEqual (String.Empty, authentication_node.InnerText, "#B3");
497                         Assert.AreEqual (0, authentication_node.Attributes.Count, "#B4");
498                 }
499
500                 // For some reason PolicyAssertionCollection.Find is not working as expected,
501                 // so do the lookup manually.
502                 XmlNode FindAssertion (PolicyAssertionCollection assertionCollection, string name)
503                 {
504                         foreach (XmlNode node in assertionCollection)
505                                 if (node.Name == name)
506                                         return node;
507
508                         return null;
509                 }
510
511                 XmlNode FindAssertionByLocalName (PolicyAssertionCollection assertionCollection, string name)
512                 {
513                         foreach (XmlNode node in assertionCollection)
514                                 if (node.LocalName == name)
515                                         return node;
516                         
517                         return null;
518                 }
519
520                 class MyMessageEncodingElement : MessageEncodingBindingElement {
521                         MessageVersion version;
522                         
523                         public MyMessageEncodingElement (MessageVersion version)
524                         {
525                                 this.version = version;
526                         }
527                         
528                         public override BindingElement Clone ()
529                         {
530                                 return new MyMessageEncodingElement (version);
531                         }
532                         public override MessageEncoderFactory CreateMessageEncoderFactory ()
533                         {
534                                 throw new NotImplementedException ();
535                         }
536                         public override MessageVersion MessageVersion {
537                                 get {
538                                         return version;
539                                 }
540                                 set {
541                                         throw new NotImplementedException ();
542                                 }
543                         }
544                 }
545                 
546                 [Test]
547                 public void ExportPolicy_CustomEncoding_Soap12 ()
548                 {
549                         HttpTransportBindingElement binding_element = new HttpTransportBindingElement ();
550                         IPolicyExportExtension export_extension = binding_element as IPolicyExportExtension;
551                         PolicyConversionContext conversion_context = new CustomPolicyConversionContext ();
552                         conversion_context.BindingElements.Add (new MyMessageEncodingElement (MessageVersion.Soap12));
553                         export_extension.ExportPolicy (new WsdlExporter (), conversion_context);
554                         
555                         PolicyAssertionCollection binding_assertions = conversion_context.GetBindingAssertions ();
556                         BindingElementCollection binding_elements = conversion_context.BindingElements;
557                         Assert.AreEqual (0, binding_assertions.Count, "#A0");
558                         Assert.AreEqual (1, binding_elements.Count, "#A1");
559                 }
560                 
561                 [Test]
562                 public void ExportPolicy_CustomEncoding_Soap12August2004 ()
563                 {
564                         HttpTransportBindingElement binding_element = new HttpTransportBindingElement ();
565                         IPolicyExportExtension export_extension = binding_element as IPolicyExportExtension;
566                         PolicyConversionContext conversion_context = new CustomPolicyConversionContext ();
567                         conversion_context.BindingElements.Add (new MyMessageEncodingElement (MessageVersion.Soap12WSAddressingAugust2004));
568                         export_extension.ExportPolicy (new WsdlExporter (), conversion_context);
569                         
570                         PolicyAssertionCollection binding_assertions = conversion_context.GetBindingAssertions ();
571                         BindingElementCollection binding_elements = conversion_context.BindingElements;
572                         Assert.AreEqual (1, binding_assertions.Count, "#A0");
573                         Assert.AreEqual (1, binding_elements.Count, "#A1");
574                         
575                         // UsingAddressing
576                         XmlNode using_addressing_node = FindAssertionByLocalName (binding_assertions, "UsingAddressing");
577                         Assert.AreEqual (true, using_addressing_node != null, "#B0");
578                         Assert.AreEqual ("UsingAddressing", using_addressing_node.LocalName, "#B1");
579                         Assert.AreEqual ("http://schemas.xmlsoap.org/ws/2004/08/addressing/policy", using_addressing_node.NamespaceURI, "#B2");
580                         Assert.AreEqual (String.Empty, using_addressing_node.InnerText, "#B3");
581                         Assert.AreEqual (0, using_addressing_node.Attributes.Count, "#B4");
582                         Assert.AreEqual (0, using_addressing_node.ChildNodes.Count, "#B5");
583                 }
584
585                 #endregion
586     }
587 }