126 lines
2.8 KiB
Go
126 lines
2.8 KiB
Go
package testutils
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"maps"
|
|
"net/http"
|
|
)
|
|
|
|
const (
|
|
StandardUserAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
StandardAcceptEncoding = "gzip"
|
|
)
|
|
|
|
type RequestBuilder struct {
|
|
method string
|
|
url string
|
|
body io.Reader
|
|
headers map[string]string
|
|
withAuth bool
|
|
authToken string
|
|
withJSON bool
|
|
jsonData any
|
|
withStdHeaders bool
|
|
withIP bool
|
|
ipAddress string
|
|
}
|
|
|
|
func NewRequestBuilder(method, url string) *RequestBuilder {
|
|
return &RequestBuilder{
|
|
method: method,
|
|
url: url,
|
|
headers: make(map[string]string),
|
|
withStdHeaders: true,
|
|
}
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithBody(body io.Reader) *RequestBuilder {
|
|
rb.body = body
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithJSONBody(data any) *RequestBuilder {
|
|
rb.withJSON = true
|
|
rb.jsonData = data
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithHeader(key, value string) *RequestBuilder {
|
|
rb.headers[key] = value
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithHeaders(headers map[string]string) *RequestBuilder {
|
|
maps.Copy(rb.headers, headers)
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithAuth(token string) *RequestBuilder {
|
|
rb.withAuth = true
|
|
rb.authToken = token
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithIP(ipAddress string) *RequestBuilder {
|
|
rb.withIP = true
|
|
rb.ipAddress = ipAddress
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) WithoutStandardHeaders() *RequestBuilder {
|
|
rb.withStdHeaders = false
|
|
return rb
|
|
}
|
|
|
|
func (rb *RequestBuilder) Build() (*http.Request, error) {
|
|
var body io.Reader = rb.body
|
|
if rb.withJSON && rb.jsonData != nil {
|
|
jsonBytes, err := json.Marshal(rb.jsonData)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal JSON body: %w", err)
|
|
}
|
|
body = bytes.NewReader(jsonBytes)
|
|
}
|
|
request, err := http.NewRequest(rb.method, rb.url, body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create request: %w", err)
|
|
}
|
|
if rb.withStdHeaders {
|
|
request.Header.Set("User-Agent", StandardUserAgent)
|
|
request.Header.Set("Accept-Encoding", StandardAcceptEncoding)
|
|
}
|
|
if rb.withJSON {
|
|
request.Header.Set("Content-Type", "application/json")
|
|
}
|
|
if rb.withAuth && rb.authToken != "" {
|
|
request.Header.Set("Authorization", "Bearer "+rb.authToken)
|
|
}
|
|
if rb.withIP && rb.ipAddress != "" {
|
|
request.Header.Set("X-Forwarded-For", rb.ipAddress)
|
|
}
|
|
for key, value := range rb.headers {
|
|
request.Header.Set(key, value)
|
|
}
|
|
return request, nil
|
|
}
|
|
|
|
func (rb *RequestBuilder) BuildOrFatal(t TestingT) *http.Request {
|
|
req, err := rb.Build()
|
|
if err != nil {
|
|
if h, ok := t.(interface{ Helper() }); ok {
|
|
h.Helper()
|
|
}
|
|
t.Fatalf("RequestBuilder.Build failed: %v", err)
|
|
}
|
|
return req
|
|
}
|
|
|
|
type TestingT interface {
|
|
Helper()
|
|
Errorf(format string, args ...any)
|
|
Fatalf(format string, args ...any)
|
|
}
|