Repository: goadesign/goa
Pull request #3652 (2025-02-11 06:05:53)

Fix generation of unused validation functions
Alias attributes are validated in their parent type validation function.


Patch:
diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go
index b570c482..8ac72888 100644
--- a/http/codegen/service_data.go
+++ b/http/codegen/service_data.go
@@ -2586,9 +2586,10 @@ func attributeTypeData(ut expr.UserType, req, ptr, server bool, rd *ServiceData)
 		ctx = "response"
 	}
 	desc = name + " is used to define fields on " + ctx + " body types."
-	if req || !req && !server {
-		// generate validations for responses client-side and for
-		// requests server-side and CLI
+	if (req || !req && !server) && !expr.IsAlias(ut) {
+		// Generate validations for responses client-side and for
+		// requests server-side and CLI.
+		// Alias types are validated inline in the parent type
 		validate = codegen.ValidationCode(ut.Attribute(), ut, hctx, true, expr.IsAlias(ut), false, "body")
 	}
 	if validate != "" {


Test patch:
diff --git a/http/codegen/server_types_test.go b/http/codegen/server_types_test.go
index c9cdd092..ead1819a 100644
--- a/http/codegen/server_types_test.go
+++ b/http/codegen/server_types_test.go
@@ -32,6 +32,7 @@ func TestServerTypes(t *testing.T) {
 		{"server-query-custom-name", testdata.PayloadQueryCustomNameDSL, QueryCustomNameServerTypesFile},
 		{"server-header-custom-name", testdata.PayloadHeaderCustomNameDSL, HeaderCustomNameServerTypesFile},
 		{"server-cookie-custom-name", testdata.PayloadCookieCustomNameDSL, CookieCustomNameServerTypesFile},
+		{"server-payload-with-validated-alias", testdata.PayloadWithValidatedAliasDSL, PayloadWithValidatedAliasServerTypeCode},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
@@ -380,3 +381,39 @@ func NewMethodCookieCustomNamePayload(c2 *string) *servicecookiecustomname.Metho
 	return v
 }
 `
+
+const PayloadWithValidatedAliasServerTypeCode = `// MethodStreamingBody is the type of the "ServicePayloadValidatedAlias"
+// service "Method" endpoint HTTP request body.
+type MethodStreamingBody struct {
+	Name *ValidatedStringStreamingBody ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
+}
+
+// ValidatedStringStreamingBody is used to define fields on request body types.
+type ValidatedStringStreamingBody string
+
+// NewMethodStreamingBody builds a ServicePayloadValidatedAlias service Method
+// endpoint payload.
+func NewMethodStreamingBody(body *MethodStreamingBody) *servicepayloadvalidatedalias.MethodStreamingPayload {
+	v := &servicepayloadvalidatedalias.MethodStreamingPayload{}
+	if body.Name != nil {
+		name := servicepayloadvalidatedalias.ValidatedString(*body.Name)
+		v.Name = &name
+	}
+
+	return v
+}
+
+// ValidateMethodStreamingBody runs the validations defined on
+// MethodStreamingBody
+func ValidateMethodStreamingBody(body *MethodStreamingBody) (err error) {
+	if body.Name != nil {
+		err = goa.MergeErrors(err, goa.ValidatePattern("body.name", string(*body.Name), "^[a-zA-Z]+$"))
+	}
+	if body.Name != nil {
+		if utf8.RuneCountInString(string(*body.Name)) < 10 {
+			err = goa.MergeErrors(err, goa.InvalidLengthError("body.name", string(*body.Name), utf8.RuneCountInString(string(*body.Name)), 10, true))
+		}
+	}
+	return
+}
+`
diff --git a/http/codegen/testdata/payload_dsls.go b/http/codegen/testdata/payload_dsls.go
index f22df95a..a19c9667 100644
--- a/http/codegen/testdata/payload_dsls.go
+++ b/http/codegen/testdata/payload_dsls.go
@@ -3648,3 +3648,21 @@ var PayloadCookieCustomNameDSL = func() {
 		})
 	})
 }
+
+var PayloadWithValidatedAliasDSL = func() {
+	var ValidatedString = Type("ValidatedString", String, func() {
+		MinLength(10)
+		Pattern("^[a-zA-Z]+$")
+	})
+
+	Service("ServicePayloadValidatedAlias", func() {
+		Method("Method", func() {
+			StreamingPayload(func() {
+				Attribute("name", ValidatedString)
+			})
+			HTTP(func() {
+				GET("/")
+			})
+		})
+	})
+}