Solution restructured to use multiple test projects
This commit is contained in:
@@ -0,0 +1,477 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Antiforgery;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
|
||||
namespace AMWD.Common.AspNetCore.Tests.Extensions
|
||||
{
|
||||
[TestClass]
|
||||
public class HttpContextExtensionsTest
|
||||
{
|
||||
private Mock<ISession> _sessionMock;
|
||||
|
||||
private string _tokenFormName;
|
||||
private string _tokenHeaderName;
|
||||
private string _tokenValue;
|
||||
|
||||
private Dictionary<string, string> _requestHeaders;
|
||||
private Dictionary<string, string> _requestQueries;
|
||||
private Dictionary<object, object> _items;
|
||||
|
||||
private IPAddress _remote;
|
||||
|
||||
[TestInitialize]
|
||||
public void InitializeTests()
|
||||
{
|
||||
_tokenFormName = null;
|
||||
_tokenHeaderName = null;
|
||||
_tokenValue = null;
|
||||
|
||||
_requestHeaders = [];
|
||||
_requestQueries = [];
|
||||
_items = [];
|
||||
|
||||
_remote = IPAddress.Loopback;
|
||||
}
|
||||
|
||||
#region Antiforgery
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnAntiforgery()
|
||||
{
|
||||
// arrange
|
||||
_tokenFormName = "af-token";
|
||||
_tokenHeaderName = "af-header";
|
||||
_tokenValue = "security_first";
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var (formName, headerName, value) = context.GetAntiforgeryToken();
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(_tokenFormName, formName);
|
||||
Assert.AreEqual(_tokenHeaderName, headerName);
|
||||
Assert.AreEqual(_tokenValue, value);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnAntiforgeryNullService()
|
||||
{
|
||||
// arrange
|
||||
_tokenFormName = "af-token";
|
||||
_tokenHeaderName = "af-header";
|
||||
_tokenValue = "security_first";
|
||||
|
||||
var context = GetContext(hasAntiforgery: false);
|
||||
|
||||
// act
|
||||
var (formName, headerName, value) = context.GetAntiforgeryToken();
|
||||
|
||||
// assert
|
||||
Assert.IsNull(formName);
|
||||
Assert.IsNull(headerName);
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnAntiforgeryNullToken()
|
||||
{
|
||||
// arrange
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var (formName, headerName, value) = context.GetAntiforgeryToken();
|
||||
|
||||
// assert
|
||||
Assert.IsNull(formName);
|
||||
Assert.IsNull(headerName);
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
#endregion Antiforgery
|
||||
|
||||
#region RemoteAddres
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnRemoteAddress()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var result = context.GetRemoteIpAddress();
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(_remote, result);
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("Cf-Connecting-Ip")]
|
||||
[DataRow("X-Real-IP")]
|
||||
[DataRow("X-Forwarded-For")]
|
||||
public void ShouldReturnDefaultHeader(string headerName)
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
var header = IPAddress.Parse("5.6.7.8");
|
||||
_requestHeaders.Add(headerName, header.ToString());
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var result = context.GetRemoteIpAddress();
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(_remote, result);
|
||||
Assert.AreEqual(header, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnCustomHeader()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
string headerName = "FooBar";
|
||||
var headerIp = IPAddress.Parse("5.6.7.8");
|
||||
|
||||
_requestHeaders.Add(headerName, headerIp.ToString());
|
||||
_requestHeaders.Add("X-Forwarded-For", _remote.ToString());
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var result = context.GetRemoteIpAddress(ipHeaderName: headerName);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(_remote, result);
|
||||
Assert.AreEqual(headerIp, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnAddressInvalidHeader()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
_requestHeaders.Add("X-Forwarded-For", "1.2.3:4");
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var result = context.GetRemoteIpAddress();
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(_remote, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnFirstAddressOnMultipleProxies()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
var header = IPAddress.Parse("5.6.7.8");
|
||||
_requestHeaders.Add("X-Forwarded-For", $"{header}, 111.222.111.222");
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var result = context.GetRemoteIpAddress();
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(_remote, result);
|
||||
Assert.AreEqual(header, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnV4AddressOnMapped()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
var header = IPAddress.Parse("::ffff:127.0.0.1");
|
||||
_requestHeaders.Add("X-Forwarded-For", "::ffff:127.0.0.1");
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
var result = context.GetRemoteIpAddress();
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(_remote, result);
|
||||
Assert.AreNotEqual(header, result);
|
||||
Assert.AreEqual(header.MapToIPv4(), result);
|
||||
}
|
||||
|
||||
#endregion RemoteAddres
|
||||
|
||||
#region Local Request
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnTrueOnLocal()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Loopback;
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
bool result = context.IsLocalRequest();
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnFalseOnRemote()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
bool result = context.IsLocalRequest();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnTrueOnDefaultHeader()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
var headerIp = IPAddress.Loopback;
|
||||
_requestHeaders.Add("X-Forwarded-For", headerIp.ToString());
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
bool result = context.IsLocalRequest();
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnTrueOnCustomHeader()
|
||||
{
|
||||
// arrange
|
||||
_remote = IPAddress.Parse("1.2.3.4");
|
||||
string headerName = "FooBar";
|
||||
var headerIp = IPAddress.Loopback;
|
||||
_requestHeaders.Add(headerName, headerIp.ToString());
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
bool result = context.IsLocalRequest(ipHeaderName: headerName);
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnFalseOnDefaultHeader()
|
||||
{
|
||||
// arrange
|
||||
var headerIp = IPAddress.Parse("1.2.3.4");
|
||||
_requestHeaders.Add("X-Forwarded-For", headerIp.ToString());
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
bool result = context.IsLocalRequest();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnFalseOnCustomHeader()
|
||||
{
|
||||
// arrange
|
||||
string headerName = "FooBar";
|
||||
var headerIp = IPAddress.Parse("1.2.3.4");
|
||||
_requestHeaders.Add(headerName, headerIp.ToString());
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
bool result = context.IsLocalRequest(ipHeaderName: headerName);
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
#endregion Local Request
|
||||
|
||||
#region ReturnUrl
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnNull()
|
||||
{
|
||||
// arrange
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
string result = context.GetReturnUrl();
|
||||
|
||||
// assert
|
||||
Assert.IsNull(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnOriginalRequest()
|
||||
{
|
||||
// arrange
|
||||
string request = "abc";
|
||||
string query = "def";
|
||||
|
||||
_items.Add("OriginalRequest", request);
|
||||
_requestQueries.Add("ReturnUrl", query);
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
string result = context.GetReturnUrl();
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(request, result);
|
||||
Assert.AreNotEqual(query, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnUrl()
|
||||
{
|
||||
// arrange
|
||||
string query = "def";
|
||||
_requestQueries.Add("ReturnUrl", query);
|
||||
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
string result = context.GetReturnUrl();
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(query, result);
|
||||
}
|
||||
|
||||
#endregion ReturnUrl
|
||||
|
||||
#region Session
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldClearSession()
|
||||
{
|
||||
// arrange
|
||||
var context = GetContext();
|
||||
|
||||
// act
|
||||
context.ClearSession();
|
||||
|
||||
// assert
|
||||
_sessionMock.Verify(s => s.Clear(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldSkipWhenNoSession()
|
||||
{
|
||||
// arrange
|
||||
var context = GetContext(hasSession: false);
|
||||
|
||||
// act
|
||||
context.ClearSession();
|
||||
|
||||
// assert
|
||||
_sessionMock.Verify(s => s.Clear(), Times.Never);
|
||||
}
|
||||
|
||||
#endregion Session
|
||||
|
||||
private HttpContext GetContext(bool hasAntiforgery = true, bool hasSession = true)
|
||||
{
|
||||
// Request
|
||||
var requestHeaderMock = new Mock<IHeaderDictionary>();
|
||||
foreach (var header in _requestHeaders)
|
||||
{
|
||||
requestHeaderMock
|
||||
.Setup(h => h.ContainsKey(header.Key))
|
||||
.Returns(true);
|
||||
requestHeaderMock
|
||||
.Setup(h => h[header.Key])
|
||||
.Returns(header.Value);
|
||||
}
|
||||
|
||||
var requestQueryMock = new Mock<IQueryCollection>();
|
||||
foreach (var query in _requestQueries)
|
||||
{
|
||||
requestQueryMock
|
||||
.Setup(h => h.ContainsKey(query.Key))
|
||||
.Returns(true);
|
||||
requestQueryMock
|
||||
.Setup(h => h[query.Key])
|
||||
.Returns(query.Value);
|
||||
}
|
||||
|
||||
var requestMock = new Mock<HttpRequest>();
|
||||
requestMock
|
||||
.Setup(r => r.Headers)
|
||||
.Returns(requestHeaderMock.Object);
|
||||
requestMock
|
||||
.Setup(r => r.Query)
|
||||
.Returns(requestQueryMock.Object);
|
||||
|
||||
// Request Services
|
||||
var requestServicesMock = new Mock<IServiceProvider>();
|
||||
if (hasAntiforgery)
|
||||
{
|
||||
var antiforgeryMock = new Mock<IAntiforgery>();
|
||||
antiforgeryMock
|
||||
.Setup(af => af.GetAndStoreTokens(It.IsAny<HttpContext>()))
|
||||
.Returns(() => string.IsNullOrWhiteSpace(_tokenValue) ? null : new AntiforgeryTokenSet(_tokenValue, _tokenValue, _tokenFormName, _tokenHeaderName));
|
||||
|
||||
requestServicesMock
|
||||
.Setup(rs => rs.GetService(typeof(IAntiforgery)))
|
||||
.Returns(antiforgeryMock.Object);
|
||||
}
|
||||
|
||||
// Connection
|
||||
var connectionInfoMock = new Mock<ConnectionInfo>();
|
||||
connectionInfoMock
|
||||
.Setup(ci => ci.LocalIpAddress)
|
||||
.Returns(IPAddress.Loopback);
|
||||
connectionInfoMock
|
||||
.Setup(ci => ci.RemoteIpAddress)
|
||||
.Returns(_remote);
|
||||
|
||||
// Session
|
||||
_sessionMock = new Mock<ISession>();
|
||||
|
||||
var contextMock = new Mock<HttpContext>();
|
||||
contextMock
|
||||
.Setup(c => c.Request)
|
||||
.Returns(requestMock.Object);
|
||||
contextMock
|
||||
.Setup(c => c.RequestServices)
|
||||
.Returns(requestServicesMock.Object);
|
||||
contextMock
|
||||
.Setup(c => c.Connection)
|
||||
.Returns(connectionInfoMock.Object);
|
||||
contextMock
|
||||
.Setup(c => c.Items)
|
||||
.Returns(_items);
|
||||
if (hasSession)
|
||||
{
|
||||
contextMock
|
||||
.Setup(c => c.Session)
|
||||
.Returns(_sessionMock.Object);
|
||||
}
|
||||
|
||||
return contextMock.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user