| File: ServiceModel\WSHttpBindingTransactionTests.cs | Web Access |
| Project: ..\..\..\src\System.ServiceModel.Http\tests\System.ServiceModel.Http.Tests.csproj (System.ServiceModel.Http.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Runtime.InteropServices; using System.ServiceModel; using System.ServiceModel.Channels; using Infrastructure.Common; using Xunit; public static class WSHttpBindingTransactionTests { // ===== WSHttpBinding TransactionFlow default tests ===== [WcfFact] public static void WSHttpBinding_TransactionFlow_Default_Is_False() { var binding = new WSHttpBinding(); Assert.False(binding.TransactionFlow); } [WcfFact] public static void WS2007HttpBinding_TransactionFlow_Default_Is_False() { var binding = new WS2007HttpBinding(); Assert.False(binding.TransactionFlow); } // ===== TransactionFlow property setter tests ===== [WcfTheory] [InlineData(true)] [InlineData(false)] public static void WSHttpBinding_TransactionFlow_Property_Sets(bool value) { var binding = new WSHttpBinding(); binding.TransactionFlow = value; Assert.Equal(value, binding.TransactionFlow); } [WcfTheory] [InlineData(true)] [InlineData(false)] public static void WS2007HttpBinding_TransactionFlow_Property_Sets(bool value) { var binding = new WS2007HttpBinding(); binding.TransactionFlow = value; Assert.Equal(value, binding.TransactionFlow); } // ===== CreateBindingElements includes TransactionFlowBindingElement ===== [WcfFact] public static void WSHttpBinding_CreateBindingElements_Contains_TransactionFlowBindingElement() { var binding = new WSHttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); } [WcfFact] public static void WS2007HttpBinding_CreateBindingElements_Contains_TransactionFlowBindingElement() { var binding = new WS2007HttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); } // ===== TransactionProtocol defaults ===== [WcfFact] public static void WSHttpBinding_TransactionFlowBindingElement_Uses_WSAtomicTransactionOctober2004() { var binding = new WSHttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, txFlowElement.TransactionProtocol); } [WcfFact] public static void WS2007HttpBinding_TransactionFlowBindingElement_Uses_WSAtomicTransaction11() { var binding = new WS2007HttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, txFlowElement.TransactionProtocol); } // ===== WSHttpBinding and WS2007HttpBinding use correct protocols across all constructor overloads ===== [WcfFact] public static void WSHttpBinding_Default_Ctor_TransactionFlow_Default_Matches_SecurityMode_None_Ctor() { // The default constructor uses SecurityMode.Message which prevents CreateBindingElements // on non-Windows, but the TransactionFlow default should be the same regardless of security mode. var defaultBinding = new WSHttpBinding(); var noneSecBinding = new WSHttpBinding(SecurityMode.None); Assert.Equal(defaultBinding.TransactionFlow, noneSecBinding.TransactionFlow); } [WcfFact] public static void WSHttpBinding_SecurityMode_Ctor_Uses_WSAtomicTransactionOctober2004() { var binding = new WSHttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, txFlowElement.TransactionProtocol); } [WcfFact] public static void WSHttpBinding_SecurityMode_ReliableSession_Ctor_Uses_WSAtomicTransactionOctober2004() { var binding = new WSHttpBinding(SecurityMode.None, reliableSessionEnabled: true); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, txFlowElement.TransactionProtocol); } [WcfFact] public static void WS2007HttpBinding_Default_Ctor_TransactionFlow_Default_Matches_SecurityMode_None_Ctor() { var defaultBinding = new WS2007HttpBinding(); var noneSecBinding = new WS2007HttpBinding(SecurityMode.None); Assert.Equal(defaultBinding.TransactionFlow, noneSecBinding.TransactionFlow); } // ===== Protocols differ between WSHttpBinding and WS2007HttpBinding ===== [WcfFact] public static void WSHttpBinding_And_WS2007HttpBinding_Use_Different_Protocols() { var wsBinding = new WSHttpBinding(SecurityMode.None); var ws2007Binding = new WS2007HttpBinding(SecurityMode.None); var wsElements = wsBinding.CreateBindingElements(); var ws2007Elements = ws2007Binding.CreateBindingElements(); var wsTxFlow = wsElements.Find<TransactionFlowBindingElement>(); var ws2007TxFlow = ws2007Elements.Find<TransactionFlowBindingElement>(); Assert.NotEqual(wsTxFlow.TransactionProtocol, ws2007TxFlow.TransactionProtocol); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, wsTxFlow.TransactionProtocol); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, ws2007TxFlow.TransactionProtocol); } // ===== TransactionFlow=true propagates to TransactionFlowBindingElement ===== [WcfFact] public static void WSHttpBinding_TransactionFlow_True_Propagates_To_BindingElement() { var binding = new WSHttpBinding(SecurityMode.None); binding.TransactionFlow = true; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); // The binding element is cloned, so just verify it was created from // a binding with TransactionFlow=true by checking the binding itself Assert.True(binding.TransactionFlow); } // ===== TransactionFlowBindingElement is first in binding elements ===== [WcfFact] public static void WSHttpBinding_TransactionFlowBindingElement_Is_First_Element() { var binding = new WSHttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); Assert.IsType<TransactionFlowBindingElement>(elements[0]); } [WcfFact] public static void WS2007HttpBinding_TransactionFlowBindingElement_Is_First_Element() { var binding = new WS2007HttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); Assert.IsType<TransactionFlowBindingElement>(elements[0]); } // ===== Constructor variations preserve transaction protocol ===== [WcfFact] public static void WS2007HttpBinding_SecurityMode_Ctor_Uses_WSAtomicTransaction11() { var binding = new WS2007HttpBinding(SecurityMode.None); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, txFlowElement.TransactionProtocol); } [WcfFact] public static void WS2007HttpBinding_SecurityMode_ReliableSession_Ctor_Uses_WSAtomicTransaction11() { var binding = new WS2007HttpBinding(SecurityMode.None, reliableSessionEnabled: true); var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, txFlowElement.TransactionProtocol); } // ===== TransactionFlow + Protocol combination tests ===== [WcfFact] public static void WSHttpBinding_TransactionFlow_True_With_WSAtomicTransactionOctober2004() { var binding = new WSHttpBinding(SecurityMode.None); binding.TransactionFlow = true; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, txFlowElement.TransactionProtocol); Assert.True(binding.TransactionFlow); } [WcfFact] public static void WS2007HttpBinding_TransactionFlow_True_With_WSAtomicTransaction11() { var binding = new WS2007HttpBinding(SecurityMode.None); binding.TransactionFlow = true; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, txFlowElement.TransactionProtocol); Assert.True(binding.TransactionFlow); } [WcfFact] public static void WSHttpBinding_TransactionFlow_False_Preserves_Protocol() { var binding = new WSHttpBinding(SecurityMode.None); binding.TransactionFlow = false; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, txFlowElement.TransactionProtocol); } [WcfFact] public static void WS2007HttpBinding_TransactionFlow_False_Preserves_Protocol() { var binding = new WS2007HttpBinding(SecurityMode.None); binding.TransactionFlow = false; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, txFlowElement.TransactionProtocol); } [WcfFact] public static void WSHttpBinding_ReliableSession_TransactionFlow_True_Preserves_Protocol() { var binding = new WSHttpBinding(SecurityMode.None, reliableSessionEnabled: true); binding.TransactionFlow = true; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); Assert.Equal(TransactionProtocol.WSAtomicTransactionOctober2004, txFlowElement.TransactionProtocol); Assert.True(binding.TransactionFlow); } [WcfFact] public static void WS2007HttpBinding_ReliableSession_TransactionFlow_True_Preserves_Protocol() { var binding = new WS2007HttpBinding(SecurityMode.None, reliableSessionEnabled: true); binding.TransactionFlow = true; var elements = binding.CreateBindingElements(); var txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); Assert.Equal(TransactionProtocol.WSAtomicTransaction11, txFlowElement.TransactionProtocol); Assert.True(binding.TransactionFlow); } } // ===== Platform-specific tests (PlatformNotSupportedException on non-Windows) ===== // These tests validate that on non-Windows platforms, enabling transactions // will throw PlatformNotSupportedException since System.Transactions requires Windows. // They won't execute on Windows but must exist. public static class WSHttpBindingTransactionPlatformTests { public static bool Is_Not_Windows() { return !RuntimeInformation.IsOSPlatform(OSPlatform.Windows); } private static void AssertTransactionFlowUsageThrowsOnNonWindows(Binding binding) { BindingElementCollection elements = binding.CreateBindingElements(); TransactionFlowBindingElement txFlowElement = elements.Find<TransactionFlowBindingElement>(); Assert.NotNull(txFlowElement); CustomBinding customBinding = new CustomBinding(elements); Assert.Throws<PlatformNotSupportedException>(() => { customBinding.BuildChannelFactory<IRequestChannel>(new BindingParameterCollection()); }); } [WcfFact] [Condition(nameof(Is_Not_Windows))] public static void WSHttpBinding_TransactionFlow_True_Throws_On_NonWindows() { // On non-Windows, setting TransactionFlow=true and attempting to use the binding // should fail because System.Transactions is not supported. WSHttpBinding binding = new WSHttpBinding(SecurityMode.None); binding.TransactionFlow = true; AssertTransactionFlowUsageThrowsOnNonWindows(binding); } [WcfFact] [Condition(nameof(Is_Not_Windows))] public static void WS2007HttpBinding_TransactionFlow_True_Throws_On_NonWindows() { WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.None); binding.TransactionFlow = true; AssertTransactionFlowUsageThrowsOnNonWindows(binding); } }