You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.2 KiB
7.2 KiB
W3-T8 独立复审报告
复审结论
- Verdict:PASS
- 复审范围:
mydreamjob-server/src/main/java/com/mydreamjob/skill/SkillCloudController.javamydreamjob-server/src/test/java/com/mydreamjob/skill/SkillCloudControllerTest.javamydreamjob-server/src/test/java/com/mydreamjob/skill/SkillCloudAuthorizationIntegrationTest.java- 对照前次报告
changes/n03-skill-cloud/.superpowers/sdd/reviews/W3-T8.md
- 复审方式:静态核对实现、测试断言、DTO、JWT/角色链路与测试清理;独立运行指定 8 个测试类。未修改任何实现或测试文件。
原 Important finding 关闭状态
T8-I1:CLOSED
前次问题为三个 OpenAPI 200 示例的 total、计数与数组长度矛盾,且测试未读取示例内容。当前修复已关闭该问题:
SkillCloudController.java:56:词云示例改为total=1且items为 1 项。SkillCloudController.java:103:匹配示例改为matchScore=50、matchedCount=1、totalCount=2,命中 1 项、缺失 1 项。SkillCloudController.java:150:学习路径示例改为total=1且items为 1 项。SkillCloudControllerTest.java:267-307:测试读取/v3/api-docs中的responses.200.content.application/json.examples.success.value,使用 Jackson 解析字符串示例或对象示例。SkillCloudControllerTest.java:278-280:词云 data 字段集合精确匹配,total == items.size(),技能项字段集合与SkillCloudItem一致。SkillCloudControllerTest.java:282-292:匹配字段集合精确匹配,matchedSkills.size == matchedCount、missingSkills.size == totalCount - matchedCount,并按计数校验matchScore。SkillCloudControllerTest.java:294-299:学习路径字段集合精确匹配,total == items.size(),路径项字段集合与SkillLearningPathItem一致。- 对照 DTO:
SkillCloudResponse.java:industry、occupation、category、total、items。SkillCloudItem.java:rank、skillId、skillCode、nameZh、nameEn、sourceType、sourceCode、categoryId、categoryName、heat、heatSourceCode、heatElementId、heatProxy。SkillMatchResponse.java:matchScore、matchedCount、totalCount、matchedSkills、missingSkills。SkillLearningPathResponse.java:total、items。SkillLearningPathItem.java:priority、skillId、skillName、categoryId、categoryName、suggestion。
可证伪性:单独篡改 matchScore 会在 SkillCloudControllerTest.java:289-290 失败;篡改 total 会在 :279、:288 或 :297 失败;缩短或扩长数组会因元素数量不一致失败;直接删除示例或改坏 JSON 会在 :302-306 失败。
T8-I2:CLOSED
前次问题为角色测试通过 Mock ProfileService 按 userId 决定结果,未证明真实数据库角色集合。当前修复已关闭该问题:
SkillCloudAuthorizationIntegrationTest.java:42-46:使用@SpringBootTest、MockMvc、真实integration-testprofile 和独立 H2 数据库。:55-74:测试注入真实UserRepository、真实JwtTokenProvider;只 Mock 三个技能服务及 Redis,不 MockProfileService。:95-108:真实保存STUDENT、COMPANY、ADMIN、STUDENT+COMPANY、COMPANY+ADMIN五种角色集合,并在三个端点上分别断言 200、403、403、200、403。SkillCloudController.java:185-198:身份只取认证主体userId,随后调用真实profileService.assertStudentRole(userId)。ProfileService.java:50-57:真实读取UserRepository并按User.roles中是否包含STUDENT判断。JwtAuthenticationFilter.java:34-40:JWT 仅用于解析 subject 并建立认证主体;测试 token 即使统一携带roles=STUDENTclaim,生产链路仍按数据库角色拒绝 COMPANY/ADMIN,因此断言真实可证。
可证伪性:若实现改为信任 JWT 的 roles claim,COMPANY/ADMIN 场景会因测试 token 的 STUDENT claim 返回 200 而失败;若改回 Mock 按 userId 放行,数据库角色集合测试在本类中无法满足,且真实 ProfileService 未替换。
额外身份查询参数
SkillCloudAuthorizationIntegrationTest.java:112-130:对三个端点同时传入公司用户的userId和studentId,但使用学生 JWT;全部返回 200,并验证SkillMatchService与SkillLearningPathService收到 JWT 学生 ID,SkillCloudQueryService只收到筛选参数。SkillCloudController.java:73-83、:120-130、:167-177:三个接口均未声明userId或studentId请求参数,身份只来自resolveAuthenticatedStudent()。- 结论:额外查询参数不能覆盖 JWT 主体。
端点、参数与安全回归
SkillCloudController.java:73、:120、:167:三个 GET 路由保持为/skills/word-cloud、/skills/match、/skills/learning-path。- 三个方法均要求正整数
industryId、occupationId,可选正整数categoryId;@Validated与@Positive生效。 SecurityConfig.java:77-78:GET /skills/**要求 authenticated,匿名请求无法进入 Controller。SkillCloudControllerTest.java:156-165:三个端点匿名请求均断言 401。SkillCloudControllerTest.java:168-206:覆盖必填参数缺失、非正整数和可选参数非法返回 400。SkillCloudControllerTest.java:110-154:三个 STUDENT 成功路径均返回统一ApiResponse和对应 Service DTO 载荷。- 未发现 T8 修改导致三个端点、参数校验或 SecurityConfig 行为回归。
测试清理与范围
SkillCloudControllerTest.java:50-51与SkillCloudAuthorizationIntegrationTest.java:45-46使用不同的 H2 数据库名,避免类别间共享数据。SkillCloudControllerTest.java:105-108、SkillCloudAuthorizationIntegrationTest.java:89-92均在每个测试后执行userRepository.deleteAll()。- 指定 8 个测试类完成后全部通过,未观察到外键残留或后续测试污染。
- 当前工作区中未出现
docs/skill-cloud-api.md,未修改docs/openapi-rc.json、docs/frontend-integration.md,未实现 T9/T10。
独立测试结果
环境:JDK 17.0.16,Maven 3.9.7。
执行命令:
$env:JAVA_HOME='D:\java\jdk'
& 'D:\maven\apache-maven-3.9.7\bin\mvn.cmd' '-Dtest=SkillTaxonomyMigrationTest,SkillCloudSeedDataIntegrationTest,SkillTaxonomyRepositoryTest,SkillCloudQueryServiceTest,SkillMatchServiceTest,SkillLearningPathServiceTest,SkillCloudControllerTest,SkillCloudAuthorizationIntegrationTest' test
结果:
Tests run: 66, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
Total time: 53.008 s
分类结果:
SkillTaxonomyMigrationTest:2SkillCloudSeedDataIntegrationTest:8SkillTaxonomyRepositoryTest:6SkillCloudQueryServiceTest:8SkillMatchServiceTest:16SkillLearningPathServiceTest:10SkillCloudControllerTest:14SkillCloudAuthorizationIntegrationTest:2
剩余阻断项
无 Critical、Important 阻断项。T8-I1、T8-I2 均已关闭,T8 可进入后续流程。
非阻断备注:200 响应目前通过示例和测试断言锁定字段及计数,未显式绑定具体响应 schema;本轮要求已满足,不阻断 T8。