Merge branch 'dev-frontend-optimization'
This commit is contained in:
@@ -48,11 +48,3 @@ func (UsageStats) TableName() string {
|
||||
return "usage_stats"
|
||||
}
|
||||
|
||||
// MaskAPIKey 掩码 API Key(仅显示最后 4 个字符)
|
||||
func (p *Provider) MaskAPIKey() {
|
||||
if len(p.APIKey) > 4 {
|
||||
p.APIKey = "***" + p.APIKey[len(p.APIKey)-4:]
|
||||
} else {
|
||||
p.APIKey = "***"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,3 @@ type Provider struct {
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// MaskAPIKey 掩码 API Key(仅显示最后 4 个字符)
|
||||
func (p *Provider) MaskAPIKey() {
|
||||
if len(p.APIKey) > 4 {
|
||||
p.APIKey = "***" + p.APIKey[len(p.APIKey)-4:]
|
||||
} else {
|
||||
p.APIKey = "***"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestProviderHandler_CreateProvider_Success(t *testing.T) {
|
||||
var result domain.Provider
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &result))
|
||||
assert.Equal(t, "p1", result.ID)
|
||||
assert.Contains(t, result.APIKey, "***")
|
||||
assert.Equal(t, "sk-test", result.APIKey)
|
||||
}
|
||||
|
||||
func TestProviderHandler_CreateProvider_WithProtocol(t *testing.T) {
|
||||
@@ -73,7 +73,7 @@ func TestProviderHandler_UpdateProvider(t *testing.T) {
|
||||
|
||||
mockSvc := mocks.NewMockProviderService(ctrl)
|
||||
mockSvc.EXPECT().Update(gomock.Eq("p1"), gomock.Any()).Return(nil)
|
||||
mockSvc.EXPECT().Get(gomock.Eq("p1"), gomock.Eq(true)).Return(&domain.Provider{ID: "p1", Name: "Updated", APIKey: "***"}, nil)
|
||||
mockSvc.EXPECT().Get(gomock.Eq("p1")).Return(&domain.Provider{ID: "p1", Name: "Updated", APIKey: "sk-test"}, nil)
|
||||
h := NewProviderHandler(mockSvc)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"name": "Updated"})
|
||||
|
||||
@@ -24,6 +24,8 @@ func init() {
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func TestProviderHandler_CreateProvider_MissingFields(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
@@ -69,7 +71,7 @@ func TestProviderHandler_GetProvider(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
|
||||
mockSvc := mocks.NewMockProviderService(ctrl)
|
||||
mockSvc.EXPECT().Get(gomock.Eq("p1"), gomock.Eq(true)).Return(&domain.Provider{ID: "p1", Name: "P1", APIKey: "***"}, nil)
|
||||
mockSvc.EXPECT().Get(gomock.Eq("p1")).Return(&domain.Provider{ID: "p1", Name: "P1", APIKey: "sk-test"}, nil)
|
||||
h := NewProviderHandler(mockSvc)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
@@ -66,7 +66,6 @@ func (h *ProviderHandler) CreateProvider(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
provider.MaskAPIKey()
|
||||
c.JSON(http.StatusCreated, provider)
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ func (h *ProviderHandler) ListProviders(c *gin.Context) {
|
||||
func (h *ProviderHandler) GetProvider(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
provider, err := h.providerService.Get(id, true)
|
||||
provider, err := h.providerService.Get(id)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
@@ -131,7 +130,7 @@ func (h *ProviderHandler) UpdateProvider(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
provider, err := h.providerService.Get(id, true)
|
||||
provider, err := h.providerService.Get(id)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
|
||||
@@ -26,6 +26,8 @@ func init() {
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func setupProxyEngine(t *testing.T) *conversion.ConversionEngine {
|
||||
t.Helper()
|
||||
registry := conversion.NewMemoryRegistry()
|
||||
|
||||
@@ -7,7 +7,7 @@ import "nex/backend/internal/domain"
|
||||
// ProviderService 供应商服务接口
|
||||
type ProviderService interface {
|
||||
Create(provider *domain.Provider) error
|
||||
Get(id string, maskKey bool) (*domain.Provider, error)
|
||||
Get(id string) (*domain.Provider, error)
|
||||
List() ([]domain.Provider, error)
|
||||
Update(id string, updates map[string]interface{}) error
|
||||
Delete(id string) error
|
||||
|
||||
@@ -32,26 +32,12 @@ func (s *providerService) Create(provider *domain.Provider) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *providerService) Get(id string, maskKey bool) (*domain.Provider, error) {
|
||||
provider, err := s.providerRepo.GetByID(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if maskKey {
|
||||
provider.MaskAPIKey()
|
||||
}
|
||||
return provider, nil
|
||||
func (s *providerService) Get(id string) (*domain.Provider, error) {
|
||||
return s.providerRepo.GetByID(id)
|
||||
}
|
||||
|
||||
func (s *providerService) List() ([]domain.Provider, error) {
|
||||
providers, err := s.providerRepo.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range providers {
|
||||
providers[i].MaskAPIKey()
|
||||
}
|
||||
return providers, nil
|
||||
return s.providerRepo.List()
|
||||
}
|
||||
|
||||
func (s *providerService) Update(id string, updates map[string]interface{}) error {
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestProviderService_Update(t *testing.T) {
|
||||
err := svc.Update("p1", map[string]interface{}{"name": "Updated"})
|
||||
require.NoError(t, err)
|
||||
|
||||
result, err := svc.Get("p1", false)
|
||||
result, err := svc.Get("p1")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Updated", result.Name)
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ func TestProviderService_Update_Success(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
updated, err := svc.Get("openai", false)
|
||||
updated, err := svc.Get("openai")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "OpenAI Updated", updated.Name)
|
||||
}
|
||||
@@ -425,9 +425,9 @@ func TestProviderService_isUniqueConstraintError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ============ ProviderService - List MaskAPIKey 测试 ============
|
||||
// ============ ProviderService - List API Key 测试 ============
|
||||
|
||||
func TestProviderService_List_MaskAPIKey(t *testing.T) {
|
||||
func TestProviderService_List_APIKeyNotMasked(t *testing.T) {
|
||||
db := setupServiceTestDB(t)
|
||||
repo := repository.NewProviderRepository(db)
|
||||
modelRepo := repository.NewModelRepository(db)
|
||||
@@ -442,9 +442,13 @@ func TestProviderService_List_MaskAPIKey(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, providers, 2)
|
||||
|
||||
expectedKeys := map[string]string{
|
||||
"openai": "sk-1234567890",
|
||||
"anthropic": "sk-anthropic1234",
|
||||
}
|
||||
for _, p := range providers {
|
||||
assert.Contains(t, p.APIKey, "***")
|
||||
assert.Len(t, p.APIKey, 7)
|
||||
assert.NotContains(t, p.APIKey, "***")
|
||||
assert.Equal(t, expectedKeys[p.ID], p.APIKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -533,8 +533,7 @@ func TestConversion_ProviderWithProtocol(t *testing.T) {
|
||||
|
||||
var created map[string]any
|
||||
json.Unmarshal(w.Body.Bytes(), &created)
|
||||
// API Key 被掩码
|
||||
assert.Contains(t, created["api_key"], "***")
|
||||
assert.Equal(t, "sk-test", created["api_key"])
|
||||
|
||||
// 获取时应包含 protocol
|
||||
w = httptest.NewRecorder()
|
||||
|
||||
@@ -103,7 +103,7 @@ func TestOpenAI_CompleteFlow(t *testing.T) {
|
||||
var providers []domain.Provider
|
||||
json.Unmarshal(w.Body.Bytes(), &providers)
|
||||
assert.Len(t, providers, 1)
|
||||
assert.Contains(t, providers[0].APIKey, "***") // 已掩码
|
||||
assert.Equal(t, "sk-test-key", providers[0].APIKey)
|
||||
|
||||
// 4. 列出 Model
|
||||
w = httptest.NewRecorder()
|
||||
|
||||
@@ -69,18 +69,18 @@ func (mr *MockProviderServiceMockRecorder) Delete(id any) *gomock.Call {
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockProviderService) Get(id string, maskKey bool) (*domain.Provider, error) {
|
||||
func (m *MockProviderService) Get(id string) (*domain.Provider, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", id, maskKey)
|
||||
ret := m.ctrl.Call(m, "Get", id)
|
||||
ret0, _ := ret[0].(*domain.Provider)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockProviderServiceMockRecorder) Get(id, maskKey any) *gomock.Call {
|
||||
func (mr *MockProviderServiceMockRecorder) Get(id any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockProviderService)(nil).Get), id, maskKey)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockProviderService)(nil).Get), id)
|
||||
}
|
||||
|
||||
// GetModelByProviderAndName mocks base method.
|
||||
|
||||
Reference in New Issue
Block a user