Skip to content

Commit

Permalink
refactor: replaced RequestUriMatcher with UriMatcher. Additionally, a…
Browse files Browse the repository at this point in the history
…dded option to disable wildcards on request URI matching.
  • Loading branch information
skwasjer committed Sep 7, 2024
1 parent 7c211f8 commit c5ca29c
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 227 deletions.
27 changes: 24 additions & 3 deletions src/MockHttp/Extensions/RequestMatchingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Text;
using MockHttp.Http;
using MockHttp.Matchers;
using MockHttp.Matchers.Patterns;
using static MockHttp.Http.UriExtensions;

namespace MockHttp;

Expand All @@ -14,13 +16,30 @@ namespace MockHttp;
/// </summary>
public static class RequestMatchingExtensions
{
private static bool ContainsWildcard(this string value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}

#if NETSTANDARD2_0 || NETFRAMEWORK
return value.Contains("*");
#else
return value.Contains('*', StringComparison.InvariantCultureIgnoreCase);
#endif
}

/// <summary>
/// Matches a request by specified <paramref name="requestUri" />.
/// </summary>
/// <param name="builder">The request matching builder instance.</param>
/// <param name="requestUri">The request URI or a URI wildcard.</param>
/// <param name="allowWildcards"><see langword="true" /> to allow wildcards, or <see langword="false" /> if exact matching.</param>
/// <returns>The request matching builder instance.</returns>
public static RequestMatching RequestUri(this RequestMatching builder, string requestUri)
#pragma warning disable CA1054
public static RequestMatching RequestUri(this RequestMatching builder, string requestUri, bool allowWildcards = true)
#pragma warning restore CA1054
{
if (builder is null)
{
Expand All @@ -32,7 +51,9 @@ public static RequestMatching RequestUri(this RequestMatching builder, string re
throw new ArgumentNullException(nameof(requestUri));
}

return builder.With(new RequestUriMatcher(requestUri, true));
return allowWildcards && requestUri.ContainsWildcard()
? builder.With(new UriMatcher(new UriStringPatternMatcher(uri => uri.ToString(), new WildcardPatternMatcher(requestUri)), requestUri))
: builder.RequestUri(new Uri(requestUri, DotNetRelativeOrAbsolute));
}

/// <summary>
Expand All @@ -53,7 +74,7 @@ public static RequestMatching RequestUri(this RequestMatching builder, Uri reque
throw new ArgumentNullException(nameof(requestUri));
}

return builder.With(new RequestUriMatcher(requestUri));
return builder.With(new UriMatcher(new RelativeOrAbsoluteUriPatternMatcher(requestUri), requestUri.ToString()));
}

/// <summary>
Expand Down
97 changes: 0 additions & 97 deletions src/MockHttp/Matchers/RequestUriMatcher.cs

This file was deleted.

182 changes: 168 additions & 14 deletions test/MockHttp.Tests/Extensions/RequestMatchingExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Collections.Specialized;
using System;
using System.Collections.Specialized;
using System.Linq.Expressions;
using System.Net.Http.Headers;
using System.Text;
using System.Xml;
using MockHttp.Http;
using MockHttp.Matchers;
using MockHttp.Responses;
using static MockHttp.Http.UriExtensions;

namespace MockHttp.Extensions;

Expand All @@ -20,33 +22,184 @@ protected RequestMatchingExtensionsTests()

public class RequestUri : RequestMatchingExtensionsTests
{
[Fact]
public async Task When_configuring_requestUri_as_string_should_match()
[Theory]
[InlineData("relative.htm", true, "http://127.0.0.1/relative.htm", true)]
[InlineData("relative.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("relative.htm", false, "http://127.0.0.1/relative.htm", true)]
[InlineData("relative.htm", false, "http://127.0.0.1/relative.htm?query=string", false)]

[InlineData("/relative.htm", true, "http://127.0.0.1/relative.htm", true)]
[InlineData("/relative.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("/relative.htm", false, "http://127.0.0.1/relative.htm", true)]
[InlineData("/relative.htm", false, "http://127.0.0.1/relative.htm?query=string", false)]

[InlineData("relative.htm?query=string", true, "http://127.0.0.1/relative.htm?query=string", true)]
[InlineData("relative.htm?query=string", false, "http://127.0.0.1/relative.htm?query=string", true)]
[InlineData("http://127.0.0.1/absolute.htm?query=string", true, "http://127.0.0.1/absolute.htm?query=string", true)]
[InlineData("http://127.0.0.1/absolute.htm?query=string", false, "http://127.0.0.1/absolute.htm?query=string", true)]

[InlineData("/folder/relative.htm", true, "http://127.0.0.1/relative.htm", false)]
[InlineData("/folder/relative.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("/folder/relative.htm", false, "http://127.0.0.1/relative.htm", false)]
[InlineData("/folder/relative.htm", false, "http://127.0.0.1/relative.htm?query=string", false)]

[InlineData("relative.htm", true, "http://127.0.0.1/folder/relative.htm", false)]
[InlineData("relative.htm", true, "http://127.0.0.1/folder/relative.htm?query=string", false)]
[InlineData("relative.htm", false, "http://127.0.0.1/folder/relative.htm", false)]
[InlineData("relative.htm", false, "http://127.0.0.1/folder/relative.htm?query=string", false)]

[InlineData("folder/relative.htm", true, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("folder/relative.htm", true, "http://127.0.0.1/folder/relative.htm?query=string", false)]
[InlineData("folder/relative.htm", false, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("folder/relative.htm", false, "http://127.0.0.1/folder/relative.htm?query=string", false)]

[InlineData("/folder/relative.htm", true, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("/folder/relative.htm", true, "http://127.0.0.1/folder/relative.htm?query=string", false)]
[InlineData("/folder/relative.htm", false, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("/folder/relative.htm", false, "http://127.0.0.1/folder/relative.htm?query=string", false)]

[InlineData("http://127.0.0.1/absolute.htm", true, "http://127.0.0.1/absolute.htm", true)]
[InlineData("http://127.0.0.1/absolute.htm", true, "http://127.0.0.1/absolute.htm?query=string", false)]
[InlineData("http://127.0.0.1/absolute.htm", false, "http://127.0.0.1/absolute.htm", true)]
[InlineData("http://127.0.0.1/absolute.htm", false, "http://127.0.0.1/absolute.htm?query=string", false)]

[InlineData("http://127.0.0.1/absolute.htm", true, "http://127.0.0.1/folder/absolute.htm", false)]
[InlineData("http://127.0.0.1/absolute.htm", true, "http://127.0.0.1/folder/absolute.htm?query=string", false)]
[InlineData("http://127.0.0.1/absolute.htm", false, "http://127.0.0.1/folder/absolute.htm", false)]
[InlineData("http://127.0.0.1/absolute.htm", false, "http://127.0.0.1/folder/absolute.htm?query=string", false)]

[InlineData("http://127.0.0.1/folder/absolute.htm", true, "http://127.0.0.1/folder/absolute.htm", true)]
[InlineData("http://127.0.0.1/folder/absolute.htm", true, "http://127.0.0.1/folder/absolute.htm?query=string", false)]
[InlineData("http://127.0.0.1/folder/absolute.htm", false, "http://127.0.0.1/folder/absolute.htm", true)]
[InlineData("http://127.0.0.1/folder/absolute.htm", false, "http://127.0.0.1/folder/absolute.htm?query=string", false)]

[InlineData("*.htm", true, "http://127.0.0.1/relative.htm", true)]
[InlineData("*.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("*.htm", false, "http://127.0.0.1/relative.htm", false)]

[InlineData("*/relative.htm", true, "http://127.0.0.1/relative.htm", true)]
[InlineData("*/relative.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("*/relative.htm", false, "http://127.0.0.1/relative.htm", false)]

[InlineData("/*/relative.htm", true, "http://127.0.0.1/folder/relative.htm", false)]
[InlineData("/*/relative.htm", true, "http://127.0.0.1/folder/relative.htm?query=string", false)]
[InlineData("/*/relative.htm", false, "http://127.0.0.1/folder/relative.htm", false)]

[InlineData("/*/relative.htm", true, "http://127.0.0.1/relative.htm", false)]
[InlineData("/*/relative.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("/*/relative.htm", false, "http://127.0.0.1/relative.htm", false)]

[InlineData("/folder/*.htm", true, "http://127.0.0.1/folder/relative.htm", false)]
[InlineData("/folder/*.htm", true, "http://127.0.0.1/folder/relative.htm?query=string", false)]
[InlineData("/folder/*.htm", false, "http://127.0.0.1/folder/relative.htm", false)]

[InlineData("*/folder/*.htm", true, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("*/folder/*.htm", true, "http://127.0.0.1/folder/relative.htm?query=string", false)]
[InlineData("*/folder/*.htm", false, "http://127.0.0.1/folder/relative.htm", false)]

[InlineData("/folder/*.htm", true, "http://127.0.0.1/relative.htm", false)]
[InlineData("/folder/*.htm", true, "http://127.0.0.1/relative.htm?query=string", false)]
[InlineData("/folder/*.htm", false, "http://127.0.0.1/relative.htm", false)]

[InlineData("/*/*/relative.*", true, "http://127.0.0.1/folder1/folder2/relative.htm", false)]
[InlineData("/*/*/relative.*", true, "http://127.0.0.1/folder1/folder2/relative.htm?query=string", false)]
[InlineData("/*/*/relative.*", false, "http://127.0.0.1/folder1/folder2/relative.htm", false)]

[InlineData("*/folder1/*/relative.*", true, "http://127.0.0.1/folder1/folder2/relative.htm", true)]
[InlineData("*/folder1/*/relative.*", true, "http://127.0.0.1/folder1/folder2/relative.htm?query=string", true)]
[InlineData("*/folder1/*/relative.*", false, "http://127.0.0.1/folder1/folder2/relative.htm", false)]

[InlineData("/*/*/relative.*", true, "http://127.0.0.1/folder1/relative.htm", false)]
[InlineData("/*/*/relative.*", true, "http://127.0.0.1/folder1/relative.htm?query=string", false)]
[InlineData("/*/*/relative.*", false, "http://127.0.0.1/folder1/relative.htm", false)]

[InlineData("http://127.0.0.1/*.htm", true, "http://127.0.0.1/absolute.htm", true)]
[InlineData("http://127.0.0.1/*.htm", true, "http://127.0.0.1/absolute.htm?query=string", false)]
[InlineData("http://127.0.0.1/*.htm", false, "http://127.0.0.1/absolute.htm", false)]

[InlineData("http://127.0.0.1/*.htm", true, "http://127.0.0.1/folder/absolute.htm", true)]
[InlineData("http://127.0.0.1/*.htm", true, "http://127.0.0.1/folder/absolute.htm?query=string", false)]
[InlineData("http://127.0.0.1/*.htm", false, "http://127.0.0.1/folder/absolute.htm", false)]
public async Task When_configuring_requestUri_as_string_it_should_match(string uriString, bool allowWildcards, string requestUri, bool isMatch)
{
var request = new HttpRequestMessage { RequestUri = new Uri("http://127.0.0.1/") };
var request = new HttpRequestMessage { RequestUri = new Uri(requestUri, UriKind.Absolute) };

// Act
_sut.RequestUri("http://127.0.0.1/");
_sut.RequestUri(uriString, allowWildcards);
IReadOnlyCollection<IAsyncHttpRequestMatcher> matchers = _sut.Build();

// Assert
matchers.Should().HaveCount(1).And.AllBeOfType<RequestUriMatcher>();
(await matchers.AnyAsync(new MockHttpRequestContext(request))).Should().BeTrue();
matchers.Should().HaveCount(1).And.AllBeAssignableTo<UriMatcher>();
(await matchers.AnyAsync(new MockHttpRequestContext(request))).Should().Be(isMatch);
}

[Fact]
public async Task When_configuring_requestUri_as_uri_should_match()
[Theory]
[InlineData("", UriKind.Relative, "http://127.0.0.1/", true)]
[InlineData("relative.htm", UriKind.Relative, "http://127.0.0.1/relative.htm", true)]
[InlineData("/folder/relative.htm", UriKind.Relative, "http://127.0.0.1/relative.htm", false)]
[InlineData("relative.htm", UriKind.Relative, "http://127.0.0.1/folder/relative.htm", false)]
[InlineData("folder/relative.htm", UriKind.Relative, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("/folder/relative.htm", UriKind.Relative, "http://127.0.0.1/folder/relative.htm", true)]
[InlineData("http://127.0.0.1/absolute.htm", UriKind.Absolute, "http://127.0.0.1/absolute.htm", true)]
[InlineData("http://127.0.0.1/absolute.htm", UriKind.Absolute, "http://127.0.0.1/folder/absolute.htm", false)]
public async Task When_configuring_requestUri_as_uri_it_should_match(string matchUri, UriKind uriKind, string requestUri, bool isMatch)
{
var uri = new Uri("http://127.0.0.1/");
var request = new HttpRequestMessage { RequestUri = new Uri("http://127.0.0.1/") };
var uri = new Uri(matchUri, uriKind);
var request = new HttpRequestMessage { RequestUri = new Uri(requestUri, UriKind.Absolute) };

// Act
_sut.RequestUri(uri);
IReadOnlyCollection<IAsyncHttpRequestMatcher> matchers = _sut.Build();

// Assert
matchers.Should().HaveCount(1).And.AllBeOfType<RequestUriMatcher>();
(await matchers.AnyAsync(new MockHttpRequestContext(request))).Should().BeTrue();
matchers.Should().HaveCount(1).And.AllBeAssignableTo<UriMatcher>();
(await matchers.AnyAsync(new MockHttpRequestContext(request))).Should().Be(isMatch);
}

[Theory]
[InlineData("*/controller/*", false)]
[InlineData("*/controller/*", true)]
[InlineData("file.jpg", true)]
[InlineData("file.jpg", false)]
[InlineData("http://0.0.0.0/path/file.jpg", true)]
[InlineData("http://0.0.0.0/path/file.jpg", false)]
public void When_formatting_uriString_matcher_it_should_return_human_readable_representation(string uriString, bool allowWildcards)
{
string expectedText = $"RequestUri: '{uriString}'";

// Act
_sut.RequestUri(uriString, allowWildcards);
IReadOnlyCollection<IAsyncHttpRequestMatcher> matchers = _sut.Build();
string displayText = matchers.Should()
.ContainSingle()
.Which.Should()
.BeAssignableTo<UriMatcher>()
.Which.ToString();

// Assert
displayText.Should().Be(expectedText);
}

[Theory]
[InlineData("*/controller/*")]
[InlineData("file.jpg")]
[InlineData("http://0.0.0.0/path/file.jpg")]
public void When_formatting_uri_matcher_it_should_return_human_readable_representation(string uriString)
{
string expectedText = $"RequestUri: '{uriString}'";
var uri = new Uri(uriString, DotNetRelativeOrAbsolute);

// Act
_sut.RequestUri(uri);
IReadOnlyCollection<IAsyncHttpRequestMatcher> matchers = _sut.Build();
string displayText = matchers.Should()
.ContainSingle()
.Which.Should()
.BeAssignableTo<UriMatcher>()
.Which.ToString();

// Assert
displayText.Should().Be(expectedText);
}
}

Expand Down Expand Up @@ -692,7 +845,8 @@ public void Given_null_argument_when_executing_method_it_should_throw(params obj
DelegateTestCase.Create(
RequestMatchingExtensions.RequestUri,
instance,
uri.ToString()),
uri.ToString(),
true),
DelegateTestCase.Create(
RequestMatchingExtensions.RequestUri,
instance,
Expand Down
Loading

0 comments on commit c5ca29c

Please sign in to comment.