feat: 添加应用骨架,配置化 zap 日志贯穿全链路
- cmd/server/main.go: 使用 logger.NewLogger(cfg.Log) 替代 zap.NewProduction() - internal/app: 依赖注入组装 DB/Slurm/Service/Handler,传递 logger - internal/middleware: RequestLogger 请求日志中间件 - internal/server: 统一响应格式和路由注册 - go.mod: module 更名为 gcy_hpc_server,添加 gin/zap/lumberjack/gorm 依赖 - 日志初始化失败时 fail fast (os.Exit(1)) - GormLevel 从配置传递到 NewGormDB,支持 YAML 独立配置 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
116
internal/server/response_test.go
Normal file
116
internal/server/response_test.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func setupTestContext() (*httptest.ResponseRecorder, *gin.Context) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
return w, c
|
||||
}
|
||||
|
||||
func parseResponse(t *testing.T, w *httptest.ResponseRecorder) APIResponse {
|
||||
t.Helper()
|
||||
var resp APIResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to parse response body: %v", err)
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
func TestOK(t *testing.T) {
|
||||
w, c := setupTestContext()
|
||||
OK(c, map[string]string{"msg": "hello"})
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", w.Code)
|
||||
}
|
||||
resp := parseResponse(t, w)
|
||||
if !resp.Success {
|
||||
t.Fatal("expected success=true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreated(t *testing.T) {
|
||||
w, c := setupTestContext()
|
||||
Created(c, map[string]int{"id": 1})
|
||||
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Fatalf("expected 201, got %d", w.Code)
|
||||
}
|
||||
resp := parseResponse(t, w)
|
||||
if !resp.Success {
|
||||
t.Fatal("expected success=true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadRequest(t *testing.T) {
|
||||
w, c := setupTestContext()
|
||||
BadRequest(c, "invalid input")
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("expected 400, got %d", w.Code)
|
||||
}
|
||||
resp := parseResponse(t, w)
|
||||
if resp.Success {
|
||||
t.Fatal("expected success=false")
|
||||
}
|
||||
if resp.Error != "invalid input" {
|
||||
t.Fatalf("expected error 'invalid input', got '%s'", resp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotFound(t *testing.T) {
|
||||
w, c := setupTestContext()
|
||||
NotFound(c, "resource missing")
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("expected 404, got %d", w.Code)
|
||||
}
|
||||
resp := parseResponse(t, w)
|
||||
if resp.Success {
|
||||
t.Fatal("expected success=false")
|
||||
}
|
||||
if resp.Error != "resource missing" {
|
||||
t.Fatalf("expected error 'resource missing', got '%s'", resp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInternalError(t *testing.T) {
|
||||
w, c := setupTestContext()
|
||||
InternalError(c, "something broke")
|
||||
|
||||
if w.Code != http.StatusInternalServerError {
|
||||
t.Fatalf("expected 500, got %d", w.Code)
|
||||
}
|
||||
resp := parseResponse(t, w)
|
||||
if resp.Success {
|
||||
t.Fatal("expected success=false")
|
||||
}
|
||||
if resp.Error != "something broke" {
|
||||
t.Fatalf("expected error 'something broke', got '%s'", resp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorWithStatus(t *testing.T) {
|
||||
w, c := setupTestContext()
|
||||
ErrorWithStatus(c, http.StatusConflict, "already exists")
|
||||
|
||||
if w.Code != http.StatusConflict {
|
||||
t.Fatalf("expected 409, got %d", w.Code)
|
||||
}
|
||||
resp := parseResponse(t, w)
|
||||
if resp.Success {
|
||||
t.Fatal("expected success=false")
|
||||
}
|
||||
if resp.Error != "already exists" {
|
||||
t.Fatalf("expected error 'already exists', got '%s'", resp.Error)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user