Skip to content

Commit ade4036

Browse files
Port transport layer tests (#3187)
1 parent e50b8ec commit ade4036

10 files changed

+758
-0
lines changed

src/Microsoft.OData.Client/Microsoft.OData.Client.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
<ItemGroup>
2929
<InternalsVisibleTo Include="Microsoft.OData.Client.Tests" />
30+
<InternalsVisibleTo Include="Microsoft.OData.Client.E2E.Tests" />
3031
</ItemGroup>
3132

3233
<ItemGroup>

src/Microsoft.OData.Client/Serialization/HttpClientRequestMessage.cs

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace Microsoft.OData.Client
1414
using System.Net;
1515
using System.Net.Http;
1616
using System.Net.Http.Headers;
17+
using System.Text;
1718
using System.Threading;
1819
using System.Threading.Tasks;
1920
using Microsoft.OData;
@@ -410,6 +411,8 @@ private Task<HttpResponseMessage> CreateSendTask()
410411
{
411412
_requestMessage.Content.Headers.Add(contentHeader.Key, contentHeader.Value);
412413
}
414+
415+
string contentString = Encoding.UTF8.GetString(messageContent);
413416
}
414417

415418
_requestMessage.Method = new HttpMethod(_effectiveHttpMethod);

src/Microsoft.OData.Client/ShippingAssemblyAttributes.cs

+1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@
1818
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.Test.Data.Services.DDBasics" + AssemblyRef.TestPublicKey)]
1919
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AstoriaUnitTests.ClientCSharp" + AssemblyRef.TestPublicKey)]
2020
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.OData.Client.Tests" + AssemblyRef.TestPublicKey)]
21+
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.OData.Client.E2E.Tests" + AssemblyRef.TestPublicKey)]
2122
#pragma warning restore 436

test/EndToEndTests/Tests/Client/Microsoft.OData.Client.E2E.Tests/Microsoft.OData.Client.E2E.Tests.csproj

+17
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,25 @@
44
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
7+
8+
<AssemblyName>Microsoft.OData.Client.E2E.Tests</AssemblyName>
9+
<RootNamespace>Microsoft.OData.Client.E2E.Tests</RootNamespace>
710

811
<IsPackable>false</IsPackable>
912
<IsTestProject>true</IsTestProject>
13+
<SignAssembly>True</SignAssembly>
14+
<AssemblyOriginatorKeyFile>..\..\..\..\..\tools\StrongNamePublicKeys\testkey.snk</AssemblyOriginatorKeyFile>
15+
<DelaySign>True</DelaySign>
16+
</PropertyGroup>
17+
18+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19+
<OutputPath>..\..\..\bin\AnyCPU\Debug\Test\</OutputPath>
20+
<DefineConstants>DEBUG;TRACE</DefineConstants>
21+
</PropertyGroup>
22+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
23+
<OutputPath>..\..\..\bin\AnyCPU\Release\Test\</OutputPath>
24+
<DefineConstants>TRACE</DefineConstants>
25+
1026
</PropertyGroup>
1127

1228
<ItemGroup>
@@ -39,6 +55,7 @@
3955
</ItemGroup>
4056

4157
<ItemGroup>
58+
<ProjectReference Include="..\..\..\..\..\src\Microsoft.OData.Client\Microsoft.OData.Client.csproj" />
4259
<ProjectReference Include="..\..\..\Common\Microsoft.OData.E2E.TestCommon\Microsoft.OData.E2E.TestCommon.csproj" />
4360
</ItemGroup>
4461

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
//-----------------------------------------------------------------------------
2+
// <copyright file="HttpClientTests.cs" company=".NET Foundation">
3+
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
4+
// See License.txt in the project root for license information.
5+
// </copyright>
6+
//------------------------------------------------------------------------------
7+
8+
using Microsoft.AspNetCore.OData;
9+
using Microsoft.AspNetCore.OData.Batch;
10+
using Microsoft.AspNetCore.OData.Routing.Controllers;
11+
using Microsoft.Extensions.DependencyInjection;
12+
using Microsoft.OData.Client.E2E.Tests.TransportLayerTests.Server;
13+
using Microsoft.OData.E2E.TestCommon;
14+
using Microsoft.OData.E2E.TestCommon.Common.Client.EndToEnd;
15+
using Microsoft.OData.E2E.TestCommon.Common.Client.EndToEnd.Default;
16+
using Microsoft.OData.E2E.TestCommon.Common.Server.EndToEnd;
17+
using Xunit;
18+
using ClientEndToEndModel = Microsoft.OData.E2E.TestCommon.Common.Client.EndToEnd;
19+
20+
namespace Microsoft.OData.Client.E2E.Tests.TransportLayerTests
21+
{
22+
public class HttpClientTests : EndToEndTestBase<HttpClientTests.TestsStartup>
23+
{
24+
private readonly Uri _baseUri;
25+
private readonly Container _context;
26+
27+
public class TestsStartup : TestStartupBase
28+
{
29+
public override void ConfigureServices(IServiceCollection services)
30+
{
31+
services.ConfigureControllers(typeof(HttpClientController), typeof(MetadataController));
32+
33+
services.AddControllers().AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(null)
34+
.AddRouteComponents("odata", CommonEndToEndEdmModel.GetEdmModel(), new DefaultODataBatchHandler()));
35+
}
36+
}
37+
38+
public HttpClientTests(TestWebApplicationFactory<TestsStartup> fixture)
39+
: base(fixture)
40+
{
41+
_baseUri = new Uri(Client.BaseAddress, "odata/");
42+
43+
_context = new Container(_baseUri)
44+
{
45+
HttpClientFactory = HttpClientFactory
46+
};
47+
48+
ResetDataSource();
49+
}
50+
51+
[Fact]
52+
public async Task QueryForEntity_ShouldReturnResults()
53+
{
54+
var results = await _context.CreateQuery<ClientEndToEndModel.Product>("Products").ExecuteAsync();
55+
Assert.NotEmpty(results);
56+
}
57+
58+
[Fact]
59+
public async Task InsertNewEntity_ShouldInsertEntity()
60+
{
61+
_context.AddToOrders(new ClientEndToEndModel.Order { OrderId = 993, });
62+
await _context.SaveChangesAsync();
63+
64+
var createdOrderQuery = _context.Orders.ByKey(993);
65+
var createdOrder = await createdOrderQuery.GetValueAsync();
66+
Assert.Equal(993, createdOrder.OrderId);
67+
}
68+
69+
[Fact]
70+
public async Task UpdateEntityWithPatch_ShouldUpdateEntitySuccessfully()
71+
{
72+
var product = _context.Products.First();
73+
var newProductDescription = "Foo " + Guid.NewGuid().ToString();
74+
product.Description = newProductDescription;
75+
_context.UpdateObject(product);
76+
77+
await _context.SaveChangesAsync();
78+
79+
var updatedProduct = _context.Products.First();
80+
Assert.Equal(newProductDescription, updatedProduct.Description);
81+
}
82+
83+
[Fact]
84+
public async Task UpdateEntityWithReplaceUsingJson_ShouldUpdareTheEntity()
85+
{
86+
_context.Format.UseJson();
87+
88+
var product = _context.Products.First();
89+
product.Description = "Foo " + Guid.NewGuid().ToString();
90+
_context.UpdateObject(product);
91+
92+
await _context.SaveChangesAsync(SaveChangesOptions.ReplaceOnUpdate);
93+
var updateProduct = _context.Products.First();
94+
Assert.Equal(product.Description, updateProduct.Description);
95+
}
96+
97+
[Fact]
98+
public async Task DeleteEntity_ShouldDeleteTheEntity()
99+
{
100+
var computer = _context.Computers.First();
101+
Assert.Equal(-10, computer.ComputerId);
102+
_context.DeleteObject(computer);
103+
await _context.SaveChangesAsync();
104+
105+
var deletedComputer = _context.Computers.FirstOrDefault(c => c.ComputerId == -10);
106+
Assert.Null(deletedComputer);
107+
}
108+
109+
[Fact]
110+
public async Task DoingMultipleChangesUsingBatch_ShouldExecuteSuccessfully()
111+
{
112+
_context.AddToOrders(new ClientEndToEndModel.Order { OrderId = 953, });
113+
var customerToDelete = _context.Customers.First();
114+
Assert.Equal(-10, customerToDelete.CustomerId);
115+
_context.DeleteObject(customerToDelete);
116+
117+
var product = _context.Products.First();
118+
product.Description = "Foo " + Guid.NewGuid().ToString();
119+
_context.UpdateObject(product);
120+
121+
await _context.SaveChangesAsync(SaveChangesOptions.BatchWithSingleChangeset);
122+
123+
//Assert new order was created.
124+
var createdOrder = await _context.Orders.ByKey(953).GetValueAsync();
125+
Assert.Equal(953, createdOrder.OrderId);
126+
127+
//Assert customer was deleted
128+
var deletedCustomer = _context.Customers.FirstOrDefault(c => c.CustomerId == -10);
129+
Assert.Null(deletedCustomer);
130+
131+
//Assert product was updated
132+
var updatedProduct = _context.Products.First();
133+
Assert.Equal(product.Description, updatedProduct.Description);
134+
}
135+
136+
[Fact]
137+
public async Task DoingMultipleChangesWithoutBatch_ShouldExecuteSuccessfully()
138+
{
139+
_context.AddToOrders(new ClientEndToEndModel.Order { OrderId = 953, });
140+
_context.DeleteObject(_context.Customers.First());
141+
142+
var product = _context.Products.First();
143+
product.Description = "Foo " + Guid.NewGuid().ToString();
144+
_context.UpdateObject(product);
145+
146+
await _context.SaveChangesAsync();
147+
148+
//Assert new order was created.
149+
var createdOrder = await _context.Orders.ByKey(953).GetValueAsync();
150+
Assert.Equal(953, createdOrder.OrderId);
151+
152+
//Assert customer was deleted
153+
var deletedCustomer = _context.Customers.FirstOrDefault(c => c.CustomerId == -10);
154+
Assert.Null(deletedCustomer);
155+
156+
//Assert product was updated
157+
var updatedProduct = _context.Products.First();
158+
Assert.Equal(product.Description, updatedProduct.Description);
159+
}
160+
161+
[Fact]
162+
public async Task LoadProperty_ExecutesSuccessfully()
163+
{
164+
var product = _context.Products.First();
165+
166+
var response = await _context.LoadPropertyAsync(product, "Description");
167+
Assert.Equal(200, response.StatusCode);
168+
}
169+
170+
[Fact]
171+
public async Task BatchUpdatesAsync()
172+
{
173+
_context.AddObject("Products", new ClientEndToEndModel.Product { ProductId = 55443, Description = "My new product", });
174+
175+
ClientEndToEndModel.Customer customerWithCustomerInfo = null;
176+
var query = _context.Customers.Expand(c => c.Info).Where(c => c.Info != null) as DataServiceQuery<ClientEndToEndModel.Customer>;
177+
var queryResult = await query.ExecuteAsync();
178+
customerWithCustomerInfo = queryResult.First();
179+
180+
var customerInfo = customerWithCustomerInfo.Info;
181+
customerInfo.Information = "New Information " + Guid.NewGuid().ToString();
182+
_context.UpdateObject(customerInfo);
183+
184+
_context.DetachLink(customerWithCustomerInfo, "Info", customerInfo);
185+
_context.UpdateObject(customerWithCustomerInfo);
186+
187+
var response = await _context.SaveChangesAsync(SaveChangesOptions.BatchWithSingleChangeset);
188+
189+
Assert.Equal(200, response.BatchStatusCode);
190+
Assert.Equal(3, response.Count());
191+
}
192+
193+
[Fact]
194+
//Client should not append () to navigation property query URI
195+
public async Task ClientShouldNotAppendParenthesisToNavigationPropertyQueryUri()
196+
{
197+
var product = new ClientEndToEndModel.Product { ProductId = 55445, Description = "My new product" };
198+
_context.AddObject("Products", product);
199+
await _context.SaveChangesAsync();
200+
_context.Detach(product);
201+
_context.AttachTo("Products", product);
202+
//Collection
203+
var response = await _context.LoadPropertyAsync(product, "RelatedProducts");
204+
Assert.EndsWith("RelatedProducts", response.Query.RequestUri.AbsolutePath);
205+
}
206+
207+
private void ResetDataSource()
208+
{
209+
var actionUri = new Uri(_baseUri + "httpclient/Default.ResetDataSource", UriKind.Absolute);
210+
_context.Execute(actionUri, "POST");
211+
}
212+
}
213+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//-----------------------------------------------------------------------------
2+
// <copyright file="RequestMessageArgsTests.cs" company=".NET Foundation">
3+
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
4+
// See License.txt in the project root for license information.
5+
// </copyright>
6+
//------------------------------------------------------------------------------
7+
8+
using Microsoft.AspNetCore.OData;
9+
using Microsoft.AspNetCore.OData.Routing.Controllers;
10+
using Microsoft.Extensions.DependencyInjection;
11+
using Microsoft.OData.Client.E2E.Tests.TransportLayerTests.Server;
12+
using Microsoft.OData.E2E.TestCommon;
13+
using Microsoft.OData.E2E.TestCommon.Common.Client.EndToEnd.Default;
14+
using Microsoft.OData.E2E.TestCommon.Common.Server.EndToEnd;
15+
using Xunit;
16+
using ClientEndToEndModel = Microsoft.OData.E2E.TestCommon.Common.Client.EndToEnd;
17+
18+
namespace Microsoft.OData.Client.E2E.Tests.TransportLayerTests
19+
{
20+
public class RequestMessageArgsTests : EndToEndTestBase<RequestMessageArgsTests.TestsStartup>
21+
{
22+
private readonly Uri _baseUri;
23+
private readonly Container _context;
24+
25+
public class TestsStartup : TestStartupBase
26+
{
27+
public override void ConfigureServices(IServiceCollection services)
28+
{
29+
services.ConfigureControllers(typeof(RequestMessageArgsTestsController), typeof(MetadataController));
30+
31+
services.AddControllers().AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(null)
32+
.AddRouteComponents("odata", CommonEndToEndEdmModel.GetEdmModel()));
33+
}
34+
}
35+
36+
public RequestMessageArgsTests(TestWebApplicationFactory<TestsStartup> fixture)
37+
: base(fixture)
38+
{
39+
_baseUri = new Uri(Client.BaseAddress, "odata/");
40+
41+
_context = new Container(_baseUri)
42+
{
43+
HttpClientFactory = HttpClientFactory
44+
};
45+
46+
ResetDataSource();
47+
}
48+
49+
[Fact]
50+
public async Task AddingCustomHeaderToRequest_ShouldSucceed()
51+
{
52+
string headerName = "MyNewHeader";
53+
string headerValue = "MyNewHeaderValue";
54+
IODataRequestMessage lastRequestMessage = null;
55+
56+
Func<DataServiceClientRequestMessageArgs, DataServiceClientRequestMessage> configureRequest =
57+
args =>
58+
{
59+
args.Headers.Add(headerName, headerValue);
60+
return new HttpClientRequestMessage(args);
61+
};
62+
63+
_context.SendingRequest2 += (obj, args) => lastRequestMessage = args.RequestMessage;
64+
_context.Configurations.RequestPipeline.OnMessageCreating = configureRequest;
65+
66+
DataServiceQuery<ClientEndToEndModel.Product> query = _context.Products;
67+
await query.ExecuteAsync();
68+
69+
Assert.NotNull(lastRequestMessage);
70+
var header = lastRequestMessage.Headers.SingleOrDefault(h => h.Key == headerName);
71+
Assert.Equal(headerValue, header.Value);
72+
}
73+
74+
private void ResetDataSource()
75+
{
76+
var actionUri = new Uri(_baseUri + "requestmessageargs/Default.ResetDataSource", UriKind.Absolute);
77+
_context.Execute(actionUri, "POST");
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)