From c06a95ffe3c788a8cffac730b768d4f84790f3b9 Mon Sep 17 00:00:00 2001 From: 500poundbear <6437216+500poundbear@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:23:33 +0800 Subject: [PATCH] Fix incorrectly generated repeated_path_param_separator --- internal/descriptor/registry.go | 2 +- .../internal/genopenapi/template.go | 2 +- .../internal/genopenapi/template_test.go | 113 ++++++++++++++++++ 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/internal/descriptor/registry.go b/internal/descriptor/registry.go index ec516563e0a..bd1facc851e 100644 --- a/internal/descriptor/registry.go +++ b/internal/descriptor/registry.go @@ -182,7 +182,7 @@ func NewRegistry() *Registry { openAPINamingStrategy: "legacy", visibilityRestrictionSelectors: make(map[string]bool), repeatedPathParamSeparator: repeatedFieldSeparator{ - name: "csv", + name: "multi", sep: ',', }, fileOptions: make(map[string]*options.Swagger), diff --git a/protoc-gen-openapiv2/internal/genopenapi/template.go b/protoc-gen-openapiv2/internal/genopenapi/template.go index 5fe42c2b0d8..9b72dc09b88 100644 --- a/protoc-gen-openapiv2/internal/genopenapi/template.go +++ b/protoc-gen-openapiv2/internal/genopenapi/template.go @@ -330,7 +330,7 @@ func nestedQueryParams(message *descriptor.Message, field *descriptor.Field, pre Enum: schema.Enum, } if param.Type == "array" { - param.CollectionFormat = "multi" + param.CollectionFormat = reg.GetRepeatedPathParamSeparatorName() } param.Name = prefix + reg.FieldName(field) diff --git a/protoc-gen-openapiv2/internal/genopenapi/template_test.go b/protoc-gen-openapiv2/internal/genopenapi/template_test.go index d6635d678da..0df13af5a1d 100644 --- a/protoc-gen-openapiv2/internal/genopenapi/template_test.go +++ b/protoc-gen-openapiv2/internal/genopenapi/template_test.go @@ -486,6 +486,119 @@ func TestMessageToQueryParametersWithOmitEnumDefaultValue(t *testing.T) { } } +func TestMessageToQueryParametersWithRepeatedPathParamSeparator(t *testing.T) { + type test struct { + MsgDescs []*descriptorpb.DescriptorProto + Message string + Params []openapiParameterObject + RepeatedPathParam string + } + + tests := []test{ + { + MsgDescs: []*descriptorpb.DescriptorProto{ + { + Name: proto.String("ExampleMessage"), + Field: []*descriptorpb.FieldDescriptorProto{ + { + Name: proto.String("c"), + Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(), + Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(), + Number: proto.Int32(3), + }, + }, + }, + }, + Message: "ExampleMessage", + Params: []openapiParameterObject{ + { + Name: "c", + In: "query", + Required: false, + Type: "array", + CollectionFormat: "ssv", + }, + }, + RepeatedPathParam: "ssv", + }, + { + MsgDescs: []*descriptorpb.DescriptorProto{ + { + Name: proto.String("ExampleMessage"), + Field: []*descriptorpb.FieldDescriptorProto{ + { + Name: proto.String("c"), + Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(), + Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(), + Number: proto.Int32(3), + }, + }, + }, + }, + Message: "ExampleMessage", + Params: []openapiParameterObject{ + { + Name: "c", + In: "query", + Required: false, + Type: "array", + CollectionFormat: "pipes", + }, + }, + RepeatedPathParam: "pipes", + }, + } + + for _, test := range tests { + reg := descriptor.NewRegistry() + reg.SetRepeatedPathParamSeparator(test.RepeatedPathParam) + msgs := []*descriptor.Message{} + for _, msgdesc := range test.MsgDescs { + msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc}) + } + file := descriptor.File{ + FileDescriptorProto: &descriptorpb.FileDescriptorProto{ + SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, + Name: proto.String("example.proto"), + Package: proto.String("example"), + Dependency: []string{}, + MessageType: test.MsgDescs, + Service: []*descriptorpb.ServiceDescriptorProto{}, + Options: &descriptorpb.FileOptions{ + GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"), + }, + }, + GoPkg: descriptor.GoPackage{ + Path: "example.com/path/to/example/example.pb", + Name: "example_pb", + }, + Messages: msgs, + } + err := reg.Load(&pluginpb.CodeGeneratorRequest{ + ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto}, + }) + if err != nil { + t.Fatalf("failed to load code generator request: %v", err) + } + + message, err := reg.LookupMsg("", ".example."+test.Message) + if err != nil { + t.Fatalf("failed to lookup message: %s", err) + } + params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil, "") + if err != nil { + t.Fatalf("failed to convert message to query parameters: %s", err) + } + // avoid checking Items for array types + for i := range params { + params[i].Items = nil + } + if !reflect.DeepEqual(params, test.Params) { + t.Errorf("expected %v, got %v", test.Params, params) + } + } +} + func TestMessageToQueryParameters(t *testing.T) { type test struct { MsgDescs []*descriptorpb.DescriptorProto