Files
kra-new/internal/biz/business/account_test.go
T

113 lines
3.9 KiB
Go

package business
import (
"context"
"golang.org/x/crypto/bcrypt"
"kra/internal/biz/system"
"testing"
)
type accountRepoFake struct {
AccountRepo
accounts map[uint]*Account
created *Account
updated *Account
listCalls int
scope UserScope
}
func (r *accountRepoFake) Find(_ context.Context, id uint) (*Account, error) {
if a := r.accounts[id]; a != nil {
copy := *a
return &copy, nil
}
return nil, ErrAccountNotFound
}
func (r *accountRepoFake) AuthorityForLevel(_ context.Context, level int) (uint, error) {
return uint(900 + level), nil
}
func (r *accountRepoFake) Create(_ context.Context, a *Account) error {
copy := *a
r.created = &copy
a.ID = 30
return nil
}
func (r *accountRepoFake) Update(_ context.Context, a *Account) error { r.updated = a; return nil }
func (r *accountRepoFake) List(_ context.Context, scope UserScope, _ ...ListOption) ([]*Account, int64, error) {
r.listCalls++
r.scope = scope
return []*Account{}, 0, nil
}
func accountContext(id, aid uint) context.Context {
return system.NewActorContext(context.Background(), system.Actor{UserID: id, AuthorityID: aid})
}
func TestChildBusinessUsesServerHierarchyAndMappedRole(t *testing.T) {
for _, level := range []int{0, 1, 2, 3} {
r := &accountRepoFake{accounts: map[uint]*Account{12: {ID: 12, Level: level, IDPath: "0,5"}}}
uc := NewAccountUsecase(r)
aid := uint(901)
if level == 0 {
aid = 888
}
a, err := uc.CreateChild(accountContext(12, aid), &Account{ID: 999, Level: 1, ParentID: 999, IDPath: "0,999", AuthorityID: 888, Username: "child", Password: "password", RealName: "姓名"})
if level == 3 {
if err != ErrChildLevel || r.created != nil {
t.Fatalf("三级不应创建子商务: %v", err)
}
continue
}
if err != nil {
t.Fatal(err)
}
if r.created.Level != level+1 || r.created.AuthorityID != uint(901+level) || r.created.Status != 0 || r.created.NickName != "姓名" {
t.Fatalf("层级或默认信息不正确: %+v", r.created)
}
if level == 0 {
if r.created.ParentID != 0 || r.created.IDPath != "0" {
t.Fatal("超管创建的一级挂错归属")
}
} else if r.created.ParentID != 12 || r.created.IDPath != "0,5,12" {
t.Fatal("子商务祖先链不正确")
}
if a.Password != "" || bcrypt.CompareHashAndPassword([]byte(r.created.Password), []byte("password")) != nil {
t.Fatal("密码未安全写入或泄露到返回值")
}
}
}
func TestBusinessScopeSeparatesDescendantsAndSiblings(t *testing.T) {
r := &accountRepoFake{accounts: map[uint]*Account{
12: {ID: 12, Level: 1, IDPath: "0"}, 13: {ID: 13, Level: 2, ParentID: 12, IDPath: "0,12"}, 14: {ID: 14, Level: 3, IDPath: "0,12,13"},
99: {ID: 99, Level: 2, IDPath: "0,123"},
}}
uc := NewAccountUsecase(r)
ctx := accountContext(12, 901)
for _, id := range []uint{12, 13, 14} {
if _, err := uc.Find(ctx, id); err != nil {
t.Fatalf("本人及下级应可查: %v", err)
}
}
if _, err := uc.Find(ctx, 99); err != ErrAccountScope {
t.Fatalf("ID 前缀相似的其他树不应可见: %v", err)
}
if _, _, err := uc.List(accountContext(14, 903), AccountFilter{}); err != nil || r.listCalls != 0 {
t.Fatal("三级商务列表应直接返回空")
}
if _, _, err := uc.List(ctx, AccountFilter{}); err != nil || r.scope.IncludeSelf || r.scope.All || r.scope.DescendantPath != "0,12" {
t.Fatalf("商务列表应仅下级: %+v %v", r.scope, err)
}
}
func TestAccountPartialEditKeepsHierarchyAndReviewState(t *testing.T) {
r := &accountRepoFake{accounts: map[uint]*Account{1: {ID: 1}, 2: {ID: 2, Level: 2, ParentID: 8, IDPath: "0,8", Status: 3, AuthorityID: 902, Username: "child"}}}
name := "新姓名"
if err := NewAccountUsecase(r).Update(accountContext(1, 888), &AccountUpdate{ID: 2, RealName: &name}); err != nil {
t.Fatal(err)
}
if a := r.updated; a.Status != 3 || a.Level != 2 || a.ParentID != 8 || a.AuthorityID != 902 || a.Username != "child" || a.RealName != name {
t.Fatalf("部分更新改变了其他字段: %+v", a)
}
}