127 lines
3.6 KiB
Go
127 lines
3.6 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
app "haixun-backend/internal/library/errors"
|
|
"haixun-backend/internal/library/errors/code"
|
|
"haixun-backend/internal/model/member/domain/entity"
|
|
domrepo "haixun-backend/internal/model/member/domain/repository"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type memoryMemberRepo struct {
|
|
byEmail map[string]*entity.Member
|
|
}
|
|
|
|
func memberKey(tenantID, email string) string {
|
|
return tenantID + ":" + normalizeEmail(email)
|
|
}
|
|
|
|
func (m *memoryMemberRepo) EnsureIndexes(context.Context) error { return nil }
|
|
|
|
func (m *memoryMemberRepo) Create(_ context.Context, member *entity.Member) (*entity.Member, error) {
|
|
if m.byEmail == nil {
|
|
m.byEmail = map[string]*entity.Member{}
|
|
}
|
|
key := memberKey(member.TenantID, member.Email)
|
|
if _, ok := m.byEmail[key]; ok {
|
|
return nil, app.For(code.Member).ResConflict("member already exists")
|
|
}
|
|
cp := *member
|
|
m.byEmail[key] = &cp
|
|
return &cp, nil
|
|
}
|
|
|
|
func (m *memoryMemberRepo) FindByUID(_ context.Context, tenantID, uid string) (*entity.Member, error) {
|
|
for _, item := range m.byEmail {
|
|
if item.TenantID == tenantID && item.UID == uid {
|
|
cp := *item
|
|
return &cp, nil
|
|
}
|
|
}
|
|
return nil, app.For(code.Member).ResNotFound("member not found")
|
|
}
|
|
|
|
func (m *memoryMemberRepo) FindByEmail(_ context.Context, tenantID, email string) (*entity.Member, error) {
|
|
item, ok := m.byEmail[memberKey(tenantID, email)]
|
|
if !ok {
|
|
return nil, app.For(code.Member).ResNotFound("member not found")
|
|
}
|
|
cp := *item
|
|
return &cp, nil
|
|
}
|
|
|
|
func (m *memoryMemberRepo) UpdateProfile(context.Context, string, string, domrepo.ProfileUpdate) (*entity.Member, error) {
|
|
return nil, app.For(code.Member).SysNotImplemented("not implemented")
|
|
}
|
|
|
|
func (m *memoryMemberRepo) SetActiveThreadsAccountID(_ context.Context, tenantID, uid, accountID string) error {
|
|
for _, item := range m.byEmail {
|
|
if item.TenantID == tenantID && item.UID == uid {
|
|
item.ActiveThreadsAccountID = accountID
|
|
return nil
|
|
}
|
|
}
|
|
return app.For(code.Member).ResNotFound("member not found")
|
|
}
|
|
|
|
func (m *memoryMemberRepo) SetRoles(_ context.Context, tenantID, uid string, roles []string) error {
|
|
for _, item := range m.byEmail {
|
|
if item.TenantID == tenantID && item.UID == uid {
|
|
item.Roles = append([]string(nil), roles...)
|
|
return nil
|
|
}
|
|
}
|
|
return app.For(code.Member).ResNotFound("member not found")
|
|
}
|
|
|
|
func TestEnsureAdminMemberCreatesAdmin(t *testing.T) {
|
|
repo := &memoryMemberRepo{byEmail: map[string]*entity.Member{}}
|
|
member, created, err := EnsureAdminMember(context.Background(), repo, AdminOptions{
|
|
TenantID: "default",
|
|
Email: "admin@haixun.local",
|
|
Password: "Admin-Pass-1!",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("EnsureAdminMember: %v", err)
|
|
}
|
|
if !created {
|
|
t.Fatal("expected created=true")
|
|
}
|
|
if member.Roles[0] != "admin" {
|
|
t.Fatalf("roles=%v", member.Roles)
|
|
}
|
|
if err := bcrypt.CompareHashAndPassword([]byte(member.PasswordHash), []byte("Admin-Pass-1!")); err != nil {
|
|
t.Fatalf("password hash mismatch: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestEnsureAdminMemberUpgradesExisting(t *testing.T) {
|
|
repo := &memoryMemberRepo{byEmail: map[string]*entity.Member{
|
|
memberKey("default", "admin@haixun.local"): {
|
|
TenantID: "default",
|
|
UID: "uid-1",
|
|
Email: "admin@haixun.local",
|
|
Roles: []string{"user"},
|
|
},
|
|
}}
|
|
_, created, err := EnsureAdminMember(context.Background(), repo, AdminOptions{
|
|
TenantID: "default",
|
|
Email: "admin@haixun.local",
|
|
Password: "Admin-Pass-1!",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("EnsureAdminMember: %v", err)
|
|
}
|
|
if created {
|
|
t.Fatal("expected created=false")
|
|
}
|
|
member := repo.byEmail[memberKey("default", "admin@haixun.local")]
|
|
if len(member.Roles) != 1 || member.Roles[0] != "admin" {
|
|
t.Fatalf("roles=%v", member.Roles)
|
|
}
|
|
}
|