richardszalay/mockhttp

Package does not support URI containing fragments

Meliv opened this issue · 3 comments

Meliv commented

We're attemping to mock a URI containing a fragment. For example, http://localhost/test#resource

Here's a unit test from the repo where I'm testing this scenario

[Fact]
public void Should_match_pathswithfragment()
{
    var result = Test(
        expected: "/test#resource",
        actual: "http://tempuri.org/test#resource"
        );
    Assert.True(result);
}

This test will fail. It seems to be because GetUrlToMatch method in the UriMatcher falls back to the URI's local path which strips out everything after the fragment

Are there any plans to support fragments?

I think this may be an issue with your specific environment as the follow test passes:

[Fact]
public async Task Matchers_can_match_against_uri_fragments()
{
    var mockHttp = new MockHttpMessageHandler();

    mockHttp.When("http://localhost/test#frag")
        .Respond(HttpStatusCode.OK);

    var client = mockHttp.ToHttpClient();

    var response = await client.GetAsync("http://localhost/test#frag");

    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
Meliv commented

Hi Richard, thanks for getting back
I've taken another look and you're right, I don't think it's the fragment that's causing the issue but the content. To be a bit more clear, we're using HttpClient.PostAsJsonAsync() and I suspect the ContentMatcher is what's causing it to fail. Here's a modified version of your unit test that is failing on my end. Any chance you can help me diagnose this or do you want me to raise a separate issue?

Cheers!

[Fact]
public async Task Matchers_can_match_against_uri_fragments()
{
    var mockHttp = new MockHttpMessageHandler();

    mockHttp
        .Expect("http://localhost/test#frag")
        .WithContent("test")
        .Respond(HttpStatusCode.OK);

    var client = mockHttp.ToHttpClient();
    
    var response = await client.PostAsJsonAsync("http://localhost/test#frag", "test");

    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}

Ah, this is failing because:

  1. Serializing a string to JSON includes quotes: "string"
  2. WithContent is an absolute match.

ie. you're matching test but what is being sent is "test"

To resolve, either:

  1. .WithPartialContent("test")
  2. .WithContent("\"test\"")