StudentKnowledgeGraphIntegrationTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <?php
  2. namespace Tests\Feature;
  3. use Tests\TestCase;
  4. use App\Models\Student;
  5. use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
  6. use Illuminate\Support\Facades\Http;
  7. class StudentKnowledgeGraphIntegrationTest extends TestCase
  8. {
  9. use LazilyRefreshDatabase;
  10. protected function setUp(): void
  11. {
  12. parent::setUp();
  13. // 创建测试学生数据
  14. Student::create([
  15. 'student_id' => 1001,
  16. 'name' => '张三',
  17. 'grade' => '高一',
  18. 'class_name' => '1班',
  19. 'teacher_id' => 1,
  20. ]);
  21. Student::create([
  22. 'student_id' => 1002,
  23. 'name' => '李四',
  24. 'grade' => '高一',
  25. 'class_name' => '1班',
  26. 'teacher_id' => 1,
  27. ]);
  28. }
  29. /** @test */
  30. public function student_knowledge_graph_page_can_be_loaded()
  31. {
  32. $response = $this->get('/admin/student-knowledge-graph-page');
  33. $response->assertStatus(200);
  34. $response->assertSee('学生知识图谱');
  35. $response->assertSee('选择学生');
  36. $response->assertSee('知识点依赖关系图');
  37. }
  38. /** @test */
  39. public function page_displays_student_dropdown()
  40. {
  41. $response = $this->get('/admin/student-knowledge-graph-page');
  42. $response->assertSee('张三 (高一-1班)');
  43. $response->assertSee('李四 (高一-1班)');
  44. }
  45. /** @test */
  46. public function selecting_student_loads_knowledge_graph_data()
  47. {
  48. // 模拟API响应
  49. Http::fake([
  50. 'localhost:5010/api/mastery/1001' => Http::response([
  51. 'masteries' => [
  52. [
  53. 'student_id' => 1001,
  54. 'kp_code' => 'R01',
  55. 'mastery_level' => 0.85,
  56. 'confidence_level' => 0.8,
  57. ],
  58. [
  59. 'student_id' => 1001,
  60. 'kp_code' => 'R02',
  61. 'mastery_level' => 0.72,
  62. 'confidence_level' => 0.75,
  63. ],
  64. ],
  65. ], 200),
  66. 'localhost:5010/api/knowledge/dependencies' => Http::response([
  67. 'dependencies' => [
  68. [
  69. 'prerequisite_kp' => 'R01',
  70. 'dependent_kp' => 'R02',
  71. 'influence_weight' => 0.9,
  72. 'dependency_type' => 'must',
  73. ],
  74. ],
  75. ], 200),
  76. 'localhost:5010/api/mastery/1001/statistics' => Http::response([
  77. 'total_knowledge_points' => 2,
  78. 'average_mastery' => 0.785,
  79. 'high_mastery_count' => 2,
  80. 'medium_mastery_count' => 0,
  81. 'low_mastery_count' => 0,
  82. ], 200),
  83. ]);
  84. // 模拟Livewire请求
  85. $this->actingAsAdmin()
  86. ->get('/admin/student-knowledge-graph-page')
  87. ->assertStatus(200);
  88. // 使用Livewire测试器
  89. $this->livewire(\App\Livewire\StudentKnowledgeGraph::class)
  90. ->set('selectedStudentId', 1001)
  91. ->assertSet('selectedStudentId', 1001)
  92. ->call('loadStudentData', 1001)
  93. ->assertSee('张三')
  94. ->assertSee('78.5%'); // 平均掌握度
  95. }
  96. /** @test */
  97. public function api_failure_shows_mock_data()
  98. {
  99. // 模拟API失败
  100. Http::fake([
  101. 'localhost:5010/*' => Http::response([], 500),
  102. ]);
  103. $this->livewire(\App\Livewire\StudentKnowledgeGraph::class)
  104. ->set('selectedStudentId', 1001)
  105. ->call('loadStudentData', 1001)
  106. ->assertSee('有理数'); // 模拟数据中的知识点
  107. }
  108. /** @test */
  109. public function mastery_statistics_display_correctly()
  110. {
  111. // 模拟API响应
  112. Http::fake([
  113. 'localhost:5010/api/mastery/1001' => Http::response([
  114. 'masteries' => [
  115. ['kp_code' => 'R01', 'mastery_level' => 0.9, 'confidence_level' => 0.8],
  116. ['kp_code' => 'R02', 'mastery_level' => 0.6, 'confidence_level' => 0.7],
  117. ['kp_code' => 'R03', 'mastery_level' => 0.3, 'confidence_level' => 0.6],
  118. ],
  119. ], 200),
  120. 'localhost:5010/api/mastery/1001/statistics' => Http::response([
  121. 'total_knowledge_points' => 3,
  122. 'average_mastery' => 0.6,
  123. 'high_mastery_count' => 1,
  124. 'medium_mastery_count' => 1,
  125. 'low_mastery_count' => 1,
  126. ], 200),
  127. ]);
  128. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class)
  129. ->set('selectedStudentId', 1001)
  130. ->call('loadStudentData', 1001);
  131. $component->assertSee('60.0%'); // 平均掌握度
  132. $component->assertSee('1'); // 优秀数量
  133. $component->assertSee('1'); // 中等数量
  134. $component->assertSee('1'); // 待提高数量
  135. }
  136. /** @test */
  137. public function knowledge_graph_renders_with_correct_colors()
  138. {
  139. // 模拟API响应
  140. Http::fake([
  141. 'localhost:5010/api/mastery/1001' => Http::response([
  142. 'masteries' => [
  143. ['kp_code' => 'R01', 'mastery_level' => 0.85, 'confidence_level' => 0.8],
  144. ],
  145. ], 200),
  146. 'localhost:5010/api/knowledge/dependencies' => Http::response([
  147. 'dependencies' => [],
  148. ], 200),
  149. ]);
  150. $response = $this->actingAsAdmin()
  151. ->get('/admin/student-knowledge-graph-page');
  152. $response->assertStatus(200);
  153. // 验证图例显示
  154. $response->assertSee('掌握度');
  155. $response->assertSee('优秀 (≥80%)');
  156. $response->assertSee('良好 (60-80%)');
  157. $response->assertSee('中等 (40-60%)');
  158. $response->assertSee('待提高 (20-40%)');
  159. $response->assertSee('薄弱 (<20%)');
  160. }
  161. /** @test */
  162. public function refresh_button_works()
  163. {
  164. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class);
  165. // 设置学生ID
  166. $component->set('selectedStudentId', 1001);
  167. // 验证刷新按钮存在
  168. $component->assertSee('刷新');
  169. }
  170. /** @test */
  171. public function no_student_selected_shows_prompt()
  172. {
  173. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class);
  174. $component->assertSee('选择学生查看知识图谱');
  175. $component->assertSee('从上方下拉列表中选择一个学生');
  176. }
  177. /** @test */
  178. public function knowledge_points_list_displays_correctly()
  179. {
  180. // 模拟API响应
  181. Http::fake([
  182. 'localhost:5010/api/mastery/1001' => Http::response([
  183. 'masteries' => [
  184. ['kp_code' => 'R01', 'mastery_level' => 0.85, 'confidence_level' => 0.8],
  185. ['kp_code' => 'R02', 'mastery_level' => 0.72, 'confidence_level' => 0.75],
  186. ],
  187. ], 200),
  188. 'localhost:5010/api/knowledge/dependencies' => Http::response([
  189. 'dependencies' => [],
  190. ], 200),
  191. ]);
  192. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class)
  193. ->set('selectedStudentId', 1001)
  194. ->call('loadStudentData', 1001);
  195. // 验证知识点列表
  196. $component->assertSee('知识点列表');
  197. $component->assertSee('R01');
  198. $component->assertSee('R02');
  199. $component->assertSee('85.0%');
  200. $component->assertSee('72.0%');
  201. }
  202. /** @test */
  203. public function loading_state_displays_correctly()
  204. {
  205. // 模拟慢速API响应
  206. Http::fake([
  207. 'localhost:5010/*' => Http::response([
  208. 'masteries' => [],
  209. ], 200),
  210. ]);
  211. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class)
  212. ->set('selectedStudentId', 1001)
  213. ->call('loadStudentData', 1001);
  214. // 验证加载状态
  215. $this->assertNotNull($component->isLoading);
  216. }
  217. /** @test */
  218. public function reset_data_when_no_student_selected()
  219. {
  220. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class);
  221. // 先选择一个学生
  222. $component->set('selectedStudentId', 1001);
  223. $component->assertNotNull($component->selectedStudentId);
  224. // 然后取消选择
  225. $component->set('selectedStudentId', null);
  226. // 验证数据被重置
  227. $component->assertNull($component->selectedStudent);
  228. $component->assertEmpty($component->knowledgePoints);
  229. $component->assertEmpty($component->masteryData);
  230. $component->assertEmpty($component->statistics);
  231. }
  232. /** @test */
  233. public function livewire_form_validation_works()
  234. {
  235. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class);
  236. // 验证规则
  237. $component->assertValidationPassesFor('selectedStudentId', 1001);
  238. $component->assertValidationFailsFor('selectedStudentId', 'invalid-id');
  239. }
  240. /** @test */
  241. public function multiple_students_can_be_loaded()
  242. {
  243. // 模拟不同学生的数据
  244. Http::fake([
  245. 'localhost:5010/api/mastery/1001' => Http::response([
  246. 'masteries' => [
  247. ['kp_code' => 'R01', 'mastery_level' => 0.9, 'confidence_level' => 0.8],
  248. ],
  249. ], 200),
  250. 'localhost:5010/api/mastery/1002' => Http::response([
  251. 'masteries' => [
  252. ['kp_code' => 'R01', 'mastery_level' => 0.6, 'confidence_level' => 0.7],
  253. ],
  254. ], 200),
  255. ]);
  256. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class);
  257. // 加载第一个学生
  258. $component->set('selectedStudentId', 1001);
  259. $component->call('loadStudentData', 1001);
  260. $this->assertNotNull($component->selectedStudent);
  261. $this->assertEquals(1001, $component->selectedStudent->student_id);
  262. // 切换到第二个学生
  263. $component->set('selectedStudentId', 1002);
  264. $component->call('loadStudentData', 1002);
  265. $this->assertEquals(1002, $component->selectedStudent->student_id);
  266. }
  267. /** @test */
  268. public function error_handling_displays_message()
  269. {
  270. // 模拟网络异常
  271. Http::fake([
  272. 'localhost:5010/*' => Http::throw(new \Exception('Network error')),
  273. ]);
  274. $component = $this->livewire(\App\Livewire\StudentKnowledgeGraph::class)
  275. ->set('selectedStudentId', 1001)
  276. ->call('loadStudentData', 1001);
  277. // 应该使用模拟数据
  278. $component->assertSee('有理数');
  279. }
  280. protected function actingAsAdmin()
  281. {
  282. return $this->actingAs(\App\Models\User::factory()->create(), 'admin');
  283. }
  284. }