public async Task CreateUser_should_create_a_new_user()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new ApplicationRole("Admin"));
                    await session.StoreAsync(new ApplicationRole("Accounts"));
                    await session.SaveChangesAsync();

                    var controller = GetAccountsController(session);

                    // Arrange
                    var model = new CreateUserBindingModel
                    {
                        Username = "******",
                        FirstName = "Jeremy",
                        LastName = "Holt",
                        Email = "*****@*****.**",
                        Password = "******"
                    };
                    model.Roles.AddRange(new List<string> {"Admin", "Accounts"});

                    // Act
                    var userModel = await controller.CreateUser(model);
                    var created = (CreatedNegotiatedContentResult<ReturnUserModel>) (userModel);

                    var userReturnModel = await controller.GetUser(ApplicationUser.GenerateKey("jeremyholt"));
                    var result = (OkNegotiatedContentResult<ReturnUserModel>) (userReturnModel);

                    // Assert
                    result.Content.UserName.Should().Be("jeremyholt");
                    result.Content.FullName.Should().Be("Jeremy Holt");
                    result.Content.Claims.Should().HaveCount(2).And.Contain(c => c.Type == ClaimTypes.Role && c.Value == "Accounts");
                    result.Content.EmailConfirmed.Should().BeFalse();
                    result.Content.Roles.Should().HaveCount(2).And.Contain(c => c == "Accounts");
                    result.Content.OkMessage.Should().BeNull();
                    created.Content.OkMessage.Should().Be("Criou usuário jeremyholt");
                }
            }
        }
        public void CreateUser_should_throw_exception_if_the_role_he_is_allocated_to_does_not_exist()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    var controller = GetAccountsController(session);

                    // Arrange
                    var model = new CreateUserBindingModel
                    {
                        Username = "******",
                        FirstName = "Jeremy",
                        LastName = "Holt",
                        Email = "*****@*****.**",
                        Password = "******"
                    };
                    model.Roles.AddRange(new List<string> {"Admin", "Accounts"});

                    // Act
                    var act = new Func<Task>(() => controller.CreateUser(model));

                    // Assert
                    act.ShouldThrow<InvalidOperationException>()
                        .WithMessage("Não existem as cargas 'Admin, Accounts' - por favor cria essas cargas antes que tentando de adicionar o usuário.");
                }
            }
        }
        public async Task UpdateUser_should_not_change_his_password_hash()
        {
            using (var store = NewDocumentStore())
            {
                string passwordHash;
                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new ApplicationRole("Admin"));
                    await session.SaveChangesAsync();

                    // Arrange
                    var userModel = new CreateUserBindingModel
                    {
                        Username = "******",
                        FirstName = "Jeremy",
                        LastName = "Holt",
                        Email = "*****@*****.**",
                        Password = "******"
                    };
                    userModel.Roles.Add("Admin");

                    var controller = GetAccountsController(session);

                    await controller.CreateUser(userModel);

                    // Check saved properly
                    var user = await session.LoadAsync<ApplicationUser>(ApplicationUser.GenerateKey("jeremyholt"));
                    user.PasswordHash.Should().NotBeNull();
                    passwordHash = user.PasswordHash;
                }

                using (var session = store.OpenAsyncSession())
                {
                    // Act - load and change user's first name
                    var controller = GetAccountsController(session);
                    var updateModel = new UpdateUserBindingModel
                    {
                        UserName = "******",
                        FirstName = "Jeremy",
                        LastName = "Last name",
                        Email = "*****@*****.**",                        
                        JoinDate = new DateTime(2013, 5, 6)
                    };
                    updateModel.Roles.AddRange(new List<string> {"Admin", "Accounts"});

                    await controller.UpdateUserAsync(updateModel);

                    // Assert
                    var actual = (OkNegotiatedContentResult<ReturnUserModel>) (await controller.GetUserByName("jeremyholt"));
                    actual.Content.FirstName.Should().Be("Jeremy");
                    actual.Content.LastName.Should().Be("Last name");                    
                    actual.Content.Roles.Should().HaveCount(2).And.Contain("Admin").And.Contain("Accounts");
                    actual.Content.Claims.Should().HaveCount(2).And.Contain(c => c.Type == ClaimTypes.Role && c.Value == "Accounts");

                    // Load user directly from db
                    var user = await session.LoadAsync<ApplicationUser>(ApplicationUser.GenerateKey("jeremyholt"));
                    user.LastName.Should().Be("Last name");                    
                    user.PasswordHash.Should().Be(passwordHash);
                    user.JoinDate.Should().Be(new DateTime(2013, 5, 6));
                }
            }
        }
        public async Task CreateUser_should_return_an_error_if_the_password_is_too_short()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    var controller = GetAccountsController(session);

                    // Arrange
                    var model = new CreateUserBindingModel
                    {
                        Username = "******",
                        FirstName = "Jeremy",
                        LastName = "Holt",
                        Email = "*****@*****.**",
                        Password = "******"
                    };

                    // Act
                    var actionResult = await controller.CreateUser(model);

                    // Assert
                    actionResult.GetModelStateErrorMessages().Should().Be("Passwords must be at least 6 characters.");
                }
            }
        }
        public async Task CreateUser_should_not_throw_exception_if_the_role_he_is_allocated_exists()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new ApplicationRole("Admin"));
                    await session.StoreAsync(new ApplicationRole("Accounts"));
                    await session.SaveChangesAsync();

                    var controller = GetAccountsController(session);

                    // Arrange
                    var model = new CreateUserBindingModel
                    {
                        Username = "******",
                        FirstName = "Jeremy",
                        LastName = "Holt",
                        Email = "*****@*****.**",
                        Password = "******"
                    };
                    model.Roles.AddRange(new List<string> {"Admin", "Accounts"});

                    // Act
                    var actionResult = await controller.CreateUser(model);
                    actionResult.Should().BeOfType<CreatedNegotiatedContentResult<ReturnUserModel>>();
                }
            }
        }
        public async Task<IHttpActionResult> CreateUser(CreateUserBindingModel createUserModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var user = new ApplicationUser(createUserModel.Username)
            {
                Email = createUserModel.Email,
                FirstName = createUserModel.FirstName,
                LastName = createUserModel.LastName,
                JoinDate = DateTime.Now.Date
            };
            user.Roles.AddRange(createUserModel.Roles);


            var addUserResult = await AppUserManager.CreateAsync(user, createUserModel.Password);

            if (!addUserResult.Succeeded)
            {
                return GetErrorResult(addUserResult);
            }

            //var code = await AppUserManager.GenerateEmailConfirmationTokenAsync(user.Id);

            //var callbackUrl = new Uri(Url.Link("ConfirmEmailRoute", new {userId = user.Id, code}));

            //await AppUserManager.SendEmailAsync(user.Id,
            //    "Confirm your account",
            //    "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

            var locationHeader = new Uri(Url.Link("GetUserById", new {id = user.Id}));

            var returnModel = TheModelFactory.Create(user);
            returnModel.OkMessage = "Criou usuário " + user.UserName;

            return Created(locationHeader, returnModel);
        }