Commit 5bb8b2ad authored by erio's avatar erio
Browse files

fix: resolve CI failures — gofmt, unused functions, test parameter mismatches

- gofmt: user.go, config_test.go, group_handler.go, smart_retry_test.go
- Remove unused: mergeGroupIDs, resolveProxyURL, "time" import
- Fix api_contract_test.go: remove extra Sora args from NewAdminService,
  NewSettingHandler, NewAccountHandler; remove Sora field expectations
- Fix account_test_service_openai_test.go: restore test helpers
parent 93b42ccf
...@@ -34,13 +34,13 @@ func NewUserHandler(adminService service.AdminService, concurrencyService *servi ...@@ -34,13 +34,13 @@ func NewUserHandler(adminService service.AdminService, concurrencyService *servi
// CreateUserRequest represents admin create user request // CreateUserRequest represents admin create user request
type CreateUserRequest struct { type CreateUserRequest struct {
Email string `json:"email" binding:"required,email"` Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=6"` Password string `json:"password" binding:"required,min=6"`
Username string `json:"username"` Username string `json:"username"`
Notes string `json:"notes"` Notes string `json:"notes"`
Balance float64 `json:"balance"` Balance float64 `json:"balance"`
Concurrency int `json:"concurrency"` Concurrency int `json:"concurrency"`
AllowedGroups []int64 `json:"allowed_groups"` AllowedGroups []int64 `json:"allowed_groups"`
} }
// UpdateUserRequest represents admin update user request // UpdateUserRequest represents admin update user request
...@@ -56,7 +56,7 @@ type UpdateUserRequest struct { ...@@ -56,7 +56,7 @@ type UpdateUserRequest struct {
AllowedGroups *[]int64 `json:"allowed_groups"` AllowedGroups *[]int64 `json:"allowed_groups"`
// GroupRates 用户专属分组倍率配置 // GroupRates 用户专属分组倍率配置
// map[groupID]*rate,nil 表示删除该分组的专属倍率 // map[groupID]*rate,nil 表示删除该分组的专属倍率
GroupRates map[int64]*float64 `json:"group_rates"` GroupRates map[int64]*float64 `json:"group_rates"`
} }
// UpdateBalanceRequest represents balance update request // UpdateBalanceRequest represents balance update request
...@@ -180,13 +180,13 @@ func (h *UserHandler) Create(c *gin.Context) { ...@@ -180,13 +180,13 @@ func (h *UserHandler) Create(c *gin.Context) {
} }
user, err := h.adminService.CreateUser(c.Request.Context(), &service.CreateUserInput{ user, err := h.adminService.CreateUser(c.Request.Context(), &service.CreateUserInput{
Email: req.Email, Email: req.Email,
Password: req.Password, Password: req.Password,
Username: req.Username, Username: req.Username,
Notes: req.Notes, Notes: req.Notes,
Balance: req.Balance, Balance: req.Balance,
Concurrency: req.Concurrency, Concurrency: req.Concurrency,
AllowedGroups: req.AllowedGroups, AllowedGroups: req.AllowedGroups,
}) })
if err != nil { if err != nil {
response.ErrorFrom(c, err) response.ErrorFrom(c, err)
...@@ -213,15 +213,15 @@ func (h *UserHandler) Update(c *gin.Context) { ...@@ -213,15 +213,15 @@ func (h *UserHandler) Update(c *gin.Context) {
// 使用指针类型直接传递,nil 表示未提供该字段 // 使用指针类型直接传递,nil 表示未提供该字段
user, err := h.adminService.UpdateUser(c.Request.Context(), userID, &service.UpdateUserInput{ user, err := h.adminService.UpdateUser(c.Request.Context(), userID, &service.UpdateUserInput{
Email: req.Email, Email: req.Email,
Password: req.Password, Password: req.Password,
Username: req.Username, Username: req.Username,
Notes: req.Notes, Notes: req.Notes,
Balance: req.Balance, Balance: req.Balance,
Concurrency: req.Concurrency, Concurrency: req.Concurrency,
Status: req.Status, Status: req.Status,
AllowedGroups: req.AllowedGroups, AllowedGroups: req.AllowedGroups,
GroupRates: req.GroupRates, GroupRates: req.GroupRates,
}) })
if err != nil { if err != nil {
response.ErrorFrom(c, err) response.ErrorFrom(c, err)
......
...@@ -604,20 +604,20 @@ func userEntityToService(u *dbent.User) *service.User { ...@@ -604,20 +604,20 @@ func userEntityToService(u *dbent.User) *service.User {
return nil return nil
} }
return &service.User{ return &service.User{
ID: u.ID, ID: u.ID,
Email: u.Email, Email: u.Email,
Username: u.Username, Username: u.Username,
Notes: u.Notes, Notes: u.Notes,
PasswordHash: u.PasswordHash, PasswordHash: u.PasswordHash,
Role: u.Role, Role: u.Role,
Balance: u.Balance, Balance: u.Balance,
Concurrency: u.Concurrency, Concurrency: u.Concurrency,
Status: u.Status, Status: u.Status,
TotpSecretEncrypted: u.TotpSecretEncrypted, TotpSecretEncrypted: u.TotpSecretEncrypted,
TotpEnabled: u.TotpEnabled, TotpEnabled: u.TotpEnabled,
TotpEnabledAt: u.TotpEnabledAt, TotpEnabledAt: u.TotpEnabledAt,
CreatedAt: u.CreatedAt, CreatedAt: u.CreatedAt,
UpdatedAt: u.UpdatedAt, UpdatedAt: u.UpdatedAt,
} }
} }
......
package service
import (
"fmt"
"io"
"net/http"
"strings"
"github.com/Wei-Shaw/sub2api/internal/pkg/tlsfingerprint"
)
// queuedHTTPUpstream is a test helper that serves pre-loaded responses in order.
type queuedHTTPUpstream struct {
responses []*http.Response
requests []*http.Request
tlsFlags []bool
}
func (u *queuedHTTPUpstream) Do(_ *http.Request, _ string, _ int64, _ int) (*http.Response, error) {
return nil, fmt.Errorf("unexpected Do call")
}
func (u *queuedHTTPUpstream) DoWithTLS(req *http.Request, _ string, _ int64, _ int, profile *tlsfingerprint.Profile) (*http.Response, error) {
u.requests = append(u.requests, req)
u.tlsFlags = append(u.tlsFlags, profile != nil)
if len(u.responses) == 0 {
return nil, fmt.Errorf("no mocked response")
}
resp := u.responses[0]
u.responses = u.responses[1:]
return resp, nil
}
// newJSONResponse creates a simple HTTP response for testing.
func newJSONResponse(status int, body string) *http.Response {
return &http.Response{
StatusCode: status,
Header: make(http.Header),
Body: io.NopCloser(strings.NewReader(body)),
}
}
// newJSONResponseWithHeader creates a JSON response with a custom header.
func newJSONResponseWithHeader(status int, body, key, value string) *http.Response {
resp := newJSONResponse(status, body)
resp.Header.Set(key, value)
return resp
}
...@@ -4,6 +4,7 @@ package service ...@@ -4,6 +4,7 @@ package service
import ( import (
"context" "context"
"fmt"
"io" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
...@@ -13,8 +14,43 @@ import ( ...@@ -13,8 +14,43 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/Wei-Shaw/sub2api/internal/pkg/tlsfingerprint"
) )
// --- shared test helpers ---
type queuedHTTPUpstream struct {
responses []*http.Response
requests []*http.Request
tlsFlags []bool
}
func (u *queuedHTTPUpstream) Do(_ *http.Request, _ string, _ int64, _ int) (*http.Response, error) {
return nil, fmt.Errorf("unexpected Do call")
}
func (u *queuedHTTPUpstream) DoWithTLS(req *http.Request, _ string, _ int64, _ int, profile *tlsfingerprint.Profile) (*http.Response, error) {
u.requests = append(u.requests, req)
u.tlsFlags = append(u.tlsFlags, profile != nil)
if len(u.responses) == 0 {
return nil, fmt.Errorf("no mocked response")
}
resp := u.responses[0]
u.responses = u.responses[1:]
return resp, nil
}
func newJSONResponse(status int, body string) *http.Response {
return &http.Response{
StatusCode: status,
Header: make(http.Header),
Body: io.NopCloser(strings.NewReader(body)),
}
}
// --- test functions ---
func newTestContext() (*gin.Context, *httptest.ResponseRecorder) { func newTestContext() (*gin.Context, *httptest.ResponseRecorder) {
gin.SetMode(gin.TestMode) gin.SetMode(gin.TestMode)
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment