Skip to content

Commit

Permalink
Merge pull request OData#507 from mirsking/issue#505
Browse files Browse the repository at this point in the history
fix issue 505 and add patch test cases, also support key as segment and add CORS header
  • Loading branch information
chinadragon0515 authored Sep 2, 2016
2 parents aac986b + 929ccf7 commit b113b14
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ private void SetValues(DbEntityEntry dbEntry, DataModificationItem item, Type re
propertyPair.Key));
}

value = Activator.CreateInstance(type);
value = propertyEntry.CurrentValue;
SetValues(value, type, dic);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ protected void TestPostStatusCodeIs(string uriStringAfterServiceRoot, int status
Assert.Equal(statusCode, response.StatusCode);
}
}

protected async void TestPatchStatusCodeIs(string uriStringAfterServiceRoot, string patchContent, HttpStatusCode statusCode)
{
var requestUri = string.Format("{0}/{1}", this.ServiceBaseUri, uriStringAfterServiceRoot);
var request = new HttpRequestMessage(new HttpMethod("PATCH"), requestUri);

request.Content = new StringContent(patchContent);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

HttpClient client = new HttpClient();
HttpResponseMessage response = await client.SendAsync(request);

Assert.Equal(statusCode, response.StatusCode);
}

#endregion

protected void ResetDataSource()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<HintPath>..\..\..\packages\FluentAssertions.4.13.0\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.OData.Client, Version=6.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.OData.Client.6.15.0\lib\net40\Microsoft.OData.Client.dll</HintPath>
<Private>True</Private>
Expand All @@ -96,6 +97,10 @@
<HintPath>..\..\..\packages\Microsoft.Spatial.6.15.0\lib\portable-net45+win+wpa81\Microsoft.Spatial.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ServiceModel.Web" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using Microsoft.OData.Client;
using Microsoft.OData.Core;
using Microsoft.OData.Service.Sample.Trippin.Models;
using Newtonsoft.Json;
using Xunit;

namespace Microsoft.OData.Service.Sample.Tests
Expand Down Expand Up @@ -295,11 +297,11 @@ public void CURDComputedImmutableProperty()
// Query the updated entity
this.TestClientContext.Detach(employee);
employee = this.TestClientContext.Orders.Where(e => e.PersonId == personId && e.OrderId == orderId).First();

// both computed property and immutable property should not have new value
Assert.Equal(400, employee.Price);
Assert.NotEqual("ShouldBeIgnored2", employee.ComputedProperty);

// Immutable property has value set during insert.
Assert.NotEqual("ShouldBeIgnored2", employee.ImmutableProperty);
Assert.Equal("ShouldNotBeIgnored", employee.ImmutableProperty);
Expand Down Expand Up @@ -409,9 +411,9 @@ public void UQProperty()
Assert.Equal("Cooper", lastName);

// Update a property
Dictionary<string, string> headers = new Dictionary<string, string>()
Dictionary<string, string> headers = new Dictionary<string, string>()
{
{ "Content-Type", "application/json" }
{ "Content-Type", "application/json" }
};

HttpWebRequestMessage request = new HttpWebRequestMessage(
Expand Down Expand Up @@ -566,12 +568,12 @@ public void QueryOptions()
// skip
people2 = this.TestClientContext.People.Skip((int)(personId - 1)).ToList();
Assert.Equal(personId, people2.First().PersonId);

// count
var countQuery = this.TestClientContext.People.IncludeTotalCount().Skip(1).Take(2) as DataServiceQuery<Person>;
var response = countQuery.Execute() as QueryOperationResponse<Person>;
Assert.Equal(response.TotalCount, 14);

// count with expand
countQuery = this.TestClientContext.People.IncludeTotalCount().Expand("Friends").Skip(1).Take(2) as DataServiceQuery<Person>;
response = countQuery.Execute() as QueryOperationResponse<Person>;
Expand Down Expand Up @@ -638,7 +640,7 @@ public void FilterBuiltInDateFunctions()
Assert.True(flight1.All(f => f.StartsAt.Second == startDate.Second));

// Following built-in functions are not supported now.
// fractionalseconds
// fractionalseconds
// date
// time
// totaloffsetminutes
Expand Down Expand Up @@ -1119,5 +1121,32 @@ public void ConventionBasedChangeSetAuthorizerTest()
"The current user does not have permission to delete entities from the EntitySet 'Trips'.",
clientException.Message);
}

[Fact]
public void TestPatchSuccessfully()
{
// Get origin content.
var uriStringAfterServiceRoot = "Orders(PersonId=1, OrderId=1)";
var originContent = default(string);
Action<string> getContent = p => originContent = p;
TestGetPayload(uriStringAfterServiceRoot, getContent);

// Patch it.
var changedDescription = "TestDescription";
var changedNormalProperty = "TestNormalProperty";
string patchContent =
string.Format(
"{{\n \"Description\": \"{0}\",\n \"NormalOrderDetail\": {{\n \"NormalProperty\": \"{1}\"\n }}\n}}",
changedDescription,
changedNormalProperty);
TestPatchStatusCodeIs(uriStringAfterServiceRoot, patchContent, HttpStatusCode.NoContent);

// Test patch results.
dynamic content = JsonConvert.DeserializeObject(originContent);
content.Description = changedDescription;
content.NormalOrderDetail.NormalProperty = changedNormalProperty;
string changedContent = JsonConvert.SerializeObject(content);
TestGetPayloadContains(uriStringAfterServiceRoot, changedContent);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Net;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Xunit;

namespace Microsoft.OData.Service.Sample.Tests
Expand Down Expand Up @@ -44,8 +48,8 @@ public class TrippinInMemoryE2ETest : TrippinInMemoryE2ETestBase
// TODO since webapi doesnot handle query with null, the trips here in the datasource are actually not null.
[InlineData("/People('clydeguess')/Trips", 200)]
// collection of navigation property's property and navigation property has null value
// TODO should be bad request 400 as this is not allowed, 404 is returned by WebApi Route Match method. 500 is returned actually.
[InlineData("/People('willieashmore')/Friends/MiddleName", 500)]
// TODO should be bad request 400 as this is not allowed, 404 is returned by WebApi Route Match method. (404 is returned when key-as-segment, otherwise, 500 will be returned.)
[InlineData("/People('willieashmore')/Friends/MiddleName", 404)]
public void QueryPropertyWithNullValueStatusCode(string url, int expectedCode)
{
TestGetStatusCodeIs(url, expectedCode);
Expand Down Expand Up @@ -77,8 +81,8 @@ public void QueryPropertyWithNullValueStatusCode(string url, int expectedCode)
// collection of navigation property
[InlineData("/People('NoneExist')/Friends", 404)]
// collection of navigation property's property
// TODO should be bad request 400 as this is not allowed, 404 is returned by WebApi Route Match method. 500 is returned actually.
[InlineData("/People('NoneExist')/Friends/MiddleName", 500)]
// TODO should be bad request 400 as this is not allowed, 404 is returned by WebApi Route Match method. (404 is returned when key-as-segment, otherwise, 500 will be returned.)
[InlineData("/People('NoneExist')/Friends/MiddleName", 404)]
public void QueryPropertyWithNonExistEntity(string url, int expectedCode)
{
TestGetStatusCodeIs(url, expectedCode);
Expand Down Expand Up @@ -158,5 +162,46 @@ public void TestRawValuedEnumPropertyAccess()
{
TestGetPayloadIs("People('russellwhyte')/FavoriteFeature/$value", "Feature1");
}

[Fact]
public void TestPatchSuccessfully()
{
// Get origin content and sessionId.
var uriStringAfterServiceRoot = "Airports('KLAX')";
var originContent = default(string);
Action<string> getContent = p => originContent = p;
TestGetPayload(uriStringAfterServiceRoot, getContent);
var sessionId = GetSessionIdFromResponse(originContent);
Assert.NotNull(sessionId);

// Patch it.
uriStringAfterServiceRoot = string.Format(@"(S({0}))/{1}", sessionId, uriStringAfterServiceRoot);
var changedRegion = "TestRegion";
var changedAddress = "1 World Way, Los Angeles, CA, 90045";
string patchContent =
string.Format(
"{{\r\n \"Location\":{{\r\n \"Address\":\"{0}\",\r\n \"City\":{{\r\n \"Region\":\"{1}\"\r\n }}\r\n }}\r\n}}",
changedAddress,
changedRegion);
TestPatchStatusCodeIs(uriStringAfterServiceRoot, patchContent, HttpStatusCode.NoContent);

// Test patch results.
dynamic content = JsonConvert.DeserializeObject(originContent);
content.Location.Address = changedAddress;
content.Location.City.Region = changedRegion;
string changedContent = JsonConvert.SerializeObject(content);
TestGetPayloadContains(uriStringAfterServiceRoot, changedContent);
}

private static string GetSessionIdFromResponse(string response)
{
var match = Regex.Match(response, @"/\(S\((\w+)\)\)");
if (match.Success)
{
return match.Groups[1].Value;
}

return default(string);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<package id="Microsoft.OData.Core" version="6.15.0" targetFramework="net45" />
<package id="Microsoft.OData.Edm" version="6.15.0" targetFramework="net45" />
<package id="Microsoft.Spatial" version="6.15.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="xunit" version="2.1.0" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
<package id="xunit.assert" version="2.1.0" targetFramework="net45" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public OrderDetail()

public string NormalProperty { get; set; }

public string AnotherNormalProperty { get; set; }

public string ComputedProperty { get; set; }

public string ImmutableProperty { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,11 @@ public static void ResetDataSource()
OrderId = 1,
Description = "Person 1 Order 1",
Price = 200,
NormalOrderDetail = new OrderDetail(),
NormalOrderDetail = new OrderDetail()
{
NormalProperty = "NormalProperty",
AnotherNormalProperty = "AnotherNormalProperty"
},
ComputedOrderDetail = new OrderDetail(),
ImmutableOrderDetail = new OrderDetail()
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Extensions;
using Microsoft.OData.Service.Sample.TrippinInMemory.Api;
using Microsoft.Restier.Publishers.OData;
using Microsoft.Restier.Publishers.OData.Batch;
Expand All @@ -13,9 +14,10 @@ public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
RegisterTrippin(config, GlobalConfiguration.DefaultServer);
config.SetUseVerboseErrors(true);
config.MessageHandlers.Add(new ETagMessageHandler());
config.SetUrlKeyDelimiter(ODataUrlKeyDelimiter.Slash);
RegisterTrippin(config, GlobalConfiguration.DefaultServer);
}

public static async void RegisterTrippin(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
<uri>
<schemeSettings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private static void SetValues(object instance, Type type, IReadOnlyDictionary<st

if (dic != null)
{
value = Activator.CreateInstance(propertyInfo.PropertyType);
value = propertyInfo.GetValue(instance);
SetValues(value, propertyInfo.PropertyType, dic);
}
else if (propertyInfo.PropertyType.IsGenericType)
Expand Down

0 comments on commit b113b14

Please sign in to comment.