Move Identity tests from SQL Server to SQLite for better reliability (#10300)

This commit is contained in:
Arthur Vickers 2019-05-23 16:32:48 -07:00 committed by Nate McMaster
parent 72433039c0
commit eef19949de
35 changed files with 291 additions and 819 deletions

View File

@ -2,6 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Data.Common;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
@ -9,21 +11,36 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
public class InMemoryContext :
InMemoryContext<IdentityUser, IdentityRole, string>
{
public InMemoryContext(DbContextOptions options) : base(options)
private InMemoryContext(DbConnection connection) : base(connection)
{ }
public new static InMemoryContext Create(DbConnection connection)
=> Initialize(new InMemoryContext(connection));
public static TContext Initialize<TContext>(TContext context) where TContext : DbContext
{
context.Database.EnsureCreated();
return context;
}
}
public class InMemoryContext<TUser> :
IdentityUserContext<TUser, string>
where TUser : IdentityUser
{
public InMemoryContext(DbContextOptions options) : base(options)
{ }
private readonly DbConnection _connection;
private InMemoryContext(DbConnection connection)
{
_connection = connection;
}
public static InMemoryContext<TUser> Create(DbConnection connection)
=> InMemoryContext.Initialize(new InMemoryContext<TUser>(connection));
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase("ScratchUsers");
}
=> optionsBuilder.UseSqlite(_connection);
}
public class InMemoryContext<TUser, TRole, TKey> : IdentityDbContext<TUser, TRole, TKey>
@ -31,16 +48,22 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
{
public InMemoryContext(DbContextOptions options) : base(options)
{ }
private readonly DbConnection _connection;
protected InMemoryContext(DbConnection connection)
{
_connection = connection;
}
public static InMemoryContext<TUser, TRole, TKey> Create(DbConnection connection)
=> InMemoryContext.Initialize(new InMemoryContext<TUser, TRole, TKey>(connection));
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase("Scratch");
}
=> optionsBuilder.UseSqlite(_connection);
}
public abstract class InMemoryContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
public abstract class InMemoryContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> :
IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
@ -50,9 +73,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
public InMemoryContext(DbContextOptions options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseInMemoryDatabase("Scratch");
protected InMemoryContext(DbContextOptions options)
: base(options)
{
}
}
}
}

View File

@ -0,0 +1,26 @@
// 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 Microsoft.Data.Sqlite;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
{
public class InMemoryDatabaseFixture : IDisposable
{
private readonly SqliteConnection _connection = new SqliteConnection($"DataSource=:memory:");
public InMemoryDatabaseFixture()
{
_connection.Open();
}
public SqliteConnection Connection => _connection;
public void Dispose()
{
_connection.Close();
_connection.Dispose();
}
}
}

View File

@ -6,13 +6,23 @@ using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
{
public class InMemoryEFOnlyUsersTest : UserManagerSpecificationTestBase<IdentityUser, string>
public class InMemoryEFOnlyUsersTest
: UserManagerSpecificationTestBase<IdentityUser, string>,
IClassFixture<InMemoryDatabaseFixture>
{
private readonly InMemoryDatabaseFixture _fixture;
public InMemoryEFOnlyUsersTest(InMemoryDatabaseFixture fixture)
{
_fixture = fixture;
}
protected override object CreateTestContext()
=> new InMemoryContext<IdentityUser>(new DbContextOptionsBuilder().Options);
=> InMemoryContext<IdentityUser>.Create(_fixture.Connection);
protected override void AddUserStore(IServiceCollection services, object context = null)
=> services.AddSingleton<IUserStore<IdentityUser>>(new UserStore<IdentityUser, IdentityRole, DbContext, string, IdentityUserClaim<string>, IdentityUserRole<string>, IdentityUserLogin<string>, IdentityUserToken<string>, IdentityRoleClaim<string>>((InMemoryContext<IdentityUser>)context, new IdentityErrorDescriber()));

View File

@ -4,18 +4,23 @@
using System;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
{
public class InMemoryEFUserStoreTest : IdentitySpecificationTestBase<IdentityUser, IdentityRole, string>
public class InMemoryEFUserStoreTest : IdentitySpecificationTestBase<IdentityUser, IdentityRole, string>, IClassFixture<InMemoryDatabaseFixture>
{
protected override object CreateTestContext()
private readonly InMemoryDatabaseFixture _fixture;
public InMemoryEFUserStoreTest(InMemoryDatabaseFixture fixture)
{
return new InMemoryContext(new DbContextOptionsBuilder().Options);
_fixture = fixture;
}
protected override object CreateTestContext()
=> InMemoryContext.Create(_fixture.Connection);
protected override void AddUserStore(IServiceCollection services, object context = null)
{
services.AddSingleton<IUserStore<IdentityUser>>(new UserStore<IdentityUser>((InMemoryContext)context));

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
@ -16,20 +17,26 @@ using Xunit;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
{
public class InMemoryEFUserStoreTestWithGenerics : IdentitySpecificationTestBase<IdentityUserWithGenerics, MyIdentityRole, string>, IDisposable
public class InMemoryEFUserStoreTestWithGenerics
: IdentitySpecificationTestBase<IdentityUserWithGenerics, MyIdentityRole, string>, IClassFixture<InMemoryDatabaseFixture>
{
private readonly InMemoryDatabaseFixture _fixture;
private readonly InMemoryContextWithGenerics _context;
private UserStoreWithGenerics _store;
public InMemoryEFUserStoreTestWithGenerics()
public InMemoryEFUserStoreTestWithGenerics(InMemoryDatabaseFixture fixture)
{
_fixture = fixture;
var services = new ServiceCollection();
services.AddHttpContextAccessor();
services.AddDbContext<InMemoryContextWithGenerics>(
options => options
.UseInMemoryDatabase("Scratch")
.UseSqlite(_fixture.Connection)
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning)));
_context = services.BuildServiceProvider().GetRequiredService<InMemoryContextWithGenerics>();
_context.Database.EnsureCreated();
}
protected override object CreateTestContext()
@ -83,10 +90,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
[Fact]
public async Task CanAddRemoveUserClaimWithIssuer()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -115,10 +118,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
[Fact]
public async Task RemoveClaimWithIssuerOnlyAffectsUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
var user2 = CreateTestUser();
@ -148,10 +147,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
[Fact]
public async Task CanReplaceUserClaimWithIssuer()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -168,10 +163,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
Assert.Equal(claim.Value, newClaim.Value);
Assert.Equal(claim.Issuer, newClaim.Issuer);
}
public void Dispose()
{
}
}
public class ClaimEqualityComparer : IEqualityComparer<Claim>
@ -324,13 +315,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
public class InMemoryContextWithGenerics : InMemoryContext<IdentityUserWithGenerics, MyIdentityRole, string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext, IdentityRoleClaimWithIssuer, IdentityUserTokenWithStuff>
{
public InMemoryContextWithGenerics(DbContextOptions options) : base(options)
public InMemoryContextWithGenerics(DbContextOptions<InMemoryContextWithGenerics> options) : base(options)
{ }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase("Scratch");
}
}
#endregion

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
@ -14,7 +14,7 @@
<Reference Include="Microsoft.AspNetCore.Identity.Specification.Tests" />
<Reference Include="Microsoft.AspNetCore.Hosting" />
<Reference Include="Microsoft.AspNetCore.Http" />
<Reference Include="Microsoft.EntityFrameworkCore.InMemory" />
<Reference Include="Microsoft.EntityFrameworkCore.Sqlite" />
</ItemGroup>
</Project>

View File

@ -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.Data.Common;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.EntityFrameworkCore;
@ -11,12 +12,19 @@ using Xunit;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
{
public class RoleStoreTest
public class RoleStoreTest : IClassFixture<InMemoryDatabaseFixture>
{
private readonly InMemoryDatabaseFixture _fixture;
public RoleStoreTest(InMemoryDatabaseFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async Task CanCreateUsingAddRoleManager()
{
var manager = TestIdentityFactory.CreateRoleManager();
var manager = TestIdentityFactory.CreateRoleManager(_fixture.Connection);
Assert.NotNull(manager);
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new IdentityRole("arole")));
}
@ -25,8 +33,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
public async Task CanCreateRoleWithSingletonManager()
{
var services = TestIdentityFactory.CreateTestServices();
services.AddEntityFrameworkInMemoryDatabase();
services.AddSingleton(new InMemoryContext(new DbContextOptionsBuilder().Options));
services.AddEntityFrameworkSqlite();
services.AddSingleton(InMemoryContext.Create(_fixture.Connection));
services.AddTransient<IRoleStore<IdentityRole>, RoleStore<IdentityRole, InMemoryContext>>();
services.AddSingleton<RoleManager<IdentityRole>>();
var provider = services.BuildServiceProvider();
@ -38,7 +46,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
[Fact]
public async Task RoleStoreMethodsThrowWhenDisposedTest()
{
var store = new RoleStore<IdentityRole>(new InMemoryContext(new DbContextOptionsBuilder().Options));
var store = new RoleStore<IdentityRole>(InMemoryContext.Create(_fixture.Connection));
store.Dispose();
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByIdAsync(null));
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByNameAsync(null));
@ -54,7 +62,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
public async Task RoleStorePublicNullCheckTest()
{
Assert.Throws<ArgumentNullException>("context", () => new RoleStore<IdentityRole>(null));
var store = new RoleStore<IdentityRole>(new InMemoryContext(new DbContextOptionsBuilder().Options));
var store = new RoleStore<IdentityRole>(InMemoryContext.Create(_fixture.Connection));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await store.GetRoleIdAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await store.GetRoleNameAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await store.SetRoleNameAsync(null, null));
@ -66,7 +74,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
[Fact]
public async Task CanUpdateRoleName()
{
var manager = TestIdentityFactory.CreateRoleManager();
var manager = TestIdentityFactory.CreateRoleManager(_fixture.Connection);
var role = new IdentityRole("UpdateRoleName");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(role));
Assert.Null(await manager.FindByNameAsync("New"));

View File

@ -1,25 +1,15 @@
// 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 Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
{
public static class TestIdentityFactory
{
public static InMemoryContext CreateContext()
{
var services = new ServiceCollection();
services.AddEntityFrameworkInMemoryDatabase();
var serviceProvider = services.BuildServiceProvider();
var db = new InMemoryContext(new DbContextOptionsBuilder().Options);
db.Database.EnsureCreated();
return db;
}
private static InMemoryContext CreateContext(SqliteConnection connection)
=> InMemoryContext.Create(connection);
public static IServiceCollection CreateTestServices()
{
@ -37,9 +27,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
return services.BuildServiceProvider().GetRequiredService<RoleManager<IdentityRole>>();
}
public static RoleManager<IdentityRole> CreateRoleManager()
{
return CreateRoleManager(CreateContext());
}
public static RoleManager<IdentityRole> CreateRoleManager(SqliteConnection connection)
=> CreateRoleManager(CreateContext(connection));
}
}

View File

@ -35,9 +35,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
}
public CustomDbContext<TKey> GetContext<TKey>() where TKey : IEquatable<TKey>
private CustomDbContext<TKey> GetContext<TKey>() where TKey : IEquatable<TKey>
{
return DbUtil.Create<CustomDbContext<TKey>>(_fixture.ConnectionString);
return DbUtil.Create<CustomDbContext<TKey>>(_fixture.Connection);
}
public CustomDbContext<TKey> CreateContext<TKey>(bool delete = false) where TKey : IEquatable<TKey>
@ -168,4 +168,4 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
}
}
}
}
}

View File

@ -1,76 +1,71 @@
// 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.Data.SqlClient;
using System.Data.Common;
using System.Linq;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
{
public static class DbUtil
{
public static IServiceCollection ConfigureDbServices<TContext>(string connectionString, IServiceCollection services = null) where TContext : DbContext
public static IServiceCollection ConfigureDbServices<TContext>(
DbConnection connection,
IServiceCollection services = null) where TContext : DbContext
{
if (services == null)
{
services = new ServiceCollection();
}
services.AddHttpContextAccessor();
services.AddDbContext<TContext>(options =>
{
options
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning))
.UseSqlServer(connectionString);
.UseSqlite(connection);
});
return services;
}
public static TContext Create<TContext>(string connectionString, IServiceCollection services = null) where TContext : DbContext
public static TContext Create<TContext>(DbConnection connection, IServiceCollection services = null) where TContext : DbContext
{
var serviceProvider = ConfigureDbServices<TContext>(connectionString, services).BuildServiceProvider();
var serviceProvider = ConfigureDbServices<TContext>(connection, services).BuildServiceProvider();
return serviceProvider.GetRequiredService<TContext>();
}
public static bool VerifyMaxLength(SqlConnection conn, string table, int maxLength, params string[] columns)
public static bool VerifyMaxLength(DbContext context, string table, int maxLength, params string[] columns)
{
var count = 0;
using (
var command =
new SqlCommand("SELECT COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@Table", conn))
foreach (var property in context.Model.GetEntityTypes().Single(e => e.Relational().TableName == table).GetProperties())
{
command.Parameters.Add(new SqlParameter("Table", table));
using (var reader = command.ExecuteReader())
if (!columns.Contains(property.Relational().ColumnName))
{
while (reader.Read())
{
if (!columns.Contains(reader.GetString(0)))
{
continue;
}
if (reader.GetInt32(1) != maxLength)
{
return false;
}
count++;
}
return count == columns.Length;
continue;
}
if (property.GetMaxLength() != maxLength)
{
return false;
}
count++;
}
return count == columns.Length;
}
public static bool VerifyColumns(SqlConnection conn, string table, params string[] columns)
public static bool VerifyColumns(SqliteConnection conn, string table, params string[] columns)
{
var count = 0;
using (
var command =
new SqlCommand("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@Table", conn))
using (var command = new SqliteCommand("SELECT \"name\" FROM pragma_table_info(@table)", conn))
{
command.Parameters.Add(new SqlParameter("Table", table));
command.Parameters.Add(new SqliteParameter("table", table));
using (var reader = command.ExecuteReader())
{
while (reader.Read())
@ -86,16 +81,15 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
}
}
public static void VerifyIndex(SqlConnection conn, string table, string index, bool isUnique = false)
public static void VerifyIndex(SqliteConnection conn, string table, string index, bool isUnique = false)
{
using (
var command =
new SqlCommand(
"SELECT COUNT(*) FROM sys.indexes where NAME=@Index AND object_id = OBJECT_ID(@Table) AND is_unique = @Unique", conn))
using (var command =
new SqliteCommand(
"SELECT COUNT(*) FROM pragma_index_list(@table) WHERE \"name\" = @index AND \"unique\" = @unique", conn))
{
command.Parameters.Add(new SqlParameter("Index", index));
command.Parameters.Add(new SqlParameter("Table", table));
command.Parameters.Add(new SqlParameter("Unique", isUnique));
command.Parameters.Add(new SqliteParameter("index", index));
command.Parameters.Add(new SqliteParameter("table", table));
command.Parameters.Add(new SqliteParameter("unique", isUnique));
using (var reader = command.ExecuteReader())
{
Assert.True(reader.Read());
@ -103,6 +97,5 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
}
}
}
}
}

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
services
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
.AddDbContext<IdentityDbContext>(o =>
o.UseSqlServer(fixture.ConnectionString)
o.UseSqlite(fixture.Connection)
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning)))
.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityDbContext>();

View File

@ -4,6 +4,7 @@
using System.Data.SqlClient;
using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Configuration;
@ -24,7 +25,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
services
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
.AddDbContext<IdentityDbContext>(o =>
o.UseSqlServer(fixture.ConnectionString)
o.UseSqlite(fixture.Connection)
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning)))
.AddIdentity<IdentityUser, IdentityRole>(o => o.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<IdentityDbContext>();
@ -55,7 +56,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
{
var sqlConn = dbContext.Database.GetDbConnection();
using (var db = new SqlConnection(sqlConn.ConnectionString))
using (var db = new SqliteConnection(sqlConn.ConnectionString))
{
db.Open();
Assert.True(DbUtil.VerifyColumns(db, "AspNetUsers", "Id", "UserName", "Email", "PasswordHash", "SecurityStamp",
@ -67,10 +68,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
Assert.True(DbUtil.VerifyColumns(db, "AspNetUserLogins", "UserId", "ProviderKey", "LoginProvider", "ProviderDisplayName"));
Assert.True(DbUtil.VerifyColumns(db, "AspNetUserTokens", "UserId", "LoginProvider", "Name", "Value"));
Assert.True(DbUtil.VerifyMaxLength(db, "AspNetUsers", 256, "UserName", "Email", "NormalizedUserName", "NormalizedEmail"));
Assert.True(DbUtil.VerifyMaxLength(db, "AspNetRoles", 256, "Name", "NormalizedName"));
Assert.True(DbUtil.VerifyMaxLength(db, "AspNetUserLogins", 128, "LoginProvider", "ProviderKey"));
Assert.True(DbUtil.VerifyMaxLength(db, "AspNetUserTokens", 128, "LoginProvider", "Name"));
Assert.True(DbUtil.VerifyMaxLength(dbContext, "AspNetUsers", 256, "UserName", "Email", "NormalizedUserName", "NormalizedEmail"));
Assert.True(DbUtil.VerifyMaxLength(dbContext, "AspNetRoles", 256, "Name", "NormalizedName"));
Assert.True(DbUtil.VerifyMaxLength(dbContext, "AspNetUserLogins", 128, "LoginProvider", "ProviderKey"));
Assert.True(DbUtil.VerifyMaxLength(dbContext, "AspNetUserTokens", 128, "LoginProvider", "Name"));
DbUtil.VerifyIndex(db, "AspNetRoles", "RoleNameIndex", isUnique: true);
DbUtil.VerifyIndex(db, "AspNetUsers", "UserNameIndex", isUnique: true);

View File

@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TestDependsOnMssql>true</TestDependsOnMssql>
<!-- These tests are broken in Azure Pipelines right now due to deadlocks in EFCore on machines with few CPU cores. -->
<SkipTests Condition=" '$(BUILD_REASON)' == 'PullRequest' ">true</SkipTests>
@ -20,8 +19,7 @@
<Reference Include="Microsoft.AspNetCore.Hosting" />
<Reference Include="Microsoft.AspNetCore.Http" />
<Reference Include="Microsoft.AspNetCore.TestHost" />
<Reference Include="Microsoft.EntityFrameworkCore.InMemory" />
<Reference Include="Microsoft.EntityFrameworkCore.SqlServer" />
<Reference Include="Microsoft.EntityFrameworkCore.Sqlite" />
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<Reference Include="Microsoft.Extensions.Configuration.FileExtensions" />
<Reference Include="Microsoft.Extensions.Configuration.Json" />

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
@ -27,11 +28,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
_fixture = fixture;
}
protected override bool ShouldSkipDbTests()
{
return TestPlatformHelper.IsMono || !TestPlatformHelper.IsWindows;
}
public class TestUserDbContext : IdentityUserContext<TUser, TKey>
{
public TestUserDbContext(DbContextOptions options) : base(options) { }
@ -54,9 +50,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
protected override Expression<Func<TUser, bool>> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
public TestUserDbContext CreateContext()
private TestUserDbContext CreateContext()
{
var db = DbUtil.Create<TestUserDbContext>(_fixture.ConnectionString);
var db = DbUtil.Create<TestUserDbContext>(_fixture.Connection);
db.Database.EnsureCreated();
return db;
}
@ -89,7 +85,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
{
var sqlConn = dbContext.Database.GetDbConnection();
using (var db = new SqlConnection(sqlConn.ConnectionString))
using (var db = new SqliteConnection(sqlConn.ConnectionString))
{
db.Open();
Assert.True(DbUtil.VerifyColumns(db, "AspNetUsers", "Id", "UserName", "Email", "PasswordHash", "SecurityStamp",
@ -104,7 +100,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
DbUtil.VerifyIndex(db, "AspNetUsers", "UserNameIndex", isUnique: true);
DbUtil.VerifyIndex(db, "AspNetUsers", "EmailIndex");
DbUtil.VerifyMaxLength(db, "AspNetUsers", 256, "UserName", "Email", "NormalizeUserName", "NormalizeEmail");
DbUtil.VerifyMaxLength(dbContext, "AspNetUsers", 256, "UserName", "Email", "NormalizeUserName", "NormalizeEmail");
db.Close();
}
@ -249,4 +245,4 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
Assert.Equal(2, (await manager.GetRolesAsync(userByEmail)).Count);
}
}
}
}

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -58,11 +59,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
SetupAddIdentity(services);
}
protected override bool ShouldSkipDbTests()
{
return TestPlatformHelper.IsMono || !TestPlatformHelper.IsWindows;
}
public class TestDbContext : IdentityDbContext<TUser, TRole, TKey> {
public TestDbContext(DbContextOptions options) : base(options) { }
}
@ -94,11 +90,11 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
protected override Expression<Func<TUser, bool>> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
public virtual TestDbContext CreateContext()
protected virtual TestDbContext CreateContext()
{
var services = new ServiceCollection();
SetupAddIdentity(services);
var db = DbUtil.Create<TestDbContext>(_fixture.ConnectionString, services);
var db = DbUtil.Create<TestDbContext>(_fixture.Connection, services);
db.Database.EnsureCreated();
return db;
}
@ -136,7 +132,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
{
var sqlConn = dbContext.Database.GetDbConnection();
using (var db = new SqlConnection(sqlConn.ConnectionString))
using (var db = new SqliteConnection(sqlConn.ConnectionString))
{
db.Open();
Assert.True(DbUtil.VerifyColumns(db, "AspNetUsers", "Id", "UserName", "Email", "PasswordHash", "SecurityStamp",
@ -148,8 +144,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
Assert.True(DbUtil.VerifyColumns(db, "AspNetUserLogins", "UserId", "ProviderKey", "LoginProvider", "ProviderDisplayName"));
Assert.True(DbUtil.VerifyColumns(db, "AspNetUserTokens", "UserId", "LoginProvider", "Name", "Value"));
Assert.True(DbUtil.VerifyMaxLength(db, "AspNetUsers", 256, "UserName", "Email", "NormalizedUserName", "NormalizedEmail"));
Assert.True(DbUtil.VerifyMaxLength(db, "AspNetRoles", 256, "Name", "NormalizedName"));
Assert.True(DbUtil.VerifyMaxLength(dbContext, "AspNetUsers", 256, "UserName", "Email", "NormalizedUserName", "NormalizedEmail"));
Assert.True(DbUtil.VerifyMaxLength(dbContext, "AspNetRoles", 256, "Name", "NormalizedName"));
DbUtil.VerifyIndex(db, "AspNetRoles", "RoleNameIndex", isUnique: true);
DbUtil.VerifyIndex(db, "AspNetUsers", "UserNameIndex", isUnique: true);

View File

@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
services
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
.AddDbContext<CustomContext>(o =>
o.UseSqlServer(fixture.ConnectionString)
o.UseSqlite(fixture.Connection)
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning)))
.AddIdentityCore<IdentityUser>(o => { })
.AddEntityFrameworkStores<CustomContext>();

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
services
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
.AddDbContext<TestUserDbContext>(
o => o.UseSqlServer(fixture.ConnectionString)
o => o.UseSqlite(fixture.Connection)
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning)))
.AddIdentityCore<IdentityUser>(o => { })
.AddEntityFrameworkStores<TestUserDbContext>();

View File

@ -75,10 +75,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
[Fact]
public async Task CanRotateKeysAndStillFind()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var name = Guid.NewGuid().ToString();
var user = CreateTestUser(name);
@ -176,11 +172,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
[InlineData(false)]
public async Task CustomPersonalDataPropertiesAreProtected(bool protect)
{
if (ShouldSkipDbTests())
{
return;
}
using (var scratch = new ScratchDatabaseFixture())
{
var services = new ServiceCollection().AddLogging();
@ -191,7 +182,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
.AddEntityFrameworkStores<IdentityDbContext<CustomUser>>()
.AddPersonalDataProtection<InkProtector, DefaultKeyRing>();
var dbOptions = new DbContextOptionsBuilder().UseSqlServer(scratch.ConnectionString)
var dbOptions = new DbContextOptionsBuilder().UseSqlite(scratch.Connection)
.UseApplicationServiceProvider(services.BuildServiceProvider())
.Options;
var dbContext = new IdentityDbContext<CustomUser>(dbOptions);
@ -260,11 +251,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
[Fact]
public void ProtectedPersonalDataThrowsOnNonString()
{
if (ShouldSkipDbTests())
{
return;
}
using (var scratch = new ScratchDatabaseFixture())
{
var services = new ServiceCollection().AddLogging();
@ -274,7 +260,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
})
.AddEntityFrameworkStores<IdentityDbContext<CustomUser>>()
.AddPersonalDataProtection<InkProtector, DefaultKeyRing>();
var dbOptions = new DbContextOptionsBuilder().UseSqlServer(scratch.ConnectionString)
var dbOptions = new DbContextOptionsBuilder().UseSqlite(scratch.Connection)
.UseApplicationServiceProvider(services.BuildServiceProvider())
.Options;
var dbContext = new IdentityDbContext<InvalidUser>(dbOptions);

View File

@ -23,9 +23,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
_fixture = fixture;
}
protected override bool ShouldSkipDbTests()
=> TestPlatformHelper.IsMono || !TestPlatformHelper.IsWindows;
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
@ -48,9 +45,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
}
}
public IdentityDbContext CreateContext(bool delete = false)
private IdentityDbContext CreateContext(bool delete = false)
{
var db = DbUtil.Create<IdentityDbContext>(_fixture.ConnectionString);
var db = DbUtil.Create<IdentityDbContext>(_fixture.Connection);
if (delete)
{
db.Database.EnsureDeleted();
@ -64,13 +61,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
return CreateContext();
}
public ApplicationDbContext CreateAppContext()
{
var db = DbUtil.Create<ApplicationDbContext>(_fixture.ConnectionString);
db.Database.EnsureCreated();
return db;
}
protected override void AddUserStore(IServiceCollection services, object context = null)
{
services.AddSingleton<IUserStore<IdentityUser>>(new UserStore<IdentityUser, IdentityRole, IdentityDbContext>((IdentityDbContext)context));

View File

@ -8,7 +8,6 @@ using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.AspNetCore.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
@ -24,9 +23,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
_fixture = fixture;
}
public ContextWithGenerics CreateContext()
private ContextWithGenerics CreateContext()
{
var db = DbUtil.Create<ContextWithGenerics>(_fixture.ConnectionString);
var db = DbUtil.Create<ContextWithGenerics>(_fixture.Connection);
db.Database.EnsureCreated();
return db;
}
@ -36,11 +35,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
return CreateContext();
}
protected override bool ShouldSkipDbTests()
{
return TestPlatformHelper.IsMono || !TestPlatformHelper.IsWindows;
}
protected override void AddUserStore(IServiceCollection services, object context = null)
{
services.AddSingleton<IUserStore<IdentityUserWithGenerics>>(new UserStoreWithGenerics((ContextWithGenerics)context, "TestContext"));
@ -104,10 +98,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
[Fact]
public async Task CanAddRemoveUserClaimWithIssuer()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -136,10 +126,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
[Fact]
public async Task RemoveClaimWithIssuerOnlyAffectsUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
var user2 = CreateTestUser();
@ -169,10 +155,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
[Fact]
public async Task CanReplaceUserClaimWithIssuer()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -348,4 +330,4 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
}
#endregion
}
}

View File

@ -2,28 +2,40 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.Utilities;
using Microsoft.EntityFrameworkCore.Internal;
using System.Data.Common;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
{
public class ScratchDatabaseFixture : IDisposable
{
private readonly Lazy<SqlServerTestStore> _testStore;
private readonly SqliteConnection _connection;
public ScratchDatabaseFixture()
{
_testStore = new Lazy<SqlServerTestStore>(() => SqlServerTestStore.CreateScratch());
_connection = new SqliteConnection($"DataSource=D{Guid.NewGuid()}.db");
using (var context = CreateEmptyContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
}
}
public string ConnectionString => _testStore.Value.Connection.ConnectionString;
private DbContext CreateEmptyContext()
=> new DbContext(new DbContextOptionsBuilder().UseSqlite(_connection).Options);
public DbConnection Connection => _connection;
public void Dispose()
{
if (_testStore.IsValueCreated)
using (var context = CreateEmptyContext())
{
_testStore.Value.Dispose();
context.Database.EnsureDeleted();
}
_connection.Dispose();
}
}
}

View File

@ -1,165 +0,0 @@
// 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.Data.Common;
using System.Data.SqlClient;
using System.IO;
using System.Threading;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.Utilities
{
public class SqlServerTestStore : IDisposable
{
public const int CommandTimeout = 90;
public static string CreateConnectionString(string name)
{
var connStrBuilder = new SqlConnectionStringBuilder(TestEnvironment.Config["Test:SqlServer:DefaultConnectionString"])
{
InitialCatalog = name
};
return connStrBuilder.ConnectionString;
}
public static SqlServerTestStore CreateScratch(bool createDatabase = true)
=> new SqlServerTestStore(GetScratchDbName()).CreateTransient(createDatabase);
private SqlConnection _connection;
private readonly string _name;
private bool _deleteDatabase;
private SqlServerTestStore(string name)
{
_name = name;
}
private static string GetScratchDbName()
{
string name;
do
{
name = "Scratch_" + Guid.NewGuid();
} while (DatabaseExists(name)
|| DatabaseFilesExist(name));
return name;
}
private static void WaitForExists(SqlConnection connection)
{
var retryCount = 0;
while (true)
{
try
{
connection.Open();
connection.Close();
return;
}
catch (SqlException e)
{
if (++retryCount >= 30
|| (e.Number != 233 && e.Number != -2 && e.Number != 4060))
{
throw;
}
SqlConnection.ClearPool(connection);
Thread.Sleep(100);
}
}
}
private SqlServerTestStore CreateTransient(bool createDatabase)
{
_connection = new SqlConnection(CreateConnectionString(_name));
if (createDatabase)
{
using (var master = new SqlConnection(CreateConnectionString("master")))
{
master.Open();
using (var command = master.CreateCommand())
{
command.CommandTimeout = CommandTimeout;
command.CommandText = $"{Environment.NewLine}CREATE DATABASE [{_name}]";
command.ExecuteNonQuery();
WaitForExists(_connection);
}
}
_connection.Open();
}
_deleteDatabase = true;
return this;
}
private static bool DatabaseExists(string name)
{
using (var master = new SqlConnection(CreateConnectionString("master")))
{
master.Open();
using (var command = master.CreateCommand())
{
command.CommandTimeout = CommandTimeout;
command.CommandText = $@"SELECT COUNT(*) FROM sys.databases WHERE name = N'{name}'";
return (int) command.ExecuteScalar() > 0;
}
}
}
private static bool DatabaseFilesExist(string name)
{
var userFolder = Environment.GetEnvironmentVariable("USERPROFILE") ??
Environment.GetEnvironmentVariable("HOME");
return userFolder != null
&& (File.Exists(Path.Combine(userFolder, name + ".mdf"))
|| File.Exists(Path.Combine(userFolder, name + "_log.ldf")));
}
private void DeleteDatabase(string name)
{
using (var master = new SqlConnection(CreateConnectionString("master")))
{
master.Open();
using (var command = master.CreateCommand())
{
command.CommandTimeout = CommandTimeout;
// Query will take a few seconds if (and only if) there are active connections
// SET SINGLE_USER will close any open connections that would prevent the drop
command.CommandText
= string.Format(@"IF EXISTS (SELECT * FROM sys.databases WHERE name = N'{0}')
BEGIN
ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [{0}];
END", name);
command.ExecuteNonQuery();
}
}
}
public DbConnection Connection => _connection;
public void Dispose()
{
_connection.Dispose();
if (_deleteDatabase)
{
DeleteDatabase(_name);
}
}
}
}

View File

@ -7,7 +7,6 @@ using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Xunit;
@ -129,10 +128,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanCreateRoleTest()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var roleName = "create" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -169,10 +164,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task BadValidatorBlocksCreateRole()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
manager.RoleValidators.Clear();
manager.RoleValidators.Add(new AlwaysBadValidator());
@ -189,10 +180,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChainRoleValidators()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
manager.RoleValidators.Clear();
manager.RoleValidators.Add(new AlwaysBadValidator());
@ -211,10 +198,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task BadValidatorBlocksRoleUpdate()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var role = CreateTestRole("poorguy");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(role));
@ -232,10 +215,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanDeleteRole()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var roleName = "delete" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -253,10 +232,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanAddRemoveRoleClaim()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var role = CreateTestRole("ClaimsAddRemove");
var roleSafe = CreateTestRole("ClaimsAdd");
@ -296,10 +271,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanRoleFindById()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var role = CreateTestRole("FindByIdAsync");
Assert.Null(await manager.FindByIdAsync(await manager.GetRoleIdAsync(role)));
@ -314,10 +285,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanRoleFindByName()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var roleName = "FindByNameAsync" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -334,10 +301,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanUpdateRoleName()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var roleName = "update" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -357,10 +320,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanQueryableRoles()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
if (manager.SupportsQueryableRoles)
{
@ -384,10 +343,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CreateRoleFailsIfExists()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateRoleManager();
var roleName = "dupeRole" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -405,10 +360,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanAddUsersToRole()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var manager = CreateManager(context);
var roleManager = CreateRoleManager(context);
@ -434,11 +385,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanGetRolesForUser()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var userManager = CreateManager(context);
var roleManager = CreateRoleManager(context);
@ -477,10 +423,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task RemoveUserFromRoleWithMultipleRoles()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var userManager = CreateManager(context);
var roleManager = CreateRoleManager(context);
@ -504,10 +446,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanRemoveUsersFromRole()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var userManager = CreateManager(context);
var roleManager = CreateRoleManager(context);
@ -538,10 +476,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task RemoveUserNotInRoleFails()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var userMgr = CreateManager(context);
var roleMgr = CreateRoleManager(context);
@ -562,10 +496,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddUserToRoleFailsIfAlreadyInRole()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var userMgr = CreateManager(context);
var roleMgr = CreateRoleManager(context);
@ -587,10 +517,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddUserToRolesIgnoresDuplicates()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var userMgr = CreateManager(context);
var roleMgr = CreateRoleManager(context);
@ -611,10 +537,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanFindRoleByNameWithManager()
{
if (ShouldSkipDbTests())
{
return;
}
var roleMgr = CreateRoleManager();
var roleName = "findRoleByNameTest" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -629,10 +551,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanFindRoleWithManager()
{
if (ShouldSkipDbTests())
{
return;
}
var roleMgr = CreateRoleManager();
var roleName = "findRoleTest" + Guid.NewGuid().ToString();
var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true);
@ -647,10 +565,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanGetUsersInRole()
{
if (ShouldSkipDbTests())
{
return;
}
var context = CreateTestContext();
var manager = CreateManager(context);
var roleManager = CreateRoleManager(context);

View File

@ -7,7 +7,6 @@ using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.DependencyInjection;
@ -72,12 +71,6 @@ namespace Microsoft.AspNetCore.Identity.Test
return builder;
}
/// <summary>
/// If true, tests that require a database will be skipped.
/// </summary>
/// <returns></returns>
protected virtual bool ShouldSkipDbTests() => false;
/// <summary>
/// Creates the user manager used for tests.
/// </summary>
@ -184,10 +177,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorWithNoErrorsCanBlockAddPassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -203,10 +192,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CreateUserWillSetCreateDateOnlyIfSupported()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -220,10 +205,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanDeleteUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -239,10 +220,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanUpdateUserName()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var name = Guid.NewGuid().ToString();
var user = CreateTestUser(name);
@ -262,10 +239,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CheckSetUserNameValidatesUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var username = "UpdateAsync" + Guid.NewGuid().ToString();
var newUsername = "New" + Guid.NewGuid().ToString();
@ -294,10 +267,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task SetUserNameUpdatesSecurityStamp()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var username = "UpdateAsync" + Guid.NewGuid().ToString();
var newUsername = "New" + Guid.NewGuid().ToString();
@ -316,10 +285,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ResetAuthenticatorKeyUpdatesSecurityStamp()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var username = "Create" + Guid.NewGuid().ToString();
var user = CreateTestUser(username, useNamePrefixAsUserName: true);
@ -336,10 +301,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CheckSetEmailValidatesUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.Options.User.RequireUniqueEmail = true;
manager.UserValidators.Add(new UserValidator<TUser>());
@ -363,10 +324,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanUpdatePasswordUsingHasher()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("UpdatePassword");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password"));
@ -387,10 +344,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanFindById()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -404,10 +357,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task UserValidatorCanBlockCreate()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
manager.UserValidators.Clear();
@ -423,10 +372,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task UserValidatorCanBlockUpdate()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -443,10 +388,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChainUserValidators()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.UserValidators.Clear();
var user = CreateTestUser();
@ -467,10 +408,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[InlineData(null)]
public async Task UserValidatorBlocksShortEmailsWhenRequiresUniqueEmail(string email)
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
manager.Options.User.RequireUniqueEmail = true;
@ -486,10 +423,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[InlineData("bogus")]
public async Task UserValidatorBlocksInvalidEmailsWhenRequiresUniqueEmail(string email)
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("UpdateBlocked", email);
manager.Options.User.RequireUniqueEmail = true;
@ -503,10 +436,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorCanBlockAddPassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -524,10 +453,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChainPasswordValidators()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.PasswordValidators.Clear();
manager.PasswordValidators.Add(new EmptyBadValidator());
@ -546,10 +471,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorWithNoErrorsCanBlockChangePassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password"));
@ -565,10 +486,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorWithNoErrorsCanBlockCreateUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
manager.PasswordValidators.Clear();
@ -583,10 +500,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorWithNoErrorsCanBlockResetPasswordWithStaticTokenProvider()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
@ -611,10 +524,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorCanBlockChangePassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password"));
@ -632,10 +541,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorCanBlockCreateUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
manager.PasswordValidators.Clear();
@ -651,10 +556,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanCreateUserNoPassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var username = "CreateUserTest" + Guid.NewGuid();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(CreateTestUser(username, useNamePrefixAsUserName: true)));
@ -674,10 +575,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanCreateUserAddLogin()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
const string provider = "ZzAuth";
const string display = "display";
@ -700,10 +597,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanCreateUserLoginAndAddPassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -727,10 +620,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddPasswordFailsIfAlreadyHave()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "Password"));
@ -747,10 +636,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanCreateUserAddRemoveLogin()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
var result = await manager.CreateAsync(user);
@ -782,10 +667,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanRemovePassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("CanRemovePassword");
const string password = "password";
@ -806,10 +687,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChangePassword()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
const string password = "password";
@ -830,10 +707,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanAddRemoveUserClaim()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -863,10 +736,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task RemoveClaimOnlyAffectsUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
var user2 = CreateTestUser();
@ -900,10 +769,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanReplaceUserClaim()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -927,10 +792,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ReplaceUserClaimOnlyAffectsUser()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
var user2 = CreateTestUser();
@ -964,10 +825,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangePasswordFallsIfPasswordWrong()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password"));
@ -983,10 +840,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddDupeUserNameFails()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var username = "AddDupeUserNameFails" + Guid.NewGuid();
var user = CreateTestUser(username, useNamePrefixAsUserName: true);
@ -1002,10 +855,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddDupeEmailAllowedByDefault()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(email: "yup@yup.com");
var user2 = CreateTestUser(email: "yup@yup.com");
@ -1021,10 +870,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddDupeEmailFailsWhenUniqueEmailRequired()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.Options.User.RequireUniqueEmail = true;
var user = CreateTestUser(email: "FooUser@yup.com");
@ -1040,10 +885,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task UpdateSecurityStampActuallyChanges()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1059,10 +900,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task AddDupeLoginFails()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
var login = new UserLoginInfo("Provider", "key", "display");
@ -1082,10 +919,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanFindByEmail()
{
if (ShouldSkipDbTests())
{
return;
}
var email = "foouser@test.com";
var manager = CreateManager();
var user = CreateTestUser(email: email);
@ -1101,11 +934,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async virtual Task CanFindUsersViaUserQuerable()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
if (mgr.SupportsQueryableUsers)
{
@ -1126,10 +954,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ConfirmEmailFalseByDefaultTest()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1166,10 +990,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanResetPasswordWithStaticTokenProvider()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
@ -1195,10 +1015,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PasswordValidatorCanBlockResetPasswordWithStaticTokenProvider()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
@ -1225,10 +1041,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ResetPasswordWithStaticTokenProviderFailsWithWrongToken()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
@ -1251,10 +1063,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanGenerateAndVerifyUserTokenWithStaticTokenProvider()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
var user = CreateTestUser();
@ -1283,10 +1091,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanConfirmEmailWithStaticToken()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.EmailConfirmationTokenProvider = "Static";
@ -1309,10 +1113,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ConfirmEmailWithStaticTokenFailsWithWrongToken()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.EmailConfirmationTokenProvider = "Static";
@ -1331,10 +1131,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ConfirmTokenFailsAfterPasswordChange()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(namePrefix: "Test");
Assert.False(await manager.IsEmailConfirmedAsync(user));
@ -1356,10 +1152,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task SingleFailureLockout()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
mgr.Options.Lockout.MaxFailedAccessAttempts = 0;
@ -1382,10 +1174,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task TwoFailureLockout()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
mgr.Options.Lockout.MaxFailedAccessAttempts = 2;
@ -1411,10 +1199,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ResetAccessCountPreventsLockout()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
mgr.Options.Lockout.MaxFailedAccessAttempts = 2;
@ -1443,10 +1227,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanEnableLockoutManuallyAndLockout()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
mgr.Options.Lockout.AllowedForNewUsers = false;
@ -1475,10 +1255,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
@ -1495,10 +1271,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task LockoutFailsIfNotEnabled()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
mgr.Options.Lockout.AllowedForNewUsers = false;
var user = CreateTestUser();
@ -1517,10 +1289,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
var user = CreateTestUser(lockoutEnd: DateTimeOffset.UtcNow.AddSeconds(-1));
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
@ -1535,10 +1303,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
@ -1554,10 +1318,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
var lockoutEnd = DateTimeOffset.UtcNow.AddMinutes(5);
var user = CreateTestUser(lockoutEnd: lockoutEnd);
@ -1573,10 +1333,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task UserLockedOutWithDateTimeLocalKindNowPlus30()
{
if (ShouldSkipDbTests())
{
return;
}
var mgr = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
@ -1595,10 +1351,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task SetPhoneNumberTest()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "123-456-7890");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1616,10 +1368,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChangePhoneNumber()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "123-456-7890");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1639,10 +1387,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangePhoneNumberTokenIsInt()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "123-456-7890");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1657,10 +1401,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangePhoneNumberFailsWithWrongToken()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "123-456-7890");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1693,10 +1433,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangePhoneNumberWithCustomProvider()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
manager.RegisterTokenProvider("Yes", new YesPhoneNumberProvider());
manager.Options.Tokens.ChangePhoneNumberTokenProvider = "Yes";
@ -1717,10 +1453,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangePhoneNumberFailsWithWrongPhoneNumber()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "123-456-7890");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1741,10 +1473,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanVerifyPhoneNumber()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1770,10 +1498,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChangeEmail()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("foouser");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1796,10 +1520,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChangeEmailOnlyIfEmailSame()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("foouser");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1824,10 +1544,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanChangeEmailWithDifferentTokenProvider()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager(context: null, services: null,
configureServices: s => s.Configure<IdentityOptions>(
o => o.Tokens.ProviderMap["NewProvider2"] = new TokenProviderDescriptor(typeof(EmailTokenProvider<TUser>))));
@ -1853,10 +1569,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangeEmailTokensFailsAfterEmailChanged()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("foouser");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1880,10 +1592,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangeEmailFailsWithWrongToken()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("foouser");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1907,10 +1615,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task ChangeEmailFailsWithEmail()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser("foouser");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1936,10 +1640,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1766", FlakyOn.All)]
public async Task EmailFactorFailsAfterSecurityStampChangeTest()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
string factorId = "Email"; //default
var user = CreateTestUser("foouser");
@ -1970,10 +1670,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task EnableTwoFactorChangesSecurityStamp()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1991,10 +1687,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task GenerateTwoFactorWithUnknownFactorProviderWillThrow()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2020,10 +1712,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task GetValidTwoFactorTestEmptyWithNoProviders()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2039,10 +1727,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanGetSetUpdateAndRemoveUserToken()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2067,10 +1751,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanRedeemRecoveryCodeOnlyOnce()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2099,10 +1779,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task RecoveryCodesInvalidAfterReplace()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2131,10 +1807,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanGetValidTwoFactor()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2175,10 +1847,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task PhoneFactorFailsAfterSecurityStampChangeTest()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var factorId = "Phone"; // default
var user = CreateTestUser(phoneNumber: "4251234567");
@ -2199,10 +1867,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task VerifyTokenFromWrongTokenProviderFails()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "4251234567");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2219,10 +1883,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task VerifyWithWrongSmsTokenFails()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
var user = CreateTestUser(phoneNumber: "4251234567");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -2237,10 +1897,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task NullableDateTimeOperationTest()
{
if (ShouldSkipDbTests())
{
return;
}
var userMgr = CreateManager();
var user = CreateTestUser(lockoutEnabled: true);
IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user));
@ -2263,10 +1919,6 @@ namespace Microsoft.AspNetCore.Identity.Test
[Fact]
public async Task CanGetUsersWithClaims()
{
if (ShouldSkipDbTests())
{
return;
}
var manager = CreateManager();
for (int i = 0; i < 6; i++)

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
where TStartup : class
where TContext : DbContext
{
public AuthorizationTests(ServerFactory<TStartup, TContext> serverFactory)
protected AuthorizationTests(ServerFactory<TStartup, TContext> serverFactory)
{
ServerFactory = serverFactory;
}

View File

@ -2,12 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Data.Common;
using System.Security.Claims;
using System.Threading.Tasks;
using Identity.DefaultUI.WebSite;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
@ -18,10 +18,10 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
{
public static class FunctionalTestsServiceCollectionExtensions
{
public static IServiceCollection SetupTestDatabase<TContext>(this IServiceCollection services, string databaseName) where TContext : DbContext =>
public static IServiceCollection SetupTestDatabase<TContext>(this IServiceCollection services, DbConnection connection) where TContext : DbContext =>
services.AddDbContext<TContext>(options =>
options.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning))
.UseInMemoryDatabase(databaseName, memoryOptions => { }));
.UseSqlite(connection));
public static IServiceCollection SetupTestThirdPartyLogin(this IServiceCollection services) =>
services.AddAuthentication()

View File

@ -3,19 +3,24 @@
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Identity.FunctionalTests
{
public class ServerFactory<TStartup,TContext>: WebApplicationFactory<TStartup>
public class ServerFactory<TStartup,TContext>: WebApplicationFactory<TStartup>
where TStartup : class
where TContext : DbContext
{
private readonly SqliteConnection _connection
= new SqliteConnection($"DataSource=:memory:");
public ServerFactory()
{
_connection.Open();
ClientOptions.AllowAutoRedirect = false;
ClientOptions.BaseAddress = new Uri("https://localhost");
}
@ -24,11 +29,30 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
{
base.ConfigureWebHost(builder);
builder.UseStartup<TStartup>();
builder.ConfigureServices(sc => sc.SetupTestDatabase<TContext>(Guid.NewGuid().ToString())
builder.ConfigureServices(sc =>
{
sc.SetupTestDatabase<TContext>(_connection)
.AddMvc()
// Mark the cookie as essential for right now, as Identity uses it on
// several places to pass important data in post-redirect-get flows.
.AddCookieTempDataProvider(o => o.Cookie.IsEssential = true));
.AddCookieTempDataProvider(o => o.Cookie.IsEssential = true);
});
}
public override void EnsureDatabaseCreated()
{
using (var scope = Services.CreateScope())
{
scope.ServiceProvider.GetService<TContext>().Database.EnsureCreated();
}
}
protected override void Dispose(bool disposing)
{
_connection.Dispose();
base.Dispose(disposing);
}
}
}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
where TStartup : class
where TContext : DbContext
{
public LoginTests(ServerFactory<TStartup, TContext> serverFactory)
protected LoginTests(ServerFactory<TStartup, TContext> serverFactory)
{
ServerFactory = serverFactory;
}
@ -289,6 +289,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices));
ServerFactory.EnsureDatabaseCreated();
var client = server.CreateClient();
var newClient = server.CreateClient();
@ -311,6 +313,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices));
ServerFactory.EnsureDatabaseCreated();
var client = server.CreateClient();
var resetPasswordClient = server.CreateClient();
var newClient = server.CreateClient();

View File

@ -289,6 +289,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.WithWebHostBuilder(whb => whb.ConfigureTestServices(ConfigureTestServices))
.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var userName = $"{Guid.NewGuid()}@example.com";
var guid = Guid.NewGuid();
var email = userName;

View File

@ -20,7 +20,7 @@
<Reference Include="Microsoft.AspNetCore.Mvc.Testing" />
<Reference Include="Microsoft.Extensions.Logging.Testing" />
<Reference Include="Microsoft.EntityFrameworkCore.InMemory" />
<Reference Include="Microsoft.EntityFrameworkCore.Sqlite" />
<Reference Include="AngleSharp" />
</ItemGroup>

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
where TStartup : class
where TContext : DbContext
{
public RegistrationTests(ServerFactory<TStartup, TContext> serverFactory)
protected RegistrationTests(ServerFactory<TStartup, TContext> serverFactory)
{
ServerFactory = serverFactory;
}
@ -31,6 +31,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
@ -49,6 +51,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var client = server.CreateClient();
var client2 = server.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
@ -81,6 +85,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var client = server.CreateClient();
var client2 = server.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
@ -102,6 +108,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
@ -121,6 +129,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var guid = Guid.NewGuid();
var userName = $"{guid}";
var email = $"{guid}@example.com";
@ -141,6 +151,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var guid = Guid.NewGuid();
var userName = $"{guid}";
var email = $"{guid}@example.com";
@ -162,6 +174,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
ServerFactory.EnsureDatabaseCreated();
var guid = Guid.NewGuid();
var userName = $"{guid}";
var email = $"{guid}@example.com";

View File

@ -4,11 +4,13 @@
using System;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.AspNetCore.Identity.InMemory.Test
{
public class InMemoryUserStoreTest : UserManagerSpecificationTestBase<PocoUser, string>
public class InMemoryUserStoreTest : UserManagerSpecificationTestBase<PocoUser, string>, IClassFixture<InMemoryUserStoreTest.Fixture>
{
protected override object CreateTestContext()
{
@ -41,5 +43,22 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
protected override Expression<Func<PocoUser, bool>> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
protected override Expression<Func<PocoUser, bool>> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
public class Fixture : IDisposable
{
private readonly SqliteConnection _connection
= new SqliteConnection($"DataSource=:memory:");
public Fixture()
{
_connection.Open();
}
public void Dispose()
{
_connection.Close();
_connection.Dispose();
}
}
}
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
@ -14,6 +14,7 @@
<Reference Include="Microsoft.AspNetCore.Identity.Specification.Tests" />
<Reference Include="Microsoft.AspNetCore.Identity" />
<Reference Include="Microsoft.AspNetCore.TestHost" />
<Reference Include="Microsoft.EntityFrameworkCore.Sqlite" />
</ItemGroup>
</Project>

View File

@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.Mvc.Testing
protected virtual Microsoft.AspNetCore.Hosting.IWebHostBuilder CreateWebHostBuilder() { throw null; }
public void Dispose() { }
protected virtual void Dispose(bool disposing) { }
public virtual void EnsureDatabaseCreated() { }
~WebApplicationFactory() { }
protected virtual System.Collections.Generic.IEnumerable<System.Reflection.Assembly> GetTestAssemblies() { throw null; }
public Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint> WithWebHostBuilder(System.Action<Microsoft.AspNetCore.Hosting.IWebHostBuilder> configuration) { throw null; }

View File

@ -162,6 +162,12 @@ namespace Microsoft.AspNetCore.Mvc.Testing
SetContentRoot(builder);
_configuration(builder);
_server = CreateServer(builder);
EnsureDatabaseCreated();
}
public virtual void EnsureDatabaseCreated()
{
}
private void SetContentRoot(IWebHostBuilder builder)