1
0
Files
nex/backend/tests/mysql/constraint_test.go
lanyuanxiaoyao 4c6b49099d feat: 配置 golangci-lint 静态分析并修复存量违规
- 新增 backend/.golangci.yml 配置 12 个 linter(forbidigo、errorlint、errcheck、staticcheck、revive、gocritic、gosec、bodyclose、noctx、nilerr、goimports、gocyclo)
- 新增 lefthook.yml 配置 pre-commit hook 自动运行 lint
- 修复存量代码违规:errors.Is/As 替换、zap.Error 替换、import 排序、errcheck 修复
- 更新 README 补充编码规范说明
- 归档 backend-code-lint 变更
2026-04-24 13:01:48 +08:00

131 lines
3.4 KiB
Go

//go:build mysql
package mysql
import (
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
"nex/backend/internal/config"
)
func TestConstraint_ForeignKeyEnforced(t *testing.T) {
db := SetupMySQLTestDB(t)
model := config.Model{
ID: "test-model-id",
ProviderID: "non-existent-provider",
ModelName: "gpt-4",
Enabled: true,
}
err := db.Create(&model).Error
assert.Error(t, err, "创建 model 时 provider_id 不存在应失败")
assert.Contains(t, err.Error(), "foreign key constraint", "错误应为外键约束错误")
}
func TestConstraint_CascadeDelete(t *testing.T) {
db := SetupMySQLTestDB(t)
provider := config.Provider{
ID: "test-provider-cascade",
Name: "Test Provider",
APIKey: "test-key",
BaseURL: "https://test.com",
Enabled: true,
}
err := db.Create(&provider).Error
require.NoError(t, err, "创建 provider 应成功")
model := config.Model{
ID: "test-model-cascade",
ProviderID: provider.ID,
ModelName: "gpt-4",
Enabled: true,
}
err = db.Create(&model).Error
require.NoError(t, err, "创建 model 应成功")
err = db.Delete(&provider).Error
require.NoError(t, err, "删除 provider 应成功")
var count int64
err = db.Model(&config.Model{}).Where("provider_id = ?", provider.ID).Count(&count).Error
require.NoError(t, err)
assert.Equal(t, int64(0), count, "删除 provider 后其 models 应被级联删除")
}
func TestConstraint_UniqueProviderModel(t *testing.T) {
db := SetupMySQLTestDB(t)
provider := config.Provider{
ID: "test-provider-unique",
Name: "Test Provider",
APIKey: "test-key",
BaseURL: "https://test.com",
Enabled: true,
}
err := db.Create(&provider).Error
require.NoError(t, err, "创建 provider 应成功")
model1 := config.Model{
ID: "test-model-unique-1",
ProviderID: provider.ID,
ModelName: "gpt-4",
Enabled: true,
}
err = db.Create(&model1).Error
require.NoError(t, err, "创建第一个 model 应成功")
model2 := config.Model{
ID: "test-model-unique-2",
ProviderID: provider.ID,
ModelName: "gpt-4",
Enabled: true,
}
err = db.Create(&model2).Error
assert.Error(t, err, "创建相同 (provider_id, model_name) 的 model 应失败")
assert.True(t, errors.Is(err, gorm.ErrDuplicatedKey) ||
(err != nil && (err.Error() == "Error 1062" || containsDuplicateError(err.Error()))),
"错误应为唯一约束错误")
}
func TestConstraint_UniqueUsageStats(t *testing.T) {
db := SetupMySQLTestDB(t)
today := time.Now().Format("2006-01-02")
todayTime, _ := time.Parse("2006-01-02", today)
providerID := "test-provider-unique-stats"
stats1 := config.UsageStats{
ProviderID: providerID,
ModelName: "gpt-4",
RequestCount: 10,
Date: todayTime,
}
err := db.Create(&stats1).Error
require.NoError(t, err, "创建第一个 usage_stats 应成功")
stats2 := config.UsageStats{
ProviderID: providerID,
ModelName: "gpt-4",
RequestCount: 20,
Date: todayTime,
}
err = db.Create(&stats2).Error
assert.Error(t, err, "创建相同 (provider_id, model_name, date) 的 usage_stats 应失败")
assert.True(t, errors.Is(err, gorm.ErrDuplicatedKey) ||
(err != nil && (err.Error() == "Error 1062" || containsDuplicateError(err.Error()))),
"错误应为唯一约束错误")
}
func containsDuplicateError(errStr string) bool {
return len(errStr) > 0 && (errStr[0:8] == "Error 10" || errStr[0:5] == "Dupli")
}