Skip to content

Commit

Permalink
fix: avoid null exception when received body is empty but recorded bo…
Browse files Browse the repository at this point in the history
…dy isn't (#59)
  • Loading branch information
jhonny-apiiro authored Feb 2, 2024
1 parent 62b5926 commit 8db019f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Add .NET 8.0 support
- `AdvancedSettings` uses `MatchRules.Default` instead of a new instance of `MatchRules` if not provided during construction
- Fix `NullReferenceException` when trying to match by body with a null body (`refit` compatibility)

## v0.9.0 (2023-05-17)

Expand Down
20 changes: 20 additions & 0 deletions EasyVCR.Tests/ClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,26 @@ public async Task TestMatchNonJsonBody()
Assert.IsNotNull(response);
}

[TestMethod]
public async Task TestMatchEmptyStringBodyToNonEmptyStringBody()
{
var cassette = TestUtils.GetCassette("test_match_empty_body");
cassette.Erase(); // Erase cassette before recording

const string url = "https://httpbin.org/post";

var client = HttpClients.NewHttpClient(cassette, Mode.Record);
var someContent = new ByteArrayContent(Encoding.UTF8.GetBytes("non_empty_string_body"));
_ = await client.PostAsync(url, someContent);

// try to replay the request with match by body enforcement
client = HttpClients.NewHttpClient(cassette, Mode.Replay, new AdvancedSettings
{
MatchRules = new MatchRules().ByBody()
});
var emptyContent = new ByteArrayContent(Encoding.UTF8.GetBytes(string.Empty));
await Assert.ThrowsExceptionAsync<VCRException>(async () => await client.PostAsync(url, emptyContent), $"No interaction found for request POST {url}");
}

[TestMethod]
public async Task TestInteractionElements()
Expand Down
7 changes: 7 additions & 0 deletions EasyVCR/InternalUtilities/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace EasyVCR.InternalUtilities
{
public static class Extensions
{
public static bool IsEmptyStringOrNull(this string? str) => str == null || string.IsNullOrWhiteSpace(str);
}
}
18 changes: 16 additions & 2 deletions EasyVCR/MatchRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EasyVCR.InternalUtilities;
using EasyVCR.RequestElements;
using JsonSerialization = EasyVCR.InternalUtilities.JSON.Serialization;
using XmlSerialization = EasyVCR.InternalUtilities.XML.Serialization;
Expand Down Expand Up @@ -132,7 +133,7 @@ public MatchRules ByBody(List<CensorElement>? ignoredElements = null)
return true;
if (received.Body == null || recorded.Body == null)
// one has a null body, so they don't match
// one has a null body, the other does not, so they don't match
return false;
var receivedBody = received.Body;
Expand All @@ -155,11 +156,24 @@ public MatchRules ByBody(List<CensorElement>? ignoredElements = null)
// not JSON, using the string as it is
}
if (receivedBody.IsEmptyStringOrNull())
// short-cut if the received body is empty
receivedBody = null;
if (recordedBody.IsEmptyStringOrNull())
// short-cut if the recorded body is empty
recordedBody = null;
if (receivedBody == null && recordedBody == null)
// both have empty string bodies, so they match
return true;
return receivedBody!.Equals(recordedBody, StringComparison.OrdinalIgnoreCase);
if (receivedBody == null || recordedBody == null)
// one has a null body, the other does not, so they don't match
return false;
// if the bodies are not null, then we can compare them
return receivedBody.Equals(recordedBody, StringComparison.OrdinalIgnoreCase);
});
return this;
}
Expand Down

0 comments on commit 8db019f

Please sign in to comment.