syncService = app(TerminalSyncService::class); } /** * 测试单个终端同步 */ public function test_can_sync_single_terminal(): void { Queue::fake(); // 创建测试终端 $terminal = Terminal::factory()->create([ 'name' => '测试终端', 'code' => 'TEST-001', ]); // 执行同步 $log = $this->syncService->syncConfiguration($terminal); // 断言同步日志已创建 $this->assertInstanceOf(TerminalSyncLog::class, $log); $this->assertEquals('pending', $log->status); $this->assertEquals($terminal->id, $log->terminal_id); $this->assertNotNull($log->config_snapshot); // 断言任务已加入队列 Queue::assertPushed(SyncTerminalConfigJob::class, function ($job) use ($terminal, $log) { return $job->terminal->id === $terminal->id && $job->log->id === $log->id; }); } /** * 测试配置快照包含完整信息 */ public function test_config_snapshot_contains_complete_information(): void { // 创建终端及关联数据 $terminal = Terminal::factory()->create([ 'name' => '测试终端', 'code' => 'TEST-002', 'ip_address' => '192.168.1.100', 'station_id' => 1, 'diagram_url' => 'https://example.com/diagram.html', 'display_config' => ['resolution' => '1920x1080'], ]); // 创建知识库关联 $kb1 = KnowledgeBase::factory()->create(['name' => '知识库1']); $kb2 = KnowledgeBase::factory()->create(['name' => '知识库2']); $terminal->knowledgeBases()->attach($kb1->id, ['priority' => 1]); $terminal->knowledgeBases()->attach($kb2->id, ['priority' => 2]); // 创建提示词 TerminalPrompt::factory()->create([ 'terminal_id' => $terminal->id, 'prompt_template' => '你好,{user}', 'variables' => ['user' => 'string'], ]); // 获取配置快照 $snapshot = $this->syncService->getConfigSnapshot($terminal); // 断言快照包含终端信息 $this->assertArrayHasKey('terminal', $snapshot); $this->assertEquals('测试终端', $snapshot['terminal']['name']); $this->assertEquals('TEST-002', $snapshot['terminal']['code']); $this->assertEquals('192.168.1.100', $snapshot['terminal']['ip_address']); // 断言快照包含知识库信息 $this->assertArrayHasKey('knowledge_bases', $snapshot); $this->assertCount(2, $snapshot['knowledge_bases']); $this->assertEquals('知识库1', $snapshot['knowledge_bases'][0]['name']); $this->assertEquals(1, $snapshot['knowledge_bases'][0]['priority']); // 断言快照包含提示词信息 $this->assertArrayHasKey('prompt', $snapshot); $this->assertEquals('你好,{user}', $snapshot['prompt']['prompt_template']); } /** * 测试批量同步 */ public function test_can_batch_sync_terminals(): void { Queue::fake(); // 创建多个终端 $terminals = Terminal::factory()->count(3)->create(); $terminalIds = $terminals->pluck('id')->toArray(); // 执行批量同步 $logs = $this->syncService->batchSync($terminalIds); // 断言创建了3个同步日志 $this->assertCount(3, $logs); // 断言每个终端都有同步日志 foreach ($terminals as $terminal) { $this->assertDatabaseHas('terminal_sync_logs', [ 'terminal_id' => $terminal->id, 'status' => 'pending', ]); } // 断言任务已加入队列 Queue::assertPushed(SyncTerminalConfigJob::class, 3); } /** * 测试同步状态更新 */ public function test_can_update_sync_status(): void { $terminal = Terminal::factory()->create(); $log = TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'pending', 'config_snapshot' => [], ]); // 更新为同步中 $this->syncService->updateSyncStatus($log, 'syncing'); $this->assertEquals('syncing', $log->fresh()->status); // 更新为已同步 $this->syncService->updateSyncStatus($log, 'synced'); $log->refresh(); $this->assertEquals('synced', $log->status); $this->assertNotNull($log->synced_at); // 更新为失败 $this->syncService->updateSyncStatus($log, 'failed', '测试错误'); $log->refresh(); $this->assertEquals('failed', $log->status); $this->assertEquals('测试错误', $log->error_message); } /** * 测试同步任务成功执行 */ public function test_sync_job_executes_successfully(): void { $terminal = Terminal::factory()->create(); $log = TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'pending', 'config_snapshot' => [], ]); // 执行任务 $job = new SyncTerminalConfigJob($terminal, $log); $job->handle(); // 断言状态更新为已同步 $log->refresh(); $this->assertEquals('synced', $log->status); $this->assertNotNull($log->synced_at); $this->assertNull($log->error_message); } /** * 测试同步失败处理 */ public function test_sync_job_handles_failure(): void { $terminal = Terminal::factory()->create(); $log = TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'pending', 'config_snapshot' => [], ]); $job = new SyncTerminalConfigJob($terminal, $log); // 模拟失败(通过调用failed方法) $exception = new \Exception('测试同步失败'); $job->failed($exception); // 断言状态更新为失败 $log->refresh(); $this->assertEquals('failed', $log->status); $this->assertStringContainsString('测试同步失败', $log->error_message); } /** * 测试同步历史记录 */ public function test_can_view_sync_history(): void { $terminal = Terminal::factory()->create(); // 创建多条同步记录 TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'synced', 'config_snapshot' => [], 'synced_at' => now()->subHours(2), 'created_at' => now()->subHours(2), ]); TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'failed', 'config_snapshot' => [], 'error_message' => '网络错误', 'created_at' => now()->subHour(), ]); TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'synced', 'config_snapshot' => [], 'synced_at' => now(), 'created_at' => now(), ]); // 获取同步历史(应该按时间倒序) $logs = $terminal->syncLogs; $this->assertCount(3, $logs); // 最新的记录应该在第一位 $this->assertEquals('synced', $logs[0]->status); $this->assertEquals('failed', $logs[1]->status); $this->assertEquals('synced', $logs[2]->status); } /** * 测试获取最新同步日志 */ public function test_can_get_latest_sync_log(): void { $terminal = Terminal::factory()->create(); // 创建多条同步记录 TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'synced', 'config_snapshot' => [], 'created_at' => now()->subHours(2), ]); $latestLog = TerminalSyncLog::create([ 'terminal_id' => $terminal->id, 'status' => 'pending', 'config_snapshot' => [], 'created_at' => now(), ]); // 获取最新同步日志 $result = $terminal->latestSyncLog; $this->assertNotNull($result); $this->assertEquals($latestLog->id, $result->id); $this->assertEquals('pending', $result->status); } }