first commit

This commit is contained in:
alexandre-spieser
2017-10-22 00:24:46 +00:00
commit 0dc4240d2c
69 changed files with 17455 additions and 0 deletions
@@ -0,0 +1,97 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNetCore.Identity.Test
{
public abstract class ApiConsistencyTestBase
{
[Fact]
public void Public_inheritable_apis_should_be_virtual()
{
var nonVirtualMethods
= (from type in GetAllTypes(TargetAssembly.DefinedTypes)
where type.IsVisible
&& !type.IsSealed
&& type.DeclaredConstructors.Any(c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly)
&& type.Namespace != null
&& !type.Namespace.EndsWith(".Compiled")
from method in type.DeclaredMethods.Where(m => m.IsPublic && !m.IsStatic)
where GetBasestTypeInAssembly(method.DeclaringType) == type
&& !(method.IsVirtual && !method.IsFinal)
&& !method.Name.StartsWith("get_")
&& !method.Name.StartsWith("set_")
&& !method.Name.Equals("Dispose")
select type.Name + "." + method.Name)
.ToList();
Assert.False(
nonVirtualMethods.Any(),
"\r\n-- Missing virtual APIs --\r\n" + string.Join("\r\n", nonVirtualMethods));
}
[Fact]
public void Async_methods_should_end_with_async_suffix()
{
var asyncMethods
= (from type in GetAllTypes(TargetAssembly.DefinedTypes)
where type.IsVisible
from method in type.DeclaredMethods.Where(m => m.IsPublic)
where GetBasestTypeInAssembly(method.DeclaringType) == type
where typeof(Task).IsAssignableFrom(method.ReturnType)
select method).ToList();
var missingSuffixMethods
= asyncMethods
.Where(method => !method.Name.EndsWith("Async"))
.Select(method => method.DeclaringType.Name + "." + method.Name)
.Except(GetAsyncSuffixExceptions())
.ToList();
Assert.False(
missingSuffixMethods.Any(),
"\r\n-- Missing async suffix --\r\n" + string.Join("\r\n", missingSuffixMethods));
}
protected virtual IEnumerable<string> GetCancellationTokenExceptions()
{
return Enumerable.Empty<string>();
}
protected virtual IEnumerable<string> GetAsyncSuffixExceptions()
{
return Enumerable.Empty<string>();
}
protected abstract Assembly TargetAssembly { get; }
protected virtual IEnumerable<TypeInfo> GetAllTypes(IEnumerable<TypeInfo> types)
{
foreach (var type in types)
{
yield return type;
foreach (var nestedType in GetAllTypes(type.DeclaredNestedTypes))
{
yield return nestedType;
}
}
}
protected TypeInfo GetBasestTypeInAssembly(Type type)
{
while (type.GetTypeInfo()?.BaseType?.GetTypeInfo()?.Assembly == type.GetTypeInfo().Assembly)
{
type = type.GetTypeInfo().BaseType;
}
return type.GetTypeInfo();
}
}
}
@@ -0,0 +1,100 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
namespace Microsoft.AspNetCore.Identity.Test
{
public static class MockHelpers
{
public static StringBuilder LogMessage = new StringBuilder();
public static Mock<UserManager<TUser>> MockUserManager<TUser>() where TUser : class
{
var store = new Mock<IUserStore<TUser>>();
var mgr = new Mock<UserManager<TUser>>(store.Object, null, null, null, null, null, null, null, null);
mgr.Object.UserValidators.Add(new UserValidator<TUser>());
mgr.Object.PasswordValidators.Add(new PasswordValidator<TUser>());
return mgr;
}
public static Mock<RoleManager<TRole>> MockRoleManager<TRole>(IRoleStore<TRole> store = null) where TRole : class
{
store = store ?? new Mock<IRoleStore<TRole>>().Object;
var roles = new List<IRoleValidator<TRole>>();
roles.Add(new RoleValidator<TRole>());
return new Mock<RoleManager<TRole>>(store, roles, new UpperInvariantLookupNormalizer(),
new IdentityErrorDescriber(), null);
}
public static Mock<ILogger<T>> MockILogger<T>(StringBuilder logStore = null) where T : class
{
logStore = logStore ?? LogMessage;
var logger = new Mock<ILogger<T>>();
logger.Setup(x => x.Log(It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<object>(),
It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>()))
.Callback((LogLevel logLevel, EventId eventId, object state, Exception exception, Func<object, Exception, string> formatter) =>
{
if (formatter == null)
{
logStore.Append(state.ToString());
}
else
{
logStore.Append(formatter(state, exception));
}
logStore.Append(" ");
});
logger.Setup(x => x.BeginScope(It.IsAny<object>())).Callback((object state) =>
{
logStore.Append(state.ToString());
logStore.Append(" ");
});
logger.Setup(x => x.IsEnabled(LogLevel.Debug)).Returns(true);
logger.Setup(x => x.IsEnabled(LogLevel.Warning)).Returns(true);
return logger;
}
public static UserManager<TUser> TestUserManager<TUser>(IUserStore<TUser> store = null) where TUser : class
{
store = store ?? new Mock<IUserStore<TUser>>().Object;
var options = new Mock<IOptions<IdentityOptions>>();
var idOptions = new IdentityOptions();
idOptions.Lockout.AllowedForNewUsers = false;
options.Setup(o => o.Value).Returns(idOptions);
var userValidators = new List<IUserValidator<TUser>>();
var validator = new Mock<IUserValidator<TUser>>();
userValidators.Add(validator.Object);
var pwdValidators = new List<PasswordValidator<TUser>>();
pwdValidators.Add(new PasswordValidator<TUser>());
var userManager = new UserManager<TUser>(store, options.Object, new PasswordHasher<TUser>(),
userValidators, pwdValidators, new UpperInvariantLookupNormalizer(),
new IdentityErrorDescriber(), null,
new Mock<ILogger<UserManager<TUser>>>().Object);
validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>()))
.Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
return userManager;
}
public static RoleManager<TRole> TestRoleManager<TRole>(IRoleStore<TRole> store = null) where TRole : class
{
store = store ?? new Mock<IRoleStore<TRole>>().Object;
var roles = new List<IRoleValidator<TRole>>();
roles.Add(new RoleValidator<TRole>());
return new AspNetRoleManager<TRole>(store, roles,
new UpperInvariantLookupNormalizer(),
new IdentityErrorDescriber(),
null,
null);
}
}
}
@@ -0,0 +1,78 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Identity.Test
{
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;
/// <summary>
/// Test priority
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestPriorityAttribute : Attribute
{
/// <summary>
/// ctor
/// </summary>
/// <param name="priority"></param>
public TestPriorityAttribute(int priority)
{
Priority = priority;
}
/// <summary>
/// Priority
/// </summary>
public int Priority { get; private set; }
}
/// <summary>
/// Used to run tests in order.
/// </summary>
public class PriorityOrderer : ITestCaseOrderer
{
/// <summary>
/// Orders tests cases
/// </summary>
/// <typeparam name="XunitTestCase"></typeparam>
/// <param name="testCases"></param>
/// <returns></returns>
public IEnumerable<XunitTestCase> OrderTestCases<XunitTestCase>(IEnumerable<XunitTestCase> testCases) where XunitTestCase : ITestCase
{
var sortedMethods = new SortedDictionary<int, List<XunitTestCase>>();
foreach (XunitTestCase testCase in testCases)
{
int priority = 0;
foreach (IAttributeInfo attr in testCase.TestMethod.Method.GetCustomAttributes((typeof(TestPriorityAttribute)).AssemblyQualifiedName))
priority = attr.GetNamedArgument<int>("Priority");
GetOrCreate(sortedMethods, priority).Add(testCase);
}
foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
{
list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name));
foreach (XunitTestCase testCase in list)
yield return testCase;
}
}
static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
{
TValue result;
if (dictionary.TryGetValue(key, out result)) return result;
result = new TValue();
dictionary[key] = result;
return result;
}
}
}
@@ -0,0 +1,77 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// Represents a Role entity
/// </summary>
public class TestRole : TestRole<string>
{
/// <summary>
/// Constructor
/// </summary>
public TestRole()
{
Id = Guid.NewGuid().ToString();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="roleName"></param>
public TestRole(string roleName) : this()
{
Name = roleName;
}
}
/// <summary>
/// Represents a Role entity
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestRole<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Constructor
/// </summary>
public TestRole() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="roleName"></param>
public TestRole(string roleName) : this()
{
Name = roleName;
}
/// <summary>
/// Role id
/// </summary>
public virtual TKey Id { get; set; }
/// <summary>
/// Navigation property for claims in the role
/// </summary>
public virtual ICollection<TestRoleClaim<TKey>> Claims { get; private set; } = new List<TestRoleClaim<TKey>>();
/// <summary>
/// Role name
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// Normalized name used for equality
/// </summary>
public virtual string NormalizedName { get; set; }
/// <summary>
/// A random value that should change whenever a role is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
}
}
@@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// EntityType that represents one specific role claim
/// </summary>
public class TestRoleClaim : TestRoleClaim<string> { }
/// <summary>
/// EntityType that represents one specific role claim
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestRoleClaim<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Primary key
/// </summary>
public virtual int Id { get; set; }
/// <summary>
/// User Id for the role this claim belongs to
/// </summary>
public virtual TKey RoleId { get; set; }
/// <summary>
/// Claim type
/// </summary>
public virtual string ClaimType { get; set; }
/// <summary>
/// Claim value
/// </summary>
public virtual string ClaimValue { get; set; }
}
}
@@ -0,0 +1,144 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// Test user class
/// </summary>
public class TestUser : TestUser<string>
{
/// <summary>
/// Ctor
/// </summary>
public TestUser()
{
Id = Guid.NewGuid().ToString();
}
/// <summary>
/// Ctor
/// </summary>
/// <param name="userName"></param>
public TestUser(string userName) : this()
{
UserName = userName;
}
}
/// <summary>
/// Test user
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestUser<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// ctor
/// </summary>
public TestUser() { }
/// <summary>
/// ctor
/// </summary>
/// <param name="userName"></param>
public TestUser(string userName) : this()
{
UserName = userName;
}
/// <summary>
/// Id
/// </summary>
public virtual TKey Id { get; set; }
/// <summary>
/// Name
/// </summary>
public virtual string UserName { get; set; }
/// <summary>
/// normalized user name
/// </summary>
public virtual string NormalizedUserName { get; set; }
/// <summary>
/// Email
/// </summary>
public virtual string Email { get; set; }
/// <summary>
/// normalized email
/// </summary>
public virtual string NormalizedEmail { get; set; }
/// <summary>
/// True if the email is confirmed, default is false
/// </summary>
public virtual bool EmailConfirmed { get; set; }
/// <summary>
/// The salted/hashed form of the user password
/// </summary>
public virtual string PasswordHash { get; set; }
/// <summary>
/// A random value that should change whenever a users credentials change (password changed, login removed)
/// </summary>
public virtual string SecurityStamp { get; set; }
/// <summary>
/// A random value that should change whenever a user is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// PhoneNumber for the user
/// </summary>
public virtual string PhoneNumber { get; set; }
/// <summary>
/// True if the phone number is confirmed, default is false
/// </summary>
public virtual bool PhoneNumberConfirmed { get; set; }
/// <summary>
/// Is two factor enabled for the user
/// </summary>
public virtual bool TwoFactorEnabled { get; set; }
/// <summary>
/// DateTime in UTC when lockout ends, any time in the past is considered not locked out.
/// </summary>
public virtual DateTimeOffset? LockoutEnd { get; set; }
/// <summary>
/// Is lockout enabled for this user
/// </summary>
public virtual bool LockoutEnabled { get; set; }
/// <summary>
/// Used to record failures for the purposes of lockout
/// </summary>
public virtual int AccessFailedCount { get; set; }
/// <summary>
/// Navigation property
/// </summary>
public virtual ICollection<TestUserRole<TKey>> Roles { get; private set; } = new List<TestUserRole<TKey>>();
/// <summary>
/// Navigation property
/// </summary>
public virtual ICollection<TestUserClaim<TKey>> Claims { get; private set; } = new List<TestUserClaim<TKey>>();
/// <summary>
/// Navigation property
/// </summary>
public virtual ICollection<TestUserLogin<TKey>> Logins { get; private set; } = new List<TestUserLogin<TKey>>();
/// <summary>
/// Navigation property
/// </summary>
public virtual ICollection<TestUserToken<TKey>> Tokens { get; private set; } = new List<TestUserToken<TKey>>();
}
}
@@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// EntityType that represents one specific user claim
/// </summary>
public class TestUserClaim : TestUserClaim<string> { }
/// <summary>
/// EntityType that represents one specific user claim
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestUserClaim<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Primary key
/// </summary>
public virtual int Id { get; set; }
/// <summary>
/// User Id for the user who owns this claim
/// </summary>
public virtual TKey UserId { get; set; }
/// <summary>
/// Claim type
/// </summary>
public virtual string ClaimType { get; set; }
/// <summary>
/// Claim value
/// </summary>
public virtual string ClaimValue { get; set; }
}
}
@@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// Entity type for a user's login (i.e. facebook, google)
/// </summary>
public class TestUserLogin : TestUserLogin<string> { }
/// <summary>
/// Entity type for a user's login (i.e. facebook, google)
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestUserLogin<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// The login provider for the login (i.e. facebook, google)
/// </summary>
public virtual string LoginProvider { get; set; }
/// <summary>
/// Key representing the login for the provider
/// </summary>
public virtual string ProviderKey { get; set; }
/// <summary>
/// Display name for the login
/// </summary>
public virtual string ProviderDisplayName { get; set; }
/// <summary>
/// User Id for the user who owns this login
/// </summary>
public virtual TKey UserId { get; set; }
}
}
@@ -0,0 +1,29 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// EntityType that represents a user belonging to a role
/// </summary>
public class TestUserRole : TestUserRole<string> { }
/// <summary>
/// EntityType that represents a user belonging to a role
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestUserRole<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// UserId for the user that is in the role
/// </summary>
public virtual TKey UserId { get; set; }
/// <summary>
/// RoleId for the role
/// </summary>
public virtual TKey RoleId { get; set; }
}
}
@@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Identity.Test
{
/// <summary>
/// Entity type for a user's token
/// </summary>
public class TestUserToken : TestUserToken<string> { }
/// <summary>
/// Entity type for a user's token
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class TestUserToken<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// The login provider for the login (i.e. facebook, google)
/// </summary>
public virtual string LoginProvider { get; set; }
/// <summary>
/// Key representing the login for the provider
/// </summary>
public virtual string TokenName { get; set; }
/// <summary>
/// Display name for the login
/// </summary>
public virtual string TokenValue { get; set; }
/// <summary>
/// User Id for the user who owns this login
/// </summary>
public virtual TKey UserId { get; set; }
}
}