Files
moby/client/client_mock_test.go
Sebastiaan van Stijn 839c2709af client: WithMockClient: match version behavior of actual client
The WithMockClient option was explicitly resetting the client's API
version (see [1]), which differs from the regular client, which is
initialized with the current API version used by the client (see [2]).

This patch:

- reduces the `WithMockClient` to only set the custom HTTP client, leaving
  other fields un-touched.
- adds a test utility and updates tests to handle the API-version prefix
- removes redundant uses of `WithVersion()` in tests; for most test-cases
  it was used to make sure a current API version is used that supports the
  feature being tested, but there was no test to verify the behavior for
  lower API versions, so we may as well test against "latest".

[1]: 5a582729d8/client/client_mock_test.go (L22-L36)
[2]: 5a582729d8/client/client.go (L167-L190)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-18 11:37:56 +02:00

78 lines
2.1 KiB
Go

package client
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"github.com/moby/moby/api/types/common"
)
// defaultAPIPath is the API path prefix for the default API version used.
const defaultAPIPath = "/v" + MaxAPIVersion
// assertRequest checks for the request method and path. If the expected
// path does not contain a version prefix, it is prefixed with the current API
// version.
func assertRequest(req *http.Request, expMethod string, expectedPath string) error {
if !strings.HasPrefix(expectedPath, "/v1.") {
expectedPath = defaultAPIPath + expectedPath
}
if !strings.HasPrefix(req.URL.Path, expectedPath) {
return fmt.Errorf("expected URL '%s', got '%s'", expectedPath, req.URL.Path)
}
if req.Method != expMethod {
return fmt.Errorf("expected %s method, got %s", expMethod, req.Method)
}
return nil
}
func transportEnsureBody(f transportFunc) transportFunc {
return func(req *http.Request) (*http.Response, error) {
resp, err := f(req)
if resp != nil && resp.Body == nil {
resp.Body = http.NoBody
}
return resp, err
}
}
// WithMockClient is a test helper that allows you to inject a mock client for testing.
func WithMockClient(doer func(*http.Request) (*http.Response, error)) Opt {
return WithHTTPClient(&http.Client{
Transport: transportEnsureBody(transportFunc(doer)),
})
}
func errorMock(statusCode int, message string) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
header := http.Header{}
header.Set("Content-Type", "application/json")
body, err := json.Marshal(&common.ErrorResponse{
Message: message,
})
if err != nil {
return nil, err
}
return &http.Response{
StatusCode: statusCode,
Body: io.NopCloser(bytes.NewReader(body)),
Header: header,
}, nil
}
}
func plainTextErrorMock(statusCode int, message string) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: statusCode,
Body: io.NopCloser(bytes.NewReader([]byte(message))),
}, nil
}
}