mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-22 00:52:51 +08:00
feat(management): add test to validate priority preservation in auth file uploads
- Implemented `TestUploadAuthFile_PreservesPriorityAttributes` to ensure priority attributes and metadata are preserved during auth file uploads. - Updated `UploadAuthFile` logic to utilize `SynthesizeAuthFile` for better handling of generated auth attributes and metadata. Closes: #2924
This commit is contained in:
@@ -32,6 +32,7 @@ import (
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/misc"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/registry"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/util"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/watcher/synthesizer"
|
||||
sdkAuth "github.com/router-for-me/CLIProxyAPI/v7/sdk/auth"
|
||||
coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginapi"
|
||||
@@ -1161,21 +1162,35 @@ func (h *Handler) buildAuthFromFileData(path string, data []byte) (*coreauth.Aut
|
||||
if authID == "" {
|
||||
authID = path
|
||||
}
|
||||
attr := map[string]string{
|
||||
"path": path,
|
||||
"source": path,
|
||||
auth := (*coreauth.Auth)(nil)
|
||||
if h != nil && h.cfg != nil {
|
||||
sctx := &synthesizer.SynthesisContext{
|
||||
Config: h.cfg,
|
||||
AuthDir: h.cfg.AuthDir,
|
||||
Now: time.Now(),
|
||||
IDGenerator: synthesizer.NewStableIDGenerator(),
|
||||
}
|
||||
if generated := synthesizer.SynthesizeAuthFile(sctx, path, data); len(generated) > 0 && generated[0] != nil {
|
||||
auth = generated[0].Clone()
|
||||
}
|
||||
}
|
||||
auth := &coreauth.Auth{
|
||||
ID: authID,
|
||||
Provider: provider,
|
||||
FileName: filepath.Base(path),
|
||||
Label: label,
|
||||
Status: coreauth.StatusActive,
|
||||
Attributes: attr,
|
||||
Metadata: metadata,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
if auth == nil {
|
||||
auth = &coreauth.Auth{
|
||||
ID: authID,
|
||||
Provider: provider,
|
||||
Label: label,
|
||||
Status: coreauth.StatusActive,
|
||||
Attributes: map[string]string{
|
||||
"path": path,
|
||||
"source": path,
|
||||
},
|
||||
Metadata: metadata,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
auth.ID = authID
|
||||
auth.FileName = filepath.Base(path)
|
||||
if hasLastRefresh {
|
||||
auth.LastRefreshedAt = lastRefresh
|
||||
}
|
||||
|
||||
69
internal/api/handlers/management/auth_files_upload_test.go
Normal file
69
internal/api/handlers/management/auth_files_upload_test.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/config"
|
||||
coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
|
||||
)
|
||||
|
||||
func TestUploadAuthFile_PreservesPriorityAttributes(t *testing.T) {
|
||||
t.Setenv("MANAGEMENT_PASSWORD", "")
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
authDir := t.TempDir()
|
||||
manager := coreauth.NewManager(nil, nil, nil)
|
||||
h := NewHandlerWithoutConfigFilePath(&config.Config{AuthDir: authDir}, manager)
|
||||
|
||||
content := `{"type":"codex","email":"midai0530@gmail.com","priority":98}`
|
||||
|
||||
var body bytes.Buffer
|
||||
writer := multipart.NewWriter(&body)
|
||||
part, err := writer.CreateFormFile("file", "codex-midai0530@gmail.com-plus.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create multipart file: %v", err)
|
||||
}
|
||||
if _, err = part.Write([]byte(content)); err != nil {
|
||||
t.Fatalf("failed to write multipart content: %v", err)
|
||||
}
|
||||
if err = writer.Close(); err != nil {
|
||||
t.Fatalf("failed to close multipart writer: %v", err)
|
||||
}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
ctx, _ := gin.CreateTestContext(rec)
|
||||
req := httptest.NewRequest(http.MethodPost, "/v0/management/auth-files", &body)
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
ctx.Request = req
|
||||
|
||||
h.UploadAuthFile(ctx)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("expected upload status %d, got %d with body %s", http.StatusOK, rec.Code, rec.Body.String())
|
||||
}
|
||||
|
||||
var payload map[string]any
|
||||
if err = json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
}
|
||||
if status, _ := payload["status"].(string); status != "ok" {
|
||||
t.Fatalf("expected status ok, got %#v", payload["status"])
|
||||
}
|
||||
|
||||
auth, ok := manager.GetByID("codex-midai0530@gmail.com-plus.json")
|
||||
if !ok || auth == nil {
|
||||
t.Fatalf("expected uploaded auth record to exist")
|
||||
}
|
||||
if got := auth.Attributes["priority"]; got != "98" {
|
||||
t.Fatalf("priority attribute = %q, want %q", got, "98")
|
||||
}
|
||||
if got := auth.Metadata["priority"]; got != float64(98) {
|
||||
t.Fatalf("priority metadata = %#v, want 98", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user