Files
backend_fiesta/services/newAccount_test.go
2026-09-01 13:53:22 +05:30

134 lines
4.4 KiB
Go

package services
import (
"testing"
"nearle/models"
"nearle/repositories"
)
/*
An account that is created perfectly and cannot sign in.
`weblogin` matches `WHERE authname = ? AND configid = ?`. A form that sends an
email and a name — which is every form in this console — produces a row with an
empty authname and a configid of 0, so the sign-in query matches nothing and
answers "we do not recognise that email".
Observed on 1 Sep 2026: a merchant added their own administrator through the
console, saw it succeed, saw it listed, and was refused at the login screen.
*/
func TestANewAccountCanActuallySignIn(t *testing.T) {
ready := PrepareNewAccount(models.User{Email: "thiruomart@gmail.com"})
if ready.Authname != "thiruomart@gmail.com" {
t.Errorf("authname was not derived from the email: %q", ready.Authname)
}
if ready.Configid != ConsoleConfigID {
t.Errorf("configid = %d, want %d — 0 matches no console account", ready.Configid, ConsoleConfigID)
}
}
// A caller with its own sign-in name keeps it. Deriving from the email is a
// fallback for forms that do not ask, not a rule that overwrites an answer.
func TestAnExplicitSignInNameIsKept(t *testing.T) {
ready := PrepareNewAccount(models.User{Authname: "suriya.nsn", Email: "suriya@example.com"})
if ready.Authname != "suriya.nsn" {
t.Errorf("an explicit authname was overwritten with %q", ready.Authname)
}
}
func TestAnExplicitConfigIsKept(t *testing.T) {
ready := PrepareNewAccount(models.User{Email: "a@b.com", Configid: 4})
if ready.Configid != 4 {
t.Errorf("configid = %d, want the caller's 4", ready.Configid)
}
}
// Whitespace around a pasted email would become an authname nothing can match —
// the same invisible failure, one space wide.
func TestASurroundingSpaceDoesNotBecomePartOfTheSignInName(t *testing.T) {
ready := PrepareNewAccount(models.User{Email: " thiru@omart.com "})
if ready.Authname != "thiru@omart.com" {
t.Errorf("authname = %q, want it trimmed", ready.Authname)
}
}
// An account with no email at all cannot be given a sign-in name, and must not
// be given a blank one that looks like it has been handled.
func TestNoEmailLeavesTheSignInNameEmpty(t *testing.T) {
ready := PrepareNewAccount(models.User{})
if 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)
}
}