- Used the work from @knight1219 (Daniel Mathews) as the basis.

* Fixed the unit tests so that they are now passing.
Note: This is my first real introduction to Moq, so there are probably a few things that can be improved.

Changes:
* Had a few issues with the mock logger, ended up adding a LoggerFactory and Logger implementation to work around this issue (for some reason the mock logger was never called and the unit tests failed because the string builder was never updated).
* Accommodated changes to the SignInManager, UserManager where the latest version has added Logging to constructor
* SecurityStamp functions in UserManager now check for null and throws an exception, so the unit tests can no longer call GetSecurityStampAsync before its set. Line 866: https://github.com/dotnet/aspnetcore/blame/605c522fa3e875fd6d3aefa783a71d1745b7e4c7/src/Identity/Extensions.Core/src/UserManager.cs
* SignInManager.RefreshSignInAsync has changed the internal method from s.SignInAsync to SignInWithClaimsAsync
This commit is contained in:
David Barker
2020-01-23 22:46:35 +08:00
parent bf44fca3ae
commit b9491256b0
10 changed files with 468 additions and 195 deletions
@@ -1,30 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.Identity.MongoDbCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="MongoDB.Driver" Version="2.7.0" />
<PackageReference Include="MongoDbGenericRepository" Version="1.4.0" />
<PackageReference Include="Moq" Version="4.8.1" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="MongoDB.Driver" Version="2.10.1" />
<PackageReference Include="MongoDbGenericRepository" Version="1.4.1" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AspNetCore.Identity.MongoDbCore.csproj" />
</ItemGroup>
</Project>
@@ -300,7 +300,7 @@ namespace Microsoft.AspNetCore.Identity.Test
private class MySignInManager : SignInManager<TestUser>
{
public MySignInManager(UserManager<TestUser> manager, IHttpContextAccessor context, IUserClaimsPrincipalFactory<TestUser> claimsFactory) : base(manager, context, claimsFactory, null, null, null) { }
public MySignInManager(UserManager<TestUser> manager, IHttpContextAccessor context, IUserClaimsPrincipalFactory<TestUser> claimsFactory) : base(manager, context, claimsFactory, null, null, null, null) { }
}
private class MyUserManager : UserManager<TestUser>
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
@@ -9,9 +10,11 @@ using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
using AspNetCore.Identity.MongoDbCore.IntegrationTests;
namespace Microsoft.AspNetCore.Identity.Test
{
@@ -71,150 +74,263 @@ namespace Microsoft.AspNetCore.Identity.Test
[InlineData(false)]
public async Task OnValidatePrincipalTestSuccess(bool isPersistent)
{
var user = new TestUser("test");
var userManager = MockHelpers.MockUserManager<TestUser>();
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var identityOptions = new Mock<IOptions<IdentityOptions>>();
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var httpContext = new Mock<HttpContext>();
var user = new TestUser { UserName = "test" };
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
var context = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(new IdentityOptions());
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var loggerFactory = new MockLoggerFactory();
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1), IsPersistent = isPersistent };
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var principal = new ClaimsPrincipal(id);
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1), IsPersistent = isPersistent };
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
signInManager.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
var logFactory = new MockLoggerFactory();
var services = new ServiceCollection();
services.AddSingleton<ILoggerFactory>(loggerFactory);
services.AddSingleton(options.Object);
services.AddSingleton(signInManager.Object);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
services.AddSingleton(helper.Object);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var ticket = new AuthenticationTicket(principal,
properties,
IdentityConstants.ApplicationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
Assert.NotNull(context.Principal);
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(cookieContext.Properties);
Assert.NotNull(cookieContext.Options);
Assert.NotNull(cookieContext.Principal);
await
SecurityStampValidator.ValidatePrincipalAsync(context);
Assert.NotNull(context.Principal);
signInManager.VerifyAll();
SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
Assert.NotNull(cookieContext.Principal);
helper.VerifyAll();
}
private static Mock<UserManager<TestUser>> SetupUserManager(TestUser user)
{
var manager = MockHelpers.MockUserManager<TestUser>();
manager.Setup(m => m.FindByNameAsync(user.UserName)).ReturnsAsync(user);
manager.Setup(m => m.FindByIdAsync(user.Id)).ReturnsAsync(user);
manager.Setup(m => m.GetUserIdAsync(user)).ReturnsAsync(user.Id.ToString());
manager.Setup(m => m.GetUserNameAsync(user)).ReturnsAsync(user.UserName);
return manager;
}
[Fact]
public async Task OnValidateIdentityRejectsWhenValidateSecurityStampFails()
{
var user = new TestUser("test");
var userManager = MockHelpers.MockUserManager<TestUser>();
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var identityOptions = new Mock<IOptions<IdentityOptions>>();
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var httpContext = new Mock<HttpContext>();
var user = new TestUser { UserName = "test" };
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
var context = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
var services = new ServiceCollection();
services.AddSingleton(options.Object);
services.AddSingleton(signInManager.Object);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(new IdentityOptions());
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var logStore = new StringBuilder();
var loggerFactory = new MockLoggerFactory();
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) };
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var principal = new ClaimsPrincipal(id);
//because the request fails the create user principal is never called and therefore not verifiable
//helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
var services = new ServiceCollection();
services.AddSingleton(options.Object);
services.AddSingleton(helper.Object);
services.AddSingleton<ILoggerFactory>(loggerFactory);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) },
IdentityConstants.ApplicationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
Assert.NotNull(context.Principal);
await SecurityStampValidator.ValidatePrincipalAsync(context);
Assert.Null(context.Principal);
signInManager.VerifyAll();
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(cookieContext.Properties);
Assert.NotNull(cookieContext.Options);
Assert.NotNull(cookieContext.Principal);
await SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
Assert.Null(cookieContext.Principal);
helper.VerifyAll();
}
[Fact]
public async Task OnValidateIdentityRejectsWhenNoIssuedUtc()
{
var user = new TestUser("test");
var httpContext = new Mock<HttpContext>();
var userManager = MockHelpers.MockUserManager<TestUser>();
var identityOptions = new Mock<IOptions<IdentityOptions>>();
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var user = new TestUser { UserName = "test" };
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
var context = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
var services = new ServiceCollection();
services.AddSingleton(options.Object);
services.AddSingleton(signInManager.Object);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(new IdentityOptions());
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var logStore = new StringBuilder();
var loggerFactory = new MockLoggerFactory();
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) };
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var principal = new ClaimsPrincipal(id);
//because the request fails the create user principal is never called and therefore not verifiable
//helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
var services = new ServiceCollection();
services.AddSingleton(options.Object);
services.AddSingleton(helper.Object);
services.AddSingleton<ILoggerFactory>(loggerFactory);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
// testing the ticket UTC setting, in this case lack of setting
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
new AuthenticationProperties(),
IdentityConstants.ApplicationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
Assert.NotNull(context.Principal);
await SecurityStampValidator.ValidatePrincipalAsync(context);
Assert.Null(context.Principal);
signInManager.VerifyAll();
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(cookieContext.Properties);
Assert.NotNull(cookieContext.Options);
Assert.NotNull(cookieContext.Principal);
await SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
Assert.Null(cookieContext.Principal);
helper.VerifyAll();
}
[Fact]
public async Task OnValidateIdentityDoesNotRejectsWhenNotExpired()
{
var user = new TestUser("test");
var httpContext = new Mock<HttpContext>();
var userManager = MockHelpers.MockUserManager<TestUser>();
var identityOptions = new Mock<IOptions<IdentityOptions>>();
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.FromDays(1) });
var user = new TestUser { UserName = "test" };
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
var context = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).Throws(new Exception("Shouldn't be called"));
signInManager.Setup(s => s.SignInAsync(user, false, null)).Throws(new Exception("Shouldn't be called"));
var services = new ServiceCollection();
services.AddSingleton(options.Object);
services.AddSingleton(signInManager.Object);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(new IdentityOptions());
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var logStore = new StringBuilder();
var loggerFactory = new MockLoggerFactory();
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) };
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var principal = new ClaimsPrincipal(id);
//because the request fails the create user principal is never called and therefore not verifiable
//helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
helper.Setup(s => s.SignInAsync(user, false, null)).Throws(new Exception("Shouldn't be called"));
var services = new ServiceCollection();
services.AddSingleton(options.Object);
services.AddSingleton(helper.Object);
services.AddSingleton<ILoggerFactory>(loggerFactory);
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
IdentityConstants.ApplicationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
Assert.NotNull(context.Principal);
await SecurityStampValidator.ValidatePrincipalAsync(context);
Assert.NotNull(context.Principal);
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
Assert.NotNull(cookieContext.Properties);
Assert.NotNull(cookieContext.Options);
Assert.NotNull(cookieContext.Principal);
await SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
Assert.NotNull(cookieContext.Principal);
}
}
}
@@ -7,6 +7,7 @@ using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using AspNetCore.Identity.MongoDbCore.IntegrationTests;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
@@ -68,13 +69,13 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public void ConstructorNullChecks()
{
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<TestUser>(null, null, null, null, null, null));
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<TestUser>(null, null, null, null, null, null, null));
var userManager = MockHelpers.MockUserManager<TestUser>().Object;
Assert.Throws<ArgumentNullException>("contextAccessor", () => new SignInManager<TestUser>(userManager, null, null, null, null, null));
Assert.Throws<ArgumentNullException>("contextAccessor", () => new SignInManager<TestUser>(userManager, null, null, null, null, null, null));
var contextAccessor = new Mock<IHttpContextAccessor>();
var context = new Mock<HttpContext>();
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
Assert.Throws<ArgumentNullException>("claimsFactory", () => new SignInManager<TestUser>(userManager, contextAccessor.Object, null, null, null, null));
Assert.Throws<ArgumentNullException>("claimsFactory", () => new SignInManager<TestUser>(userManager, contextAccessor.Object, null, null, null, null, null));
}
//[Fact]
@@ -122,9 +123,9 @@ namespace Microsoft.AspNetCore.Identity.Test
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(identityOptions);
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var logStore = new StringBuilder();
var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger.Object, new Mock<IAuthenticationSchemeProvider>().Object);
var loggerFactory = new MockLoggerFactory();
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
@@ -132,7 +133,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// Assert
Assert.False(result.Succeeded);
Assert.True(result.IsLockedOut);
Assert.Contains($"User {user.Id} is currently locked out.", logStore.ToString());
Assert.Contains($"User {user.Id} is currently locked out.", loggerFactory.LogStore.ToString());
manager.Verify();
}
@@ -153,9 +154,9 @@ namespace Microsoft.AspNetCore.Identity.Test
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(identityOptions);
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var logStore = new StringBuilder();
var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger.Object, new Mock<IAuthenticationSchemeProvider>().Object);
var loggerFactory = new MockLoggerFactory();
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
// Act
var result = await helper.CheckPasswordSignInAsync(user, "bogus", false);
@@ -163,7 +164,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// Assert
Assert.False(result.Succeeded);
Assert.True(result.IsLockedOut);
Assert.Contains($"User {user.Id} is currently locked out.", logStore.ToString());
Assert.Contains($"User {user.Id} is currently locked out.", loggerFactory.LogStore.ToString());
manager.Verify();
}
@@ -177,7 +178,7 @@ namespace Microsoft.AspNetCore.Identity.Test
return manager;
}
private static SignInManager<TestUser> SetupSignInManager(UserManager<TestUser> manager, HttpContext context, StringBuilder logStore = null, IdentityOptions identityOptions = null)
private static SignInManager<TestUser> SetupSignInManager(UserManager<TestUser> manager, HttpContext context, MockLoggerFactory factory, IdentityOptions identityOptions = null)
{
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(context);
@@ -186,8 +187,20 @@ namespace Microsoft.AspNetCore.Identity.Test
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(identityOptions);
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager, roleManager.Object, options.Object);
var sm = new SignInManager<TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
sm.Logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore ?? new StringBuilder()).Object;
var sm = new SignInManager<TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object,factory.CreateLogger<SignInManager<TestUser>>(), new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
return sm;
}
private static Mock<SignInManager<TestUser>> MockSignInManager(UserManager<TestUser> manager, HttpContext context, MockLoggerFactory factory, IdentityOptions identityOptions = null)
{
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(context);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
identityOptions = identityOptions ?? new IdentityOptions();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Value).Returns(identityOptions);
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager, roleManager.Object, options.Object);
var sm = new Mock<SignInManager<TestUser>>(manager, contextAccessor.Object, claimsFactory, options.Object, factory.CreateLogger<SignInManager<TestUser>>(), new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
return sm;
}
@@ -206,7 +219,9 @@ namespace Microsoft.AspNetCore.Identity.Test
var context = new DefaultHttpContext();
var auth = MockAuth(context);
SetupSignIn(context, auth, user.Id, isPersistent);
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
@@ -230,8 +245,8 @@ namespace Microsoft.AspNetCore.Identity.Test
var context = new DefaultHttpContext();
var auth = MockAuth(context);
SetupSignIn(context, auth, user.Id, false);
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
@@ -256,8 +271,8 @@ namespace Microsoft.AspNetCore.Identity.Test
var context = new DefaultHttpContext();
var auth = MockAuth(context);
SetupSignIn(context, auth);
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
@@ -288,7 +303,10 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.GetValidTwoFactorProvidersAsync(user)).ReturnsAsync(new string[1] { "Fake" }).Verifiable();
var context = new DefaultHttpContext();
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
var auth = MockAuth(context);
auth.Setup(a => a.SignInAsync(context, IdentityConstants.TwoFactorUserIdScheme,
It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id),
@@ -326,7 +344,9 @@ namespace Microsoft.AspNetCore.Identity.Test
}
var context = new DefaultHttpContext();
var auth = MockAuth(context);
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
if (bypass)
{
@@ -473,7 +493,10 @@ namespace Microsoft.AspNetCore.Identity.Test
var context = new DefaultHttpContext();
var auth = MockAuth(context);
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
SetupSignIn(context, auth, user.Id, isPersistent, loginProvider);
// Act
@@ -493,6 +516,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// Setup
var user = new TestUser { UserName = "Foo" };
var context = new DefaultHttpContext();
var services = new ServiceCollection();
var auth = MockAuth(context);
var loginProvider = "loginprovider";
var id = new ClaimsIdentity();
@@ -503,25 +527,26 @@ namespace Microsoft.AspNetCore.Identity.Test
// REVIEW: auth changes we lost the ability to mock is persistent
//var properties = new AuthenticationProperties { IsPersistent = isPersistent };
var authResult = AuthenticateResult.NoResult();
auth.Setup(a => a.AuthenticateAsync(context, IdentityConstants.ApplicationScheme))
.Returns(Task.FromResult(authResult)).Verifiable();
auth.Setup(a => a.AuthenticateAsync(context, IdentityConstants.ApplicationScheme)).Returns(Task.FromResult(authResult)).Verifiable();
var manager = SetupUserManager(user);
var signInManager = new Mock<SignInManager<TestUser>>(manager.Object,
new HttpContextAccessor { HttpContext = context },
new Mock<IUserClaimsPrincipalFactory<TestUser>>().Object,
null, null, new Mock<IAuthenticationSchemeProvider>().Object)
{ CallBase = true };
//signInManager.Setup(s => s.SignInAsync(user, It.Is<AuthenticationProperties>(p => p.IsPersistent == isPersistent),
//externalLogin? loginProvider : null)).Returns(Task.FromResult(0)).Verifiable();
signInManager.Setup(s => s.SignInAsync(user, It.IsAny<AuthenticationProperties>(), null)).Returns(Task.FromResult(0)).Verifiable();
signInManager.Object.Context = context;
// Act
await signInManager.Object.RefreshSignInAsync(user);
using (MockLoggerFactory loggerFactory = new MockLoggerFactory())
{
var signInManager = MockSignInManager(manager.Object, context, loggerFactory, null);
// Assert
auth.Verify();
signInManager.Verify();
signInManager.CallBase = true; // need this magic!
signInManager.Setup(s => s.SignInWithClaimsAsync(user, It.IsAny<AuthenticationProperties>(), It.IsAny<List<Claim>>())).Returns(Task.FromResult(0)).Verifiable();
// Act
await signInManager.Object.RefreshSignInAsync(user);
// Assert
auth.Verify();
signInManager.Verify();
}
}
//[Theory]
@@ -606,7 +631,10 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = SetupUserManager(user);
var context = new DefaultHttpContext();
var auth = MockAuth(context);
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
auth.Setup(a => a.SignInAsync(
context,
IdentityConstants.TwoFactorRememberMeScheme,
@@ -644,9 +672,12 @@ namespace Microsoft.AspNetCore.Identity.Test
SetupSignIn(context, auth);
var id = new ClaimsIdentity(IdentityConstants.TwoFactorRememberMeScheme);
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
auth.Setup(a => a.AuthenticateAsync(context, IdentityConstants.TwoFactorRememberMeScheme))
auth.Setup(a => a.AuthenticateAsync(It.IsAny<HttpContext>(), IdentityConstants.TwoFactorRememberMeScheme))
.ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(id), null, IdentityConstants.TwoFactorRememberMeScheme))).Verifiable();
var helper = SetupSignInManager(manager.Object, context);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
@@ -664,6 +695,15 @@ namespace Microsoft.AspNetCore.Identity.Test
return auth;
}
private Mock<IAuthenticationService> MockAuth(ServiceCollection services)
{
var auth = new Mock<IAuthenticationService>();
services.AddSingleton(auth.Object);
return auth;
}
[Fact]
public async Task SignOutCallsContextResponseSignOut()
{
@@ -671,10 +711,11 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = MockHelpers.TestUserManager<TestUser>();
var context = new DefaultHttpContext();
var auth = MockAuth(context);
var loggerFactory = new MockLoggerFactory();
auth.Setup(a => a.SignOutAsync(context, IdentityConstants.ApplicationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
auth.Setup(a => a.SignOutAsync(context, IdentityConstants.TwoFactorUserIdScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
auth.Setup(a => a.SignOutAsync(context, IdentityConstants.ExternalScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
var helper = SetupSignInManager(manager, context, null, manager.Options);
var helper = SetupSignInManager(manager, context, loggerFactory, manager.Options);
// Act
await helper.SignOutAsync();
@@ -693,8 +734,10 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
var context = new Mock<HttpContext>();
var logStore = new StringBuilder();
var helper = SetupSignInManager(manager.Object, context.Object, logStore);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
var checkResult = await helper.CheckPasswordSignInAsync(user, "bogus", false);
@@ -702,7 +745,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// Assert
Assert.False(result.Succeeded);
Assert.False(checkResult.Succeeded);
Assert.Contains($"User {user.Id} failed to provide the correct password.", logStore.ToString());
Assert.Contains($"User {user.Id} failed to provide the correct password.", loggerFactory.LogStore.ToString());
manager.Verify();
context.Verify();
}
@@ -714,7 +757,9 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = MockHelpers.MockUserManager<TestUser>();
manager.Setup(m => m.FindByNameAsync("bogus")).ReturnsAsync(default(TestUser)).Verifiable();
var context = new Mock<HttpContext>();
var helper = SetupSignInManager(manager.Object, context.Object);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
@@ -741,7 +786,9 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
var context = new Mock<HttpContext>();
var helper = SetupSignInManager(manager.Object, context.Object);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);
@@ -768,7 +815,9 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
var context = new Mock<HttpContext>();
var helper = SetupSignInManager(manager.Object, context.Object);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
// Act
var result = await helper.CheckPasswordSignInAsync(user, "bogus", true);
@@ -802,8 +851,9 @@ namespace Microsoft.AspNetCore.Identity.Test
var identityOptions = new IdentityOptions();
identityOptions.SignIn.RequireConfirmedEmail = true;
var logStore = new StringBuilder();
var helper = SetupSignInManager(manager.Object, context, logStore, identityOptions);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory, identityOptions);
// Act
var result = await helper.PasswordSignInAsync(user, "password", false, false);
@@ -811,7 +861,7 @@ namespace Microsoft.AspNetCore.Identity.Test
Assert.Equal(confirmed, result.Succeeded);
Assert.NotEqual(confirmed, result.IsNotAllowed);
Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed email."));
Assert.Equal(confirmed, !loggerFactory.LogStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed email."));
manager.Verify();
auth.Verify();
@@ -846,8 +896,9 @@ namespace Microsoft.AspNetCore.Identity.Test
var identityOptions = new IdentityOptions();
identityOptions.SignIn.RequireConfirmedPhoneNumber = true;
var logStore = new StringBuilder();
var helper = SetupSignInManager(manager.Object, context, logStore, identityOptions);
MockLoggerFactory loggerFactory = new MockLoggerFactory();
var helper = SetupSignInManager(manager.Object, context, loggerFactory, identityOptions);
// Act
var result = await helper.PasswordSignInAsync(user, "password", false, false);
@@ -855,7 +906,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// Assert
Assert.Equal(confirmed, result.Succeeded);
Assert.NotEqual(confirmed, result.IsNotAllowed);
Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed phone number."));
Assert.Equal(confirmed, !loggerFactory.LogStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed phone number."));
manager.Verify();
auth.Verify();
}
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.Extensions.Logging;
namespace AspNetCore.Identity.MongoDbCore.IntegrationTests
{
public class MockLoggerFactory : ILoggerFactory
{
public StringBuilder LogStore;
public List<ILogger> Loggers = new List<ILogger>();
public MockLoggerFactory()
{
LogStore = new StringBuilder();
}
public void AddProvider(ILoggerProvider provider)
{
}
public ILogger CreateLogger(string categoryName)
{
var logger = MockHelpers.MockILogger(LogStore).Object;
Loggers.Add(logger);
return logger;
}
public ILogger<T> CreateLogger<T>() where T : class
{
//var logger = MockHelpers.MockILogger<T>(LogStore).Object;
var logger = new MockLogger<T>(LogStore);
Loggers.Add(logger);
return logger;
}
public void Dispose()
{
}
}
public class MockLogger<T> : ILogger<T>
{
public StringBuilder LogMessages;
public MockLogger(StringBuilder store)
{
LogMessages = store;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (formatter != null)
{
LogMessages.Append(formatter(state, exception));
}
else
{
LogMessages.Append(state.ToString());
}
}
}
}
@@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = CreateManager();
var username = "Create" + Guid.NewGuid().ToString();
var user = CreateTestUser(username, useNamePrefixAsUserName: true);
var stamp = await manager.GetSecurityStampAsync(user);
Assert.Null(user.SecurityStamp);
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
Assert.NotNull(await manager.GetSecurityStampAsync(user));
}
@@ -947,10 +947,12 @@ namespace Microsoft.AspNetCore.Identity.Test
}
var manager = CreateManager();
var user = CreateTestUser();
Assert.Null(await manager.GetSecurityStampAsync(user));
var originalStamp = user.SecurityStamp;
//Update to library, can no longer test for null; throws an exceptoin
Assert.Null(user.SecurityStamp);
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
var stamp = await manager.GetSecurityStampAsync(user);
Assert.NotNull(stamp);
Assert.NotEqual(originalStamp, stamp);
IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user));
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
}