package authsvc import ( "context" "testing" "time" "github.com/stretchr/testify/require" "portal-mini-go/internal/model/admin" "portal-mini-go/internal/pkg/auth" "portal-mini-go/internal/pkg/errors" ) type fakeUserRepo struct { byUsername map[string]*admin.User byID map[uint64]*admin.User } func (r *fakeUserRepo) GetByUsername(_ context.Context, username string) (*admin.User, error) { if u, ok := r.byUsername[username]; ok { return u, nil } return nil, errors.ErrNotFound } func (r *fakeUserRepo) GetByID(_ context.Context, id uint64) (*admin.User, error) { if u, ok := r.byID[id]; ok { return u, nil } return nil, errors.ErrNotFound } type fakeProvider struct { roles []string perms []string menus []admin.MenuNode } func (p *fakeProvider) Load(context.Context, uint64) ([]string, []string, error) { return p.roles, p.perms, nil } func (p *fakeProvider) RolesOf(context.Context, uint64) ([]string, error) { return p.roles, nil } func (p *fakeProvider) PermissionsOf(context.Context, uint64) ([]string, error) { return p.perms, nil } func (p *fakeProvider) MenuTree(context.Context, uint64) ([]admin.MenuNode, error) { return p.menus, nil } func newSvc(u *admin.User) *Service { repo := &fakeUserRepo{ byUsername: map[string]*admin.User{u.Username: u}, byID: map[uint64]*admin.User{u.ID: u}, } return New(repo, &fakeProvider{}, "secret", time.Hour) } func TestLogin_Success(t *testing.T) { hash, _ := auth.HashPassword("Admin@123456") u := &admin.User{ID: 7, Username: "admin", PasswordHash: hash, Status: admin.UserStatusEnabled} svc := newSvc(u) tok, err := svc.Login(context.Background(), LoginReq{Username: "admin", Password: "Admin@123456"}) require.NoError(t, err) require.NotEmpty(t, tok) } func TestLogin_Failures(t *testing.T) { hash, _ := auth.HashPassword("Admin@123456") u := &admin.User{ID: 7, Username: "admin", PasswordHash: hash, Status: admin.UserStatusEnabled} svc := newSvc(u) _, err := svc.Login(context.Background(), LoginReq{Username: "admin", Password: "wrong"}) require.ErrorIs(t, err, errors.ErrUnauthorized) disabled := &admin.User{ID: 8, Username: "disabled", PasswordHash: hash, Status: admin.UserStatusDisabled} svc2 := newSvc(disabled) _, err = svc2.Login(context.Background(), LoginReq{Username: "disabled", Password: "Admin@123456"}) require.ErrorIs(t, err, errors.ErrUnauthorized) _, err = svc.Login(context.Background(), LoginReq{Username: "nope", Password: "x"}) require.ErrorIs(t, err, errors.ErrUnauthorized) } func TestInfo(t *testing.T) { hash, _ := auth.HashPassword("Admin@123456") u := &admin.User{ID: 7, Username: "admin", Nickname: "超管", PasswordHash: hash, Status: admin.UserStatusEnabled} repo := &fakeUserRepo{byID: map[uint64]*admin.User{7: u}} prov := &fakeProvider{roles: []string{"super_admin"}, perms: []string{"user:view"}, menus: nil} svc := New(repo, prov, "secret", time.Hour) info, err := svc.Info(context.Background(), 7) require.NoError(t, err) require.Equal(t, "7", info.ID) require.Equal(t, "admin", info.Username) require.Equal(t, []string{"super_admin"}, info.Roles) require.Equal(t, []string{"user:view"}, info.Permissions) }