user accounts
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"nearle/models"
|
"nearle/models"
|
||||||
|
"nearle/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -62,3 +63,71 @@ func TestNoEmailLeavesTheSignInNameEmpty(t *testing.T) {
|
|||||||
t.Errorf("authname = %q, want empty", ready.Authname)
|
t.Errorf("authname = %q, want empty", ready.Authname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The wiring, not the function.
|
||||||
|
|
||||||
|
PrepareNewAccount was written, tested and committed — and never called from
|
||||||
|
`users/create`. The unit tests above all passed, because they exercise the
|
||||||
|
function directly; nothing asserted that the creation path actually used it. So
|
||||||
|
four deployments shipped a fix that was not reachable, and the bug it fixes was
|
||||||
|
still reproducible in production every time.
|
||||||
|
|
||||||
|
These call the SERVICE and inspect what reaches the repository, which is the
|
||||||
|
only thing that can tell the two apart.
|
||||||
|
*/
|
||||||
|
|
||||||
|
type recordingUserRepo struct {
|
||||||
|
repositories.UserRepository
|
||||||
|
created models.User
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *recordingUserRepo) CreateUser(user models.User) (int, error) {
|
||||||
|
r.created = user
|
||||||
|
return 4242, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *recordingUserRepo) GetUserById(uid int) (models.UserInfo, error) {
|
||||||
|
return models.UserInfo{Userid: uid}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateUserActuallyPreparesTheAccount(t *testing.T) {
|
||||||
|
repo := &recordingUserRepo{}
|
||||||
|
if _, err := NewUserService(repo).CreateUser(models.User{
|
||||||
|
Email: "thiruomart@gmail.com",
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("CreateUser: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo.created.Authname != "thiruomart@gmail.com" {
|
||||||
|
t.Errorf("the account reached the repository with authname %q — PrepareNewAccount is not wired in",
|
||||||
|
repo.created.Authname)
|
||||||
|
}
|
||||||
|
if repo.created.Configid != ConsoleConfigID {
|
||||||
|
t.Errorf("the account reached the repository with configid %d, want %d",
|
||||||
|
repo.created.Configid, ConsoleConfigID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type recordingTenantRepo struct {
|
||||||
|
repositories.TenantRepository
|
||||||
|
created models.User
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *recordingTenantRepo) CreateStaff(user models.User) error {
|
||||||
|
r.created = user
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The other creation path. Both make back-office accounts, so both have to
|
||||||
|
// prepare them — and only one of them did.
|
||||||
|
func TestCreateStaffActuallyPreparesTheAccount(t *testing.T) {
|
||||||
|
repo := &recordingTenantRepo{}
|
||||||
|
if err := NewTenantService(repo).CreateStaff(models.User{Email: "suriya@example.com"}); err != nil {
|
||||||
|
t.Fatalf("CreateStaff: %v", err)
|
||||||
|
}
|
||||||
|
if repo.created.Authname != "suriya@example.com" || repo.created.Configid != ConsoleConfigID {
|
||||||
|
t.Errorf("CreateStaff did not prepare the account: authname=%q configid=%d",
|
||||||
|
repo.created.Authname, repo.created.Configid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -167,6 +167,12 @@ func (s *userService) AppLogin(user models.User) (models.TenantUserInfo, fiber.M
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userService) CreateUser(user models.User) (models.UserInfo, error) {
|
func (s *userService) CreateUser(user models.User) (models.UserInfo, error) {
|
||||||
|
// Without an authname and a console configid the account is created,
|
||||||
|
// listed, and then refused at the login screen: `weblogin` matches
|
||||||
|
// `WHERE authname = ? AND configid = ?` and never looks at the email
|
||||||
|
// column. See PrepareNewAccount.
|
||||||
|
user = PrepareNewAccount(user)
|
||||||
|
|
||||||
// Call repository to create user
|
// Call repository to create user
|
||||||
userid, err := s.repo.CreateUser(user)
|
userid, err := s.repo.CreateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user