Unit test work (Core @ 78%)

Starting using Microsoft.AspNet.Testing
Add/Port a bunch more unit tests
This commit is contained in:
Hao Kung 2014-03-17 16:03:54 -07:00
parent 389815482e
commit f77614c97f
19 changed files with 951 additions and 302 deletions

View File

@ -15,7 +15,9 @@ namespace Microsoft.AspNet.Identity.InMemory
IUserEmailStore<TUser, string>, IUserEmailStore<TUser, string>,
IUserLockoutStore<TUser, string>, IUserLockoutStore<TUser, string>,
IUserPhoneNumberStore<TUser, string>, IUserPhoneNumberStore<TUser, string>,
IQueryableUserStore<TUser, string> where TUser : InMemoryUser IQueryableUserStore<TUser, string>,
IUserTwoFactorStore<TUser, string>
where TUser : InMemoryUser
{ {
private readonly Dictionary<UserLoginInfo, TUser> _logins = private readonly Dictionary<UserLoginInfo, TUser> _logins =
new Dictionary<UserLoginInfo, TUser>(new LoginComparer()); new Dictionary<UserLoginInfo, TUser>(new LoginComparer());
@ -267,5 +269,16 @@ namespace Microsoft.AspNet.Identity.InMemory
return (obj.ProviderKey + "--" + obj.LoginProvider).GetHashCode(); return (obj.ProviderKey + "--" + obj.LoginProvider).GetHashCode();
} }
} }
public Task SetTwoFactorEnabled(TUser user, bool enabled)
{
user.TwoFactorEnabled = enabled;
return Task.FromResult(0);
}
public Task<bool> GetTwoFactorEnabled(TUser user)
{
return Task.FromResult(user.TwoFactorEnabled);
}
} }
} }

View File

@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.AspNet.Identity namespace Microsoft.AspNet.Identity
@ -5,14 +6,18 @@ namespace Microsoft.AspNet.Identity
/// <summary> /// <summary>
/// Used to validate a role /// Used to validate a role
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="TRole"></typeparam>
public interface IRoleValidator<in T> /// <typeparam name="TKey"></typeparam>
public interface IRoleValidator<TRole, TKey>
where TRole : class, IRole<TKey>
where TKey : IEquatable<TKey>
{ {
/// <summary> /// <summary>
/// Validate the user /// Validate the user
/// </summary> /// </summary>
/// <param name="role"></param> /// <param name="role"></param>
/// <param name="manager"></param>
/// <returns></returns> /// <returns></returns>
Task<IdentityResult> Validate(T role); Task<IdentityResult> Validate(RoleManager<TRole, TKey> manager, TRole role);
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Microsoft.AspNet.Identity namespace Microsoft.AspNet.Identity
{ {
@ -23,9 +24,9 @@ namespace Microsoft.AspNet.Identity
/// <param name="errors"></param> /// <param name="errors"></param>
public IdentityResult(IEnumerable<string> errors) public IdentityResult(IEnumerable<string> errors)
{ {
if (errors == null) if (errors == null || !errors.Any())
{ {
errors = new[] {"Resources.DefaultError"}; errors = new[] {Resources.DefaultError};
} }
Succeeded = false; Succeeded = false;
Errors = errors; Errors = errors;

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Identity
throw new ArgumentNullException("store"); throw new ArgumentNullException("store");
} }
Store = store; Store = store;
RoleValidator = new RoleValidator<TRole, TKey>(this); RoleValidator = new RoleValidator<TRole, TKey>();
} }
/// <summary> /// <summary>
@ -53,7 +53,7 @@ namespace Microsoft.AspNet.Identity
/// <summary> /// <summary>
/// Used to validate roles before persisting changes /// Used to validate roles before persisting changes
/// </summary> /// </summary>
public IRoleValidator<TRole> RoleValidator { get; set; } public IRoleValidator<TRole, TKey> RoleValidator { get; set; }
/// <summary> /// <summary>
/// Returns an IQueryable of roles if the store is an IQueryableRoleStore /// Returns an IQueryable of roles if the store is an IQueryableRoleStore
@ -71,6 +71,18 @@ namespace Microsoft.AspNet.Identity
} }
} }
/// <summary>
/// Returns true if the store is an IQueryableRoleStore
/// </summary>
public virtual bool SupportsQueryableRoles
{
get
{
ThrowIfDisposed();
return Store is IQueryableRoleStore<TRole, TKey>;
}
}
/// <summary> /// <summary>
/// Dispose this object /// Dispose this object
/// </summary> /// </summary>
@ -82,7 +94,7 @@ namespace Microsoft.AspNet.Identity
private async Task<IdentityResult> ValidateRoleInternal(TRole role) private async Task<IdentityResult> ValidateRoleInternal(TRole role)
{ {
return (RoleValidator == null) ? IdentityResult.Success : await RoleValidator.Validate(role).ConfigureAwait(false); return (RoleValidator == null) ? IdentityResult.Success : await RoleValidator.Validate(this, role).ConfigureAwait(false);
} }
/// <summary> /// <summary>

View File

@ -10,38 +10,28 @@ namespace Microsoft.AspNet.Identity
/// </summary> /// </summary>
/// <typeparam name="TRole"></typeparam> /// <typeparam name="TRole"></typeparam>
/// <typeparam name="TKey"></typeparam> /// <typeparam name="TKey"></typeparam>
public class RoleValidator<TRole, TKey> : IRoleValidator<TRole> public class RoleValidator<TRole, TKey> : IRoleValidator<TRole, TKey>
where TRole : class, IRole<TKey> where TRole : class, IRole<TKey>
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
/// <summary> /// <summary>
/// Constructor /// Validates a role before saving
/// </summary> /// </summary>
/// <param name="manager"></param> /// <param name="manager"></param>
public RoleValidator(RoleManager<TRole, TKey> manager) /// <param name="role"></param>
/// <returns></returns>
public virtual async Task<IdentityResult> Validate(RoleManager<TRole, TKey> manager, TRole role)
{ {
if (manager == null) if (manager == null)
{ {
throw new ArgumentNullException("manager"); throw new ArgumentNullException("manager");
} }
Manager = manager; if (role == null)
}
private RoleManager<TRole, TKey> Manager { get; set; }
/// <summary>
/// Validates a role before saving
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public virtual async Task<IdentityResult> Validate(TRole item)
{
if (item == null)
{ {
throw new ArgumentNullException("item"); throw new ArgumentNullException("role");
} }
var errors = new List<string>(); var errors = new List<string>();
await ValidateRoleName(item, errors); await ValidateRoleName(manager, role, errors);
if (errors.Count > 0) if (errors.Count > 0)
{ {
return IdentityResult.Failed(errors.ToArray()); return IdentityResult.Failed(errors.ToArray());
@ -49,7 +39,7 @@ namespace Microsoft.AspNet.Identity
return IdentityResult.Success; return IdentityResult.Success;
} }
private async Task ValidateRoleName(TRole role, List<string> errors) private static async Task ValidateRoleName(RoleManager<TRole, TKey> manager, TRole role, ICollection<string> errors)
{ {
if (string.IsNullOrWhiteSpace(role.Name)) if (string.IsNullOrWhiteSpace(role.Name))
{ {
@ -57,7 +47,7 @@ namespace Microsoft.AspNet.Identity
} }
else else
{ {
var owner = await Manager.FindByName(role.Name); var owner = await manager.FindByName(role.Name);
if (owner != null && !EqualityComparer<TKey>.Default.Equals(owner.Id, role.Id)) if (owner != null && !EqualityComparer<TKey>.Default.Equals(owner.Id, role.Id))
{ {
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateName, role.Name)); errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateName, role.Name));

View File

@ -271,7 +271,6 @@ namespace Microsoft.AspNet.Identity
} }
} }
/// <summary> /// <summary>
/// Returns an IQueryable of users if the store is an IQueryableUserStore /// Returns an IQueryable of users if the store is an IQueryableUserStore
/// </summary> /// </summary>
@ -1162,14 +1161,14 @@ namespace Microsoft.AspNet.Identity
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound, throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound,
userId)); userId));
} }
if (await VerifyChangePhoneNumberToken(userId, token, phoneNumber).ConfigureAwait(false)) if (!await VerifyChangePhoneNumberToken(userId, token, phoneNumber).ConfigureAwait(false))
{ {
await store.SetPhoneNumber(user, phoneNumber).ConfigureAwait(false); return IdentityResult.Failed(Resources.InvalidToken);
await store.SetPhoneNumberConfirmed(user, true).ConfigureAwait(false);
await UpdateSecurityStampInternal(user).ConfigureAwait(false);
return await Update(user).ConfigureAwait(false);
} }
return IdentityResult.Failed(Resources.InvalidToken); await store.SetPhoneNumber(user, phoneNumber).ConfigureAwait(false);
await store.SetPhoneNumberConfirmed(user, true).ConfigureAwait(false);
await UpdateSecurityStampInternal(user).ConfigureAwait(false);
return await Update(user).ConfigureAwait(false);
} }
/// <summary> /// <summary>
@ -1520,12 +1519,12 @@ namespace Microsoft.AspNet.Identity
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound, throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound,
userId)); userId));
} }
if (await store.GetLockoutEnabled(user).ConfigureAwait(false)) if (!await store.GetLockoutEnabled(user).ConfigureAwait(false))
{ {
var lockoutTime = await store.GetLockoutEndDate(user).ConfigureAwait((false)); return false;
return lockoutTime >= DateTimeOffset.UtcNow;
} }
return false; var lockoutTime = await store.GetLockoutEndDate(user).ConfigureAwait((false));
return lockoutTime >= DateTimeOffset.UtcNow;
} }
/// <summary> /// <summary>
@ -1627,13 +1626,14 @@ namespace Microsoft.AspNet.Identity
} }
// If this puts the user over the threshold for lockout, lock them out and reset the access failed count // If this puts the user over the threshold for lockout, lock them out and reset the access failed count
var count = await store.IncrementAccessFailedCount(user).ConfigureAwait(false); var count = await store.IncrementAccessFailedCount(user).ConfigureAwait(false);
if (count >= MaxFailedAccessAttemptsBeforeLockout) if (count < MaxFailedAccessAttemptsBeforeLockout)
{ {
await return await Update(user).ConfigureAwait(false);
store.SetLockoutEndDate(user, DateTimeOffset.UtcNow.Add(DefaultAccountLockoutTimeSpan))
.ConfigureAwait(false);
await store.ResetAccessFailedCount(user).ConfigureAwait(false);
} }
await
store.SetLockoutEndDate(user, DateTimeOffset.UtcNow.Add(DefaultAccountLockoutTimeSpan))
.ConfigureAwait(false);
await store.ResetAccessFailedCount(user).ConfigureAwait(false);
return await Update(user).ConfigureAwait(false); return await Update(user).ConfigureAwait(false);
} }

View File

@ -94,20 +94,20 @@ namespace Microsoft.AspNet.Identity
} }
/// <summary> /// <summary>
/// Returns true if the character is upper, lower, or a digit /// Returns true if the character is upper, lower, a digit, or a common email character [@_.]
/// </summary> /// </summary>
/// <param name="c"></param> /// <param name="c"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool IsAlphaNumeric(char c) public virtual bool IsAlphaNumeric(char c)
{ {
return IsUpper(c) || IsLower(c) || IsDigit(c) || c == '@' || c == '_'; return IsUpper(c) || IsLower(c) || IsDigit(c) || c == '@' || c == '_' || c == '.';
} }
private async Task ValidateUserName(UserManager<TUser, TKey> manager, TUser user, ICollection<string> errors) private async Task ValidateUserName(UserManager<TUser, TKey> manager, TUser user, ICollection<string> errors)
{ {
if (string.IsNullOrWhiteSpace(user.UserName)) if (string.IsNullOrWhiteSpace(user.UserName))
{ {
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "Name")); errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "UserName"));
} }
else if (AllowOnlyAlphanumericUserNames && !user.UserName.All(IsAlphaNumeric)) else if (AllowOnlyAlphanumericUserNames && !user.UserName.All(IsAlphaNumeric))
{ {

View File

@ -1,47 +0,0 @@
using System;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNet.Identity.InMemory.Test
{
public static class ExceptionHelper
{
public static async Task<TException> ThrowsWithError<TException>(Func<Task> act, string error)
where TException : Exception
{
var e = await Assert.ThrowsAsync<TException>(act);
if (e != null)
{
Assert.Equal(error, e.Message);
}
return e;
}
public static async Task<ArgumentException> ThrowsArgumentException(Func<Task> del, string exceptionMessage,
string paramName)
{
var e = await Assert.ThrowsAsync<ArgumentException>(del);
// Only check exception message on English build and OS, since some exception messages come from the OS
// and will be in the native language.
// TODO: needed? if (IdentityResultAssert.EnglishBuildAndOS)
//{
Assert.Equal(exceptionMessage, e.Message);
Assert.Equal(paramName, e.ParamName);;
//}
return e;
}
public static Task<ArgumentException> ThrowsArgumentNullOrEmpty(Func<Task> del, string paramName)
{
return ThrowsArgumentException(del, "Value cannot be null or empty.\r\nParameter name: " + paramName,
paramName);
}
public static async Task<ArgumentNullException> ThrowsArgumentNull(Func<Task> del, string paramName)
{
var e = await Assert.ThrowsAsync<ArgumentNullException>(del);
Assert.Equal(paramName, e.ParamName);
return e;
}
}
}

View File

@ -2,6 +2,7 @@ using System;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Testing;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Identity.InMemory.Test namespace Microsoft.AspNet.Identity.InMemory.Test
@ -57,7 +58,9 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
var user = new InMemoryUser("CreateUserLoginAddPasswordTest"); var user = new InMemoryUser("CreateUserLoginAddPasswordTest");
IdentityResultAssert.IsSuccess(await manager.Create(user)); IdentityResultAssert.IsSuccess(await manager.Create(user));
IdentityResultAssert.IsSuccess(await manager.AddLogin(user.Id, login)); IdentityResultAssert.IsSuccess(await manager.AddLogin(user.Id, login));
Assert.False(await manager.HasPassword(user.Id));
IdentityResultAssert.IsSuccess(await manager.AddPassword(user.Id, "password")); IdentityResultAssert.IsSuccess(await manager.AddPassword(user.Id, "password"));
Assert.True(await manager.HasPassword(user.Id));
var logins = await manager.GetLogins(user.Id); var logins = await manager.GetLogins(user.Id);
Assert.NotNull(logins); Assert.NotNull(logins);
Assert.Equal(1, logins.Count()); Assert.Equal(1, logins.Count());
@ -165,6 +168,27 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
IdentityResultAssert.IsFailure(await manager.Create(user2), "Name dupe is already taken."); IdentityResultAssert.IsFailure(await manager.Create(user2), "Name dupe is already taken.");
} }
[Fact]
public async Task AddDupeEmailAllowedByDefault()
{
var manager = CreateManager();
var user = new InMemoryUser("dupe") {Email = "yup@yup.com"};
var user2 = new InMemoryUser("dupeEmail") { Email = "yup@yup.com" };
IdentityResultAssert.IsSuccess(await manager.Create(user));
IdentityResultAssert.IsSuccess(await manager.Create(user2));
}
[Fact]
public async Task AddDupeEmailFallsWhenUniqueEmailRequired()
{
var manager = CreateManager();
manager.UserValidator = new UserValidator<InMemoryUser, string> { RequireUniqueEmail = true };
var user = new InMemoryUser("dupe") { Email = "yup@yup.com" };
var user2 = new InMemoryUser("dupeEmail") { Email = "yup@yup.com" };
IdentityResultAssert.IsSuccess(await manager.Create(user));
IdentityResultAssert.IsFailure(await manager.Create(user2), "Email 'yup@yup.com' is already taken.");
}
[Fact] [Fact]
public async Task UpdateSecurityStampActuallyChanges() public async Task UpdateSecurityStampActuallyChanges()
{ {
@ -235,23 +259,91 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
} }
// TODO: No token provider implementations yet // TODO: No token provider implementations yet
//[Fact] private class StaticTokenProvider : IUserTokenProvider<InMemoryUser, string>
//public async Task ConfirmEmailTest() {
//{ private static string MakeToken(string purpose, IUser<string> user)
// var manager = CreateManager(); {
// var user = new InMemoryUser("test"); return string.Join(":", user.Id, purpose, "ImmaToken");
// Assert.False(user.EmailConfirmed); }
// IdentityResultAssert.IsSuccess(await manager.Create(user));
// var token = await manager.GenerateEmailConfirmationToken(user.Id);
// Assert.NotNull(token);
// IdentityResultAssert.IsSuccess(await manager.ConfirmEmail(user.Id, token));
// Assert.True(await manager.IsEmailConfirmed(user.Id));
// IdentityResultAssert.IsSuccess(await manager.SetEmail(user.Id, null));
// Assert.False(await manager.IsEmailConfirmed(user.Id));
//}
public Task<string> Generate(string purpose, UserManager<InMemoryUser, string> manager,
InMemoryUser user)
{
return Task.FromResult(MakeToken(purpose, user));
}
public Task<bool> Validate(string purpose, string token, UserManager<InMemoryUser, string> manager,
InMemoryUser user)
{
return Task.FromResult(token == MakeToken(purpose, user));
}
public Task Notify(string token, UserManager<InMemoryUser, string> manager, InMemoryUser user)
{
return Task.FromResult(0);
}
public Task<bool> IsValidProviderForUser(UserManager<InMemoryUser, string> manager, InMemoryUser user)
{
return Task.FromResult(true);
}
}
[Fact]
public async Task CanResetPasswordWithStaticTokenProvider()
{
var manager = CreateManager();
manager.UserTokenProvider = new StaticTokenProvider();
var user = new InMemoryUser("ResetPasswordTest");
const string password = "password";
const string newPassword = "newpassword";
IdentityResultAssert.IsSuccess(await manager.Create(user, password));
var stamp = user.SecurityStamp;
Assert.NotNull(stamp);
var token = await manager.GeneratePasswordResetToken(user.Id);
Assert.NotNull(token);
IdentityResultAssert.IsSuccess(await manager.ResetPassword(user.Id, token, newPassword));
Assert.Null(await manager.Find(user.UserName, password));
Assert.Equal(user, await manager.Find(user.UserName, newPassword));
Assert.NotEqual(stamp, user.SecurityStamp);
}
[Fact]
public async Task CanGenerateAndVerifyUserTokenWithStaticTokenProvider()
{
var manager = CreateManager();
manager.UserTokenProvider = new StaticTokenProvider();
var user = new InMemoryUser("UserTokenTest");
var user2 = new InMemoryUser("UserTokenTest2");
IdentityResultAssert.IsSuccess(await manager.Create(user));
IdentityResultAssert.IsSuccess(await manager.Create(user2));
var token = await manager.GenerateUserToken("test", user.Id);
Assert.True(await manager.VerifyUserToken(user.Id, "test", token));
Assert.False(await manager.VerifyUserToken(user.Id, "test2", token));
Assert.False(await manager.VerifyUserToken(user.Id, "test", token + "a"));
Assert.False(await manager.VerifyUserToken(user2.Id, "test", token));
}
[Fact]
public async Task CanConfirmEmailWithStaticToken()
{
var manager = CreateManager();
manager.UserTokenProvider = new StaticTokenProvider();
var user = new InMemoryUser("test");
Assert.False(user.EmailConfirmed);
IdentityResultAssert.IsSuccess(await manager.Create(user));
var token = await manager.GenerateEmailConfirmationToken(user.Id);
Assert.NotNull(token);
IdentityResultAssert.IsSuccess(await manager.ConfirmEmail(user.Id, token));
Assert.True(await manager.IsEmailConfirmed(user.Id));
IdentityResultAssert.IsSuccess(await manager.SetEmail(user.Id, null));
Assert.False(await manager.IsEmailConfirmed(user.Id));
}
// TODO: Can't reenable til we have a SecurityStamp linked token provider
//[Fact] //[Fact]
//public async Task ConfirmTokenFailsAfterPasswordChangeTest() //public async Task ConfirmTokenFailsAfterPasswordChange()
//{ //{
// var manager = CreateManager(); // var manager = CreateManager();
// var user = new InMemoryUser("test"); // var user = new InMemoryUser("test");
@ -446,25 +538,40 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
Assert.True(await manager.RoleExists(role.Name)); Assert.True(await manager.RoleExists(role.Name));
} }
//[Fact] private class AlwaysBadValidator : IUserValidator<InMemoryUser, string>, IRoleValidator<InMemoryRole, string>
//public async Task BadValidatorBlocksCreateTest() {
//{ public const string ErrorMessage = "I'm Bad.";
// var manager = CreateRoleManager();
// manager.RoleValidator = new AlwaysBadValidator<InMemoryRole>();
// IdentityResultAssert.IsFailure(await manager.Create(new InMemoryRole("blocked")),
// AlwaysBadValidator<InMemoryRole>.ErrorMessage);
//}
//[Fact] public Task<IdentityResult> Validate(UserManager<InMemoryUser, string> manager, InMemoryUser user)
//public async Task BadValidatorBlocksAllUpdatesTest() {
//{ return Task.FromResult(IdentityResult.Failed(ErrorMessage));
// var manager = CreateRoleManager(); }
// var role = new InMemoryRole("poorguy");
// IdentityResultAssert.IsSuccess(await manager.Create(role)); public Task<IdentityResult> Validate(RoleManager<InMemoryRole, string> manager, InMemoryRole role)
// var error = AlwaysBadValidator<InMemoryRole>.ErrorMessage; {
// manager.RoleValidator = new AlwaysBadValidator<InMemoryRole>(); return Task.FromResult(IdentityResult.Failed(ErrorMessage));
// IdentityResultAssert.IsFailure(await manager.Update(role), error); }
//} }
[Fact]
public async Task BadValidatorBlocksCreateRole()
{
var manager = CreateRoleManager();
manager.RoleValidator = new AlwaysBadValidator();
IdentityResultAssert.IsFailure(await manager.Create(new InMemoryRole("blocked")),
AlwaysBadValidator.ErrorMessage);
}
[Fact]
public async Task BadValidatorBlocksRoleUpdate()
{
var manager = CreateRoleManager();
var role = new InMemoryRole("poorguy");
IdentityResultAssert.IsSuccess(await manager.Create(role));
var error = AlwaysBadValidator.ErrorMessage;
manager.RoleValidator = new AlwaysBadValidator();
IdentityResultAssert.IsFailure(await manager.Update(role), error);
}
[Fact] [Fact]
public async Task CanDeleteRoleTest() public async Task CanDeleteRoleTest()
@ -801,28 +908,76 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
Assert.False(await manager.VerifyChangePhoneNumberToken(user.Id, token1, num2)); Assert.False(await manager.VerifyChangePhoneNumberToken(user.Id, token1, num2));
} }
//[Fact] private class EmailTokenProvider : IUserTokenProvider<InMemoryUser, string>
//public async Task EmailTokenFactorTest() {
//{
// var manager = CreateManager(); public Task<string> Generate(string purpose, UserManager<InMemoryUser, string> manager, InMemoryUser user)
// var messageService = new TestMessageService(); {
// manager.EmailService = messageService; return Task.FromResult(purpose);
// const string factorId = "EmailCode"; }
// manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider<InMemoryUser>());
// var user = new InMemoryUser("EmailCodeTest") { Email = "foo@foo.com" }; public Task<bool> Validate(string purpose, string token, UserManager<InMemoryUser, string> manager, InMemoryUser user)
// const string password = "password"; {
// IdentityResultAssert.IsSuccess(await manager.Create(user, password)); return Task.FromResult(token == purpose);
// var stamp = user.SecurityStamp; }
// Assert.NotNull(stamp);
// var token = await manager.GenerateTwoFactorToken(user.Id, factorId); public Task Notify(string token, UserManager<InMemoryUser, string> manager, InMemoryUser user)
// Assert.NotNull(token); {
// Assert.Null(messageService.Message); return manager.SendEmail(user.Id, token, token);
// IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorToken(user.Id, factorId, token)); }
// Assert.NotNull(messageService.Message);
// Assert.Equal(String.Empty, messageService.Message.Subject); public Task<bool> IsValidProviderForUser(UserManager<InMemoryUser, string> manager, InMemoryUser user)
// Assert.Equal(token, messageService.Message.Body); {
// Assert.True(await manager.VerifyTwoFactorToken(user.Id, factorId, token)); return Task.FromResult(true);
//} }
}
private class SmsTokenProvider : IUserTokenProvider<InMemoryUser, string>
{
public Task<string> Generate(string purpose, UserManager<InMemoryUser, string> manager, InMemoryUser user)
{
return Task.FromResult(purpose);
}
public Task<bool> Validate(string purpose, string token, UserManager<InMemoryUser, string> manager, InMemoryUser user)
{
return Task.FromResult(token == purpose);
}
public Task Notify(string token, UserManager<InMemoryUser, string> manager, InMemoryUser user)
{
return manager.SendSms(user.Id, token);
}
public Task<bool> IsValidProviderForUser(UserManager<InMemoryUser, string> manager, InMemoryUser user)
{
return Task.FromResult(true);
}
}
[Fact]
public async Task CanEmailTwoFactorToken()
{
var manager = CreateManager();
var messageService = new TestMessageService();
manager.EmailService = messageService;
const string factorId = "EmailCode";
manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider());
var user = new InMemoryUser("EmailCodeTest") { Email = "foo@foo.com" };
const string password = "password";
IdentityResultAssert.IsSuccess(await manager.Create(user, password));
var stamp = user.SecurityStamp;
Assert.NotNull(stamp);
var token = await manager.GenerateTwoFactorToken(user.Id, factorId);
Assert.NotNull(token);
Assert.Null(messageService.Message);
IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorToken(user.Id, factorId, token));
Assert.NotNull(messageService.Message);
Assert.Equal(token, messageService.Message.Subject);
Assert.Equal(token, messageService.Message.Body);
Assert.True(await manager.VerifyTwoFactorToken(user.Id, factorId, token));
}
//[Fact] //[Fact]
//public async Task EmailTokenFactorWithFormatTest() //public async Task EmailTokenFactorWithFormatTest()
@ -867,20 +1022,18 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
// Assert.False(await manager.VerifyTwoFactorToken(user.Id, factorId, token)); // Assert.False(await manager.VerifyTwoFactorToken(user.Id, factorId, token));
//} //}
//[Fact] [Fact]
//public async Task UserTwoFactorProviderTest() public async Task EnableTwoFactorChangesSecurityStamp()
//{ {
// var manager = CreateManager(); var manager = CreateManager();
// const string factorId = "PhoneCode"; var user = new InMemoryUser("TwoFactorEnabledTest");
// manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider<InMemoryUser>()); IdentityResultAssert.IsSuccess(await manager.Create(user));
// var user = new InMemoryUser("PhoneCodeTest"); var stamp = user.SecurityStamp;
// IdentityResultAssert.IsSuccess(await manager.Create(user)); Assert.NotNull(stamp);
// var stamp = user.SecurityStamp; IdentityResultAssert.IsSuccess(await manager.SetTwoFactorEnabled(user.Id, true));
// Assert.NotNull(stamp); Assert.NotEqual(stamp, await manager.GetSecurityStamp(user.Id));
// IdentityResultAssert.IsSuccess(await manager.SetTwoFactorEnabled(user.Id, true)); Assert.True(await manager.GetTwoFactorEnabled(user.Id));
// Assert.NotEqual(stamp, await manager.GetSecurityStamp(user.Id)); }
// Assert.True(await manager.GetTwoFactorEnabled(user.Id));
//}
[Fact] [Fact]
public async Task CanSendSms() public async Task CanSendSms()
@ -909,26 +1062,26 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
Assert.Equal("Body", messageService.Message.Body); Assert.Equal("Body", messageService.Message.Body);
} }
//[Fact] [Fact]
//public async Task PhoneTokenFactorTest() public async Task CanSmsTwoFactorToken()
//{ {
// var manager = CreateManager(); var manager = CreateManager();
// var messageService = new TestMessageService(); var messageService = new TestMessageService();
// manager.SmsService = messageService; manager.SmsService = messageService;
// const string factorId = "PhoneCode"; const string factorId = "PhoneCode";
// manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider<InMemoryUser>()); manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider());
// var user = new InMemoryUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; var user = new InMemoryUser("PhoneCodeTest") { PhoneNumber = "4251234567" };
// IdentityResultAssert.IsSuccess(await manager.Create(user)); IdentityResultAssert.IsSuccess(await manager.Create(user));
// var stamp = user.SecurityStamp; var stamp = user.SecurityStamp;
// Assert.NotNull(stamp); Assert.NotNull(stamp);
// var token = await manager.GenerateTwoFactorToken(user.Id, factorId); var token = await manager.GenerateTwoFactorToken(user.Id, factorId);
// Assert.NotNull(token); Assert.NotNull(token);
// Assert.Null(messageService.Message); Assert.Null(messageService.Message);
// IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorToken(user.Id, factorId, token)); IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorToken(user.Id, factorId, token));
// Assert.NotNull(messageService.Message); Assert.NotNull(messageService.Message);
// Assert.Equal(token, messageService.Message.Body); Assert.Equal(token, messageService.Message.Body);
// Assert.True(await manager.VerifyTwoFactorToken(user.Id, factorId, token)); Assert.True(await manager.VerifyTwoFactorToken(user.Id, factorId, token));
//} }
//[Fact] //[Fact]
//public async Task PhoneTokenFactorFormatTest() //public async Task PhoneTokenFactorFormatTest()
@ -961,8 +1114,8 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
var user = new InMemoryUser("PhoneCodeTest"); var user = new InMemoryUser("PhoneCodeTest");
IdentityResultAssert.IsSuccess(await manager.Create(user)); IdentityResultAssert.IsSuccess(await manager.Create(user));
const string error = "No IUserTwoFactorProvider for 'bogus' is registered."; const string error = "No IUserTwoFactorProvider for 'bogus' is registered.";
await ExceptionHelper.ThrowsWithError<NotSupportedException>(() => manager.GenerateTwoFactorToken(user.Id, "bogus"), error); await ExceptionAssert.ThrowsAsync<NotSupportedException>(() => manager.GenerateTwoFactorToken(user.Id, "bogus"), error);
await ExceptionHelper.ThrowsWithError<NotSupportedException>( await ExceptionAssert.ThrowsAsync<NotSupportedException>(
() => manager.VerifyTwoFactorToken(user.Id, "bogus", "bogus"), error); () => manager.VerifyTwoFactorToken(user.Id, "bogus", "bogus"), error);
} }

View File

@ -4,6 +4,7 @@
"Microsoft.AspNet.Identity" : "0.1-alpha-*", "Microsoft.AspNet.Identity" : "0.1-alpha-*",
"Microsoft.AspNet.Identity.InMemory" : "0.1-alpha-*", "Microsoft.AspNet.Identity.InMemory" : "0.1-alpha-*",
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*", "Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
"Microsoft.AspNet.Testing" : "0.1-alpha-*",
"Xunit.KRunner": "0.1-alpha-*", "Xunit.KRunner": "0.1-alpha-*",
"xunit.abstractions": "2.0.0-aspnet-*", "xunit.abstractions": "2.0.0-aspnet-*",
"xunit.assert": "2.0.0-aspnet-*", "xunit.assert": "2.0.0-aspnet-*",

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNet.Identity.Test
{
public class IdentityResultTest
{
[Fact]
public void VerifyDefaultConstructor()
{
var result = new IdentityResult();
Assert.False(result.Succeeded);
Assert.Equal(1, result.Errors.Count());
Assert.Equal("An unknown failure has occured.", result.Errors.First());
}
}
}

View File

@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Security.Claims;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Identity.Test
{
public class NoopRoleStore : IRoleStore<TestRole, string>
{
public Task Create(TestRole user)
{
return Task.FromResult(0);
}
public Task Update(TestRole user)
{
return Task.FromResult(0);
}
public Task<TestRole> FindById(string roleId)
{
return Task.FromResult<TestRole>(null);
}
public Task<TestRole> FindByName(string userName)
{
return Task.FromResult<TestRole>(null);
}
public void Dispose()
{
}
public Task Delete(TestRole user)
{
return Task.FromResult(0);
}
}
}

View File

@ -0,0 +1,37 @@
using System.Threading.Tasks;
namespace Microsoft.AspNet.Identity.Test
{
public class NoopUserStore : IUserStore<TestUser, string>
{
public Task Create(TestUser user)
{
return Task.FromResult(0);
}
public Task Update(TestUser user)
{
return Task.FromResult(0);
}
public Task<TestUser> FindById(string userId)
{
return Task.FromResult<TestUser>(null);
}
public Task<TestUser> FindByName(string userName)
{
return Task.FromResult<TestUser>(null);
}
public void Dispose()
{
}
public Task Delete(TestUser user)
{
return Task.FromResult(0);
}
}
}

View File

@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Security.Claims;
using Moq;
using System;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNet.Identity.Test
{
public class RoleManagerTest
{
[Fact]
public void ConstructorThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>("store", () => new RoleManager<TestRole, string>(null));
}
[Fact]
public void RolesQueryableFailWhenStoreNotImplemented()
{
var manager = new RoleManager<TestRole, string>(new NoopRoleStore());
Assert.False(manager.SupportsQueryableRoles);
Assert.Throws<NotSupportedException>(() => manager.Roles.Count());
}
[Fact]
public void DisposeAfterDisposeDoesNotThrow()
{
var manager = new RoleManager<TestRole, string>(new NoopRoleStore());
manager.Dispose();
manager.Dispose();
}
[Fact]
public async Task RoleManagerPublicNullChecks()
{
Assert.Throws<ArgumentNullException>("store",
() => new RoleManager<TestRole, string>(null));
var manager = new RoleManager<TestRole, string>(new NotImplementedStore());
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.Create(null));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.Update(null));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.Delete(null));
await Assert.ThrowsAsync<ArgumentNullException>("roleName", async () => await manager.FindByName(null));
}
private class NotImplementedStore : IRoleStore<TestRole, string>
{
public Task Create(TestRole role)
{
throw new NotImplementedException();
}
public Task Update(TestRole role)
{
throw new NotImplementedException();
}
public Task Delete(TestRole role)
{
throw new NotImplementedException();
}
public Task<TestRole> FindById(string roleId)
{
throw new NotImplementedException();
}
public Task<TestRole> FindByName(string roleName)
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
}
}
}

View File

@ -0,0 +1,9 @@
namespace Microsoft.AspNet.Identity.Test
{
public class TestRole : IRole<string>
{
public string Id { get; private set; }
public string Name { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace Microsoft.AspNet.Identity.Test
{
public class TestUser : IUser<string>
{
public string Id { get; private set; }
public string UserName { get; set; }
}
}

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNet.Testing;
using Moq; using Moq;
using System; using System;
using System.Linq; using System.Linq;
@ -143,122 +144,151 @@ namespace Microsoft.AspNet.Identity.Test
} }
[Fact] [Fact]
public void DisposeAfterDisposeWorksTest() public void DisposeAfterDisposeDoesNotThrow()
{ {
var manager = new UserManager<TestUser, string>(new NoopUserStore()); var manager = new UserManager<TestUser, string>(new NoopUserStore());
manager.Dispose(); manager.Dispose();
manager.Dispose(); manager.Dispose();
} }
[Fact] private class BadPasswordValidtor : IPasswordValidator
public async Task ManagerPublicNullCheckTest()
{ {
Assert.Throws<ArgumentNullException>(() => new UserManager<TestUser, string>((IUserStore<TestUser, string>)null)); public const string ErrorMessage = "I'm Bad.";
public Task<IdentityResult> Validate(string password)
{
return Task.FromResult(IdentityResult.Failed(ErrorMessage));
}
}
[Fact]
public async Task PasswordValidatorBlocksCreate()
{
// TODO: Can switch to Mock eventually
var manager = new UserManager<TestUser, string>(new EmptyStore())
{
PasswordValidator = new BadPasswordValidtor()
};
IdentityResultAssert.IsFailure(await manager.Create(new TestUser(), "password"),
BadPasswordValidtor.ErrorMessage);
}
[Fact]
public async Task ManagerPublicNullChecks()
{
Assert.Throws<ArgumentNullException>("store", () => new UserManager<TestUser, string>((IUserStore<TestUser, string>)null));
var manager = new UserManager<TestUser, string>(new NotImplementedStore()); var manager = new UserManager<TestUser, string>(new NotImplementedStore());
Assert.Throws<ArgumentNullException>(() => manager.ClaimsIdentityFactory = null); Assert.Throws<ArgumentNullException>(() => manager.ClaimsIdentityFactory = null);
Assert.Throws<ArgumentNullException>(() => manager.PasswordHasher = null); Assert.Throws<ArgumentNullException>(() => manager.PasswordHasher = null);
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.CreateIdentity(null, "whatever")); await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.CreateIdentity(null, "whatever"));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.Create(null)); await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.Create(null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.Create(null, null)); await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.Create(null, null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.Create(new TestUser(), null)); await Assert.ThrowsAsync<ArgumentNullException>("password", async () => await manager.Create(new TestUser(), null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.Update(null)); await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.Update(null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.Delete(null)); await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.Delete(null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.AddClaim("bogus", null)); await Assert.ThrowsAsync<ArgumentNullException>("claim", async () => await manager.AddClaim("bogus", null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.FindByName(null)); await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByName(null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.Find(null, null)); await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.Find(null, null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.AddLogin("bogus", null)); await Assert.ThrowsAsync<ArgumentNullException>("login", async () => await manager.AddLogin("bogus", null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.RemoveLogin("bogus", null)); await Assert.ThrowsAsync<ArgumentNullException>("login", async () => await manager.RemoveLogin("bogus", null));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await manager.FindByEmail(null)); await Assert.ThrowsAsync<ArgumentNullException>("email", async () => await manager.FindByEmail(null));
Assert.Throws<ArgumentNullException>(() => manager.RegisterTwoFactorProvider(null, null)); Assert.Throws<ArgumentNullException>("twoFactorProvider", () => manager.RegisterTwoFactorProvider(null, null));
Assert.Throws<ArgumentNullException>(() => manager.RegisterTwoFactorProvider("bogus", null)); Assert.Throws<ArgumentNullException>("provider", () => manager.RegisterTwoFactorProvider("bogus", null));
} }
//[Fact] [Fact]
//public void MethodsFailWithUnknownUserTest() public async Task MethodsFailWithUnknownUserTest()
//{ {
// var db = IdentityResultExtensions.CreateDefaultDb(); var manager = new UserManager<TestUser, string>(new EmptyStore())
// var manager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(db)); {
// manager.UserTokenProvider = new NoOpTokenProvider(); UserTokenProvider = new NoOpTokenProvider()
// var error = "UserId not found."; };
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( const string error = "UserId not found.";
// () => AsyncHelper.RunSync(() => manager.AddClaimAsync(null, new Claim("a", "b"))), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.AddClaim(null, new Claim("a", "b")), error);
// () => AsyncHelper.RunSync(() => manager.AddLoginAsync(null, new UserLoginInfo("", ""))), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.AddLogin(null, new UserLoginInfo("", "")), error);
// () => AsyncHelper.RunSync(() => manager.AddPasswordAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.AddPassword(null, null), error);
// () => AsyncHelper.RunSync(() => manager.AddToRoleAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.AddToRole(null, null), error);
// () => AsyncHelper.RunSync(() => manager.ChangePasswordAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.ChangePassword(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.GetClaimsAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetClaims(null), error);
// () => AsyncHelper.RunSync(() => manager.GetLoginsAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetLogins(null), error);
// () => AsyncHelper.RunSync(() => manager.GetRolesAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetRoles(null), error);
// () => AsyncHelper.RunSync(() => manager.IsInRoleAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.IsInRole(null, null), error);
// () => AsyncHelper.RunSync(() => manager.RemoveClaimAsync(null, new Claim("a", "b"))), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.RemoveClaim(null, new Claim("a", "b")), error);
// () => AsyncHelper.RunSync(() => manager.RemoveLoginAsync(null, new UserLoginInfo("", ""))), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.RemoveLogin(null, new UserLoginInfo("", "")), error);
// () => AsyncHelper.RunSync(() => manager.RemovePasswordAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.RemovePassword(null), error);
// () => AsyncHelper.RunSync(() => manager.RemoveFromRoleAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.RemoveFromRole(null, null), error);
// () => AsyncHelper.RunSync(() => manager.UpdateSecurityStampAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.UpdateSecurityStamp(null), error);
// () => AsyncHelper.RunSync(() => manager.GetSecurityStampAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetSecurityStamp(null), error);
// () => AsyncHelper.RunSync(() => manager.HasPasswordAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.HasPassword(null), error);
// () => AsyncHelper.RunSync(() => manager.GeneratePasswordResetTokenAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GeneratePasswordResetToken(null), error);
// () => AsyncHelper.RunSync(() => manager.ResetPasswordAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.ResetPassword(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.IsEmailConfirmedAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.IsEmailConfirmed(null), error);
// () => AsyncHelper.RunSync(() => manager.GenerateEmailConfirmationTokenAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GenerateEmailConfirmationToken(null), error);
// () => AsyncHelper.RunSync(() => manager.ConfirmEmailAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.ConfirmEmail(null, null), error);
// () => AsyncHelper.RunSync(() => manager.GetEmailAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetEmail(null), error);
// () => AsyncHelper.RunSync(() => manager.SetEmailAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.SetEmail(null, null), error);
// () => AsyncHelper.RunSync(() => manager.IsPhoneNumberConfirmedAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.IsPhoneNumberConfirmed(null), error);
// () => AsyncHelper.RunSync(() => manager.ChangePhoneNumberAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.ChangePhoneNumber(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.VerifyChangePhoneNumberTokenAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.VerifyChangePhoneNumberToken(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.GetPhoneNumberAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetPhoneNumber(null), error);
// () => AsyncHelper.RunSync(() => manager.SetPhoneNumberAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.SetPhoneNumber(null, null), error);
// () => AsyncHelper.RunSync(() => manager.GetTwoFactorEnabledAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetTwoFactorEnabled(null), error);
// () => AsyncHelper.RunSync(() => manager.SetTwoFactorEnabledAsync(null, true)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.SetTwoFactorEnabled(null, true), error);
// () => AsyncHelper.RunSync(() => manager.GenerateTwoFactorTokenAsync(null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GenerateTwoFactorToken(null, null), error);
// () => AsyncHelper.RunSync(() => manager.VerifyTwoFactorTokenAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.VerifyTwoFactorToken(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.NotifyTwoFactorTokenAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.NotifyTwoFactorToken(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.GetValidTwoFactorProvidersAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetValidTwoFactorProviders(null), error);
// () => AsyncHelper.RunSync(() => manager.VerifyUserTokenAsync(null, null, null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.VerifyUserToken(null, null, null), error);
// () => AsyncHelper.RunSync(() => manager.AccessFailedAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.AccessFailed(null), error);
// () => AsyncHelper.RunSync(() => manager.SetLockoutEnabledAsync(null, false)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.ResetAccessFailedCount(null), error);
// () => AsyncHelper.RunSync(() => manager.SetLockoutEndDateAsync(null, DateTimeOffset.UtcNow)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
// ExceptionHelper.ThrowsWithError<InvalidOperationException>( async () => await manager.GetLockoutEnabled(null), error);
// () => AsyncHelper.RunSync(() => manager.IsLockedOutAsync(null)), error); await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
//} async () => await manager.SetLockoutEnabled(null, false), error);
await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
async () => await manager.SetLockoutEndDate(null, DateTimeOffset.UtcNow), error);
await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
async () => await manager.GetLockoutEndDate(null), error);
await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
async () => await manager.IsLockedOut(null), error);
}
[Fact] [Fact]
public async Task MethodsThrowWhenDisposedTest() public async Task MethodsThrowWhenDisposedTest()
@ -297,14 +327,45 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmail(null, null)); await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmail(null, null));
} }
private class TestUser : IUser<string> private class NoOpTokenProvider : IUserTokenProvider<TestUser, string>
{ {
public string Id { get; private set; }
public string UserName { get; set; } public Task<string> Generate(string purpose, UserManager<TestUser, string> manager, TestUser user)
{
return Task.FromResult("Test");
}
public Task<bool> Validate(string purpose, string token, UserManager<TestUser, string> manager, TestUser user)
{
return Task.FromResult(true);
}
public Task Notify(string token, UserManager<TestUser, string> manager, TestUser user)
{
return Task.FromResult(0);
}
public Task<bool> IsValidProviderForUser(UserManager<TestUser, string> manager, TestUser user)
{
return Task.FromResult(true);
}
} }
private class NoopUserStore : IUserStore<TestUser, string> private class EmptyStore :
IUserPasswordStore<TestUser, string>,
IUserClaimStore<TestUser, string>,
IUserLoginStore<TestUser, string>,
IUserEmailStore<TestUser, string>,
IUserPhoneNumberStore<TestUser, string>,
IUserLockoutStore<TestUser, string>,
IUserTwoFactorStore<TestUser, string>,
IUserRoleStore<TestUser, string>,
IUserSecurityStampStore<TestUser, string>
{ {
public void Dispose()
{
}
public Task Create(TestUser user) public Task Create(TestUser user)
{ {
return Task.FromResult(0); return Task.FromResult(0);
@ -315,6 +376,11 @@ namespace Microsoft.AspNet.Identity.Test
return Task.FromResult(0); return Task.FromResult(0);
} }
public Task Delete(TestUser user)
{
return Task.FromResult(0);
}
public Task<TestUser> FindById(string userId) public Task<TestUser> FindById(string userId)
{ {
return Task.FromResult<TestUser>(null); return Task.FromResult<TestUser>(null);
@ -325,18 +391,177 @@ namespace Microsoft.AspNet.Identity.Test
return Task.FromResult<TestUser>(null); return Task.FromResult<TestUser>(null);
} }
public void Dispose() public Task SetPasswordHash(TestUser user, string passwordHash)
{
}
public Task Delete(TestUser user)
{ {
return Task.FromResult(0); return Task.FromResult(0);
} }
public Task<string> GetPasswordHash(TestUser user)
{
return Task.FromResult<string>(null);
}
public Task<bool> HasPassword(TestUser user)
{
return Task.FromResult(false);
}
public Task<IList<Claim>> GetClaims(TestUser user)
{
return Task.FromResult<IList<Claim>>(new List<Claim>());
}
public Task AddClaim(TestUser user, Claim claim)
{
return Task.FromResult(0);
}
public Task RemoveClaim(TestUser user, Claim claim)
{
return Task.FromResult(0);
}
public Task AddLogin(TestUser user, UserLoginInfo login)
{
return Task.FromResult(0);
}
public Task RemoveLogin(TestUser user, UserLoginInfo login)
{
return Task.FromResult(0);
}
public Task<IList<UserLoginInfo>> GetLogins(TestUser user)
{
return Task.FromResult<IList<UserLoginInfo>>(new List<UserLoginInfo>());
}
public Task<TestUser> Find(UserLoginInfo login)
{
return Task.FromResult<TestUser>(null);
}
public Task SetEmail(TestUser user, string email)
{
return Task.FromResult(0);
}
public Task<string> GetEmail(TestUser user)
{
return Task.FromResult("");
}
public Task<bool> GetEmailConfirmed(TestUser user)
{
return Task.FromResult(false);
}
public Task SetEmailConfirmed(TestUser user, bool confirmed)
{
return Task.FromResult(0);
}
public Task<TestUser> FindByEmail(string email)
{
return Task.FromResult<TestUser>(null);
}
public Task SetPhoneNumber(TestUser user, string phoneNumber)
{
return Task.FromResult(0);
}
public Task<string> GetPhoneNumber(TestUser user)
{
return Task.FromResult("");
}
public Task<bool> GetPhoneNumberConfirmed(TestUser user)
{
return Task.FromResult(false);
}
public Task SetPhoneNumberConfirmed(TestUser user, bool confirmed)
{
return Task.FromResult(0);
}
public Task<DateTimeOffset> GetLockoutEndDate(TestUser user)
{
return Task.FromResult(DateTimeOffset.MinValue);
}
public Task SetLockoutEndDate(TestUser user, DateTimeOffset lockoutEnd)
{
return Task.FromResult(0);
}
public Task<int> IncrementAccessFailedCount(TestUser user)
{
return Task.FromResult(0);
}
public Task ResetAccessFailedCount(TestUser user)
{
return Task.FromResult(0);
}
public Task<int> GetAccessFailedCount(TestUser user)
{
return Task.FromResult(0);
}
public Task<bool> GetLockoutEnabled(TestUser user)
{
return Task.FromResult(false);
}
public Task SetLockoutEnabled(TestUser user, bool enabled)
{
return Task.FromResult(0);
}
public Task SetTwoFactorEnabled(TestUser user, bool enabled)
{
return Task.FromResult(0);
}
public Task<bool> GetTwoFactorEnabled(TestUser user)
{
return Task.FromResult(false);
}
public Task AddToRole(TestUser user, string roleName)
{
return Task.FromResult(0);
}
public Task RemoveFromRole(TestUser user, string roleName)
{
return Task.FromResult(0);
}
public Task<IList<string>> GetRoles(TestUser user)
{
return Task.FromResult<IList<string>>(new List<string>());
}
public Task<bool> IsInRole(TestUser user, string roleName)
{
return Task.FromResult(false);
}
public Task SetSecurityStamp(TestUser user, string stamp)
{
return Task.FromResult(0);
}
public Task<string> GetSecurityStamp(TestUser user)
{
return Task.FromResult("");
}
} }
private class NotImplementedStore : private class NotImplementedStore :
IUserPasswordStore<TestUser, string>, IUserPasswordStore<TestUser, string>,
IUserClaimStore<TestUser, string>, IUserClaimStore<TestUser, string>,

View File

@ -0,0 +1,96 @@
using System;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNet.Identity.Test
{
public class UserValidatorTest
{
[Fact]
public async Task ValidateThrowsWithNull()
{
// Setup
var manager = new UserManager<TestUser, string>(new NoopUserStore());
var validator = new UserValidator<TestUser, string>();
// Act
// Assert
await Assert.ThrowsAsync<ArgumentNullException>("manager", () => validator.Validate(null, null));
await Assert.ThrowsAsync<ArgumentNullException>("user", () => validator.Validate(manager, null));
}
[Theory,
InlineData(null),
InlineData("")]
public async Task ValidateFailsWithTooShortUserNames(string input)
{
// Setup
var manager = new UserManager<TestUser, string>(new NoopUserStore());
var validator = new UserValidator<TestUser, string>();
var user = new TestUser() { UserName = input };
// Act
var result = await validator.Validate(manager, user);
// Assert
IdentityResultAssert.IsFailure(result, "UserName cannot be null or empty.");
}
[Theory,
InlineData("test_email@foo.com", true),
InlineData("hao", true),
InlineData("test123", true),
InlineData("!noway", false),
InlineData("foo@boz#.com", false),
]
public async Task DefaultAlphaNumericOnlyUserNameValidation(string userName, bool expectSuccess)
{
// Setup
var manager = new UserManager<TestUser, string>(new NoopUserStore());
var validator = new UserValidator<TestUser, string>();
var user = new TestUser() {UserName=userName};
// Act
var result = await validator.Validate(manager, user);
// Assert
if (expectSuccess)
{
IdentityResultAssert.IsSuccess(result);
}
else
{
IdentityResultAssert.IsFailure(result);
}
}
[Theory,
InlineData("test_email@foo.com", true),
InlineData("hao", true),
InlineData("test123", true),
InlineData("!noway", true),
InlineData("foo@boz#.com", true),
]
public async Task CanAllowNonAlphaNumericUserName(string userName, bool expectSuccess)
{
// Setup
var manager = new UserManager<TestUser, string>(new NoopUserStore());
var validator = new UserValidator<TestUser, string>() { AllowOnlyAlphanumericUserNames = false };
var user = new TestUser() { UserName = userName };
// Act
var result = await validator.Validate(manager, user);
// Assert
if (expectSuccess)
{
IdentityResultAssert.IsSuccess(result);
}
else
{
IdentityResultAssert.IsFailure(result);
}
}
}
}

View File

@ -1,8 +1,10 @@
{ {
"version": "0.1-alpha-*", "version": "0.1-alpha-*",
"dependencies": { "dependencies": {
"Microsoft.AspNet.Identity" : "0.1-alpha-*", "Microsoft.AspNet.ConfigurationModel" : "0.1-alpha-*",
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*", "Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
"Microsoft.AspNet.Testing" : "0.1-alpha-*",
"Xunit.KRunner": "0.1-alpha-*", "Xunit.KRunner": "0.1-alpha-*",
"xunit.abstractions": "2.0.0-aspnet-*", "xunit.abstractions": "2.0.0-aspnet-*",
"xunit.assert": "2.0.0-aspnet-*", "xunit.assert": "2.0.0-aspnet-*",