Ctrl K
ComunidadGuías…

internal/handler/test_helpers.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package handler

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/go-chi/chi/v5"
	"github.com/johnzastrow/actalog/pkg/middleware"
)

// Test helper functions for handler tests

// createTestRequest creates an HTTP request with optional body
func createTestRequest(method, path, body string) *http.Request {
	req := httptest.NewRequest(method, path, strings.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	return req
}

// createAuthenticatedRequest creates a request with user context
func createAuthenticatedRequest(method, path, body string, userID int64, email, role string) *http.Request {
	req := createTestRequest(method, path, body)
	ctx := context.WithValue(req.Context(), middleware.UserIDKey, userID)
	ctx = context.WithValue(ctx, middleware.UserEmailKey, email)
	ctx = context.WithValue(ctx, middleware.UserRoleKey, role)
	return req.WithContext(ctx)
}

// parseJSONResponse parses a JSON response body into the target
func parseJSONResponse(rr *httptest.ResponseRecorder, target interface{}) error {
	return json.Unmarshal(rr.Body.Bytes(), target)
}

// assertStatusCode checks if response has expected status code
func assertStatusCode(t interface{ Errorf(string, ...interface{}) }, rr *httptest.ResponseRecorder, expected int) {
	if rr.Code != expected {
		t.Errorf("handler returned wrong status code: got %v want %v, body: %s",
			rr.Code, expected, rr.Body.String())
	}
}

// assertContentType checks if response has expected content type
func assertContentType(t interface{ Errorf(string, ...interface{}) }, rr *httptest.ResponseRecorder, expected string) {
	ct := rr.Header().Get("Content-Type")
	if ct != expected {
		t.Errorf("handler returned wrong content type: got %v want %v", ct, expected)
	}
}

// assertBodyContains checks if response body contains expected string
func assertBodyContains(t interface{ Errorf(string, ...interface{}) }, rr *httptest.ResponseRecorder, expected string) {
	if !strings.Contains(rr.Body.String(), expected) {
		t.Errorf("handler body does not contain %q: got %s", expected, rr.Body.String())
	}
}

// addChiURLParam adds a chi URL parameter to a request context
func addChiURLParam(r *http.Request, key, value string) *http.Request {
	rctx := chi.NewRouteContext()
	rctx.URLParams.Add(key, value)
	return r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, rctx))
}

// addChiURLParams adds multiple chi URL parameters to a request context
func addChiURLParams(r *http.Request, params map[string]string) *http.Request {
	rctx := chi.NewRouteContext()
	for key, value := range params {
		rctx.URLParams.Add(key, value)
	}
	return r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, rctx))
}

// createUserIDOnlyRequest creates a request with only userID in context (no email or role)
// Useful for testing "missing role" authorization checks
func createUserIDOnlyRequest(method, path, body string, userID int64) *http.Request {
	req := createTestRequest(method, path, body)
	ctx := context.WithValue(req.Context(), middleware.UserIDKey, userID)
	return req.WithContext(ctx)
}

// createMultipartRequest creates a multipart form request for file upload testing
// Returns nil if there's an error creating the request
func createMultipartRequest(method, path, fieldName, fileName, contentType string, fileContent []byte, userID int64, email, role string) *http.Request {
	body := &strings.Builder{}

	// Create a simple multipart form body manually
	boundary := "----WebKitFormBoundary7MA4YWxkTrZu0gW"

	body.WriteString("--" + boundary + "\r\n")
	body.WriteString("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"\r\n")
	body.WriteString("Content-Type: " + contentType + "\r\n\r\n")
	body.WriteString(string(fileContent))
	body.WriteString("\r\n--" + boundary + "--\r\n")

	req := httptest.NewRequest(method, path, strings.NewReader(body.String()))
	req.Header.Set("Content-Type", "multipart/form-data; boundary="+boundary)

	ctx := context.WithValue(req.Context(), middleware.UserIDKey, userID)
	ctx = context.WithValue(ctx, middleware.UserEmailKey, email)
	ctx = context.WithValue(ctx, middleware.UserRoleKey, role)
	return req.WithContext(ctx)
}