Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add overloads to AtUrl and AtAbsoluteUrl which can use a IStringMatcher #1221

Merged
merged 1 commit into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading