From dcc81440aa70ea6b0ae8b39196785eb8b46d2b61 Mon Sep 17 00:00:00 2001 From: belov-a Date: Thu, 25 Dec 2025 23:46:59 +0700 Subject: [PATCH 1/2] Fix batch failed with relative url & Content-Transfer-Encoding have duplicate binary --- .../UnitTests/NestedExpandExpressionTests.cs | 2 +- .../UnitTests/ODataBatchBuilderTests.cs | 26 +++++++++++++++++++ .../UnitTests/ODataCrossJoinTests.cs | 3 ++- .../UnitTests/ODataDateTimeConverterTests.cs | 2 +- .../HttpMessageContent.cs | 4 +-- .../ODataClient.Batch.cs | 2 -- .../PanoramicData.OData.Client.csproj | 4 +++ 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/PanoramicData.OData.Client.Test/UnitTests/NestedExpandExpressionTests.cs b/PanoramicData.OData.Client.Test/UnitTests/NestedExpandExpressionTests.cs index 58b4707..1066e8f 100644 --- a/PanoramicData.OData.Client.Test/UnitTests/NestedExpandExpressionTests.cs +++ b/PanoramicData.OData.Client.Test/UnitTests/NestedExpandExpressionTests.cs @@ -50,7 +50,7 @@ public void Expand_WithSingleNestedProperty_ProducesNestedExpandSyntax() /// Tests that multiple independent expands still work correctly. /// [Fact] - public void Expand_WithMultipleIndependentProperties_ProducesCommaSepa­ratedExpands() + public void Expand_WithMultipleIndependentProperties_ProducesCommaSeparatedExpands() { // Arrange var builder = new ODataQueryBuilder("People", NullLogger.Instance); diff --git a/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs b/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs index 061750a..a4195d4 100644 --- a/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs +++ b/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs @@ -1,3 +1,5 @@ +using System.Net.Http.Headers; + namespace PanoramicData.OData.Client.Test.UnitTests; /// @@ -35,6 +37,30 @@ public void Dispose() _httpClient.Dispose(); GC.SuppressFinalize(this); } + + /// + /// + /// + [Fact] + public async Task WriteToStreamAsync_ShouldIncludeRequiredHeaders() + { + using var request = new HttpRequestMessage(HttpMethod.Post, "http://test.org/Customers"); + request.Content = new StringContent("{\"Name\":\"Test\"}"); + request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + using var content = new HttpMessageContent(request); + + // Act + var resultString = await content.ReadAsStringAsync(TestContext.Current.CancellationToken); + + // Assert: Check the HttpContent headers specifically + content.Headers.TryGetValues("Content-Transfer-Encoding", out var values); + values.Should().Contain("binary"); + + // Assert: Check the serialized string content + resultString.Should().Contain("POST /Customers HTTP/1.1"); + resultString.Should().Contain("Content-Type: application/json"); + } #region Get Operation Tests diff --git a/PanoramicData.OData.Client.Test/UnitTests/ODataCrossJoinTests.cs b/PanoramicData.OData.Client.Test/UnitTests/ODataCrossJoinTests.cs index 4036682..657e2b6 100644 --- a/PanoramicData.OData.Client.Test/UnitTests/ODataCrossJoinTests.cs +++ b/PanoramicData.OData.Client.Test/UnitTests/ODataCrossJoinTests.cs @@ -113,7 +113,7 @@ public void CrossJoin_MultipleEntitySets_ShouldIncludeAll() } [Fact] - public async Task CrossJoin_LessThanTwoEntitySets_ShouldThrow() + public Task CrossJoin_LessThanTwoEntitySets_ShouldThrow() { // Arrange var logger = NullLogger.Instance; @@ -121,6 +121,7 @@ public async Task CrossJoin_LessThanTwoEntitySets_ShouldThrow() // Act & Assert var act = () => new ODataCrossJoinBuilder(["Products"], logger); act.Should().ThrowExactly(); + return Task.CompletedTask; } [Fact] diff --git a/PanoramicData.OData.Client.Test/UnitTests/ODataDateTimeConverterTests.cs b/PanoramicData.OData.Client.Test/UnitTests/ODataDateTimeConverterTests.cs index 9fb8f0c..6c74915 100644 --- a/PanoramicData.OData.Client.Test/UnitTests/ODataDateTimeConverterTests.cs +++ b/PanoramicData.OData.Client.Test/UnitTests/ODataDateTimeConverterTests.cs @@ -101,7 +101,7 @@ public void Read_InvalidDate_ReturnsDefault() public void Read_SimpleDateFormat_ParsesCorrectly() { // Arrange - var json = "\"2024-01-15\""; + var json = "\"2024-01-15Z\""; // Act var result = JsonSerializer.Deserialize(json, _options); diff --git a/PanoramicData.OData.Client/HttpMessageContent.cs b/PanoramicData.OData.Client/HttpMessageContent.cs index d2bdbdb..dbcff90 100644 --- a/PanoramicData.OData.Client/HttpMessageContent.cs +++ b/PanoramicData.OData.Client/HttpMessageContent.cs @@ -41,14 +41,14 @@ private async Task BuildContentAsync() var sb = new StringBuilder(); // Request line: METHOD path HTTP/1.1 - var requestUri = _request.RequestUri?.PathAndQuery ?? "/"; sb.Append(_request.Method.ToString()); sb.Append(' '); + var requestUri = (_request.RequestUri?.IsAbsoluteUri == true ? _request.RequestUri.PathAndQuery : _request.RequestUri?.ToString()) ?? "/"; sb.Append(requestUri); sb.AppendLine(" HTTP/1.1"); // Host header - if (_request.RequestUri?.Host is not null) + if (_request.RequestUri is { IsAbsoluteUri: true }) { sb.Append("Host: "); sb.AppendLine(_request.RequestUri.Host); diff --git a/PanoramicData.OData.Client/ODataClient.Batch.cs b/PanoramicData.OData.Client/ODataClient.Batch.cs index f518154..51fb105 100644 --- a/PanoramicData.OData.Client/ODataClient.Batch.cs +++ b/PanoramicData.OData.Client/ODataClient.Batch.cs @@ -109,8 +109,6 @@ private HttpMessageContent BuildOperationContent(ODataBatchOperation operation) } var content = new HttpMessageContent(innerRequest); - content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/http"); - content.Headers.TryAddWithoutValidation("Content-Transfer-Encoding", "binary"); return content; } diff --git a/PanoramicData.OData.Client/PanoramicData.OData.Client.csproj b/PanoramicData.OData.Client/PanoramicData.OData.Client.csproj index fc38907..d69aede 100644 --- a/PanoramicData.OData.Client/PanoramicData.OData.Client.csproj +++ b/PanoramicData.OData.Client/PanoramicData.OData.Client.csproj @@ -39,4 +39,8 @@ + + + + From 29039c6ab3d8bcd88ae7b5f443b9c523c99281c2 Mon Sep 17 00:00:00 2001 From: belov-a Date: Thu, 25 Dec 2025 23:51:05 +0700 Subject: [PATCH 2/2] Add xml docx --- .../UnitTests/ODataBatchBuilderTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs b/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs index a4195d4..79712fd 100644 --- a/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs +++ b/PanoramicData.OData.Client.Test/UnitTests/ODataBatchBuilderTests.cs @@ -37,9 +37,9 @@ public void Dispose() _httpClient.Dispose(); GC.SuppressFinalize(this); } - + /// - /// + /// Verifies that the HTTP content written to the stream includes the required headers /// [Fact] public async Task WriteToStreamAsync_ShouldIncludeRequiredHeaders() @@ -47,12 +47,12 @@ public async Task WriteToStreamAsync_ShouldIncludeRequiredHeaders() using var request = new HttpRequestMessage(HttpMethod.Post, "http://test.org/Customers"); request.Content = new StringContent("{\"Name\":\"Test\"}"); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); - + using var content = new HttpMessageContent(request); - + // Act var resultString = await content.ReadAsStringAsync(TestContext.Current.CancellationToken); - + // Assert: Check the HttpContent headers specifically content.Headers.TryGetValues("Content-Transfer-Encoding", out var values); values.Should().Contain("binary");