package mcp_test import ( "context" "testing" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/yan1h/agent-coding-workflow/internal/infra/errs" "github.com/yan1h/agent-coding-workflow/internal/mcp" "github.com/yan1h/agent-coding-workflow/internal/user" ) type fakeUserSvc struct{ users map[uuid.UUID]*user.User } func (s *fakeUserSvc) Login(_ context.Context, _, _, _ string) (string, *user.User, error) { return "", nil, nil } func (s *fakeUserSvc) Logout(_ context.Context, _ string) error { return nil } func (s *fakeUserSvc) ResolveSession(_ context.Context, _ string) (uuid.UUID, bool, error) { return uuid.Nil, false, nil } func (s *fakeUserSvc) Get(_ context.Context, id uuid.UUID) (*user.User, error) { if u, ok := s.users[id]; ok { return u, nil } return nil, errs.New(errs.CodeNotFound, "user") } func (s *fakeUserSvc) Bootstrap(_ context.Context, _, _ string) (*user.User, error) { return nil, nil } func (s *fakeUserSvc) ListAdmins(_ context.Context) ([]*user.User, error) { return nil, nil } func (s *fakeUserSvc) ListUsers(_ context.Context) ([]*user.User, error) { return nil, nil } func (s *fakeUserSvc) CreateUser(_ context.Context, _ user.CreateUserInput) (*user.User, error) { return nil, nil } func (s *fakeUserSvc) UpdateProfile(_ context.Context, _ uuid.UUID, _ string) (*user.User, error) { return nil, nil } func (s *fakeUserSvc) SetAdmin(_ context.Context, _, _ uuid.UUID, _ bool) (*user.User, error) { return nil, nil } func (s *fakeUserSvc) SetEnabled(_ context.Context, _, _ uuid.UUID, _ bool) (*user.User, error) { return nil, nil } func (s *fakeUserSvc) AdminResetPassword(_ context.Context, _ uuid.UUID) (string, error) { return "", nil } func (s *fakeUserSvc) ChangePassword(_ context.Context, _ uuid.UUID, _, _ string) error { return nil } func (s *fakeUserSvc) DeleteUser(_ context.Context, _, _ uuid.UUID) error { return nil } func ctxWithSession(s *mcp.AuthSession) context.Context { return context.WithValue(context.Background(), mcp.AuthContextKey, s) } func TestCallerResolver_Admin(t *testing.T) { t.Parallel() uid := uuid.New() uSvc := &fakeUserSvc{users: map[uuid.UUID]*user.User{ uid: {ID: uid, IsAdmin: true}, }} r := mcp.NewCallerResolver(uSvc) c, err := r.Resolve(ctxWithSession(&mcp.AuthSession{ UserID: uid.String(), TokenID: uuid.NewString(), })) require.NoError(t, err) assert.True(t, c.IsAdmin) assert.Equal(t, uid, c.UserID) } func TestCallerResolver_NonAdmin(t *testing.T) { t.Parallel() uid := uuid.New() uSvc := &fakeUserSvc{users: map[uuid.UUID]*user.User{ uid: {ID: uid, IsAdmin: false}, }} r := mcp.NewCallerResolver(uSvc) c, err := r.Resolve(ctxWithSession(&mcp.AuthSession{ UserID: uid.String(), TokenID: uuid.NewString(), })) require.NoError(t, err) assert.False(t, c.IsAdmin) } func TestCallerResolver_NoSession(t *testing.T) { t.Parallel() r := mcp.NewCallerResolver(&fakeUserSvc{}) _, err := r.Resolve(context.Background()) ae, ok := errs.As(err) require.True(t, ok) assert.Equal(t, errs.CodeInternal, ae.Code) } func TestCallerResolver_UserDeleted(t *testing.T) { t.Parallel() uid := uuid.New() r := mcp.NewCallerResolver(&fakeUserSvc{users: map[uuid.UUID]*user.User{}}) _, err := r.Resolve(ctxWithSession(&mcp.AuthSession{ UserID: uid.String(), TokenID: uuid.NewString(), })) ae, ok := errs.As(err) require.True(t, ok) assert.Equal(t, errs.CodeNotFound, ae.Code) }