Create WireMock.Net.MimePart project (#1300)

* Create WireMock.Net.MimePart project

* .

* REFACTOR

* ILRepack

* --

* ...

* x

* x

* .

* fix

* public class MimePartMatcher

* shared

* min

* .

* <!--<DelaySign>true</DelaySign>-->

* Update README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Stef Heyenrath
2025-05-24 12:17:42 +02:00
committed by GitHub
parent c15206ecd8
commit 96eca4262a
306 changed files with 9746 additions and 9285 deletions

View File

@@ -2,11 +2,11 @@
namespace WireMock.Net.Aspire.Tests.Facts;
public sealed class DockerIsRunningInLinuxContainerModeFact : FactAttribute
public sealed class DockerIsRunningInLinuxContainerModeFactAttribute : FactAttribute
{
private const string SkipReason = "Docker is not running in Linux container mode. Skipping test.";
public DockerIsRunningInLinuxContainerModeFact()
public DockerIsRunningInLinuxContainerModeFactAttribute()
{
if (!DockerUtils.IsDockerRunningLinuxContainerMode.Value)
{

View File

@@ -177,9 +177,9 @@ public class WireMockAssertionsTests : IDisposable
_server.Should()
.HaveReceivedACall()
.WithHeader("Accept", new[] { "application/xml", "application/json" })
.WithHeader("Accept", ["application/xml", "application/json"])
.And
.WithHeader("Accept-Language", new[] { "EN" });
.WithHeader("Accept-Language", ["EN"]);
}
[Fact]
@@ -209,7 +209,7 @@ public class WireMockAssertionsTests : IDisposable
act.Should()
.Throw<Exception>()
.WithMessage("Expected _server to have been called with Header \"Accept\" and Values {\"missing-value\"}, but didn't find it among the calls with Header(s) {{[\"Accept\"] = {\"application/xml, application/json\"}, [\"Host\"] = {\"localhost:*\"}}}.");
.WithMessage("Expected _server to have been called with Header \"Accept\" and Values {\"missing-value\"}, but didn't find it among the calls with Header(s)*");
}
[Fact]
@@ -223,11 +223,11 @@ public class WireMockAssertionsTests : IDisposable
Action act = () => _server.Should()
.HaveReceivedACall()
.WithHeader("Accept", new[] { "missing-value1", "missing-value2" });
.WithHeader("Accept", ["missing-value1", "missing-value2"]);
act.Should()
.Throw<Exception>()
.WithMessage("Expected _server to have been called with Header \"Accept\" and Values {\"missing-value1\", \"missing-value2\"}, but didn't find it among the calls with Header(s) {{[\"Accept\"] = {\"application/xml, application/json\"}, [\"Host\"] = {\"localhost:*\"}}}.");
.WithMessage("Expected _server to have been called with Header \"Accept\" and Values {\"missing-value1\", \"missing-value2\"}, but didn't find it among the calls with Header(s)*");
}
[Fact]
@@ -853,14 +853,14 @@ public class WireMockAssertionsTests : IDisposable
// Act
var httpClient = new HttpClient();
await httpClient.PostAsync($"{server.Url}/a", new ByteArrayContent(new byte[] { 5 }));
await httpClient.PostAsync($"{server.Url}/a", new ByteArrayContent([5]));
// Assert
Action act = () => server
.Should()
.HaveReceived(1)
.Calls()
.WithBodyAsBytes(new byte[] { 1 })
.WithBodyAsBytes([1])
.And
.UsingPost();
@@ -878,20 +878,20 @@ public class WireMockAssertionsTests : IDisposable
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath("/a").UsingPut().WithBody(new byte[] { 100 }))
.Given(Request.Create().WithPath("/a").UsingPut().WithBody([100]))
.RespondWith(Response.Create().WithBody("A response"));
// Act
var httpClient = new HttpClient();
await httpClient.PutAsync($"{server.Url}/a", new ByteArrayContent(new byte[] { 100 }));
await httpClient.PutAsync($"{server.Url}/a", new ByteArrayContent([100]));
// Assert
server
.Should()
.HaveReceived(1)
.Calls()
.WithBodyAsBytes(new byte[] { 100 })
.WithBodyAsBytes([100])
.And
.UsingPut();
@@ -899,7 +899,7 @@ public class WireMockAssertionsTests : IDisposable
.Should()
.HaveReceived(0)
.Calls()
.WithBodyAsBytes(new byte[0])
.WithBodyAsBytes([])
.And
.UsingPut();
@@ -907,7 +907,7 @@ public class WireMockAssertionsTests : IDisposable
.Should()
.HaveReceived(0)
.Calls()
.WithBodyAsBytes(new byte[] { 42 })
.WithBodyAsBytes([42])
.And
.UsingPut();
@@ -961,7 +961,7 @@ public class WireMockAssertionsTests : IDisposable
public async Task HaveReceivedACall_WithHeader_Should_ThrowWhenHttpMethodDoesNotMatch()
{
// Arrange
using var server = WireMockServer.Start();
var server = WireMockServer.Start();
// Act : HTTP GET
using var httpClient = new HttpClient();
@@ -969,24 +969,24 @@ public class WireMockAssertionsTests : IDisposable
// Act : HTTP POST
var request = new HttpRequestMessage(HttpMethod.Post, server.Url!);
request.Headers.Add("TestHeader", new[] { "Value", "Value2" });
request.Headers.Add("TestHeader", ["Value", "Value2"]);
await httpClient.SendAsync(request);
// Assert
server.Should().HaveReceivedACall().UsingPost().And.WithHeader("TestHeader", new[] { "Value", "Value2" });
server.Should().HaveReceivedACall().UsingPost().And.WithHeader("TestHeader", ["Value", "Value2"]);
Action act = () => server.Should().HaveReceivedACall().UsingGet().And.WithHeader("TestHeader", "Value");
act.Should()
.Throw<Exception>()
.WithMessage("Expected server to have been called with Header \"TestHeader\" and Values {\"Value\"}, but didn't find it among the calls with Header(s) {{[\"Host\"] = {\"localhost:*\"}}}.");
.WithMessage("Expected server to have been called with Header \"TestHeader\" and Values {\"Value\"}, but didn't find it among the calls with Header(s)*");
}
[Fact]
public async Task HaveReceivedACall_WithHeaderKey_Should_ThrowWhenHttpMethodDoesNotMatch()
{
// Arrange
using var server = WireMockServer.Start();
var server = WireMockServer.Start();
// Act : HTTP GET
using var httpClient = new HttpClient();
@@ -994,7 +994,7 @@ public class WireMockAssertionsTests : IDisposable
// Act : HTTP POST
var request = new HttpRequestMessage(HttpMethod.Post, server.Url!);
request.Headers.Add("TestHeader", new[] { "Value", "Value2" });
request.Headers.Add("TestHeader", ["Value", "Value2"]);
await httpClient.SendAsync(request);
@@ -1004,7 +1004,7 @@ public class WireMockAssertionsTests : IDisposable
Action act = () => server.Should().HaveReceivedACall().UsingGet().And.WitHeaderKey("TestHeader");
act.Should()
.Throw<Exception>()
.WithMessage("Expected server to have been called with Header \"TestHeader\", but didn't find it among the calls with Header(s) {{[\"Host\"] = {\"localhost:*\"}}}.");
.WithMessage("Expected server to have been called with Header \"TestHeader\", but didn't find it among the calls with Header(s)*");
}
public void Dispose()

View File

@@ -1,6 +1,5 @@
// Copyright © WireMock.Net
using System;
using FluentAssertions;
using Newtonsoft.Json.Linq;
using NFluent;
@@ -41,7 +40,7 @@ public class JmesPathMatcherTests
public void JmesPathMatcher_IsMatch_ByteArray()
{
// Assign
var bytes = EmptyArray<byte>.Value;
var bytes = new byte[0];
var matcher = new JmesPathMatcher("");
// Act

View File

@@ -101,7 +101,7 @@ public class JsonMatcherTests
public void JsonMatcher_IsMatch_ByteArray()
{
// Assign
var bytes = EmptyArray<byte>.Value;
var bytes = new byte[0];
var matcher = new JsonMatcher("");
// Act

View File

@@ -79,7 +79,7 @@ public class JsonPartialMatcherTests
public void JsonPartialMatcher_IsMatch_ByteArray()
{
// Assign
var bytes = EmptyArray<byte>.Value;
var bytes = new byte[0];
var matcher = new JsonPartialMatcher("");
// Act

View File

@@ -79,7 +79,7 @@ public class JsonPartialWildcardMatcherTests
public void JsonPartialWildcardMatcher_IsMatch_ByteArray()
{
// Assign
var bytes = EmptyArray<byte>.Value;
var bytes = new byte[0];
var matcher = new JsonPartialWildcardMatcher("");
// Act

View File

@@ -41,7 +41,7 @@ public class JsonPathMatcherTests
public void JsonPathMatcher_IsMatch_ByteArray()
{
// Arrange
var bytes = EmptyArray<byte>.Value;
var bytes = new byte[0];
var matcher = new JsonPathMatcher("");
// Act

View File

@@ -2,9 +2,7 @@
#if MIMEKIT
using System;
using System.Linq;
using FluentAssertions;
using MimeKit;
using WireMock.Matchers;
using WireMock.Util;
using Xunit;
@@ -13,40 +11,44 @@ namespace WireMock.Net.Tests.Matchers;
public class MimePartMatcherTests
{
private const string TestMultiPart = @"From:
Date: Sun, 23 Jul 2023 16:13:13 +0200
Subject:
Message-Id: <HZ3K1HEAJKU4.IO57XCVO4BWV@desktop-6dd5qi2>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=""=-5XgmpXt0XOfzdtcgNJc2ZQ==""
private static readonly IMimeKitUtils MimeKitUtils = new MimeKitUtils();
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/plain; charset=utf-8
private const string TestMultiPart =
"""
From:
Date: Sun, 23 Jul 2023 16:13:13 +0200
Subject:
Message-Id: <HZ3K1HEAJKU4.IO57XCVO4BWV@desktop-6dd5qi2>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-5XgmpXt0XOfzdtcgNJc2ZQ=="
This is some plain text
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/json; charset=utf-8
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/plain; charset=utf-8
{
""Key"": ""Value""
}
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: image/png; name=image.png
Content-Disposition: attachment; filename=image.png
Content-Transfer-Encoding: base64
This is some plain text
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/json; charset=utf-8
iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjl
AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
{
"Key": "Value"
}
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: image/png; name=image.png
Content-Disposition: attachment; filename=image.png
Content-Transfer-Encoding: base64
--=-5XgmpXt0XOfzdtcgNJc2ZQ==--
";
iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjl
AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
--=-5XgmpXt0XOfzdtcgNJc2ZQ==--
""";
[Fact]
public void MimePartMatcher_IsMatch_Part_TextPlain()
{
// Arrange
var message = MimeMessage.Load(StreamUtils.CreateStream(TestMultiPart));
var part = (MimePart)message.BodyParts.ToArray()[0];
var message = MimeKitUtils.LoadFromStream(StreamUtils.CreateStream(TestMultiPart));
var part = MimeKitUtils.GetBodyParts(message)[0];
// Act
var contentTypeMatcher = new ContentTypeMatcher("text/plain");
@@ -64,8 +66,8 @@ AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
public void MimePartMatcher_IsMatch_Part_TextJson()
{
// Arrange
var message = MimeMessage.Load(StreamUtils.CreateStream(TestMultiPart));
var part = (MimePart)message.BodyParts.ToArray()[1];
var message = MimeKitUtils.LoadFromStream(StreamUtils.CreateStream(TestMultiPart));
var part = MimeKitUtils.GetBodyParts(message)[1];
// Act
var contentTypeMatcher = new ContentTypeMatcher("text/json");
@@ -82,8 +84,8 @@ AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
public void MimePartMatcher_IsMatch_Part_ImagePng()
{
// Arrange
var message = MimeMessage.Load(StreamUtils.CreateStream(TestMultiPart));
var part = (MimePart)message.BodyParts.ToArray()[2];
var message = MimeKitUtils.LoadFromStream(StreamUtils.CreateStream(TestMultiPart));
var part = MimeKitUtils.GetBodyParts(message)[2];
// Act
var contentTypeMatcher = new ContentTypeMatcher("image/png");

View File

@@ -17,11 +17,11 @@ using WireMock.Owin;
#if NET452
using Microsoft.Owin;
using IResponse = Microsoft.Owin.IOwinResponse;
using Response = Microsoft.Owin.OwinResponse;
// using Response = Microsoft.Owin.OwinResponse;
#else
using Microsoft.AspNetCore.Http;
using IResponse = Microsoft.AspNetCore.Http.HttpResponse;
using Response = Microsoft.AspNetCore.Http.HttpResponse;
// using Response = Microsoft.AspNetCore.Http.HttpResponse;
using Microsoft.Extensions.Primitives;
#endif
@@ -273,7 +273,7 @@ public class OwinResponseMapperTests
await _sut.MapAsync(responseMessage, _responseMock.Object).ConfigureAwait(false);
// Assert
_stream.Verify(s => s.WriteAsync(EmptyArray<byte>.Value, 0, 0, It.IsAny<CancellationToken>()), Times.Once);
_stream.Verify(s => s.WriteAsync(new byte[0], 0, 0, It.IsAny<CancellationToken>()), Times.Once);
}
[Theory]

View File

@@ -164,12 +164,12 @@ AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
var headers = new Dictionary<string, string[]>
{
{ "Content-Type", new[] { @"multipart/mixed; boundary=""=-5XgmpXt0XOfzdtcgNJc2ZQ==""" } }
{ "Content-Type", [ @"multipart/mixed; boundary=""=-5XgmpXt0XOfzdtcgNJc2ZQ==""" ] }
};
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body, headers);
var matchers = new IMatcher?[] { matcher1, matcher2, matcher3 }
.Where(m => m is not null)
.ToArray();
var matchers = new[] { matcher1, matcher2, matcher3 }
.OfType<IMatcher>()
.ToArray();
var matcher = new RequestMessageMultiPartMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, matchers!);

View File

@@ -24,42 +24,103 @@ public class TypeLoaderTests
{
}
public interface IDummyInterfaceWithImplementationUsedForStaticTest
{
}
public class DummyClass1UsedForStaticTest : IDummyInterfaceWithImplementationUsedForStaticTest
{
public DummyClass1UsedForStaticTest(Counter counter)
{
counter.AddOne();
}
}
public class DummyClass2UsedForStaticTest : IDummyInterfaceWithImplementationUsedForStaticTest
{
public DummyClass2UsedForStaticTest(Counter counter)
{
counter.AddOne();
}
}
public class Counter
{
public int Value { get; private set; }
public void AddOne()
{
Value++;
}
}
[Fact]
public void Load_ByInterface()
public void LoadNewInstance()
{
// Act
AnyOf<string, StringPattern> pattern = "x";
var result = TypeLoader.Load<ICSharpCodeMatcher>(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, pattern);
var result = TypeLoader.LoadNewInstance<ICSharpCodeMatcher>(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, pattern);
// Assert
result.Should().NotBeNull();
}
[Fact]
public void Load_ByInterfaceAndFullName()
public void LoadNewInstanceByFullName()
{
// Act
var result = TypeLoader.LoadByFullName<IDummyInterfaceWithImplementation>(typeof(DummyClass).FullName!);
var result = TypeLoader.LoadNewInstanceByFullName<IDummyInterfaceWithImplementation>(typeof(DummyClass).FullName!);
// Assert
result.Should().BeOfType<DummyClass>();
}
[Fact]
public void Load_ByInterface_ButNoImplementationFoundForInterface_ThrowsException()
public void LoadStaticInstance_ShouldOnlyCreateInstanceOnce()
{
// Arrange
var counter = new Counter();
// Act
var result = TypeLoader.LoadStaticInstance<IDummyInterfaceWithImplementationUsedForStaticTest>(counter);
TypeLoader.LoadStaticInstance<IDummyInterfaceWithImplementationUsedForStaticTest>(counter);
// Assert
result.Should().BeOfType<DummyClass1UsedForStaticTest>();
counter.Value.Should().Be(1);
}
[Fact]
public void LoadStaticInstanceByFullName_ShouldOnlyCreateInstanceOnce()
{
// Arrange
var counter = new Counter();
var fullName = typeof(DummyClass2UsedForStaticTest).FullName!;
// Act
var result = TypeLoader.LoadStaticInstanceByFullName<IDummyInterfaceWithImplementationUsedForStaticTest>(fullName, counter);
TypeLoader.LoadStaticInstanceByFullName<IDummyInterfaceWithImplementationUsedForStaticTest>(fullName, counter);
// Assert
result.Should().BeOfType<DummyClass2UsedForStaticTest>();
counter.Value.Should().Be(1);
}
[Fact]
public void LoadNewInstance_ButNoImplementationFoundForInterface_ThrowsException()
{
// Act
Action a = () => TypeLoader.Load<IDummyInterfaceNoImplementation>();
Action a = () => TypeLoader.LoadNewInstance<IDummyInterfaceNoImplementation>();
// Assert
a.Should().Throw<DllNotFoundException>().WithMessage("No dll found which implements Interface 'WireMock.Net.Tests.Util.TypeLoaderTests+IDummyInterfaceNoImplementation'.");
}
[Fact]
public void Load_ByInterfaceAndFullName_ButNoImplementationFoundForInterface_ThrowsException()
public void LoadNewInstanceByFullName_ButNoImplementationFoundForInterface_ThrowsException()
{
// Act
Action a = () => TypeLoader.LoadByFullName<IDummyInterfaceWithImplementation>("xyz");
Action a = () => TypeLoader.LoadNewInstanceByFullName<IDummyInterfaceWithImplementation>("xyz");
// Assert
a.Should().Throw<DllNotFoundException>().WithMessage("No dll found which implements Interface 'WireMock.Net.Tests.Util.TypeLoaderTests+IDummyInterfaceWithImplementation' and has FullName 'xyz'.");

View File

@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net461;netcoreapp3.1;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net452;net461;net6.0;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<DebugType>full</DebugType>
@@ -51,7 +51,6 @@
</ItemGroup>-->
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.FluentAssertions\WireMock.Net.FluentAssertions.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.Matchers.CSharpCode\WireMock.Net.Matchers.CSharpCode.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj" />
@@ -73,7 +72,6 @@
</PackageReference>
<PackageReference Include="Moq" Version="4.17.2" />
<PackageReference Include="System.Threading" Version="4.3.0" />
<PackageReference Include="RestEase" Version="1.6.4" />
<PackageReference Include="NFluent" Version="2.8.0" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="AnyOf" Version="0.4.0" />