This commit is contained in:
157
internal/testing/helpers.go
Normal file
157
internal/testing/helpers.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestRequest represents a test HTTP request
|
||||
type TestRequest struct {
|
||||
Method string
|
||||
Path string
|
||||
Body interface{}
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// TestResponse represents a test HTTP response
|
||||
type TestResponse struct {
|
||||
StatusCode int
|
||||
Body map[string]interface{}
|
||||
Headers http.Header
|
||||
}
|
||||
|
||||
// MakeRequest creates and executes an HTTP request for testing
|
||||
func MakeRequest(t *testing.T, handler http.Handler, req TestRequest) *httptest.ResponseRecorder {
|
||||
var bodyBytes []byte
|
||||
if req.Body != nil {
|
||||
var err error
|
||||
bodyBytes, err = json.Marshal(req.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal request body: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequest(req.Method, req.Path, bytes.NewReader(bodyBytes))
|
||||
if err != nil {
|
||||
t.Fatalf("create request: %v", err)
|
||||
}
|
||||
|
||||
// Set headers
|
||||
if req.Headers != nil {
|
||||
for k, v := range req.Headers {
|
||||
httpReq.Header.Set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Set Content-Type if body is present
|
||||
if bodyBytes != nil && httpReq.Header.Get("Content-Type") == "" {
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.ServeHTTP(recorder, httpReq)
|
||||
|
||||
return recorder
|
||||
}
|
||||
|
||||
// AssertStatusCode asserts the response status code
|
||||
func AssertStatusCode(t *testing.T, recorder *httptest.ResponseRecorder, expected int) {
|
||||
if recorder.Code != expected {
|
||||
t.Errorf("expected status %d, got %d", expected, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// AssertJSONResponse asserts the response is valid JSON and matches expected structure
|
||||
func AssertJSONResponse(t *testing.T, recorder *httptest.ResponseRecorder) map[string]interface{} {
|
||||
var response map[string]interface{}
|
||||
if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil {
|
||||
t.Fatalf("unmarshal JSON response: %v\nBody: %s", err, recorder.Body.String())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// AssertHeader asserts a header value
|
||||
func AssertHeader(t *testing.T, recorder *httptest.ResponseRecorder, key, expected string) {
|
||||
actual := recorder.Header().Get(key)
|
||||
if actual != expected {
|
||||
t.Errorf("expected header %s=%s, got %s", key, expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// AssertErrorResponse asserts the response is an error response
|
||||
func AssertErrorResponse(t *testing.T, recorder *httptest.ResponseRecorder, expectedCode string) {
|
||||
response := AssertJSONResponse(t, recorder)
|
||||
|
||||
if code, ok := response["code"].(string); !ok || code != expectedCode {
|
||||
t.Errorf("expected error code %s, got %v", expectedCode, response["code"])
|
||||
}
|
||||
}
|
||||
|
||||
// AssertSuccessResponse asserts the response is a success response
|
||||
func AssertSuccessResponse(t *testing.T, recorder *httptest.ResponseRecorder) map[string]interface{} {
|
||||
AssertStatusCode(t, recorder, http.StatusOK)
|
||||
return AssertJSONResponse(t, recorder)
|
||||
}
|
||||
|
||||
// CreateTestUser creates a test user for authentication tests
|
||||
func CreateTestUser() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"username": "testuser",
|
||||
"password": "TestPass123",
|
||||
"email": "test@example.com",
|
||||
"role": "viewer",
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTestToken creates a mock JWT token for testing
|
||||
func CreateTestToken(userID, role string) string {
|
||||
// In a real test, you'd use the actual auth service
|
||||
// This is a placeholder for test token generation
|
||||
return "test-token-" + userID
|
||||
}
|
||||
|
||||
// MockZFSClient provides a mock ZFS client for testing
|
||||
type MockZFSClient struct {
|
||||
Pools []map[string]interface{}
|
||||
Datasets []map[string]interface{}
|
||||
ZVOLs []map[string]interface{}
|
||||
Snapshots []map[string]interface{}
|
||||
Error error
|
||||
}
|
||||
|
||||
// NewMockZFSClient creates a new mock ZFS client
|
||||
func NewMockZFSClient() *MockZFSClient {
|
||||
return &MockZFSClient{
|
||||
Pools: []map[string]interface{}{},
|
||||
Datasets: []map[string]interface{}{},
|
||||
ZVOLs: []map[string]interface{}{},
|
||||
Snapshots: []map[string]interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
// SetError sets an error to return
|
||||
func (m *MockZFSClient) SetError(err error) {
|
||||
m.Error = err
|
||||
}
|
||||
|
||||
// AddPool adds a mock pool
|
||||
func (m *MockZFSClient) AddPool(pool map[string]interface{}) {
|
||||
m.Pools = append(m.Pools, pool)
|
||||
}
|
||||
|
||||
// AddDataset adds a mock dataset
|
||||
func (m *MockZFSClient) AddDataset(dataset map[string]interface{}) {
|
||||
m.Datasets = append(m.Datasets, dataset)
|
||||
}
|
||||
|
||||
// Reset clears all mock data
|
||||
func (m *MockZFSClient) Reset() {
|
||||
m.Pools = []map[string]interface{}{}
|
||||
m.Datasets = []map[string]interface{}{}
|
||||
m.ZVOLs = []map[string]interface{}{}
|
||||
m.Snapshots = []map[string]interface{}{}
|
||||
m.Error = nil
|
||||
}
|
||||
Reference in New Issue
Block a user