Skip to content

Commit 723d981

Browse files
authored
Merge pull request #46 from joadan/copilot/update-http-merge-to-patch
Use HTTP PATCH instead of MERGE for update operations
2 parents 0670bf9 + da34a90 commit 723d981

2 files changed

Lines changed: 96 additions & 1 deletion

File tree

src/Linq2OData.Core/ODataClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public async Task<bool> UpdateEntityAsync(string entitysetName, string keyExpres
113113
{
114114
string json = JsonSerializer.Serialize(input, jsonOptions);
115115
var content = new StringContent(json, Encoding.UTF8, "application/json");
116-
var request = new HttpRequestMessage(new HttpMethod("MERGE"), $"{entitysetName}({keyExpression})")
116+
var request = new HttpRequestMessage(HttpMethod.Patch, $"{entitysetName}({keyExpression})")
117117
{
118118
Content = new StringContent(json, Encoding.UTF8, "application/json")
119119
};
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using Linq2OData.Core;
2+
using System.Net;
3+
using System.Text;
4+
5+
namespace Linq2OData.Tests;
6+
7+
public class UpdateEntityTests
8+
{
9+
private class MockHttpHandler : HttpMessageHandler
10+
{
11+
private readonly Func<HttpRequestMessage, HttpResponseMessage> _handler;
12+
13+
public MockHttpHandler(Func<HttpRequestMessage, HttpResponseMessage> handler)
14+
{
15+
_handler = handler;
16+
}
17+
18+
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
19+
{
20+
return Task.FromResult(_handler(request));
21+
}
22+
}
23+
24+
private static (ODataClient client, List<HttpRequestMessage> capturedRequests) CreateMockedClient(
25+
ODataVersion version,
26+
HttpStatusCode statusCode = HttpStatusCode.NoContent)
27+
{
28+
var capturedRequests = new List<HttpRequestMessage>();
29+
30+
var handler = new MockHttpHandler(request =>
31+
{
32+
capturedRequests.Add(request);
33+
return new HttpResponseMessage(statusCode);
34+
});
35+
36+
var httpClient = new HttpClient(handler)
37+
{
38+
BaseAddress = new Uri("https://example.com/odata/")
39+
};
40+
41+
return (new ODataClient(httpClient, version), capturedRequests);
42+
}
43+
44+
private class TestInput : ODataInputBase
45+
{
46+
public string? Name
47+
{
48+
get => GetValue<string>(nameof(Name));
49+
set => SetValue(nameof(Name), value);
50+
}
51+
}
52+
53+
[Fact]
54+
public async Task UpdateEntityAsync_ShouldUsePatchMethod()
55+
{
56+
// Arrange
57+
var (client, capturedRequests) = CreateMockedClient(ODataVersion.V4);
58+
var input = new TestInput { Name = "Updated" };
59+
60+
// Act
61+
await client.UpdateEntityAsync("Products", "1", input);
62+
63+
// Assert
64+
Assert.Single(capturedRequests);
65+
Assert.Equal(HttpMethod.Patch, capturedRequests[0].Method);
66+
}
67+
68+
[Fact]
69+
public async Task UpdateEntityAsync_ShouldReturnTrue_WhenSuccessful()
70+
{
71+
// Arrange
72+
var (client, _) = CreateMockedClient(ODataVersion.V4, HttpStatusCode.NoContent);
73+
var input = new TestInput { Name = "Updated" };
74+
75+
// Act
76+
var result = await client.UpdateEntityAsync("Products", "1", input);
77+
78+
// Assert
79+
Assert.True(result);
80+
}
81+
82+
[Fact]
83+
public async Task UpdateEntityAsync_ShouldReturnFalse_WhenNotFound()
84+
{
85+
// Arrange
86+
var (client, _) = CreateMockedClient(ODataVersion.V4, HttpStatusCode.NotFound);
87+
var input = new TestInput { Name = "Updated" };
88+
89+
// Act
90+
var result = await client.UpdateEntityAsync("Products", "1", input);
91+
92+
// Assert
93+
Assert.False(result);
94+
}
95+
}

0 commit comments

Comments
 (0)