Compare commits

..

34 Commits
1.6.3 ... 1.6.9

Author SHA1 Message Date
Stef Heyenrath
c548600dea 1.6.9 2024-12-06 19:22:25 +01:00
Stef Heyenrath
7f640dfa0d Fix JsonPartialMatcher when using property names with dot (#1216)
Fix JsonPartialMatcher when using property names with dot (#1216)
2024-12-06 09:23:31 +01:00
Stef Heyenrath
4b3e9feca0 1.6.8 2024-11-24 16:22:32 +01:00
Stef Heyenrath
4aaed2a6ca Fix HandlebarsContext ParseAndEvaluate method (#1213)
* Fix HandlebarsContext ParseAndEvaluate method

* test

* xxx
2024-11-22 07:58:23 +01:00
Stef Heyenrath
6f73dfe360 Use GraphQL 8.2.1 (#1211) 2024-11-18 10:23:00 +01:00
Stef Heyenrath
f4103b47aa Fix security issues (#1206)
* .

* .

* x
2024-11-17 17:25:21 +01:00
Stef Heyenrath
edab3ad7e5 WireMockLogger 2024-11-01 10:31:23 +01:00
Stef Heyenrath
38c2131472 IWireMockLogger.Error(string, Exception) 2024-10-29 19:55:02 +01:00
Stef Heyenrath
3693d6a676 Log exception when (static) mapping file cannot be read (#1202) 2024-10-29 19:52:31 +01:00
Stef Heyenrath
214fb539ec 1.6.7 2024-10-17 18:49:24 +02:00
Stef Heyenrath
a468b89788 Fix Google.Protobuf.WellKnownTypes.Value (#1198)
* <PackageReference Include="ProtoBufJsonConverter" Version="0.5.0-preview-01" />

* Fix Google.Protobuf.WellKnownTypes.Value
2024-10-17 18:47:09 +02:00
Stef Heyenrath
1682c61a0c Use latest ProtoBufJsonConverter to support WellKnownTypes (#1161)
* Use latest ProtoBufJsonConverter to support WellKnownTypes

* Fix

* 02

* WireMockServer_WithBodyAsProtoBuf_WithWellKnownTypes

* .

* extra test

* 0.4.0-preview-06

* 7

* <PackageReference Include="ProtoBufJsonConverter" Version="0.4.0-preview-08" />

* Update README.md

* <PackageReference Include="ProtoBufJsonConverter" Version="0.4.0-preview-09" />

* <PackageReference Include="ProtoBufJsonConverter" Version="0.4.0" />

* Update README.md
2024-10-16 10:57:47 +02:00
dependabot[bot]
ac693e0f96 Bump System.Text.Json from 8.0.4 to 8.0.5 in /src/dotnet-WireMock.Net (#1197)
Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 8.0.4 to 8.0.5.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v8.0.4...v8.0.5)

---
updated-dependencies:
- dependency-name: System.Text.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-16 10:41:07 +02:00
dependabot[bot]
45755adae4 Bump System.Text.Json in /examples/WireMock.Net.Console.Net472.Classic (#1190)
Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 8.0.4 to 8.0.5.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v8.0.4...v8.0.5)

---
updated-dependencies:
- dependency-name: System.Text.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-15 21:46:08 +02:00
Stef Heyenrath
2ffdae1863 Upgrade System.Text.RegularExpressions to 4.3.1 to solve CVE-2019-0820 (#1194)
* Upgrade Handlebars.Net.Helpers to 2.4.6 to solve CVE-2019-0820

* .
2024-10-10 08:29:57 +02:00
Stef Heyenrath
5adbff0fa3 Update README.md (add blog) 2024-10-06 18:31:46 +02:00
Stef Heyenrath
5e04ff1a42 Add an architecture diagram for Aspire project (#1174)
* Add an architecture diagram for Aspire project

* .

* "WireMock.Net : " +

* .
2024-10-04 19:30:47 +02:00
Stef Heyenrath
eb7e6c397f 1.6.6 2024-10-01 17:43:18 +02:00
Stef Heyenrath
f56ecf943d Fix StaticMappingsPath in WireMockContainerBuilder (#1187)
* Fix StaticMappingsPath in WireMockContainerBuilder

* .
2024-10-01 17:39:59 +02:00
Stef Heyenrath
76ae1466cc Throw exception in case WithTransformer is used after WithBodyFromFile (#1185)
* Fix .WithBodyFromFile + .WithTransformer combination

* Ex
2024-09-29 21:29:34 +02:00
Stef Heyenrath
edbc7aeb5c 1.6.5 2024-09-28 10:26:38 +02:00
Stef Heyenrath
42306d1864 Add WireMock.Net.AspNetCore.Middleware (#1175)
* Add WireMock.Net.AspNetCore.Middleware

* .

* WireMock.Net.Middleware.Tests

* .

* X-WireMock-Response-Delay
2024-09-27 20:39:57 +02:00
Stef Heyenrath
c57590b2ba Set <SonarQubeExclude>true</SonarQubeExclude> in test projects (#1183) 2024-09-27 20:06:22 +02:00
Stef Heyenrath
dca3fd0260 WireMock.Net.Testcontainers: Use 'sheyenrath/wiremock.net-alpine' image as default for Linux (#1181)
* WireMock.Net.Testcontainers: Use 'sheyenrath/wiremock.net-alpine' image as default for Linux

* ...

* .

* WithBindMount

* fix

* r

* .
2024-09-27 19:10:51 +02:00
Jason Landbridge
95994421ae pass in the request when no matching is found to the warn logger (#1182) 2024-09-27 19:10:39 +02:00
Stef Heyenrath
697411555a Update README.md (add WireMock.Net.TUnit) 2024-09-26 18:47:36 +02:00
Stef Heyenrath
f89f0fa466 1.6.4 2024-09-25 08:56:44 +02:00
Stef Heyenrath
b892e85d2a Add WireMock.Net.TUnit project (#1179)
* Add WireMock.Net.TUnit project

* fix

* .

* fix

* bd

* 0.1.812

* dotnet test

* 0.1.817

* cat

* type

* type2

* find

* -- --diagnostic

* --no-build

* fix?
2024-09-25 08:52:40 +02:00
Stef Heyenrath
836976ca19 Upgrade CS-Script to version 4.8.17 (#1178) 2024-09-20 15:20:38 +02:00
Stef Heyenrath
c845f73dd0 Unpin Testcontainers version and upgrade to version 3.10.0 (#1177) 2024-09-20 15:20:25 +02:00
Stef Heyenrath
2cbbef01ae Refactor some code (IBodyDataExtensions) 2024-09-20 13:52:45 +02:00
Ruxo
dd80fd7822 Attempt to fix JSON parsing of text/plain content type (#1172)
* UseContentType

* Fix unit tests

* Add a unit test and an integration test for the fix.

* Simplify body type checking with GetBodyType extension.

* Split IBodyDataExtension, and use imperative style instead of functional style

* Remove excessive null forgiving operators

* Adjust braces

---------

Co-authored-by: Ruxo Zheng <rz@just.sent.as>
2024-09-20 13:19:32 +02:00
Stef Heyenrath
527278e60c Update the .NET Aspire tests (#1170)
* Skip unit tests when Docker is not running in Linux container mode using DockerIsRunningInLinuxContainerModeFact

* IgnoreOnContinuousIntegrationFact
2024-09-10 16:14:05 +02:00
Stef Heyenrath
7d7f1f8fbb Allow mapping without Path or Url (#1169) 2024-09-09 20:48:09 +02:00
120 changed files with 2706 additions and 482 deletions

View File

@@ -20,7 +20,10 @@ jobs:
- uses: actions/checkout@v4
- name: 'Execute Tests'
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
run: |
dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
dotnet test './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net8.0
linux-build-and-run:
name: Run Tests on Linux
@@ -33,7 +36,10 @@ jobs:
- uses: actions/checkout@v4
- name: 'Execute Tests'
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
run: |
dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
dotnet test './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net8.0
- name: Install .NET Aspire workload
run: dotnet workload install aspire

View File

@@ -1,3 +1,49 @@
# 1.6.9 (06 December 2024)
- [#1216](https://github.com/WireMock-Net/WireMock.Net/pull/1216) - Fix JsonPartialMatcher when using property names with dot [bug] contributed by [StefH](https://github.com/StefH)
- [#1210](https://github.com/WireMock-Net/WireMock.Net/issues/1210) - JsonPartialMatcher fails to match on property name that JsonMatcher matches [bug]
# 1.6.8 (24 November 2024)
- [#1202](https://github.com/WireMock-Net/WireMock.Net/pull/1202) - Log exception when (static) mapping file cannot be read [feature] contributed by [StefH](https://github.com/StefH)
- [#1206](https://github.com/WireMock-Net/WireMock.Net/pull/1206) - Fix security issues [bug] contributed by [StefH](https://github.com/StefH)
- [#1211](https://github.com/WireMock-Net/WireMock.Net/pull/1211) - Use GraphQL 8.2.1 [feature] contributed by [StefH](https://github.com/StefH)
- [#1213](https://github.com/WireMock-Net/WireMock.Net/pull/1213) - Fix HandlebarsContext ParseAndEvaluate method [bug] contributed by [StefH](https://github.com/StefH)
- [#1201](https://github.com/WireMock-Net/WireMock.Net/issues/1201) - Mapping file parse errors are not logged to the console [feature]
- [#1209](https://github.com/WireMock-Net/WireMock.Net/issues/1209) - Upgrade of GraphQL libs to the latest [feature]
- [#1212](https://github.com/WireMock-Net/WireMock.Net/issues/1212) - Response Body Does Not Include Text After Path Segment [bug]
# 1.6.7 (17 October 2024)
- [#1161](https://github.com/WireMock-Net/WireMock.Net/pull/1161) - Use latest ProtoBufJsonConverter to support WellKnownTypes [bug] contributed by [StefH](https://github.com/StefH)
- [#1190](https://github.com/WireMock-Net/WireMock.Net/pull/1190) - Bump System.Text.Json from 8.0.4 to 8.0.5 in /examples/WireMock.Net.Console.Net472.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#1194](https://github.com/WireMock-Net/WireMock.Net/pull/1194) - Upgrade System.Text.RegularExpressions to 4.3.1 to solve CVE-2019-0820 [bug] contributed by [StefH](https://github.com/StefH)
- [#1197](https://github.com/WireMock-Net/WireMock.Net/pull/1197) - Bump System.Text.Json from 8.0.4 to 8.0.5 in /src/dotnet-WireMock.Net [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#1198](https://github.com/WireMock-Net/WireMock.Net/pull/1198) - Fix Google.Protobuf.WellKnownTypes.Value [bug] contributed by [StefH](https://github.com/StefH)
- [#1144](https://github.com/WireMock-Net/WireMock.Net/issues/1144) - Using google.protobuf.Empty as response results in a bad gRPC response [bug]
- [#1153](https://github.com/WireMock-Net/WireMock.Net/issues/1153) - Grpc support for multiple proto files [feature]
- [#1193](https://github.com/WireMock-Net/WireMock.Net/issues/1193) - Snyk issue : Regular Expression Denial of Service [bug]
# 1.6.6 (01 October 2024)
- [#1185](https://github.com/WireMock-Net/WireMock.Net/pull/1185) - Throw exception in case WithTransformer is used after WithBodyFromFile [bug] contributed by [StefH](https://github.com/StefH)
- [#1187](https://github.com/WireMock-Net/WireMock.Net/pull/1187) - Fix StaticMappingsPath in WireMockContainerBuilder [bug] contributed by [StefH](https://github.com/StefH)
- [#1184](https://github.com/WireMock-Net/WireMock.Net/issues/1184) - .WithBodyFromFile() + .WithTransformer(transformContentFromBodyAsFile: true) = empty string [bug]
- [#1186](https://github.com/WireMock-Net/WireMock.Net/issues/1186) - WithMappings path is null on Build() call [bug]
# 1.6.5 (28 September 2024)
- [#1175](https://github.com/WireMock-Net/WireMock.Net/pull/1175) - Add WireMock.Net.AspNetCore.Middleware [feature] contributed by [StefH](https://github.com/StefH)
- [#1181](https://github.com/WireMock-Net/WireMock.Net/pull/1181) - WireMock.Net.Testcontainers: Use 'sheyenrath/wiremock.net-alpine' image as default for Linux [feature] contributed by [StefH](https://github.com/StefH)
- [#1182](https://github.com/WireMock-Net/WireMock.Net/pull/1182) - pass in the request when no matching is found to the warn logger [feature] contributed by [JasonLandbridge](https://github.com/JasonLandbridge)
# 1.6.4 (25 September 2024)
- [#1169](https://github.com/WireMock-Net/WireMock.Net/pull/1169) - Allow mapping without Path or Url [bug] contributed by [StefH](https://github.com/StefH)
- [#1170](https://github.com/WireMock-Net/WireMock.Net/pull/1170) - Update the .NET Aspire tests [feature] contributed by [StefH](https://github.com/StefH)
- [#1172](https://github.com/WireMock-Net/WireMock.Net/pull/1172) - Fix JSON parsing of text/plain content type [bug] contributed by [ruxo](https://github.com/ruxo)
- [#1177](https://github.com/WireMock-Net/WireMock.Net/pull/1177) - Unpin Testcontainers version and upgrade to version 3.10.0 [bug] contributed by [StefH](https://github.com/StefH)
- [#1178](https://github.com/WireMock-Net/WireMock.Net/pull/1178) - Upgrade CS-Script to version 4.8.17 [feature] contributed by [StefH](https://github.com/StefH)
- [#1179](https://github.com/WireMock-Net/WireMock.Net/pull/1179) - Add WireMock.Net.TUnit project [feature] contributed by [StefH](https://github.com/StefH)
- [#1146](https://github.com/WireMock-Net/WireMock.Net/issues/1146) - Bump Request CS-Script 4.8.13 to 4.8.17 [feature]
- [#1167](https://github.com/WireMock-Net/WireMock.Net/issues/1167) - Admin API fails to create a mapping with Request Header matching using WildCardMatcher [bug]
- [#1168](https://github.com/WireMock-Net/WireMock.Net/issues/1168) - Numbers in text/plain content is parsed as JSON. [bug]
- [#1176](https://github.com/WireMock-Net/WireMock.Net/issues/1176) - WireMock.NET TestContainer Dependency Constraint Issue [bug]
# 1.6.3 (07 September 2024)
- [#1165](https://github.com/WireMock-Net/WireMock.Net/pull/1165) - Fix listen on AnyIP for url 0.0.0.0 contributed by [cocoon](https://github.com/cocoon)
- [#1154](https://github.com/WireMock-Net/WireMock.Net/issues/1154) - Listen on all ips [bug]
@@ -42,9 +88,7 @@
# 1.5.60 (09 July 2024)
- [#1128](https://github.com/WireMock-Net/WireMock.Net/pull/1128) - Add Handlebars.Net.Helpers.Xslt [feature] contributed by [StefH](https://github.com/StefH)
- [#1130](https://github.com/WireMock-Net/WireMock.Net/pull/1130) - Add AdminPath to WireMockServerSettings [feature] contributed by [StefH](https://github.com/StefH)
- [#1131](https://github.com/WireMock-Net/WireMock.Net/pull/1131) - Add unit tests for AdminApiMappingBuilder [test] contributed by [StefH](https://github.com/StefH)
- [#1132](https://github.com/WireMock-Net/WireMock.Net/pull/1132) - Multipart Matcher Fix [bug] contributed by [rmeshksar](https://github.com/rmeshksar)
- [#1133](https://github.com/WireMock-Net/WireMock.Net/pull/1133) - Add unit tests for AdminApiMappingBuilder_ [test] contributed by [StefH](https://github.com/StefH)
- [#1134](https://github.com/WireMock-Net/WireMock.Net/pull/1134) - Remove some files and folders [refactor] contributed by [StefH](https://github.com/StefH)
- [#1119](https://github.com/WireMock-Net/WireMock.Net/issues/1119) - Error in RequestMessageMultiPartMatcher [bug]
- [#1121](https://github.com/WireMock-Net/WireMock.Net/issues/1121) - XML transformation [feature]
@@ -129,7 +173,6 @@
# 1.5.42 (09 December 2023)
- [#1023](https://github.com/WireMock-Net/WireMock.Net/pull/1023) - Fix Mapping[] for WireMock.Org REST API [bug] contributed by [StefH](https://github.com/StefH)
- [#1029](https://github.com/WireMock-Net/WireMock.Net/pull/1029) - Add ResponseWithHandlebarsDateTimeTests [test] contributed by [StefH](https://github.com/StefH)
- [#1031](https://github.com/WireMock-Net/WireMock.Net/pull/1031) - Calling Reset also resets the scenarios [bug] contributed by [StefH](https://github.com/StefH)
- [#1034](https://github.com/WireMock-Net/WireMock.Net/pull/1034) - Workaround for: Random.Generate Type=&quot;Long&quot; [bug] contributed by [StefH](https://github.com/StefH)
- [#1021](https://github.com/WireMock-Net/WireMock.Net/issues/1021) - GetAdminMappingsResult in WireMock.Org.Abstractions should contain list of mappings [bug]
@@ -138,12 +181,9 @@
# 1.5.41 (04 December 2023)
- [#1012](https://github.com/WireMock-Net/WireMock.Net/pull/1012) - GraphQL - custom scalar support [feature] contributed by [StefH](https://github.com/StefH)
- [#1018](https://github.com/WireMock-Net/WireMock.Net/pull/1018) - Add .NET 8 [feature] contributed by [StefH](https://github.com/StefH)
- [#1020](https://github.com/WireMock-Net/WireMock.Net/pull/1020) - Add Github Action [test] contributed by [StefH](https://github.com/StefH)
- [#984](https://github.com/WireMock-Net/WireMock.Net/issues/984) - GraphQL Schema validation with custom scalars [feature]
# 1.5.40 (07 November 2023)
- [#1009](https://github.com/WireMock-Net/WireMock.Net/pull/1009) - Add more tests for JmesPathMatchers and StringUtils.ParseMatchOperator [test] contributed by [StefH](https://github.com/StefH)
- [#1010](https://github.com/WireMock-Net/WireMock.Net/pull/1010) - Add unit tests for HttpClient with WebProxy [test] contributed by [StefH](https://github.com/StefH)
- [#1011](https://github.com/WireMock-Net/WireMock.Net/pull/1011) - GraphQL - add support for standard scalar types in the schema [feature] contributed by [StefH](https://github.com/StefH)
- [#1014](https://github.com/WireMock-Net/WireMock.Net/pull/1014) - FluentAssertions - WithBody and WithBodyAsJson and WithBodyAsBytes contributed by [StefH](https://github.com/StefH)
@@ -155,7 +195,6 @@
- [#1005](https://github.com/WireMock-Net/WireMock.Net/pull/1005) - Support for xml namespaces in XPathMatcher [feature] contributed by [cal-schleupen](https://github.com/cal-schleupen)
# 1.5.37 (27 September 2023)
- [#998](https://github.com/WireMock-Net/WireMock.Net/pull/998) - Add JmesPathMatcher UnitTests [test] contributed by [StefH](https://github.com/StefH)
- [#1004](https://github.com/WireMock-Net/WireMock.Net/pull/1004) - Fix MappingModel to map IgnoreCase and RejectOnMatch for Headers, Cookies and Parameters [bug] contributed by [StefH](https://github.com/StefH)
- [#1003](https://github.com/WireMock-Net/WireMock.Net/issues/1003) - Store Mapping per POST request ignores &quot;IgnoreCase&quot; property of HeaderModel [bug]
@@ -167,7 +206,6 @@
- [#1001](https://github.com/WireMock-Net/WireMock.Net/issues/1001) - SaveUnmatchedRequests stopped working [bug]
# 1.5.35 (19 August 2023)
- [#992](https://github.com/WireMock-Net/WireMock.Net/pull/992) - Add extra unit test for WithParam multiple values comma [test] contributed by [StefH](https://github.com/StefH)
- [#993](https://github.com/WireMock-Net/WireMock.Net/pull/993) - Update JSONPathMatcher.cs to cover the string path selection to a child contributed by [DayLightDancer](https://github.com/DayLightDancer)
# 1.5.34 (04 August 2023)
@@ -193,7 +231,6 @@
# 1.5.30 (28 June 2023)
- [#959](https://github.com/WireMock-Net/WireMock.Net/pull/959) - Fixed logic for FluentAssertions WithHeader [bug] contributed by [StefH](https://github.com/StefH)
- [#961](https://github.com/WireMock-Net/WireMock.Net/pull/961) - Add unit-test for Param MatcherModel LinqMatcher [test] contributed by [StefH](https://github.com/StefH)
- [#962](https://github.com/WireMock-Net/WireMock.Net/pull/962) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.Console.Net472.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#963](https://github.com/WireMock-Net/WireMock.Net/pull/963) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#958](https://github.com/WireMock-Net/WireMock.Net/issues/958) - [FluentAssertions] Should().HaveReceivedACall().WithHeader() only checks the first header with the matching key. [bug]
@@ -214,7 +251,6 @@
- [#945](https://github.com/WireMock-Net/WireMock.Net/issues/945) - Webhook logging [feature]
# 1.5.26 (25 May 2023)
- [#938](https://github.com/WireMock-Net/WireMock.Net/pull/938) - Add more unitests for CSharpFormatter utils [test] contributed by [StefH](https://github.com/StefH)
- [#939](https://github.com/WireMock-Net/WireMock.Net/pull/939) - WireMockMiddleware should use HandleRequestsSynchronously correctly [bug] contributed by [StefH](https://github.com/StefH)
- [#940](https://github.com/WireMock-Net/WireMock.Net/pull/940) - Code generator improvements contributed by [cezarypiatek](https://github.com/cezarypiatek)
- [#942](https://github.com/WireMock-Net/WireMock.Net/pull/942) - Add GetParameter method to IRequestMessage [feature] contributed by [StefH](https://github.com/StefH)
@@ -263,7 +299,6 @@
# 1.5.17 (25 February 2023)
- [#881](https://github.com/WireMock-Net/WireMock.Net/pull/881) - Add WithBodyAsJson builder method with accepts a Func [feature] contributed by [StefH](https://github.com/StefH)
- [#882](https://github.com/WireMock-Net/WireMock.Net/pull/882) - Add example code to test HTTP Status 400 and 500 [test] contributed by [StefH](https://github.com/StefH)
- [#890](https://github.com/WireMock-Net/WireMock.Net/pull/890) - AdminApiMappingBuilder [feature] contributed by [StefH](https://github.com/StefH)
# 1.5.16 (01 February 2023)
@@ -279,7 +314,6 @@
- [#871](https://github.com/WireMock-Net/WireMock.Net/pull/871) - Add UseWebhooksFireAndForget to Server ConvertMapping [bug] contributed by [ggradnig](https://github.com/ggradnig)
- [#872](https://github.com/WireMock-Net/WireMock.Net/pull/872) - Fix unsubscribe from LogEntriesChanged event handler [bug] contributed by [StefH](https://github.com/StefH)
- [#875](https://github.com/WireMock-Net/WireMock.Net/pull/875) - Fix Self referencing loop detected for property [bug] contributed by [eseneckiy](https://github.com/eseneckiy)
- [#877](https://github.com/WireMock-Net/WireMock.Net/pull/877) - Add unit test example for Transformer Handlebars String.Append String.Join [test] contributed by [StefH](https://github.com/StefH)
- [#701](https://github.com/WireMock-Net/WireMock.Net/issues/701) - Allow to create MappingModel from c# to be able to configure local and remote mocks similarly [feature]
- [#867](https://github.com/WireMock-Net/WireMock.Net/issues/867) - Can I build mappings with code and save them to JSON-file without starting server [feature]
- [#870](https://github.com/WireMock-Net/WireMock.Net/issues/870) - Can not unsubscribe from LogEntriesChanged event. [bug]
@@ -359,7 +393,6 @@
# 1.5.2 (24 July 2022)
- [#769](https://github.com/WireMock-Net/WireMock.Net/pull/769) - Bump Microsoft.AspNetCore.Server.Kestrel.Core from 2.1.3 to 2.1.7 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#770](https://github.com/WireMock-Net/WireMock.Net/pull/770) - Added some more tests for JsonMatcher + refactored some code to use nullable [test] contributed by [StefH](https://github.com/StefH)
- [#771](https://github.com/WireMock-Net/WireMock.Net/pull/771) - JsonPartialMatcher - support Regex [feature] contributed by [StefH](https://github.com/StefH)
# 1.5.1 (08 July 2022)
@@ -645,9 +678,6 @@
- [#492](https://github.com/WireMock-Net/WireMock.Net/pull/492) - Mark FluentMockServer, FluentMockServerSettings, BlacklistedHeaders and BlacklistedCookies as obsolete [feature] contributed by [StefH](https://github.com/StefH)
- [#489](https://github.com/WireMock-Net/WireMock.Net/issues/489) - Change &quot;blacklist&quot; and &quot;whitelist&quot; terms [feature]
# 1.2.15 (19 July 2020)
- [#485](https://github.com/WireMock-Net/WireMock.Net/pull/485) - Add fluent assertions for headers [test] contributed by [akamud](https://github.com/akamud)
# 1.2.14 (09 July 2020)
- [#479](https://github.com/WireMock-Net/WireMock.Net/pull/479) - An OpenApi (swagger) parser to generate MappingModel or mapping.json file [feature] contributed by [StefH](https://github.com/StefH)
- [#482](https://github.com/WireMock-Net/WireMock.Net/pull/482) - Add PartialMatch to logging / logentries [feature] contributed by [StefH](https://github.com/StefH)
@@ -948,7 +978,6 @@
# 1.0.4.21 (30 November 2018)
- [#221](https://github.com/WireMock-Net/WireMock.Net/pull/221) - Update dependencies [feature] contributed by [StefH](https://github.com/StefH)
- [#229](https://github.com/WireMock-Net/WireMock.Net/pull/229) - Fix proxy tests [test] contributed by [StefH](https://github.com/StefH)
- [#230](https://github.com/WireMock-Net/WireMock.Net/pull/230) - Add HandleBars Random functionality (#219) [feature] contributed by [StefH](https://github.com/StefH)
- [#231](https://github.com/WireMock-Net/WireMock.Net/pull/231) - Use RandomDataGenerator.Net 1.0.3.0 contributed by [StefH](https://github.com/StefH)
- [#232](https://github.com/WireMock-Net/WireMock.Net/pull/232) - Add SonarLint checks [feature] contributed by [StefH](https://github.com/StefH)

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.6.3</VersionPrefix>
<VersionPrefix>1.6.9</VersionPrefix>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
@@ -43,13 +43,22 @@
</When>
</Choose>
<PropertyGroup>
<NuGetAudit>true</NuGetAudit>
<!--<NuGetAuditLevel>low</NuGetAuditLevel>-->
<NuGetAuditMode>all</NuGetAuditMode>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" />
<!-- CVE-2019-0820 -->
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.29.0.95321">
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.32.0.97167">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -1,7 +1,7 @@
rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.6.3
SET version=1.6.9
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
GitHubReleaseNotes --output PackageReleaseNotes.txt --skip-empty-releases --exclude-labels question invalid doc duplicate example environment --template PackageReleaseNotes.template --version %version% --token %GH_TOKEN%
GitHubReleaseNotes --output PackageReleaseNotes.txt --skip-empty-releases --exclude-labels test question invalid doc duplicate example environment --template PackageReleaseNotes.template --version %version% --token %GH_TOKEN%

View File

@@ -1,5 +1,5 @@
# 1.6.3 (07 September 2024)
- #1165 Fix listen on AnyIP for url 0.0.0.0
- #1154 Listen on all ips [bug]
# 1.6.9 (06 December 2024)
- #1216 Fix JsonPartialMatcher when using property names with dot [bug]
- #1210 JsonPartialMatcher fails to match on property name that JsonMatcher matches [bug]
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -16,9 +16,10 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
* Can be used for Aspire Distributed Application testing
## :memo: Blogs
- [mstack.nl : Generate C# Code from Mapping(s)](https://mstack.nl/blog/20230201-wiremock.net-tocode/)
- [mstack.nl : Chaos Engineering with Fault Injections](https://mstack.nl/blogs/wiremock-net-chaos-engineering-with-fault-injections/)
- [mstack.nl : gRPC / ProtoBuf Support](https://mstack.nl/blogs/wiremock-net-grpc/)
- [mstack.nl : Generate C# Code from Mapping(s)](https://mstack.nl/blog/20230201-wiremock.net-tocode)
- [mstack.nl : Chaos Engineering with Fault Injections](https://mstack.nl/blogs/wiremock-net-chaos-engineering-with-fault-injections)
- [mstack.nl : gRPC / ProtoBuf Support](https://mstack.nl/blogs/wiremock-net-grpc)
- [mstack.nl : Build and test your own .NET Aspire component](https://mstack.nl/blogs/wiremock-net-aspire-component/)
## :computer: Project Info
@@ -41,13 +42,18 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
| - | - | - |
| &nbsp;&nbsp;**WireMock.Net** | [![NuGet Badge WireMock.Net](https://img.shields.io/nuget/v/WireMock.Net)](https://www.nuget.org/packages/WireMock.Net) | [![MyGet Badge WireMock.Net](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
| &nbsp;&nbsp;**WireMock.Net.StandAlone** | [![NuGet Badge WireMock.Net](https://img.shields.io/nuget/v/WireMock.Net.StandAlone)](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [![MyGet Badge WireMock.Net.StandAlone](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.StandAlone?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
| &nbsp;&nbsp;**WireMock.Net.FluentAssertions** | [![NuGet Badge WireMock.Net.FluentAssertions](https://img.shields.io/nuget/v/WireMock.Net.FluentAssertions)](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [![MyGet Badge WireMock.Net.FluentAssertions](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.FluentAssertions?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
| &nbsp;&nbsp;**WireMock.Net.Matchers.CSharpCode** | [![NuGet Badge WireMock.Net.Matchers.CSharpCode](https://img.shields.io/nuget/v/WireMock.Net.Matchers.CSharpCode)](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [![MyGet Badge WireMock.Net.Matchers.CSharpCode](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Matchers.CSharpCode?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
| &nbsp;&nbsp;**WireMock.Net.OpenApiParser** | [![NuGet Badge WireMock.Net.OpenApiParser](https://img.shields.io/nuget/v/WireMock.Net.OpenApiParser)](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [![MyGet Badge WireMock.Net.OpenApiParser](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.OpenApiParser?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
| &nbsp;&nbsp;**WireMock.Net.RestClient** | [![NuGet Badge WireMock.Net.RestClient](https://img.shields.io/nuget/v/WireMock.Net.RestClient)](https://www.nuget.org/packages/WireMock.Net.RestClient) | [![MyGet Badge WireMock.Net.RestClient](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.RestClient?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
| &nbsp;&nbsp;**WireMock.Net.xUnit** | [![NuGet Badge WireMock.Net.xUnit](https://img.shields.io/nuget/v/WireMock.Net.xUnit)](https://www.nuget.org/packages/WireMock.Net.xUnit) | [![MyGet Badge WireMock.Net.xUnit](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.xUnit?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
| &nbsp;&nbsp;**WireMock.Net.Testcontainers** | [![NuGet Badge WireMock.Net.Testcontainers](https://img.shields.io/nuget/v/WireMock.Net.Testcontainers)](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [![MyGet Badge WireMock.Net.Testcontainers](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Testcontainers?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
| &nbsp;&nbsp;**WireMock.Net.Aspire** | [![NuGet Badge WireMock.Net.Aspire](https://img.shields.io/nuget/v/WireMock.Net.Aspire)](https://www.nuget.org/packages/WireMock.Net.Aspire) | [![MyGet Badge WireMock.Net.Aspire](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Aspire?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire)
| &nbsp;&nbsp;**WireMock.Net.AspNetCore.Middleware** | [![NuGet Badge WireMock.Net.AspNetCore.Middleware](https://img.shields.io/nuget/v/WireMock.Net.AspNetCore.Middleware)](https://www.nuget.org/packages/WireMock.Net.AspNetCore.Middleware) | [![MyGet Badge WireMock.Net.AspNetCore.Middleware](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.AspNetCore.Middleware?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.AspNetCore.Middleware)
| | | |
| &nbsp;&nbsp;**WireMock.Net.FluentAssertions** | [![NuGet Badge WireMock.Net.FluentAssertions](https://img.shields.io/nuget/v/WireMock.Net.FluentAssertions)](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [![MyGet Badge WireMock.Net.FluentAssertions](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.FluentAssertions?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
| &nbsp;&nbsp;**WireMock.Net.xUnit** | [![NuGet Badge WireMock.Net.xUnit](https://img.shields.io/nuget/v/WireMock.Net.xUnit)](https://www.nuget.org/packages/WireMock.Net.xUnit) | [![MyGet Badge WireMock.Net.xUnit](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.xUnit?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
| &nbsp;&nbsp;**WireMock.Net.TUnit** | [![NuGet Badge WireMock.Net.TUnit](https://img.shields.io/nuget/v/WireMock.Net.TUnit)](https://www.nuget.org/packages/WireMock.Net.TUnit) | [![MyGet Badge WireMock.Net.TUnit](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.TUnit?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.TUnit)
| | | |
| &nbsp;&nbsp;**WireMock.Net.Matchers.CSharpCode** | [![NuGet Badge WireMock.Net.Matchers.CSharpCode](https://img.shields.io/nuget/v/WireMock.Net.Matchers.CSharpCode)](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [![MyGet Badge WireMock.Net.Matchers.CSharpCode](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Matchers.CSharpCode?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
| &nbsp;&nbsp;**WireMock.Net.OpenApiParser** | [![NuGet Badge WireMock.Net.OpenApiParser](https://img.shields.io/nuget/v/WireMock.Net.OpenApiParser)](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [![MyGet Badge WireMock.Net.OpenApiParser](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.OpenApiParser?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
| | | |
| &nbsp;&nbsp;**WireMock.Net.RestClient** | [![NuGet Badge WireMock.Net.RestClient](https://img.shields.io/nuget/v/WireMock.Net.RestClient)](https://www.nuget.org/packages/WireMock.Net.RestClient) | [![MyGet Badge WireMock.Net.RestClient](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.RestClient?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
| &nbsp;&nbsp;**WireMock.Org.RestClient** | [![NuGet Badge WireMock.Org.RestClient](https://img.shields.io/nuget/v/WireMock.Org.RestClient)](https://www.nuget.org/packages/WireMock.Org.RestClient) | [![MyGet Badge WireMock.Org.RestClient](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Org.RestClient?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)

View File

@@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8F890C6F-9ACC-438D-928A-AD61CDA862F2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0BB8B634-407A-4610-A91F-11586990767A}"
ProjectSection(SolutionItems) = preProject
test\Directory.Build.props = test\Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net", "src\WireMock.Net\WireMock.Net.csproj", "{D3804228-91F4-4502-9595-39584E5A01AD}"
EndProject
@@ -131,6 +134,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Aspire.TestApp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspireApp1.AppHostOriginal", "examples-Aspire\AspireApp1.AppHostOriginal\AspireApp1.AppHostOriginal.csproj", "{C9210DA3-F390-4598-8512-349A473FE9C9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TUnit", "src\WireMock.Net.TUnit\WireMock.Net.TUnit.csproj", "{91024A93-848F-4A02-AF53-5EBE5834E23C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TUnitTests", "test\WireMock.Net.TUnitTests\WireMock.Net.TUnitTests.csproj", "{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.WebApplication", "examples\WireMock.Net.WebApplication\WireMock.Net.WebApplication.csproj", "{E72ADFAB-4B42-439E-B1EE-C06E504B35D2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.AspNetCore.Middleware", "src\WireMock.Net.AspNetCore.Middleware\WireMock.Net.AspNetCore.Middleware.csproj", "{B6269AAC-170A-4346-8B9A-579DED3D9A13}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TestWebApplication", "test\WireMock.Net.TestWebApplication\WireMock.Net.TestWebApplication.csproj", "{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Middleware.Tests", "test\WireMock.Net.Middleware.Tests\WireMock.Net.Middleware.Tests.csproj", "{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -317,6 +332,30 @@ Global
{C9210DA3-F390-4598-8512-349A473FE9C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9210DA3-F390-4598-8512-349A473FE9C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9210DA3-F390-4598-8512-349A473FE9C9}.Release|Any CPU.Build.0 = Release|Any CPU
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Release|Any CPU.Build.0 = Release|Any CPU
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Release|Any CPU.Build.0 = Release|Any CPU
{E72ADFAB-4B42-439E-B1EE-C06E504B35D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E72ADFAB-4B42-439E-B1EE-C06E504B35D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E72ADFAB-4B42-439E-B1EE-C06E504B35D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E72ADFAB-4B42-439E-B1EE-C06E504B35D2}.Release|Any CPU.Build.0 = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Release|Any CPU.Build.0 = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|Any CPU.Build.0 = Release|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -369,6 +408,12 @@ Global
{CE602F57-FEF8-4559-A9E0-6200BE1BF398} = {0BB8B634-407A-4610-A91F-11586990767A}
{F1B5999D-D22E-48A6-AB86-18A7876BD32E} = {0BB8B634-407A-4610-A91F-11586990767A}
{C9210DA3-F390-4598-8512-349A473FE9C9} = {AD474543-0715-49F2-A284-936B060BF736}
{91024A93-848F-4A02-AF53-5EBE5834E23C} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE} = {0BB8B634-407A-4610-A91F-11586990767A}
{E72ADFAB-4B42-439E-B1EE-C06E504B35D2} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{B6269AAC-170A-4346-8B9A-579DED3D9A13} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE} = {0BB8B634-407A-4610-A91F-11586990767A}
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5} = {0BB8B634-407A-4610-A91F-11586990767A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}

View File

@@ -38,7 +38,7 @@ jobs:
# See: https://docs.sonarsource.com/sonarcloud/enriching/test-coverage/dotnet-test-coverage
- script: |
dotnet sonarscanner begin /k:"WireMock-Net_WireMock.Net" /o:"wiremock-net" /d:sonar.branch.name=$(Build.SourceBranchName) /d:sonar.host.url="https://sonarcloud.io" /d:sonar.token="$(SONAR_TOKEN)" /d:sonar.pullrequest.provider=github /d:sonar.dotnet.excludeTestProjects=true /d:sonar.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
dotnet sonarscanner begin /k:"WireMock-Net_WireMock.Net" /o:"wiremock-net" /d:sonar.branch.name=$(Build.SourceBranchName) /d:sonar.host.url="https://sonarcloud.io" /d:sonar.token="$(SONAR_TOKEN)" /d:sonar.pullrequest.provider=github /d:sonar.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
displayName: 'Begin analysis on SonarCloud'
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
@@ -52,13 +52,15 @@ jobs:
- task: CmdLine@2
inputs:
script: |
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-1.xml"
displayName: 'Execute WireMock.Net.Tests with Coverage'
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-xunit.xml"
dotnet-coverage collect "dotnet test ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-tunit.xml"
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-middleware.xml"
displayName: 'Execute WireMock.Net.Tests with Coverage'
- task: CmdLine@2
inputs:
script: |
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-2.xml"
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-aspire.xml"
displayName: 'Execute WireMock.Net.Aspire.Tests with Coverage'
- task: CmdLine@2

View File

@@ -2,20 +2,48 @@ using AspireApp1.AppHost;
var builder = DistributedApplication.CreateBuilder(args);
//IResourceBuilder<ProjectResource> apiService = builder.AddProject<Projects.AspireApp1_ApiService>("apiservice");
IResourceBuilder<ProjectResource> apiService = builder.AddProject<Projects.AspireApp1_ApiService>("apiservice");
var mappingsPath = Path.Combine(Directory.GetCurrentDirectory(), "WireMockMappings");
Console.WriteLine($"MappingsPath: {mappingsPath}");
//IResourceBuilder<WireMockServerResource> apiService = builder
// .AddWireMock("apiservice", WireMockServerArguments.DefaultPort)
// .WithMappingsPath(mappingsPath)
// .WithReadStaticMappings()
// .WithApiMappingBuilder(WeatherForecastApiMock.BuildAsync);
var wiremock = builder
.AddWireMock("apiservice", WireMockServerArguments.DefaultPort)
.WithMappingsPath(mappingsPath)
.WithReadStaticMappings()
.WithApiMappingBuilder(WeatherForecastApiMock.BuildAsync);
//var apiServiceUsedForDocs = builder
// .AddWireMock("apiservice1", WireMockServerArguments.DefaultPort)
// .WithApiMappingBuilder(adminApiBuilder =>
// {
// var summaries = new[]
// {
// "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
// };
// adminApiBuilder.Given(b => b
// .WithRequest(request => request
// .UsingGet()
// .WithPath("/weatherforecast2")
// )
// .WithResponse(response => response
// .WithHeaders(h => h.Add("Content-Type", "application/json"))
// .WithBodyAsJson(() => Enumerable.Range(1, 5).Select(index =>
// new WeatherForecast
// (
// DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
// Random.Shared.Next(-20, 55),
// "WireMock.Net : " + summaries[Random.Shared.Next(summaries.Length)]
// ))
// .ToArray())
// )
// );
// return Task.CompletedTask;
// });
builder.AddProject<Projects.AspireApp1_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(wiremock);
.WithReference(apiService);
builder.Build().Run();

View File

@@ -23,7 +23,7 @@ internal class WeatherForecastApiMock
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
"WireMock.Net 2 : " + summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray())
)

View File

@@ -11,27 +11,27 @@
{
"date": "2024-05-24",
"temperatureC": -17,
"summary": "Balmy"
"summary": "WireMock.Net 1 : Balmy"
},
{
"date": "2024-05-25",
"temperatureC": -13,
"summary": "Mild"
"summary": "WireMock.Net 1 : Mild"
},
{
"date": "2024-05-26",
"temperatureC": 31,
"summary": "Bracing"
"summary": "WireMock.Net 1 : Bracing"
},
{
"date": "2024-05-27",
"temperatureC": 6,
"summary": "Hot"
"summary": "WireMock.Net 1 : Hot"
},
{
"date": "2024-05-28",
"temperatureC": -2,
"summary": "Mild"
"summary": "WireMock.Net 1 : Mild"
}
],
"Headers": {

View File

@@ -39,7 +39,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
@@ -47,31 +47,31 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Handlebars" publicKeyToken="22225d0bf33cd661" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.2.0" newVersion="2.1.2.0" />
<bindingRedirect oldVersion="0.0.0.0-2.1.6.0" newVersion="2.1.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.Core" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.1.2" newVersion="2.4.1.2" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="XPath2" publicKeyToken="463c6d7fb740c7e5" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.4.0" newVersion="1.1.4.0" />
<bindingRedirect oldVersion="0.0.0.0-1.1.5.0" newVersion="1.1.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.1" newVersion="4.0.5.1" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Handlebars.Net.Helpers" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.1.2" newVersion="2.4.1.2" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Dynamic.Core" publicKeyToken="0f07ec44de6ac832" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.23.0" newVersion="1.2.23.0" />
<bindingRedirect oldVersion="0.0.0.0-1.3.14.0" newVersion="1.3.14.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Fare" publicKeyToken="ea68d375bf33a7c8" culture="neutral" />
@@ -83,7 +83,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.Json" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.3.10.0" newVersion="2.3.10.0" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
@@ -91,20 +91,324 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" />
<bindingRedirect oldVersion="0.0.0.0-7.2.0.0" newVersion="7.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" />
<bindingRedirect oldVersion="0.0.0.0-7.2.0.0" newVersion="7.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" />
<bindingRedirect oldVersion="0.0.0.0-6.34.0.0" newVersion="6.34.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NJsonSchema" publicKeyToken="c2f9c3bdfae56102" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.7.2.0" newVersion="10.7.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AnyOf" publicKeyToken="b35e6abbb527c6b1" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.3.0.0" newVersion="0.3.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.DynamicLinq" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.Humanizer" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.Random" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.Xeger" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="HandlebarsDotNet.Helpers.XPath" publicKeyToken="00d131fae0c250bc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Humanizer" publicKeyToken="979442b78dfc278e" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.14.0.0" newVersion="2.14.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="JmesPath.Net" publicKeyToken="b29d616b7f4faff0" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.125.0" newVersion="1.0.125.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.17.0" newVersion="2.0.17.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Authentication.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Authentication.Core" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Connections.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Diagnostics" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Diagnostics.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.HostFiltering" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Hosting" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Hosting.Server.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Http" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Http.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Http.Extensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Http.Features" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.HttpOverrides" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Routing" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Routing.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Server.IISIntegration" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Server.Kestrel" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Server.Kestrel.Core" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Server.Kestrel.Https" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNetCore.WebUtilities" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.Binder" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.CommandLine" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.EnvironmentVariables" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.FileExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.Json" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.UserSecrets" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.FileProviders.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.FileProviders.Physical" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.FileSystemGlobbing" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Configuration" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Console" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Debug" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.EventSource" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.ObjectPool" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Options.ConfigurationExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Abstractions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.2.0.0" newVersion="7.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.JsonWebTokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.2.0.0" newVersion="7.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocols" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.12.2.0" newVersion="6.12.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocols.OpenIdConnect" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.12.2.0" newVersion="6.12.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Net.Http.Headers" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Namotion.Reflection" publicKeyToken="c2f9c3bdfae56102" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.10.0" newVersion="2.0.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NJsonSchema.Extensions" publicKeyToken="e52fadf300daf456" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.1.0.0" newVersion="0.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NSwag.Core" publicKeyToken="c2d88086e098d109" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.16.1.0" newVersion="13.16.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="RandomDataGenerator" publicKeyToken="ae5c571d29a3b8d9" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.16.0" newVersion="1.0.16.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Scriban.Signed" publicKeyToken="5675fb69b15f2433" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.4.0" newVersion="2.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SimMetrics.Net" publicKeyToken="c58dc06d59f3391b" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.5.0" newVersion="1.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.8.0" newVersion="5.2.8.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.4.3.0" newVersion="1.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Principal.Windows" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.5" newVersion="8.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="TinyMapper" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="XPath2.Extensions" publicKeyToken="463c6d7fb740c7e5" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.5.0" newVersion="1.1.5.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -158,7 +158,7 @@
<HintPath>..\..\packages\Microsoft.AspNetCore.WebUtilities.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.WebUtilities.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\..\packages/Microsoft.Bcl.AsyncInterfaces.8.0.0/lib/net462/Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
@@ -234,15 +234,15 @@
<HintPath>..\..\packages\Microsoft.Extensions.Primitives.5.0.0\lib\net461\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Abstractions, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<HintPath>..\..\packages/Microsoft.IdentityModel.Abstractions.7.2.0/lib/net472/Microsoft.IdentityModel.Abstractions.dll</HintPath>
<HintPath>..\..\packages\Microsoft.IdentityModel.Abstractions.7.2.0\lib\net472\Microsoft.IdentityModel.Abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.IdentityModel.JsonWebTokens, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<HintPath>..\..\packages/Microsoft.IdentityModel.JsonWebTokens.7.2.0/lib/net472/Microsoft.IdentityModel.JsonWebTokens.dll</HintPath>
<HintPath>..\..\packages\Microsoft.IdentityModel.JsonWebTokens.7.2.0\lib\net472\Microsoft.IdentityModel.JsonWebTokens.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<HintPath>..\..\packages/Microsoft.IdentityModel.Logging.7.2.0/lib/net472/Microsoft.IdentityModel.Logging.dll</HintPath>
<HintPath>..\..\packages\Microsoft.IdentityModel.Logging.7.2.0\lib\net472\Microsoft.IdentityModel.Logging.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocols, Version=6.12.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -252,7 +252,7 @@
<HintPath>..\..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.6.12.2\lib\net472\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<HintPath>..\..\packages/Microsoft.IdentityModel.Tokens.7.2.0/lib/net472/Microsoft.IdentityModel.Tokens.dll</HintPath>
<HintPath>..\..\packages\Microsoft.IdentityModel.Tokens.7.2.0\lib\net472\Microsoft.IdentityModel.Tokens.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Net.Http.Headers, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
@@ -302,7 +302,7 @@
<HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.5.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=6.34.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<HintPath>..\..\packages/System.IdentityModel.Tokens.Jwt.6.34.0/lib/net472/System.IdentityModel.Tokens.Jwt.dll</HintPath>
<HintPath>..\..\packages\System.IdentityModel.Tokens.Jwt.6.34.0\lib\net472\System.IdentityModel.Tokens.Jwt.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
@@ -312,7 +312,7 @@
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.14\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\..\packages/System.Memory.4.5.5/lib/net461/System.Memory.dll</HintPath>
<HintPath>..\..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net" />
@@ -328,7 +328,7 @@
<HintPath>..\..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<HintPath>..\..\packages/System.Runtime.CompilerServices.Unsafe.6.0.0/lib/net461/System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<HintPath>..\..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.Serialization" />
@@ -339,11 +339,11 @@
<HintPath>..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\..\packages/System.Text.Encodings.Web.8.0.0/lib/net462/System.Text.Encodings.Web.dll</HintPath>
<HintPath>..\..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Text.Json, Version=8.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\..\packages/System.Text.Json.8.0.4/lib/net462/System.Text.Json.dll</HintPath>
<Reference Include="System.Text.Json, Version=8.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\..\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">

View File

@@ -147,7 +147,7 @@
<package id="System.Security.Principal.Windows" version="4.5.0" targetFramework="net472" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net472" />
<package id="System.Text.Json" version="8.0.4" targetFramework="net472" />
<package id="System.Text.Json" version="8.0.5" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
<package id="TinyMapper" version="3.0.3" targetFramework="net472" />

View File

@@ -1,7 +1,7 @@
// Copyright © WireMock.Net
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using Testcontainers.MsSql;
using WireMock.Net.Testcontainers;
namespace WireMock.Net.TestcontainersExample;
@@ -10,17 +10,128 @@ internal class Program
{
private static async Task Main(string[] args)
{
var container = new WireMockContainerBuilder()
var original = Console.ForegroundColor;
try
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Linux");
await TestAsync("sheyenrath/wiremock.net:1.6.5");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}
try
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Linux Alpine");
await TestAsync("sheyenrath/wiremock.net-alpine:1.6.5");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}
try
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("WithLinux");
await TestAsync("WithLinux");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}
try
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Windows");
await TestAsync("sheyenrath/wiremock.net-windows:1.6.5");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}
try
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("WithWindows");
await TestAsync("WithWindows");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}
try
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Automatic");
await TestAsync();
}
finally
{
Console.ForegroundColor = original;
}
}
private static async Task TestAsync(string? image = null)
{
var mappingsPath = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "WireMock.Net.Console.NET6", "__admin", "mappings");
var builder = new WireMockContainerBuilder()
.WithAdminUserNameAndPassword("x", "y")
.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings")
.WithMappings(mappingsPath)
.WithWatchStaticMappings(true)
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
.WithCleanUp(true);
await container.StartAsync().ConfigureAwait(false);
if (image != null)
{
builder = image switch
{
"WithWindows" => builder.WithWindowsImage(),
"WithLinux" => builder.WithLinuxImage(),
_ => builder.WithImage(image)
};
}
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false);
var container = builder.Build();
await container.StartAsync();
await Task.Delay(1_000);
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1));
Console.WriteLine("logs = " + logs.Stdout);
var restEaseApiClient = container.CreateWireMockAdminClient();
@@ -36,10 +147,5 @@ internal class Program
Console.WriteLine("result = " + result);
await container.StopAsync();
var sql = new MsSqlBuilder()
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
}
}

View File

@@ -1,24 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Testcontainers.MsSql" Version="3.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,56 @@
using WireMock.Net.AspNetCore.Middleware;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
var builder = WebApplication.CreateBuilder(args);
if (!builder.Environment.IsProduction())
{
builder.Services.AddWireMockService(server =>
{
server.Given(Request.Create()
.WithPath("/test1")
.UsingAnyMethod()
).RespondWith(Response.Create()
.WithBody("1 : WireMock.Net !")
);
server.Given(Request.Create()
.WithPath("/test2")
.UsingAnyMethod()
).RespondWith(Response.Create()
.WithBody("2 : WireMock.Net !")
);
}, true);
}
var app = builder.Build();
app.MapGet("/weatherforecast", async (HttpClient client) =>
{
var result = await client.GetStringAsync("https://real-api:12345/test1");
return Enumerable.Range(1, 3).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
result
));
});
app.MapGet("/weatherforecast2", async (IHttpClientFactory factory) =>
{
using var client = factory.CreateClient();
var result = await client.GetStringAsync("https://real-api:12345/test2");
return Enumerable.Range(1, 3).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
result
));
});
await app.RunAsync();

View File

@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:57375",
"sslPort": 44333
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5112",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "https://localhost:7021;http://localhost:5112",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,4 @@
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.AspNetCore.Middleware\WireMock.Net.AspNetCore.Middleware.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -89,7 +89,7 @@ public class MappingModel
/// <summary>
/// Data Object which can be used when WithTransformer is used.
/// e.g. lookup an path in this object using
/// e.g. lookup a path in this object using
/// <example>
/// lookup data "1"
/// </example>
@@ -105,4 +105,9 @@ public class MappingModel
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
/// </summary>
public string? ProtoDefinition { get; set; }
/// <summary>
/// The Grpc ProtoDefinitions which are used for this mapping (request and response). [Optional]
/// </summary>
public string[]? ProtoDefinitions { get; set; }
}

View File

@@ -137,6 +137,11 @@ public class ResponseModel
/// </summary>
public string? ProtoDefinition { get; set; }
/// <summary>
/// Gets or sets the proto definitions.
/// </summary>
public string[]? ProtoDefinitions { get; set; }
/// <summary>
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
/// </summary>

View File

@@ -121,7 +121,7 @@ public class SettingsModel
/// <summary>
/// A list of Grpc ProtoDefinitions which can be used.
/// </summary>
public Dictionary<string, string>? ProtoDefinitions { get; set; }
public Dictionary<string, string[]>? ProtoDefinitions { get; set; }
#if NETSTANDARD1_3_OR_GREATER || NET461
/// <summary>

View File

@@ -51,10 +51,10 @@ public interface IWireMockLogger
/// <summary>
/// Writes the message at the Error level using the specified exception.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="message">The message.</param>
/// <param name="exception">The exception.</param>
[PublicAPI]
void Error(string formatString, Exception exception);
void Error(string message, Exception exception);
/// <summary>
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).

View File

@@ -79,7 +79,7 @@ public interface IBodyData
/// <summary>
/// Gets or sets the proto definition.
/// </summary>
public Func<IdOrText>? ProtoDefinition { get; set; }
public Func<IdOrTexts>? ProtoDefinition { get; set; }
/// <summary>
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".

View File

@@ -0,0 +1,25 @@
// Copyright © WireMock.Net
using WireMock.Types;
// ReSharper disable once CheckNamespace
namespace WireMock.Util;
// ReSharper disable once InconsistentNaming
public static class IBodyDataExtensions
{
public static BodyType GetBodyType(this IBodyData bodyData)
{
if (bodyData.DetectedBodyTypeFromContentType is not null and not BodyType.None)
{
return bodyData.DetectedBodyTypeFromContentType.Value;
}
if (bodyData.DetectedBodyType is not null and not BodyType.None)
{
return bodyData.DetectedBodyType.Value;
}
return BodyType.None;
}
}

View File

@@ -1,35 +0,0 @@
// Copyright © WireMock.Net
namespace WireMock.Models;
/// <summary>
/// A structure defining an (optional) Id and a Text.
/// </summary>
public readonly struct IdOrText
{
/// <summary>
/// The Id [optional].
/// </summary>
public string? Id { get; }
/// <summary>
/// The Text.
/// </summary>
public string Text { get; }
/// <summary>
/// When Id is defined, return the Id, else the Text.
/// </summary>
public string Value => Id ?? Text;
/// <summary>
/// Create a IdOrText
/// </summary>
/// <param name="id">The Id [optional]</param>
/// <param name="text">The Text.</param>
public IdOrText(string? id, string text)
{
Id = id;
Text = text;
}
}

View File

@@ -0,0 +1,59 @@
// Copyright © WireMock.Net
using System;
using System.Collections.Generic;
namespace WireMock.Models;
/// <summary>
/// A structure defining an (optional) Id and a Text.
/// </summary>
public readonly struct IdOrTexts
{
/// <summary>
/// The Id [optional].
/// </summary>
public string? Id { get; }
/// <summary>
/// The Text.
/// </summary>
public IReadOnlyList<string> Texts { get; }
/// <summary>
/// Create a IdOrText
/// </summary>
/// <param name="id">The Id [optional]</param>
/// <param name="text">The Text.</param>
public IdOrTexts(string? id, string text) : this(id, [text])
{
}
/// <summary>
/// Create a IdOrText
/// </summary>
/// <param name="id">The Id [optional]</param>
/// <param name="texts">The Texts.</param>
public IdOrTexts(string? id, IReadOnlyList<string> texts)
{
Id = id;
Texts = texts;
}
/// <summary>
/// When Id is defined, return process the Id, else process the Texts.
/// </summary>
/// <param name="id">Callback to process the id.</param>
/// <param name="texts">Callback to process the texts.</param>
public void Value(Action<string> id, Action<IReadOnlyList<string>> texts)
{
if (Id != null)
{
id(Id);
}
else
{
texts(Texts);
}
}
}

View File

@@ -4,7 +4,7 @@
<Description>Commonly used models, enumerations and types.</Description>
<AssemblyTitle>WireMock.Net.Abstractions</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net45;net451;net461;netstandard1.0;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net45;net451;net461;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591;8603</NoWarn>
<AssemblyName>WireMock.Net.Abstractions</AssemblyName>
@@ -36,15 +36,18 @@
<ItemGroup>
<!-- See also https://mstack.nl/blog/20210801-source-generators -->
<PackageReference Include="FluentBuilder" Version="0.9.0">
<PackageReference Include="FluentBuilder" Version="0.10.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PolySharp" Version="1.14.0">
<PackageReference Include="PolySharp" Version="1.14.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- CVE-2018-8292 -->
<PackageReference Include="System.Net.Http " Version="4.3.4" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('netstandard')) and '$(TargetFramework)' != 'netstandard1.0'">

View File

@@ -0,0 +1,9 @@
// Copyright © WireMock.Net
namespace WireMock.Net.AspNetCore.Middleware;
internal static class AppConstants
{
internal const string HEADER_REDIRECT = "X-WireMock-Redirect";
internal const string HEADER_RESPONSE_DELAY = "X-WireMock-Response-Delay";
}

View File

@@ -0,0 +1,72 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Stef.Validation;
using WireMock.Server;
namespace WireMock.Net.AspNetCore.Middleware.HttpDelegatingHandler;
/// <summary>
/// DelegatingHandler that takes requests made via the <see cref="HttpClient"/>
/// and routes them to the <see cref="WireMockServer"/>.
/// </summary>
internal class WireMockDelegationHandler : DelegatingHandler
{
private readonly ILogger<WireMockDelegationHandler> _logger;
private readonly WireMockServerInstance _server;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly WireMockDelegationHandlerSettings _settings;
/// <summary>
/// Creates a new instance of <see cref="WireMockDelegationHandler"/>
/// </summary>
public WireMockDelegationHandler(
ILogger<WireMockDelegationHandler> logger,
WireMockServerInstance server,
IHttpContextAccessor httpContextAccessor,
WireMockDelegationHandlerSettings settings
)
{
_server = Guard.NotNull(server);
_httpContextAccessor = Guard.NotNull(httpContextAccessor);
_logger = Guard.NotNull(logger);
_settings = Guard.NotNull(settings);
}
/// <inheritdoc />
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Guard.NotNull(request);
Guard.NotNull(_httpContextAccessor.HttpContext);
if (_settings.AlwaysRedirect || IsWireMockRedirectHeaderSetToTrue())
{
_logger.LogDebug("Redirecting request to WireMock server");
if (_server.Instance?.Url != null)
{
request.RequestUri = new Uri(_server.Instance.Url + request.RequestUri!.PathAndQuery);
}
}
if (TryGetDelayHeaderValue(out var delayInMs))
{
await Task.Delay(delayInMs, cancellationToken);
}
return await base.SendAsync(request, cancellationToken);
}
private bool IsWireMockRedirectHeaderSetToTrue()
{
return
_httpContextAccessor.HttpContext!.Request.Headers.TryGetValue(AppConstants.HEADER_REDIRECT, out var values) &&
bool.TryParse(values.ToString(), out var shouldRedirectToWireMock) && shouldRedirectToWireMock;
}
private bool TryGetDelayHeaderValue(out int delayInMs)
{
delayInMs = 0;
return
_httpContextAccessor.HttpContext!.Request.Headers.TryGetValue(AppConstants.HEADER_RESPONSE_DELAY, out var values) &&
int.TryParse(values.ToString(), out delayInMs);
}
}

View File

@@ -0,0 +1,8 @@
// Copyright © WireMock.Net
namespace WireMock.Net.AspNetCore.Middleware.HttpDelegatingHandler;
internal class WireMockDelegationHandlerSettings
{
public bool AlwaysRedirect { get; set; }
}

View File

@@ -0,0 +1,52 @@
// Copyright © WireMock.Net
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http;
using Stef.Validation;
using WireMock.Net.AspNetCore.Middleware.HttpDelegatingHandler;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.AspNetCore.Middleware;
/// <summary>
/// Extension methods for <see cref="IServiceCollection"/>.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds all the components necessary to run WireMock.Net as a background service.
/// </summary>
public static IServiceCollection AddWireMockService(
this IServiceCollection services,
Action<WireMockServer> configure,
bool alwaysRedirectToWireMock = true,
WireMockServerSettings? settings = null
)
{
Guard.NotNull(services);
Guard.NotNull(configure);
services.AddTransient<WireMockDelegationHandler>();
services.AddSingleton(new WireMockServerInstance(configure, settings));
services.AddSingleton(new WireMockDelegationHandlerSettings
{
AlwaysRedirect = alwaysRedirectToWireMock
});
services.AddHostedService<WireMockBackgroundService>();
services.AddHttpClient();
services.AddHttpContextAccessor();
services.ConfigureAll<HttpClientFactoryOptions>(options =>
{
options.HttpMessageHandlerBuilderActions.Add(builder =>
{
builder.AdditionalHandlers.Add(builder.Services.GetRequiredService<WireMockDelegationHandler>());
});
});
return services;
}
}

View File

@@ -0,0 +1,45 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Description>Middleware which can be used to host WireMock.Net as a Middleware background process in a AspNetCore WebApplication</Description>
<AssemblyTitle>WireMock.Net.AspNetCore.Middleware</AssemblyTitle>
<Authors>Matthew Yost;Stef Heyenrath</Authors>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.AspNetCore.Middleware</AssemblyName>
<PackageId>WireMock.Net.AspNetCore.Middleware</PackageId>
<PackageTags>dotnet;middleware;wiremock;service;webapplication;aspnetcore</PackageTags>
<ProjectGuid>{B6269AAC-170A-4346-8B9A-579DED3D9A13}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>WireMock.Net-LogoAspire.png</PackageIcon>
<ApplicationIcon>../../resources/WireMock.Net-LogoAspire.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<None Remove="../../resources/WireMock.Net-Logo.png" />
<None Include="../../resources/WireMock.Net-LogoAspire.png" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,39 @@
// Copyright © WireMock.Net
using Microsoft.Extensions.Hosting;
using Stef.Validation;
using WireMock.Server;
namespace WireMock.Net.AspNetCore.Middleware;
/// <summary>
/// A <see cref="BackgroundService"/> used to start/stop the <see cref="WireMockServer"/>
/// </summary>
internal class WireMockBackgroundService : BackgroundService
{
private readonly WireMockServerInstance _serverInstance;
/// <summary>
/// Creates a new <see cref="BackgroundService"/> using an instance
/// of <see cref="WireMockServerInstance"/>
/// </summary>
/// <param name="serverInstance"></param>
public WireMockBackgroundService(WireMockServerInstance serverInstance)
{
_serverInstance = Guard.NotNull(serverInstance);
}
/// <inheritdoc />
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_serverInstance.Start();
return Task.CompletedTask;
}
/// <inheritdoc />
public override Task StopAsync(CancellationToken cancellationToken)
{
_serverInstance.Stop();
return base.StopAsync(cancellationToken);
}
}

View File

@@ -0,0 +1,49 @@
// Copyright © WireMock.Net
using Stef.Validation;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.AspNetCore.Middleware;
/// <summary>
/// WireMockServer Instance object
/// </summary>
internal class WireMockServerInstance
{
private readonly Action<WireMockServer> _configureAction;
private readonly WireMockServerSettings? _settings;
/// <summary>
/// Creates a new instance and provides ability to add configuration
/// for the start method of <see cref="WireMockServer"/>
/// </summary>
public WireMockServerInstance(Action<WireMockServer> configure, WireMockServerSettings? settings = null)
{
_configureAction = Guard.NotNull(configure);
_settings = settings;
}
/// <summary>
/// Instance accessor for the <see cref="WireMockServer" />
/// </summary>
public WireMockServer? Instance { get; private set; }
/// <summary>
/// Configures and starts <see cref="WireMockServer"/> instance for use.
/// </summary>
public void Start()
{
Instance = _settings != null ? WireMockServer.Start(_settings) : WireMockServer.Start();
_configureAction.Invoke(Instance);
}
/// <summary>
/// Stops the <see cref="WireMockServer"/>
/// </summary>
public void Stop()
{
Instance?.Stop();
}
}

View File

@@ -35,7 +35,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting" Version="8.2.0" />
<PackageReference Include="Aspire.Hosting" Version="8.2.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,59 @@
overview
```mermaid
classDiagram
class WireMockServerResource {
}
class ContainerResource {
}
class IResourceWithServiceDiscovery {
}
class IResourceWithEndpoints {
}
class WireMockServerArguments {
}
class EndpointReference {
}
class AdminApiMappingBuilder {
}
class IWireMockAdminApi {
}
class MappingModelBuilder {
}
class WireMockServerLifecycleHook {
}
class ResourceLoggerService {
}
class DistributedApplicationModel {
}
class IDistributedApplicationLifecycleHook {
}
WireMockServerResource --> ContainerResource : Inherits
WireMockServerResource --> IResourceWithServiceDiscovery : Implements
WireMockServerResource --> WireMockServerArguments : Uses
WireMockServerResource --> EndpointReference : Returns
WireMockServerArguments --> AdminApiMappingBuilder : Uses
AdminApiMappingBuilder --> MappingModelBuilder : Uses
AdminApiMappingBuilder --> IWireMockAdminApi : Uses
IResourceWithServiceDiscovery --> IResourceWithEndpoints : Inherits
WireMockServerLifecycleHook --> IDistributedApplicationLifecycleHook : Implements
WireMockServerLifecycleHook --> ResourceLoggerService : Uses
WireMockServerLifecycleHook --> DistributedApplicationModel : Uses
WireMockServerLifecycleHook --> WireMockServerResource : Uses
WireMockServerLifecycleHook --> IWireMockAdminApi : Uses
```

View File

@@ -43,7 +43,7 @@
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'">
<PackageReference Include="CS-Script" Version="4.8.13" />
<PackageReference Include="CS-Script" Version="4.8.17" />
</ItemGroup>
</Project>

View File

@@ -26,7 +26,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="RamlToOpenApiConverter" Version="0.6.1" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.17" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.18" />
<PackageReference Include="Stef.Validation" Version="0.1.1" />
</ItemGroup>

View File

@@ -4,7 +4,7 @@
<Description>A RestClient using RestEase to access the admin interface.</Description>
<AssemblyTitle>WireMock.Net.RestClient</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net45;netstandard1.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net45;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.RestClient</AssemblyName>
<PackageId>WireMock.Net.RestClient</PackageId>
@@ -30,8 +30,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JsonConverter.Newtonsoft.Json" Version="0.3.0" />
<PackageReference Include="RestEase" Version="1.5.7" />
<PackageReference Include="JsonConverter.Newtonsoft.Json" Version="0.7.0" />
<PackageReference Include="RestEase" Version="1.6.4" />
<PackageReference Include="Stef.Validation" Version="0.1.1" />
</ItemGroup>

View File

@@ -0,0 +1,80 @@
// Copyright © WireMock.Net
using System;
using Newtonsoft.Json;
using Stef.Validation;
using TUnit.Core.Logging;
using WireMock.Admin.Requests;
using WireMock.Logging;
namespace WireMock.Net.TUnit;
/// <summary>
/// When using TUnit, this class enables to log the output from WireMock.Net to the <see cref="TUnitLogger"/>.
/// </summary>
// ReSharper disable once InconsistentNaming
public sealed class TUnitWireMockLogger : IWireMockLogger
{
private readonly TUnitLogger _tUnitLogger;
/// <summary>
/// Create a new instance on the <see cref="TUnitWireMockLogger"/>.
/// </summary>
/// <param name="tUnitLogger">Represents a class which can be used to provide test output.</param>
public TUnitWireMockLogger(TUnitLogger tUnitLogger)
{
_tUnitLogger = Guard.NotNull(tUnitLogger);
}
/// <inheritdoc />
public void Debug(string formatString, params object[] args)
{
_tUnitLogger.LogDebug(Format("Debug", formatString, args));
}
/// <inheritdoc />
public void Info(string formatString, params object[] args)
{
_tUnitLogger.LogInformation(Format("Info", formatString, args));
}
/// <inheritdoc />
public void Warn(string formatString, params object[] args)
{
_tUnitLogger.LogWarning(Format("Warning", formatString, args));
}
/// <inheritdoc />
public void Error(string formatString, params object[] args)
{
_tUnitLogger.LogError(Format("Error", formatString, args));
}
/// <inheritdoc />
public void Error(string formatString, Exception exception)
{
_tUnitLogger.LogError(Format("Error", formatString, exception.Message), exception);
if (exception is AggregateException ae)
{
ae.Handle(ex =>
{
_tUnitLogger.LogError(Format("Error", "Exception {0}", ex.Message), exception);
return true;
});
}
}
/// <inheritdoc />
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
var message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
_tUnitLogger.LogDebug(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
}
private static string Format(string level, string formatString, params object[] args)
{
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
return $"{DateTime.UtcNow} [{level}] : {message}";
}
}

View File

@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Some extensions for TUnit (TUnitLogger)</Description>
<AssemblyTitle>WireMock.Net.TUnit</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.TUnit</AssemblyName>
<RootNamespace>WireMock.Net.Tunit</RootNamespace>
<PackageId>WireMock.Net.TUnit</PackageId>
<PackageTags>tdd;wiremock;test;unittest;TUnit</PackageTags>
<ProjectGuid>{0DE0954F-8C00-4E8D-B94A-4361FC1CB34A}</ProjectGuid>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Stef.Validation" Version="0.1.1" />
<PackageReference Include="TUnit.Core" Version="0.2.195" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
</ItemGroup>
</Project>

View File

@@ -28,7 +28,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Stef.Validation" Version="0.1.1" />
<PackageReference Include="Testcontainers" Version="[3.9.0]" />
<PackageReference Include="Testcontainers" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,5 +1,6 @@
// Copyright © WireMock.Net
using System;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Configurations;
@@ -16,6 +17,8 @@ public sealed class WireMockConfiguration : ContainerConfiguration
public string? Password { get; }
public string? StaticMappingsPath { get; private set; }
public bool HasBasicAuthentication => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
public WireMockConfiguration(string? username = null, string? password = null)
@@ -61,5 +64,17 @@ public sealed class WireMockConfiguration : ContainerConfiguration
{
Username = BuildConfiguration.Combine(oldValue.Username, newValue.Username);
Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password);
StaticMappingsPath = BuildConfiguration.Combine(oldValue.StaticMappingsPath, newValue.StaticMappingsPath);
}
/// <summary>
/// Set the StaticMappingsPath.
/// </summary>
/// <param name="path">The path which contains the StaticMappings.</param>
/// <returns><see cref="WireMockConfiguration"/> </returns>
public WireMockConfiguration WithStaticMappingsPath(string path)
{
StaticMappingsPath = path;
return this;
}
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
@@ -17,15 +18,14 @@ namespace WireMock.Net.Testcontainers;
/// </summary>
public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContainerBuilder, WireMockContainer, WireMockConfiguration>
{
private readonly Dictionary<bool, ContainerInfo> _info = new()
private const string DefaultLogger = "WireMockConsoleLogger";
private readonly Dictionary<OSPlatform, ContainerInfo> _info = new()
{
{ false, new ContainerInfo("sheyenrath/wiremock.net:latest", "/app/__admin/mappings") },
{ true, new ContainerInfo("sheyenrath/wiremock.net-windows:latest", @"c:\app\__admin\mappings") }
{ OSPlatform.Linux, new ContainerInfo("sheyenrath/wiremock.net-alpine", "/app/__admin/mappings") },
{ OSPlatform.Windows, new ContainerInfo("sheyenrath/wiremock.net-windows", @"c:\app\__admin\mappings") }
};
private const string DefaultLogger = "WireMockConsoleLogger";
private readonly Lazy<Task<bool>> _isWindowsAsLazy = new(async () =>
private readonly Lazy<Task<OSPlatform>> _getOSAsLazy = new(async () =>
{
if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null)
{
@@ -36,9 +36,11 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
using var dockerClient = dockerClientConfig.CreateClient();
var version = await dockerClient.System.GetVersionAsync();
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) >= 0 ? OSPlatform.Windows : OSPlatform.Linux;
});
private OSPlatform? _imageOS;
/// <summary>
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
/// </summary>
@@ -48,14 +50,36 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
}
/// <summary>
/// Automatically set the correct image (Linux or Windows) for WireMock which to create the container.
/// Automatically use the correct image for WireMock.
/// For Linux this is "sheyenrath/wiremock.net-alpine:latest"
/// For Windows this is "sheyenrath/wiremock.net-windows:latest"
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithImage()
{
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
return WithImage(_info[isWindows].Image);
_imageOS ??= _getOSAsLazy.Value.GetAwaiter().GetResult();
return WithImage(_imageOS.Value);
}
/// <summary>
/// Automatically use a Linux image for WireMock. This is "sheyenrath/wiremock.net-alpine:latest"
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithLinuxImage()
{
return WithImage(OSPlatform.Linux);
}
/// <summary>
/// Automatically use a Windows image for WireMock. This is "sheyenrath/wiremock.net-windows:latest"
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithWindowsImage()
{
return WithImage(OSPlatform.Windows);
}
/// <summary>
@@ -120,11 +144,9 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
{
Guard.NotNullOrEmpty(path);
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
return WithReadStaticMappings()
.WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}")
.WithBindMount(path, _info[isWindows].MappingsPath);
return Merge(DockerResourceConfiguration, DockerResourceConfiguration.WithStaticMappingsPath(path))
.WithReadStaticMappings()
.WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}");
}
private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration)
@@ -138,9 +160,33 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
/// <inheritdoc />
public override WireMockContainer Build()
{
Validate();
var builder = this;
return new WireMockContainer(DockerResourceConfiguration);
// In case no image has been set, set the image using internal logic.
if (DockerResourceConfiguration.Image == null)
{
builder = WithImage();
}
// In case the _imageOS is not set, determine it from the Image FullName.
if (_imageOS == null)
{
if (builder.DockerResourceConfiguration.Image.FullName.IndexOf("wiremock.net", StringComparison.OrdinalIgnoreCase) < 0)
{
throw new InvalidOperationException();
}
_imageOS = builder.DockerResourceConfiguration.Image.FullName.IndexOf("windows", StringComparison.OrdinalIgnoreCase) >= 0 ? OSPlatform.Windows : OSPlatform.Linux;
}
if (!string.IsNullOrEmpty(builder.DockerResourceConfiguration.StaticMappingsPath))
{
builder = builder.WithBindMount(builder.DockerResourceConfiguration.StaticMappingsPath, _info[_imageOS.Value].MappingsPath);
}
builder.Validate();
return new WireMockContainer(builder.DockerResourceConfiguration);
}
/// <inheritdoc />
@@ -148,14 +194,7 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
{
var builder = base.Init();
// In case no image has been set, set the image using internal logic.
if (builder.DockerResourceConfiguration.Image == null)
{
builder = builder.WithImage();
}
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
var waitForContainerOS = isWindows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
var waitForContainerOS = _imageOS == OSPlatform.Windows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
return builder
.WithPortBinding(WireMockContainer.ContainerPort, true)
.WithCommand($"--WireMockLogger {DefaultLogger}")
@@ -179,4 +218,10 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
{
return new WireMockContainerBuilder(new WireMockConfiguration(oldValue, newValue));
}
private WireMockContainerBuilder WithImage(OSPlatform os)
{
_imageOS = os;
return WithImage(_info[os].Image);
}
}

View File

@@ -73,8 +73,6 @@ public sealed class TestOutputHelperWireMockLogger : IWireMockLogger
private static string Format(string level, string formatString, params object[] args)
{
Guard.NotNull(formatString);
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
return $"{DateTime.UtcNow} [{level}] : {message}";
}

View File

@@ -3,7 +3,7 @@
<Description>Some extensions for xUnit (ITestOutputHelper)</Description>
<AssemblyTitle>WireMock.Net.xUnit</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net45;net451;netstandard1.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net45;net451;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.xUnit</AssemblyName>
<RootNamespace>WireMock.Net.Xunit</RootNamespace>

View File

@@ -22,6 +22,16 @@ public static class AnyOfExtensions
return value.IsFirst ? value.First : value.Second.Pattern;
}
/// <summary>
/// Gets the patterns.
/// </summary>
/// <param name="values">AnyOf types</param>
/// <returns>string values</returns>
public static string[] GetPatterns(this AnyOf<string, StringPattern>[] values)
{
return values.Select(GetPattern).ToArray();
}
/// <summary>
/// Converts a string-patterns to AnyOf patterns.
/// </summary>

View File

@@ -9,6 +9,7 @@ using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Constants;
using WireMock.Types;
using WireMock.Util;
namespace WireMock.Http;
@@ -33,12 +34,14 @@ internal static class HttpRequestMessageHelper
MediaTypeHeaderValue.TryParse(value, out contentType);
}
httpRequestMessage.Content = requestMessage.BodyData?.DetectedBodyType switch
var bodyData = requestMessage.BodyData;
httpRequestMessage.Content = bodyData?.GetBodyType() switch
{
BodyType.Bytes => ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType),
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType),
BodyType.String => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
BodyType.FormUrlEncoded => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
BodyType.Bytes => ByteArrayContentHelper.Create(bodyData!.BodyAsBytes!, contentType),
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(bodyData!.BodyAsJson), contentType),
BodyType.String => StringContentHelper.Create(bodyData!.BodyAsString!, contentType),
BodyType.FormUrlEncoded => StringContentHelper.Create(bodyData!.BodyAsString!, contentType),
_ => httpRequestMessage.Content
};

View File

@@ -141,7 +141,7 @@ public interface IMapping
/// <summary>
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
/// </summary>
IdOrText? ProtoDefinition { get; }
IdOrTexts? ProtoDefinition { get; }
/// <summary>
/// ProvideResponseAsync
@@ -175,26 +175,7 @@ public interface IMapping
/// <summary>
/// Define a Grpc ProtoDefinition which is used for this mapping (request and response).
/// </summary>
/// <param name="protoDefinition">The proto definition as text.</param>
/// <param name="protoDefinition">The proto definitions as id or text.</param>
/// <returns>The <see cref="IMapping"/>.</returns>
IMapping WithProtoDefinition(IdOrText protoDefinition);
}
/*
executionConditionState">State in which the current mapping can occur. [Optional]
nextState">The next state which will occur after the current mapping execution. [Optional]
stateTimes">Only when the current state is executed this number, the next state which will occur. [Optional]
webhooks">The Webhooks. [Optional]
useWebhooksFireAndForget">Use Fire and Forget for the defined webhook(s). [Optional]
timeSettings">The TimeSettings. [Optional]
data">The data object. [Optional]
string? executionConditionState,
string? nextState,
int? stateTimes,
IWebhook[]? webhooks,
bool? useWebhooksFireAndForget,
ITimeSettings? timeSettings,
object? data,
*/
IMapping WithProtoDefinition(IdOrTexts protoDefinition);
}

View File

@@ -52,15 +52,15 @@ public class WireMockConsoleLogger : IWireMockLogger
}
/// <see cref="IWireMockLogger.Error(string, Exception)"/>
public void Error(string formatString, Exception exception)
public void Error(string message, Exception exception)
{
Console.WriteLine(Format("Error", formatString, exception.Message));
Console.WriteLine(Format("Error", $"{message} {{0}}", exception));
if (exception is AggregateException ae)
{
ae.Handle(ex =>
{
Console.WriteLine(Format("Error", "Exception {0}", ex.Message));
Console.WriteLine(Format("Error", "Exception {0}", ex));
return true;
});
}

View File

@@ -36,7 +36,7 @@ public class WireMockNullLogger : IWireMockLogger
}
/// <see cref="IWireMockLogger.Error(string, Exception)"/>
public void Error(string formatString, Exception exception)
public void Error(string message, Exception exception)
{
// Log nothing
}

View File

@@ -82,7 +82,7 @@ public class Mapping : IMapping
public double? Probability { get; private set; }
/// <inheritdoc />
public IdOrText? ProtoDefinition { get; private set; }
public IdOrTexts? ProtoDefinition { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="Mapping"/> class.
@@ -189,7 +189,7 @@ public class Mapping : IMapping
}
/// <inheritdoc />
public IMapping WithProtoDefinition(IdOrText protoDefinition)
public IMapping WithProtoDefinition(IdOrTexts protoDefinition)
{
ProtoDefinition = protoDefinition;
return this;

View File

@@ -82,7 +82,7 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
case JTokenType.Object:
var nestedValues = value.ToObject<Dictionary<string, JToken>>();
return nestedValues?.Any() != true ||
nestedValues.All(pair => IsMatch(pair.Value, input.SelectToken(pair.Key)));
nestedValues.All(pair => IsMatch(pair.Value, input.SelectToken(pair.Key) ?? input[pair.Key])); // First try to select based on JPath expression, else just get the value.
case JTokenType.Array:
var valuesArray = value.ToObject<JToken[]>();

View File

@@ -113,16 +113,16 @@ public class GraphQLMatcher : IStringMatcher
{
try
{
var executionResult = new DocumentExecuter().ExecuteAsync(_ =>
var executionResult = new DocumentExecuter().ExecuteAsync(eo =>
{
_.ThrowOnUnhandledException = true;
eo.ThrowOnUnhandledException = true;
_.Schema = _schema;
_.Query = graphQLRequest.Query;
eo.Schema = _schema;
eo.Query = graphQLRequest.Query;
if (graphQLRequest.Variables != null)
{
_.Variables = new Inputs(graphQLRequest.Variables);
eo.Variables = new Inputs(graphQLRequest.Variables);
}
}).GetAwaiter().GetResult();

View File

@@ -2,6 +2,7 @@
#if PROTOBUF
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ProtoBufJsonConverter;
@@ -25,9 +26,9 @@ public class ProtoBufMatcher : IProtoBufMatcher
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// The Func to define The proto definition as text.
/// The Func to define the proto definition as id or texts.
/// </summary>
public Func<IdOrText> ProtoDefinition { get; }
public Func<IdOrTexts> ProtoDefinition { get; }
/// <summary>
/// The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
@@ -44,12 +45,12 @@ public class ProtoBufMatcher : IProtoBufMatcher
/// <summary>
/// Initializes a new instance of the <see cref="ProtoBufMatcher"/> class.
/// </summary>
/// <param name="protoDefinition">The proto definition.</param>
/// <param name="protoDefinition">The proto definition as id or text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
/// <param name="matcher">The optional jsonMatcher to use to match the ProtoBuf as (json) object.</param>
public ProtoBufMatcher(
Func<IdOrText> protoDefinition,
Func<IdOrTexts> protoDefinition,
string messageType,
MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch,
IObjectMatcher? matcher = null
@@ -102,7 +103,11 @@ public class ProtoBufMatcher : IProtoBufMatcher
return null;
}
var request = new ConvertToObjectRequest(ProtoDefinition().Text, MessageType, input);
var protoDefinitions = ProtoDefinition().Texts;
var resolver = new WireMockProtoFileResolver(protoDefinitions);
var request = new ConvertToObjectRequest(protoDefinitions[0], MessageType, input)
.WithProtoFileResolver(resolver);
try
{

View File

@@ -19,10 +19,10 @@ public class RequestMessageProtoBufMatcher : IRequestMatcher
/// Initializes a new instance of the <see cref="RequestMessageProtoBufMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
/// <param name="protoDefinition">The Func to define The proto definition as text.</param>
/// <param name="protoDefinition">The Func to define the proto definitions as id or text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="matcher">The optional matcher to use to match the ProtoBuf as (json) object.</param>
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, Func<IdOrText> protoDefinition, string messageType, IObjectMatcher? matcher = null)
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, Func<IdOrTexts> protoDefinition, string messageType, IObjectMatcher? matcher = null)
{
#if PROTOBUF
Matcher = new ProtoBufMatcher(protoDefinition, messageType, matchBehaviour, matcher);

View File

@@ -52,7 +52,7 @@ public class BodyData : IBodyData
#region ProtoBuf
/// <inheritdoc />
public Func<IdOrText>? ProtoDefinition { get; set; }
public Func<IdOrTexts>? ProtoDefinition { get; set; }
/// <inheritdoc />
public string? ProtoBufMessageType { get; set; }

View File

@@ -136,30 +136,37 @@ namespace WireMock.Owin.Mappers
return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage;
}
private async Task<byte[]?> GetNormalBodyAsync(IResponseMessage responseMessage)
{
switch (responseMessage.BodyData?.DetectedBodyType)
private async Task<byte[]?> GetNormalBodyAsync(IResponseMessage responseMessage) {
var bodyData = responseMessage.BodyData;
switch (bodyData?.GetBodyType())
{
case BodyType.String:
case BodyType.FormUrlEncoded:
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString!);
return (bodyData.Encoding ?? _utf8NoBom).GetBytes(bodyData.BodyAsString!);
case BodyType.Json:
var formatting = responseMessage.BodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
var jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
var formatting = bodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
var jsonBody = JsonConvert.SerializeObject(bodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
return (bodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
#if PROTOBUF
case BodyType.ProtoBuf:
var protoDefinition = responseMessage.BodyData.ProtoDefinition?.Invoke().Text;
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinition, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson).ConfigureAwait(false);
var protoDefinitions = bodyData.ProtoDefinition?.Invoke().Texts;
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinitions, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson).ConfigureAwait(false);
#endif
case BodyType.Bytes:
return responseMessage.BodyData.BodyAsBytes;
return bodyData.BodyAsBytes;
case BodyType.File:
return _options.FileSystemHandler?.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile!);
return _options.FileSystemHandler?.ReadResponseBodyAsFile(bodyData.BodyAsFile!);
case BodyType.MultiPart:
_options.Logger.Warn("MultiPart body type is not handled!");
break;
case BodyType.None:
break;
}
return null;
@@ -171,10 +178,7 @@ namespace WireMock.Owin.Mappers
AppendResponseHeader(
response,
HttpKnownHeaderNames.Date,
new[]
{
DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture)
}
[ DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture) ]
);
// Set other headers

View File

@@ -126,7 +126,7 @@ namespace WireMock.Owin
if (targetMapping == null)
{
logRequest = true;
_options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");
_options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found", ctx.Request);
response = ResponseMessageBuilder.Create(HttpStatusCode.NotFound, WireMockConstants.NoMatchingFound);
return;
}
@@ -357,4 +357,4 @@ namespace WireMock.Owin
}
}
}
}
}

View File

@@ -1,5 +1,6 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using WireMock.Matchers;
namespace WireMock.RequestBuilders;
@@ -10,7 +11,7 @@ namespace WireMock.RequestBuilders;
public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
{
/// <summary>
/// WithGrpcProto
/// WithBodyAsProtoBuf
/// </summary>
/// <param name="protoDefinition">The proto definition as text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
@@ -19,7 +20,7 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithGrpcProto
/// WithBodyAsProtoBuf
/// </summary>
/// <param name="protoDefinition">The proto definition as text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
@@ -29,7 +30,26 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithGrpcProto
/// WithBodyAsProtoBuf
/// </summary>
/// <param name="protoDefinitions">The proto definitions as text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithBodyAsProtoBuf
/// </summary>
/// <param name="protoDefinitions">The proto definitions as text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="matcher">The matcher to use to match the ProtoBuf as (json) object.</param>
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithBodyAsProtoBuf
/// </summary>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
@@ -37,7 +57,7 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
IRequestBuilder WithBodyAsProtoBuf(string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithGrpcProto
/// WithBodyAsProtoBuf
/// </summary>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="matcher">The matcher to use to match the ProtoBuf as (json) object.</param>

View File

@@ -1,7 +1,10 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using System.Linq;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Models;
namespace WireMock.RequestBuilders;
@@ -10,13 +13,25 @@ public partial class Request
/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new (null, protoDefinition), messageType));
return WithBodyAsProtoBuf([ protoDefinition ], messageType, matchBehaviour);
}
/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new(null, protoDefinition), messageType, matcher));
return WithBodyAsProtoBuf([protoDefinition], messageType, matcher, matchBehaviour);
}
/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new IdOrTexts(null, protoDefinitions), messageType));
}
/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new IdOrTexts(null, protoDefinitions), messageType, matcher));
}
/// <inheritdoc />

View File

@@ -1,6 +1,7 @@
// Copyright © WireMock.Net
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using JsonConverter.Abstractions;
@@ -109,7 +110,7 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter jsonConverter, JsonConverterOptions? options = null);
/// <summary>
/// WithBody : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
/// </summary>
/// <param name="protoDefinition">The proto definition as text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
@@ -126,7 +127,24 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
);
/// <summary>
/// WithBody : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on proto definitions, message type and the value.
/// </summary>
/// <param name="protoDefinitions">The proto definition as text.</param>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="value">The object to convert to protobuf byte[].</param>
/// <param name="jsonConverter">The <see cref="IJsonConverter"/> [optional]. Default value is NewtonsoftJsonConverter.</param>
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsProtoBuf(
IReadOnlyList<string> protoDefinitions,
string messageType,
object value,
IJsonConverter? jsonConverter = null,
JsonConverterOptions? options = null
);
/// <summary>
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
/// </summary>
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
/// <param name="value">The object to convert to protobuf byte[].</param>

View File

@@ -1,11 +1,13 @@
// Copyright © WireMock.Net
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using JsonConverter.Abstractions;
using Stef.Validation;
using WireMock.Exceptions;
using WireMock.Models;
using WireMock.Types;
using WireMock.Util;
@@ -13,6 +15,8 @@ namespace WireMock.ResponseBuilders;
public partial class Response
{
private bool _bodyFromFileSet;
/// <inheritdoc />
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
{
@@ -78,6 +82,8 @@ public partial class Response
{
Guard.NotNull(filename);
_bodyFromFileSet = true;
ResponseMessage.BodyData = new BodyData
{
BodyAsFileIsCached = cache,
@@ -219,7 +225,19 @@ public partial class Response
JsonConverterOptions? options = null
)
{
Guard.NotNullOrWhiteSpace(protoDefinition);
return WithBodyAsProtoBuf([protoDefinition], messageType, value, jsonConverter, options);
}
/// <inheritdoc />
public IResponseBuilder WithBodyAsProtoBuf(
IReadOnlyList<string> protoDefinitions,
string messageType,
object value,
IJsonConverter? jsonConverter = null,
JsonConverterOptions? options = null
)
{
Guard.NotNullOrEmpty(protoDefinitions);
Guard.NotNullOrWhiteSpace(messageType);
Guard.NotNull(value);
@@ -231,7 +249,7 @@ public partial class Response
{
DetectedBodyType = BodyType.ProtoBuf,
BodyAsJson = value,
ProtoDefinition = () => new (null, protoDefinition),
ProtoDefinition = () => new IdOrTexts(null, protoDefinitions),
ProtoBufMessageType = messageType
};
#endif

View File

@@ -0,0 +1,36 @@
// Copyright © WireMock.Net
using System;
using WireMock.Types;
namespace WireMock.ResponseBuilders;
public partial class Response
{
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
{
return WithTransformer(TransformerType.Handlebars, transformContentFromBodyAsFile);
}
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(ReplaceNodeOptions)"/>
public IResponseBuilder WithTransformer(ReplaceNodeOptions options)
{
return WithTransformer(TransformerType.Handlebars, false, options);
}
/// <inheritdoc />
public IResponseBuilder WithTransformer(TransformerType transformerType, bool transformContentFromBodyAsFile = false, ReplaceNodeOptions options = ReplaceNodeOptions.EvaluateAndTryToConvert)
{
if (_bodyFromFileSet)
{
throw new InvalidOperationException("WithTransformer should be used before WithBodyFromFile.");
}
UseTransformer = true;
TransformerType = transformerType;
UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
TransformerReplaceNodeOptions = options;
return this;
}
}

View File

@@ -164,28 +164,6 @@ public partial class Response : IResponseBuilder
return WithStatusCode((int)HttpStatusCode.NotFound);
}
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
{
return WithTransformer(TransformerType.Handlebars, transformContentFromBodyAsFile);
}
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(ReplaceNodeOptions)"/>
public IResponseBuilder WithTransformer(ReplaceNodeOptions options)
{
return WithTransformer(TransformerType.Handlebars, false, options);
}
/// <inheritdoc />
public IResponseBuilder WithTransformer(TransformerType transformerType, bool transformContentFromBodyAsFile = false, ReplaceNodeOptions options = ReplaceNodeOptions.EvaluateAndTryToConvert)
{
UseTransformer = true;
TransformerType = transformerType;
UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
TransformerReplaceNodeOptions = options;
return this;
}
/// <inheritdoc />
public IResponseBuilder WithDelay(TimeSpan delay)
{
@@ -286,7 +264,7 @@ public partial class Response : IResponseBuilder
if (UseTransformer)
{
// Check if the body matcher is a RequestMessageProtoBufMatcher and try to to decode the byte-array to a BodyAsJson.
// Check if the body matcher is a RequestMessageProtoBufMatcher and try to decode the byte-array to a BodyAsJson.
if (mapping.RequestMatcher is Request requestMatcher && requestMessage is RequestMessage request)
{
var protoBufMatcher = requestMatcher.GetRequestMessageMatcher<RequestMessageProtoBufMatcher>()?.Matcher;

View File

@@ -273,7 +273,6 @@ internal class MappingConverter(MatcherMapper mapper)
WhenStateIs = mapping.ExecutionConditionState,
SetStateTo = mapping.NextState,
Data = mapping.Data,
ProtoDefinition = mapping.ProtoDefinition?.Value,
Probability = mapping.Probability,
Request = new RequestModel
{
@@ -304,6 +303,20 @@ internal class MappingConverter(MatcherMapper mapper)
Response = new ResponseModel()
};
mapping.ProtoDefinition?.Value(
id => mappingModel.ProtoDefinition = id,
texts =>
{
if (texts.Count == 1)
{
mappingModel.ProtoDefinition = texts[0];
}
else
{
mappingModel.ProtoDefinitions = texts.ToArray();
}
});
if (methodMatcher != null)
{
mappingModel.Request.Methods = methodMatcher.Methods;
@@ -491,10 +504,22 @@ internal class MappingConverter(MatcherMapper mapper)
break;
case BodyType.ProtoBuf:
// If the ProtoDefinition is not defined at the MappingModel, get the ProtoDefinition from the ResponseMessage.
if (mappingModel.ProtoDefinition == null)
// If the ProtoDefinition(s) is/are not defined at the MappingModel, get the ProtoDefinition(s) from the ResponseMessage.
if (mappingModel.ProtoDefinition == null && mappingModel.ProtoDefinitions == null)
{
mappingModel.Response.ProtoDefinition = response.ResponseMessage.BodyData.ProtoDefinition?.Invoke().Value;
response.ResponseMessage.BodyData.ProtoDefinition?.Invoke().Value(
id => mappingModel.Response.ProtoDefinition = id,
texts =>
{
if (texts.Count == 1)
{
mappingModel.Response.ProtoDefinition = texts[0];
}
else
{
mappingModel.Response.ProtoDefinitions = texts.ToArray();
}
});
}
mappingModel.Response.ProtoBufMessageType = response.ResponseMessage.BodyData.ProtoBufMessageType;

View File

@@ -79,7 +79,7 @@ internal class MatcherMapper
#if PROTOBUF
case nameof(ProtoBufMatcher):
return CreateProtoBufMatcher(matchBehaviour, stringPatterns[0].GetPattern(), matcherModel);
return CreateProtoBufMatcher(matchBehaviour, stringPatterns.GetPatterns(), matcherModel);
#endif
case nameof(RegexMatcher):
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, useRegexExtended, matchOperator);
@@ -211,7 +211,18 @@ internal class MatcherMapper
#if PROTOBUF
case ProtoBufMatcher protoBufMatcher:
model.Pattern = protoBufMatcher.ProtoDefinition().Value;
protoBufMatcher.ProtoDefinition().Value(id => model.Pattern = id, texts =>
{
if (texts.Count == 1)
{
model.Pattern = texts[0];
}
else
{
model.Patterns = texts.Cast<object>().ToArray();
}
});
model.ProtoBufMessageType = protoBufMatcher.MessageType;
model.ContentMatcher = Map(protoBufMatcher.Matcher);
break;
@@ -278,22 +289,30 @@ internal class MatcherMapper
#endif
#if PROTOBUF
private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, string protoDefinitionOrId, MatcherModel matcher)
private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, IReadOnlyList<string> protoDefinitions, MatcherModel matcher)
{
var objectMatcher = Map(matcher.ContentMatcher) as IObjectMatcher;
IdOrText protoDefinition;
if (_settings.ProtoDefinitions?.TryGetValue(protoDefinitionOrId, out var protoDefinitionFromSettings) == true)
IdOrTexts protoDefinitionAsIdOrTexts;
if (protoDefinitions.Count == 1)
{
protoDefinition = new(protoDefinitionOrId, protoDefinitionFromSettings);
var idOrText = protoDefinitions[0];
if (_settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitionFromSettings) == true)
{
protoDefinitionAsIdOrTexts = new(idOrText, protoDefinitionFromSettings);
}
else
{
protoDefinitionAsIdOrTexts = new(null, protoDefinitions);
}
}
else
{
protoDefinition = new(null, protoDefinitionOrId);
protoDefinitionAsIdOrTexts = new(null, protoDefinitions);
}
return new ProtoBufMatcher(
() => protoDefinition,
() => protoDefinitionAsIdOrTexts,
matcher!.ProtoBufMessageType!,
matchBehaviour ?? MatchBehaviour.AcceptOnMatch,
objectMatcher

View File

@@ -242,7 +242,7 @@ public interface IRespondWithAProvider
/// </summary>
/// <param name="protoDefinitionOrId">The proto definition as text or as id.</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
IRespondWithAProvider WithProtoDefinition(string protoDefinitionOrId);
IRespondWithAProvider WithProtoDefinition(params string[] protoDefinitionOrId);
/// <summary>
/// Define a GraphQL Schema which is used for the request and the response.

View File

@@ -37,7 +37,7 @@ internal class RespondWithAProvider : IRespondWithAProvider
private int _timesInSameState = 1;
private bool? _useWebhookFireAndForget;
private double? _probability;
private IdOrText? _protoDefinition;
private IdOrTexts? _protoDefinition;
private GraphQLSchemaDetails? _graphQLSchemaDetails;
public Guid Guid { get; private set; }
@@ -351,18 +351,27 @@ internal class RespondWithAProvider : IRespondWithAProvider
}
/// <inheritdoc />
public IRespondWithAProvider WithProtoDefinition(string protoDefinitionOrId)
public IRespondWithAProvider WithProtoDefinition(params string[] protoDefinitionOrId)
{
Guard.NotNullOrWhiteSpace(protoDefinitionOrId);
Guard.NotNull(protoDefinitionOrId);
if (_settings.ProtoDefinitions?.TryGetValue(protoDefinitionOrId, out var protoDefinition) == true)
if (protoDefinitionOrId.Length == 1)
{
_protoDefinition = new (protoDefinitionOrId, protoDefinition);
var idOrText = protoDefinitionOrId[0];
if (_settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitions) == true)
{
_protoDefinition = new(idOrText, protoDefinitions);
}
else
{
_protoDefinition = new(null, protoDefinitionOrId);
}
}
else
{
_protoDefinition = new(null, protoDefinitionOrId);
}
return this;
}

View File

@@ -178,9 +178,9 @@ public partial class WireMockServer
{
ReadStaticMappingAndAddOrUpdate(filename);
}
catch
catch (Exception exception)
{
_settings.Logger.Error("Static MappingFile : '{0}' could not be read. This file will be skipped.", filename);
_settings.Logger.Error($"Static MappingFile : '{filename}' could not be read. This file will be skipped.", exception);
}
}
}
@@ -623,7 +623,7 @@ public partial class WireMockServer
{
var requestModel = DeserializeObject<RequestModel>(requestMessage);
var request = (Request)InitRequestBuilder(requestModel, false)!;
var request = (Request)InitRequestBuilder(requestModel);
var dict = new Dictionary<ILogEntry, RequestMatchResult>();
foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))

View File

@@ -36,17 +36,13 @@ public partial class WireMockServer
}
}
private Guid? ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string? path = null)
private Guid ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string? path = null)
{
Guard.NotNull(mappingModel);
Guard.NotNull(mappingModel.Request);
Guard.NotNull(mappingModel.Response);
var requestBuilder = InitRequestBuilder(mappingModel.Request, true);
if (requestBuilder == null)
{
return null;
}
var requestBuilder = InitRequestBuilder(mappingModel.Request);
var respondProvider = Given(requestBuilder, mappingModel.SaveToFile == true);
@@ -126,9 +122,9 @@ public partial class WireMockServer
return respondProvider.Guid;
}
private IRequestBuilder? InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
{
IRequestBuilder requestBuilder = Request.Create();
var requestBuilder = Request.Create();
if (requestModel.ClientIP != null)
{
@@ -146,13 +142,11 @@ public partial class WireMockServer
}
}
bool pathOrUrlMatchersValid = false;
if (requestModel.Path != null)
{
if (requestModel.Path is string path)
{
requestBuilder = requestBuilder.WithPath(path);
pathOrUrlMatchersValid = true;
}
else
{
@@ -161,7 +155,6 @@ public partial class WireMockServer
{
var matchOperator = StringUtils.ParseMatchOperator(pathModel.MatchOperator);
requestBuilder = requestBuilder.WithPath(matchOperator, pathModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
pathOrUrlMatchersValid = true;
}
}
}
@@ -170,7 +163,6 @@ public partial class WireMockServer
if (requestModel.Url is string url)
{
requestBuilder = requestBuilder.WithUrl(url);
pathOrUrlMatchersValid = true;
}
else
{
@@ -179,17 +171,10 @@ public partial class WireMockServer
{
var matchOperator = StringUtils.ParseMatchOperator(urlModel.MatchOperator);
requestBuilder = requestBuilder.WithUrl(matchOperator, urlModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
pathOrUrlMatchersValid = true;
}
}
}
if (pathOrUrlRequired && !pathOrUrlMatchersValid)
{
_settings.Logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added.");
return null;
}
if (requestModel.Methods != null)
{
var matchBehaviour = requestModel.MethodsRejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
@@ -233,7 +218,7 @@ public partial class WireMockServer
{
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: { } }))
{
bool ignoreCase = paramModel.IgnoreCase == true;
var ignoreCase = paramModel.IgnoreCase == true;
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
}
}
@@ -253,7 +238,7 @@ public partial class WireMockServer
private static IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
{
IResponseBuilder responseBuilder = Response.Create();
var responseBuilder = Response.Create();
if (responseModel.Delay > 0)
{

View File

@@ -595,12 +595,12 @@ public partial class WireMockServer : IWireMockServer
/// <param name="protoDefinition">The ProtoDefinition as text.</param>
/// <returns><see cref="WireMockServer"/></returns>
[PublicAPI]
public WireMockServer AddProtoDefinition(string id, string protoDefinition)
public WireMockServer AddProtoDefinition(string id, params string[] protoDefinition)
{
Guard.NotNullOrWhiteSpace(id);
Guard.NotNullOrWhiteSpace(protoDefinition);
Guard.NotNullOrEmpty(protoDefinition);
_settings.ProtoDefinitions ??= new Dictionary<string, string>();
_settings.ProtoDefinitions ??= new Dictionary<string, string[]>();
_settings.ProtoDefinitions[id] = protoDefinition;

View File

@@ -298,7 +298,7 @@ public class WireMockServerSettings
public IDictionary<string, Func<MatcherModel, IMatcher>>? CustomMatcherMappings { get; set; }
/// <summary>
/// The <see cref="JsonSerializerSettings"/> used when the a JSON response is generated.
/// The <see cref="JsonSerializerSettings"/> used when the JSON response is generated.
/// </summary>
[PublicAPI, JsonIgnore]
public JsonSerializerSettings? JsonSerializerSettings { get; set; }
@@ -315,7 +315,7 @@ public class WireMockServerSettings
/// A list of Grpc ProtoDefinitions which can be used.
/// </summary>
[PublicAPI]
public Dictionary<string, string>? ProtoDefinitions { get; set; }
public Dictionary<string, string[]>? ProtoDefinitions { get; set; }
/// <summary>
/// A list of GraphQL Schemas which can be used.

View File

@@ -61,7 +61,7 @@ public static class WireMockServerSettingsParser
HandleRequestsSynchronously = parser.GetBoolValue(nameof(WireMockServerSettings.HandleRequestsSynchronously)),
HostingScheme = parser.GetEnumValue<HostingScheme>(nameof(WireMockServerSettings.HostingScheme)),
MaxRequestLogCount = parser.GetIntValue(nameof(WireMockServerSettings.MaxRequestLogCount)),
ProtoDefinitions = parser.GetObjectValueFromJson<Dictionary<string, string>>(nameof(settings.ProtoDefinitions)),
ProtoDefinitions = parser.GetObjectValueFromJson<Dictionary<string, string[]>>(nameof(settings.ProtoDefinitions)),
QueryParameterMultipleValueSupport = parser.GetEnumValue<QueryParameterMultipleValueSupport>(nameof(WireMockServerSettings.QueryParameterMultipleValueSupport)),
ReadStaticMappings = parser.GetBoolValue(nameof(WireMockServerSettings.ReadStaticMappings)),
RequestLogExpirationDuration = parser.GetIntValue(nameof(WireMockServerSettings.RequestLogExpirationDuration)),

View File

@@ -27,7 +27,9 @@ internal class HandlebarsContext : IHandlebarsContext
public object? ParseAndEvaluate(string text, object model)
{
if (Handlebars.TryEvaluate(text, model, out var result) && result is not UndefinedBindingResult)
if (text.StartsWith("{{") && text.EndsWith("}}") &&
Handlebars.TryEvaluate(text, model, out var result) &&
result is not UndefinedBindingResult)
{
return result;
}

View File

@@ -198,7 +198,7 @@ internal class Transformer : ITransformer
private JToken ReplaceSingleNode(ITransformerContext transformerContext, ReplaceNodeOptions options, string stringValue, object model)
{
string transformedString = transformerContext.ParseAndRender(stringValue, model);
var transformedString = transformerContext.ParseAndRender(stringValue, model);
if (!string.Equals(stringValue, transformedString))
{
@@ -346,7 +346,7 @@ internal class Transformer : ITransformer
private static IBodyData TransformBodyAsFile(ITransformerContext transformerContext, object model, IBodyData original, bool useTransformerForBodyAsFile)
{
string transformedBodyAsFilename = transformerContext.ParseAndRender(original.BodyAsFile!, model);
var transformedBodyAsFilename = transformerContext.ParseAndRender(original.BodyAsFile!, model);
if (!useTransformerForBodyAsFile)
{
@@ -358,7 +358,7 @@ internal class Transformer : ITransformer
};
}
string text = transformerContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
var text = transformerContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
return new BodyData
{
DetectedBodyType = BodyType.String,

View File

@@ -1,7 +1,7 @@
// Copyright © WireMock.Net
#if PROTOBUF
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using JsonConverter.Abstractions;
@@ -13,31 +13,25 @@ namespace WireMock.Util;
internal static class ProtoBufUtils
{
internal static async Task<byte[]> GetProtoBufMessageWithHeaderAsync(
string? protoDefinition,
IReadOnlyList<string>? protoDefinitions,
string? messageType,
object? value,
IJsonConverter? jsonConverter = null,
JsonConverterOptions? options = null,
CancellationToken cancellationToken = default
)
{
if (string.IsNullOrWhiteSpace(protoDefinition) || string.IsNullOrWhiteSpace(messageType) || value is null)
if (protoDefinitions == null || string.IsNullOrWhiteSpace(messageType) || value is null)
{
return Array.Empty<byte>();
return [];
}
var request = new ConvertToProtoBufRequest(protoDefinition, messageType, value, true);
var resolver = new WireMockProtoFileResolver(protoDefinitions);
var request = new ConvertToProtoBufRequest(protoDefinitions[0], messageType, value, true)
.WithProtoFileResolver(resolver);
if (jsonConverter != null)
{
request = request.WithJsonConverter(jsonConverter);
if (options != null)
{
request = request.WithJsonConverterOptions(options);
}
}
return await SingletonFactory<Converter>.GetInstance().ConvertAsync(request, cancellationToken).ConfigureAwait(false);
return await SingletonFactory<Converter>
.GetInstance()
.ConvertAsync(request, cancellationToken).ConfigureAwait(false);
}
}
#endif

View File

@@ -0,0 +1,46 @@
// Copyright © WireMock.Net
#if PROTOBUF
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ProtoBufJsonConverter;
using Stef.Validation;
namespace WireMock.Util;
internal class WireMockProtoFileResolver : IProtoFileResolver
{
private readonly Dictionary<string, string> _files = new();
public WireMockProtoFileResolver(IReadOnlyCollection<string> protoDefinitions)
{
if (Guard.NotNullOrEmpty(protoDefinitions).Count() > 1)
{
foreach (var extraProtoDefinition in protoDefinitions.Skip(1))
{
var firstNonEmptyLine = extraProtoDefinition.Split(['\r', '\n']).FirstOrDefault(l => !string.IsNullOrEmpty(l));
if (firstNonEmptyLine != null)
{
_files.Add(firstNonEmptyLine.TrimStart(['\r', '\n', '/', ' ']), extraProtoDefinition);
}
}
}
}
public bool Exists(string path)
{
return _files.ContainsKey(path);
}
public TextReader OpenText(string path)
{
if (_files.TryGetValue(path, out var extraProtoDefinition))
{
return new StringReader(extraProtoDefinition);
}
throw new FileNotFoundException($"The ProtoDefinition '{path}' was not found.");
}
}
#endif

View File

@@ -59,13 +59,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JsonConverter.Abstractions" Version="0.5.0" />
<PackageReference Include="JsonConverter.Abstractions" Version="0.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
<PackageReference Include="NSwag.Core" Version="13.16.1" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
<PackageReference Include="AnyOf" Version="0.3.0" />
<PackageReference Include="JmesPath.Net" Version="1.0.330" />
<PackageReference Include="AnyOf" Version="0.4.0" />
<PackageReference Include="TinyMapper" Version="3.0.3" />
</ItemGroup>
@@ -108,9 +108,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/697 -->
<PackageReference Include="System.Text.Encodings.Web" Version="4.7.2" />
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/507 -->
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
</ItemGroup>
@@ -147,10 +144,9 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
<PackageReference Include="GraphQL" Version="7.5.0" />
<PackageReference Include="GraphQL.NewtonsoftJson" Version="7.5.0" />
<PackageReference Include="GraphQL.NewtonsoftJson" Version="8.2.1" />
<PackageReference Include="MimeKitLite" Version="4.1.0.1" />
<PackageReference Include="ProtoBufJsonConverter" Version="0.3.0" />
<PackageReference Include="ProtoBufJsonConverter" Version="0.5.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
@@ -179,17 +175,22 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.6" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.6" />
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.4.6" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.6" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.6" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.6" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.6" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' ">
<PackageReference Include="Handlebars.Net.Helpers.Xslt" Version="2.4.4" />
<PackageReference Include="Handlebars.Net.Helpers.Xslt" Version="2.4.6" />
</ItemGroup>
<ItemGroup>
<!-- CVE-2021-26701 and https://github.com/WireMock-Net/WireMock.Net/issues/697 -->
<PackageReference Include="System.Text.Encodings.Web" Version="4.7.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -30,8 +30,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AnyOf" Version="0.3.0" />
<PackageReference Include="RestEase" Version="1.5.7" />
<PackageReference Include="AnyOf" Version="0.4.0" />
<PackageReference Include="RestEase" Version="1.6.4" />
</ItemGroup>
<ItemGroup>

View File

@@ -47,9 +47,9 @@ public class WireMockLogger : IWireMockLogger
}
/// <see cref="IWireMockLogger.Error(string, Exception)"/>
public void Error(string formatString, Exception exception)
public void Error(string message, Exception exception)
{
_logger.LogError(exception, formatString);
_logger.LogError(exception, message);
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>

View File

@@ -17,7 +17,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,8 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<ItemGroup Condition=" '$(TargetFramework)' != 'net45' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net461' ">
<AssemblyAttribute Include="System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute" />
</ItemGroup>
</Project>

View File

@@ -18,7 +18,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -8,10 +8,7 @@ namespace WireMock.Net.Aspire.Tests;
[ExcludeFromCodeCoverage]
internal static class DockerUtils
{
public static bool IsDockerRunningLinuxContainerMode()
{
return IsDockerRunning() && IsLinuxContainerMode();
}
public static Lazy<bool> IsDockerRunningLinuxContainerMode => new(() => IsDockerRunning() && IsLinuxContainerMode());
private static bool IsDockerRunning()
{

View File

@@ -0,0 +1,16 @@
// Copyright © WireMock.Net
namespace WireMock.Net.Aspire.Tests.Facts;
public sealed class DockerIsRunningInLinuxContainerModeFact : FactAttribute
{
private const string SkipReason = "Docker is not running in Linux container mode. Skipping test.";
public DockerIsRunningInLinuxContainerModeFact()
{
if (!DockerUtils.IsDockerRunningLinuxContainerMode.Value)
{
Skip = SkipReason;
}
}
}

View File

@@ -3,6 +3,7 @@
using System.Net.Http.Json;
using FluentAssertions;
using Projects;
using WireMock.Net.Aspire.Tests.Facts;
using Xunit.Abstractions;
namespace WireMock.Net.Aspire.Tests;
@@ -11,15 +12,9 @@ public class IntegrationTests(ITestOutputHelper output)
{
private record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary);
[Fact]
[DockerIsRunningInLinuxContainerModeFact]
public async Task StartAppHostWithWireMockAndCreateHttpClientToCallTheMockedWeatherForecastEndpoint()
{
if (!DockerUtils.IsDockerRunningLinuxContainerMode())
{
output.WriteLine("Docker is not running in Linux container mode. Skipping test.");
return;
}
// Arrange
var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>();
await using var app = await appHostBuilder.BuildAsync();
@@ -44,15 +39,9 @@ public class IntegrationTests(ITestOutputHelper output)
weatherForecasts2.Should().HaveCount(5);
}
[Fact]
[DockerIsRunningInLinuxContainerModeFact]
public async Task StartAppHostWithWireMockAndCreateWireMockAdminClientToCallTheAdminEndpoint()
{
if (!DockerUtils.IsDockerRunningLinuxContainerMode())
{
output.WriteLine("Docker is not running in Linux container mode. Skipping test.");
return;
}
// Arrange
var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>();
await using var app = await appHostBuilder.BuildAsync();

View File

@@ -6,13 +6,14 @@
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<SonarQubeExclude>true</SonarQubeExclude>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../src/WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="8.2.0" />
<PackageReference Include="Aspire.Hosting.Testing" Version="8.2.2" />
<PackageReference Include="Codecov" Version="1.13.0" />
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>

View File

@@ -0,0 +1,25 @@
// Copyright © WireMock.Net
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
namespace WireMock.Net.Middleware.Tests;
internal class CustomWebApplicationFactory<TEntryPoint> : WebApplicationFactory<TEntryPoint>
where TEntryPoint : class
{
private readonly List<(string Key, string Value)> _settings = new();
public CustomWebApplicationFactory(bool alwaysRedirectToWireMock = true)
{
_settings.Add(("AlwaysRedirectToWireMock", alwaysRedirectToWireMock.ToString().ToLowerInvariant()));
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
foreach (var arg in _settings)
{
builder.UseSetting(arg.Key, arg.Value);
}
}
}

View File

@@ -0,0 +1,49 @@
// Copyright © WireMock.Net
using FluentAssertions;
using WireMock.Net.TestWebApplication;
namespace WireMock.Net.Middleware.Tests;
public class IntegrationTests
{
[Theory]
[InlineData("/real1", "Hello 1 from WireMock.Net !")]
[InlineData("/real2", "Hello 2 from WireMock.Net !")]
public async Task CallingRealApi_WithAlwaysRedirectToWireMockIsTrue(string requestUri, string expectedResponse)
{
// Arrange
await using var factory = new CustomWebApplicationFactory<Program>();
using var client = factory.CreateClient();
// Act
var response = await client.GetAsync(requestUri);
// Assert
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
stringResponse.Should().Be(expectedResponse);
}
[Theory]
[InlineData("/real1", "Hello 1 from WireMock.Net !")]
[InlineData("/real2", "Hello 2 from WireMock.Net !")]
public async Task CallingRealApi_WithAlwaysRedirectToWireMockIsFalse(string requestUri, string expectedResponse)
{
// Arrange
await using var factory = new CustomWebApplicationFactory<Program>(false);
using var client = factory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.Add("X-WireMock-Redirect", "true");
request.Headers.Add("X-WireMock-Response-Delay", "10");
// Act
var response = await client.SendAsync(request);
// Assert
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
stringResponse.Should().Be(expectedResponse);
}
}

View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../src/WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Codecov" Version="1.13.0" />
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.TestWebApplication\WireMock.Net.TestWebApplication.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,37 @@
// Copyright © WireMock.Net
using WireMock.Net.TUnit;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.TUnitTests;
// ReSharper disable once InconsistentNaming
public class TUnitTests
{
[Test]
public async Task Test_TUnitWireMockLogger()
{
// Assign
var path = $"/foo_{Guid.NewGuid()}";
using var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = new TUnitWireMockLogger(TestContext.Current!.GetDefaultLogger())
});
server
.Given(Request.Create()
.WithPath(path)
.UsingGet())
.RespondWith(Response.Create().WithBody("TUnit"));
// Act
var response = await server.CreateClient().GetStringAsync($"{server.Url}{path}");
// Assert
await Assert.That(response).IsEqualTo("TUnit");
}
}

View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsTestProject>true</IsTestProject>
<SonarQubeExclude>true</SonarQubeExclude>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TUnit" Version="0.2.195" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.TUnit\WireMock.Net.TUnit.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,49 @@
using WireMock.Net.AspNetCore.Middleware;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
namespace WireMock.Net.TestWebApplication;
// Make the implicit Program class public so test projects can access it.
public class Program
{
public static async Task Main(string[] args)
{
var alwaysRedirectToWireMock = args.Contains("--AlwaysRedirectToWireMock=true");
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWireMockService(server =>
{
server.Given(Request.Create()
.WithPath("/test1")
.UsingAnyMethod()
).RespondWith(Response.Create()
.WithBody("Hello 1 from WireMock.Net !")
);
server.Given(Request.Create()
.WithPath("/test2")
.UsingAnyMethod()
).RespondWith(Response.Create()
.WithBody("Hello 2 from WireMock.Net !")
);
}, alwaysRedirectToWireMock);
var app = builder.Build();
app.MapGet("/real1", async (HttpClient client) =>
{
var result = await client.GetStringAsync("https://real-api:12345/test1");
return result;
});
app.MapGet("/real2", async (IHttpClientFactory factory) =>
{
using var client = factory.CreateClient();
return await client.GetStringAsync("https://real-api:12345/test2");
});
await app.RunAsync();
}
}

View File

@@ -0,0 +1,12 @@
{
"profiles": {
"WireMock.Net.TestWebApplication": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:57712;http://localhost:57713"
}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.AspNetCore.Middleware\WireMock.Net.AspNetCore.Middleware.csproj" />
</ItemGroup>
</Project>

Some files were not shown because too many files have changed in this diff Show More