func (suite *AccountsTestSuite) TestResetPassword() {
	// Insert a test password reset
	testPasswordReset, err := accounts.NewPasswordReset(
		suite.users[1],
		suite.cnf.AppSpecific.PasswordResetLifetime,
	)
	assert.NoError(suite.T(), err, "Failed to create a new password reset object")
	err = suite.db.Create(testPasswordReset).Error
	assert.NoError(suite.T(), err, "Inserting test data failed")
	testPasswordReset.User = suite.users[1]

	// Error should be nil
	assert.Nil(
		suite.T(),
		suite.service.ResetPassword(testPasswordReset, "newpassword"),
	)

	// The password reset object should have been deleted
	assert.True(
		suite.T(),
		suite.db.Find(new(accounts.PasswordReset), testPasswordReset.ID).RecordNotFound(),
	)
}
func (suite *AccountsTestSuite) TestConfirmPasswordReset() {
	var (
		testOauthUser     *oauth.User
		testUser          *accounts.User
		testPasswordReset *accounts.PasswordReset
		err               error
	)

	// Insert a test user
	testOauthUser, err = suite.service.GetOauthService().CreateUser(
		roles.User,
		"harold@finch",
		"", // blank password
	)
	assert.NoError(suite.T(), err, "Failed to insert a test oauth user")
	testUser, err = accounts.NewUser(
		suite.accounts[0],
		testOauthUser,
		"",    //facebook ID
		false, // confirmed
		&accounts.UserRequest{
			FirstName: "Harold",
			LastName:  "Finch",
		},
	)
	assert.NoError(suite.T(), err, "Failed to create a new user object")
	err = suite.db.Create(testUser).Error
	assert.NoError(suite.T(), err, "Failed to insert a test user")
	testUser.Account = suite.accounts[0]
	testUser.OauthUser = testOauthUser

	// Insert a test password reset
	testPasswordReset, err = accounts.NewPasswordReset(
		testUser,
		suite.cnf.AppSpecific.PasswordResetLifetime,
	)
	assert.NoError(suite.T(), err, "Failed to create a new password reset object")
	err = suite.db.Create(testPasswordReset).Error
	assert.NoError(suite.T(), err, "Failed to insert a test password reset")
	testPasswordReset.User = testUser

	// Prepare a request
	payload, err := json.Marshal(&accounts.ConfirmPasswordResetRequest{
		PasswordRequest: accounts.PasswordRequest{Password: "******"},
	})
	assert.NoError(suite.T(), err, "JSON marshalling failed")
	r, err := http.NewRequest(
		"POST",
		fmt.Sprintf("http://1.2.3.4/v1/password-resets/%s", testPasswordReset.Reference),
		bytes.NewBuffer(payload),
	)
	assert.NoError(suite.T(), err, "Request setup should not get an error")
	r.Header.Set(
		"Authorization",
		fmt.Sprintf(
			"Basic %s",
			b64.StdEncoding.EncodeToString([]byte("test_client_1:test_secret")),
		),
	)

	// Check the routing
	match := new(mux.RouteMatch)
	suite.router.Match(r, match)
	if assert.NotNil(suite.T(), match.Route) {
		assert.Equal(suite.T(), "confirm_password_reset", match.Route.GetName())
	}

	// Count before
	var countBefore int
	suite.db.Model(new(accounts.PasswordReset)).Count(&countBefore)

	// And serve the request
	w := httptest.NewRecorder()
	suite.router.ServeHTTP(w, r)

	// Count after
	var countAfter int
	suite.db.Model(new(accounts.PasswordReset)).Count(&countAfter)
	assert.Equal(suite.T(), countBefore-1, countAfter)

	// Fetch the updated user
	user := new(accounts.User)
	notFound := accounts.UserPreload(suite.db).First(user, testUser.ID).RecordNotFound()
	assert.False(suite.T(), notFound)

	// Password reset should have been soft deleted
	assert.True(suite.T(), suite.db.First(new(accounts.PasswordReset), testPasswordReset.ID).RecordNotFound())

	// And correct data was saved
	assert.Nil(suite.T(), pass.VerifyPassword(user.OauthUser.Password.String, "test_password"))

	// Check the response
	expected, err := accounts.NewPasswordResetResponse(testPasswordReset)
	assert.NoError(suite.T(), err, "Failed to create expected response object")
	testutil.TestResponseObject(suite.T(), w, expected, 200)
}
func (suite *AccountsTestSuite) TestFindPasswordResetByReference() {
	var (
		testExpiredPasswordReset, testPasswordReset, passwordReset *accounts.PasswordReset
		err                                                        error
	)

	// Insert test password resets

	testExpiredPasswordReset, err = accounts.NewPasswordReset(
		suite.users[1],
		-10, // expires in
	)
	assert.NoError(suite.T(), err, "Failed to create a new password reset object")
	err = suite.db.Create(testExpiredPasswordReset).Error
	assert.NoError(suite.T(), err, "Inserting test expired password reset failed")
	testExpiredPasswordReset.User = suite.users[1]

	testPasswordReset, err = accounts.NewPasswordReset(
		suite.users[1],
		suite.cnf.AppSpecific.PasswordResetLifetime,
	)
	assert.NoError(suite.T(), err, "Failed to create a new password reset object")
	err = suite.db.Create(testPasswordReset).Error
	assert.NoError(suite.T(), err, "Inserting test password reset failed")
	testPasswordReset.User = suite.users[1]

	// Let's try to find an expired password reset by a valid reference
	passwordReset, err = suite.service.FindPasswordResetByReference(testExpiredPasswordReset.Reference)

	// Password reset should be nil
	assert.Nil(suite.T(), passwordReset)

	// Correct error should be returned
	if assert.NotNil(suite.T(), err) {
		assert.Equal(suite.T(), accounts.ErrPasswordResetNotFound, err)
	}

	// Let's try to find a password reset by a bogus reference
	passwordReset, err = suite.service.FindPasswordResetByReference("bogus")

	// Password reset should be nil
	assert.Nil(suite.T(), passwordReset)

	// Correct error should be returned
	if assert.NotNil(suite.T(), err) {
		assert.Equal(suite.T(), accounts.ErrPasswordResetNotFound, err)
	}

	// Now let's pass a valid reference of an expired password reset
	passwordReset, err = suite.service.FindPasswordResetByReference(testExpiredPasswordReset.Reference)

	// Password reset should be nil
	assert.Nil(suite.T(), passwordReset)

	// Correct error should be returned
	if assert.NotNil(suite.T(), err) {
		assert.Equal(suite.T(), accounts.ErrPasswordResetNotFound, err)
	}

	// Now let's pass a valid reference
	passwordReset, err = suite.service.FindPasswordResetByReference(testPasswordReset.Reference)

	// Error should be nil
	assert.Nil(suite.T(), err)

	// Correct password reset should be returned with preloaded data
	if assert.NotNil(suite.T(), passwordReset) {
		assert.Equal(suite.T(), suite.users[1].ID, passwordReset.User.ID)
		assert.False(suite.T(), passwordReset.EmailSent)
		assert.Nil(suite.T(), passwordReset.EmailSentAt)
	}
}
func (suite *AccountsTestSuite) TestCreatePasswordResetSecondTime() {
	// Insert a test password reset
	testPasswordReset, err := accounts.NewPasswordReset(
		suite.users[1],
		suite.cnf.AppSpecific.PasswordResetLifetime,
	)
	assert.NoError(suite.T(), err, "Failed to create a new password reset object")
	err = suite.db.Create(testPasswordReset).Error
	assert.NoError(suite.T(), err, "Failed to insert a test password reset")
	testPasswordReset.User = suite.users[1]

	// Prepare a request
	payload, err := json.Marshal(&accounts.PasswordResetRequest{
		Email: suite.users[1].OauthUser.Username},
	)
	assert.NoError(suite.T(), err, "JSON marshalling failed")
	r, err := http.NewRequest(
		"POST",
		"http://1.2.3.4/v1/password-resets",
		bytes.NewBuffer(payload),
	)
	assert.NoError(suite.T(), err, "Request setup should not get an error")
	r.Header.Set(
		"Authorization",
		fmt.Sprintf(
			"Basic %s",
			b64.StdEncoding.EncodeToString([]byte("test_client_1:test_secret")),
		),
	)

	suite.service.WaitForNotifications(1)
	// Mock password reset email
	suite.mockPasswordResetEmail()

	// Check the routing
	match := new(mux.RouteMatch)
	suite.router.Match(r, match)
	if assert.NotNil(suite.T(), match.Route) {
		assert.Equal(suite.T(), "create_password_reset", match.Route.GetName())
	}

	// Count before
	var countBefore int
	suite.db.Model(new(accounts.PasswordReset)).Count(&countBefore)

	// And serve the request
	w := httptest.NewRecorder()
	suite.router.ServeHTTP(w, r)

	// Count after
	var countAfter int
	suite.db.Model(new(accounts.PasswordReset)).Count(&countAfter)
	assert.Equal(suite.T(), countBefore, countAfter)

	// Fetch the created password reset
	passwordReset := new(accounts.PasswordReset)
	notFound := accounts.PasswordResetPreload(suite.db).Last(passwordReset).RecordNotFound()
	assert.False(suite.T(), notFound)

	// And correct data was saved
	assert.NotEqual(suite.T(), testPasswordReset.ID, passwordReset.ID)
	assert.Equal(suite.T(), testPasswordReset.User.ID, passwordReset.User.ID)

	// Check the response
	expected, err := accounts.NewPasswordResetResponse(passwordReset)
	assert.NoError(suite.T(), err, "Failed to create expected response object")
	testutil.TestResponseObject(suite.T(), w, expected, 201)

	// block until email goroutine has finished
	assert.True(suite.T(), <-suite.service.GetNotifications(), "The email goroutine should have run")

	// Check that the mock object expectations were met
	suite.assertMockExpectations()
}