@@ -83,7 +83,11 @@ func TestGenerateExtension(t *testing.T) {
8383 name: "Test"
8484 input_type: ".example.v1.Foo"
8585 output_type: ".example.v1.Foo"
86- options: {}
86+ options: {
87+ [google.api.http]: {
88+ get: "/v1/test"
89+ }
90+ }
8791 }
8892 }
8993 options: {
@@ -1938,3 +1942,136 @@ func TestGenerateXGoType(t *testing.T) {
19381942 })
19391943 }
19401944}
1945+
1946+ // TestIssue5684_UnusedMethodsNotInOpenAPI tests that methods without HTTP bindings
1947+ // do not appear in the OpenAPI definitions.
1948+ // See https://github.com/grpc-ecosystem/grpc-gateway/issues/5684
1949+ func TestIssue5684_UnusedMethodsNotInOpenAPI (t * testing.T ) {
1950+ t .Parallel ()
1951+
1952+ // Create a proto definition similar to the issue report:
1953+ // - Service with two methods: Add (no HTTP binding) and Show (with HTTP binding)
1954+ // - Only Show should appear in the OpenAPI output
1955+ // - AddRequest and AddResponse should NOT appear in definitions
1956+ const in = `
1957+ file_to_generate: "account/account.proto"
1958+ proto_file: {
1959+ name: "account/account.proto"
1960+ package: "account"
1961+
1962+ message_type: {
1963+ name: "Money"
1964+ field: {
1965+ name: "amount"
1966+ number: 1
1967+ label: LABEL_OPTIONAL
1968+ type: TYPE_INT64
1969+ json_name: "amount"
1970+ }
1971+ }
1972+
1973+ message_type: {
1974+ name: "AddRequest"
1975+ field: {
1976+ name: "money"
1977+ number: 1
1978+ label: LABEL_OPTIONAL
1979+ type: TYPE_MESSAGE
1980+ type_name: ".account.Money"
1981+ json_name: "money"
1982+ }
1983+ }
1984+
1985+ message_type: {
1986+ name: "AddResponse"
1987+ }
1988+
1989+ message_type: {
1990+ name: "ShowRequest"
1991+ }
1992+
1993+ message_type: {
1994+ name: "ShowResponse"
1995+ field: {
1996+ name: "money"
1997+ number: 1
1998+ label: LABEL_OPTIONAL
1999+ type: TYPE_MESSAGE
2000+ type_name: ".account.Money"
2001+ json_name: "money"
2002+ }
2003+ }
2004+
2005+ service: {
2006+ name: "AccountService"
2007+ method: {
2008+ name: "Add"
2009+ input_type: ".account.AddRequest"
2010+ output_type: ".account.AddResponse"
2011+ }
2012+ method: {
2013+ name: "Show"
2014+ input_type: ".account.ShowRequest"
2015+ output_type: ".account.ShowResponse"
2016+ options: {
2017+ [google.api.http]: {
2018+ get: "/v1/account"
2019+ }
2020+ }
2021+ }
2022+ }
2023+
2024+ options: {
2025+ go_package: "accounts/pkg/account;account"
2026+ }
2027+ }`
2028+
2029+ var req pluginpb.CodeGeneratorRequest
2030+ if err := prototext .Unmarshal ([]byte (in ), & req ); err != nil {
2031+ t .Fatalf ("failed to unmarshal proto: %v" , err )
2032+ }
2033+
2034+ resp := requireGenerate (t , & req , genopenapi .FormatYAML , false , false )
2035+ if len (resp ) != 1 {
2036+ t .Fatalf ("invalid count, expected: 1, actual: %d" , len (resp ))
2037+ }
2038+
2039+ var openAPIDoc map [string ]interface {}
2040+ if err := yaml .Unmarshal ([]byte (resp [0 ].GetContent ()), & openAPIDoc ); err != nil {
2041+ t .Fatalf ("failed to parse OpenAPI YAML: %v" , err )
2042+ }
2043+
2044+ definitions , ok := openAPIDoc ["definitions" ].(map [string ]interface {})
2045+ if ! ok {
2046+ t .Fatalf ("no definitions found in OpenAPI document" )
2047+ }
2048+
2049+ if _ , exists := definitions ["accountAddRequest" ]; exists {
2050+ t .Error ("accountAddRequest found in definitions, but should be excluded (Add method has no HTTP binding)" )
2051+ }
2052+
2053+ if _ , exists := definitions ["accountAddResponse" ]; exists {
2054+ t .Error ("accountAddResponse found in definitions, but should be excluded (Add method has no HTTP binding)" )
2055+ }
2056+
2057+ if _ , exists := definitions ["accountShowResponse" ]; ! exists {
2058+ t .Error ("accountShowResponse not found in definitions, but should be included (Show method has HTTP binding)" )
2059+ }
2060+
2061+ if _ , exists := definitions ["accountMoney" ]; ! exists {
2062+ t .Error ("accountMoney not found in definitions, but should be included (referenced by ShowResponse)" )
2063+ }
2064+
2065+ paths , ok := openAPIDoc ["paths" ].(map [string ]interface {})
2066+ if ! ok {
2067+ t .Fatalf ("no paths found in OpenAPI document" )
2068+ }
2069+
2070+ if _ , exists := paths ["/v1/account" ]; ! exists {
2071+ t .Error ("/v1/account path not found, but should be included (Show method)" )
2072+ }
2073+
2074+ if len (paths ) != 1 {
2075+ t .Errorf ("expected exactly 1 path, got %d paths" , len (paths ))
2076+ }
2077+ }
0 commit comments