113 lines
3.9 KiB
Go
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 ©, 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 = ©
|
|
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)
|
|
}
|
|
}
|