-
Notifications
You must be signed in to change notification settings - Fork 707
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial set of acceptance tests (#32)
- Loading branch information
1 parent
144ed88
commit f648310
Showing
92 changed files
with
3,262 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
test/Microsoft.AspNet.WebApi.Acceptance.Tests/AcceptanceTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
namespace Microsoft.Web | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net.Http; | ||
using System.Net.Http.Formatting; | ||
using System.Net.Http.Headers; | ||
using System.Threading.Tasks; | ||
using System.Web.Http; | ||
using System.Web.Http.Dispatcher; | ||
using Xunit; | ||
using static System.Net.Http.HttpMethod; | ||
using static System.String; | ||
using static System.Web.Http.IncludeErrorDetailPolicy; | ||
|
||
[Trait( "Kind", "Acceptance" )] | ||
public abstract class AcceptanceTest : IDisposable | ||
{ | ||
private sealed class FilteredControllerTypeResolver : List<Type>, IHttpControllerTypeResolver | ||
{ | ||
public ICollection<Type> GetControllerTypes( IAssembliesResolver assembliesResolver ) => this; | ||
} | ||
|
||
private const string JsonMediaType = "application/json"; | ||
private static readonly HttpMethod Patch = new HttpMethod( "PATCH" ); | ||
private readonly FilteredControllerTypeResolver filteredControllerTypes = new FilteredControllerTypeResolver(); | ||
private bool disposed; | ||
|
||
~AcceptanceTest() | ||
{ | ||
Dispose( false ); | ||
} | ||
|
||
protected AcceptanceTest() | ||
{ | ||
Configuration.IncludeErrorDetailPolicy = Always; | ||
Configuration.Services.Replace( typeof( IHttpControllerTypeResolver ), FilteredControllerTypes ); | ||
Server = new HttpServer( Configuration ); | ||
Client = new HttpClient( new HttpSimulatorHandler( Server ) ) | ||
{ | ||
BaseAddress = new Uri( "http://localhost" ), | ||
DefaultRequestHeaders = | ||
{ | ||
{ "Host", "localhost" } | ||
} | ||
}; | ||
} | ||
|
||
protected HttpConfiguration Configuration { get; } = new HttpConfiguration(); | ||
|
||
protected HttpServer Server { get; } | ||
|
||
protected HttpClient Client { get; } | ||
|
||
protected IList<Type> FilteredControllerTypes => filteredControllerTypes; | ||
|
||
protected virtual void Dispose( bool disposing ) | ||
{ | ||
if ( disposed ) | ||
{ | ||
return; | ||
} | ||
|
||
disposed = true; | ||
|
||
if ( !disposing ) | ||
{ | ||
return; | ||
} | ||
|
||
Client.Dispose(); | ||
Server.Dispose(); | ||
Configuration.Dispose(); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Dispose( true ); | ||
GC.SuppressFinalize( this ); | ||
} | ||
|
||
private HttpRequestMessage CreateRequest<TEntity>( string requestUri, TEntity entity, HttpMethod method ) | ||
{ | ||
var request = new HttpRequestMessage( method, requestUri ); | ||
|
||
if ( !Equals( entity, default( TEntity ) ) ) | ||
{ | ||
var formatter = new JsonMediaTypeFormatter(); | ||
request.Content = new ObjectContent<TEntity>( entity, formatter, JsonMediaType ); | ||
} | ||
|
||
Client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue( JsonMediaType ) ); | ||
|
||
return request; | ||
} | ||
|
||
protected void Accept( string metadata = null ) | ||
{ | ||
var mediaType = new MediaTypeWithQualityHeaderValue( JsonMediaType ); | ||
var odataMetadata = new NameValueHeaderValue( "odata.metadata" ); | ||
|
||
if ( IsNullOrEmpty( metadata ) ) | ||
{ | ||
odataMetadata.Value = "none"; | ||
} | ||
else | ||
{ | ||
switch ( metadata.ToUpperInvariant() ) | ||
{ | ||
case "NONE": | ||
case "MINIMAL": | ||
case "FULL": | ||
break; | ||
default: | ||
throw new ArgumentOutOfRangeException( nameof( metadata ), "The specified metadata value must be 'none', 'minimal', or 'full'." ); | ||
} | ||
|
||
odataMetadata.Value = metadata; | ||
} | ||
|
||
mediaType.Parameters.Add( odataMetadata ); | ||
Client.DefaultRequestHeaders.Accept.Clear(); | ||
Client.DefaultRequestHeaders.Accept.Add( mediaType ); | ||
} | ||
|
||
protected void PreferNoReturn() => Client.DefaultRequestHeaders.Add( "Prefer", "return=representation" ); | ||
|
||
protected virtual Task<HttpResponseMessage> GetAsync( string requestUri ) => Client.SendAsync( CreateRequest( requestUri, default( object ), Get ) ); | ||
|
||
protected virtual Task<HttpResponseMessage> PostAsync<TEntity>( string requestUri, TEntity entity ) => Client.SendAsync( CreateRequest( requestUri, entity, Post ) ); | ||
|
||
protected virtual Task<HttpResponseMessage> PutAsync<TEntity>( string requestUri, TEntity entity ) => Client.SendAsync( CreateRequest( requestUri, entity, Put ) ); | ||
|
||
protected virtual Task<HttpResponseMessage> PatchAsync<TEntity>( string requestUri, TEntity entity ) => Client.SendAsync( CreateRequest( requestUri, entity, Patch ) ); | ||
|
||
protected virtual Task<HttpResponseMessage> DeleteAsync( string requestUri ) => Client.SendAsync( CreateRequest( requestUri, default( object ), Delete ) ); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
test/Microsoft.AspNet.WebApi.Acceptance.Tests/Http/Basic/BasicAcceptanceTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace Microsoft.Web.Http.Basic | ||
{ | ||
using Controllers; | ||
using Microsoft.Web.Http.Routing; | ||
using System.Web.Http; | ||
using System.Web.Http.Routing; | ||
|
||
public abstract class BasicAcceptanceTest : AcceptanceTest | ||
{ | ||
protected BasicAcceptanceTest() | ||
{ | ||
var constraintResolver = new DefaultInlineConstraintResolver() | ||
{ | ||
ConstraintMap = { ["apiVersion"] = typeof( ApiVersionRouteConstraint ) } | ||
}; | ||
|
||
FilteredControllerTypes.Add( typeof( ValuesController ) ); | ||
FilteredControllerTypes.Add( typeof( Values2Controller ) ); | ||
FilteredControllerTypes.Add( typeof( HelloWorldController ) ); | ||
Configuration.AddApiVersioning( options => options.ReportApiVersions = true ); | ||
Configuration.MapHttpAttributeRoutes( constraintResolver ); | ||
Configuration.EnsureInitialized(); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
test/Microsoft.AspNet.WebApi.Acceptance.Tests/Http/Basic/Controllers/HelloWorldController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace Microsoft.Web.Http.Basic.Controllers | ||
{ | ||
using Microsoft.Web.Http; | ||
using System.Web.Http; | ||
|
||
[ApiVersion( "1.0" )] | ||
[RoutePrefix( "api/v{version:apiVersion}/helloworld" )] | ||
public class HelloWorldController : ApiController | ||
{ | ||
[Route] | ||
public IHttpActionResult Get() => Ok( new { controller = GetType().Name, version = Request.GetRequestedApiVersion().ToString() } ); | ||
|
||
[Route( "{id:int}", Name = "GetMessageById" )] | ||
public IHttpActionResult Get( int id ) => Ok( new { controller = GetType().Name, id = id, version = Request.GetRequestedApiVersion().ToString() } ); | ||
|
||
[Route] | ||
public IHttpActionResult Post() => CreatedAtRoute( "GetMessageById", new { id = 42 }, default( object ) ); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
test/Microsoft.AspNet.WebApi.Acceptance.Tests/Http/Basic/Controllers/Values2Controller.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace Microsoft.Web.Http.Basic.Controllers | ||
{ | ||
using Microsoft.Web.Http; | ||
using System.Web.Http; | ||
|
||
[ApiVersion( "2.0" )] | ||
[Route( "api/values" )] | ||
public class Values2Controller : ApiController | ||
{ | ||
public IHttpActionResult Get() => Ok( new { controller = GetType().Name, version = Request.GetRequestedApiVersion().ToString() } ); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
test/Microsoft.AspNet.WebApi.Acceptance.Tests/Http/Basic/Controllers/ValuesController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace Microsoft.Web.Http.Basic.Controllers | ||
{ | ||
using Microsoft.Web.Http; | ||
using System.Web.Http; | ||
|
||
[ApiVersion( "1.0" )] | ||
[Route( "api/values" )] | ||
public class ValuesController : ApiController | ||
{ | ||
public IHttpActionResult Get() => Ok( new { controller = GetType().Name, version = Request.GetRequestedApiVersion().ToString() } ); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
...nce.Tests/Http/Basic/given/a_query_string_versioned_ApiController_split_into_two_types.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
namespace given | ||
{ | ||
using FluentAssertions; | ||
using Microsoft.Web; | ||
using Microsoft.Web.Http.Basic; | ||
using Microsoft.Web.Http.Basic.Controllers; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using static System.Net.HttpStatusCode; | ||
|
||
public class _a_query_string_versioned_ApiController_split_into_two_types : BasicAcceptanceTest | ||
{ | ||
[Theory] | ||
[InlineData( nameof( ValuesController ), "1.0" )] | ||
[InlineData( nameof( Values2Controller ), "2.0" )] | ||
public async Task _get_should_return_200( string controller, string apiVersion ) | ||
{ | ||
// arrange | ||
|
||
|
||
// act | ||
var response = await GetAsync( $"api/values?api-version={apiVersion}" ).EnsureSuccessStatusCode(); | ||
var content = await response.Content.ReadAsAsync<IDictionary<string, string>>(); | ||
|
||
// assert | ||
response.Headers.GetValues( "api-supported-versions" ).Single().Should().Be( "1.0, 2.0" ); | ||
content.ShouldBeEquivalentTo( | ||
new Dictionary<string, string>() | ||
{ | ||
["controller"] = controller, | ||
["version"] = apiVersion | ||
} ); | ||
} | ||
|
||
[Fact] | ||
public async Task _get_should_return_400_when_version_is_unsupported() | ||
{ | ||
// arrange | ||
|
||
|
||
// act | ||
var response = await GetAsync( "api/values?api-version=3.0" ); | ||
var content = await response.Content.ReadAsAsync<OneApiErrorResponse>(); | ||
|
||
// assert | ||
response.StatusCode.Should().Be( BadRequest ); | ||
content.Error.Code.Should().Be( "UnsupportedApiVersion" ); | ||
} | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
...icrosoft.AspNet.WebApi.Acceptance.Tests/Http/Basic/given/a_url_versioned_ApiController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
namespace given | ||
{ | ||
using FluentAssertions; | ||
using Microsoft.Web; | ||
using Microsoft.Web.Http.Basic; | ||
using Microsoft.Web.Http.Basic.Controllers; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using static System.Net.HttpStatusCode; | ||
|
||
public class _a_url_versioned_ApiController : BasicAcceptanceTest | ||
{ | ||
[Theory] | ||
[InlineData( "api/v1/helloworld", null )] | ||
[InlineData( "api/v1/helloworld/42", "42" )] | ||
public async Task _get_should_return_200( string requestUrl, string id ) | ||
{ | ||
// arrange | ||
var body = new Dictionary<string, string>() | ||
{ | ||
["controller"] = nameof( HelloWorldController ), | ||
["version"] = "1" | ||
}; | ||
|
||
if ( !string.IsNullOrEmpty( id ) ) | ||
{ | ||
body["id"] = id; | ||
} | ||
|
||
// act | ||
var response = await GetAsync( requestUrl ).EnsureSuccessStatusCode(); | ||
var content = await response.Content.ReadAsAsync<IDictionary<string, string>>(); | ||
|
||
// assert | ||
response.Headers.GetValues( "api-supported-versions" ).Single().Should().Be( "1.0" ); | ||
content.ShouldBeEquivalentTo( body ); | ||
} | ||
|
||
[Fact] | ||
public async Task _post_should_return_201() | ||
{ | ||
// arrange | ||
var entity = default( object ); | ||
|
||
// act | ||
var response = await PostAsync( "api/v1/helloworld", entity ).EnsureSuccessStatusCode(); | ||
|
||
// assert | ||
response.Headers.Location.Should().Be( new Uri( "http://localhost/api/v1/helloworld/42" ) ); | ||
} | ||
|
||
[Fact] | ||
public async Task _get_should_return_400_when_version_is_unsupported() | ||
{ | ||
// arrange | ||
|
||
|
||
// act | ||
var response = await GetAsync( "api/v2/helloworld" ); | ||
var content = await response.Content.ReadAsAsync<OneApiErrorResponse>(); | ||
|
||
// assert | ||
response.StatusCode.Should().Be( BadRequest ); | ||
content.Error.Code.Should().Be( "UnsupportedApiVersion" ); | ||
} | ||
} | ||
} |
Oops, something went wrong.