From 2b74924118247c75fa8893877cabc0bb52ddb489 Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 25 Jul 2025 09:46:02 +0100 Subject: [PATCH 01/10] add upgrade context --- upgrade.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 upgrade.md diff --git a/upgrade.md b/upgrade.md new file mode 100644 index 0000000..8e27b05 --- /dev/null +++ b/upgrade.md @@ -0,0 +1,36 @@ +# Upgrade Plan: HttpMock to .NET 8 + +## User Instructions + +1. Upgrade the entire project to .NET 8. +2. Remove the Kayak dependency completely. +3. Preserve all tests. Do not change any test code. + +## Assistant Suggestions & Plan + +### 1. Project Upgrade +- Convert all `.csproj` files to SDK-style format. +- Change target framework to `net8.0` for all projects. +- Remove any legacy or obsolete settings from project files. +- Ensure all dependencies are compatible with .NET 8. + +### 2. Remove Kayak +- Remove Kayak references from all `.csproj` and `packages.config` files. +- Remove all `using Kayak` and `using Kayak.Http` statements from code. +- Refactor the HTTP server implementation to use `HttpListner' (primarily in `HttpServer.cs`) to use a modern .NET 8 HTTP servers. +- Update or replace any code that depends on Kayak types or APIs. +- Don't break any of the interfaces + +### 3. Preserve Tests +- Do not modify any test logic or files. +- Ensure tests still reference the main library and run under .NET 8. + +### 4. Build & Test +- Update build/test scripts (e.g., Azure Pipelines, PowerShell) to use .NET 8 if needed. +- Verify that all tests pass after the upgrade and refactor. + +--- + +**Note:** +- The main focus is to modernize the codebase and remove Kayak, while keeping the test suite unchanged and fully functional. +- The HTTP server implementation will need the most attention, as it is tightly coupled to Kayak in the current codebase. \ No newline at end of file From dde07da762c84636f0118d4722645b1f14f342ff Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 25 Jul 2025 21:00:33 +0100 Subject: [PATCH 02/10] add updated instructions --- .../Properties/AssemblyInfo.cs | 36 ----------------- .../Properties/AssemblyInfo.cs | 35 ---------------- .../BufferedConsumerTests.cs | 29 -------------- .../Properties/AssemblyInfo.cs | 40 ------------------- upgrade.md | 10 ++++- 5 files changed, 9 insertions(+), 141 deletions(-) delete mode 100644 src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs delete mode 100644 src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs delete mode 100644 src/HttpMock.Unit.Tests/BufferedConsumerTests.cs delete mode 100644 src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs diff --git a/src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs b/src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 448bed8..0000000 --- a/src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("StubHttp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("StubHttp")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("c8dd9eca-377b-4b3d-a136-a5824d21119f")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs b/src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs deleted file mode 100644 index c302f65..0000000 --- a/src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("HttpMock.Logging.Log4Net")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("HttpMock.Logging.Log4Net")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("873e4657-ed89-4b3a-b2f2-82b183ab358c")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/src/HttpMock.Unit.Tests/BufferedConsumerTests.cs b/src/HttpMock.Unit.Tests/BufferedConsumerTests.cs deleted file mode 100644 index 22210c2..0000000 --- a/src/HttpMock.Unit.Tests/BufferedConsumerTests.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Text; -using NUnit.Framework; - -namespace HttpMock.Unit.Tests -{ - [TestFixture] - public class BufferedConsumerTests - { - [Test] - public void Should_return_data_in_order() - { - string expected = "1234"; - string data = ""; - - var bufferedConsumer = new BufferedConsumer(s => { data = s; }, exception => { }); - - bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("1")), () => { }); - bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("2")), () => { }); - bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("3")), () => { }); - bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("4")), () => { }); - - - bufferedConsumer.OnEnd(); - - Assert.That(data, Is.EqualTo(expected)); - } - } -} \ No newline at end of file diff --git a/src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs b/src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs deleted file mode 100644 index 167e1af..0000000 --- a/src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("HttpMock.Verify.NUnit")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("HttpMock.Verify.NUnit")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("1B61C8E3-7A43-479B-B7FE-D374DFEAA5E7")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/upgrade.md b/upgrade.md index 8e27b05..1f1c853 100644 --- a/upgrade.md +++ b/upgrade.md @@ -5,8 +5,12 @@ 1. Upgrade the entire project to .NET 8. 2. Remove the Kayak dependency completely. 3. Preserve all tests. Do not change any test code. +4. Run all the tests after making changes +5. Make small changes +6. Commit changes when tests pass +7. Run tests before making changes so that all the tests pass +8. Do not change test behaviour -## Assistant Suggestions & Plan ### 1. Project Upgrade - Convert all `.csproj` files to SDK-style format. @@ -29,6 +33,10 @@ - Update build/test scripts (e.g., Azure Pipelines, PowerShell) to use .NET 8 if needed. - Verify that all tests pass after the upgrade and refactor. +### 5. Keep a journal + +- Keep a journal of all changes made to journal.md + --- **Note:** From 799a3990d97ebd3602a190d9134a705f8715d8df Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 25 Jul 2025 21:11:33 +0100 Subject: [PATCH 03/10] Remove Rhino and use Moq --- .../EndpointMatchingRuleTests.cs | 227 ++++++++++-------- .../HttpMock.Unit.Tests.csproj | 4 +- .../RequestProcessorTests.cs | 20 +- src/HttpMock.Unit.Tests/packages.config | 5 +- upgrade.md | 4 +- 5 files changed, 140 insertions(+), 120 deletions(-) diff --git a/src/HttpMock.Unit.Tests/EndpointMatchingRuleTests.cs b/src/HttpMock.Unit.Tests/EndpointMatchingRuleTests.cs index b9e0d1d..0a83480 100644 --- a/src/HttpMock.Unit.Tests/EndpointMatchingRuleTests.cs +++ b/src/HttpMock.Unit.Tests/EndpointMatchingRuleTests.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Kayak.Http; using NUnit.Framework; -using Rhino.Mocks; +using Moq; namespace HttpMock.Unit.Tests { @@ -10,122 +10,132 @@ public class EndpointMatchingRuleTests { [Test] public void urls_match_it_returns_true( ) { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.QueryParams = new Dictionary(); + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.QueryParams = new Dictionary(); - var httpRequestHead = new HttpRequestHead { Uri = "test" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + var httpRequestHead = new HttpRequestHead { Uri = "test" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void urls_and_methods_the_same_it_returns_true() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "PUT"; - requestHandler.QueryParams = new Dictionary(); + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "PUT"; + requestHandlerMock.Object.QueryParams = new Dictionary(); - var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "PUT" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "PUT" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void urls_and_methods_differ_it_returns_false() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary(); - var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "PUT" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False); + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary(); + var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "PUT" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.False); } [Test] public void urls_differ_and_methods_match_it_returns_false() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "pest"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary(); - var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False); + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "pest"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary(); + var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.False); } [Test] public void urls_and_methods_match_queryparams_differ_it_returns_false() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary { { "myParam", "one" } }; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary { { "myParam", "one" } }; - var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False); + var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.False); } [Test] public void urls_and_methods_match_and_queryparams_exist_it_returns_true() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary { { "myParam", "one" } }; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary { { "myParam", "one" } }; - var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked&myParam=one", Method = "GET" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked&myParam=one", Method = "GET" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void urls_and_methods_match_and_queryparams_does_not_exist_it_returns_false() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary { { "myParam", "one" } }; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary { { "myParam", "one" } }; - var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked", Method = "GET" }; - var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False); + var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked", Method = "GET" }; + var endpointMatchingRule = new EndpointMatchingRule(); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.False); } [Test] public void urls_and_methods_match_and_no_query_params_are_set_but_request_has_query_params_returns_true() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary (); + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary (); - var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked", Method = "GET" }; - var endpointMatchingRule = new EndpointMatchingRule(); + var httpRequestHead = new HttpRequestHead { Uri = "test?oauth_consumer_key=test-api&elvis=alive&moonlandings=faked", Method = "GET" }; + var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.True); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.True); } [Test] public void urls_and_methods_and_queryparams_match_it_returns_true() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary{{"myParam", "one"}}; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary{{"myParam", "one"}}; - var httpRequestHead = new HttpRequestHead { Uri = "test?myParam=one", Method = "GET" }; + var httpRequestHead = new HttpRequestHead { Uri = "test?myParam=one", Method = "GET" }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void urls_and_methods_match_headers_differ_it_returns_false() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary(); - requestHandler.RequestHeaders = new Dictionary { { "myHeader", "one" } }; - - var httpRequestHead = new HttpRequestHead + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary(); + requestHandlerMock.Object.RequestHeaders = new Dictionary { { "myHeader", "one" } }; + + var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET", @@ -135,18 +145,19 @@ public void urls_and_methods_match_headers_differ_it_returns_false() { } }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.False); } [Test] public void urls_and_methods_match_and_headers_match_it_returns_true() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary(); - requestHandler.RequestHeaders = new Dictionary { { "myHeader", "one" } }; - - var httpRequestHead = new HttpRequestHead + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary(); + requestHandlerMock.Object.RequestHeaders = new Dictionary { { "myHeader", "one" } }; + + var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET", @@ -157,44 +168,47 @@ public void urls_and_methods_match_and_headers_match_it_returns_true() { } }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void urls_and_methods_match_and_header_does_not_exist_it_returns_false() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary(); - requestHandler.RequestHeaders = new Dictionary { { "myHeader", "one" } }; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary(); + requestHandlerMock.Object.RequestHeaders = new Dictionary { { "myHeader", "one" } }; var httpRequestHead = new HttpRequestHead { Uri = "test", Method = "GET" }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead), Is.False); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead), Is.False); } [Test] public void should_do_a_case_insensitive_match_on_query_string_parameter_values() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary { { "myParam", "one" } }; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary { { "myParam", "one" } }; var httpRequestHead = new HttpRequestHead { Uri = "test?myParam=OnE", Method = "GET" }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void should_do_a_case_insensitive_match_on_header_names_and_values() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary(); - requestHandler.RequestHeaders = new Dictionary { { "myHeader", "one" } }; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary(); + requestHandlerMock.Object.RequestHeaders = new Dictionary { { "myHeader", "one" } }; var httpRequestHead = new HttpRequestHead { @@ -207,35 +221,37 @@ public void should_do_a_case_insensitive_match_on_header_names_and_values() { }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void should_match_when_the_query_string_has_a_trailing_ampersand() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "test"; - requestHandler.Method = "GET"; - requestHandler.QueryParams = new Dictionary { { "a", "b" } ,{"c","d"}}; + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "test"; + requestHandlerMock.Object.Method = "GET"; + requestHandlerMock.Object.QueryParams = new Dictionary { { "a", "b" } ,{"c","d"}}; var httpRequestHead = new HttpRequestHead { Uri = "test?a=b&c=d&", Method = "GET" }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } [Test] public void should_match_urls_containings_regex_reserved_characters() { - var requestHandler = MockRepository.GenerateStub(); - requestHandler.Path = "/test()"; - requestHandler.QueryParams = new Dictionary(); + var requestHandlerMock = new Mock(); + requestHandlerMock.SetupAllProperties(); + requestHandlerMock.Object.Path = "/test()"; + requestHandlerMock.Object.QueryParams = new Dictionary(); var httpRequestHead = new HttpRequestHead { Uri = "/test()" }; var endpointMatchingRule = new EndpointMatchingRule(); - Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandler, httpRequestHead)); + Assert.That(endpointMatchingRule.IsEndpointMatch(requestHandlerMock.Object, httpRequestHead)); } } @@ -295,4 +311,5 @@ public void Should_match_a_specific_handler() Assert.That(matchedRequest.Path, Is.EqualTo(expectedRequest.Path)); } } -} \ No newline at end of file +} + diff --git a/src/HttpMock.Unit.Tests/HttpMock.Unit.Tests.csproj b/src/HttpMock.Unit.Tests/HttpMock.Unit.Tests.csproj index 0b5fed3..ddddc1c 100644 --- a/src/HttpMock.Unit.Tests/HttpMock.Unit.Tests.csproj +++ b/src/HttpMock.Unit.Tests/HttpMock.Unit.Tests.csproj @@ -50,8 +50,8 @@ - - ..\..\packages\RhinoMocks.3.6.1\lib\net\Rhino.Mocks.dll + + ..\..\packages\Moq.4.20.1\lib\netstandard2.0\Moq.dll diff --git a/src/HttpMock.Unit.Tests/RequestProcessorTests.cs b/src/HttpMock.Unit.Tests/RequestProcessorTests.cs index 0fd03f8..a048e67 100644 --- a/src/HttpMock.Unit.Tests/RequestProcessorTests.cs +++ b/src/HttpMock.Unit.Tests/RequestProcessorTests.cs @@ -3,7 +3,7 @@ using Kayak; using Kayak.Http; using NUnit.Framework; -using Rhino.Mocks; +using Moq; namespace HttpMock.Unit.Tests { [TestFixture] @@ -18,16 +18,18 @@ public class RequestProcessorTests [SetUp] public void SetUp() { - _processor = new RequestProcessor(_ruleThatReturnsFirstHandler, new RequestHandlerList()); - _requestHandlerFactory = new RequestHandlerFactory(_processor); - _dataProducer = MockRepository.GenerateStub(); - _httpResponseDelegate = MockRepository.GenerateStub(); + var ruleFirstHandlerMock = new Mock(); + ruleFirstHandlerMock.Setup(x => x.IsEndpointMatch(It.IsAny(), It.IsAny())).Returns(true); + _ruleThatReturnsFirstHandler = ruleFirstHandlerMock.Object; - _ruleThatReturnsFirstHandler = MockRepository.GenerateStub(); - _ruleThatReturnsFirstHandler.Stub(x => x.IsEndpointMatch(null, new HttpRequestHead())).IgnoreArguments().Return(true).Repeat.Once(); + var ruleNoHandlersMock = new Mock(); + ruleNoHandlersMock.Setup(x => x.IsEndpointMatch(It.IsAny(), It.IsAny())).Returns(false); + _ruleThatReturnsNoHandlers = ruleNoHandlersMock.Object; - _ruleThatReturnsNoHandlers = MockRepository.GenerateStub(); - _ruleThatReturnsNoHandlers.Stub(x => x.IsEndpointMatch(null, new HttpRequestHead())).IgnoreArguments().Return(false); + _processor = new RequestProcessor(_ruleThatReturnsFirstHandler, new RequestHandlerList()); + _requestHandlerFactory = new RequestHandlerFactory(_processor); + _dataProducer = new Mock().Object; + _httpResponseDelegate = new Mock().Object; } [Test] diff --git a/src/HttpMock.Unit.Tests/packages.config b/src/HttpMock.Unit.Tests/packages.config index 3884e82..1254b96 100644 --- a/src/HttpMock.Unit.Tests/packages.config +++ b/src/HttpMock.Unit.Tests/packages.config @@ -1,7 +1,6 @@  - - - + + \ No newline at end of file diff --git a/upgrade.md b/upgrade.md index 1f1c853..91ba86b 100644 --- a/upgrade.md +++ b/upgrade.md @@ -1,5 +1,6 @@ # Upgrade Plan: HttpMock to .NET 8 +Always use Test Drven Development. ## User Instructions 1. Upgrade the entire project to .NET 8. @@ -10,7 +11,8 @@ 6. Commit changes when tests pass 7. Run tests before making changes so that all the tests pass 8. Do not change test behaviour - +9. Maintain the behaviour of interfaces that are used in test. Change the parameters of the interfaces to remove Kayak dependencies, but ensure that the interfaces still behave the same way. +10. Change the RhinoMocks to use Moq ### 1. Project Upgrade - Convert all `.csproj` files to SDK-style format. From cf6d60226ec764e04d4512b53c949eb719112d47 Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:07:01 +0100 Subject: [PATCH 04/10] fix pipeline image --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b98deb0..1cb058e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,7 +4,7 @@ # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net pool: - vmImage: 'VS2017-Win2016' + vmImage: 'windows-2025' variables: solution: '**/*.sln' From 1ba7eed90914511ae507ab113737e06f2552ee84 Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:10:54 +0100 Subject: [PATCH 05/10] Add solution folder --- HttpMock.sln | 6 ++++++ upgrade.md | 2 ++ 2 files changed, 8 insertions(+) diff --git a/HttpMock.sln b/HttpMock.sln index 0a48628..7c078b2 100644 --- a/HttpMock.sln +++ b/HttpMock.sln @@ -20,6 +20,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpMock.Verify.NUnit", "sr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpMock.Logging.Log4Net", "src\HttpMock.Logging.Log4Net\HttpMock.Logging.Log4Net.csproj", "{873E4657-ED89-4B3A-B2F2-82B183AB358C}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ci", "ci", "{AB33A74A-FBFF-4598-855E-1BD6014F0CE3}" + ProjectSection(SolutionItems) = preProject + azure-pipelines.yml = azure-pipelines.yml + buildpackage.ps1 = buildpackage.ps1 + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/upgrade.md b/upgrade.md index 91ba86b..dcec475 100644 --- a/upgrade.md +++ b/upgrade.md @@ -3,6 +3,7 @@ Always use Test Drven Development. ## User Instructions + 1. Upgrade the entire project to .NET 8. 2. Remove the Kayak dependency completely. 3. Preserve all tests. Do not change any test code. @@ -15,6 +16,7 @@ Always use Test Drven Development. 10. Change the RhinoMocks to use Moq ### 1. Project Upgrade +- Create a Dockerfile to build and test the project in a container. Use an image .Net framework 4.8 first, then upgrade to .NET 8. - Convert all `.csproj` files to SDK-style format. - Change target framework to `net8.0` for all projects. - Remove any legacy or obsolete settings from project files. From 9317efc3fc9d06f9125fc5852a93f14435c416c8 Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:26:22 +0100 Subject: [PATCH 06/10] use 2019 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1cb058e..eb5dcb2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,7 +4,7 @@ # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net pool: - vmImage: 'windows-2025' + vmImage: 'windows-2019' variables: solution: '**/*.sln' From f4c8945230351b794e32808d7680caf12fda00f3 Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:31:23 +0100 Subject: [PATCH 07/10] restore assembly info --- .../Properties/AssemblyInfo.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs diff --git a/src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs b/src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9f63f82 --- /dev/null +++ b/src/HttpMock.Logging.Log4Net/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("HttpMock.Logging.Log4Net")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("HttpMock.Logging.Log4Net")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("873e4657-ed89-4b3a-b2f2-82b183ab358c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file From 4d80423366221173e5d0b0c21bcbf67f9cf9473d Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:40:06 +0100 Subject: [PATCH 08/10] Add assembly info --- .../Properties/AssemblyInfo.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs diff --git a/src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs b/src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..55ad8f2 --- /dev/null +++ b/src/HttpMock.Verify.NUnit/Properties/AssemblyInfo.cs @@ -0,0 +1,40 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyTitle("HttpMock.Verify.NUnit")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("HttpMock.Verify.NUnit")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly: Guid("1B61C8E3-7A43-479B-B7FE-D374DFEAA5E7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file From 192ec5579f7e0e09435d6690d418d163678c16ab Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:41:30 +0100 Subject: [PATCH 09/10] add missing files --- .../BufferedConsumerTests.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/HttpMock.Unit.Tests/BufferedConsumerTests.cs diff --git a/src/HttpMock.Unit.Tests/BufferedConsumerTests.cs b/src/HttpMock.Unit.Tests/BufferedConsumerTests.cs new file mode 100644 index 0000000..e6be2ba --- /dev/null +++ b/src/HttpMock.Unit.Tests/BufferedConsumerTests.cs @@ -0,0 +1,29 @@ +using System; +using System.Text; +using NUnit.Framework; + +namespace HttpMock.Unit.Tests +{ + [TestFixture] + public class BufferedConsumerTests + { + [Test] + public void Should_return_data_in_order() + { + string expected = "1234"; + string data = ""; + + var bufferedConsumer = new BufferedConsumer(s => { data = s; }, exception => { }); + + bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("1")), () => { }); + bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("2")), () => { }); + bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("3")), () => { }); + bufferedConsumer.OnData(new ArraySegment(Encoding.UTF8.GetBytes("4")), () => { }); + + + bufferedConsumer.OnEnd(); + + Assert.That(data, Is.EqualTo(expected)); + } + } +} \ No newline at end of file From 1111640463b05d47fb256fd692edbcb861f3ca0b Mon Sep 17 00:00:00 2001 From: Hibri Marzook Date: Fri, 8 Aug 2025 14:44:26 +0100 Subject: [PATCH 10/10] Add missing file to get the build working --- .../Properties/AssemblyInfo.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs diff --git a/src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs b/src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3eb036a --- /dev/null +++ b/src/HttpMock.Integration.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("StubHttp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("StubHttp")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c8dd9eca-377b-4b3d-a136-a5824d21119f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file