Fix test setup and middleware chain - Handler tests now passing
- Fix TestRequireRoleMiddleware by chaining RequireAuth before RequireRole (role context requirement) - Remove unused 'strings' import from testdb.go - Create crussell_test database in Docker setup - Tests now properly initialize authentication context for role-based tests Result: handlers test suite passes (13/13 tests) Remaining failures in admin/auth/bookings/portfolio/scheduling/services/user packages need further investigation (environment setup, database constraints, endpoint initialization)
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
//go:build test
|
||||
// +build test
|
||||
|
||||
package httptest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TestClient struct {
|
||||
client *http.Client
|
||||
authToken string
|
||||
baseURL string
|
||||
}
|
||||
|
||||
func NewTestClient(handler http.Handler) *TestClient {
|
||||
server := httptest.NewServer(handler)
|
||||
return &TestClient{
|
||||
client: server.Client(),
|
||||
baseURL: server.URL,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *TestClient) Server() *httptest.Server {
|
||||
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
c.client.Transport.RoundTrip(r)
|
||||
}))
|
||||
}
|
||||
|
||||
func (c *TestClient) SetAuthToken(token string) {
|
||||
c.authToken = token
|
||||
}
|
||||
|
||||
func (c *TestClient) ClearAuthToken() {
|
||||
c.authToken = ""
|
||||
}
|
||||
|
||||
func (c *TestClient) getAuthHeader() string {
|
||||
if c.authToken == "" {
|
||||
return ""
|
||||
}
|
||||
return "Bearer " + c.authToken
|
||||
}
|
||||
|
||||
func (c *TestClient) Get(path string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("GET", c.baseURL+path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if auth := c.getAuthHeader(); auth != "" {
|
||||
req.Header.Set("Authorization", auth)
|
||||
}
|
||||
return c.client.Do(req)
|
||||
}
|
||||
|
||||
func (c *TestClient) Post(path string, body interface{}) (*http.Response, error) {
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
jsonBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader = bytes.NewReader(jsonBytes)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", c.baseURL+path, bodyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if auth := c.getAuthHeader(); auth != "" {
|
||||
req.Header.Set("Authorization", auth)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
return c.client.Do(req)
|
||||
}
|
||||
|
||||
func (c *TestClient) Put(path string, body interface{}) (*http.Response, error) {
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
jsonBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader = bytes.NewReader(jsonBytes)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("PUT", c.baseURL+path, bodyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if auth := c.getAuthHeader(); auth != "" {
|
||||
req.Header.Set("Authorization", auth)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
return c.client.Do(req)
|
||||
}
|
||||
|
||||
func (c *TestClient) Delete(path string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("DELETE", c.baseURL+path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if auth := c.getAuthHeader(); auth != "" {
|
||||
req.Header.Set("Authorization", auth)
|
||||
}
|
||||
return c.client.Do(req)
|
||||
}
|
||||
|
||||
func (c *TestClient) Patch(path string, body interface{}) (*http.Response, error) {
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
jsonBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader = bytes.NewReader(jsonBytes)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("PATCH", c.baseURL+path, bodyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if auth := c.getAuthHeader(); auth != "" {
|
||||
req.Header.Set("Authorization", auth)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
return c.client.Do(req)
|
||||
}
|
||||
|
||||
func (c *TestClient) ReadResponse(resp *http.Response, dest interface{}) error {
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(body, dest)
|
||||
}
|
||||
|
||||
func (c *TestClient) GetBody(resp *http.Response) (string, error) {
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func (c *TestClient) Close() {
|
||||
c.client.CloseIdleConnections()
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
StatusCode int
|
||||
Body []byte
|
||||
Header http.Header
|
||||
}
|
||||
|
||||
func (c *TestClient) Do(req *http.Request) (*Response, error) {
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Response{
|
||||
StatusCode: resp.StatusCode,
|
||||
Body: body,
|
||||
Header: resp.Header,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *TestClient) NewRequest(method, path string, body interface{}) (*http.Request, error) {
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
jsonBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader = bytes.NewReader(jsonBytes)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, c.baseURL+path, bodyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if auth := c.getAuthHeader(); auth != "" {
|
||||
req.Header.Set("Authorization", auth)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func MustParseJSON(body []byte, v interface{}) {
|
||||
if err := json.Unmarshal(body, v); err != nil {
|
||||
panic("failed to parse JSON: " + err.Error() + "\nBody: " + string(body))
|
||||
}
|
||||
}
|
||||
|
||||
func JSONBody(v interface{}) io.Reader {
|
||||
jsonBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
panic("failed to marshal JSON: " + err.Error())
|
||||
}
|
||||
return bytes.NewReader(jsonBytes)
|
||||
}
|
||||
|
||||
func SetDefaultTimeout(client *http.Client) {
|
||||
client.Timeout = 10 * time.Second
|
||||
}
|
||||
|
||||
func Contains(s, substr string) bool {
|
||||
return strings.Contains(s, substr)
|
||||
}
|
||||
Reference in New Issue
Block a user