Skip to content

Commit 5753c8d

Browse files
authored
chore: restore public API compatibility. Some stuff was removed/changed in #110, and claimed in PR that the public API did not change, which is not true. (#113)
1 parent 56ee517 commit 5753c8d

File tree

3 files changed

+222
-1
lines changed

3 files changed

+222
-1
lines changed

src/MockHttp/Extensions/RequestMatchingExtensions.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ private static bool ContainsWildcard(this string value)
3030
#endif
3131
}
3232

33+
/// <summary>
34+
/// Matches a request by specified <paramref name="requestUri" />.
35+
/// </summary>
36+
/// <param name="builder">The request matching builder instance.</param>
37+
/// <param name="requestUri">The request URI or a URI wildcard.</param>
38+
/// <returns>The request matching builder instance.</returns>
39+
#pragma warning disable CA1054
40+
public static RequestMatching RequestUri(this RequestMatching builder, string requestUri)
41+
#pragma warning restore CA1054
42+
{
43+
return builder.RequestUri(requestUri, true);
44+
}
45+
3346
/// <summary>
3447
/// Matches a request by specified <paramref name="requestUri" />.
3548
/// </summary>
@@ -38,7 +51,8 @@ private static bool ContainsWildcard(this string value)
3851
/// <param name="allowWildcards"><see langword="true" /> to allow wildcards, or <see langword="false" /> if exact matching.</param>
3952
/// <returns>The request matching builder instance.</returns>
4053
#pragma warning disable CA1054
41-
public static RequestMatching RequestUri(this RequestMatching builder, string requestUri, bool allowWildcards = true)
54+
// For now, keep this internal. For coverage, and most likely, the API will change so then we'd have more to deprecate (using patterns).
55+
internal static RequestMatching RequestUri(this RequestMatching builder, string requestUri, bool allowWildcards)
4256
#pragma warning restore CA1054
4357
{
4458
if (requestUri is null)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using System.Diagnostics;
2+
using MockHttp.Http;
3+
using MockHttp.Patterns;
4+
using MockHttp.Responses;
5+
using static MockHttp.Http.UriExtensions;
6+
7+
namespace MockHttp.Matchers;
8+
9+
/// <summary>
10+
/// Matches a request by the request URI.
11+
/// </summary>
12+
[Obsolete($"Replaced with {nameof(UriMatcher)}. Will be removed in next major release.")]
13+
public class RequestUriMatcher : HttpRequestMatcher
14+
{
15+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
16+
private readonly Uri _requestUri = default!;
17+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
18+
private readonly string _formattedUri;
19+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
20+
private readonly WildcardPattern? _uriPatternMatcher;
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="RequestUriMatcher" /> class using specified <paramref name="uri" />.
24+
/// </summary>
25+
/// <param name="uri">The request URI.</param>
26+
public RequestUriMatcher(Uri uri)
27+
{
28+
_requestUri = uri.EnsureIsRooted();
29+
_formattedUri = _requestUri.ToString();
30+
}
31+
32+
/// <summary>
33+
/// Initializes a new instance of the <see cref="RequestUriMatcher" /> class using specified <paramref name="uriString" />.
34+
/// </summary>
35+
/// <param name="uriString">The request URI or a URI wildcard.</param>
36+
/// <param name="allowWildcards"><see langword="true" /> to allow wildcards, or <see langword="false" /> if exact matching.</param>
37+
public RequestUriMatcher(string uriString, bool allowWildcards = true)
38+
{
39+
_formattedUri = uriString ?? throw new ArgumentNullException(nameof(uriString));
40+
41+
if (allowWildcards
42+
#if NETSTANDARD2_0 || NETFRAMEWORK
43+
&& uriString.Contains("*")
44+
#else
45+
&& uriString.Contains('*', StringComparison.InvariantCultureIgnoreCase)
46+
#endif
47+
)
48+
{
49+
_uriPatternMatcher = WildcardPattern.Create(uriString);
50+
}
51+
else
52+
{
53+
// If no wildcards, then must be actual uri.
54+
_requestUri = new Uri(uriString, DotNetRelativeOrAbsolute).EnsureIsRooted();
55+
_formattedUri = _requestUri.ToString();
56+
}
57+
}
58+
59+
/// <inheritdoc />
60+
public override bool IsMatch(MockHttpRequestContext requestContext)
61+
{
62+
if (requestContext is null)
63+
{
64+
throw new ArgumentNullException(nameof(requestContext));
65+
}
66+
67+
Uri? requestUri = requestContext.Request.RequestUri;
68+
if (requestUri is null)
69+
{
70+
return false;
71+
}
72+
73+
if (_uriPatternMatcher is null)
74+
{
75+
return IsAbsoluteUriMatch(requestUri) || IsRelativeUriMatch(requestUri);
76+
}
77+
78+
return _uriPatternMatcher.Value.IsMatch(requestUri.ToString());
79+
}
80+
81+
private bool IsAbsoluteUriMatch(Uri uri)
82+
{
83+
return _requestUri.IsAbsoluteUri && uri.Equals(_requestUri);
84+
}
85+
86+
private bool IsRelativeUriMatch(Uri uri)
87+
{
88+
return !_requestUri.IsAbsoluteUri
89+
&& uri.IsBaseOf(_requestUri)
90+
&& uri.ToString().EndsWith(_requestUri.ToString(), StringComparison.Ordinal);
91+
}
92+
93+
/// <inheritdoc />
94+
public override string ToString()
95+
{
96+
return $"RequestUri: '{_formattedUri}'";
97+
}
98+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using MockHttp.Responses;
2+
3+
namespace MockHttp.Matchers;
4+
5+
public class RequestUriMatcherTests
6+
{
7+
[Theory]
8+
[InlineData("", UriKind.Relative, "http://127.0.0.1/", true)]
9+
[InlineData("relative.htm", UriKind.Relative, "http://127.0.0.1/relative.htm", true)]
10+
[InlineData("/folder/relative.htm", UriKind.Relative, "http://127.0.0.1/relative.htm", false)]
11+
[InlineData("relative.htm", UriKind.Relative, "http://127.0.0.1/folder/relative.htm", false)]
12+
[InlineData("folder/relative.htm", UriKind.Relative, "http://127.0.0.1/folder/relative.htm", true)]
13+
[InlineData("/folder/relative.htm", UriKind.Relative, "http://127.0.0.1/folder/relative.htm", true)]
14+
[InlineData("http://127.0.0.1/absolute.htm", UriKind.Absolute, "http://127.0.0.1/absolute.htm", true)]
15+
[InlineData("http://127.0.0.1/absolute.htm", UriKind.Absolute, "http://127.0.0.1/folder/absolute.htm", false)]
16+
public void Given_uri_when_matching_should_match(string matchUri, UriKind uriKind, string requestUri, bool isMatch)
17+
{
18+
var request = new HttpRequestMessage { RequestUri = new Uri(requestUri, UriKind.Absolute) };
19+
var sut = new RequestUriMatcher(new Uri(matchUri, uriKind));
20+
21+
// Act & assert
22+
sut.IsMatch(new MockHttpRequestContext(request)).Should().Be(isMatch);
23+
}
24+
25+
[Theory]
26+
[InlineData("relative.htm", true, "http://127.0.0.1/relative.htm", true)]
27+
[InlineData("/folder/relative.htm", true, "http://127.0.0.1/relative.htm", false)]
28+
[InlineData("relative.htm", true, "http://127.0.0.1/folder/relative.htm", false)]
29+
[InlineData("folder/relative.htm", true, "http://127.0.0.1/folder/relative.htm", true)]
30+
[InlineData("/folder/relative.htm", true, "http://127.0.0.1/folder/relative.htm", true)]
31+
[InlineData("http://127.0.0.1/absolute.htm", true, "http://127.0.0.1/absolute.htm", true)]
32+
[InlineData("http://127.0.0.1/absolute.htm", true, "http://127.0.0.1/folder/absolute.htm", false)]
33+
[InlineData("*.htm", true, "http://127.0.0.1/relative.htm", true)]
34+
[InlineData("*/relative.htm", true, "http://127.0.0.1/relative.htm", true)]
35+
[InlineData("/*/relative.htm", true, "http://127.0.0.1/folder/relative.htm", false)]
36+
[InlineData("/*/relative.htm", true, "http://127.0.0.1/relative.htm", false)]
37+
[InlineData("/folder/*.htm", true, "http://127.0.0.1/folder/relative.htm", false)]
38+
[InlineData("*/folder/*.htm", true, "http://127.0.0.1/folder/relative.htm", true)]
39+
[InlineData("/folder/*.htm", true, "http://127.0.0.1/relative.htm", false)]
40+
[InlineData("/*/*/relative.*", true, "http://127.0.0.1/folder1/folder2/relative.htm", false)]
41+
[InlineData("*/folder1/*/relative.*", true, "http://127.0.0.1/folder1/folder2/relative.htm", true)]
42+
[InlineData("/*/*/relative.*", true, "http://127.0.0.1/folder1/relative.htm", false)]
43+
[InlineData("http://127.0.0.1/*.htm", true, "http://127.0.0.1/absolute.htm", true)]
44+
[InlineData("http://127.0.0.1/*.htm", true, "http://127.0.0.1/folder/absolute.htm", true)]
45+
public void Given_uriString_when_matching_should_match(string uriString, bool hasWildcard, string requestUri, bool isMatch)
46+
{
47+
var request = new HttpRequestMessage { RequestUri = new Uri(requestUri, UriKind.Absolute) };
48+
var sut = new RequestUriMatcher(uriString, hasWildcard);
49+
50+
// Act & assert
51+
sut.IsMatch(new MockHttpRequestContext(request)).Should().Be(isMatch);
52+
}
53+
54+
[Fact]
55+
public void Given_null_uri_when_creating_matcher_should_throw()
56+
{
57+
Uri? uri = null;
58+
59+
// Act
60+
Func<RequestUriMatcher> act = () => new RequestUriMatcher(uri!);
61+
62+
// Assert
63+
act.Should()
64+
.Throw<ArgumentNullException>()
65+
.WithParameterName(nameof(uri));
66+
}
67+
68+
[Fact]
69+
public void Given_null_uriString_when_creating_matcher_should_throw()
70+
{
71+
string? uriString = null;
72+
73+
// Act
74+
Func<RequestUriMatcher> act = () => new RequestUriMatcher(uriString!, false);
75+
76+
// Assert
77+
act.Should()
78+
.Throw<ArgumentNullException>()
79+
.WithParameterName(nameof(uriString));
80+
}
81+
82+
[Fact]
83+
public void When_formatting_should_return_human_readable_representation()
84+
{
85+
const string expectedText = "RequestUri: '*/controller/*'";
86+
var sut = new RequestUriMatcher("*/controller/*");
87+
88+
// Act
89+
string displayText = sut.ToString();
90+
91+
// Assert
92+
displayText.Should().Be(expectedText);
93+
}
94+
95+
[Fact]
96+
public void Given_null_context_when_matching_it_should_throw()
97+
{
98+
var sut = new RequestUriMatcher("*/controller/*");
99+
MockHttpRequestContext? requestContext = null;
100+
101+
// Act
102+
Action act = () => sut.IsMatch(requestContext!);
103+
104+
// Assert
105+
act.Should()
106+
.Throw<ArgumentNullException>()
107+
.WithParameterName(nameof(requestContext));
108+
}
109+
}

0 commit comments

Comments
 (0)