diff --git a/TUnit.Mocks.Http.Tests/MockHttpHandlerTests.cs b/TUnit.Mocks.Http.Tests/MockHttpHandlerTests.cs index 6872794ed3..6376057178 100644 --- a/TUnit.Mocks.Http.Tests/MockHttpHandlerTests.cs +++ b/TUnit.Mocks.Http.Tests/MockHttpHandlerTests.cs @@ -559,4 +559,50 @@ public async Task FactoryDelegateSeesOriginalContentType() await Assert.That(capturedContentType).IsEqualTo("application/json"); } + + [Test] + public async Task MatchesByPath_AutoPrependsSlashWhenMissing() + { + using var client = Mock.HttpClient("https://my.domain/"); + client.Handler.OnPost("my_endpoint").Respond(HttpStatusCode.Accepted); + + var response = await client.PostAsync("my_endpoint", null); + + await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.Accepted); + } + + [Test] + public async Task MatchesByPathPrefix_AutoPrependsSlashWhenMissing() + { + using var client = Mock.HttpClient("http://localhost"); + client.Handler.OnRequest(r => r.Method(HttpMethod.Get).PathStartsWith("api/v2")) + .Respond(HttpStatusCode.OK); + + var response = await client.GetAsync("/api/v2/anything/here"); + + await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK); + } + + [Test] + public async Task MatchesByPath_KeepsAbsoluteUrlAsIs() + { + using var client = Mock.HttpClient(); + client.Handler.OnGet("https://my.domain/foo").Respond(HttpStatusCode.OK); + + var response = await client.GetAsync("https://my.domain/foo"); + + await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK); + } + + [Test] + public async Task MatchesByPath_RegexNotNormalized() + { + using var client = Mock.HttpClient("http://localhost"); + client.Handler.OnRequest(r => r.Method(HttpMethod.Get).PathMatches(@"^/api/users/\d+$")) + .Respond(HttpStatusCode.OK); + + var response = await client.GetAsync("/api/users/42"); + + await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK); + } } diff --git a/TUnit.Mocks.Http/RequestMatcher.cs b/TUnit.Mocks.Http/RequestMatcher.cs index 88c4707a31..5a9d48d3ed 100644 --- a/TUnit.Mocks.Http/RequestMatcher.cs +++ b/TUnit.Mocks.Http/RequestMatcher.cs @@ -26,17 +26,24 @@ public RequestMatcher Method(HttpMethod method) /// Match requests to the exact path. public RequestMatcher Path(string path) { - _exactPath = path; + _exactPath = NormalizePath(path); return this; } /// Match requests whose path starts with the specified prefix. public RequestMatcher PathStartsWith(string prefix) { - _pathPrefix = prefix; + _pathPrefix = NormalizePath(prefix); return this; } + private static string NormalizePath(string value) + { + if (string.IsNullOrEmpty(value) || value[0] == '/') return value; + if (Uri.TryCreate(value, UriKind.Absolute, out _)) return value; + return "/" + value; + } + /// Match requests whose path matches the regex pattern. public RequestMatcher PathMatches(string pattern) {