Files
Authorization/helper/response_test.go
T
2025-12-16 10:57:26 +08:00

283 lines
6.4 KiB
Go

package helper
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
func TestRespondWithError(t *testing.T) {
tests := []struct {
name string
statusCode int
message string
}{
{
name: "responds with 400 bad request",
statusCode: http.StatusBadRequest,
message: "Invalid request",
},
{
name: "responds with 401 unauthorized",
statusCode: http.StatusUnauthorized,
message: "Unauthorized",
},
{
name: "responds with 403 forbidden",
statusCode: http.StatusForbidden,
message: "Forbidden",
},
{
name: "responds with 404 not found",
statusCode: http.StatusNotFound,
message: "Not found",
},
{
name: "responds with 500 internal server error",
statusCode: http.StatusInternalServerError,
message: "Internal server error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := httptest.NewRecorder()
RespondWithError(w, tt.statusCode, tt.message)
resp := w.Result()
defer resp.Body.Close()
// Check status code
if resp.StatusCode != tt.statusCode {
t.Errorf("status code = %v, want %v", resp.StatusCode, tt.statusCode)
}
// Check content type
contentType := resp.Header.Get("Content-Type")
if contentType != "application/json" {
t.Errorf("Content-Type = %v, want application/json", contentType)
}
// Check response body
var body map[string]string
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if body["error"] != tt.message {
t.Errorf("error message = %v, want %v", body["error"], tt.message)
}
})
}
}
func TestRespondWithMessage(t *testing.T) {
tests := []struct {
name string
message string
}{
{
name: "responds with success message",
message: "Operation successful",
},
{
name: "responds with info message",
message: "Data updated",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := httptest.NewRecorder()
RespondWithMessage(w, tt.message)
resp := w.Result()
defer resp.Body.Close()
// Check response body
var body map[string]string
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if body["message"] != tt.message {
t.Errorf("message = %v, want %v", body["message"], tt.message)
}
})
}
}
func TestRespondWithJSON(t *testing.T) {
tests := []struct {
name string
statusCode int
data interface{}
wantJSON string
}{
{
name: "responds with simple map",
statusCode: http.StatusOK,
data: map[string]string{"key": "value"},
wantJSON: `{"key":"value"}`,
},
{
name: "responds with struct",
statusCode: http.StatusCreated,
data: struct {
ID int `json:"id"`
Name string `json:"name"`
}{ID: 1, Name: "Test"},
wantJSON: `{"id":1,"name":"Test"}`,
},
{
name: "responds with array",
statusCode: http.StatusOK,
data: []string{"item1", "item2"},
wantJSON: `["item1","item2"]`,
},
{
name: "responds with nested structure",
statusCode: http.StatusOK,
data: map[string]interface{}{
"user": map[string]string{
"name": "John",
"role": "admin",
},
"active": true,
},
wantJSON: `{"active":true,"user":{"name":"John","role":"admin"}}`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := httptest.NewRecorder()
RespondWithJSON(w, tt.statusCode, tt.data)
resp := w.Result()
defer resp.Body.Close()
// Check status code
if resp.StatusCode != tt.statusCode {
t.Errorf("status code = %v, want %v", resp.StatusCode, tt.statusCode)
}
// Check content type
contentType := resp.Header.Get("Content-Type")
if contentType != "application/json" {
t.Errorf("Content-Type = %v, want application/json", contentType)
}
// Decode and re-encode to normalize JSON for comparison
var got interface{}
if err := json.NewDecoder(resp.Body).Decode(&got); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
var want interface{}
if err := json.Unmarshal([]byte(tt.wantJSON), &want); err != nil {
t.Fatalf("failed to unmarshal expected JSON: %v", err)
}
gotJSON, _ := json.Marshal(got)
wantJSON, _ := json.Marshal(want)
if string(gotJSON) != string(wantJSON) {
t.Errorf("response body = %s, want %s", string(gotJSON), string(wantJSON))
}
})
}
}
func TestRespondWithJSON_StatusCodes(t *testing.T) {
statusCodes := []int{
http.StatusOK,
http.StatusCreated,
http.StatusAccepted,
http.StatusNoContent,
http.StatusBadRequest,
http.StatusUnauthorized,
http.StatusForbidden,
http.StatusNotFound,
http.StatusInternalServerError,
}
for _, code := range statusCodes {
t.Run(http.StatusText(code), func(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]string{"status": http.StatusText(code)}
RespondWithJSON(w, code, data)
resp := w.Result()
defer resp.Body.Close()
if resp.StatusCode != code {
t.Errorf("status code = %v, want %v", resp.StatusCode, code)
}
})
}
}
func TestRespondWithError_EmptyMessage(t *testing.T) {
w := httptest.NewRecorder()
RespondWithError(w, http.StatusBadRequest, "")
resp := w.Result()
defer resp.Body.Close()
var body map[string]string
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if body["error"] != "" {
t.Errorf("error message = %v, want empty string", body["error"])
}
}
func TestRespondWithMessage_EmptyMessage(t *testing.T) {
w := httptest.NewRecorder()
RespondWithMessage(w, "")
resp := w.Result()
defer resp.Body.Close()
var body map[string]string
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if body["message"] != "" {
t.Errorf("message = %v, want empty string", body["message"])
}
}
func TestRespondWithJSON_NilData(t *testing.T) {
w := httptest.NewRecorder()
RespondWithJSON(w, http.StatusOK, nil)
resp := w.Result()
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Errorf("status code = %v, want %v", resp.StatusCode, http.StatusOK)
}
var body interface{}
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if body != nil {
t.Errorf("body = %v, want nil", body)
}
}