mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-23 09:17:18 +08:00
- Introduced `/openai/v1/videos` endpoint to support OpenAI-specific video generation. - Added error normalization and handling for OpenAI video resources, including detailed error propagation. - Enhanced response structure to include OpenAI-specific fields for status, progress, and model mappings. - Implemented new handlers for video content retrieval and error scenarios. - Expanded test coverage to validate OpenAI video support, error handling, and backend compatibility.
126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package logging
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TestGinLogrusRecoveryRepanicsErrAbortHandler(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
engine := gin.New()
|
|
engine.Use(GinLogrusRecovery())
|
|
engine.GET("/abort", func(c *gin.Context) {
|
|
panic(http.ErrAbortHandler)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/abort", nil)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
defer func() {
|
|
recovered := recover()
|
|
if recovered == nil {
|
|
t.Fatalf("expected panic, got nil")
|
|
}
|
|
err, ok := recovered.(error)
|
|
if !ok {
|
|
t.Fatalf("expected error panic, got %T", recovered)
|
|
}
|
|
if !errors.Is(err, http.ErrAbortHandler) {
|
|
t.Fatalf("expected ErrAbortHandler, got %v", err)
|
|
}
|
|
if err != http.ErrAbortHandler {
|
|
t.Fatalf("expected exact ErrAbortHandler sentinel, got %v", err)
|
|
}
|
|
}()
|
|
|
|
engine.ServeHTTP(recorder, req)
|
|
}
|
|
|
|
func TestGinLogrusRecoveryHandlesRegularPanic(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
engine := gin.New()
|
|
engine.Use(GinLogrusRecovery())
|
|
engine.GET("/panic", func(c *gin.Context) {
|
|
panic("boom")
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/panic", nil)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
engine.ServeHTTP(recorder, req)
|
|
if recorder.Code != http.StatusInternalServerError {
|
|
t.Fatalf("expected 500, got %d", recorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestIsAIAPIPathIncludesImages(t *testing.T) {
|
|
if !isAIAPIPath("/v1/images/generations") {
|
|
t.Fatalf("expected /v1/images/generations to be treated as AI API path")
|
|
}
|
|
if !isAIAPIPath("/v1/images/edits") {
|
|
t.Fatalf("expected /v1/images/edits to be treated as AI API path")
|
|
}
|
|
if !isAIAPIPath("/v1/videos") {
|
|
t.Fatalf("expected /v1/videos to be treated as AI API path")
|
|
}
|
|
if !isAIAPIPath("/v1/videos/video_123") {
|
|
t.Fatalf("expected /v1/videos/video_123 to be treated as AI API path")
|
|
}
|
|
if !isAIAPIPath("/openai/v1/videos") {
|
|
t.Fatalf("expected /openai/v1/videos to be treated as AI API path")
|
|
}
|
|
if !isAIAPIPath("/openai/v1/videos/video_123/content") {
|
|
t.Fatalf("expected /openai/v1/videos/video_123/content to be treated as AI API path")
|
|
}
|
|
}
|
|
|
|
func TestIsAIAPIPathIncludesCodexBackend(t *testing.T) {
|
|
paths := []string{
|
|
"/backend-api/codex/responses",
|
|
"/backend-api/codex/responses/compact",
|
|
}
|
|
for _, path := range paths {
|
|
if !isAIAPIPath(path) {
|
|
t.Fatalf("expected %s to be treated as AI API path", path)
|
|
}
|
|
}
|
|
if isAIAPIPath("/backend-api/codex-status") {
|
|
t.Fatalf("expected /backend-api/codex-status not to be treated as AI API path")
|
|
}
|
|
}
|
|
|
|
func TestGinLogrusLoggerAddsRequestIDForCodexBackend(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
engine := gin.New()
|
|
engine.Use(GinLogrusLogger())
|
|
|
|
var requestIDFromContext string
|
|
var requestIDFromGin string
|
|
engine.POST("/backend-api/codex/responses", func(c *gin.Context) {
|
|
requestIDFromContext = GetRequestID(c.Request.Context())
|
|
requestIDFromGin = GetGinRequestID(c)
|
|
c.Status(http.StatusOK)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/backend-api/codex/responses", nil)
|
|
recorder := httptest.NewRecorder()
|
|
engine.ServeHTTP(recorder, req)
|
|
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("expected 200, got %d", recorder.Code)
|
|
}
|
|
if requestIDFromContext == "" {
|
|
t.Fatalf("expected request ID in request context")
|
|
}
|
|
if requestIDFromGin != requestIDFromContext {
|
|
t.Fatalf("expected Gin request ID %q to match context request ID %q", requestIDFromGin, requestIDFromContext)
|
|
}
|
|
}
|