Files
Agent-System/internal/server/project_members_role_test.go
T
weichenandCursor 0fa4a5784e fix(authz): clear reviewer/approver slots in the member-write transaction
Duty revoke must share the project advisory lock with reading old holders and writing members, so a post-commit service snapshot cannot miss a transfer. Heal still fills the new holder after commit, and sync failure stays ERR_DUTY_SYNC.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:37:24 +00:00

52 lines
1.4 KiB
Go

package server
import (
"errors"
"net/http"
"net/http/httptest"
"strings"
"testing"
"chat-agent-system/internal/authz"
)
func TestResolveUpdateProjectRole_KeepsExistingOwner(t *testing.T) {
role, err := resolveUpdateProjectRole("", &authz.ProjectMemberRecord{ProjectRole: authz.RoleOwner})
if err != nil {
t.Fatal(err)
}
if role != authz.RoleOwner {
t.Fatalf("omitted project_role must keep owner, got %q", role)
}
}
func TestResolveUpdateProjectRole_RejectsMissingMember(t *testing.T) {
if _, err := resolveUpdateProjectRole("", nil); !errors.Is(err, errProjectRoleRequired) {
t.Fatalf("want errProjectRoleRequired, got %v", err)
}
if _, err := resolveUpdateProjectRole("", &authz.ProjectMemberRecord{}); !errors.Is(err, errProjectRoleRequired) {
t.Fatalf("empty existing role must be rejected, got %v", err)
}
}
func TestWriteDutySyncError_UsesExplicitCode(t *testing.T) {
rec := httptest.NewRecorder()
writeDutySyncError(rec)
if rec.Code != http.StatusInternalServerError {
t.Fatalf("status=%d", rec.Code)
}
if !strings.Contains(rec.Body.String(), "ERR_DUTY_SYNC") {
t.Fatalf("body=%s", rec.Body.String())
}
}
func TestResolveUpdateProjectRole_ExplicitRoleWins(t *testing.T) {
role, err := resolveUpdateProjectRole(authz.RoleViewer, &authz.ProjectMemberRecord{ProjectRole: authz.RoleOwner})
if err != nil {
t.Fatal(err)
}
if role != authz.RoleViewer {
t.Fatalf("explicit role must win, got %q", role)
}
}