Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for static query parameters in path patterns #212

Merged
merged 1 commit into from Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 25 additions & 11 deletions client/request.go
Expand Up @@ -273,22 +273,36 @@ DoneChoosingBodySource:
}
}

// create http request
var reinstateSlash bool
if r.pathPattern != "" && r.pathPattern != "/" && r.pathPattern[len(r.pathPattern)-1] == '/' {
reinstateSlash = true
// In case the basePath or the request pathPattern include static query parameters,
// parse those out before constructing the final path. The parameters themselves
// will be merged with the ones set by the client, with the priority given first to
// the ones set by the client, then the path pattern, and lastly the base path.
basePathURL, err := url.Parse(basePath)
if err != nil {
return nil, err
}
staticQueryParams := basePathURL.Query()

// In case the basePath includes hardcoded query parameters, parse those out before
// constructing the final path. The parameters themselves will be merged with the
// ones set by the client, with the priority given to the latter.
basePathURL, err := url.Parse(basePath)
pathPatternURL, err := url.Parse(r.pathPattern)
if err != nil {
return nil, err
}
basePathQueryParams := basePathURL.Query()
for name, values := range pathPatternURL.Query() {
if _, present := staticQueryParams[name]; present {
staticQueryParams.Del(name)
}
for _, value := range values {
staticQueryParams.Add(name, value)
}
}

// create http request
var reinstateSlash bool
if pathPatternURL.Path != "" && pathPatternURL.Path != "/" && pathPatternURL.Path[len(pathPatternURL.Path)-1] == '/' {
reinstateSlash = true
}

urlPath := path.Join(basePathURL.Path, r.pathPattern)
urlPath := path.Join(basePathURL.Path, pathPatternURL.Path)
for k, v := range r.pathParams {
urlPath = strings.Replace(urlPath, "{"+k+"}", url.PathEscape(v), -1)
}
Expand All @@ -305,7 +319,7 @@ DoneChoosingBodySource:

// Merge the query parameters extracted from the basePath with the ones set by
// the client in this struct. In case of conflict, the client wins.
for k, v := range basePathQueryParams {
for k, v := range staticQueryParams {
_, present := originalParams[k]
if !present {
if err = r.SetQueryParam(k, v...); err != nil {
Expand Down
38 changes: 35 additions & 3 deletions client/request_test.go
Expand Up @@ -517,7 +517,7 @@ func TestBuildRequest_BuildHTTP_EscapedPath(t *testing.T) {
}
}

func TestBuildRequest_BuildHTTP_BasePathWithParameters(t *testing.T) {
func TestBuildRequest_BuildHTTP_BasePathWithQueryParameters(t *testing.T) {
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
_ = req.SetBodyParam(nil)
_ = req.SetQueryParam("hello", "world")
Expand All @@ -534,14 +534,30 @@ func TestBuildRequest_BuildHTTP_BasePathWithParameters(t *testing.T) {
}
}

func TestBuildRequest_BuildHTTP_BasePathWithConflictingParameters(t *testing.T) {
func TestBuildRequest_BuildHTTP_PathPatternWithQueryParameters(t *testing.T) {
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
_ = req.SetBodyParam(nil)
_ = req.SetQueryParam("hello", "world")
_ = req.SetPathParam("id", "1234")
return nil
})
r, _ := newRequest("POST", "/flats/{id}/", reqWrtr)
r, _ := newRequest("POST", "/flats/{id}/?foo=bar", reqWrtr)

req, err := r.BuildHTTP(runtime.JSONMime, "/basepath", testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "world", req.URL.Query().Get("hello"))
assert.Equal(t, "bar", req.URL.Query().Get("foo"))
assert.Equal(t, "/basepath/flats/1234/", req.URL.Path)
}
}

func TestBuildRequest_BuildHTTP_StaticParametersPathPatternPrevails(t *testing.T) {
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
_ = req.SetBodyParam(nil)
_ = req.SetPathParam("id", "1234")
return nil
})
r, _ := newRequest("POST", "/flats/{id}/?hello=world", reqWrtr)

req, err := r.BuildHTTP(runtime.JSONMime, "/basepath?hello=kitty", testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
Expand All @@ -550,6 +566,22 @@ func TestBuildRequest_BuildHTTP_BasePathWithConflictingParameters(t *testing.T)
}
}

func TestBuildRequest_BuildHTTP_StaticParametersConflictClientPrevails(t *testing.T) {
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
_ = req.SetBodyParam(nil)
_ = req.SetQueryParam("hello", "there")
_ = req.SetPathParam("id", "1234")
return nil
})
r, _ := newRequest("POST", "/flats/{id}/?hello=world", reqWrtr)

req, err := r.BuildHTTP(runtime.JSONMime, "/basepath?hello=kitty", testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "there", req.URL.Query().Get("hello"))
assert.Equal(t, "/basepath/flats/1234/", req.URL.Path)
}
}

type testReqFn func(*testing.T, *http.Request)

type testRoundTripper struct {
Expand Down