Skip to content

Commit

Permalink
Add overloads to AtUrl and AtAbsoluteUrl which can use a IStringMatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Dec 22, 2024
1 parent deda7fb commit 609f237
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright © WireMock.Net

#pragma warning disable CS1591
using System;
using WireMock.Extensions;
using WireMock.Matchers;

// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
Expand All @@ -11,7 +12,17 @@ public partial class WireMockAssertions
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, string> AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.AbsoluteUrl, absoluteUrl, StringComparison.OrdinalIgnoreCase));
_ = AtAbsoluteUrl(new ExactMatcher(true, absoluteUrl), because, becauseArgs);

return new AndWhichConstraint<WireMockAssertions, string>(this, absoluteUrl);
}

[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtAbsoluteUrl(IStringMatcher absoluteUrlMatcher, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => absoluteUrlMatcher.IsPerfectMatch(request.AbsoluteUrl));

var absoluteUrl = absoluteUrlMatcher.GetPatterns().FirstOrDefault().GetPattern();

Execute.Assertion
.BecauseOf(because, becauseArgs)
Expand All @@ -31,13 +42,23 @@ public AndWhichConstraint<WireMockAssertions, string> AtAbsoluteUrl(string absol

FilterRequestMessages(filter);

return new AndWhichConstraint<WireMockAssertions, string>(this, absoluteUrl);
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, absoluteUrlMatcher);
}

[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, string> AtUrl(string url, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.Url, url, StringComparison.OrdinalIgnoreCase));
_ = AtUrl(new ExactMatcher(true, url), because, becauseArgs);

return new AndWhichConstraint<WireMockAssertions, string>(this, url);
}

[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtUrl(IStringMatcher urlMatcher, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => urlMatcher.IsPerfectMatch(request.Url));

var url = urlMatcher.GetPatterns().FirstOrDefault().GetPattern();

Execute.Assertion
.BecauseOf(because, becauseArgs)
Expand All @@ -57,6 +78,6 @@ public AndWhichConstraint<WireMockAssertions, string> AtUrl(string url, string b

FilterRequestMessages(filter);

return new AndWhichConstraint<WireMockAssertions, string>(this, url);
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, urlMatcher);
}
}
20 changes: 20 additions & 0 deletions src/WireMock.Net/Matchers/MatcherExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright © WireMock.Net

namespace WireMock.Matchers;

/// <summary>
/// Provides some extension methods for matchers.
/// </summary>
public static class MatcherExtensions
{
/// <summary>
/// Determines if the match result is a perfect match.
/// </summary>
/// <param name="matcher">The string matcher.</param>
/// <param name="input">The input string to match.</param>
/// <returns><c>true</c>> if the match is perfect; otherwise, <c>false</c>>.</returns>
public static bool IsPerfectMatch(this IStringMatcher matcher, string? input)

Check warning on line 16 in src/WireMock.Net/Matchers/MatcherExtensions.cs

View check run for this annotation

Codecov / codecov/patch

src/WireMock.Net/Matchers/MatcherExtensions.cs#L16

Added line #L16 was not covered by tests
{
return matcher.IsMatch(input).IsPerfect();
}
}

Check warning on line 20 in src/WireMock.Net/Matchers/MatcherExtensions.cs

View check run for this annotation

Codecov / codecov/patch

src/WireMock.Net/Matchers/MatcherExtensions.cs#L20

Added line #L20 was not covered by tests
48 changes: 38 additions & 10 deletions test/WireMock.Net.Tests/FluentAssertions/WireMockAssertionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ public async Task HaveReceivedACall_AtAbsoluteUrl_WhenACallWasMadeToAbsoluteUrl_
{
await _httpClient.GetAsync("anyurl").ConfigureAwait(false);

_server.Should()
.HaveReceivedACall()
.AtAbsoluteUrl(new WildcardMatcher($"http://localhost:{_portUsed}/any*"));
}

[Fact]
public async Task HaveReceivedACall_AtAbsoluteUrlWilcardMAtcher_WhenACallWasMadeToAbsoluteUrl_Should_BeOK()
{
await _httpClient.GetAsync("anyurl").ConfigureAwait(false);

_server.Should()
.HaveReceivedACall()
.AtAbsoluteUrl($"http://localhost:{_portUsed}/anyurl");
Expand Down Expand Up @@ -231,7 +241,7 @@ public async Task HaveReceivedACall_WithHeader_ShouldCheckAllRequests()
using var client2 = server.CreateClient(handler);

// Act 1
await client1.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
var task1 = client1.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
{
Headers =
{
Expand All @@ -240,14 +250,16 @@ await client1.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
});

// Act 2
await client2.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
var task2 = client2.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
{
Headers =
{
Authorization = new AuthenticationHeaderValue("Bearer", "validToken")
}
});

await Task.WhenAll(task1, task2);

// Assert
server.Should()
.HaveReceivedACall()
Expand All @@ -268,6 +280,16 @@ public async Task HaveReceivedACall_AtUrl_WhenACallWasMadeToUrl_Should_BeOK()
.AtUrl($"http://localhost:{_portUsed}/anyurl");
}

[Fact]
public async Task HaveReceivedACall_AtUrlWildcardMatcher_WhenACallWasMadeToUrl_Should_BeOK()
{
await _httpClient.GetAsync("anyurl").ConfigureAwait(false);

_server.Should()
.HaveReceivedACall()
.AtUrl(new WildcardMatcher($"http://localhost:{_portUsed}/AN*", true));
}

[Fact]
public void HaveReceivedACall_AtUrl_Should_ThrowWhenNoCallsWereMade()
{
Expand Down Expand Up @@ -393,11 +415,14 @@ public async Task HaveReceivedNoCalls_UsingPost_WhenACallWasNotMadeUsingPost_Sho
[Fact]
public async Task HaveReceived2Calls_UsingDelete_WhenACallWasMadeUsingDelete_Should_BeOK()
{
await _httpClient.DeleteAsync("anyurl").ConfigureAwait(false);

await _httpClient.DeleteAsync("anyurl").ConfigureAwait(false);
var tasks = new[]
{
_httpClient.DeleteAsync("anyurl"),
_httpClient.DeleteAsync("anyurl"),
_httpClient.GetAsync("anyurl")
};

await _httpClient.GetAsync("anyurl").ConfigureAwait(false);
await Task.WhenAll(tasks);

_server.Should()
.HaveReceived(2).Calls()
Expand Down Expand Up @@ -521,11 +546,14 @@ public async Task HaveReceived1Calls_AtAbsoluteUrlUsingPost_ShouldChain()
// Act
var httpClient = new HttpClient();

await httpClient.GetAsync($"{server.Url}/a");

await httpClient.PostAsync($"{server.Url}/b", new StringContent("B"));
var tasks = new[]
{
httpClient.GetAsync($"{server.Url}/a"),
httpClient.PostAsync($"{server.Url}/b", new StringContent("B")),
httpClient.PostAsync($"{server.Url}/c", new StringContent("C"))
};

await httpClient.PostAsync($"{server.Url}/c", new StringContent("C"));
await Task.WhenAll(tasks);

// Assert
server
Expand Down

0 comments on commit 609f237

Please sign in to comment.