| index 949e2c052..c9f18c7ef 100644 |
| --- a/internal/console/signupscopebinding_test.go |
| +++ b/internal/console/signupscopebinding_test.go |
| @@ -109,7 +109,11 @@ func TestSignupScopeBindingStaysPrivateAndUnmounted(t *testing.T) { |
| if name == "signupscopebinding.go" { |
| switch d := decl.(type) { |
| case *ast.FuncDecl: |
| - allowed = d.Name.Name == "signupScopeBindingFromCandidate" || d.Name.Name == "bytes" && d.Recv != nil && len(d.Recv.List) == 1 |
| + allowed = d.Name.Name == "signupScopeBindingFromCandidate" && d.Recv == nil |
| + if d.Name.Name == "bytes" && d.Recv != nil && len(d.Recv.List) == 1 { |
| + receiver, ok := d.Recv.List[0].Type.(*ast.Ident) |
| + allowed = ok && receiver.Name == "signupScopeBinding" |
| + } |
| case *ast.GenDecl: |
| if len(d.Specs) == 1 { |
| if s, ok := d.Specs[0].(*ast.TypeSpec); ok { |
| @@ -149,7 +153,7 @@ func TestSignupScopeBindingRejectsFutureProfileAST(t *testing.T) { |
| } |
| var helper *ast.FuncDecl |
| for _, decl := range file.Decls { |
| - if fn, ok := decl.(*ast.FuncDecl); ok && fn.Name.Name == "signupScopeBindingFromCandidate" { |
| + if fn, ok := decl.(*ast.FuncDecl); ok && fn.Name.Name == "signupScopeBindingFromCandidate" && fn.Recv == nil { |
| helper = fn |
| } |
| } |
| @@ -160,28 +164,51 @@ func TestSignupScopeBindingRejectsFutureProfileAST(t *testing.T) { |
| if !ok { |
| t.Fatal("guard must precede encoding") |
| } |
| + top, ok := guard.Cond.(*ast.BinaryExpr) |
| + if !ok || top.Op != token.LOR { |
| + t.Fatal("profile refusal must be an OR chain") |
| + } |
| + var operands func(ast.Expr) []ast.Expr |
| + operands = func(expr ast.Expr) []ast.Expr { |
| + if binary, ok := expr.(*ast.BinaryExpr); ok && binary.Op == token.LOR { |
| + return append(operands(binary.X), operands(binary.Y)...) |
| + } |
| + return []ast.Expr{expr} |
| + } |
| checks := map[string]bool{} |
| - ast.Inspect(guard.Cond, func(n ast.Node) bool { |
| - binary, ok := n.(*ast.BinaryExpr) |
| + parts := operands(guard.Cond) |
| + if len(parts) != 3 { |
| + t.Fatal("profile refusal needs exactly three direct comparisons") |
| + } |
| + for _, part := range parts { |
| + binary, ok := part.(*ast.BinaryExpr) |
| if !ok || binary.Op != token.NEQ { |
| - return true |
| + t.Fatal("profile refusal operand is not a direct inequality") |
| + } |
| + if id, ok := binary.X.(*ast.Ident); ok && id.Name == "code" { |
| + sel, ok := binary.Y.(*ast.SelectorExpr) |
| + if !ok || sel.Sel.Name != "NamespaceAccepted" { |
| + t.Fatal("candidate refusal comparison changed") |
| + } |
| + pkg, ok := sel.X.(*ast.Ident) |
| + if !ok || pkg.Name != "release" { |
| + t.Fatal("candidate refusal package changed") |
| + } |
| + checks["code"] = true |
| + continue |
| } |
| sel, ok := binary.X.(*ast.SelectorExpr) |
| if !ok { |
| - return true |
| + t.Fatal("profile operand does not compare facts") |
| } |
| id, ok := sel.X.(*ast.Ident) |
| - if !ok || id.Name != "facts" { |
| - return true |
| - } |
| - literal, ok := binary.Y.(*ast.BasicLit) |
| - if !ok { |
| - return true |
| + literal, literalOK := binary.Y.(*ast.BasicLit) |
| + if !ok || id.Name != "facts" || !literalOK || literal.Kind != token.STRING { |
| + t.Fatal("profile operand is not a direct facts/string comparison") |
| } |
| checks[sel.Sel.Name+"="+literal.Value] = true |
| - return true |
| - }) |
| - if !checks[`Mode="aws"`] || !checks[`EffectivePrefix=""`] { |
| + } |
| + if !checks["code"] || !checks[`Mode="aws"`] || !checks[`EffectivePrefix=""`] { |
| t.Fatal("future custom/prefix candidate needs independent refusal") |
| } |
| if len(guard.Body.List) != 1 { |