mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-13 13:53:34 +01:00
Compare commits
58 Commits
bug/973-Ti
...
1.6.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
888d913729 | ||
|
|
6688a64d49 | ||
|
|
6aa1594d31 | ||
|
|
44c1c7aaa8 | ||
|
|
9c94324cff | ||
|
|
1198feae5e | ||
|
|
ab7ce37e7e | ||
|
|
485f7ad952 | ||
|
|
c4ae4eaf8e | ||
|
|
6db5427e6e | ||
|
|
deda7fb686 | ||
|
|
2a19b4491f | ||
|
|
c548600dea | ||
|
|
7f640dfa0d | ||
|
|
4b3e9feca0 | ||
|
|
4aaed2a6ca | ||
|
|
6f73dfe360 | ||
|
|
f4103b47aa | ||
|
|
edab3ad7e5 | ||
|
|
38c2131472 | ||
|
|
3693d6a676 | ||
|
|
214fb539ec | ||
|
|
a468b89788 | ||
|
|
1682c61a0c | ||
|
|
ac693e0f96 | ||
|
|
45755adae4 | ||
|
|
2ffdae1863 | ||
|
|
5adbff0fa3 | ||
|
|
5e04ff1a42 | ||
|
|
eb7e6c397f | ||
|
|
f56ecf943d | ||
|
|
76ae1466cc | ||
|
|
edbc7aeb5c | ||
|
|
42306d1864 | ||
|
|
c57590b2ba | ||
|
|
dca3fd0260 | ||
|
|
95994421ae | ||
|
|
697411555a | ||
|
|
f89f0fa466 | ||
|
|
b892e85d2a | ||
|
|
836976ca19 | ||
|
|
c845f73dd0 | ||
|
|
2cbbef01ae | ||
|
|
dd80fd7822 | ||
|
|
527278e60c | ||
|
|
7d7f1f8fbb | ||
|
|
af124d556d | ||
|
|
60931f6273 | ||
|
|
b99a80e782 | ||
|
|
07c9aebf44 | ||
|
|
8348a7b9a3 | ||
|
|
9a49e6a1cd | ||
|
|
f82891c996 | ||
|
|
da100298c1 | ||
|
|
95573eeb96 | ||
|
|
487d6d2db1 | ||
|
|
d2b53893db | ||
|
|
088444024f |
25
.github/workflows/ci.yml
vendored
25
.github/workflows/ci.yml
vendored
@@ -19,8 +19,14 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Execute Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
- name: 'WireMock.Net.Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests'
|
||||
run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Middleware.Tests'
|
||||
run: 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
|
||||
@@ -32,11 +38,22 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Execute Tests'
|
||||
- name: Setup .NET 8
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: 'WireMock.Net.Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests'
|
||||
run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Middleware.Tests'
|
||||
run: 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
|
||||
|
||||
- name: 'Execute .NET Aspire Tests'
|
||||
- name: 'WireMock.Net.Aspire.Tests'
|
||||
run: dotnet test './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release
|
||||
111
CHANGELOG.md
111
CHANGELOG.md
@@ -1,3 +1,97 @@
|
||||
# 1.6.12 (21 January 2025)
|
||||
- [#1231](https://github.com/WireMock-Net/WireMock.Net/pull/1231) - Fix google protobuf WellKnownTypes: Empty, Duration and Timestamp [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1235](https://github.com/WireMock-Net/WireMock.Net/pull/1235) - Fix ArgumentException in FindLogEntries [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1241](https://github.com/WireMock-Net/WireMock.Net/pull/1241) - Upgrade to Handlebars.Net.Helpers 2.4.9 [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1227](https://github.com/WireMock-Net/WireMock.Net/issues/1227) - unable to call grpc method with namespace [bug]
|
||||
- [#1228](https://github.com/WireMock-Net/WireMock.Net/issues/1228) - how to set datetime for grpc field [bug]
|
||||
- [#1234](https://github.com/WireMock-Net/WireMock.Net/issues/1234) - FindLogEntries regression [bug]
|
||||
- [#1240](https://github.com/WireMock-Net/WireMock.Net/issues/1240) - Method 'get_Category' in type 'WireMock.Transformers.Handlebars.FileHelpers' [bug]
|
||||
|
||||
# 1.6.11 (02 January 2025)
|
||||
- [#1221](https://github.com/WireMock-Net/WireMock.Net/pull/1221) - Add overloads to AtUrl and AtAbsoluteUrl which can use a IStringMatcher [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1222](https://github.com/WireMock-Net/WireMock.Net/pull/1222) - Fix WireMockContainerBuilder (duplicate entries) [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1223](https://github.com/WireMock-Net/WireMock.Net/pull/1223) - Add functionality to call a PostTransform method after the Webhook request has been transformed [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1224](https://github.com/WireMock-Net/WireMock.Net/pull/1224) - Add FindLogEntries to IWireMockServer [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1092](https://github.com/WireMock-Net/WireMock.Net/issues/1092) - FindLogEntries present in WireMockServer but not IWireMockServer [feature]
|
||||
- [#1192](https://github.com/WireMock-Net/WireMock.Net/issues/1192) - Feature: add URL assertion excluding query parameters [feature]
|
||||
- [#1204](https://github.com/WireMock-Net/WireMock.Net/issues/1204) - Supplying Values From Request for Webhook Body and Headers [feature]
|
||||
- [#1217](https://github.com/WireMock-Net/WireMock.Net/issues/1217) - Order of WireMockContainerBuilder WithX calls caused duplicate Networks in Configuration [bug]
|
||||
|
||||
# 1.6.10 (15 December 2024)
|
||||
- [#1189](https://github.com/WireMock-Net/WireMock.Net/pull/1189) - WireMock.Net.Testcontainers: implement watching the static mapping folder for changes [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1188](https://github.com/WireMock-Net/WireMock.Net/issues/1188) - WithWatchStaticMappings doesn't respect new files [bug]
|
||||
|
||||
# 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]
|
||||
|
||||
# 1.6.2 (04 September 2024)
|
||||
- [#1152](https://github.com/WireMock-Net/WireMock.Net/pull/1152) - Update MappingConverter to correctly write the Matcher as C# code [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1163](https://github.com/WireMock-Net/WireMock.Net/pull/1163) - Upgrade Aspire to version 8.2.0 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1166](https://github.com/WireMock-Net/WireMock.Net/pull/1166) - Also update IWireMockMiddlewareOptions when settings are updated via admin interface [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1151](https://github.com/WireMock-Net/WireMock.Net/issues/1151) - MappingsToCSharpCode should use RegexMatcher when specified [bug]
|
||||
- [#1164](https://github.com/WireMock-Net/WireMock.Net/issues/1164) - WithParam not working. [bug]
|
||||
|
||||
# 1.6.1 (22 August 2024)
|
||||
- [#1160](https://github.com/WireMock-Net/WireMock.Net/pull/1160) - Use default timeout for Regex [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1159](https://github.com/WireMock-Net/WireMock.Net/issues/1159) - RegexMatchTimeoutException when trying to parse HTTP version [bug]
|
||||
|
||||
# 1.6.0 (16 August 2024)
|
||||
- [#1042](https://github.com/WireMock-Net/WireMock.Net/pull/1042) - Update + add fluent builder methods [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1109](https://github.com/WireMock-Net/WireMock.Net/pull/1109) - Add Aspire Extension [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1148](https://github.com/WireMock-Net/WireMock.Net/pull/1148) - Use Guid.TryParseExact with format "D" contributed by [StefH](https://github.com/StefH)
|
||||
- [#1157](https://github.com/WireMock-Net/WireMock.Net/pull/1157) - Fix FormUrlEncodedMatcher (MatchOperator.And) [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1158](https://github.com/WireMock-Net/WireMock.Net/pull/1158) - Allow setting Content-Length header on the response [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#720](https://github.com/WireMock-Net/WireMock.Net/issues/720) - Response Header Content-Length not available when call HEAD Method [feature]
|
||||
- [#1145](https://github.com/WireMock-Net/WireMock.Net/issues/1145) - Response is auto converting string to guid [bug]
|
||||
- [#1156](https://github.com/WireMock-Net/WireMock.Net/issues/1156) - FormUrlEncodedMatcher is not requiring to match all properties when MatchOperator.And [bug]
|
||||
|
||||
# 1.5.62 (27 July 2024)
|
||||
- [#1147](https://github.com/WireMock-Net/WireMock.Net/pull/1147) - Add FormUrlEncodedMatcher [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1143](https://github.com/WireMock-Net/WireMock.Net/issues/1143) - FormEncoded Request fails (404 Not Found) if key value pairs order in mapping is different from request body order [bug]
|
||||
@@ -17,9 +111,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]
|
||||
@@ -104,7 +196,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="Long" [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]
|
||||
@@ -113,12 +204,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)
|
||||
|
||||
@@ -130,7 +218,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 "IgnoreCase" property of HeaderModel [bug]
|
||||
|
||||
@@ -142,7 +229,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)
|
||||
@@ -168,7 +254,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]
|
||||
@@ -189,7 +274,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)
|
||||
@@ -238,7 +322,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)
|
||||
@@ -254,7 +337,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]
|
||||
@@ -334,7 +416,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)
|
||||
@@ -620,9 +701,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 "blacklist" and "whitelist" 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)
|
||||
@@ -923,7 +1001,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)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.5.62</VersionPrefix>
|
||||
<VersionPrefix>1.6.12</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>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=1.5.62
|
||||
SET version=1.6.12
|
||||
|
||||
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%
|
||||
@@ -1,5 +1,10 @@
|
||||
# 1.5.62 (27 July 2024)
|
||||
- #1147 Add FormUrlEncodedMatcher [feature]
|
||||
- #1143 FormEncoded Request fails (404 Not Found) if key value pairs order in mapping is different from request body order [bug]
|
||||
# 1.6.12 (21 January 2025)
|
||||
- #1231 Fix google protobuf WellKnownTypes: Empty, Duration and Timestamp [bug]
|
||||
- #1235 Fix ArgumentException in FindLogEntries [bug]
|
||||
- #1241 Upgrade to Handlebars.Net.Helpers 2.4.9 [bug]
|
||||
- #1227 unable to call grpc method with namespace [bug]
|
||||
- #1228 how to set datetime for grpc field [bug]
|
||||
- #1234 FindLogEntries regression [bug]
|
||||
- #1240 Method 'get_Category' in type 'WireMock.Transformers.Handlebars.FileHelpers' [bug]
|
||||
|
||||
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
||||
32
README.md
32
README.md
@@ -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
|
||||
@@ -39,16 +40,21 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
|
||||
|
||||
| | Official | Preview [:information_source:](https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions) |
|
||||
| - | - | - |
|
||||
| **WireMock.Net** | [](https://www.nuget.org/packages/WireMock.Net) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
|
||||
| **WireMock.Net.StandAlone** | [](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
|
||||
| **WireMock.Net.FluentAssertions** | [](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
||||
| **WireMock.Net.Testcontainers** | [](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
|
||||
| **WireMock.Net.Aspire** | [](https://www.nuget.org/packages/WireMock.Net.Aspire) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire)
|
||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||
| **WireMock.Net** | [](https://www.nuget.org/packages/WireMock.Net) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
|
||||
| **WireMock.Net.StandAlone** | [](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
|
||||
| **WireMock.Net.Testcontainers** | [](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
|
||||
| **WireMock.Net.Aspire** | [](https://www.nuget.org/packages/WireMock.Net.Aspire) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire)
|
||||
| **WireMock.Net.AspNetCore.Middleware** | [](https://www.nuget.org/packages/WireMock.Net.AspNetCore.Middleware) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.AspNetCore.Middleware)
|
||||
| | | |
|
||||
| **WireMock.Net.FluentAssertions** | [](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
|
||||
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
||||
| **WireMock.Net.TUnit** | [](https://www.nuget.org/packages/WireMock.Net.TUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.TUnit)
|
||||
| | | |
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
| | | |
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||
|
||||
|
||||
## :memo: Development
|
||||
|
||||
@@ -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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Guids/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Levenstein/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=openapi/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pacticipant/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=protobuf/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -43,6 +44,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sigil/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=templated/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Testcontainers/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Victoor/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhook/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhooks/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@@ -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,9 +52,26 @@ 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"
|
||||
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"
|
||||
displayName: 'Execute Unit 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"
|
||||
displayName: 'WireMock.Net.Tests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
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"
|
||||
displayName: 'WireMock.Net.TUnitTests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
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: 'WireMock.Net.Middleware.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-aspire.xml"
|
||||
displayName: 'WireMock.Net.Aspire.Tests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'Merge coverage files'
|
||||
@@ -98,18 +115,25 @@ jobs:
|
||||
version: '8.0.x'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Build Unit tests'
|
||||
inputs:
|
||||
command: 'build'
|
||||
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj'
|
||||
arguments: '--configuration Debug --framework net8.0'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Execute Unit Tests with Coverage'
|
||||
displayName: 'WireMock.Net.Tests with Coverage'
|
||||
inputs:
|
||||
command: 'test'
|
||||
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj'
|
||||
arguments: '--no-build --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
arguments: '--configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'WireMock.Net.TUnitTests with Coverage'
|
||||
inputs:
|
||||
command: 'test'
|
||||
projects: './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj'
|
||||
arguments: '--configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'WireMock.Net.Middleware.Tests with Coverage'
|
||||
inputs:
|
||||
command: 'test'
|
||||
projects: './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj'
|
||||
arguments: '--configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
|
||||
- job: Windows_Release_to_MyGet
|
||||
dependsOn: Windows_Build_Test
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.0" />
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,20 +2,49 @@ 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}");
|
||||
|
||||
var wiremock = builder
|
||||
IResourceBuilder<WireMockServerResource> apiService = builder
|
||||
.AddWireMock("apiservice", WireMockServerArguments.DefaultPort)
|
||||
.WithMappingsPath(mappingsPath)
|
||||
.WithReadStaticMappings()
|
||||
.WithWatchStaticMappings()
|
||||
.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();
|
||||
@@ -4,7 +4,7 @@ namespace AspireApp1.AppHost;
|
||||
|
||||
internal class WeatherForecastApiMock
|
||||
{
|
||||
public static async Task BuildAsync(AdminApiMappingBuilder builder)
|
||||
public static async Task BuildAsync(AdminApiMappingBuilder builder, CancellationToken cancellationToken)
|
||||
{
|
||||
var summaries = new[]
|
||||
{
|
||||
@@ -23,13 +23,13 @@ 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())
|
||||
)
|
||||
);
|
||||
|
||||
await builder.BuildAndPostAsync();
|
||||
await builder.BuildAndPostAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.0" />
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -137,7 +137,6 @@ message HelloReply {
|
||||
public static void Run()
|
||||
{
|
||||
RunOnLocal();
|
||||
return;
|
||||
|
||||
var mappingBuilder = new MappingBuilder();
|
||||
mappingBuilder
|
||||
@@ -308,17 +307,6 @@ message HelloReply {
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("GraphQL is ok")
|
||||
);
|
||||
|
||||
//server
|
||||
// .AddGraphQLSchema("my-graphql", TestSchema, customScalars)
|
||||
// .Given(Request.Create()
|
||||
// .WithPath("/graphql2")
|
||||
// .UsingPost()
|
||||
// )
|
||||
// .WithGraphQLSchema("my-graphql")
|
||||
// .RespondWith(Response.Create()
|
||||
// .WithBody("GraphQL is ok")
|
||||
// );
|
||||
#endif
|
||||
|
||||
#if MIMEKIT
|
||||
@@ -377,6 +365,15 @@ message HelloReply {
|
||||
.WithHeader("Content-Type", "text/plain")
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingHead()
|
||||
.WithPath("/cl")
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithHeader("Content-Length", "42")
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -1,27 +1,234 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using DotNet.Testcontainers.Builders;
|
||||
using DotNet.Testcontainers.Configurations;
|
||||
using Newtonsoft.Json;
|
||||
using Testcontainers.MsSql;
|
||||
using WireMock.Net.Testcontainers;
|
||||
|
||||
namespace WireMock.Net.TestcontainersExample;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static readonly ConsoleColor OriginalColor = Console.ForegroundColor;
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
var container = new WireMockContainerBuilder()
|
||||
.WithAdminUserNameAndPassword("x", "y")
|
||||
.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings")
|
||||
await TestLinux();
|
||||
|
||||
await TestAutomatic();
|
||||
|
||||
await TestLinuxWithVersionTag();
|
||||
|
||||
await TestLinuxAlpineWithVersionTag();
|
||||
|
||||
await TestWindowsWithVersionTag();
|
||||
|
||||
await TestWindows();
|
||||
|
||||
await TestCopy();
|
||||
}
|
||||
|
||||
private static async Task TestWindows()
|
||||
{
|
||||
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 = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestWindowsWithVersionTag()
|
||||
{
|
||||
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 = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestLinux()
|
||||
{
|
||||
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 = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestLinuxAlpineWithVersionTag()
|
||||
{
|
||||
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 = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestLinuxWithVersionTag()
|
||||
{
|
||||
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 = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestAutomatic()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine("Automatic");
|
||||
await TestAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.ForegroundColor = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestCopy()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine("Copy");
|
||||
await TestWindowsCopyAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.ForegroundColor = OriginalColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task TestWindowsCopyAsync()
|
||||
{
|
||||
var builder = new WireMockContainerBuilder()
|
||||
.WithWatchStaticMappings(true)
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true);
|
||||
|
||||
var container = builder.Build();
|
||||
|
||||
await container.StartAsync();
|
||||
|
||||
if (await GetImageOSAsync.Value == OSPlatform.Linux)
|
||||
{
|
||||
try
|
||||
{
|
||||
await container.CopyAsync(@"C:\temp-wiremock\__admin\mappings\StefBodyAsFileExample.json", "/app/__admin/mappings");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("PublicUrl = " + container.GetPublicUrl());
|
||||
|
||||
var adminClient = container.CreateWireMockAdminClient();
|
||||
|
||||
var mappings = await adminClient.GetMappingsAsync();
|
||||
Console.WriteLine("mappings = " + JsonConvert.SerializeObject(mappings, Formatting.Indented));
|
||||
|
||||
await Task.Delay(1_000);
|
||||
|
||||
await container.StopAsync();
|
||||
}
|
||||
|
||||
private static async Task TestAsync(string? image = null)
|
||||
{
|
||||
var mappingsPath = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "WireMock.Net.Console.NET6", "__admin", "mappings");
|
||||
|
||||
var dummyNetwork = new NetworkBuilder()
|
||||
.WithName($"Dummy Network for {image ?? "null"}")
|
||||
.WithReuse(true)
|
||||
.WithCleanUp(true)
|
||||
.Build();
|
||||
|
||||
await container.StartAsync().ConfigureAwait(false);
|
||||
var builder = new WireMockContainerBuilder()
|
||||
.WithNetwork(dummyNetwork)
|
||||
.WithAdminUserNameAndPassword("x", "y")
|
||||
.WithMappings(mappingsPath)
|
||||
.WithWatchStaticMappings(true)
|
||||
// .WithAutoRemove(true)
|
||||
.WithCleanUp(true);
|
||||
|
||||
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false);
|
||||
Console.WriteLine("logs = " + logs.Stdout);
|
||||
if (image != null)
|
||||
{
|
||||
builder = image switch
|
||||
{
|
||||
"WithWindows" => builder.WithWindowsImage(),
|
||||
"WithLinux" => builder.WithLinuxImage(),
|
||||
_ => builder.WithImage(image)
|
||||
};
|
||||
}
|
||||
|
||||
var container = builder.Build();
|
||||
|
||||
await container.StartAsync();
|
||||
|
||||
await container.ReloadStaticMappingsAsync();
|
||||
|
||||
//var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1));
|
||||
//Console.WriteLine("logs = " + logs.Stdout);
|
||||
|
||||
Console.WriteLine("PublicUrl = " + container.GetPublicUrl());
|
||||
|
||||
var restEaseApiClient = container.CreateWireMockAdminClient();
|
||||
|
||||
@@ -29,17 +236,26 @@ internal class Program
|
||||
Console.WriteLine("settings = " + JsonConvert.SerializeObject(settings, Formatting.Indented));
|
||||
|
||||
var mappings = await restEaseApiClient.GetMappingsAsync();
|
||||
Console.WriteLine("mappings = " + JsonConvert.SerializeObject(mappings, Formatting.Indented));
|
||||
Console.WriteLine("mappingsStef = " + JsonConvert.SerializeObject(mappings, Formatting.Indented));
|
||||
|
||||
var client = container.CreateClient();
|
||||
var result = await client.GetStringAsync("/static/mapping");
|
||||
Console.WriteLine("result = " + result);
|
||||
|
||||
await container.StopAsync();
|
||||
|
||||
var sql = new MsSqlBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.Build();
|
||||
}
|
||||
|
||||
private static readonly Lazy<Task<OSPlatform>> GetImageOSAsync = new(async () =>
|
||||
{
|
||||
if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null)
|
||||
{
|
||||
throw new InvalidOperationException($"The {nameof(TestcontainersSettings.OS.DockerEndpointAuthConfig)} is null. Check if Docker is started.");
|
||||
}
|
||||
|
||||
using var dockerClientConfig = TestcontainersSettings.OS.DockerEndpointAuthConfig.GetDockerClientConfiguration();
|
||||
using var dockerClient = dockerClientConfig.CreateClient();
|
||||
|
||||
var version = await dockerClient.System.GetVersionAsync();
|
||||
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) >= 0 ? OSPlatform.Windows : OSPlatform.Linux;
|
||||
});
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
56
examples/WireMock.Net.WebApplication/Program.cs
Normal file
56
examples/WireMock.Net.WebApplication/Program.cs
Normal 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();
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
examples/WireMock.Net.WebApplication/WeatherForecast.cs
Normal file
4
examples/WireMock.Net.WebApplication/WeatherForecast.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
|
||||
{
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
examples/WireMock.Net.WebApplication/appsettings.json
Normal file
9
examples/WireMock.Net.WebApplication/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using JetBrains.Annotations;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Handlers;
|
||||
@@ -21,69 +20,69 @@ public interface IFileSystemHandler
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>true if path refers to an existing directory; false if the directory does not exist or an error occurs when trying to determine if the specified directory exists.</returns>
|
||||
bool FolderExists([NotNull] string path);
|
||||
bool FolderExists(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Creates all directories and subdirectories in the specified path unless they already exist.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
void CreateFolder([NotNull] string path);
|
||||
void CreateFolder(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerable collection of file names in a specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="includeSubdirectories">A value indicating whether subdirectories should also included when enumerating files.</param>
|
||||
/// <param name="includeSubdirectories">A value indicating whether subdirectories should also be included when enumerating files.</param>
|
||||
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.</returns>
|
||||
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
|
||||
IEnumerable<string> EnumerateFiles(string path, bool includeSubdirectories);
|
||||
|
||||
/// <summary>
|
||||
/// Read a static mapping file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <returns>The file content as text.</returns>
|
||||
string ReadMappingFile([NotNull] string path);
|
||||
string ReadMappingFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Write the static mapping file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteMappingFile([NotNull] string path, [NotNull] string text);
|
||||
void WriteMappingFile(string path, string text);
|
||||
|
||||
/// <summary>
|
||||
/// Read a response body file as byte[].
|
||||
/// </summary>
|
||||
/// <param name="path">The path or filename from the file to read.</param>
|
||||
/// <returns>The file content as bytes.</returns>
|
||||
byte[] ReadResponseBodyAsFile([NotNull] string path);
|
||||
byte[] ReadResponseBodyAsFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Read a response body file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path or filename from the file to read.</param>
|
||||
/// <returns>The file content as text.</returns>
|
||||
string ReadResponseBodyAsString([NotNull] string path);
|
||||
string ReadResponseBodyAsString(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Delete a file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
void DeleteFile([NotNull] string filename);
|
||||
void DeleteFile(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given path refers to an existing file on disk.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>true if path refers to an existing file; false if the file does not exist.</returns>
|
||||
bool FileExists([NotNull] string filename);
|
||||
bool FileExists(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Write a file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
void WriteFile([NotNull] string filename, [NotNull] byte[] bytes);
|
||||
void WriteFile(string filename, byte[] bytes);
|
||||
|
||||
/// <summary>
|
||||
/// Write a file.
|
||||
@@ -91,21 +90,21 @@ public interface IFileSystemHandler
|
||||
/// <param name="folder">The folder.</param>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
void WriteFile([NotNull] string folder, [NotNull] string filename, [NotNull] byte[] bytes);
|
||||
void WriteFile(string folder, string filename, byte[] bytes);
|
||||
|
||||
/// <summary>
|
||||
/// Read a file as bytes.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>The file content as bytes.</returns>
|
||||
byte[] ReadFile([NotNull] string filename);
|
||||
byte[] ReadFile(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Read a file as string.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>The file content as a string.</returns>
|
||||
string ReadFileAsString([NotNull] string filename);
|
||||
string ReadFileAsString(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`.
|
||||
@@ -114,9 +113,9 @@ public interface IFileSystemHandler
|
||||
string GetUnmatchedRequestsFolder();
|
||||
|
||||
/// <summary>
|
||||
/// Write a unmatched request to the Unmatched RequestsFolder.
|
||||
/// Write an unmatched request to the Unmatched RequestsFolder.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text);
|
||||
void WriteUnmatchedRequest(string filename, string text);
|
||||
}
|
||||
@@ -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).
|
||||
|
||||
@@ -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}".
|
||||
|
||||
25
src/WireMock.Net.Abstractions/Models/IBodyDataExtensions.cs
Normal file
25
src/WireMock.Net.Abstractions/Models/IBodyDataExtensions.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
59
src/WireMock.Net.Abstractions/Models/IdOrTexts.cs
Normal file
59
src/WireMock.Net.Abstractions/Models/IdOrTexts.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Server;
|
||||
@@ -27,12 +28,12 @@ public interface IWireMockServer : IDisposable
|
||||
/// <summary>
|
||||
/// Gets the request logs.
|
||||
/// </summary>
|
||||
IEnumerable<ILogEntry> LogEntries { get; }
|
||||
IReadOnlyList<ILogEntry> LogEntries { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mappings as MappingModels.
|
||||
/// </summary>
|
||||
IEnumerable<MappingModel> MappingModels { get; }
|
||||
IReadOnlyList<MappingModel> MappingModels { get; }
|
||||
|
||||
// <summary>
|
||||
// Gets the mappings.
|
||||
@@ -109,7 +110,12 @@ public interface IWireMockServer : IDisposable
|
||||
/// <param name="guid">The unique identifier.</param>
|
||||
bool DeleteMapping(Guid guid);
|
||||
|
||||
//IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers);
|
||||
/// <summary>
|
||||
/// Search log-entries based on matchers.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The request matchers to use.</param>
|
||||
/// <returns>The <see cref="IReadOnlyList{ILogEntry}"/>.</returns>
|
||||
IReadOnlyList<ILogEntry> FindLogEntries(params IRequestMatcher[] matchers);
|
||||
|
||||
// IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false);
|
||||
|
||||
|
||||
@@ -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'">
|
||||
|
||||
9
src/WireMock.Net.AspNetCore.Middleware/AppConstants.cs
Normal file
9
src/WireMock.Net.AspNetCore.Middleware/AppConstants.cs
Normal 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";
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Net.AspNetCore.Middleware.HttpDelegatingHandler;
|
||||
|
||||
internal class WireMockDelegationHandlerSettings
|
||||
{
|
||||
public bool AlwaysRedirect { get; set; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using Aspire.Hosting.ApplicationModel;
|
||||
|
||||
namespace WireMock.Net.Aspire.Extensions;
|
||||
|
||||
internal static class ResourceLoggerServiceExtensions
|
||||
{
|
||||
public static void SetLogger(this ResourceLoggerService resourceLoggerService, WireMockServerResource wireMockServerResource)
|
||||
{
|
||||
var logger = resourceLoggerService.GetLogger(wireMockServerResource);
|
||||
wireMockServerResource.SetLogger(logger);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>0.0.1-preview-05</Version>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Description>Aspire extension to start a WireMock.Net server to stub an api.</Description>
|
||||
<AssemblyTitle>WireMock.Net.Aspire</AssemblyTitle>
|
||||
@@ -31,12 +30,16 @@
|
||||
<None Include="../../resources/WireMock.Net-LogoAspire.png" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net\Util\EnhancedFileSystemWatcher.cs" Link="Utils\EnhancedFileSystemWatcher.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="Aspire.Hosting" Version="8.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -50,7 +50,7 @@ public class WireMockServerArguments
|
||||
///
|
||||
/// Default value is <c>false</c>.
|
||||
/// </summary>
|
||||
public bool WithWatchStaticMappings { get; set; }
|
||||
public bool WatchStaticMappings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the path for the (static) mapping json files.
|
||||
@@ -65,7 +65,7 @@ public class WireMockServerArguments
|
||||
/// <summary>
|
||||
/// Optional delegate that will be invoked to configure the WireMock.Net resource using the <see cref="AdminApiMappingBuilder"/>.
|
||||
/// </summary>
|
||||
public Func<AdminApiMappingBuilder, Task>? ApiMappingBuilder { get; set; }
|
||||
public Func<AdminApiMappingBuilder, CancellationToken, Task>? ApiMappingBuilder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts the current instance's properties to an array of command-line arguments for starting the WireMock.Net server.
|
||||
@@ -88,7 +88,7 @@ public class WireMockServerArguments
|
||||
Add(args, "--ReadStaticMappings", "true");
|
||||
}
|
||||
|
||||
if (WithWatchStaticMappings)
|
||||
if (WatchStaticMappings)
|
||||
{
|
||||
Add(args, "--ReadStaticMappings", "true");
|
||||
Add(args, "--WatchStaticMappings", "true");
|
||||
|
||||
@@ -112,7 +112,7 @@ public static class WireMockServerBuilderExtensions
|
||||
/// <returns>A reference to the <see cref="IResourceBuilder{WireMockServerResource}"/>.</returns>
|
||||
public static IResourceBuilder<WireMockServerResource> WithWatchStaticMappings(this IResourceBuilder<WireMockServerResource> wiremock)
|
||||
{
|
||||
Guard.NotNull(wiremock).Resource.Arguments.WithWatchStaticMappings = true;
|
||||
Guard.NotNull(wiremock).Resource.Arguments.WatchStaticMappings = true;
|
||||
return wiremock;
|
||||
}
|
||||
|
||||
@@ -124,8 +124,10 @@ public static class WireMockServerBuilderExtensions
|
||||
/// <returns>A reference to the <see cref="IResourceBuilder{WireMockServerResource}"/>.</returns>
|
||||
public static IResourceBuilder<WireMockServerResource> WithMappingsPath(this IResourceBuilder<WireMockServerResource> wiremock, string mappingsPath)
|
||||
{
|
||||
return Guard.NotNull(wiremock)
|
||||
.WithBindMount(Guard.NotNullOrWhiteSpace(mappingsPath), DefaultLinuxMappingsPath);
|
||||
Guard.NotNullOrWhiteSpace(mappingsPath);
|
||||
Guard.NotNull(wiremock).Resource.Arguments.MappingsPath = mappingsPath;
|
||||
|
||||
return wiremock.WithBindMount(mappingsPath, DefaultLinuxMappingsPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -151,6 +153,17 @@ public static class WireMockServerBuilderExtensions
|
||||
/// <param name="configure">Delegate that will be invoked to configure the WireMock.Net resource.</param>
|
||||
/// <returns></returns>
|
||||
public static IResourceBuilder<WireMockServerResource> WithApiMappingBuilder(this IResourceBuilder<WireMockServerResource> wiremock, Func<AdminApiMappingBuilder, Task> configure)
|
||||
{
|
||||
return wiremock.WithApiMappingBuilder((adminApiMappingBuilder, _) => configure.Invoke(adminApiMappingBuilder));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use WireMock Client's AdminApiMappingBuilder to configure the WireMock.Net resource.
|
||||
/// </summary>
|
||||
/// <param name="wiremock">The <see cref="IResourceBuilder{WireMockServerResource}"/>.</param>
|
||||
/// <param name="configure">Delegate that will be invoked to configure the WireMock.Net resource.</param>
|
||||
/// <returns></returns>
|
||||
public static IResourceBuilder<WireMockServerResource> WithApiMappingBuilder(this IResourceBuilder<WireMockServerResource> wiremock, Func<AdminApiMappingBuilder, CancellationToken, Task> configure)
|
||||
{
|
||||
Guard.NotNull(wiremock);
|
||||
|
||||
|
||||
@@ -3,50 +3,39 @@
|
||||
using Aspire.Hosting.ApplicationModel;
|
||||
using Aspire.Hosting.Lifecycle;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RestEase;
|
||||
using WireMock.Client;
|
||||
using WireMock.Client.Extensions;
|
||||
|
||||
namespace WireMock.Net.Aspire;
|
||||
|
||||
internal class WireMockServerLifecycleHook(ResourceLoggerService loggerService) : IDistributedApplicationLifecycleHook
|
||||
internal class WireMockServerLifecycleHook(ILoggerFactory loggerFactory) : IDistributedApplicationLifecycleHook, IAsyncDisposable
|
||||
{
|
||||
private readonly CancellationTokenSource _shutdownCts = new();
|
||||
|
||||
public async Task AfterResourcesCreatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var cts = CancellationTokenSource.CreateLinkedTokenSource(_shutdownCts.Token, cancellationToken);
|
||||
|
||||
var wireMockServerResources = appModel.Resources
|
||||
.OfType<WireMockServerResource>()
|
||||
.Where(resource => resource.Arguments.ApiMappingBuilder is not null)
|
||||
.ToArray();
|
||||
|
||||
if (wireMockServerResources.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var wireMockServerResource in wireMockServerResources)
|
||||
{
|
||||
wireMockServerResource.SetLogger(loggerFactory.CreateLogger<WireMockServerResource>());
|
||||
|
||||
var endpoint = wireMockServerResource.GetEndpoint();
|
||||
if (endpoint.IsAllocated)
|
||||
{
|
||||
var adminApi = CreateWireMockAdminApi(wireMockServerResource);
|
||||
await wireMockServerResource.WaitForHealthAsync(cts.Token);
|
||||
|
||||
var logger = loggerService.GetLogger(wireMockServerResource);
|
||||
logger.LogInformation("Checking Health status from WireMock.Net");
|
||||
await wireMockServerResource.CallApiMappingBuilderActionAsync(cts.Token);
|
||||
|
||||
await adminApi.WaitForHealthAsync(cancellationToken: cancellationToken);
|
||||
|
||||
logger.LogInformation("Calling ApiMappingBuilder to add mappings to WireMock.Net");
|
||||
var mappingBuilder = adminApi.GetMappingBuilder();
|
||||
await wireMockServerResource.Arguments.ApiMappingBuilder!.Invoke(mappingBuilder);
|
||||
wireMockServerResource.StartWatchingStaticMappings(cts.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IWireMockAdminApi CreateWireMockAdminApi(WireMockServerResource resource)
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
var adminApi = RestClient.For<IWireMockAdminApi>(resource.GetEndpoint().Url);
|
||||
return resource.Arguments.HasBasicAuthentication ?
|
||||
adminApi.WithAuthorization(resource.Arguments.AdminUsername!, resource.Arguments.AdminPassword!) :
|
||||
adminApi;
|
||||
await _shutdownCts.CancelAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RestEase;
|
||||
using Stef.Validation;
|
||||
using WireMock.Client;
|
||||
using WireMock.Client.Extensions;
|
||||
using WireMock.Util;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Aspire.Hosting.ApplicationModel;
|
||||
@@ -10,7 +15,13 @@ namespace Aspire.Hosting.ApplicationModel;
|
||||
/// </summary>
|
||||
public class WireMockServerResource : ContainerResource, IResourceWithServiceDiscovery
|
||||
{
|
||||
private const int EnhancedFileSystemWatcherTimeoutMs = 2000;
|
||||
|
||||
internal WireMockServerArguments Arguments { get; }
|
||||
internal Lazy<IWireMockAdminApi> AdminApi => new(CreateWireMockAdminApi);
|
||||
|
||||
private ILogger? _logger;
|
||||
private EnhancedFileSystemWatcher? _enhancedFileSystemWatcher;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WireMockServerResource"/> class.
|
||||
@@ -30,4 +41,82 @@ public class WireMockServerResource : ContainerResource, IResourceWithServiceDis
|
||||
{
|
||||
return new EndpointReference(this, "http");
|
||||
}
|
||||
|
||||
internal void SetLogger(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
internal async Task WaitForHealthAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger?.LogInformation("Checking Health status from WireMock.Net");
|
||||
await AdminApi.Value.WaitForHealthAsync(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
internal async Task CallApiMappingBuilderActionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Arguments.ApiMappingBuilder == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_logger?.LogInformation("Calling ApiMappingBuilder to add mappings to WireMock.Net");
|
||||
|
||||
var mappingBuilder = AdminApi.Value.GetMappingBuilder();
|
||||
await Arguments.ApiMappingBuilder.Invoke(mappingBuilder, cancellationToken);
|
||||
}
|
||||
|
||||
internal void StartWatchingStaticMappings(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Arguments.WatchStaticMappings || string.IsNullOrEmpty(Arguments.MappingsPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cancellationToken.Register(() =>
|
||||
{
|
||||
if (_enhancedFileSystemWatcher != null)
|
||||
{
|
||||
_enhancedFileSystemWatcher.EnableRaisingEvents = false;
|
||||
_enhancedFileSystemWatcher.Created -= FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Changed -= FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Deleted -= FileCreatedChangedOrDeleted;
|
||||
|
||||
_enhancedFileSystemWatcher.Dispose();
|
||||
_enhancedFileSystemWatcher = null;
|
||||
}
|
||||
});
|
||||
|
||||
_logger?.LogInformation("Starting to watch static mappings on path: '{Path}'. ", Arguments.MappingsPath);
|
||||
|
||||
_enhancedFileSystemWatcher = new EnhancedFileSystemWatcher(Arguments.MappingsPath, "*.json", EnhancedFileSystemWatcherTimeoutMs)
|
||||
{
|
||||
IncludeSubdirectories = true
|
||||
};
|
||||
_enhancedFileSystemWatcher.Created += FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Changed += FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Deleted += FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
private IWireMockAdminApi CreateWireMockAdminApi()
|
||||
{
|
||||
var adminApi = RestClient.For<IWireMockAdminApi>(GetEndpoint().Url);
|
||||
return Arguments.HasBasicAuthentication ?
|
||||
adminApi.WithAuthorization(Arguments.AdminUsername!, Arguments.AdminPassword!) :
|
||||
adminApi;
|
||||
}
|
||||
|
||||
private async void FileCreatedChangedOrDeleted(object sender, FileSystemEventArgs args)
|
||||
{
|
||||
_logger?.LogInformation("MappingFile created, changed or deleted: '{0}'. Triggering ReloadStaticMappings.", args.FullPath);
|
||||
try
|
||||
{
|
||||
await AdminApi.Value.ReloadStaticMappingsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogWarning(ex, "Error calling /__admin/mappings/reloadStaticMappings");
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/WireMock.Net.Aspire/doc/architecture.md
Normal file
59
src/WireMock.Net.Aspire/doc/architecture.md
Normal 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
|
||||
|
||||
|
||||
```
|
||||
@@ -1,17 +1,28 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#pragma warning disable CS1591
|
||||
using System;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Matchers;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace WireMock.FluentAssertions;
|
||||
|
||||
#pragma warning disable CS1591
|
||||
public partial class WireMockAssertions
|
||||
{
|
||||
[CustomAssertion]
|
||||
public AndWhichConstraint<WireMockAssertions, string> AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs)
|
||||
{
|
||||
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.AbsoluteUrl, absoluteUrl, StringComparison.OrdinalIgnoreCase));
|
||||
_ = AtAbsoluteUrl(new ExactMatcher(true, absoluteUrl), because, becauseArgs);
|
||||
|
||||
return new AndWhichConstraint<WireMockAssertions, string>(this, absoluteUrl);
|
||||
}
|
||||
|
||||
[CustomAssertion]
|
||||
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtAbsoluteUrl(IStringMatcher absoluteUrlMatcher, string because = "", params object[] becauseArgs)
|
||||
{
|
||||
var (filter, condition) = BuildFilterAndCondition(request => absoluteUrlMatcher.IsPerfectMatch(request.AbsoluteUrl));
|
||||
|
||||
var absoluteUrl = absoluteUrlMatcher.GetPatterns().FirstOrDefault().GetPattern();
|
||||
|
||||
Execute.Assertion
|
||||
.BecauseOf(because, becauseArgs)
|
||||
@@ -31,13 +42,23 @@ public partial class WireMockAssertions
|
||||
|
||||
FilterRequestMessages(filter);
|
||||
|
||||
return new AndWhichConstraint<WireMockAssertions, string>(this, absoluteUrl);
|
||||
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, absoluteUrlMatcher);
|
||||
}
|
||||
|
||||
[CustomAssertion]
|
||||
public AndWhichConstraint<WireMockAssertions, string> AtUrl(string url, string because = "", params object[] becauseArgs)
|
||||
{
|
||||
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.Url, url, StringComparison.OrdinalIgnoreCase));
|
||||
_ = AtUrl(new ExactMatcher(true, url), because, becauseArgs);
|
||||
|
||||
return new AndWhichConstraint<WireMockAssertions, string>(this, url);
|
||||
}
|
||||
|
||||
[CustomAssertion]
|
||||
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtUrl(IStringMatcher urlMatcher, string because = "", params object[] becauseArgs)
|
||||
{
|
||||
var (filter, condition) = BuildFilterAndCondition(request => urlMatcher.IsPerfectMatch(request.Url));
|
||||
|
||||
var url = urlMatcher.GetPatterns().FirstOrDefault().GetPattern();
|
||||
|
||||
Execute.Assertion
|
||||
.BecauseOf(because, becauseArgs)
|
||||
@@ -57,6 +78,6 @@ public partial class WireMockAssertions
|
||||
|
||||
FilterRequestMessages(filter);
|
||||
|
||||
return new AndWhichConstraint<WireMockAssertions, string>(this, url);
|
||||
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, urlMatcher);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using Stef.Validation;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -92,6 +93,17 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
|
||||
$")";
|
||||
}
|
||||
|
||||
private bool IsMatch(dynamic input, string pattern)
|
||||
{
|
||||
var isMatchWithString = input is string;
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public static class WireMockAdminApiExtensions
|
||||
|
||||
if (retries >= MaxRetries)
|
||||
{
|
||||
throw new InvalidOperationException($"The /__admin/health endpoint did not return 'Healthy' after {MaxRetries} retries and {totalWaitTime / 1000.0:0.0} seconds.");
|
||||
throw new InvalidOperationException($"The /__admin/health endpoint did not return '{HealthStatusHealthy}' after {MaxRetries} retries and {totalWaitTime / 1000.0:0.0} seconds.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,13 @@ public interface IWireMockAdminApi
|
||||
[Post("mappings/reset")]
|
||||
Task<StatusModel> ResetMappingsAsync(bool? reloadStaticMappings = false, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Reload the static mappings.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Post("mappings/reloadStaticMappings")]
|
||||
Task<StatusModel> ReloadStaticMappingsAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get a mapping based on the guid
|
||||
/// </summary>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
80
src/WireMock.Net.TUnit/TUnitWireMockLogger.cs
Normal file
80
src/WireMock.Net.TUnit/TUnitWireMockLogger.cs
Normal 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}";
|
||||
}
|
||||
}
|
||||
38
src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj
Normal file
38
src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj
Normal 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>
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using WireMock.Net.Testcontainers.Models;
|
||||
|
||||
namespace WireMock.Net.Testcontainers.Utils;
|
||||
|
||||
internal static class ContainerInfoProvider
|
||||
{
|
||||
public static readonly Dictionary<OSPlatform, ContainerInfo> Info = new()
|
||||
{
|
||||
{ OSPlatform.Linux, new ContainerInfo("sheyenrath/wiremock.net-alpine", "/app/__admin/mappings") },
|
||||
{ OSPlatform.Windows, new ContainerInfo("sheyenrath/wiremock.net-windows", @"c:\app\__admin\mappings") }
|
||||
};
|
||||
}
|
||||
31
src/WireMock.Net.Testcontainers/Utils/TestcontainersUtils.cs
Normal file
31
src/WireMock.Net.Testcontainers/Utils/TestcontainersUtils.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using DotNet.Testcontainers.Configurations;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WireMock.Net.Testcontainers.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// Some utility methods for containers.
|
||||
/// </summary>
|
||||
public static class TestcontainersUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the OS platform of the Docker image.
|
||||
/// </summary>
|
||||
public static Lazy<Task<OSPlatform>> GetImageOSAsync = new(async () =>
|
||||
{
|
||||
if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null)
|
||||
{
|
||||
throw new InvalidOperationException($"The {nameof(TestcontainersSettings.OS.DockerEndpointAuthConfig)} is null. Check if Docker is started.");
|
||||
}
|
||||
|
||||
using var dockerClientConfig = TestcontainersSettings.OS.DockerEndpointAuthConfig.GetDockerClientConfiguration();
|
||||
using var dockerClient = dockerClientConfig.CreateClient();
|
||||
|
||||
var version = await dockerClient.System.GetVersionAsync();
|
||||
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) >= 0 ? OSPlatform.Windows : OSPlatform.Linux;
|
||||
});
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net\Http\HttpClientFactory2.cs" Link="Http\HttpClientFactory2.cs" />
|
||||
<Compile Include="..\WireMock.Net\Util\EnhancedFileSystemWatcher.cs" Link="Utils\EnhancedFileSystemWatcher.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -28,7 +29,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>
|
||||
|
||||
@@ -16,6 +16,12 @@ public sealed class WireMockConfiguration : ContainerConfiguration
|
||||
|
||||
public string? Password { get; }
|
||||
|
||||
public string? StaticMappingsPath { get; private set; }
|
||||
|
||||
public bool WatchStaticMappings { get; private set; }
|
||||
|
||||
public bool WatchStaticMappingsInSubdirectories { get; private set; }
|
||||
|
||||
public bool HasBasicAuthentication => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
|
||||
|
||||
public WireMockConfiguration(string? username = null, string? password = null)
|
||||
@@ -61,5 +67,31 @@ 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);
|
||||
WatchStaticMappings = BuildConfiguration.Combine(oldValue.WatchStaticMappings, newValue.WatchStaticMappings);
|
||||
WatchStaticMappingsInSubdirectories = BuildConfiguration.Combine(oldValue.WatchStaticMappingsInSubdirectories, newValue.WatchStaticMappingsInSubdirectories);
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Watch the static mappings.
|
||||
/// </summary>
|
||||
/// <param name="includeSubDirectories">Also look in SubDirectories.</param>
|
||||
/// <returns><see cref="WireMockConfiguration"/></returns>
|
||||
public WireMockConfiguration WithWatchStaticMappings(bool includeSubDirectories)
|
||||
{
|
||||
WatchStaticMappings = true;
|
||||
WatchStaticMappingsInSubdirectories = includeSubDirectories;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DotNet.Testcontainers.Configurations;
|
||||
using DotNet.Testcontainers.Containers;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RestEase;
|
||||
using Stef.Validation;
|
||||
using WireMock.Client;
|
||||
using WireMock.Client.Extensions;
|
||||
using WireMock.Http;
|
||||
using WireMock.Net.Testcontainers.Utils;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Net.Testcontainers;
|
||||
|
||||
@@ -17,17 +23,23 @@ namespace WireMock.Net.Testcontainers;
|
||||
/// </summary>
|
||||
public sealed class WireMockContainer : DockerContainer
|
||||
{
|
||||
private const int EnhancedFileSystemWatcherTimeoutMs = 2000;
|
||||
internal const int ContainerPort = 80;
|
||||
|
||||
private readonly WireMockConfiguration _configuration;
|
||||
|
||||
private IWireMockAdminApi? _adminApi;
|
||||
private EnhancedFileSystemWatcher? _enhancedFileSystemWatcher;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WireMockContainer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The container configuration.</param>
|
||||
public WireMockContainer(WireMockConfiguration configuration) : base(configuration)
|
||||
{
|
||||
_configuration = Guard.NotNull(configuration);
|
||||
_configuration = Stef.Validation.Guard.NotNull(configuration);
|
||||
|
||||
Started += WireMockContainer_Started;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -92,6 +104,71 @@ public sealed class WireMockContainer : DockerContainer
|
||||
return client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a test host directory or file to the container and triggers a reload of the static mappings if required.
|
||||
/// </summary>
|
||||
/// <param name="source">The source directory or file to be copied.</param>
|
||||
/// <param name="target">The target directory path to copy the files to.</param>
|
||||
/// <param name="fileMode">The POSIX file mode permission.</param>
|
||||
/// <param name="ct">Cancellation token.</param>
|
||||
/// <returns>A task that completes when the directory or file has been copied.</returns>
|
||||
public new async Task CopyAsync(string source, string target, UnixFileModes fileMode = Unix.FileMode644, CancellationToken ct = default)
|
||||
{
|
||||
await base.CopyAsync(source, target, fileMode, ct);
|
||||
|
||||
if (_configuration.WatchStaticMappings && await PathStartsWithContainerMappingsPath(target))
|
||||
{
|
||||
await ReloadStaticMappingsAsync(target, ct);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reload the static mappings.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
public async Task ReloadStaticMappingsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_adminApi == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _adminApi.ReloadStaticMappingsAsync(cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning(ex, "Error calling /__admin/mappings/reloadStaticMappings");
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override ValueTask DisposeAsyncCore()
|
||||
{
|
||||
if (_enhancedFileSystemWatcher != null)
|
||||
{
|
||||
_enhancedFileSystemWatcher.EnableRaisingEvents = false;
|
||||
_enhancedFileSystemWatcher.Created -= FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Changed -= FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Deleted -= FileCreatedChangedOrDeleted;
|
||||
|
||||
_enhancedFileSystemWatcher.Dispose();
|
||||
_enhancedFileSystemWatcher = null;
|
||||
}
|
||||
|
||||
Started -= WireMockContainer_Started;
|
||||
|
||||
return base.DisposeAsyncCore();
|
||||
}
|
||||
|
||||
private static async Task<bool> PathStartsWithContainerMappingsPath(string value)
|
||||
{
|
||||
var imageOs = await TestcontainersUtils.GetImageOSAsync.Value;
|
||||
|
||||
return value.StartsWith(ContainerInfoProvider.Info[imageOs].MappingsPath);
|
||||
}
|
||||
|
||||
private void ValidateIfRunning()
|
||||
{
|
||||
if (State != TestcontainersStates.Running)
|
||||
@@ -100,5 +177,35 @@ public sealed class WireMockContainer : DockerContainer
|
||||
}
|
||||
}
|
||||
|
||||
private void WireMockContainer_Started(object sender, EventArgs e)
|
||||
{
|
||||
_adminApi = CreateWireMockAdminClient();
|
||||
|
||||
if (!_configuration.WatchStaticMappings || string.IsNullOrEmpty(_configuration.StaticMappingsPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enhancedFileSystemWatcher = new EnhancedFileSystemWatcher(_configuration.StaticMappingsPath!, "*.json", EnhancedFileSystemWatcherTimeoutMs)
|
||||
{
|
||||
IncludeSubdirectories = _configuration.WatchStaticMappingsInSubdirectories
|
||||
};
|
||||
_enhancedFileSystemWatcher.Created += FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Changed += FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.Deleted += FileCreatedChangedOrDeleted;
|
||||
_enhancedFileSystemWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
private async void FileCreatedChangedOrDeleted(object sender, FileSystemEventArgs args)
|
||||
{
|
||||
await ReloadStaticMappingsAsync(args.FullPath);
|
||||
}
|
||||
|
||||
private async Task ReloadStaticMappingsAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Logger.LogInformation("MappingFile created, changed or deleted: '{Path}'. Triggering ReloadStaticMappings.", path);
|
||||
await ReloadStaticMappingsAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private Uri GetPublicUri() => new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(ContainerPort)).Uri;
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using Docker.DotNet.Models;
|
||||
using DotNet.Testcontainers.Builders;
|
||||
using DotNet.Testcontainers.Configurations;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Net.Testcontainers.Models;
|
||||
using WireMock.Net.Testcontainers.Utils;
|
||||
|
||||
namespace WireMock.Net.Testcontainers;
|
||||
|
||||
@@ -17,27 +16,8 @@ namespace WireMock.Net.Testcontainers;
|
||||
/// </summary>
|
||||
public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContainerBuilder, WireMockContainer, WireMockConfiguration>
|
||||
{
|
||||
private readonly Dictionary<bool, 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") }
|
||||
};
|
||||
|
||||
private const string DefaultLogger = "WireMockConsoleLogger";
|
||||
|
||||
private readonly Lazy<Task<bool>> _isWindowsAsLazy = new(async () =>
|
||||
{
|
||||
if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null)
|
||||
{
|
||||
throw new InvalidOperationException($"The {nameof(TestcontainersSettings.OS.DockerEndpointAuthConfig)} is null. Check if Docker is started.");
|
||||
}
|
||||
|
||||
using var dockerClientConfig = TestcontainersSettings.OS.DockerEndpointAuthConfig.GetDockerClientConfiguration();
|
||||
using var dockerClient = dockerClientConfig.CreateClient();
|
||||
|
||||
var version = await dockerClient.System.GetVersionAsync();
|
||||
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
|
||||
});
|
||||
private OSPlatform? _imageOS;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
|
||||
@@ -48,14 +28,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 ??= TestcontainersUtils.GetImageOSAsync.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>
|
||||
@@ -106,7 +108,10 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
|
||||
[PublicAPI]
|
||||
public WireMockContainerBuilder WithWatchStaticMappings(bool includeSubDirectories)
|
||||
{
|
||||
return WithCommand("--WatchStaticMappings true").WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}");
|
||||
DockerResourceConfiguration.WithWatchStaticMappings(includeSubDirectories);
|
||||
return
|
||||
WithCommand("--WatchStaticMappings true").
|
||||
WithCommand("--WatchStaticMappingsInSubdirectories", includeSubDirectories);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,11 +125,16 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
|
||||
{
|
||||
Guard.NotNullOrEmpty(path);
|
||||
|
||||
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
|
||||
DockerResourceConfiguration.WithStaticMappingsPath(path);
|
||||
|
||||
return WithReadStaticMappings()
|
||||
.WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}")
|
||||
.WithBindMount(path, _info[isWindows].MappingsPath);
|
||||
return
|
||||
WithReadStaticMappings().
|
||||
WithCommand("--WatchStaticMappingsInSubdirectories", includeSubDirectories);
|
||||
}
|
||||
|
||||
private WireMockContainerBuilder WithCommand(string param, bool value)
|
||||
{
|
||||
return !value ? this : WithCommand($"{param} true");
|
||||
}
|
||||
|
||||
private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration)
|
||||
@@ -138,9 +148,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, ContainerInfoProvider.Info[_imageOS.Value].MappingsPath);
|
||||
}
|
||||
|
||||
builder.Validate();
|
||||
|
||||
return new WireMockContainer(builder.DockerResourceConfiguration);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -148,18 +182,11 @@ 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}")
|
||||
.WithWaitStrategy(waitForContainerOS.UntilMessageIsLogged("By Stef Heyenrath"));
|
||||
.WithWaitStrategy(waitForContainerOS.UntilMessageIsLogged("WireMock.Net server running"));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -179,4 +206,10 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
|
||||
{
|
||||
return new WireMockContainerBuilder(new WireMockConfiguration(oldValue, newValue));
|
||||
}
|
||||
|
||||
private WireMockContainerBuilder WithImage(OSPlatform os)
|
||||
{
|
||||
_imageOS = os;
|
||||
return WithImage(ContainerInfoProvider.Info[os].Image);
|
||||
}
|
||||
}
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -10,6 +10,7 @@ using Microsoft.IdentityModel.Protocols;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Stef.Validation;
|
||||
using WireMock.Constants;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
|
||||
@@ -41,7 +42,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
return EmptyArray<AnyOf<string, StringPattern>>.Value;
|
||||
}
|
||||
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
public MatchOperator MatchOperator => MatchOperator.Or;
|
||||
|
||||
public MatchResult IsMatch(string? input)
|
||||
{
|
||||
@@ -50,7 +51,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
var token = Regex.Replace(input, BearerPrefix, string.Empty, RegexOptions.IgnoreCase);
|
||||
var token = Regex.Replace(input, BearerPrefix, string.Empty, RegexOptions.IgnoreCase, WireMockConstants.DefaultRegexTimeout);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -75,5 +76,11 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
return new MatchResult(MatchScores.Mismatch, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -6,12 +6,9 @@ using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.Authentication;
|
||||
|
||||
internal class BasicAuthenticationMatcher : RegexMatcher
|
||||
internal class BasicAuthenticationMatcher(string username, string password)
|
||||
: RegexMatcher(BuildPattern(username, password))
|
||||
{
|
||||
public BasicAuthenticationMatcher(string username, string password) : base(BuildPattern(username, password))
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => nameof(BasicAuthenticationMatcher);
|
||||
|
||||
private static string BuildPattern(string username, string password)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#if NET451 || NET452 || NET46 || NET451 || NET461 || NETSTANDARD1_3 || NETSTANDARD2_0
|
||||
using System.Text.RegularExpressions;
|
||||
using WireMock.Constants;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System;
|
||||
@@ -11,7 +12,7 @@ internal static class StringExtensions
|
||||
public static string Replace(this string text, string oldValue, string newValue, StringComparison stringComparison)
|
||||
{
|
||||
var options = stringComparison == StringComparison.OrdinalIgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;
|
||||
return Regex.Replace(text, oldValue, newValue, options);
|
||||
return Regex.Replace(text, oldValue, newValue, options, WireMockConstants.DefaultRegexTimeout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,15 +1,19 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
|
||||
namespace WireMock.Constants;
|
||||
|
||||
internal static class WireMockConstants
|
||||
{
|
||||
public const int AdminPriority = int.MinValue;
|
||||
public const int MinPriority = -1_000_000;
|
||||
public const int ProxyPriority = -2_000_000;
|
||||
internal static readonly TimeSpan DefaultRegexTimeout = TimeSpan.FromSeconds(10);
|
||||
|
||||
internal const int AdminPriority = int.MinValue;
|
||||
internal const int MinPriority = -1_000_000;
|
||||
internal const int ProxyPriority = -2_000_000;
|
||||
|
||||
public const string ContentTypeJson = "application/json";
|
||||
public const string ContentTypeTextPlain = "text/plain";
|
||||
internal const string ContentTypeJson = "application/json";
|
||||
internal const string ContentTypeTextPlain = "text/plain";
|
||||
|
||||
public const string NoMatchingFound = "No matching mapping found";
|
||||
}
|
||||
internal const string NoMatchingFound = "No matching mapping found";
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -14,12 +14,12 @@ namespace WireMock.Http;
|
||||
/// </summary>
|
||||
internal static class HttpKnownHeaderNames
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.net.webheadercollection.isrestricted
|
||||
// - https://docs.microsoft.com/en-us/dotnet/api/system.net.webheadercollection.isrestricted
|
||||
// - ContentLength is allowed per #720
|
||||
private static readonly string[] RestrictedResponseHeaders =
|
||||
{
|
||||
Accept,
|
||||
Connection,
|
||||
ContentLength,
|
||||
ContentType,
|
||||
Date, // RFC1123Pattern
|
||||
Expect,
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ internal class WebhookSender
|
||||
|
||||
IBodyData? bodyData;
|
||||
IDictionary<string, WireMockList<string>>? headers;
|
||||
string webhookRequestUrl;
|
||||
string requestUrl;
|
||||
if (webhookRequest.UseTransformer == true)
|
||||
{
|
||||
ITransformer transformer;
|
||||
@@ -69,18 +69,20 @@ internal class WebhookSender
|
||||
|
||||
bodyData = transformer.TransformBody(mapping, originalRequestMessage, originalResponseMessage, webhookRequest.BodyData, webhookRequest.TransformerReplaceNodeOptions);
|
||||
headers = transformer.TransformHeaders(mapping, originalRequestMessage, originalResponseMessage, webhookRequest.Headers);
|
||||
webhookRequestUrl = transformer.TransformString(mapping, originalRequestMessage, originalResponseMessage, webhookRequest.Url);
|
||||
requestUrl = transformer.TransformString(mapping, originalRequestMessage, originalResponseMessage, webhookRequest.Url);
|
||||
|
||||
mapping.Settings.WebhookSettings?.PostTransform(mapping, requestUrl, bodyData, headers);
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyData = webhookRequest.BodyData;
|
||||
headers = webhookRequest.Headers;
|
||||
webhookRequestUrl = webhookRequest.Url;
|
||||
requestUrl = webhookRequest.Url;
|
||||
}
|
||||
|
||||
// Create RequestMessage
|
||||
var requestMessage = new RequestMessage(
|
||||
new UrlDetails(webhookRequestUrl),
|
||||
new UrlDetails(requestUrl),
|
||||
webhookRequest.Method,
|
||||
ClientIp,
|
||||
bodyData,
|
||||
@@ -91,7 +93,7 @@ internal class WebhookSender
|
||||
};
|
||||
|
||||
// Create HttpRequestMessage
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, webhookRequestUrl);
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, requestUrl);
|
||||
|
||||
// Delay (if required)
|
||||
if (TryGetDelay(webhookRequest, out var delay))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
// Copied from https://github.com/Handlebars-Net/Handlebars.Net.Helpers/blob/master/src/Handlebars.Net.Helpers.DynamicLinq
|
||||
// Copied from https://github.com/Handlebars-Net/Handlebars.Net.Helpers/blob/master/src/Handlebars.Net.Helpers.DynamicLinq which is copied from https://github.com/StefH/JsonConverter
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
@@ -14,9 +14,7 @@ namespace WireMock.Json;
|
||||
|
||||
internal static class JObjectExtensions
|
||||
{
|
||||
private class JTokenResolvers : Dictionary<JTokenType, Func<JToken, DynamicJsonClassOptions?, object?>>
|
||||
{
|
||||
}
|
||||
private class JTokenResolvers : Dictionary<JTokenType, Func<JToken, DynamicJsonClassOptions?, object?>>;
|
||||
|
||||
private static readonly JTokenResolvers Resolvers = new()
|
||||
{
|
||||
@@ -180,7 +178,7 @@ internal static class JObjectExtensions
|
||||
private static IEnumerable ConvertToTypedArray(IEnumerable<object?> src, Type newType)
|
||||
{
|
||||
var method = ConvertToTypedArrayGenericMethod.MakeGenericMethod(newType);
|
||||
return (IEnumerable)method.Invoke(null, new object[] { src })!;
|
||||
return (IEnumerable)method.Invoke(null, [src])!;
|
||||
}
|
||||
|
||||
private static readonly MethodInfo ConvertToTypedArrayGenericMethod = typeof(JObjectExtensions).GetMethod(nameof(ConvertToTypedArrayGeneric), BindingFlags.NonPublic | BindingFlags.Static)!;
|
||||
@@ -193,7 +191,7 @@ internal static class JObjectExtensions
|
||||
public static DynamicClass CreateInstance(IList<DynamicPropertyWithValue> dynamicPropertiesWithValue, bool createParameterCtor = true)
|
||||
{
|
||||
var type = DynamicClassFactory.CreateType(dynamicPropertiesWithValue.Cast<DynamicProperty>().ToArray(), createParameterCtor);
|
||||
var dynamicClass = (DynamicClass)Activator.CreateInstance(type);
|
||||
var dynamicClass = (DynamicClass)Activator.CreateInstance(type)!;
|
||||
foreach (var dynamicPropertyWithValue in dynamicPropertiesWithValue.Where(p => p.Value != null))
|
||||
{
|
||||
dynamicClass.SetDynamicPropertyValue(dynamicPropertyWithValue.Name, dynamicPropertyWithValue.Value!);
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -130,7 +130,10 @@ public class MappingBuilder : IMappingBuilder
|
||||
|
||||
private IMapping[] GetNonAdminMappings()
|
||||
{
|
||||
return _options.Mappings.Values.Where(m => !m.IsAdminInterface).OrderBy(m => m.UpdatedAt).ToArray();
|
||||
return _options.Mappings.Values
|
||||
.Where(m => !m.IsAdminInterface)
|
||||
.OrderBy(m => m.Guid)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void RegisterMapping(IMapping mapping, bool saveToFile)
|
||||
|
||||
@@ -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[]>();
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -19,7 +22,7 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
|
||||
public ContentTypeMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this([pattern], ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,7 +32,8 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour,
|
||||
[pattern], ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -50,7 +54,7 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
/// <param name="ignoreCase">IgnoreCase (default false)</param>
|
||||
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase)
|
||||
{
|
||||
_patterns = patterns;
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -72,4 +76,15 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => nameof(ContentTypeMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,9 @@ using System;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -86,8 +88,20 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "ExactMatcher";
|
||||
public string Name => nameof(ExactMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IgnoreCase { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_values)}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -72,5 +72,11 @@ public class ExactObjectMatcher : IObjectMatcher
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "ExactObjectMatcher";
|
||||
public string Name => nameof(ExactObjectMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return "NotImplemented";
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
@@ -163,4 +164,16 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -156,6 +156,12 @@ public class GraphQLMatcher : IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(GraphQLMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return "NotImplemented";
|
||||
}
|
||||
|
||||
private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -16,4 +16,10 @@ public interface IMatcher
|
||||
/// Gets the match behaviour.
|
||||
/// </summary>
|
||||
MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the C# code arguments.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetCSharpCodeArguments();
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -89,7 +90,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
Exception? exception = null;
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
if (input != null && input is not byte[])
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -116,7 +117,18 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "JsonPathMatcher";
|
||||
public string Name => nameof(JsonPathMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
|
||||
$")";
|
||||
}
|
||||
|
||||
private double IsMatch(JToken jToken)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -115,4 +116,15 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(JmesPathMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Util;
|
||||
using JsonUtils = WireMock.Util.JsonUtils;
|
||||
|
||||
@@ -98,6 +99,18 @@ public class JsonMatcher : IJsonMatcher
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
|
||||
$")";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the input against the matcher value
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
@@ -34,4 +37,16 @@ public class JsonPartialMatcher : AbstractJsonPartialMatcher
|
||||
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, MatchOperator.Or, value);
|
||||
return exactStringMatcher.IsMatch(input).IsPerfect();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
@@ -34,4 +37,16 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
|
||||
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
|
||||
return wildcardStringMatcher.IsMatch(input).IsPerfect();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Json;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -136,4 +137,15 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(LinqMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
20
src/WireMock.Net/Matchers/MatcherExtensions.cs
Normal file
20
src/WireMock.Net/Matchers/MatcherExtensions.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// Provides some extension methods for matchers.
|
||||
/// </summary>
|
||||
public static class MatcherExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if the match result is a perfect match.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The string matcher.</param>
|
||||
/// <param name="input">The input string to match.</param>
|
||||
/// <returns><c>true</c>> if the match is perfect; otherwise, <c>false</c>>.</returns>
|
||||
public static bool IsPerfectMatch(this IStringMatcher matcher, string? input)
|
||||
{
|
||||
return matcher.IsMatch(input).IsPerfect();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#if MIMEKIT
|
||||
using System;
|
||||
using MimeKit;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Helpers;
|
||||
using WireMock.Models;
|
||||
@@ -60,13 +61,13 @@ public class MimePartMatcher : IMatcher
|
||||
ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
|
||||
ContentMatcher = contentMatcher;
|
||||
|
||||
_funcs = new[]
|
||||
{
|
||||
_funcs =
|
||||
[
|
||||
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
|
||||
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
|
||||
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect,
|
||||
MatchOnContent
|
||||
};
|
||||
];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -94,6 +95,12 @@ public class MimePartMatcher : IMatcher
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return "NotImplemented";
|
||||
}
|
||||
|
||||
private MatchResult MatchOnContent(MimePart mimePart)
|
||||
{
|
||||
if (ContentMatcher == null)
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -70,5 +72,14 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
public MatchOperator MatchOperator => MatchOperator.Or;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -89,6 +90,12 @@ public class ProtoBufMatcher : IProtoBufMatcher
|
||||
return DecodeAsync(input, false, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return "NotImplemented";
|
||||
}
|
||||
|
||||
private async Task<object?> DecodeAsync(byte[]? input, bool throwException, CancellationToken cancellationToken)
|
||||
{
|
||||
if (input == null)
|
||||
@@ -96,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
|
||||
{
|
||||
|
||||
@@ -5,10 +5,12 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Constants;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.RegularExpressions;
|
||||
using Stef.Validation;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -21,6 +23,7 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
private readonly Regex[] _expressions;
|
||||
private readonly bool _useRegexExtended;
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
@@ -37,7 +40,7 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
bool ignoreCase = false,
|
||||
bool useRegexExtended = true,
|
||||
MatchOperator matchOperator = MatchOperator.Or) :
|
||||
this(MatchBehaviour.AcceptOnMatch, new[] { pattern }, ignoreCase, useRegexExtended, matchOperator)
|
||||
this(MatchBehaviour.AcceptOnMatch, [pattern], ignoreCase, useRegexExtended, matchOperator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -55,7 +58,7 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
bool ignoreCase = false,
|
||||
bool useRegexExtended = true,
|
||||
MatchOperator matchOperator = MatchOperator.Or) :
|
||||
this(matchBehaviour, new[] { pattern }, ignoreCase, useRegexExtended, matchOperator)
|
||||
this(matchBehaviour, [pattern], ignoreCase, useRegexExtended, matchOperator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,17 +79,18 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
_patterns = Guard.NotNull(patterns);
|
||||
IgnoreCase = ignoreCase;
|
||||
_useRegexExtended = useRegexExtended;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
MatchOperator = matchOperator;
|
||||
|
||||
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline;
|
||||
var options = RegexOptions.Compiled | RegexOptions.Multiline;
|
||||
|
||||
if (ignoreCase)
|
||||
{
|
||||
options |= RegexOptions.IgnoreCase;
|
||||
}
|
||||
|
||||
_expressions = patterns.Select(p => useRegexExtended ? new RegexExtended(p.GetPattern(), options) : new Regex(p.GetPattern(), options)).ToArray();
|
||||
_expressions = patterns.Select(p => useRegexExtended ? new RegexExtended(p.GetPattern(), options) : new Regex(p.GetPattern(), options, WireMockConstants.DefaultRegexTimeout)).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -125,4 +129,16 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(_useRegexExtended)}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user