mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-11-13 12:23:42 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
567f94d70d | ||
|
|
22576eb539 | ||
|
|
384c083a78 | ||
|
|
920b5b48f2 | ||
|
|
b7a02e2971 | ||
|
|
dbf90c6888 | ||
|
|
6ae65ba73e | ||
|
|
2760ecbe00 | ||
|
|
f594a7cb19 | ||
|
|
30cf82fd8d | ||
|
|
3630093d49 | ||
|
|
f0965e5650 | ||
|
|
69ea61e42c | ||
|
|
bc65bccce5 | ||
|
|
f6dc299ecb | ||
|
|
dc14136492 | ||
|
|
c94824bd64 | ||
|
|
54e16fc045 | ||
|
|
7d0de75ab1 | ||
|
|
afb01a0fa6 | ||
|
|
0132ec873a | ||
|
|
64734c4f92 | ||
|
|
a5589e1e2f | ||
|
|
cb4503b1a6 | ||
|
|
dd762f218b | ||
|
|
b0f9924933 |
No files matched your search
@@ -6,7 +6,7 @@ applyTo: '**/*.csproj, **/*.cs'
|
||||
# Multi .NET Framework Targeting
|
||||
|
||||
## Instructions
|
||||
- The main project "WireMock.Net.Minimal" targets `netstandard2.0` and `net8.0`. Ensure that any new code or dependencies are compatible with these frameworks.
|
||||
- The main project "WireMock.Net.Minimal" targets `netstandard2.0`, `net8.0` and `net10.0`. Ensure that any new code or dependencies are compatible with these frameworks.
|
||||
|
||||
|
||||
# C# Guidelines
|
||||
|
||||
@@ -4,6 +4,7 @@ permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- "*.*.*"
|
||||
@@ -13,9 +14,50 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||
|
||||
- name: Setup .NET 8 and 10
|
||||
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
|
||||
with:
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
10.0.x
|
||||
|
||||
- name: Publish Standalone Binaries
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ./artifacts
|
||||
RIDS=("win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
|
||||
|
||||
for RID in "${RIDS[@]}"; do
|
||||
echo "Publishing for $RID..."
|
||||
dotnet publish ./src/dotnet-WireMock.Net/dotnet-WireMock.csproj \
|
||||
-c Release \
|
||||
-r "$RID" \
|
||||
--self-contained true \
|
||||
-p:PublishSingleFile=true \
|
||||
-p:IncludeNativeLibrariesForSelfExtract=true \
|
||||
-p:PublishDocumentationFile=false \
|
||||
-p:DebugType=None \
|
||||
-p:DebugSymbols=false \
|
||||
-o "./publish/$RID"
|
||||
|
||||
if [[ "$RID" == win-* ]]; then
|
||||
(cd "./publish/$RID" && zip "../../artifacts/wiremock-net-$RID.zip" dotnet-WireMock.exe)
|
||||
else
|
||||
tar -czvf "./artifacts/wiremock-net-$RID.tar.gz" -C "./publish/$RID" dotnet-WireMock
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Upload Standalone Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wiremock-standalone
|
||||
path: ./artifacts/*
|
||||
|
||||
- name: Release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
generate_release_notes: true
|
||||
generate_release_notes: true
|
||||
files: ./artifacts/*
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||
|
||||
- name: Build projects
|
||||
shell: pwsh
|
||||
|
||||
+139
-26
@@ -8,6 +8,9 @@ on:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
windows-build-and-run:
|
||||
name: Run Tests on Windows
|
||||
@@ -17,24 +20,35 @@ jobs:
|
||||
IsRunningOnGitHubActions: 'true'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||
|
||||
- name: Setup .NET 8
|
||||
uses: actions/setup-dotnet@v4
|
||||
- name: Setup .NET 8 and 10
|
||||
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
10.0.x
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests'
|
||||
run: dotnet test --project './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release
|
||||
# - name: 'WireMock.Net.TUnitTests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Tests'
|
||||
run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
- name: 'WireMock.Net.TUnitTests (net10.0)'
|
||||
run: dotnet test --project './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net10.0
|
||||
|
||||
- name: 'WireMock.Net.Tests.UsingNuGet'
|
||||
run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
|
||||
# - name: 'WireMock.Net.Tests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Middleware.Tests'
|
||||
run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release
|
||||
- name: 'WireMock.Net.Tests (net10.0)'
|
||||
run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net10.0
|
||||
|
||||
# - name: 'WireMock.Net.Tests.UsingNuGet'
|
||||
# run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
|
||||
|
||||
# - name: 'WireMock.Net.Middleware.Tests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Middleware.Tests (net10.0)'
|
||||
run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net10.0
|
||||
|
||||
linux-build-and-run:
|
||||
name: Run Tests on Linux
|
||||
@@ -44,24 +58,123 @@ jobs:
|
||||
IsRunningOnGitHubActions: 'true'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||
|
||||
- name: Setup .NET 8
|
||||
uses: actions/setup-dotnet@v4
|
||||
- name: Setup .NET 8 and 10
|
||||
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
10.0.x
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests'
|
||||
run: dotnet test --project './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release
|
||||
- name: Setup Java 17
|
||||
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '17'
|
||||
|
||||
- name: 'WireMock.Net.Tests'
|
||||
run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
- name: Install .NET coverage and SonarScanner tools
|
||||
run: |
|
||||
dotnet tool install --global dotnet-sonarscanner
|
||||
dotnet tool install --global dotnet-coverage
|
||||
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
|
||||
|
||||
- name: 'WireMock.Net.Tests.UsingNuGet'
|
||||
run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
|
||||
- name: Begin analysis on SonarCloud
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_BRANCH: ${{ github.head_ref }}
|
||||
PR_BASE: ${{ github.base_ref }}
|
||||
run: |
|
||||
sonar_args=(
|
||||
/k:"wiremock_WireMock.Net"
|
||||
/o:"wiremock"
|
||||
/d:sonar.host.url="https://sonarcloud.io"
|
||||
/d:sonar.token="$SONAR_TOKEN"
|
||||
/d:sonar.cs.vscoveragexml.reportsPaths="**/wiremock-coverage-*.xml"
|
||||
/d:sonar.verbose=true
|
||||
)
|
||||
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
||||
sonar_args+=(
|
||||
/d:sonar.pullrequest.provider=github
|
||||
/d:sonar.pullrequest.key="$PR_NUMBER"
|
||||
/d:sonar.pullrequest.branch="$PR_BRANCH"
|
||||
/d:sonar.pullrequest.base="$PR_BASE"
|
||||
)
|
||||
else
|
||||
sonar_args+=(/d:sonar.branch.name="$GITHUB_REF_NAME")
|
||||
fi
|
||||
dotnet sonarscanner begin "${sonar_args[@]}"
|
||||
|
||||
- name: Build test projects for coverage
|
||||
run: |
|
||||
dotnet build ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Release --framework net10.0
|
||||
dotnet build ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Release --framework net10.0
|
||||
dotnet build ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Release --framework net10.0
|
||||
dotnet build ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Release --framework net10.0
|
||||
|
||||
# - name: 'WireMock.Net.TUnitTests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests (net10.0) with coverage'
|
||||
run: dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Release --no-build --framework net10.0" -f xml -o "wiremock-coverage-tunit.xml"
|
||||
|
||||
# - name: 'WireMock.Net.Tests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Tests (net10.0) with coverage'
|
||||
run: dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Release --no-build --framework net10.0" -f xml -o "wiremock-coverage-xunit.xml"
|
||||
|
||||
- name: 'WireMock.Net.Tests.UsingNuGet (net8.0)'
|
||||
run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release --framework net8.0
|
||||
|
||||
# - name: 'WireMock.Net.Tests.UsingNuGet (net10.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release --framework net10.0
|
||||
|
||||
- name: 'WireMock.Net.Middleware.Tests'
|
||||
run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release
|
||||
# - name: 'WireMock.Net.Middleware.Tests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Aspire.Tests'
|
||||
run: dotnet test --project './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release
|
||||
- name: 'WireMock.Net.Middleware.Tests (net10.0) with coverage'
|
||||
run: dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Release --no-build --framework net10.0" -f xml -o "wiremock-coverage-middleware.xml"
|
||||
|
||||
# - name: 'WireMock.Net.Aspire.Tests (net8.0)'
|
||||
# run: dotnet test --project './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Aspire.Tests (net10.0) with coverage'
|
||||
run: dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Release --no-build --framework net10.0" -f xml -o "wiremock-coverage-aspire.xml"
|
||||
|
||||
- name: Merge coverage files
|
||||
run: dotnet coverage merge **/wiremock-coverage-*.xml --output ./test/wiremock-coverage.xml --output-format xml
|
||||
|
||||
- name: End analysis on SonarCloud
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"
|
||||
|
||||
- name: Upload coverage results to Codecov
|
||||
uses: codecov/codecov-action@0fb7174895f61a3b6b78fc075e0cd60383518dac # v5.5.5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./test/wiremock-coverage.xml
|
||||
|
||||
- name: 'dotnet-WireMock stops on CTRL-C'
|
||||
run: |
|
||||
set -m # job control, so the background process does not ignore SIGINT
|
||||
dotnet build ./src/dotnet-WireMock.Net/dotnet-WireMock.csproj -c Release
|
||||
dotnet ./src/dotnet-WireMock.Net/bin/Release/net10.0/dotnet-WireMock.dll --Urls http://localhost:0 > wiremock.log 2>&1 & # port 0 = OS assigns a free port
|
||||
PID=$!
|
||||
sleep 3
|
||||
grep -q 'Server listening at' wiremock.log || { cat wiremock.log; kill -9 $PID; exit 1; }
|
||||
kill -INT $PID
|
||||
for i in $(seq 1 10); do
|
||||
if ! kill -0 $PID 2>/dev/null; then
|
||||
EXIT_CODE=0
|
||||
wait $PID || EXIT_CODE=$?
|
||||
echo "dotnet-WireMock stopped (exit code $EXIT_CODE)"
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "dotnet-WireMock did not stop within 10 seconds after CTRL-C"
|
||||
kill -9 $PID
|
||||
exit 1
|
||||
+2
-2
@@ -253,7 +253,7 @@ paket-files/
|
||||
|
||||
./report/coverlet/
|
||||
/test/WireMock.Net.Tests/coverage.opencover.xml
|
||||
/test/WireMock.Net.Tests/coverage.netcoreapp3.1.opencover.xml
|
||||
/test/WireMock.Net.Tests/coverage.net8.0.opencover.xml
|
||||
|
||||
/test/WireMock.Net.Tests/coverage.*.opencover.xml
|
||||
/test/WireMock.Net.Middleware.Tests/coverage.opencover.xml
|
||||
*.received.*
|
||||
@@ -1,3 +1,34 @@
|
||||
# 2.31.0 (12 November 2026)
|
||||
- [#1538](https://github.com/wiremock/WireMock.Net/pull/1538) - Bump Microsoft.AspNetCore.WebUtilities from 2.3.0 to 2.3.14 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#1540](https://github.com/wiremock/WireMock.Net/pull/1540) - Bump Aspire from 13.6.4 to 13.6.5 [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1542](https://github.com/wiremock/WireMock.Net/pull/1542) - Upgrade dependencies [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1543](https://github.com/wiremock/WireMock.Net/pull/1543) - Use X509CertificateLoader on .NET 9+ [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1365](https://github.com/wiremock/WireMock.Net/issues/1365) - Client certificate authentication works with .NET 8 and fails with .NET 9 [bug]
|
||||
- [#1541](https://github.com/wiremock/WireMock.Net/issues/1541) - WireMock.Shared depends on Microsoft.AspNetCore.Http 2.3.9 which has a high-severity vulnerability [dependencies]
|
||||
|
||||
# 2.30.0 (07 November 2026)
|
||||
- [#1527](https://github.com/wiremock/WireMock.Net/pull/1527) - Publish standalone single-file binaries in GitHub Releases [feature] contributed by [tomas-pinto](https://github.com/tomas-pinto)
|
||||
- [#1528](https://github.com/wiremock/WireMock.Net/pull/1528) - Add .NET 10 target framework [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1530](https://github.com/wiremock/WireMock.Net/pull/1530) - Use 10.x.x NuGets for .NET 10 [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1532](https://github.com/wiremock/WireMock.Net/pull/1532) - Switch to IHost for .NET 10 + update dotnet-WireMock [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 2.21.0 (28 October 2026)
|
||||
- [#1526](https://github.com/wiremock/WireMock.Net/pull/1526) - Update Scriban to 7.5.3 [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1525](https://github.com/wiremock/WireMock.Net/issues/1525) - High security vulnerability in Scriban package [security]
|
||||
|
||||
# 2.20.0 (23 October 2026)
|
||||
- [#1516](https://github.com/wiremock/WireMock.Net/pull/1516) - Add ScribanRegistrationCallback to register custom Scriban functions [feature] contributed by [Quattordici](https://github.com/Quattordici)
|
||||
- [#1519](https://github.com/wiremock/WireMock.Net/pull/1519) - Bump MessagePack from 2.5.302 to 2.5.303 [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1521](https://github.com/wiremock/WireMock.Net/pull/1521) - Add near-miss diagnostics and request count/unmatched endpoints to the admin API [feature] contributed by [Quattordici](https://github.com/Quattordici)
|
||||
- [#1522](https://github.com/wiremock/WireMock.Net/pull/1522) - Downgrade JsonPath.Net from 3.0.2 to 2.2.0 to avoid Open Source Maintenance Fee issues [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1515](https://github.com/wiremock/WireMock.Net/issues/1515) - Allow registering custom Scriban functions (ScribanRegistrationCallback), like HandlebarsRegistrationCallback [feature]
|
||||
- [#1520](https://github.com/wiremock/WireMock.Net/issues/1520) - json-everything sub-dependency now has Open Source Maintenance Fee [dependencies]
|
||||
|
||||
# 2.19.0 (07 October 2026)
|
||||
- [#1512](https://github.com/wiremock/WireMock.Net/pull/1512) - Use IDateTimeUtils in WireMockWebSocketContext [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1514](https://github.com/wiremock/WireMock.Net/pull/1514) - Fix DateTime in Response [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1511](https://github.com/wiremock/WireMock.Net/issues/1511) - Incorrect response datetime for mapped response [bug]
|
||||
|
||||
# 2.18.0 (22 September 2026)
|
||||
- [#1510](https://github.com/wiremock/WireMock.Net/pull/1510) - WireMock.Net.OpenApiParser: fix depencency on RamlToOpenApiConverter.SourceOnly [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1508](https://github.com/wiremock/WireMock.Net/issues/1508) - Transitive Dependency Conflict with Microsoft.OpenApi in 2.16.0 [bug]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.18.0</VersionPrefix>
|
||||
<VersionPrefix>2.31.0</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
@@ -52,10 +52,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.401" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.403" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||
<ItemGroup Condition="('$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net10.0')">
|
||||
<!--<PackageReference Include="SonarAnalyzer.CSharp" Version="10.15.0.120848">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=2.18.0
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
for /f "usebackq delims=" %%v in (`powershell -NoProfile -Command "[xml]$props = Get-Content 'Directory.Build.props'; $props.Project.PropertyGroup | ForEach-Object { $_.VersionPrefix } | Where-Object { $_ } | Select-Object -First 1"`) do set version=%%v
|
||||
|
||||
if "%version%"=="" (
|
||||
echo Unable to determine VersionPrefix from Directory.Build.props.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
|
||||
if errorlevel 1 exit /b %errorlevel%
|
||||
|
||||
GitHubReleaseNotes --output PackageReleaseNotes.txt --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --template PackageReleaseNotes.template --version %version% --token %GH_TOKEN%
|
||||
GitHubReleaseNotes --output PackageReleaseNotes.txt --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --template PackageReleaseNotes.template --version %version% --token %GH_TOKEN%
|
||||
if errorlevel 1 exit /b %errorlevel%
|
||||
@@ -1,5 +1,9 @@
|
||||
# 2.18.0 (22 September 2026)
|
||||
- #1510 WireMock.Net.OpenApiParser: fix depencency on RamlToOpenApiConverter.SourceOnly [bug]
|
||||
- #1508 Transitive Dependency Conflict with Microsoft.OpenApi in 2.16.0 [bug]
|
||||
# 2.31.0 (12 November 2026)
|
||||
- #1538 Bump Microsoft.AspNetCore.WebUtilities from 2.3.0 to 2.3.14 [dependencies]
|
||||
- #1540 Bump Aspire from 13.6.4 to 13.6.5 [dependencies]
|
||||
- #1542 Upgrade dependencies [dependencies]
|
||||
- #1543 Use X509CertificateLoader on .NET 9+ [bug]
|
||||
- #1365 Client certificate authentication works with .NET 8 and fails with .NET 9 [bug]
|
||||
- #1541 WireMock.Shared depends on Microsoft.AspNetCore.Http 2.3.9 which has a high-severity vulnerability [dependencies]
|
||||
|
||||
The full release notes can be found here: https://github.com/wiremock/WireMock.Net/blob/master/CHANGELOG.md
|
||||
@@ -40,9 +40,9 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w
|
||||
| ***Quality*** | |
|
||||
| **Build Azure** | [](https://stef.visualstudio.com/WireMock.Net/_build/latest?definitionId=61) |
|
||||
| **Build GitHub** | [](https://github.com/wiremock/WireMock.Net/actions/workflows/ci.yml)
|
||||
| **Quality** | [](https://sonarcloud.io/project/issues?id=WireMock-Net_WireMock.Net) [](https://www.codefactor.io/repository/github/wiremock/wiremock.net) |
|
||||
| **SonarQube** | [](https://sonarcloud.io/project/issues?id=WireMock-Net_WireMock.Net&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=WireMock-Net_WireMock.Net&resolved=false&types=CODE_SMELL) |
|
||||
| **Coverage** | [](https://sonarcloud.io/component_measures?id=WireMock-Net_WireMock.Net&metric=coverage) [](https://codecov.io/gh/wiremock/WireMock.Net)|
|
||||
| **Quality** | [](https://sonarcloud.io/project/issues?id=wiremock_WireMock.Net) [](https://www.codefactor.io/repository/github/wiremock/wiremock.net) |
|
||||
| **SonarQube** | [](https://sonarcloud.io/project/issues?id=wiremock_WireMock.Net&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=wiremock_WireMock.Net&resolved=false&types=CODE_SMELL) |
|
||||
| **Coverage** | [](https://sonarcloud.io/component_measures?id=wiremock_WireMock.Net&metric=coverage) [](https://codecov.io/gh/wiremock/WireMock.Net)|
|
||||
| **TIOBE** | [TIOBE Quality Indicator](https://ticsdemo.tiobe.com/tiobeweb/DEMO/TqiDashboard.html#axes=Project(WireMock.Net),Sub()&metric=tqi)
|
||||
|
||||
### :package: NuGet packages
|
||||
|
||||
+16
-15
@@ -1,3 +1,4 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 18
|
||||
VisualStudioVersion = 18.0.11205.157
|
||||
@@ -73,8 +74,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Testcontainers
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TestcontainersExample", "examples\WireMock.Net.TestcontainersExample\WireMock.Net.TestcontainersExample.csproj", "{56A38798-C48B-4A4A-B805-071E05C02CE1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NET8", "examples\WireMock.Net.Console.NET8\WireMock.Net.Console.NET8.csproj", "{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{7FC0B409-2682-40EE-B3B9-3930D6769D01}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.GrpcClient", "examples\WireMock.Net.Console.GrpcClient\WireMock.Net.Console.GrpcClient.csproj", "{B1580A38-84E7-44BE-8FE7-3EE5031D74A1}"
|
||||
@@ -153,6 +152,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Matchers.Syste
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Service", "examples\WireMock.Net.Service\WireMock.Net.Service.csproj", "{7F0B2446-0363-4720-AF46-F47F83B557DC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console", "examples\WireMock.Net.Console\WireMock.Net.Console.csproj", "{1B2D0EF9-A494-400C-91CF-651249B2BA0B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -379,18 +380,6 @@ Global
|
||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7FC0B409-2682-40EE-B3B9-3930D6769D01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7FC0B409-2682-40EE-B3B9-3930D6769D01}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7FC0B409-2682-40EE-B3B9-3930D6769D01}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
@@ -847,6 +836,18 @@ Global
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -872,7 +873,6 @@ Global
|
||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{56A38798-C48B-4A4A-B805-071E05C02CE1} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{1EA72C0F-92E9-486B-8FFE-53F992BFC4AA} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{7FC0B409-2682-40EE-B3B9-3930D6769D01} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{B1580A38-84E7-44BE-8FE7-3EE5031D74A1} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{CAB42D88-B4E4-4887-B684-9F3E09D085A1} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
@@ -911,6 +911,7 @@ Global
|
||||
{F4B2B967-98D7-4D93-9A5C-5EF7B84B941A} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{1B2D0EF9-A494-400C-91CF-651249B2BA0B} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
+79
-65
@@ -1,3 +1,6 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
parameters:
|
||||
- name: runWindowsReleaseToMyGet
|
||||
displayName: Run Windows Release to MyGet
|
||||
@@ -20,6 +23,12 @@ jobs:
|
||||
echo "BuildId = $(buildId)"
|
||||
displayName: 'Print buildId'
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET 10.0
|
||||
inputs:
|
||||
packageType: 'sdk'
|
||||
version: '10.0.x'
|
||||
|
||||
- script: |
|
||||
dotnet tool install --global dotnet-sonarscanner
|
||||
dotnet tool install --global dotnet-coverage
|
||||
@@ -39,7 +48,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.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
|
||||
dotnet sonarscanner begin /k:"wiremock_WireMock.Net" /o:"wiremock" /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
|
||||
|
||||
@@ -48,30 +57,30 @@ jobs:
|
||||
inputs:
|
||||
command: 'build'
|
||||
projects: '**/test/**/*.csproj'
|
||||
arguments: '--configuration Debug --framework net8.0'
|
||||
arguments: '--configuration Debug --framework net10.0'
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-xunit.xml"
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net10.0" -f xml -o "wiremock-coverage-xunit.xml"
|
||||
displayName: 'WireMock.Net.Tests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-tunit.xml"
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build --framework net10.0" -f xml -o "wiremock-coverage-tunit.xml"
|
||||
displayName: 'WireMock.Net.TUnitTests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-middleware.xml"
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --no-build --framework net10.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 --project ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-aspire.xml"
|
||||
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build --framework net10.0" -f xml -o "wiremock-coverage-aspire.xml"
|
||||
displayName: 'WireMock.Net.Aspire.Tests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
@@ -110,77 +119,82 @@ jobs:
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET 8.0
|
||||
displayName: Use .NET 10.0
|
||||
inputs:
|
||||
packageType: 'sdk'
|
||||
version: '8.0.x'
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'WireMock.Net.Tests.UsingNuGet'
|
||||
inputs:
|
||||
script: 'dotnet test ./test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj --configuration Release'
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'WireMock.Net.Tests with Coverage'
|
||||
inputs:
|
||||
script: 'dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
version: '10.0.x'
|
||||
|
||||
# - task: CmdLine@2
|
||||
# displayName: 'WireMock.Net.TUnitTests with Coverage'
|
||||
# displayName: 'WireMock.Net.Tests.UsingNuGet'
|
||||
# inputs:
|
||||
# script: 'dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
# script: 'dotnet test ./test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj --configuration Release'
|
||||
|
||||
# - task: CmdLine@2
|
||||
# displayName: 'WireMock.Net.Tests'
|
||||
# inputs:
|
||||
# script: 'dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net8.0'
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: 'WireMock.Net.Middleware.Tests with Coverage'
|
||||
displayName: 'WireMock.Net.Tests'
|
||||
inputs:
|
||||
script: 'dotnet test ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
|
||||
script: 'dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net10.0'
|
||||
|
||||
- job: Windows_Release_to_MyGet
|
||||
dependsOn: Windows_Build_Test
|
||||
condition: and(succeeded(), ${{ parameters.runWindowsReleaseToMyGet }})
|
||||
# - task: CmdLine@2
|
||||
# displayName: 'WireMock.Net.TUnitTests'
|
||||
# inputs:
|
||||
# script: 'dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --framework net10.0'
|
||||
|
||||
pool:
|
||||
vmImage: 'windows-2025'
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
echo "BuildId = $(buildId)"
|
||||
displayName: 'Print buildId'
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET 8.0
|
||||
- task: CmdLine@2
|
||||
displayName: 'WireMock.Net.Middleware.Tests'
|
||||
inputs:
|
||||
packageType: 'sdk'
|
||||
version: '8.0.x'
|
||||
script: 'dotnet test ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --framework net10.0'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Build Release
|
||||
inputs:
|
||||
command: 'build'
|
||||
arguments: /p:Configuration=Release
|
||||
projects: $(buildProjects)
|
||||
# - job: Windows_Release_to_MyGet
|
||||
# dependsOn: Windows_Build_Test
|
||||
# condition: and(succeeded(), ${{ parameters.runWindowsReleaseToMyGet }})
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Pack
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
inputs:
|
||||
command: pack
|
||||
configuration: 'Release'
|
||||
packagesToPack: $(buildProjects)
|
||||
nobuild: true
|
||||
packDirectory: '$(Build.ArtifactStagingDirectory)/packages'
|
||||
verbosityPack: 'normal'
|
||||
# pool:
|
||||
# vmImage: 'windows-2025'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifacts
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
# steps:
|
||||
# - script: |
|
||||
# echo "BuildId = $(buildId)"
|
||||
# displayName: 'Print buildId'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Push to MyGet
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
inputs:
|
||||
command: custom
|
||||
custom: nuget
|
||||
arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg -n -s https://www.myget.org/F/wiremock-net/api/v3/index.json -k $(MyGetKey)
|
||||
# - task: UseDotNet@2
|
||||
# displayName: Use .NET 10.0
|
||||
# inputs:
|
||||
# packageType: 'sdk'
|
||||
# version: '10.0.x'
|
||||
|
||||
# - task: DotNetCoreCLI@2
|
||||
# displayName: Build Release
|
||||
# inputs:
|
||||
# command: 'build'
|
||||
# arguments: /p:Configuration=Release
|
||||
# projects: $(buildProjects)
|
||||
|
||||
# - task: DotNetCoreCLI@2
|
||||
# displayName: Pack
|
||||
# condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
# inputs:
|
||||
# command: pack
|
||||
# configuration: 'Release'
|
||||
# packagesToPack: $(buildProjects)
|
||||
# nobuild: true
|
||||
# packDirectory: '$(Build.ArtifactStagingDirectory)/packages'
|
||||
# verbosityPack: 'normal'
|
||||
|
||||
# - task: PublishBuildArtifacts@1
|
||||
# displayName: Publish Artifacts
|
||||
# condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
# inputs:
|
||||
# PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
# - task: DotNetCoreCLI@2
|
||||
# displayName: Push to MyGet
|
||||
# condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
# inputs:
|
||||
# command: custom
|
||||
# custom: nuget
|
||||
# arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg -n -s https://www.myget.org/F/wiremock-net/api/v3/index.json -k $(MyGetKey)
|
||||
@@ -18,6 +18,12 @@ steps:
|
||||
packageType: sdk
|
||||
version: 8.0.x
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET 10'
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 10.0.x
|
||||
|
||||
# Based on https://whereslou.com/2018/09/versioning-and-publishing-nuget-packages-automatically-using-azure-devops-pipelines/
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Build Release
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="13.4.0" />
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="13.6.5" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AspireUseCliBundle>true</AspireUseCliBundle>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -18,10 +19,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.4.3" />
|
||||
|
||||
<!-- CVE-2026-48109 -->
|
||||
<PackageReference Include="MessagePack" Version="2.5.302" />
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.6.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="13.4.0" />
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="13.6.5" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AspireUseCliBundle>true</AspireUseCliBundle>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -15,10 +16,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.4.3" />
|
||||
|
||||
<!-- CVE-2026-48109 -->
|
||||
<PackageReference Include="MessagePack" Version="2.5.302" />
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.6.5" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsAspireSharedProject>true</IsAspireSharedProject>
|
||||
@@ -10,8 +10,8 @@
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.4.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="10.11.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="10.11.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ApplicationIcon>../../resources/WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
<PackageReference Include="log4net" Version="3.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="log4net" Version="3.5.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.14" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ApplicationIcon>../../resources/WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
File renamed without changes.
+26
-1
@@ -3,6 +3,7 @@
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using Scriban.Runtime;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
@@ -285,11 +286,21 @@ namespace WireMock.Net.ConsoleApplication
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
StartAdminInterface = true,
|
||||
Logger = new WireMockConsoleLogger(),
|
||||
|
||||
Port = 9091
|
||||
});
|
||||
|
||||
server
|
||||
.WhenRequest(r => r
|
||||
.WithPath("/test")
|
||||
.UsingAnyMethod()
|
||||
)
|
||||
.ThenRespondWith(r => r
|
||||
.WithStatusCode(HttpStatusCode.OK)
|
||||
.WithBody("OK")
|
||||
);
|
||||
|
||||
server
|
||||
.WhenRequest(r => r
|
||||
.WithPath("/Content-Length")
|
||||
@@ -399,12 +410,26 @@ namespace WireMock.Net.ConsoleApplication
|
||||
// handlebarsContext.RegisterHelper(transformer.Name, transformer.Render); TODO
|
||||
},
|
||||
|
||||
ScribanRegistrationCallback = (scriptObject, fileSystemHandler) =>
|
||||
{
|
||||
var globals = (ScriptObject)scriptObject;
|
||||
globals.Import("greet", new Func<string, string>(name => $"Hello {name}"));
|
||||
},
|
||||
|
||||
// Uncomment below if you want to use the CustomFileSystemFileHandler
|
||||
// FileSystemHandler = new CustomFileSystemFileHandler()
|
||||
});
|
||||
System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
|
||||
|
||||
server.SetBasicAuthentication("a", "b");
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/scriban/greet").UsingGet())
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("{{ greet 'WireMock.Net' }}")
|
||||
.WithTransformer(TransformerType.Scriban)
|
||||
);
|
||||
|
||||
//server.SetAzureADAuthentication(Environment.GetEnvironmentVariable("WIREMOCK_AAD_TENANT")!, "api://e083d51a-01a6-446c-8ad5-0c5c7f002208");
|
||||
|
||||
//var http = new HttpClient();
|
||||
+1
-1
@@ -6,7 +6,7 @@ using log4net.Config;
|
||||
using log4net.Repository;
|
||||
using WireMock.Net.ConsoleApplication;
|
||||
|
||||
namespace WireMock.Net.Console.NET8;
|
||||
namespace WireMock.Net.Console;
|
||||
|
||||
static class Program
|
||||
{
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<!--<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>-->
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
<PackageReference Include="log4net" Version="3.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="log4net" Version="3.5.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.14" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+17
-15
@@ -1,22 +1,24 @@
|
||||
<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>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>-->
|
||||
<ItemGroup>
|
||||
<PackageReference Update="SonarAnalyzer.CSharp" Version="10.12.0.118525" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="SonarAnalyzer.CSharp" Version="10.12.0.118525" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WireMock.Net" Version="2.30.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WireMock.Net" Version="2.15.0" />
|
||||
</ItemGroup>
|
||||
<!-- CVE -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.14" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.3.14" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -90,8 +90,11 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Core">
|
||||
<Version>2.3.11</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities">
|
||||
<Version>2.3.14</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="WireMock.Net">
|
||||
<Version>2.12.0</Version>
|
||||
<Version>2.30.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<!--<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>-->
|
||||
<StartupObject>WireMock.Net.WebApplication.Program</StartupObject>
|
||||
<AssemblyName>WireMock.Net.WebApplication</AssemblyName>
|
||||
@@ -10,10 +10,6 @@
|
||||
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -4,7 +4,7 @@ This project demonstrates all the WebSocket capabilities of WireMock.Net.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- .NET 8.0 SDK
|
||||
- .NET 10.0 SDK
|
||||
- Optional: `wscat` for manual testing (`npm install -g wscat`)
|
||||
|
||||
## Running the Examples
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<AssemblyName>WireMock.Net.WebSocketExamples</AssemblyName>
|
||||
<RootNamespace>WireMock.Net.WebSocketExamples</RootNamespace>
|
||||
</PropertyGroup>
|
||||
@@ -12,7 +12,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.14" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
|
||||
<UserSecretsId>bb7d8355-68c4-4f81-8c2d-6cdd80cd7602</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Admin.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// NearMiss Model: a mapping which did not (fully) match a request.
|
||||
/// </summary>
|
||||
public class NearMissModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the log entry for the request. [Optional]
|
||||
/// </summary>
|
||||
public Guid? LogEntryGuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The request.
|
||||
/// </summary>
|
||||
public LogRequestModel? Request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier of the mapping.
|
||||
/// </summary>
|
||||
public Guid MappingGuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The title of the mapping.
|
||||
/// </summary>
|
||||
public string? MappingTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The request match result, containing the score per matcher.
|
||||
/// </summary>
|
||||
public LogRequestMatchModel? RequestMatchResult { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Admin.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// RequestCount Model
|
||||
/// </summary>
|
||||
public class RequestCountModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of requests which match the criteria.
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public interface IRequestMessage
|
||||
string? ProxyUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DateTime.
|
||||
/// The DateTime when this request was done.
|
||||
/// </summary>
|
||||
DateTime DateTime { get; }
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public interface IResponseMessage
|
||||
object? StatusCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DateTime.
|
||||
/// The DateTime when this response was sent.
|
||||
/// </summary>
|
||||
DateTime DateTime { get; }
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// A mapping which did not (fully) match a request, together with the match result explaining why.
|
||||
/// </summary>
|
||||
public class NearMiss
|
||||
{
|
||||
/// <summary>
|
||||
/// The request which was evaluated against the mapping.
|
||||
/// </summary>
|
||||
public required IRequestMessage RequestMessage { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier of the log entry for the request. [Optional]
|
||||
/// </summary>
|
||||
public Guid? LogEntryGuid { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier of the mapping.
|
||||
/// </summary>
|
||||
public required Guid MappingGuid { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The title of the mapping. [Optional]
|
||||
/// </summary>
|
||||
public string? MappingTitle { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The match result, containing the score per matcher.
|
||||
/// </summary>
|
||||
public required IRequestMatchResult RequestMatchResult { get; init; }
|
||||
}
|
||||
@@ -107,6 +107,39 @@ public interface IWireMockServer : IDisposable
|
||||
/// <returns>The <see cref="IReadOnlyList{ILogEntry}"/>.</returns>
|
||||
IReadOnlyList<ILogEntry> FindLogEntries(params IRequestMatcher[] matchers);
|
||||
|
||||
/// <summary>
|
||||
/// Get the log-entries for the requests which did not fully match any mapping.
|
||||
/// This includes the requests which were served by a partial match when AllowPartialMapping is enabled.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IReadOnlyList{ILogEntry}"/>.</returns>
|
||||
IReadOnlyList<ILogEntry> FindUnmatchedLogEntries();
|
||||
|
||||
/// <summary>
|
||||
/// Find the mappings which partially match the request (the near misses), ordered by best match first.
|
||||
/// Perfect matches and mappings which do not match at all are excluded.
|
||||
/// Use this to find out why a request did not match the expected mapping.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request to evaluate.</param>
|
||||
/// <param name="maxResults">The maximum number of near misses to return. Default is 3.</param>
|
||||
/// <returns>The <see cref="IReadOnlyList{NearMiss}"/>.</returns>
|
||||
IReadOnlyList<NearMiss> FindNearMisses(IRequestMessage requestMessage, int maxResults = 3);
|
||||
|
||||
/// <summary>
|
||||
/// Find the mappings which partially match the request of a log-entry (the near misses), ordered by best match first.
|
||||
/// Perfect matches and mappings which do not match at all are excluded.
|
||||
/// </summary>
|
||||
/// <param name="logEntry">The log-entry for which to evaluate the request.</param>
|
||||
/// <param name="maxResults">The maximum number of near misses to return. Default is 3.</param>
|
||||
/// <returns>The <see cref="IReadOnlyList{NearMiss}"/>.</returns>
|
||||
IReadOnlyList<NearMiss> FindNearMisses(ILogEntry logEntry, int maxResults = 3);
|
||||
|
||||
/// <summary>
|
||||
/// Find the near misses for all requests which did not fully match any mapping.
|
||||
/// </summary>
|
||||
/// <param name="maxResultsPerRequest">The maximum number of near misses to return per request. Default is 3.</param>
|
||||
/// <returns>The <see cref="IReadOnlyList{NearMiss}"/>.</returns>
|
||||
IReadOnlyList<NearMiss> FindNearMissesForUnmatchedRequests(int maxResultsPerRequest = 3);
|
||||
|
||||
/// <summary>
|
||||
/// Reads a static mapping file and adds or updates a single mapping.
|
||||
///
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<Description>Commonly used interfaces, models, enumerations and types.</Description>
|
||||
<AssemblyTitle>WireMock.Net.Abstractions</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591;8603</NoWarn>
|
||||
<AssemblyName>WireMock.Net.Abstractions</AssemblyName>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<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>
|
||||
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.AspNetCore.Middleware</AssemblyName>
|
||||
<PackageId>WireMock.Net.AspNetCore.Middleware</PackageId>
|
||||
@@ -31,7 +31,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" Condition=" '$(TargetFramework)' != 'net10.0' " />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.14" Condition=" '$(TargetFramework)' == 'net10.0' " />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Description>Aspire extension to start a WireMock.Net server to stub an api.</Description>
|
||||
<AssemblyTitle>WireMock.Net.Aspire</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.Aspire</AssemblyName>
|
||||
<PackageId>WireMock.Net.Aspire</PackageId>
|
||||
@@ -22,6 +22,7 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageIcon>WireMock.Net-LogoAspire.png</PackageIcon>
|
||||
<ApplicationIcon>../../resources/WireMock.Net-LogoAspire.ico</ApplicationIcon>
|
||||
<AspireUseCliBundle>true</AspireUseCliBundle>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -45,10 +46,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting" Version="13.4.3" />
|
||||
|
||||
<!-- CVE-2026-48109 -->
|
||||
<PackageReference Include="MessagePack" Version="2.5.302" />
|
||||
<PackageReference Include="Aspire.Hosting" Version="13.6.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AwesomeAssertions" Version="9.4.0" />
|
||||
<PackageReference Include="AwesomeAssertions" Version="9.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -71,7 +71,7 @@ This leads to more maintainable, scalable, and production-like test code.
|
||||
- Asynchronous handlers
|
||||
- Fluent, composable routing extensions
|
||||
- Easy integration with existing WireMock.Net servers
|
||||
- .NET 8+ support
|
||||
- .NET 8 and .NET 10 support
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<Description>WireMock.Net.Routing extends WireMock.Net with modern, minimal-API-style routing for .NET</Description>
|
||||
<Authors>Gennadii Saltyshchak</Authors>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>tdd;mock;http;wiremock;test;server;unittest;routing;minimalapi</PackageTags>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>GraphQL support for WireMock.Net</Description>
|
||||
<AssemblyTitle>WireMock.Net.Matchers.GraphQL</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net462;netstandard2.1;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462;netstandard2.1;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>wiremock;matchers;matcher;graphql</PackageTags>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
|
||||
+5
-4
@@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>A SystemTextJsonPathMatcher which can be used to match WireMock.Net Requests using JsonPath.Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.Matchers.SystemTextJsonPath</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>wiremock;matchers;matcher;jsonpath;systemtextjson</PackageTags>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
@@ -35,7 +35,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JsonPath.Net" Version="3.0.2" />
|
||||
<!-- Downgraded from 3.0.2 to 2.2.0 to avoid Open Source Maintenance Fee issues -->
|
||||
<PackageReference Include="JsonPath.Net" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>MultiPart Mime support for WireMock.Net using MimeKitLite</Description>
|
||||
<AssemblyTitle>WireMock.Net.MimePart</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>wiremock;matchers;matcher;mime;multipart;mimekit</PackageTags>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace WireMock.Extensions;
|
||||
|
||||
internal static class HttpContextExtensions
|
||||
{
|
||||
internal static bool TryGet<T>(this HttpContext httpContext, [NotNullWhen(true)] out T? value)
|
||||
{
|
||||
return httpContext.Items.TryGetValue(nameof(T), out value);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using WireMock.Owin;
|
||||
#if NETSTANDARD2_0
|
||||
using Enum = WireMock.Compatiblity.EnumCompat;
|
||||
#endif
|
||||
|
||||
namespace WireMock.HttpsCertificate;
|
||||
|
||||
@@ -18,32 +21,24 @@ internal static class CertificateLoader
|
||||
{
|
||||
var thumbprintOrSubjectNameOrHost = options.X509ThumbprintOrSubjectName ?? host;
|
||||
|
||||
var certStore = new X509Store((StoreName)Enum.Parse(typeof(StoreName), options.X509StoreName!), (StoreLocation)Enum.Parse(typeof(StoreLocation), options.X509StoreLocation!));
|
||||
try
|
||||
{
|
||||
certStore.Open(OpenFlags.ReadOnly);
|
||||
using var certStore = new X509Store(Enum.Parse<StoreName>(options.X509StoreName!), Enum.Parse<StoreLocation>(options.X509StoreLocation!));
|
||||
certStore.Open(OpenFlags.ReadOnly);
|
||||
|
||||
// Attempt to find by Thumbprint first
|
||||
var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjectNameOrHost, false);
|
||||
// Attempt to find by Thumbprint first
|
||||
var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjectNameOrHost, false);
|
||||
if (matchingCertificates.Count == 0)
|
||||
{
|
||||
// Fallback to SubjectName
|
||||
matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubjectNameOrHost, false);
|
||||
if (matchingCertificates.Count == 0)
|
||||
{
|
||||
// Fallback to SubjectName
|
||||
matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubjectNameOrHost, false);
|
||||
if (matchingCertificates.Count == 0)
|
||||
{
|
||||
// No certificates matched the search criteria.
|
||||
throw new FileNotFoundException($"No Certificate found with in store '{options.X509StoreName}', location '{options.X509StoreLocation}' for Thumbprint or SubjectName '{thumbprintOrSubjectNameOrHost}'.");
|
||||
}
|
||||
// No certificates matched the search criteria.
|
||||
throw new FileNotFoundException($"No Certificate found with in store '{options.X509StoreName}', location '{options.X509StoreLocation}' for Thumbprint or SubjectName '{thumbprintOrSubjectNameOrHost}'.");
|
||||
}
|
||||
}
|
||||
|
||||
// Use the first matching certificate.
|
||||
return matchingCertificates[0];
|
||||
}
|
||||
finally
|
||||
{
|
||||
certStore.Dispose();
|
||||
certStore.Close();
|
||||
}
|
||||
// Use the first matching certificate.
|
||||
return matchingCertificates[0];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(options.X509CertificateFilePath))
|
||||
@@ -55,10 +50,14 @@ internal static class CertificateLoader
|
||||
if (!string.IsNullOrEmpty(options.X509CertificatePassword))
|
||||
{
|
||||
var certPem = File.ReadAllText(options.X509CertificateFilePath);
|
||||
var cert = X509Certificate2.CreateFromPem(certPem, options.X509CertificatePassword);
|
||||
using var cert = X509Certificate2.CreateFromPem(certPem, options.X509CertificatePassword);
|
||||
const string defaultPasswordPem = "WireMock.Net";
|
||||
|
||||
#if NET9_0_OR_GREATER
|
||||
return X509CertificateLoader.LoadPkcs12(cert.Export(X509ContentType.Pfx, defaultPasswordPem), defaultPasswordPem);
|
||||
#else
|
||||
return new X509Certificate2(cert.Export(X509ContentType.Pfx, defaultPasswordPem), defaultPasswordPem);
|
||||
#endif
|
||||
}
|
||||
return X509Certificate2.CreateFromPemFile(options.X509CertificateFilePath);
|
||||
#else
|
||||
@@ -66,9 +65,29 @@ internal static class CertificateLoader
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NET9_0_OR_GREATER
|
||||
var data = File.ReadAllBytes(options.X509CertificateFilePath);
|
||||
var contentType = X509Certificate2.GetCertContentType(data);
|
||||
if (contentType == X509ContentType.Pfx)
|
||||
{
|
||||
return X509CertificateLoader.LoadPkcs12(data, string.IsNullOrEmpty(options.X509CertificatePassword) ? null : options.X509CertificatePassword);
|
||||
}
|
||||
if (contentType == X509ContentType.Cert)
|
||||
{
|
||||
return X509CertificateLoader.LoadCertificate(data);
|
||||
}
|
||||
|
||||
// The loader does not support legacy formats such as PKCS#7 and serialized certificates.
|
||||
#pragma warning disable SYSLIB0057
|
||||
return !string.IsNullOrEmpty(options.X509CertificatePassword) ?
|
||||
new X509Certificate2(data, options.X509CertificatePassword) :
|
||||
new X509Certificate2(data);
|
||||
#pragma warning restore SYSLIB0057
|
||||
#else
|
||||
return !string.IsNullOrEmpty(options.X509CertificatePassword) ?
|
||||
new X509Certificate2(options.X509CertificateFilePath, options.X509CertificatePassword) :
|
||||
new X509Certificate2(options.X509CertificateFilePath);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (options.X509Certificate != null)
|
||||
|
||||
@@ -89,6 +89,10 @@ wTM1Z+CJZG9xAcf1zAVGl4ggYyYEFGBFyJ8VBwijS2zy1qwN1WYGtcWoAgIH0A==
|
||||
public static X509Certificate2 GetX509Certificate2()
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(Data);
|
||||
#if NET9_0_OR_GREATER
|
||||
return X509CertificateLoader.LoadPkcs12(data, null);
|
||||
#else
|
||||
return new X509Certificate2(data);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ internal sealed class AdminPaths(string? adminPath) : IAdminPaths
|
||||
|
||||
public RegexMatcher RequestsGuidPathMatcher => new($@"^{PrefixRegexEscaped}\/requests\/([0-9A-Fa-f]{{8}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{12}})$");
|
||||
|
||||
public RegexMatcher RequestsGuidNearMissesPathMatcher => new($@"^{PrefixRegexEscaped}\/requests\/([0-9A-Fa-f]{{8}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{12}})\/near-misses$");
|
||||
|
||||
public RegexMatcher ScenariosNameMatcher => new($@"^{PrefixRegexEscaped}\/scenarios\/.+$");
|
||||
|
||||
public RegexMatcher ScenariosNameWithStateMatcher => new($@"^{PrefixRegexEscaped}\/scenarios\/.+\/state$");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if NET8_0
|
||||
#if NET8_0_OR_GREATER
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.Types;
|
||||
|
||||
@@ -11,6 +11,11 @@ using WireMock.Serialization;
|
||||
using WireMock.Services;
|
||||
using WireMock.Util;
|
||||
|
||||
#if NET10_0
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin;
|
||||
|
||||
internal partial class AspNetCoreSelfHost
|
||||
@@ -20,7 +25,11 @@ internal partial class AspNetCoreSelfHost
|
||||
private readonly IWireMockLogger _logger;
|
||||
private readonly HostUrlOptions _urlOptions;
|
||||
|
||||
#if NET10_0
|
||||
private Microsoft.Extensions.Hosting.IHost _host = null!;
|
||||
#else
|
||||
private IWebHost _host = null!;
|
||||
#endif
|
||||
|
||||
public bool IsStarted { get; private set; }
|
||||
|
||||
@@ -43,6 +52,36 @@ internal partial class AspNetCoreSelfHost
|
||||
|
||||
public Task StartAsync()
|
||||
{
|
||||
#if NET10_0
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
// Workaround for https://github.com/wiremock/WireMock.Net/issues/292
|
||||
// On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not
|
||||
// specified (even though we don't actually use that base path mechanism, since we have our own way of configuring
|
||||
// a filesystem handler).
|
||||
ContentRootPath = string.IsNullOrEmpty(AppContext.BaseDirectory) ? Directory.GetCurrentDirectory() : null
|
||||
});
|
||||
|
||||
builder.Configuration.Sources.Clear();
|
||||
builder.Configuration.AddEnvironmentVariables();
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddProvider(new WireMockAspNetCoreLoggerProvider(_logger));
|
||||
builder.Logging.SetMinimumLevel(LogLevel.Warning);
|
||||
builder.Services.Configure<KestrelServerOptions>(builder.Configuration.GetSection("Kestrel"));
|
||||
|
||||
// The default ConsoleLifetime cancels Ctrl+C and shuts down the host itself, which prevents the consuming application from controlling the process lifetime.
|
||||
builder.Services.AddSingleton<Microsoft.Extensions.Hosting.IHostLifetime, NoopHostLifetime>();
|
||||
ConfigureServices(builder.Services);
|
||||
builder.WebHost.ConfigureKestrel(options =>
|
||||
{
|
||||
SetKestrelOptionsLimits(options);
|
||||
SetHttpsAndUrls(options, _wireMockMiddlewareOptions, _urlOptions.GetDetails());
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
ConfigureApplication(app);
|
||||
_host = app;
|
||||
#else
|
||||
var builder = new WebHostBuilder();
|
||||
|
||||
// Workaround for https://github.com/wiremock/WireMock.Net/issues/292
|
||||
@@ -63,58 +102,71 @@ internal partial class AspNetCoreSelfHost
|
||||
logging.AddProvider(new WireMockAspNetCoreLoggerProvider(_logger));
|
||||
logging.SetMinimumLevel(LogLevel.Warning);
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton(_wireMockMiddlewareOptions);
|
||||
services.AddSingleton(_wireMockMiddlewareOptions.AdminPaths);
|
||||
services.AddSingleton<IMappingMatcher, MappingMatcher>();
|
||||
services.AddSingleton<IRandomizerDoubleBetween0And1, RandomizerDoubleBetween0And1>();
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
services.AddSingleton<IGuidUtils, GuidUtils>();
|
||||
services.AddSingleton<IDateTimeUtils, DateTimeUtils>();
|
||||
services.AddSingleton<IResponseMessageBuilder, ResponseMessageBuilder>();
|
||||
services.AddSingleton<LogEntryMapper>();
|
||||
services.AddSingleton<IWireMockMiddlewareLogger, WireMockMiddlewareLogger>();
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
AddCors(services);
|
||||
#endif
|
||||
_wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services);
|
||||
})
|
||||
.Configure(appBuilder =>
|
||||
{
|
||||
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
UseCors(appBuilder);
|
||||
|
||||
var webSocketOptions = new WebSocketOptions();
|
||||
if (_wireMockMiddlewareOptions.WebSocketSettings?.KeepAliveIntervalSeconds != null)
|
||||
{
|
||||
webSocketOptions.KeepAliveInterval = TimeSpan.FromSeconds(_wireMockMiddlewareOptions.WebSocketSettings.KeepAliveIntervalSeconds);
|
||||
}
|
||||
|
||||
appBuilder.UseWebSockets(webSocketOptions);
|
||||
#endif
|
||||
_wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
|
||||
appBuilder.UseMiddleware<WireMockMiddleware>();
|
||||
|
||||
_wireMockMiddlewareOptions.PostWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
})
|
||||
.ConfigureServices(ConfigureServices)
|
||||
.Configure(ConfigureApplication)
|
||||
.UseKestrel(options =>
|
||||
{
|
||||
SetKestrelOptionsLimits(options);
|
||||
|
||||
SetHttpsAndUrls(options, _wireMockMiddlewareOptions, _urlOptions.GetDetails());
|
||||
})
|
||||
.ConfigureKestrelServerOptions()
|
||||
.Build();
|
||||
#endif
|
||||
|
||||
return RunHost(_cts.Token);
|
||||
}
|
||||
|
||||
#if NET10_0
|
||||
private sealed class NoopHostLifetime : Microsoft.Extensions.Hosting.IHostLifetime
|
||||
{
|
||||
public Task WaitForStartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
#endif
|
||||
|
||||
private void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(_wireMockMiddlewareOptions);
|
||||
services.AddSingleton(_wireMockMiddlewareOptions.AdminPaths);
|
||||
services.AddSingleton<IMappingMatcher, MappingMatcher>();
|
||||
services.AddSingleton<IRandomizerDoubleBetween0And1, RandomizerDoubleBetween0And1>();
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
services.AddSingleton<IGuidUtils, GuidUtils>();
|
||||
services.AddSingleton<IDateTimeUtils, DateTimeUtils>();
|
||||
services.AddSingleton<IResponseMessageBuilder, ResponseMessageBuilder>();
|
||||
services.AddSingleton<LogEntryMapper>();
|
||||
services.AddSingleton<IWireMockMiddlewareLogger, WireMockMiddlewareLogger>();
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
AddCors(services);
|
||||
#endif
|
||||
_wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services);
|
||||
}
|
||||
|
||||
private void ConfigureApplication(IApplicationBuilder appBuilder)
|
||||
{
|
||||
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
UseCors(appBuilder);
|
||||
|
||||
var webSocketOptions = new WebSocketOptions();
|
||||
if (_wireMockMiddlewareOptions.WebSocketSettings?.KeepAliveIntervalSeconds != null)
|
||||
{
|
||||
webSocketOptions.KeepAliveInterval = TimeSpan.FromSeconds(_wireMockMiddlewareOptions.WebSocketSettings.KeepAliveIntervalSeconds);
|
||||
}
|
||||
|
||||
appBuilder.UseWebSockets(webSocketOptions);
|
||||
#endif
|
||||
_wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
|
||||
appBuilder.UseMiddleware<WireMockMiddleware>();
|
||||
|
||||
_wireMockMiddlewareOptions.PostWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
}
|
||||
|
||||
private Task RunHost(CancellationToken token)
|
||||
{
|
||||
try
|
||||
@@ -126,10 +178,18 @@ internal partial class AspNetCoreSelfHost
|
||||
#endif
|
||||
appLifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
#if NET10_0
|
||||
var addresses = _host.Services.GetRequiredService<Microsoft.AspNetCore.Hosting.Server.IServer>()
|
||||
.Features
|
||||
.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>()!
|
||||
.Addresses
|
||||
.ToArray();
|
||||
#else
|
||||
var addresses = _host.ServerFeatures
|
||||
.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>()!
|
||||
.Addresses
|
||||
.ToArray();
|
||||
#endif
|
||||
|
||||
if (_urlOptions.Urls == null)
|
||||
{
|
||||
@@ -169,13 +229,19 @@ internal partial class AspNetCoreSelfHost
|
||||
IsStarted = true;
|
||||
});
|
||||
|
||||
#if NET8_0
|
||||
#if NET10_0
|
||||
_logger.Info("Server using .NET 10.0");
|
||||
#elif NET8_0
|
||||
_logger.Info("Server using .NET 8.0");
|
||||
#else
|
||||
_logger.Info("Server using .NET Standard 2.0");
|
||||
#endif
|
||||
|
||||
#if NET10_0
|
||||
return Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(_host, token);
|
||||
#else
|
||||
return _host.RunAsync(token);
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,8 @@ internal interface IAdminPaths
|
||||
|
||||
RegexMatcher RequestsGuidPathMatcher { get; }
|
||||
|
||||
RegexMatcher RequestsGuidNearMissesPathMatcher { get; }
|
||||
|
||||
RegexMatcher ScenariosNameMatcher { get; }
|
||||
|
||||
RegexMatcher ScenariosNameWithStateMatcher { get; }
|
||||
|
||||
@@ -5,4 +5,6 @@ namespace WireMock.Owin;
|
||||
internal interface IMappingMatcher
|
||||
{
|
||||
(MappingMatcherResult? Match, MappingMatcherResult? Partial) FindBestMatch(RequestMessage request);
|
||||
|
||||
IReadOnlyList<MappingMatcherResult> FindNearMisses(IRequestMessage request, int maxResults);
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace WireMock.Owin.Mappers;
|
||||
/// <summary>
|
||||
/// OwinRequestMapper
|
||||
/// </summary>
|
||||
internal class OwinRequestMapper : IOwinRequestMapper
|
||||
internal class OwinRequestMapper(IDateTimeUtils dateTimeUtils) : IOwinRequestMapper
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task<RequestMessage> MapAsync(HttpContext context, IWireMockMiddlewareOptions options)
|
||||
@@ -72,7 +72,7 @@ internal class OwinRequestMapper : IOwinRequestMapper
|
||||
await request.HttpContext.Connection.GetClientCertificateAsync()
|
||||
)
|
||||
{
|
||||
DateTime = DateTime.UtcNow
|
||||
DateTime = dateTimeUtils.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,39 @@ internal class MappingMatcher(IWireMockMiddlewareOptions options, IRandomizerDou
|
||||
return (match, partialMatch);
|
||||
}
|
||||
|
||||
public IReadOnlyList<MappingMatcherResult> FindNearMisses(IRequestMessage request, int maxResults)
|
||||
{
|
||||
Guard.NotNull(request);
|
||||
|
||||
var nearMisses = new List<MappingMatcherResult>();
|
||||
|
||||
// Probability is not taken into account here: a mapping which was skipped based on probability can still be a near miss.
|
||||
foreach (var mapping in _options.Mappings.Values.Where(m => !m.IsAdminInterface && !m.IsDisabled && m.TimeSettings.IsValid()))
|
||||
{
|
||||
try
|
||||
{
|
||||
var requestMatchResult = mapping.GetRequestMatchResult(request, GetNextState(mapping));
|
||||
if (requestMatchResult.MatchDetails.All(md => md.Exception == null))
|
||||
{
|
||||
nearMisses.Add(new MappingMatcherResult(mapping, requestMatchResult));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(mapping, ex);
|
||||
}
|
||||
}
|
||||
|
||||
// A near miss is a mapping which matches the request partially: perfect matches and complete mismatches are excluded.
|
||||
return nearMisses
|
||||
.Where(nm => !nm.RequestMatchResult.IsPerfectMatch && nm.RequestMatchResult.AverageTotalScore > 0.0)
|
||||
.OrderBy(nm => nm.RequestMatchResult)
|
||||
.ThenBy(nm => nm.Mapping.Priority)
|
||||
.ThenByDescending(nm => nm.Mapping.UpdatedAt)
|
||||
.Take(maxResults)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void LogException(IMapping mapping, Exception ex)
|
||||
{
|
||||
_options.Logger.Error($"Getting a Request MatchResult for Mapping '{mapping.Guid}' failed. This mapping will not be evaluated. Exception: {ex}");
|
||||
|
||||
@@ -171,6 +171,12 @@ internal class WireMockMiddleware(
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Set the DateTime from the Response to the current DateTime
|
||||
if (response is ResponseMessage responseMessage)
|
||||
{
|
||||
responseMessage.DateTime = dateTimeUtils.UtcNow;
|
||||
}
|
||||
|
||||
logger.LogRequestAndResponse(logRequest, request, response, result.Match, result.Partial, activity);
|
||||
|
||||
try
|
||||
@@ -255,4 +261,4 @@ internal class WireMockMiddleware(
|
||||
scenario.Finished = mapping.NextState == null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,20 +73,20 @@ internal class WireMockMiddlewareLogger(
|
||||
var logEntries = options.LogEntries.ToList();
|
||||
|
||||
foreach (var logEntry in logEntries
|
||||
.OrderBy(le => le.RequestMessage?.DateTime ?? le.ResponseMessage?.DateTime)
|
||||
.OrderBy(le => le.RequestMessage?.DateTime)
|
||||
.Take(logEntries.Count - options.MaxRequestLogCount.Value))
|
||||
{
|
||||
TryRemoveLogEntry(logEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the date.
|
||||
// In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the RequestMessage date.
|
||||
if (options.RequestLogExpirationDuration is > 0)
|
||||
{
|
||||
var logEntries = options.LogEntries.ToList();
|
||||
|
||||
var checkTime = dateTimeUtils.UtcNow.AddHours(-options.RequestLogExpirationDuration.Value);
|
||||
foreach (var logEntry in logEntries.Where(le => le.RequestMessage?.DateTime < checkTime || le.ResponseMessage?.DateTime < checkTime))
|
||||
foreach (var logEntry in logEntries.Where(le => le.RequestMessage?.DateTime < checkTime))
|
||||
{
|
||||
TryRemoveLogEntry(logEntry);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public partial class Response : IResponseBuilder
|
||||
{
|
||||
var message = responseMessage ?? new ResponseMessage
|
||||
{
|
||||
DateTime = DateTime.UtcNow // We set it here to the current time.
|
||||
DateTime = DateTime.UtcNow // Initially, this is set to the current time, but will be updated to the real time once the response has been sent.
|
||||
};
|
||||
|
||||
return new Response(message);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Types;
|
||||
|
||||
@@ -67,7 +67,8 @@ internal class WebSocketResponseProvider(WebSocketBuilder builder, IGuidUtils gu
|
||||
builder,
|
||||
options,
|
||||
logger,
|
||||
guidUtils
|
||||
guidUtils,
|
||||
dateTimeUtils
|
||||
);
|
||||
|
||||
// Add to registry
|
||||
|
||||
@@ -14,60 +14,7 @@ internal class LogEntryMapper(IWireMockMiddlewareOptions options)
|
||||
{
|
||||
public LogEntryModel Map(ILogEntry logEntry)
|
||||
{
|
||||
LogRequestModel? logRequestModel = null;
|
||||
if (logEntry.RequestMessage != null)
|
||||
{
|
||||
logRequestModel = new LogRequestModel
|
||||
{
|
||||
DateTime = logEntry.RequestMessage.DateTime,
|
||||
ClientIP = logEntry.RequestMessage.ClientIP,
|
||||
Path = logEntry.RequestMessage.Path,
|
||||
AbsolutePath = logEntry.RequestMessage.AbsolutePath,
|
||||
Url = logEntry.RequestMessage.Url,
|
||||
AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
|
||||
ProxyUrl = logEntry.RequestMessage.ProxyUrl,
|
||||
Query = logEntry.RequestMessage.Query,
|
||||
Method = logEntry.RequestMessage.Method,
|
||||
HttpVersion = logEntry.RequestMessage.HttpVersion,
|
||||
Headers = logEntry.RequestMessage.Headers,
|
||||
Cookies = logEntry.RequestMessage.Cookies
|
||||
};
|
||||
|
||||
if (logEntry.RequestMessage.BodyData != null)
|
||||
{
|
||||
logRequestModel.DetectedBodyType = logEntry.RequestMessage.BodyData.DetectedBodyType?.ToString();
|
||||
logRequestModel.DetectedBodyTypeFromContentType = logEntry.RequestMessage.BodyData.DetectedBodyTypeFromContentType?.ToString();
|
||||
|
||||
switch (logEntry.RequestMessage.BodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.String:
|
||||
case BodyType.FormUrlEncoded:
|
||||
case BodyType.WebSocketText:
|
||||
case BodyType.WebSocketClose:
|
||||
logRequestModel.Body = logEntry.RequestMessage.BodyData.BodyAsString;
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
logRequestModel.Body = logEntry.RequestMessage.BodyData.BodyAsString; // In case of Json, do also save the Body as string (backwards compatible)
|
||||
logRequestModel.BodyAsJson = logEntry.RequestMessage.BodyData.BodyAsJson;
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
case BodyType.WebSocketBinary:
|
||||
logRequestModel.BodyAsBytes = logEntry.RequestMessage.BodyData.BodyAsBytes;
|
||||
break;
|
||||
}
|
||||
|
||||
logRequestModel.BodyEncoding = logEntry.RequestMessage.BodyData.Encoding != null
|
||||
? new EncodingModel
|
||||
{
|
||||
EncodingName = logEntry.RequestMessage.BodyData.Encoding.EncodingName,
|
||||
CodePage = logEntry.RequestMessage.BodyData.Encoding.CodePage,
|
||||
WebName = logEntry.RequestMessage.BodyData.Encoding.WebName
|
||||
}
|
||||
: null;
|
||||
}
|
||||
}
|
||||
var logRequestModel = logEntry.RequestMessage != null ? MapRequest(logEntry.RequestMessage) : null;
|
||||
|
||||
LogResponseModel? logResponseModel = null;
|
||||
if (logEntry.ResponseMessage != null)
|
||||
@@ -123,6 +70,74 @@ internal class LogEntryMapper(IWireMockMiddlewareOptions options)
|
||||
};
|
||||
}
|
||||
|
||||
public NearMissModel Map(NearMiss nearMiss)
|
||||
{
|
||||
return new NearMissModel
|
||||
{
|
||||
LogEntryGuid = nearMiss.LogEntryGuid,
|
||||
Request = MapRequest(nearMiss.RequestMessage),
|
||||
MappingGuid = nearMiss.MappingGuid,
|
||||
MappingTitle = nearMiss.MappingTitle,
|
||||
RequestMatchResult = Map(nearMiss.RequestMatchResult)
|
||||
};
|
||||
}
|
||||
|
||||
private static LogRequestModel MapRequest(IRequestMessage requestMessage)
|
||||
{
|
||||
var logRequestModel = new LogRequestModel
|
||||
{
|
||||
DateTime = requestMessage.DateTime,
|
||||
ClientIP = requestMessage.ClientIP,
|
||||
Path = requestMessage.Path,
|
||||
AbsolutePath = requestMessage.AbsolutePath,
|
||||
Url = requestMessage.Url,
|
||||
AbsoluteUrl = requestMessage.AbsoluteUrl,
|
||||
ProxyUrl = requestMessage.ProxyUrl,
|
||||
Query = requestMessage.Query,
|
||||
Method = requestMessage.Method,
|
||||
HttpVersion = requestMessage.HttpVersion,
|
||||
Headers = requestMessage.Headers,
|
||||
Cookies = requestMessage.Cookies
|
||||
};
|
||||
|
||||
if (requestMessage.BodyData != null)
|
||||
{
|
||||
logRequestModel.DetectedBodyType = requestMessage.BodyData.DetectedBodyType?.ToString();
|
||||
logRequestModel.DetectedBodyTypeFromContentType = requestMessage.BodyData.DetectedBodyTypeFromContentType?.ToString();
|
||||
|
||||
switch (requestMessage.BodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.String:
|
||||
case BodyType.FormUrlEncoded:
|
||||
case BodyType.WebSocketText:
|
||||
case BodyType.WebSocketClose:
|
||||
logRequestModel.Body = requestMessage.BodyData.BodyAsString;
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
logRequestModel.Body = requestMessage.BodyData.BodyAsString; // In case of Json, do also save the Body as string (backwards compatible)
|
||||
logRequestModel.BodyAsJson = requestMessage.BodyData.BodyAsJson;
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
case BodyType.WebSocketBinary:
|
||||
logRequestModel.BodyAsBytes = requestMessage.BodyData.BodyAsBytes;
|
||||
break;
|
||||
}
|
||||
|
||||
logRequestModel.BodyEncoding = requestMessage.BodyData.Encoding != null
|
||||
? new EncodingModel
|
||||
{
|
||||
EncodingName = requestMessage.BodyData.Encoding.EncodingName,
|
||||
CodePage = requestMessage.BodyData.Encoding.CodePage,
|
||||
WebName = requestMessage.BodyData.Encoding.WebName
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
return logRequestModel;
|
||||
}
|
||||
|
||||
private void MapBody(ILogEntry logEntry, LogResponseModel logResponseModel)
|
||||
{
|
||||
switch (logEntry.ResponseMessage?.BodyData?.DetectedBodyType)
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.Admin.Scenarios;
|
||||
using WireMock.Admin.Settings;
|
||||
using WireMock.Constants;
|
||||
@@ -93,6 +94,18 @@ public partial class WireMockServer
|
||||
Given(Request.Create().WithPath(_adminPaths.RequestsGuidPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestGet));
|
||||
Given(Request.Create().WithPath(_adminPaths.RequestsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestDelete));
|
||||
|
||||
// __admin/requests/{guid}/near-misses
|
||||
Given(Request.Create().WithPath(_adminPaths.RequestsGuidNearMissesPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestNearMissesGet));
|
||||
|
||||
// __admin/requests/count
|
||||
Given(Request.Create().WithPath(_adminPaths.Requests + "/count").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsCount));
|
||||
|
||||
// __admin/requests/unmatched
|
||||
Given(Request.Create().WithPath(_adminPaths.Requests + "/unmatched").UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsUnmatchedGet));
|
||||
|
||||
// __admin/requests/unmatched/near-misses
|
||||
Given(Request.Create().WithPath(_adminPaths.Requests + "/unmatched/near-misses").UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsUnmatchedNearMissesGet));
|
||||
|
||||
// __admin/requests/find
|
||||
Given(Request.Create().WithPath(_adminPaths.Requests + "/find").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsFind));
|
||||
Given(Request.Create().WithPath(_adminPaths.Requests + "/find").UsingGet().WithParam("mappingGuid", new NotNullOrEmptyMatcher())).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsFindByMappingGuid));
|
||||
@@ -641,6 +654,22 @@ public partial class WireMockServer
|
||||
|
||||
#region Requests/find
|
||||
private IResponseMessage RequestsFind(HttpContext _, IRequestMessage requestMessage)
|
||||
{
|
||||
var logEntryMapper = new LogEntryMapper(_options);
|
||||
var result = FindLogEntriesByRequestModel(requestMessage)
|
||||
.OrderBy(x => x.Value.AverageTotalScore)
|
||||
.Select(x => x.Key)
|
||||
.Select(logEntryMapper.Map);
|
||||
|
||||
return ToJson(result);
|
||||
}
|
||||
|
||||
private IResponseMessage RequestsCount(HttpContext _, IRequestMessage requestMessage)
|
||||
{
|
||||
return ToJson(new RequestCountModel { Count = FindLogEntriesByRequestModel(requestMessage).Count });
|
||||
}
|
||||
|
||||
private Dictionary<ILogEntry, RequestMatchResult> FindLogEntriesByRequestModel(IRequestMessage requestMessage)
|
||||
{
|
||||
var requestModel = DeserializeObject<RequestModel>(requestMessage);
|
||||
|
||||
@@ -656,10 +685,7 @@ public partial class WireMockServer
|
||||
}
|
||||
}
|
||||
|
||||
var logEntryMapper = new LogEntryMapper(_options);
|
||||
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(logEntryMapper.Map);
|
||||
|
||||
return ToJson(result);
|
||||
return dict;
|
||||
}
|
||||
|
||||
private IResponseMessage RequestsFindByMappingGuid(HttpContext _, IRequestMessage requestMessage)
|
||||
@@ -679,6 +705,65 @@ public partial class WireMockServer
|
||||
}
|
||||
#endregion Requests/find
|
||||
|
||||
#region Requests/unmatched
|
||||
private IResponseMessage RequestsUnmatchedGet(HttpContext _, IRequestMessage requestMessage)
|
||||
{
|
||||
var logEntryMapper = new LogEntryMapper(_options);
|
||||
var result = FindUnmatchedLogEntries().Select(logEntryMapper.Map);
|
||||
|
||||
return ToJson(result);
|
||||
}
|
||||
|
||||
private IResponseMessage RequestsUnmatchedNearMissesGet(HttpContext _, IRequestMessage requestMessage)
|
||||
{
|
||||
if (!TryGetMaxResultsFromQuery(requestMessage, out var maxResults))
|
||||
{
|
||||
return _responseMessageBuilder.Create(HttpStatusCode.BadRequest, "Query parameter 'maxResults' must be a positive integer");
|
||||
}
|
||||
|
||||
var logEntryMapper = new LogEntryMapper(_options);
|
||||
var result = FindNearMissesForUnmatchedRequests(maxResults).Select(logEntryMapper.Map);
|
||||
|
||||
return ToJson(result);
|
||||
}
|
||||
#endregion Requests/unmatched
|
||||
|
||||
#region Requests/{guid}/near-misses
|
||||
private IResponseMessage RequestNearMissesGet(HttpContext _, IRequestMessage requestMessage)
|
||||
{
|
||||
if (!TryGetMaxResultsFromQuery(requestMessage, out var maxResults))
|
||||
{
|
||||
return _responseMessageBuilder.Create(HttpStatusCode.BadRequest, "Query parameter 'maxResults' must be a positive integer");
|
||||
}
|
||||
|
||||
if (TryParseGuidFromSecondToLastSegment(requestMessage, out var guid))
|
||||
{
|
||||
var entry = LogEntries.SingleOrDefault(r => !_adminPaths!.Includes(r.RequestMessage?.Path) && r.Guid == guid);
|
||||
if (entry is not null)
|
||||
{
|
||||
var logEntryMapper = new LogEntryMapper(_options);
|
||||
var result = FindNearMisses(entry, maxResults).Select(logEntryMapper.Map);
|
||||
|
||||
return ToJson(result);
|
||||
}
|
||||
}
|
||||
|
||||
_settings.Logger.Warn("HttpStatusCode set to 404 : Request not found");
|
||||
return _responseMessageBuilder.Create(HttpStatusCode.NotFound, "Request not found");
|
||||
}
|
||||
|
||||
private static bool TryGetMaxResultsFromQuery(IRequestMessage requestMessage, out int maxResults)
|
||||
{
|
||||
maxResults = DefaultMaxNearMisses;
|
||||
if (requestMessage.Query == null || !requestMessage.Query.TryGetValue("maxResults", out var value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return int.TryParse(value.ToString(), out maxResults) && maxResults > 0;
|
||||
}
|
||||
#endregion Requests/{guid}/near-misses
|
||||
|
||||
#region Scenarios
|
||||
private IResponseMessage ScenariosGet(HttpContext _, IRequestMessage requestMessage)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,8 @@ using Stef.Validation;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Owin;
|
||||
using WireMock.Services;
|
||||
|
||||
namespace WireMock.Server;
|
||||
|
||||
@@ -57,6 +59,68 @@ public partial class WireMockServer
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<ILogEntry> FindUnmatchedLogEntries()
|
||||
{
|
||||
return LogEntries
|
||||
.Where(le => le.RequestMessage != null && !_options.AdminPaths.Includes(le.RequestMessage.Path))
|
||||
.Where(le => le.RequestMatchResult is not { IsPerfectMatch: true })
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<NearMiss> FindNearMisses(IRequestMessage requestMessage, int maxResults = DefaultMaxNearMisses)
|
||||
{
|
||||
Guard.NotNull(requestMessage);
|
||||
Guard.Condition(maxResults, m => m > 0);
|
||||
|
||||
return FindNearMisses(requestMessage, null, maxResults);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<NearMiss> FindNearMisses(ILogEntry logEntry, int maxResults = DefaultMaxNearMisses)
|
||||
{
|
||||
Guard.NotNull(logEntry);
|
||||
Guard.Condition(maxResults, m => m > 0);
|
||||
|
||||
return logEntry.RequestMessage is null ? [] : FindNearMisses(logEntry.RequestMessage, logEntry.Guid, maxResults);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<NearMiss> FindNearMissesForUnmatchedRequests(int maxResultsPerRequest = DefaultMaxNearMisses)
|
||||
{
|
||||
Guard.Condition(maxResultsPerRequest, m => m > 0);
|
||||
|
||||
return FindUnmatchedLogEntries()
|
||||
.SelectMany(le => FindNearMisses(le, maxResultsPerRequest))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private const int DefaultMaxNearMisses = 3;
|
||||
|
||||
private IMappingMatcher? _nearMissMappingMatcher;
|
||||
|
||||
private IReadOnlyList<NearMiss> FindNearMisses(IRequestMessage requestMessage, Guid? logEntryGuid, int maxResults)
|
||||
{
|
||||
_nearMissMappingMatcher ??= new MappingMatcher(_options, new RandomizerDoubleBetween0And1());
|
||||
|
||||
return _nearMissMappingMatcher
|
||||
.FindNearMisses(requestMessage, maxResults)
|
||||
.Select(nm => new NearMiss
|
||||
{
|
||||
RequestMessage = requestMessage,
|
||||
LogEntryGuid = logEntryGuid,
|
||||
MappingGuid = nm.Mapping.Guid,
|
||||
MappingTitle = nm.Mapping.Title,
|
||||
RequestMatchResult = nm.RequestMatchResult
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.ResetLogEntries" />
|
||||
[PublicAPI]
|
||||
public void ResetLogEntries()
|
||||
|
||||
@@ -421,6 +421,105 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StatusModel'
|
||||
|
||||
/__admin/requests/{guid}/near-misses:
|
||||
get:
|
||||
summary: Get the near misses (mappings which partially match) for a logged request
|
||||
parameters:
|
||||
- name: guid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- name: maxResults
|
||||
in: query
|
||||
required: false
|
||||
description: The maximum number of near misses per request (default 3).
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/NearMissModel'
|
||||
'400':
|
||||
description: Bad Request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StatusModel'
|
||||
'404':
|
||||
description: Not Found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StatusModel'
|
||||
|
||||
/__admin/requests/count:
|
||||
post:
|
||||
summary: Count logged requests matching a request filter
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RequestModel'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RequestCountModel'
|
||||
x-codegen-request-body-name: requestFilter
|
||||
|
||||
/__admin/requests/unmatched:
|
||||
get:
|
||||
summary: Get logged requests which did not fully match any mapping
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/LogEntryModel'
|
||||
|
||||
/__admin/requests/unmatched/near-misses:
|
||||
get:
|
||||
summary: Get the near misses (mappings which partially match) for each logged request which did not fully match any mapping
|
||||
parameters:
|
||||
- name: maxResults
|
||||
in: query
|
||||
required: false
|
||||
description: The maximum number of near misses per request (default 3).
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/NearMissModel'
|
||||
'400':
|
||||
description: Bad Request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StatusModel'
|
||||
|
||||
/__admin/requests/find:
|
||||
post:
|
||||
summary: Find logged requests matching a request filter
|
||||
@@ -895,6 +994,35 @@ components:
|
||||
additionalProperties: true
|
||||
description: Log Request Match Model
|
||||
|
||||
NearMissModel:
|
||||
type: object
|
||||
properties:
|
||||
LogEntryGuid:
|
||||
type: string
|
||||
description: The unique identifier of the log entry for the request.
|
||||
format: uuid
|
||||
Request:
|
||||
$ref: '#/components/schemas/LogRequestModel'
|
||||
MappingGuid:
|
||||
type: string
|
||||
description: The unique identifier of the mapping.
|
||||
format: uuid
|
||||
MappingTitle:
|
||||
type: string
|
||||
description: The title of the mapping.
|
||||
RequestMatchResult:
|
||||
$ref: '#/components/schemas/LogRequestMatchModel'
|
||||
description: Near Miss Model, a mapping which did not (fully) match a request
|
||||
|
||||
RequestCountModel:
|
||||
type: object
|
||||
properties:
|
||||
Count:
|
||||
type: integer
|
||||
description: The number of requests which match the criteria.
|
||||
format: int32
|
||||
description: Request Count Model
|
||||
|
||||
LogRequestModel:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using JetBrains.Annotations;
|
||||
using Scriban.Runtime;
|
||||
using Stef.Validation;
|
||||
using WireMock.Handlers;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="WireMockServerSettings"/>.
|
||||
/// </summary>
|
||||
public static class WireMockServerSettingsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a strongly typed Scriban registration to <see cref="WireMockServerSettings.ScribanRegistrationCallback"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Members added to the <see cref="ScriptObject"/> are available as globals in Scriban and Scriban-DotLiquid templates.
|
||||
/// When a callback is already configured, it is kept and invoked before <paramref name="registrationCallback"/>.
|
||||
/// </remarks>
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <param name="registrationCallback">The action which registers functions, objects or variables on the <see cref="ScriptObject"/>.</param>
|
||||
/// <returns>The same <see cref="WireMockServerSettings"/> instance.</returns>
|
||||
[PublicAPI]
|
||||
public static WireMockServerSettings WithScribanRegistration(this WireMockServerSettings settings, Action<ScriptObject, IFileSystemHandler> registrationCallback)
|
||||
{
|
||||
Guard.NotNull(settings);
|
||||
Guard.NotNull(registrationCallback);
|
||||
|
||||
var existingCallback = settings.ScribanRegistrationCallback;
|
||||
settings.ScribanRegistrationCallback = (scriptObject, fileSystemHandler) =>
|
||||
{
|
||||
existingCallback?.Invoke(scriptObject, fileSystemHandler);
|
||||
registrationCallback((ScriptObject)scriptObject, fileSystemHandler);
|
||||
};
|
||||
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using Scriban;
|
||||
using Scriban.Runtime;
|
||||
using Stef.Validation;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Types;
|
||||
@@ -9,21 +10,40 @@ namespace WireMock.Transformers.Scriban;
|
||||
|
||||
internal class ScribanContext : ITransformerContext
|
||||
{
|
||||
private static readonly MemberRenamerDelegate MemberRenamer = member => member.Name;
|
||||
|
||||
private readonly TransformerType _transformerType;
|
||||
private readonly ScriptObject? _customGlobals;
|
||||
|
||||
public IFileSystemHandler FileSystemHandler { get; }
|
||||
|
||||
public ScribanContext(IFileSystemHandler fileSystemHandler, TransformerType transformerType)
|
||||
public ScribanContext(IFileSystemHandler fileSystemHandler, TransformerType transformerType, ScriptObject? customGlobals = null)
|
||||
{
|
||||
FileSystemHandler = Guard.NotNull(fileSystemHandler);
|
||||
_transformerType = transformerType;
|
||||
_customGlobals = customGlobals;
|
||||
}
|
||||
|
||||
public string ParseAndRender(string text, object model)
|
||||
{
|
||||
var template = _transformerType == TransformerType.ScribanDotLiquid ? Template.ParseLiquid(text) : Template.Parse(text);
|
||||
var isLiquid = _transformerType == TransformerType.ScribanDotLiquid;
|
||||
var template = isLiquid ? Template.ParseLiquid(text) : Template.Parse(text);
|
||||
|
||||
return template.Render(model, member => member.Name);
|
||||
if (_customGlobals is null)
|
||||
{
|
||||
return template.Render(model, MemberRenamer);
|
||||
}
|
||||
|
||||
// Same as Template.Render(model, MemberRenamer), but with the custom globals pushed beneath the model so that the model takes precedence.
|
||||
var context = isLiquid ? new LiquidTemplateContext() : new TemplateContext();
|
||||
context.MemberRenamer = MemberRenamer;
|
||||
context.PushGlobal(_customGlobals);
|
||||
|
||||
var modelGlobals = new ScriptObject();
|
||||
modelGlobals.Import(model, renamer: MemberRenamer);
|
||||
context.PushGlobal(modelGlobals);
|
||||
|
||||
return template.Render(context);
|
||||
}
|
||||
|
||||
public object? ParseAndEvaluate(string text, object model)
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Types;
|
||||
using Scriban.Runtime;
|
||||
using Stef.Validation;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Transformers.Scriban;
|
||||
|
||||
internal class ScribanContextFactory : ITransformerContextFactory
|
||||
{
|
||||
private readonly IFileSystemHandler _fileSystemHandler;
|
||||
private readonly WireMockServerSettings _settings;
|
||||
private readonly TransformerType _transformerType;
|
||||
|
||||
public ScribanContextFactory(IFileSystemHandler fileSystemHandler, TransformerType transformerType)
|
||||
public ScribanContextFactory(WireMockServerSettings settings, TransformerType transformerType)
|
||||
{
|
||||
_fileSystemHandler = Guard.NotNull(fileSystemHandler);
|
||||
_settings = Guard.NotNull(settings);
|
||||
_transformerType = Guard.Condition(transformerType, t => t is TransformerType.Scriban or TransformerType.ScribanDotLiquid);
|
||||
}
|
||||
|
||||
public ITransformerContext Create()
|
||||
{
|
||||
return new ScribanContext(_fileSystemHandler, _transformerType);
|
||||
ScriptObject? customGlobals = null;
|
||||
if (_settings.ScribanRegistrationCallback is { } registrationCallback)
|
||||
{
|
||||
customGlobals = new ScriptObject();
|
||||
registrationCallback(customGlobals, _settings.FileSystemHandler);
|
||||
}
|
||||
|
||||
return new ScribanContext(_settings.FileSystemHandler, _transformerType, customGlobals);
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ internal static class TransformerFactory
|
||||
|
||||
case TransformerType.Scriban:
|
||||
case TransformerType.ScribanDotLiquid:
|
||||
var factoryDotLiquid = new ScribanContextFactory(settings.FileSystemHandler, transformerType);
|
||||
return new Transformer(settings, factoryDotLiquid);
|
||||
var factoryScriban = new ScribanContextFactory(settings, transformerType);
|
||||
return new Transformer(settings, factoryScriban);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"{nameof(TransformerType)} '{transformerType}' is not supported.");
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace WireMock.WebSockets;
|
||||
/// </summary>
|
||||
public class WireMockWebSocketContext : IWebSocketContext
|
||||
{
|
||||
private readonly IDateTimeUtils _dateTimeUtils;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid ConnectionId { get; }
|
||||
|
||||
@@ -50,7 +52,8 @@ public class WireMockWebSocketContext : IWebSocketContext
|
||||
WebSocketBuilder builder,
|
||||
IWireMockMiddlewareOptions options,
|
||||
IWireMockMiddlewareLogger logger,
|
||||
IGuidUtils guidUtils
|
||||
IGuidUtils guidUtils,
|
||||
IDateTimeUtils dateTimeUtils
|
||||
)
|
||||
{
|
||||
HttpContext = httpContext;
|
||||
@@ -61,6 +64,7 @@ public class WireMockWebSocketContext : IWebSocketContext
|
||||
Builder = builder;
|
||||
Options = options;
|
||||
Logger = logger;
|
||||
_dateTimeUtils = dateTimeUtils;
|
||||
|
||||
ConnectionId = guidUtils.NewGuid();
|
||||
}
|
||||
@@ -169,7 +173,7 @@ public class WireMockWebSocketContext : IWebSocketContext
|
||||
null
|
||||
)
|
||||
{
|
||||
DateTime = DateTime.UtcNow
|
||||
DateTime = _dateTimeUtils.UtcNow
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -179,7 +183,7 @@ public class WireMockWebSocketContext : IWebSocketContext
|
||||
{
|
||||
Method = method,
|
||||
BodyData = bodyData,
|
||||
DateTime = DateTime.UtcNow
|
||||
DateTime = _dateTimeUtils.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Minimal version from the lightweight Http Mocking Server for .NET</Description>
|
||||
<AssemblyTitle>WireMock.Net.Minimal</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.Minimal</AssemblyName>
|
||||
<PackageId>WireMock.Net.Minimal</PackageId>
|
||||
@@ -28,7 +28,7 @@
|
||||
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0' ">
|
||||
<PropertyGroup Condition="('$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net10.0')">
|
||||
<DefineConstants>$(DefineConstants);TRAILINGHEADERS</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||
<PackageReference Include="TinyMapper.Signed" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.34.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="7.2.5" />
|
||||
<PackageReference Include="Scriban.Signed" Version="7.5.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -52,7 +52,7 @@
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0'">
|
||||
<ItemGroup Condition="('$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net10.0')">
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<Description>Some extensions for NUnit</Description>
|
||||
<AssemblyTitle>WireMock.Net.NUnit</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net462;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.NUnit</AssemblyName>
|
||||
<RootNamespace>WireMock.Net.NUnit</RootNamespace>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>An OpenApi (swagger) parser to generate MappingModel or mapping.json file.</Description>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>wiremock;openapi;OAS;raml;converter;parser;openapiparser</PackageTags>
|
||||
<ProjectGuid>{E5B03EEF-822C-4295-952B-4479AD30082B}</ProjectGuid>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>OpenTelemetry exporter support for WireMock.Net</Description>
|
||||
<AssemblyTitle>WireMock.Net.OpenTelemetry</AssemblyTitle>
|
||||
<Authors>Petr Houška</Authors>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<RootNamespace>WireMock.OpenTelemetry</RootNamespace>
|
||||
<PackageTags>wiremock;opentelemetry;otel;tracing;telemetry</PackageTags>
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AwesomeAssertions" Version="9.4.0" />
|
||||
<PackageReference Include="AwesomeAssertions" Version="9.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -250,6 +250,39 @@ public interface IWireMockAdminApi
|
||||
[Get("requests/find")]
|
||||
Task<IList<LogEntryModel>> FindRequestsByMappingGuidAsync([Query] Guid mappingGuid, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Count the requests which match the criteria (<see cref="RequestModel"/>).
|
||||
/// </summary>
|
||||
/// <param name="model">The RequestModel</param>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Post("requests/count")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<RequestCountModel> CountRequestsAsync([Body] RequestModel model, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the requests which did not fully match any mapping.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Get("requests/unmatched")]
|
||||
Task<IList<LogEntryModel>> GetUnmatchedRequestsAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the near misses (the mappings which partially match) for all requests which did not fully match any mapping.
|
||||
/// </summary>
|
||||
/// <param name="maxResults">The maximum number of near misses per request. Default is 3.</param>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Get("requests/unmatched/near-misses")]
|
||||
Task<IList<NearMissModel>> GetNearMissesForUnmatchedRequestsAsync([Query] int? maxResults = null, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the near misses (the mappings which partially match) for a request.
|
||||
/// </summary>
|
||||
/// <param name="guid">The Guid of the request</param>
|
||||
/// <param name="maxResults">The maximum number of near misses. Default is 3.</param>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Get("requests/{guid}/near-misses")]
|
||||
Task<IList<NearMissModel>> GetNearMissesForRequestAsync([Path] Guid guid, [Query] int? maxResults = null, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get all scenarios
|
||||
/// </summary>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>A RestClient using RestEase to access the admin interface.</Description>
|
||||
<AssemblyTitle>WireMock.Net.RestClient</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.RestClient</AssemblyName>
|
||||
<PackageId>WireMock.Net.RestClient</PackageId>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
namespace WireMock.Compatiblity;
|
||||
|
||||
internal static class EnumCompat
|
||||
{
|
||||
public static TEnum Parse<TEnum>(string value) where TEnum : struct, Enum => (TEnum)Enum.Parse(typeof(TEnum), value);
|
||||
}
|
||||
#endif
|
||||
@@ -194,6 +194,20 @@ public class WireMockServerSettings
|
||||
[JsonIgnore]
|
||||
public Action<IHandlebars, IFileSystemHandler>? HandlebarsRegistrationCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which can be used to add additional Scriban registrations (functions, objects or variables). [Optional]
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The first argument is a <c>Scriban.Runtime.ScriptObject</c> from the <c>Scriban.Signed</c> package.
|
||||
/// It is typed as <see cref="object"/> so that this package does not depend on Scriban.
|
||||
/// Members added to it are available as globals in <see cref="TransformerType.Scriban"/> and <see cref="TransformerType.ScribanDotLiquid"/> templates.
|
||||
/// On a name clash the template model (<c>request</c>, <c>response</c>, <c>mapping</c> and <c>data</c>) takes precedence.
|
||||
/// The action is invoked each time a transformer context is created.
|
||||
/// </remarks>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<object, IFileSystemHandler>? ScribanRegistrationCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||
/// </summary>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Shared interfaces, models, enumerations and types.</Description>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>tdd;mock;http;wiremock;test;server;shared</PackageTags>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
@@ -25,11 +25,17 @@
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- CVE -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.14" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.3.14" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.9" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
||||
<PackageReference Include="AnyOf" Version="0.5.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" Condition=" '$(TargetFramework)' != 'net10.0' " />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.14" Condition=" '$(TargetFramework)' == 'net10.0' " />
|
||||
<PackageReference Include="JsonConverter.Newtonsoft.Json" Version="0.13.0" />
|
||||
<PackageReference Include="JsonConverter.System.Text.Json" Version="0.13.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard2.1;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.1;net8.0;net10.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.StandAlone</AssemblyName>
|
||||
<PackageId>WireMock.Net.StandAlone</PackageId>
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
|
||||
<!-- Enable OpenTelemetry exporter support for .NET 8+ -->
|
||||
<PropertyGroup Condition="' $(TargetFramework)' == 'net8.0' ">
|
||||
<PropertyGroup Condition="('$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net10.0')">
|
||||
<DefineConstants>$(DefineConstants);OPENTELEMETRY_SUPPORTED</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<!-- OpenTelemetry exporter for .NET 8+ -->
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||
<ItemGroup Condition="('$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net10.0')">
|
||||
<ProjectReference Include="..\WireMock.Net.OpenTelemetry\WireMock.Net.OpenTelemetry.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loaded 100 of 139 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user