Issue #937: Adding functional tests for Filters.

This commit is contained in:
sornaks 2014-10-05 19:08:21 -07:00
parent e985c22528
commit 2c4b3dd3fc
19 changed files with 509 additions and 0 deletions

View File

@ -55,5 +55,154 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
},
filters);
}
[Fact]
public async Task AnonymousUsersAreBlocked()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/Anonymous/GetHelloWorld");
// Assert
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}
[Fact]
public async Task CanAuthorizeParticularUsers()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/AuthorizeUser/ReturnHelloWorldOnlyForAuthorizedUser");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("Hello World!", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ExceptionFilterHandlesAnException()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/Exception/GetError?error=RandomError");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("GlobalExceptionFilter.OnException", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ServiceFilterUsesRegisteredServicesAsFilter()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/RandomNumber/GetRandomNumber");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("4", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ServiceFilterThrowsIfServiceIsNotRegistered()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var url = "http://localhost/RandomNumber/GetAuthorizedRandomNumber";
// Act & Assert
await Assert.ThrowsAsync<Exception>(() => client.GetAsync(url));
}
[Fact]
public async Task TypeFilterInitializesArguments()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var url = "http://localhost/RandomNumber/GetModifiedRandomNumber?randomNumber=10";
// Act
var response = await client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("22", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task TypeFilterThrowsIfServicesAreNotRegistered()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var url = "http://localhost/RandomNumber/GetHalfOfModifiedRandomNumber?randomNumber=3";
// Act & Assert
await Assert.ThrowsAsync<Exception>(() => client.GetAsync(url));
}
[Fact]
public async Task ActionFilterOverridesActionExecuted()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/XmlSerializer/GetDummyClass?sampleInput=10");
//Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ResultFilterOverridesOnResultExecuting()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/DummyClass/GetDummyClass");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>120</SampleInt></DummyClass>",
await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ResultFilterOverridesOnResultExecuted()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/DummyClass/GetEmptyActionResult");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = response.Headers.GetValues("OnResultExecuted");
Assert.Equal(new string[] { "ResultExecutedSuccessfully" }, result);
}
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
[BlockAnonymous]
public class AnonymousController : Controller
{
public string GetHelloWorld()
{
return "Hello World!";
}
}
}

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
[AuthorizeUser]
public class AuthorizeUserController : Controller
{
[Authorize("Permission", "CanViewPage")]
public string ReturnHelloWorldOnlyForAuthorizedUser()
{
return "Hello World!";
}
}
}

View File

@ -0,0 +1,35 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class DummyClassController : Controller
{
[ModifyResultsFilter]
public DummyClass GetDummyClass()
{
return new DummyClass()
{
SampleInt = 10
};
}
[AddHeader]
public IActionResult GetEmptyActionResult()
{
return new TestActionResult();
}
}
public class TestActionResult : IActionResult
{
public Task ExecuteResultAsync(ActionContext context)
{
return Task.FromResult(true);
}
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class ExceptionController : Controller
{
public string GetError(string error)
{
throw new InvalidOperationException(error);
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class RandomNumberController : Controller
{
[ServiceFilter(typeof(RandomNumberFilter))]
public int GetRandomNumber()
{
return 2;
}
[ServiceFilter(typeof(AuthorizeUserAttribute))]
public int GetAuthorizedRandomNumber()
{
return 2;
}
[TypeFilter(typeof(RandomNumberProvider))]
public int GetModifiedRandomNumber(int randomNumber)
{
return randomNumber / 2;
}
[TypeFilter(typeof(ModifiedRandomNumberProvider))]
public int GetHalfOfModifiedRandomNumber(int randomNumber)
{
return randomNumber / 2;
}
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
[SerializationActionFilter]
public class XmlSerializerController : Controller
{
public DummyClass GetDummyClass(int sampleInput)
{
return new DummyClass { SampleInt = sampleInput };
}
}
}

View File

@ -0,0 +1,19 @@
// Copyright(c) Microsoft Open Technologies, Inc.All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Text;
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class AddHeaderAttribute : ResultFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext context)
{
context.HttpContext.Response.Headers.Add(
"OnResultExecuted", new string[] { "ResultExecutedSuccessfully" });
base.OnResultExecuted(context);
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using System.Security.Claims;
namespace FiltersWebSite
{
public class AuthorizeUserAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(AuthorizationContext context)
{
context.HttpContext.User = new ClaimsPrincipal(
new ClaimsIdentity(
new Claim[] {
new Claim("Permission", "CanViewPage"),
new Claim(ClaimTypes.Role, "Administrator"),
new Claim(ClaimTypes.NameIdentifier, "John")},
"Basic"));
}
}
}

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class BlockAnonymous : AuthorizationFilterAttribute
{
public override void OnAuthorization(AuthorizationContext context)
{
if (!HasAllowAnonymous(context))
{
var user = context.HttpContext.User;
var userIsAnonymous =
user == null ||
user.Identity == null ||
!user.Identity.IsAuthenticated;
if (userIsAnonymous)
{
base.Fail(context);
}
}
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class ModifiedRandomNumberProvider : IActionFilter
{
private DummyService _dummyService;
public ModifiedRandomNumberProvider(DummyService dummyService)
{
_dummyService = dummyService;
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
context.ActionArguments["randomNumber"] = _dummyService.RandomNumber;
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class ModifyResultsFilterAttribute : ResultFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
var objResult = context.Result as ObjectResult;
var dummyClass = objResult.Value as DummyClass;
dummyClass.SampleInt = 120;
objResult.Formatters.Add(new XmlSerializerOutputFormatter());
base.OnResultExecuting(context);
}
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class RandomNumberFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
context.Result = new ContentResult()
{
Content = "4",
ContentType = "text/plain"
};
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class RandomNumberProvider : IActionFilter
{
private RandomNumberService _random;
public RandomNumberProvider(RandomNumberService random)
{
_random = random;
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
context.ActionArguments["randomNumber"] = _random.GetRandamNumber();
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace FiltersWebSite
{
public class SerializationActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
var result = context.Result as ObjectResult;
if (result != null)
{
result.Formatters.Add(new XmlSerializerOutputFormatter());
}
base.OnActionExecuted(context);
}
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace FiltersWebSite
{
public class DummyClass
{
public int SampleInt { get; set; }
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace FiltersWebSite
{
public class DummyService
{
public int RandomNumber
{
get
{
return 4;
}
}
}
}

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace FiltersWebSite
{
public class RandomNumberService
{
public int GetRandamNumber()
{
return 44;
}
}
}

View File

@ -18,6 +18,8 @@ namespace FiltersWebSite
app.UseServices(services =>
{
services.AddMvc(configuration);
services.AddSingleton<RandomNumberFilter>();
services.AddSingleton<RandomNumberService>();
services.Configure<MvcOptions>(options =>
{