From fa1522ff3dca4077353d854f989a16faf2ee6313 Mon Sep 17 00:00:00 2001 From: chenyuan Date: Thu, 30 Jul 2026 14:07:45 +0800 Subject: [PATCH] docs: verify training task default restore --- ...026-07-30-training-task-restore-default.md | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/docs/superpowers/plans/2026-07-30-training-task-restore-default.md b/docs/superpowers/plans/2026-07-30-training-task-restore-default.md index 8dd19a9..3702802 100644 --- a/docs/superpowers/plans/2026-07-30-training-task-restore-default.md +++ b/docs/superpowers/plans/2026-07-30-training-task-restore-default.md @@ -44,7 +44,7 @@ - Consumes: requireOwnedTeachingClass(String, String)。 - Produces: restoreClassTaskDefault(String, String, String) 和 restoreClassTasksDefaults(String, String)。 -- [ ] **Step 1: 写失败的服务测试** +- [x] **Step 1: 写失败的服务测试** 在 TrainingTaskServiceImplTest 新增如下测试。测试类创建 class-1(TEACHING,createdBy 为 teacher-1)和 class-2(createdBy 为 teacher-a)。 @@ -73,13 +73,13 @@ void teacherCannotRestoreAnotherTeachersClass() { } ~~~ -- [ ] **Step 2: 运行失败测试** +- [x] **Step 2: 运行失败测试** Run: mvn -q -Dtest=TrainingTaskServiceImplTest test Expected: 编译失败,缺少恢复服务或 Mapper 方法。 -- [ ] **Step 3: 添加 Mapper 契约与 SQL** +- [x] **Step 3: 添加 Mapper 契约与 SQL** ~~~java int deleteByTeachingClassAndTaskKey(@Param("teachingClassId") String teachingClassId, @@ -99,7 +99,7 @@ int deleteByTeachingClass(@Param("teachingClassId") String teachingClassId); ~~~ -- [ ] **Step 4: 实现服务** +- [x] **Step 4: 实现服务** ~~~java @Override @@ -118,7 +118,7 @@ public void restoreClassTasksDefaults(String teachingClassId, String operatorId) } ~~~ -- [ ] **Step 5: 验证并提交** +- [x] **Step 5: 验证并提交** Run: mvn -q -Dtest=TrainingTaskServiceImplTest test @@ -133,30 +133,33 @@ git commit -m "feat: restore class training task defaults" **Files:** - Modify: src/main/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskController.java -- Test: src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java +- Create: src/test/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskControllerRestoreDefaultTest.java **Interfaces:** - Consumes: Task 1 服务方法。 - Produces: DELETE /api/training-tasks/classes/{teachingClassId}/{taskKey}/override 和 DELETE /api/training-tasks/classes/{teachingClassId}/overrides。 -- [ ] **Step 1: 写失败的源文件契约测试** +- [x] **Step 1: 写失败的控制器调用测试** -在现有测试中读取控制器源码,添加: +创建 TrainingTaskControllerRestoreDefaultTest,向控制器注入 mock TrainingTaskService,并用带 roleId=3 的 JWT 请求调用两个端点: ~~~java -assertTrue(source.contains("@DeleteMapping(\"/classes/{teachingClassId}/{taskKey}/override\")")); -assertTrue(source.contains("trainingTaskService.restoreClassTaskDefault")); -assertTrue(source.contains("@DeleteMapping(\"/classes/{teachingClassId}/overrides\")")); -assertTrue(source.contains("trainingTaskService.restoreClassTasksDefaults")); +ResultEntity result = controller.restoreClassTaskDefault( + "class-1", "new-product-survey", requestFor("teacher-1")); + +assertEquals(HttpStatus.OK, result.getStatusCode()); +verify(service).restoreClassTaskDefault("class-1", "new-product-survey", "teacher-1"); ~~~ -- [ ] **Step 2: 运行失败测试** +全班测试调用 controller.restoreClassTasksDefaults("class-1", requestFor("teacher-1")),并验证服务收到 restoreClassTasksDefaults("class-1", "teacher-1")。 -Run: mvn -q -Dtest=TrainingTaskServiceImplTest test +- [x] **Step 2: 运行失败测试** -Expected: FAIL,两个路由尚不存在。 +Run: mvn -q -Dtest=TrainingTaskControllerRestoreDefaultTest test -- [ ] **Step 3: 实现两个 DELETE 控制器方法** +Expected: 编译失败,两个控制器方法尚不存在。 + +- [x] **Step 3: 实现两个 DELETE 控制器方法** 每个方法均使用 requireTeacher(request)。成功返回 new ResultEntity(HttpStatus.OK, "Restore success");捕获 IllegalArgumentException 后返回 new ResultEntity(HttpStatus.BAD_REQUEST, e.getMessage())。单任务方法调用: @@ -170,14 +173,14 @@ trainingTaskService.restoreClassTaskDefault(teachingClassId, taskKey, user.getUs trainingTaskService.restoreClassTasksDefaults(teachingClassId, user.getUserId()); ~~~ -- [ ] **Step 4: 验证并提交** +- [x] **Step 4: 验证并提交** Run: mvn -q -DforkCount=0 test Expected: PASS。 ~~~powershell -git add src/main/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskController.java src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java +git add src/main/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskController.java src/test/java/com/sztzjy/linkCommerce/controller/stu/TrainingTaskControllerRestoreDefaultTest.java git commit -m "feat: expose training task default restore APIs" ~~~ @@ -192,7 +195,7 @@ git commit -m "feat: expose training task default restore APIs" - Consumes: Task 2 的 DELETE 路由。 - Produces: restoreClassTrainingTaskDefault、restoreClassTrainingTasksDefaults,以及二次确认的页面操作。 -- [ ] **Step 1: 写失败的静态契约测试** +- [x] **Step 1: 写失败的静态契约测试** 创建测试文件,读取 API 和页面源码,断言存在两个恢复 API、两个中文按钮、confirm 调用和 selectedTeachingClass 条件: @@ -205,13 +208,13 @@ assert(/proxy\?\.\$modal\?\.confirm/.test(page)); assert(/v-if="selectedTeachingClass"/.test(page)); ~~~ -- [ ] **Step 2: 运行失败测试** +- [x] **Step 2: 运行失败测试** Run: node tests/training-task-restore.static.test.cjs Expected: FAIL,恢复函数和按钮不存在。 -- [ ] **Step 3: 添加 API 函数** +- [x] **Step 3: 添加 API 函数** ~~~javascript export function restoreClassTrainingTaskDefault(teachingClassId, taskKey) { @@ -229,13 +232,13 @@ export function restoreClassTrainingTasksDefaults(teachingClassId) { } ~~~ -- [ ] **Step 4: 实现恢复交互** +- [x] **Step 4: 实现恢复交互** 导入两个 API 并新增 restoring 状态。教学班筛选区仅当 selectedTeachingClass 存在时显示“恢复本班全部默认任务”;编辑抽屉 footer 仅在非只读时显示“恢复此任务默认内容”。 两个处理方法都先调用 proxy.$modal.confirm,文案明确为“仅恢复当前教学班的实训任务内容,不影响学生已提交数据、成绩、进度及其他班级。是否继续?”。确认后分别调用 API,成功提示,单任务关闭抽屉,两个操作均 await queryTasks();取消确认不提示失败。 -- [ ] **Step 5: 验证并提交** +- [x] **Step 5: 验证并提交** Run: node tests/training-task-restore.static.test.cjs; node tests/school-default-task.static.test.cjs; npm run build:prod @@ -255,13 +258,13 @@ git commit -m "feat: restore teaching class task defaults" - Consumes: Task 1–3 完成功能。 - Produces: 可复现验证记录。 -- [ ] **Step 1: 完整后端回归** +- [x] **Step 1: 完整后端回归** Run: mvn -q -DforkCount=0 test Expected: PASS。 -- [ ] **Step 2: 完整前端回归** +- [x] **Step 2: 完整前端回归** Run: node tests/training-task-restore.static.test.cjs; node tests/school-default-task.static.test.cjs; npm run build:prod @@ -271,7 +274,7 @@ Expected: PASS。 以教师账号编辑 A 班一个任务后刷新,确认 A 显示编辑内容;切换 B 班,确认 B 不变。恢复 A 的单任务,确认仅该任务默认化;恢复 A 的全部任务,确认全部默认化。检查 A 班学生端内容同步默认,且既有完成记录、成绩、进度保留。 -- [ ] **Step 4: 提交验证记录** +- [x] **Step 4: 提交验证记录** ~~~powershell git add docs/superpowers/plans/2026-07-30-training-task-restore-default.md @@ -284,3 +287,9 @@ git commit -m "docs: verify training task default restore" - Placeholder scan:无 TBD、TODO 或“类似 Task N”等占位说明。 - Type consistency:后端统一使用 restoreClassTaskDefault / restoreClassTasksDefaults,前端统一使用 restoreClassTrainingTaskDefault / restoreClassTrainingTasksDefaults。 +## 执行记录(2026-07-30) + +- 后端服务测试先因恢复方法与 Mapper 删除方法不存在而编译失败,最小实现后转绿。 +- 控制器使用 `TrainingTaskControllerRestoreDefaultTest` 做实际教师 JWT 调用测试,替代原计划的源码文本断言;该测试先因端点方法不存在而编译失败,新增端点后转绿。 +- 最终自动验证:`mvn -q -DforkCount=0 test`、`node tests/training-task-restore.static.test.cjs`、`node tests/school-default-task.static.test.cjs`、`npm run build:prod` 均以退出码 0 结束。 +- 人工验收仍待在运行中的教师端完成:编辑班级 A 的任务、单任务恢复、全班恢复,并核验班级 B 与学生的既有数据未受影响。