Files
KnowledgeBase/tests/Feature/TerminalSyncTest.php

281 lines
8.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace Tests\Feature;
use App\Jobs\SyncTerminalConfigJob;
use App\Models\Terminal;
use App\Models\TerminalSyncLog;
use App\Models\KnowledgeBase;
use App\Models\TerminalPrompt;
use App\Services\TerminalSyncService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
class TerminalSyncTest extends TestCase
{
use RefreshDatabase;
protected TerminalSyncService $syncService;
protected function setUp(): void
{
parent::setUp();
$this->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);
}
}