1. 删除计划单测
2. 增加makefile 生成swagger
This commit is contained in:
8
Makefile
8
Makefile
@@ -10,6 +10,7 @@ help:
|
|||||||
@echo " build Build the application"
|
@echo " build Build the application"
|
||||||
@echo " clean Clean generated files"
|
@echo " clean Clean generated files"
|
||||||
@echo " test Run all tests"
|
@echo " test Run all tests"
|
||||||
|
@echo " swag Generate swagger docs"
|
||||||
@echo " help Show this help message"
|
@echo " help Show this help message"
|
||||||
|
|
||||||
# 运行应用
|
# 运行应用
|
||||||
@@ -30,4 +31,9 @@ clean:
|
|||||||
# 运行所有测试
|
# 运行所有测试
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
go test --count=1 ./...
|
go test --count=1 ./...
|
||||||
|
|
||||||
|
# 生成swagger文档
|
||||||
|
.PHONY: swag
|
||||||
|
swag:
|
||||||
|
swag init
|
||||||
@@ -387,7 +387,7 @@ func (r *gormPlanRepository) DeletePlan(id uint) error {
|
|||||||
switch plan.ContentType {
|
switch plan.ContentType {
|
||||||
case models.PlanContentTypeTasks:
|
case models.PlanContentTypeTasks:
|
||||||
// 删除与此计划关联的所有非子任务
|
// 删除与此计划关联的所有非子任务
|
||||||
if err := tx.Where("plan_id = ? AND parent_task_id IS NULL", id).Delete(&models.Task{}).Error; err != nil {
|
if err := tx.Where("plan_id = ?", id).Delete(&models.Task{}).Error; err != nil {
|
||||||
return fmt.Errorf("删除计划ID %d 的任务失败: %w", id, err)
|
return fmt.Errorf("删除计划ID %d 的任务失败: %w", id, err)
|
||||||
}
|
}
|
||||||
case models.PlanContentTypeSubPlans:
|
case models.PlanContentTypeSubPlans:
|
||||||
|
|||||||
@@ -1279,7 +1279,7 @@ func TestPlanRepository_Create(t *testing.T) {
|
|||||||
tc.setupDB(db)
|
tc.setupDB(db)
|
||||||
|
|
||||||
// 执行 Create 操作
|
// 执行 Create 操作
|
||||||
err := repo.Create(tc.inputPlan)
|
err := repo.CreatePlan(tc.inputPlan)
|
||||||
|
|
||||||
// 断言错误
|
// 断言错误
|
||||||
if tc.expectedError != nil {
|
if tc.expectedError != nil {
|
||||||
@@ -1295,3 +1295,131 @@ func TestPlanRepository_Create(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPlanRepository_DeletePlan(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
name string
|
||||||
|
setupDB func(db *gorm.DB) (planToDeleteID uint)
|
||||||
|
expectedError string
|
||||||
|
verifyDB func(t *testing.T, db *gorm.DB, planToDeleteID uint)
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []testCase{
|
||||||
|
{
|
||||||
|
name: "成功删除-包含任务的计划",
|
||||||
|
setupDB: func(db *gorm.DB) uint {
|
||||||
|
plan := models.Plan{Name: "Plan with Tasks", ContentType: models.PlanContentTypeTasks}
|
||||||
|
db.Create(&plan)
|
||||||
|
db.Create(&models.Task{PlanID: plan.ID, Name: "Task 1"})
|
||||||
|
db.Create(&models.Task{PlanID: plan.ID, Name: "Task 2"})
|
||||||
|
return plan.ID
|
||||||
|
},
|
||||||
|
expectedError: "",
|
||||||
|
verifyDB: func(t *testing.T, db *gorm.DB, planToDeleteID uint) {
|
||||||
|
var plan models.Plan
|
||||||
|
err := db.First(&plan, planToDeleteID).Error
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.True(t, errors.Is(err, gorm.ErrRecordNotFound), "计划应被删除")
|
||||||
|
|
||||||
|
var taskCount int64
|
||||||
|
db.Model(&models.Task{}).Where("plan_id = ?", planToDeleteID).Count(&taskCount)
|
||||||
|
assert.Equal(t, int64(0), taskCount, "关联任务应被删除")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "成功删除-包含子计划链接的计划",
|
||||||
|
setupDB: func(db *gorm.DB) uint {
|
||||||
|
parentPlan := models.Plan{Name: "Parent Plan", ContentType: models.PlanContentTypeSubPlans}
|
||||||
|
childPlan := models.Plan{Name: "Child Plan", ContentType: models.PlanContentTypeTasks}
|
||||||
|
db.Create(&parentPlan)
|
||||||
|
db.Create(&childPlan)
|
||||||
|
db.Create(&models.SubPlan{ParentPlanID: parentPlan.ID, ChildPlanID: childPlan.ID})
|
||||||
|
return parentPlan.ID
|
||||||
|
},
|
||||||
|
expectedError: "",
|
||||||
|
verifyDB: func(t *testing.T, db *gorm.DB, planToDeleteID uint) {
|
||||||
|
var parentPlan models.Plan
|
||||||
|
err := db.First(&parentPlan, planToDeleteID).Error
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.True(t, errors.Is(err, gorm.ErrRecordNotFound), "父计划应被删除")
|
||||||
|
|
||||||
|
var subPlanLinkCount int64
|
||||||
|
db.Model(&models.SubPlan{}).Where("parent_plan_id = ?", planToDeleteID).Count(&subPlanLinkCount)
|
||||||
|
assert.Equal(t, int64(0), subPlanLinkCount, "子计划链接应被删除")
|
||||||
|
|
||||||
|
// 验证子计划本身未被删除
|
||||||
|
var childPlan models.Plan
|
||||||
|
err = db.First(&childPlan, 2).Error // Assuming childPlan.ID is 2 from setup
|
||||||
|
assert.NoError(t, err, "子计划本身不应被删除")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "失败删除-作为子计划的计划",
|
||||||
|
setupDB: func(db *gorm.DB) uint {
|
||||||
|
parentPlan := models.Plan{Name: "Parent Plan", ContentType: models.PlanContentTypeSubPlans}
|
||||||
|
childPlan := models.Plan{Name: "Child Plan", ContentType: models.PlanContentTypeTasks}
|
||||||
|
db.Create(&parentPlan)
|
||||||
|
db.Create(&childPlan)
|
||||||
|
db.Create(&models.SubPlan{ParentPlanID: parentPlan.ID, ChildPlanID: childPlan.ID})
|
||||||
|
return childPlan.ID // 尝试删除子计划
|
||||||
|
},
|
||||||
|
expectedError: repository.ErrDeleteWithReferencedPlan.Error(),
|
||||||
|
verifyDB: func(t *testing.T, db *gorm.DB, planToDeleteID uint) {
|
||||||
|
var childPlan models.Plan
|
||||||
|
err := db.First(&childPlan, planToDeleteID).Error
|
||||||
|
assert.NoError(t, err, "子计划不应被删除")
|
||||||
|
|
||||||
|
var subPlanLinkCount int64
|
||||||
|
db.Model(&models.SubPlan{}).Where("child_plan_id = ?", planToDeleteID).Count(&subPlanLinkCount)
|
||||||
|
assert.Equal(t, int64(1), subPlanLinkCount, "子计划链接不应被删除")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "失败删除-不存在的计划",
|
||||||
|
setupDB: func(db *gorm.DB) uint {
|
||||||
|
return 999 // 不存在的ID
|
||||||
|
},
|
||||||
|
expectedError: "record not found",
|
||||||
|
verifyDB: func(t *testing.T, db *gorm.DB, planToDeleteID uint) {
|
||||||
|
// 数据库状态应保持不变
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "成功删除-不含任何关联的计划",
|
||||||
|
setupDB: func(db *gorm.DB) uint {
|
||||||
|
plan := models.Plan{Name: "Simple Plan", ContentType: models.PlanContentTypeTasks}
|
||||||
|
db.Create(&plan)
|
||||||
|
return plan.ID
|
||||||
|
},
|
||||||
|
expectedError: "",
|
||||||
|
verifyDB: func(t *testing.T, db *gorm.DB, planToDeleteID uint) {
|
||||||
|
var plan models.Plan
|
||||||
|
err := db.First(&plan, planToDeleteID).Error
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.True(t, errors.Is(err, gorm.ErrRecordNotFound), "计划应被删除")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
db := setupTestDB(t)
|
||||||
|
sqlDB, _ := db.DB()
|
||||||
|
defer sqlDB.Close()
|
||||||
|
|
||||||
|
planToDeleteID := tc.setupDB(db)
|
||||||
|
|
||||||
|
repo := repository.NewGormPlanRepository(db)
|
||||||
|
err := repo.DeletePlan(planToDeleteID)
|
||||||
|
|
||||||
|
if tc.expectedError != "" {
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), tc.expectedError)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.verifyDB(t, db, planToDeleteID)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user