313 lines
7.8 KiB
Go
313 lines
7.8 KiB
Go
package helper
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestRespondWithError(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
statusCode int
|
|
message string
|
|
}{
|
|
{"Bad Request", http.StatusBadRequest, "Invalid input"},
|
|
{"Unauthorized", http.StatusUnauthorized, "Not authenticated"},
|
|
{"Forbidden", http.StatusForbidden, "Access denied"},
|
|
{"Not Found", http.StatusNotFound, "Resource not found"},
|
|
{"Internal Error", http.StatusInternalServerError, "Server error"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithError(recorder, tc.statusCode, tc.message)
|
|
|
|
// Check status code
|
|
if recorder.Code != tc.statusCode {
|
|
t.Errorf("Expected status code %d, got %d", tc.statusCode, recorder.Code)
|
|
}
|
|
|
|
// Check content type
|
|
contentType := recorder.Header().Get("Content-Type")
|
|
if contentType != "application/json" {
|
|
t.Errorf("Expected Content-Type 'application/json', got '%s'", contentType)
|
|
}
|
|
|
|
// Parse response body
|
|
var response map[string]string
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &response)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
// Check error message
|
|
if response["error"] != tc.message {
|
|
t.Errorf("Expected error message '%s', got '%s'", tc.message, response["error"])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRespondWithMessage(t *testing.T) {
|
|
testCases := []string{
|
|
"Operation successful",
|
|
"User created",
|
|
"Email sent",
|
|
"Task completed",
|
|
}
|
|
|
|
for _, message := range testCases {
|
|
t.Run(message, func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithMessage(recorder, message)
|
|
|
|
// Check status code (should default to 200)
|
|
if recorder.Code != http.StatusOK {
|
|
t.Errorf("Expected status code %d, got %d", http.StatusOK, recorder.Code)
|
|
}
|
|
|
|
// Parse response body
|
|
var response map[string]string
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &response)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
// Check message
|
|
if response["message"] != message {
|
|
t.Errorf("Expected message '%s', got '%s'", message, response["message"])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRespondWithJSON(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
statusCode int
|
|
data interface{}
|
|
}{
|
|
{
|
|
name: "Simple object",
|
|
statusCode: http.StatusOK,
|
|
data: map[string]string{"key": "value"},
|
|
},
|
|
{
|
|
name: "Array",
|
|
statusCode: http.StatusOK,
|
|
data: []string{"item1", "item2", "item3"},
|
|
},
|
|
{
|
|
name: "Nested object",
|
|
statusCode: http.StatusCreated,
|
|
data: map[string]interface{}{
|
|
"user": map[string]string{
|
|
"name": "John",
|
|
"email": "john@example.com",
|
|
},
|
|
"status": "active",
|
|
},
|
|
},
|
|
{
|
|
name: "Number",
|
|
statusCode: http.StatusOK,
|
|
data: map[string]int{"count": 42},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithJSON(recorder, tc.statusCode, tc.data)
|
|
|
|
// Check status code
|
|
if recorder.Code != tc.statusCode {
|
|
t.Errorf("Expected status code %d, got %d", tc.statusCode, recorder.Code)
|
|
}
|
|
|
|
// Check content type
|
|
contentType := recorder.Header().Get("Content-Type")
|
|
if contentType != "application/json" {
|
|
t.Errorf("Expected Content-Type 'application/json', got '%s'", contentType)
|
|
}
|
|
|
|
// Verify response can be parsed as JSON
|
|
var response interface{}
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &response)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse response as JSON: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRespondWithErrorEmptyMessage(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithError(recorder, http.StatusBadRequest, "")
|
|
|
|
var response map[string]string
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &response)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
if _, exists := response["error"]; !exists {
|
|
t.Error("Response should contain 'error' key even with empty message")
|
|
}
|
|
}
|
|
|
|
func TestRespondWithJSONNilData(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithJSON(recorder, http.StatusOK, nil)
|
|
|
|
if recorder.Code != http.StatusOK {
|
|
t.Errorf("Expected status code %d, got %d", http.StatusOK, recorder.Code)
|
|
}
|
|
|
|
body := recorder.Body.String()
|
|
if body != "null\n" {
|
|
t.Errorf("Expected 'null', got '%s'", body)
|
|
}
|
|
}
|
|
|
|
func TestRespondWithErrorStatusCodes(t *testing.T) {
|
|
statusCodes := []int{
|
|
http.StatusBadRequest,
|
|
http.StatusUnauthorized,
|
|
http.StatusForbidden,
|
|
http.StatusNotFound,
|
|
http.StatusMethodNotAllowed,
|
|
http.StatusConflict,
|
|
http.StatusUnprocessableEntity,
|
|
http.StatusTooManyRequests,
|
|
http.StatusInternalServerError,
|
|
http.StatusServiceUnavailable,
|
|
}
|
|
|
|
for _, code := range statusCodes {
|
|
t.Run(http.StatusText(code), func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithError(recorder, code, "Test error")
|
|
|
|
if recorder.Code != code {
|
|
t.Errorf("Expected status code %d, got %d", code, recorder.Code)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRespondWithJSONComplex(t *testing.T) {
|
|
type User struct {
|
|
ID int `json:"id"`
|
|
Name string `json:"name"`
|
|
Email string `json:"email"`
|
|
Roles []string `json:"roles"`
|
|
IsActive bool `json:"is_active"`
|
|
}
|
|
|
|
user := User{
|
|
ID: 123,
|
|
Name: "Test User",
|
|
Email: "test@example.com",
|
|
Roles: []string{"admin", "user"},
|
|
IsActive: true,
|
|
}
|
|
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithJSON(recorder, http.StatusOK, user)
|
|
|
|
var decoded User
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &decoded)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decode response: %v", err)
|
|
}
|
|
|
|
if decoded.ID != user.ID {
|
|
t.Errorf("Expected ID %d, got %d", user.ID, decoded.ID)
|
|
}
|
|
|
|
if decoded.Name != user.Name {
|
|
t.Errorf("Expected Name '%s', got '%s'", user.Name, decoded.Name)
|
|
}
|
|
|
|
if decoded.Email != user.Email {
|
|
t.Errorf("Expected Email '%s', got '%s'", user.Email, decoded.Email)
|
|
}
|
|
|
|
if len(decoded.Roles) != len(user.Roles) {
|
|
t.Errorf("Expected %d roles, got %d", len(user.Roles), len(decoded.Roles))
|
|
}
|
|
|
|
if decoded.IsActive != user.IsActive {
|
|
t.Errorf("Expected IsActive %v, got %v", user.IsActive, decoded.IsActive)
|
|
}
|
|
}
|
|
|
|
func TestRespondWithJSONArray(t *testing.T) {
|
|
data := []map[string]string{
|
|
{"id": "1", "name": "Item 1"},
|
|
{"id": "2", "name": "Item 2"},
|
|
{"id": "3", "name": "Item 3"},
|
|
}
|
|
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithJSON(recorder, http.StatusOK, data)
|
|
|
|
var decoded []map[string]string
|
|
err := json.Unmarshal(recorder.Body.Bytes(), &decoded)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decode response: %v", err)
|
|
}
|
|
|
|
if len(decoded) != len(data) {
|
|
t.Errorf("Expected %d items, got %d", len(data), len(decoded))
|
|
}
|
|
}
|
|
|
|
func TestResponseHeadersSet(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithJSON(recorder, http.StatusOK, map[string]string{"test": "data"})
|
|
|
|
// Verify Content-Type is set
|
|
contentType := recorder.Header().Get("Content-Type")
|
|
if contentType == "" {
|
|
t.Error("Content-Type header should be set")
|
|
}
|
|
|
|
if contentType != "application/json" {
|
|
t.Errorf("Expected Content-Type 'application/json', got '%s'", contentType)
|
|
}
|
|
}
|
|
|
|
func BenchmarkRespondWithError(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithError(recorder, http.StatusBadRequest, "Test error")
|
|
}
|
|
}
|
|
|
|
func BenchmarkRespondWithMessage(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithMessage(recorder, "Test message")
|
|
}
|
|
}
|
|
|
|
func BenchmarkRespondWithJSON(b *testing.B) {
|
|
data := map[string]interface{}{
|
|
"id": 123,
|
|
"name": "Test",
|
|
"email": "test@example.com",
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
recorder := httptest.NewRecorder()
|
|
RespondWithJSON(recorder, http.StatusOK, data)
|
|
}
|
|
}
|