Skip to content

Commit

Permalink
Merge pull request #20 from rbeauchamp/feature/18
Browse files Browse the repository at this point in the history
#18: support entities with multi-column primary keys
  • Loading branch information
Richard Beauchamp committed Dec 14, 2015
2 parents aaf7c2b + b995960 commit e3aebae
Show file tree
Hide file tree
Showing 26 changed files with 734 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<LicenseUrl>https://github.com/rbeauchamp/Swashbuckle.OData/blob/master/License.txt</LicenseUrl>
<Copyright>Copyright 2015</Copyright>
<Tags>Swashbuckle Swagger SwaggerUi OData Documentation Discovery Help WebApi AspNet AspNetWebApi Docs WebHost IIS</Tags>
<Version>2.5.1</Version>
<Version>2.5.2</Version>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Swashbuckle.OData\Swashbuckle.OData.csproj" />
Expand Down
9 changes: 5 additions & 4 deletions Swashbuckle.OData.Tests/Fixtures/GetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using NUnit.Framework;
using Swashbuckle.OData.Tests.WebHost;
using Swashbuckle.Swagger;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
Expand All @@ -17,7 +18,7 @@ public async Task It_includes_the_filter_parameter()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -40,7 +41,7 @@ public async Task It_has_all_optional_odata_query_parameters()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -58,7 +59,7 @@ public async Task It_has_a_parameter_with_a_name_equal_to_the_path_name()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -78,7 +79,7 @@ public async Task It_supports_types_with_a_guid_primary_key()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand Down
13 changes: 7 additions & 6 deletions Swashbuckle.OData.Tests/Fixtures/ODataSwaggerProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Swashbuckle.Application;
using Swashbuckle.OData.Tests.WebHost;
using Swashbuckle.Swagger;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
Expand All @@ -21,7 +22,7 @@ public async Task It_applies_document_filters()
{
// Arrange
Action<SwaggerDocsConfig> config = c => c.DocumentFilter<ApplyNewHostName>();
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder, config)))
{
Expand All @@ -39,7 +40,7 @@ public async Task It_supports_multiple_odata_routes()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -55,7 +56,7 @@ public async Task It_supports_odata_routes_that_dont_map_to_a_controller()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -71,7 +72,7 @@ public async Task It_explores_the_correct_controller()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -95,7 +96,7 @@ public async Task It_supports_both_webapi_and_odata_controllers()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -121,7 +122,7 @@ public async Task It_generates_valid_swagger_2_0_json()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var response = await httpClient.GetAsync("swagger/docs/v1");
Expand Down
3 changes: 2 additions & 1 deletion Swashbuckle.OData.Tests/Fixtures/PatchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using NUnit.Framework;
using Swashbuckle.OData.Tests.WebHost;
using Swashbuckle.Swagger;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
Expand All @@ -17,7 +18,7 @@ public async Task It_has_a_body_parameter_with_a_schema()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand Down
3 changes: 2 additions & 1 deletion Swashbuckle.OData.Tests/Fixtures/PostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using NUnit.Framework;
using Swashbuckle.OData.Tests.WebHost;
using Swashbuckle.Swagger;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
Expand All @@ -16,7 +17,7 @@ public async Task It_has_a_summary()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand Down
5 changes: 3 additions & 2 deletions Swashbuckle.OData.Tests/Fixtures/PutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using NUnit.Framework;
using Swashbuckle.OData.Tests.WebHost;
using Swashbuckle.Swagger;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
Expand All @@ -16,7 +17,7 @@ public async Task It_includes_a_put_operation()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -35,7 +36,7 @@ public async Task It_does_not_exist_if_not_in_the_controller()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand Down
63 changes: 57 additions & 6 deletions Swashbuckle.OData.Tests/Fixtures/RestierTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
using System.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Owin.Hosting;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using NUnit.Framework;
using Swashbuckle.OData.Tests.WebHost;
using Swashbuckle.Swagger;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
Expand All @@ -17,7 +23,7 @@ public async Task It_supports_restier()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -37,7 +43,7 @@ public async Task It_has_a_restier_get_with_all_optional_query_parameters()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -55,7 +61,7 @@ public async Task It_has_a_restier_response_with_the_correct_edm_model_type()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -75,7 +81,7 @@ public async Task It_groups_paths_by_entity_set()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -93,7 +99,7 @@ public async Task It_has_a_restier_get_users_response_of_type_array()
using (WebApp.Start(TestWebApiStartup.BaseAddress, appBuilder => new TestWebApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient();
var httpClient = HttpClientUtils.GetHttpClient(TestWebApiStartup.BaseAddress, ODataConfig.ODataRoutePrefix);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");
Expand All @@ -109,6 +115,51 @@ public async Task It_has_a_restier_get_users_response_of_type_array()
}
}

[Test]
public async Task It_supports_entities_with_multiple_keys()
{
using (WebApp.Start(NorthwindApiStartup.BaseAddress, appBuilder => new NorthwindApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient(NorthwindApiStartup.BaseAddress);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");

// Assert
PathItem pathItem;
swaggerDocument.paths.TryGetValue("/restier/Order_Details(OrderID={OrderID}, ProductID={ProductID})", out pathItem);
var getResponse = pathItem.get.responses.SingleOrDefault(response => response.Key == "200");
getResponse.Should().NotBeNull();
}
}

[Test]
public async Task It_generates_valid_swagger_2_0_json_for_the_northwind_model()
{
using (WebApp.Start(NorthwindApiStartup.BaseAddress, appBuilder => new NorthwindApiStartup().Configuration(appBuilder)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient(NorthwindApiStartup.BaseAddress);

// Act
var response = await httpClient.GetAsync("swagger/docs/v1");

// Assert
await response.ValidateSuccessAsync();
var swaggerJson = await response.Content.ReadAsStringAsync();

var resolver = new JSchemaPreloadedResolver();
resolver.Add(new Uri("http://json-schema.org/draft-04/schema"), File.ReadAllText(@"schema-draft-v4.json"));

var swaggerSchema = File.ReadAllText(@"swagger-2.0-schema.json");
var schema = JSchema.Parse(swaggerSchema, resolver);

var swaggerJObject = JObject.Parse(swaggerJson);
IList<string> messages;
var isValid = swaggerJObject.IsValid(schema, out messages);
isValid.Should().BeTrue();
}
}
}
}
6 changes: 2 additions & 4 deletions Swashbuckle.OData.Tests/HttpClientUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@
using System.Net.Http;
using System.Net.Http.Headers;
using Flurl;
using Swashbuckle.OData.Tests.WebHost;
using SwashbuckleODataSample;

namespace Swashbuckle.OData.Tests
{
public class HttpClientUtils
{
public static HttpClient GetHttpClient()
public static HttpClient GetHttpClient(string baseAddress, string routePrefix = null)
{
var client = new HttpClient
{
BaseAddress = new Uri(TestWebApiStartup.BaseAddress.AppendPathSegment(ODataConfig.ODataRoutePrefix)),
BaseAddress = string.IsNullOrWhiteSpace(routePrefix) ? new Uri(baseAddress) : new Uri(baseAddress.AppendPathSegment(routePrefix)),
Timeout = TimeSpan.FromMilliseconds(5 * 60 * 1000)
};

Expand Down
31 changes: 31 additions & 0 deletions Swashbuckle.OData.Tests/NorthwindAPI/Category.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;

namespace NorthwindAPI.Models
{
public class Category
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Category()
{
Products = new HashSet<Product>();
}

public int CategoryID { get; set; }

[Required]
[StringLength(15)]
public string CategoryName { get; set; }

[Column(TypeName = "ntext")]
public string Description { get; set; }

[Column(TypeName = "image")]
public byte[] Picture { get; set; }

[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Product> Products { get; set; }
}
}
26 changes: 26 additions & 0 deletions Swashbuckle.OData.Tests/NorthwindAPI/CustomerDemographic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;

namespace NorthwindAPI.Models
{
public class CustomerDemographic
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public CustomerDemographic()
{
Customers = new HashSet<NorthwindCustomer>();
}

[Key]
[StringLength(10)]
public string CustomerTypeID { get; set; }

[Column(TypeName = "ntext")]
public string CustomerDesc { get; set; }

[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<NorthwindCustomer> Customers { get; set; }
}
}
Loading

0 comments on commit e3aebae

Please sign in to comment.