Skip to content

Implicit API Minor Version Fix #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/Common/ApiVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ private static void RequireValidStatus( string status )
/// <value>The minor version number or <c>null</c>.</value>
public int? MinorVersion { get; }

private int ImpliedMinorVersion => MinorVersion ?? 0;

/// <summary>
/// Gets the optional version status.
/// </summary>
Expand Down Expand Up @@ -325,8 +327,14 @@ private void AppendMajorAndMinorVersion( StringBuilder text, IFormatProvider for
}

text.Append( MajorVersion.Value.ToString( formatProvider ) );

if ( MinorVersion == null )
{
return;
}

text.Append( '.' );
text.Append( ( MinorVersion ?? 0 ).ToString( formatProvider ) );
text.Append( MinorVersion.Value.ToString( formatProvider ) );
}
else if ( MinorVersion != null )
{
Expand Down Expand Up @@ -470,7 +478,7 @@ public bool Equals( ApiVersion other )

return Nullable.Equals( GroupVersion, other.GroupVersion ) &&
Nullable.Equals( MajorVersion, other.MajorVersion ) &&
Nullable.Equals( MinorVersion, other.MinorVersion ) &&
ImpliedMinorVersion.Equals( other.ImpliedMinorVersion ) &&
string.Equals( Status, other.Status, StringComparison.OrdinalIgnoreCase );
}

Expand Down Expand Up @@ -498,7 +506,7 @@ public virtual int CompareTo( ApiVersion other )

if ( result == 0 )
{
result = Nullable.Compare( MinorVersion, other.MinorVersion );
result = ImpliedMinorVersion.CompareTo( other.ImpliedMinorVersion );

if ( result == 0 )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ private static ApiVersion GetApiVersionFromRoutePrefix( HttpRequestMessage reque
continue;
}

requestedVersion = AddMinorVersionIfNeeded( requestedVersion );
request.SetRequestedApiVersion( requestedVersion );
return requestedVersion;
}
Expand All @@ -86,45 +85,6 @@ private static bool TryExtractApiVersionFromSegment( string segment, out ApiVers
return TryParse( text, out apiVersion );
}

private static ApiVersion AddMinorVersionIfNeeded( ApiVersion requestedVersion )
{
Contract.Requires( requestedVersion != null );
Contract.Ensures( Contract.Result<ApiVersion>() != null );

if ( requestedVersion.MinorVersion != null )
{
return requestedVersion;
}

if ( requestedVersion.MajorVersion == null )
{
return requestedVersion;
}

var major = requestedVersion.MajorVersion.Value;

if ( requestedVersion.GroupVersion == null )
{
if ( requestedVersion.Status == null )
{
return new ApiVersion( major, 0 );
}
else
{
return new ApiVersion( major, 0, requestedVersion.Status );
}
}

var group = requestedVersion.GroupVersion.Value;

if ( requestedVersion.Status == null )
{
return new ApiVersion( group, major, 0 );
}

return new ApiVersion( group, major, 0, requestedVersion.Status );
}

/// <summary>
/// Gets the API version matched by the current OData path route constraint.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,8 @@ public bool Match( HttpRequestMessage request, IHttpRoute route, string paramete
return false;
}

requestedVersion = DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( requestedVersion );
request.SetRequestedApiVersion( requestedVersion );
return true;
}

private static ApiVersion DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( ApiVersion requestedVersion )
{
Contract.Requires( requestedVersion != null );
Contract.Ensures( Contract.Result<ApiVersion>() != null );

if ( requestedVersion.MajorVersion == null )
{
return requestedVersion;
}

if ( requestedVersion.MinorVersion == null )
{
return new ApiVersion( requestedVersion.GroupVersion, requestedVersion.MajorVersion, new int?( 0 ), requestedVersion.Status );
}

return requestedVersion;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,8 @@ public bool Match( HttpContext httpContext, IRouter route, string routeKey, Rout
return false;
}

requestedVersion = DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( requestedVersion );
httpContext.SetRequestedApiVersion( requestedVersion );
return true;
}

private static ApiVersion DefaultMinorVersionToZeroWhenOnlyMajorVersionIsSpecified( ApiVersion requestedVersion )
{
Contract.Requires( requestedVersion != null );
Contract.Ensures( Contract.Result<ApiVersion>() != null );

if ( requestedVersion.MajorVersion == null )
{
return requestedVersion;
}

if ( requestedVersion.MinorVersion == null )
{
return new ApiVersion( requestedVersion.GroupVersion, requestedVersion.MajorVersion, new int?( 0 ), requestedVersion.Status );
}

return requestedVersion;
}
}
}
64 changes: 62 additions & 2 deletions test/Microsoft.AspNet.WebApi.Versioning.Tests/ApiVersionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,18 @@ public void is_valid_status_should_return_false_for_invalid_status( string statu
[Theory]
[InlineData( "2013-08-06", "2013-08-06", null, null, null )]
[InlineData( "2013-08-06-Alpha", "2013-08-06", null, null, "Alpha" )]
[InlineData( "1", null, 1, null, null )]
[InlineData( "1.1", null, 1, 1, null )]
[InlineData( "1-Alpha", null, 1, null, "Alpha" )]
[InlineData( "1.1-Alpha", null, 1, 1, "Alpha" )]
[InlineData( "2013-08-06.1", "2013-08-06", 1, null, null )]
[InlineData( "2013-08-06.1.1", "2013-08-06", 1, 1, null )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06", 1, null, "Alpha" )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06", 1, 1, "Alpha" )]
public void parse_should_return_expected_result( string text, string groupVersionValue, int? majorVersion, int? minorVersion, string status )
{
// arrange
var groupVersion = groupVersionValue == null ? null : new DateTime?( DateTime.Parse( groupVersionValue ) );
var groupVersion = groupVersionValue == null ? null : new DateTime?( Parse( groupVersionValue ) );

// act
var apiVersion = ApiVersion.Parse( text );
Expand Down Expand Up @@ -233,9 +237,13 @@ public void parse_should_throw_format_exception_for_invalid_text( string text, s
[Theory]
[InlineData( "2013-08-06", "2013-08-06", null, null, null )]
[InlineData( "2013-08-06-Alpha", "2013-08-06", null, null, "Alpha" )]
[InlineData( "1", null, 1, null, null )]
[InlineData( "1.1", null, 1, 1, null )]
[InlineData( "1-Alpha", null, 1, null, "Alpha" )]
[InlineData( "1.1-Alpha", null, 1, 1, "Alpha" )]
[InlineData( "2013-08-06.1", "2013-08-06", 1, null, null )]
[InlineData( "2013-08-06.1.1", "2013-08-06", 1, 1, null )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06", 1, null, "Alpha" )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06", 1, 1, "Alpha" )]
public void try_parse_should_return_expected_api_version( string text, string groupVersionValue, int? majorVersion, int? minorVersion, string status )
{
Expand Down Expand Up @@ -278,9 +286,12 @@ public void try_parse_should_return_false_when_text_is_invalid( string text )
[Theory]
[InlineData( "2013-08-06" )]
[InlineData( "2013-08-06-Alpha" )]
[InlineData( "1" )]
[InlineData( "1.1" )]
[InlineData( "1.1-Alpha" )]
[InlineData( "2013-08-06.1" )]
[InlineData( "2013-08-06.1.1" )]
[InlineData( "2013-08-06.1-Alpha" )]
[InlineData( "2013-08-06.1.1-Alpha" )]
public void to_string_should_return_expected_string( string text )
{
Expand Down Expand Up @@ -362,9 +373,13 @@ public void to_string_with_format_provider_should_throw_format_exception_when_fo
[Theory]
[InlineData( "2013-08-06" )]
[InlineData( "2013-08-06-Alpha" )]
[InlineData( "1" )]
[InlineData( "1.1" )]
[InlineData( "1-Alpha" )]
[InlineData( "1.1-Alpha" )]
[InlineData( "2013-08-06.1" )]
[InlineData( "2013-08-06.1.1" )]
[InlineData( "2013-08-06.1-Alpha" )]
[InlineData( "2013-08-06.1.1-Alpha" )]
public void equals_should_return_true_when_api_versions_are_equal( string text )
{
Expand All @@ -382,9 +397,13 @@ public void equals_should_return_true_when_api_versions_are_equal( string text )
[Theory]
[InlineData( "2013-08-06" )]
[InlineData( "2013-08-06-Alpha" )]
[InlineData( "1" )]
[InlineData( "1.1" )]
[InlineData( "1-Alpha" )]
[InlineData( "1.1-Alpha" )]
[InlineData( "2013-08-06.1" )]
[InlineData( "2013-08-06.1.1" )]
[InlineData( "2013-08-06.1-Alpha" )]
[InlineData( "2013-08-06.1.1-Alpha" )]
public void equals_override_should_return_true_when_api_versions_are_equal( string text )
{
Expand All @@ -402,9 +421,13 @@ public void equals_override_should_return_true_when_api_versions_are_equal( stri
[Theory]
[InlineData( "2013-08-06" )]
[InlineData( "2013-08-06-Alpha" )]
[InlineData( "1" )]
[InlineData( "1.1" )]
[InlineData( "1-Alpha" )]
[InlineData( "1.1-Alpha" )]
[InlineData( "2013-08-06.1" )]
[InlineData( "2013-08-06.1.1" )]
[InlineData( "2013-08-06.1-Alpha" )]
[InlineData( "2013-08-06.1.1-Alpha" )]
public void X3DX3D_should_return_true_when_api_versions_are_equal( string text )
{
Expand Down Expand Up @@ -448,7 +471,7 @@ public void equals_override_should_return_false_when_api_versions_are_not_equal(
}

[Fact]
public void X21X3D_should_return_true_when_api_versions_are_not_equal()
public void ne_should_return_true_when_api_versions_are_not_equal()
{
// arrange
var v1 = new ApiVersion( Today );
Expand All @@ -468,12 +491,17 @@ public void X21X3D_should_return_true_when_api_versions_are_not_equal()
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", 0 )]
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", 1 )]
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", -1 )]
[InlineData( "1", "1", 0 )]
[InlineData( "1", "1.0", 0 )]
[InlineData( "1.1", "1.1", 0 )]
[InlineData( "2.0", "1.1", 1 )]
[InlineData( "1.1", "2.0", -1 )]
[InlineData( "1-Alpha", "1-Alpha", 0 )]
[InlineData( "1-Alpha", "1.0-Alpha", 0 )]
[InlineData( "1.1-Alpha", "1.1-Alpha", 0 )]
[InlineData( "1.1-Beta", "1.1-Alpha", 1 )]
[InlineData( "1.1-Alpha", "1.1-Beta", -1 )]
[InlineData( "2013-08-06.1", "2013-08-06.1.0", 0 )]
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", 0 )]
[InlineData( "2013-08-06.2", "2013-08-06.1.1", 1 )]
[InlineData( "2013-08-06.1", "2013-08-06.1.1", -1 )]
Expand Down Expand Up @@ -502,15 +530,23 @@ public void api_version_comparisons_should_return_expected_result( string versio
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", false )]
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", false )]
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", true )]
[InlineData( "1", "1", false )]
[InlineData( "1", "1.0", false )]
[InlineData( "1.1", "1.1", false )]
[InlineData( "2.0", "1.1", false )]
[InlineData( "1.1", "2.0", true )]
[InlineData( "1-Alpha", "1-Alpha", false )]
[InlineData( "1-Alpha", "1.0-Alpha", false )]
[InlineData( "1.1-Alpha", "1.1-Alpha", false )]
[InlineData( "1.1-Beta", "1.1-Alpha", false )]
[InlineData( "1.1-Alpha", "1.1-Beta", true )]
[InlineData( "2013-08-06.1", "2013-08-06.1", false )]
[InlineData( "2013-08-06.1", "2013-08-06.1.0", false )]
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", false )]
[InlineData( "2013-08-06.2", "2013-08-06.1.1", false )]
[InlineData( "2013-08-06.1", "2013-08-06.1.1", true )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", false )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", false )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", false )]
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", false )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", true )]
Expand Down Expand Up @@ -538,15 +574,23 @@ public void api_version_1_lt_api_version_2_should_return_expected_result( string
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", true )]
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", false )]
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", true )]
[InlineData( "1", "1", true )]
[InlineData( "1", "1.0", true )]
[InlineData( "1.1", "1.1", true )]
[InlineData( "2.0", "1.1", false )]
[InlineData( "1.1", "2.0", true )]
[InlineData( "1-Alpha", "1-Alpha", true )]
[InlineData( "1-Alpha", "1.0-Alpha", true )]
[InlineData( "1.1-Alpha", "1.1-Alpha", true )]
[InlineData( "1.1-Beta", "1.1-Alpha", false )]
[InlineData( "1.1-Alpha", "1.1-Beta", true )]
[InlineData( "2013-08-06.1", "2013-08-06.1", true )]
[InlineData( "2013-08-06.1", "2013-08-06.1.0", true )]
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", true )]
[InlineData( "2013-08-06.2", "2013-08-06.1.1", false )]
[InlineData( "2013-08-06.1", "2013-08-06.1.1", true )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", true )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", true )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", true )]
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", false )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", true )]
Expand Down Expand Up @@ -574,15 +618,23 @@ public void api_version_1_le_api_version_2_should_return_expected_result( string
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", false )]
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", true )]
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", false )]
[InlineData( "1", "1", false )]
[InlineData( "1", "1.0", false )]
[InlineData( "1.1", "1.1", false )]
[InlineData( "2.0", "1.1", true )]
[InlineData( "1.1", "2.0", false )]
[InlineData( "1-Alpha", "1-Alpha", false )]
[InlineData( "1-Alpha", "1.0-Alpha", false )]
[InlineData( "1.1-Alpha", "1.1-Alpha", false )]
[InlineData( "1.1-Beta", "1.1-Alpha", true )]
[InlineData( "1.1-Alpha", "1.1-Beta", false )]
[InlineData( "2013-08-06.1", "2013-08-06.1", false )]
[InlineData( "2013-08-06.1", "2013-08-06.1.0", false )]
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", false )]
[InlineData( "2013-08-06.2", "2013-08-06.1.1", true )]
[InlineData( "2013-08-06.1", "2013-08-06.1.1", false )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", false )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", false )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", false )]
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", true )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", false )]
Expand Down Expand Up @@ -610,15 +662,23 @@ public void api_version_1_gt_api_version_2_should_return_expected_result( string
[InlineData( "2013-08-06-Alpha", "2013-08-06-Alpha", true )]
[InlineData( "2013-08-06-Beta", "2013-08-06-Alpha", true )]
[InlineData( "2013-08-06-Alpha", "2013-08-06-Beta", false )]
[InlineData( "1", "1", true )]
[InlineData( "1", "1.0", true )]
[InlineData( "1.1", "1.1", true )]
[InlineData( "2.0", "1.1", true )]
[InlineData( "1.1", "2.0", false )]
[InlineData( "1-Alpha", "1-Alpha", true )]
[InlineData( "1-Alpha", "1.0-Alpha", true )]
[InlineData( "1.1-Alpha", "1.1-Alpha", true )]
[InlineData( "1.1-Beta", "1.1-Alpha", true )]
[InlineData( "1.1-Alpha", "1.1-Beta", false )]
[InlineData( "2013-08-06.1", "2013-08-06.1", true )]
[InlineData( "2013-08-06.1", "2013-08-06.1.0", true )]
[InlineData( "2013-08-06.1.1", "2013-08-06.1.1", true )]
[InlineData( "2013-08-06.2", "2013-08-06.1.1", true )]
[InlineData( "2013-08-06.1", "2013-08-06.1.1", false )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1-Alpha", true )]
[InlineData( "2013-08-06.1-Alpha", "2013-08-06.1.0-Alpha", true )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Alpha", true )]
[InlineData( "2013-08-06.1.1-Beta", "2013-08-06.1.1-Alpha", true )]
[InlineData( "2013-08-06.1.1-Alpha", "2013-08-06.1.1-Beta", false )]
Expand Down