package app import ( "testing" "github.com/google/uuid" "github.com/yan1h/agent-coding-workflow/internal/project" ) // projectACL(app 层中央 ACL)必须与 project_service 的 assertReadable/assertWritable // 语义一致——两侧任一漂移都会让 workspace/ACP/chat 作用域与 project 鉴权分叉 // (autonomy roadmap §11)。本白盒测试直接覆盖 projectACL 的角色叠加矩阵。 func TestProjectACL_RoleMatrix(t *testing.T) { owner := uuid.New() stranger := uuid.New() private := &project.Project{ID: uuid.New(), OwnerID: owner, Visibility: project.VisibilityPrivate} internal := &project.Project{ID: uuid.New(), OwnerID: owner, Visibility: project.VisibilityInternal} cases := []struct { name string pj *project.Project caller uuid.UUID isAdmin bool role project.Role wantRead, wantWrt bool }{ {"owner_private", private, owner, false, project.RoleAdmin, true, true}, {"global_admin_private", private, stranger, true, project.RoleNone, true, true}, {"member_private_write", private, stranger, false, project.RoleMember, true, true}, {"admin_role_private_write", private, stranger, false, project.RoleAdmin, true, true}, {"viewer_private_read_only", private, stranger, false, project.RoleViewer, true, false}, {"nonmember_private_denied", private, stranger, false, project.RoleNone, false, false}, {"nonmember_internal_read", internal, stranger, false, project.RoleNone, true, false}, {"viewer_internal_read", internal, stranger, false, project.RoleViewer, true, false}, {"member_internal_write", internal, stranger, false, project.RoleMember, true, true}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { gotRead, gotWrite := projectACL(tc.pj, tc.caller, tc.isAdmin, tc.role) if gotRead != tc.wantRead || gotWrite != tc.wantWrt { t.Fatalf("projectACL(%s)=read:%v,write:%v want read:%v,write:%v", tc.name, gotRead, gotWrite, tc.wantRead, tc.wantWrt) } }) } }