public async Task CreateUserWithElasticId()
        {
            using (var store = new UserStoreFixture <ElasticUser>())
            {
                var user = new ElasticUser()
                {
                    UserName = UserName,
                    Phone    = new ElasticUserPhone
                    {
                        Number      = "555 123 1234",
                        IsConfirmed = true
                    },
                    Email = new ElasticUserEmail
                    {
                        Address     = "*****@*****.**",
                        IsConfirmed = false
                    }
                };

                await store.CreateAsync(user);

                var elasticUser = await store.FindByNameAsync(UserName);

                Assert.NotNull(elasticUser);
                Assert.Equal(elasticUser.UserName, UserName);
                Assert.NotNull(elasticUser.Id);
                Assert.NotEqual(UserId, elasticUser.Id);
                Assert.NotNull(elasticUser.Version);
            }
        }
        public async Task FindByEmail()
        {
            using (var store = new UserStoreFixture <ElasticUser>())
            {
                var user = new ElasticUser(UserId, UserName)
                {
                    Email = new ElasticUserEmail
                    {
                        Address     = "*****@*****.**",
                        IsConfirmed = false
                    }
                };

                await store.CreateAsync(user);

                var elasticUser = await store.FindByEmailAsync(user.Email.Address);

                Assert.NotNull(elasticUser);
                Assert.Equal(user.EmailAddress, elasticUser.EmailAddress);

                // should ignore case
                elasticUser = await store.FindByEmailAsync(user.Email.Address.ToUpper());

                Assert.NotNull(elasticUser);
                Assert.Equal(user.EmailAddress, elasticUser.EmailAddress);
            }
        }
        public async Task UserNotFoundShouldReturnNullWhenThrowExceptionsOn()
        {
            using (var store = new UserStoreFixture <ElasticUser>(ElasticServerUrl, "elasticidentity-tests", true, true))
            {
                var user404 = await With503RetryForIndexRecovery(async() => await store.FindByIdAsync("missing"), 5);

                Assert.Null(user404);
            }
        }
        public async Task FindById()
        {
            using (var store = new UserStoreFixture <ElasticUser>())
            {
                var user = new ElasticUser(UserId, UserName);

                await store.CreateAsync(user);

                var elasticUser = await store.FindByIdAsync(user.Id);

                Assert.NotNull(elasticUser);
                Assert.Equal(user.Id, elasticUser.Id);
            }
        }
        public async Task DeleteUser()
        {
            using (var store = new UserStoreFixture <ElasticUser>())
            {
                var user = new ElasticUser(UserId, UserName);

                await store.CreateAsync(user);

                await store.DeleteAsync(user);

                var elasticUser = await store.FindByNameAsync(user.UserName);

                Assert.Null(elasticUser);
            }
        }
        public async Task CustomIndexAndTypeName()
        {
            var indexName = "custom-index";

            using (var store = new UserStoreFixture <ExtendedUser>(ElasticServerUrl, indexName, true, true))
            {
                var user = new ExtendedUser(UserId, UserName);

                user.Roles.UnionWith(new[] { "hello" });

                await store.CreateAsync(user);

                var response = store.Client.Get <ExtendedUser>(new GetRequest(indexName, TypeName.From <ExtendedUser>(), user.Id));

                Assert.NotNull(response.Source);
                Assert.Equal(response.Source.UserName, user.UserName);
            }
        }
        public async Task UpdateUser()
        {
            using (var store = new UserStoreFixture <ElasticUser>())
            {
                var user = new ElasticUser(UserId, UserName);

                await store.CreateAsync(user);

                user = await store.FindByIdAsync(user.Id);

                user.Roles.Add("hello");

                await store.UpdateAsync(user);

                user = await store.FindByIdAsync(user.Id);

                Assert.True(user.Roles.Contains("hello"));

                // create another user object from the same id
                var sameUser = await store.FindByIdAsync(user.Id);

                sameUser.Roles.Add("another_role");
                await store.UpdateAsync(sameUser);

                sameUser = await store.FindByIdAsync(sameUser.Id);

                Assert.True(sameUser.Roles.Contains("another_role"));

                // same id, different versions
                Assert.Equal(user.Id, sameUser.Id);
                Assert.NotEqual(user.Version, sameUser.Version);

                // exception should be thrown as we're attempting to
                // update the original, out of date, user.
                user.Roles.Add("bad_role");
                await Assert.ThrowsAsync <Elasticsearch.Net.ElasticsearchClientException>(async() => await store.UpdateAsync(user));
            }
        }
        public async Task FailToCreateUserDueToExistingId()
        {
            using (var store = new UserStoreFixture <ElasticUser>())
            {
                var user = new ElasticUser(UserId, UserName);

                await store.CreateAsync(user);

                bool threwConflictException = false;
                try
                {
                    await store.CreateAsync(user);
                }
                catch (ElasticsearchClientException ex)
                {
                    if (ex.Message.Contains("409"))
                    {
                        threwConflictException = true;
                    }
                }

                Assert.True(threwConflictException);
            }
        }