protected internal virtual async Task SaveUserLoginAsync_IfAUserLoginExistAndTheUserIdIsNull_ShouldDoNothing(DatabaseProvider databaseProvider)
        {
            // Prepare
            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                identityFacade.UserManager.Store.AutoSaveChanges = true;
                var user = new UserEntity {
                    UserName = "******"
                };
                await identityFacade.UserManager.CreateAsync(user);

                await identityFacade.UserManager.AddLoginAsync(user, new UserLoginInfo("Provider-1", "User-identifier-1", "Provider-1"));
            }

            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                Assert.IsFalse(identityFacade.UserManager.Store.AutoSaveChanges);

                var result = await identityFacade.SaveUserLoginAsync(new UserLoginModel { Provider = "Provider-1", UserIdentifier = "User-identifier-1" });

                Assert.IsTrue(result.Succeeded);
                Assert.AreEqual(0, await identityFacade.DatabaseContext.SaveChangesAsync());
            }
        }
        protected internal virtual async Task SaveUserLoginAsync_IfAUserLoginExistAndTheUserIdIsNotNullAndAUserForTheUserIdDoesNotExist_ShouldCreateTheUserAndMoveTheUserLoginAndRemoveThePreviousLoginUser(DatabaseProvider databaseProvider)
        {
            const string newId = "afba39de-89b3-47fb-88a5-3dfb5e0fd176";
            const string oldId = "d63c5a23-042e-4c74-8ca1-269407c1a799";

            // Prepare
            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                identityFacade.UserManager.Store.AutoSaveChanges = true;
                var user = new UserEntity {
                    Id = oldId, UserName = "******"
                };
                await identityFacade.UserManager.CreateAsync(user);

                var claims = new List <Claim>
                {
                    new Claim("Claim-type-1", "Claim-value-1"),
                    new Claim("Claim-type-2", "Claim-value-2"),
                    new Claim("Claim-type-3", "Claim-value-3")
                };
                await identityFacade.UserManager.AddClaimsAsync(user, claims);

                await identityFacade.UserManager.AddLoginAsync(user, new UserLoginInfo("Provider-1", "User-identifier-1", "Provider-1"));

                Assert.AreEqual(3, await identityFacade.DatabaseContext.UserClaims.CountAsync());
                Assert.AreEqual(1, await identityFacade.DatabaseContext.UserLogins.CountAsync());
                Assert.AreEqual(1, await identityFacade.DatabaseContext.Users.CountAsync());
            }

            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                Assert.IsFalse(identityFacade.UserManager.Store.AutoSaveChanges);

                var result = await identityFacade.SaveUserLoginAsync(new UserLoginModel { Id = newId, Provider = "Provider-1", UserIdentifier = "User-identifier-1" });

                Assert.IsTrue(result.Succeeded);
                Assert.AreEqual(1, identityFacade.DatabaseContext.ChangeTracker.Entries().Count(entry => entry.State == EntityState.Added));
                Assert.AreEqual(1, identityFacade.DatabaseContext.ChangeTracker.Entries().Count(entry => entry.State == EntityState.Deleted));
                Assert.AreEqual(1, identityFacade.DatabaseContext.ChangeTracker.Entries().Count(entry => entry.State == EntityState.Modified));
                Assert.AreEqual(3, await identityFacade.DatabaseContext.SaveChangesAsync());
                Assert.AreEqual(0, await identityFacade.DatabaseContext.UserClaims.CountAsync());
                Assert.AreEqual(1, await identityFacade.DatabaseContext.UserLogins.CountAsync());
                Assert.AreEqual(newId, (await identityFacade.DatabaseContext.UserLogins.FirstAsync()).UserId);
                Assert.AreEqual(1, await identityFacade.DatabaseContext.Users.CountAsync());
            }
        }
        protected internal virtual async Task SaveUserLoginAsync_IfTheUserIdIsChangedAndTheOldUserHasMoreLogins_ShouldNotRemoveTheOldUserButRemoveTheClaimsForTheOldUser(DatabaseProvider databaseProvider)
        {
            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                const string id = "32348cf4-1e8e-4a97-a185-b52cdd70b996";

                // Prepare
                var autoSaveChanges = identityFacade.UserManager.Store.AutoSaveChanges;
                identityFacade.UserManager.Store.AutoSaveChanges = true;
                var user = new UserEntity {
                    Id = id, UserName = "******"
                };
                await identityFacade.UserManager.CreateAsync(user);

                var claims = new List <Claim>
                {
                    new Claim("Claim-type-1", "Claim-value-1"),
                    new Claim("Claim-type-2", "Claim-value-2"),
                    new Claim("Claim-type-3", "Claim-value-3")
                };
                await identityFacade.UserManager.AddClaimsAsync(user, claims);

                await identityFacade.UserManager.AddLoginAsync(user, new UserLoginInfo("Provider-1", "User-identifier-1", "Provider-1"));

                await identityFacade.UserManager.AddLoginAsync(user, new UserLoginInfo("Provider-2", "User-identifier-2", "Provider-2"));

                identityFacade.UserManager.Store.AutoSaveChanges = autoSaveChanges;

                Assert.IsNotNull(await identityFacade.UserManager.FindByIdAsync(id));
                Assert.AreEqual(3, (await identityFacade.UserManager.GetClaimsAsync(user)).Count);
                Assert.IsNotNull(await identityFacade.UserManager.FindByLoginAsync("Provider-1", "User-identifier-1"));
                Assert.IsNotNull(await identityFacade.UserManager.FindByLoginAsync("Provider-2", "User-identifier-2"));

                const string newId  = "89648c35-08c1-4113-bf09-bdf5b06cece5";
                var          result = await identityFacade.SaveUserLoginAsync(new UserLoginModel { Id = newId, Provider = "Provider-1", UserIdentifier = "User-identifier-1" });

                Assert.IsTrue(result.Succeeded);
                Assert.AreEqual(6, await identityFacade.DatabaseContext.SaveChangesAsync());

                Assert.IsNotNull(await identityFacade.UserManager.FindByIdAsync(id));
                Assert.IsNotNull(await identityFacade.UserManager.FindByIdAsync(newId));
                Assert.AreEqual(0, (await identityFacade.UserManager.GetClaimsAsync(user)).Count);
                Assert.IsNotNull(await identityFacade.UserManager.FindByLoginAsync("Provider-1", "User-identifier-1"));
                Assert.AreEqual(newId, (await identityFacade.UserManager.FindByLoginAsync("Provider-1", "User-identifier-1")).Id);
                Assert.IsNotNull(await identityFacade.UserManager.FindByLoginAsync("Provider-2", "User-identifier-2"));
                Assert.AreEqual(id, (await identityFacade.UserManager.FindByLoginAsync("Provider-2", "User-identifier-2")).Id);
            }
        }
        protected internal virtual async Task SaveUserLoginsAsync_IfNothingIsChanged_ShouldDoNothing(DatabaseProvider databaseProvider)
        {
            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                const string id = "32348cf4-1e8e-4a97-a185-b52cdd70b996";

                // Prepare
                var autoSaveChanges = identityFacade.UserManager.Store.AutoSaveChanges;
                identityFacade.UserManager.Store.AutoSaveChanges = true;
                var user = new UserEntity {
                    Id = id, UserName = "******"
                };
                await identityFacade.UserManager.CreateAsync(user);

                var claims = new List <Claim>
                {
                    new Claim("Claim-type-1", "Claim-value-1"),
                    new Claim("Claim-type-2", "Claim-value-2"),
                    new Claim("Claim-type-3", "Claim-value-3")
                };
                await identityFacade.UserManager.AddClaimsAsync(user, claims);

                await identityFacade.UserManager.AddLoginAsync(user, new UserLoginInfo("Provider-1", "User-identifier-1", "Provider-1"));

                identityFacade.UserManager.Store.AutoSaveChanges = autoSaveChanges;

                Assert.IsNotNull(await identityFacade.UserManager.FindByIdAsync(id));
                Assert.AreEqual(3, (await identityFacade.UserManager.GetClaimsAsync(user)).Count);
                Assert.IsNotNull(await identityFacade.UserManager.FindByLoginAsync("Provider-1", "User-identifier-1"));

                await identityFacade.SaveUserLoginAsync(new UserLoginModel { Id = id, Provider = "Provider-1", UserIdentifier = "User-identifier-1" });

                Assert.AreEqual(5, identityFacade.DatabaseContext.ChangeTracker.Entries().Count(entry => entry.State == EntityState.Unchanged));

                Assert.IsNotNull(await identityFacade.UserManager.FindByIdAsync(id));
                Assert.AreEqual(3, (await identityFacade.UserManager.GetClaimsAsync(user)).Count);
                Assert.IsNotNull(await identityFacade.UserManager.FindByLoginAsync("Provider-1", "User-identifier-1"));
            }
        }
        protected internal virtual async Task SaveUserLoginAsync_IfTheUserIdIsForAPasswordUser_ShouldThrowAnInvalidOperationException(DatabaseProvider databaseProvider)
        {
            using (var context = new Context(databaseProvider: databaseProvider))
            {
                var serviceProvider = context.ServiceProvider;
                await DatabaseHelper.MigrateDatabaseAsync(serviceProvider);

                var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider);

                const string id = "32348cf4-1e8e-4a97-a185-b52cdd70b996";

                // Prepare
                var autoSaveChanges = identityFacade.UserManager.Store.AutoSaveChanges;
                identityFacade.UserManager.Store.AutoSaveChanges = true;
                var user = new UserEntity {
                    Id = id, UserName = "******"
                };
                await identityFacade.UserManager.CreateAsync(user, "P@ssword12");

                identityFacade.UserManager.Store.AutoSaveChanges = autoSaveChanges;

                user = await identityFacade.UserManager.FindByIdAsync(id);

                Assert.IsNotNull(user);
                Assert.IsNotNull(user.PasswordHash);

                try
                {
                    await identityFacade.SaveUserLoginAsync(new UserLoginModel { Id = id, Provider = "Provider-1", UserIdentifier = "User-identifier-1" });

                    Assert.Fail("Should have thrown an exception");
                }
                catch (Exception exception)
                {
                    if (!(exception is InvalidOperationException))
                    {
                        Assert.Fail("Should have thrown an invalid-operation-exception.");
                    }
                }
            }
        }