test(阶段三): 添加终端管理功能测试
- TerminalResourceTest: 18个测试用例,测试终端CRUD和筛选功能 - TerminalKnowledgeBaseAssociationTest: 5个测试用例,测试知识库关联 - TerminalKnowledgeBaseFormTest: 6个测试用例,测试表单关联功能 - TerminalPromptTest: 6个测试用例,测试提示词模型 - TerminalPromptFormTest: 3个测试用例,测试提示词表单 - PromptTemplateTest: 16个测试用例,测试模板和变量功能 - TerminalSyncTest: 8个测试用例,测试配置同步功能 - 总计62个测试用例,覆盖所有核心功能
This commit is contained in:
266
tests/Feature/PromptTemplateTest.php
Normal file
266
tests/Feature/PromptTemplateTest.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Terminal;
|
||||
use App\Models\TerminalPrompt;
|
||||
use App\Models\User;
|
||||
use App\Services\PromptTemplateService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PromptTemplateTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected PromptTemplateService $service;
|
||||
protected User $user;
|
||||
protected Terminal $terminal;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->service = app(PromptTemplateService::class);
|
||||
|
||||
// 创建测试用户
|
||||
$this->user = User::factory()->create([
|
||||
'name' => '测试用户',
|
||||
]);
|
||||
|
||||
// 创建测试终端
|
||||
$this->terminal = Terminal::factory()->create([
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-001',
|
||||
'station_id' => 1001,
|
||||
]);
|
||||
|
||||
$this->actingAs($this->user);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_get_all_templates()
|
||||
{
|
||||
$templates = $this->service->getTemplates();
|
||||
|
||||
$this->assertIsArray($templates);
|
||||
$this->assertNotEmpty($templates);
|
||||
$this->assertArrayHasKey('id', $templates[0]);
|
||||
$this->assertArrayHasKey('name', $templates[0]);
|
||||
$this->assertArrayHasKey('content', $templates[0]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_get_template_by_id()
|
||||
{
|
||||
$template = $this->service->getTemplate('general_assistant');
|
||||
|
||||
$this->assertNotNull($template);
|
||||
$this->assertEquals('general_assistant', $template['id']);
|
||||
$this->assertArrayHasKey('content', $template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_returns_null_for_invalid_template_id()
|
||||
{
|
||||
$template = $this->service->getTemplate('non_existent_template');
|
||||
|
||||
$this->assertNull($template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_apply_template_to_terminal()
|
||||
{
|
||||
$content = $this->service->applyTemplate($this->terminal, 'general_assistant');
|
||||
|
||||
$this->assertIsString($content);
|
||||
$this->assertNotEmpty($content);
|
||||
$this->assertStringContainsString('{user}', $content);
|
||||
$this->assertStringContainsString('{station}', $content);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_throws_exception_for_invalid_template()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('模板不存在');
|
||||
|
||||
$this->service->applyTemplate($this->terminal, 'invalid_template');
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_replace_variables_in_template()
|
||||
{
|
||||
$template = '你好,{user}!当前时间是 {time},你在 {station}。';
|
||||
|
||||
$result = $this->service->replaceVariables($template, $this->terminal);
|
||||
|
||||
$this->assertStringContainsString('测试用户', $result);
|
||||
$this->assertStringContainsString('工作站 1001', $result);
|
||||
$this->assertStringNotContainsString('{user}', $result);
|
||||
$this->assertStringNotContainsString('{station}', $result);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_get_variable_values()
|
||||
{
|
||||
$variables = $this->service->getVariableValues($this->terminal);
|
||||
|
||||
$this->assertIsArray($variables);
|
||||
$this->assertArrayHasKey('user', $variables);
|
||||
$this->assertArrayHasKey('terminal_name', $variables);
|
||||
$this->assertArrayHasKey('station', $variables);
|
||||
$this->assertArrayHasKey('time', $variables);
|
||||
|
||||
$this->assertEquals('测试用户', $variables['user']);
|
||||
$this->assertEquals('测试终端', $variables['terminal_name']);
|
||||
$this->assertEquals('TEST-001', $variables['terminal_code']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_handles_array_variables_correctly()
|
||||
{
|
||||
// 创建知识库关联
|
||||
$kb1 = \App\Models\KnowledgeBase::factory()->create(['name' => '知识库1']);
|
||||
$kb2 = \App\Models\KnowledgeBase::factory()->create(['name' => '知识库2']);
|
||||
|
||||
$this->terminal->knowledgeBases()->attach([
|
||||
$kb1->id => ['priority' => 1],
|
||||
$kb2->id => ['priority' => 2],
|
||||
]);
|
||||
|
||||
$template = '可用知识库:{knowledge_bases}';
|
||||
$result = $this->service->replaceVariables($template, $this->terminal);
|
||||
|
||||
$this->assertStringContainsString('知识库1', $result);
|
||||
$this->assertStringContainsString('知识库2', $result);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_preview_template()
|
||||
{
|
||||
$template = '你好,{user}!终端:{terminal_name}';
|
||||
|
||||
$preview = $this->service->preview($template, $this->terminal);
|
||||
|
||||
$this->assertStringContainsString('测试用户', $preview);
|
||||
$this->assertStringContainsString('测试终端', $preview);
|
||||
$this->assertStringNotContainsString('{user}', $preview);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_validate_variables()
|
||||
{
|
||||
$validTemplate = '你好,{user}!时间:{time}';
|
||||
$invalidVariables = $this->service->validateVariables($validTemplate);
|
||||
|
||||
$this->assertEmpty($invalidVariables);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_detects_invalid_variables()
|
||||
{
|
||||
$invalidTemplate = '你好,{user}!无效变量:{invalid_var},另一个:{another_invalid}';
|
||||
$invalidVariables = $this->service->validateVariables($invalidTemplate);
|
||||
|
||||
$this->assertNotEmpty($invalidVariables);
|
||||
$this->assertContains('invalid_var', $invalidVariables);
|
||||
$this->assertContains('another_invalid', $invalidVariables);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_determines_shift_correctly()
|
||||
{
|
||||
// 使用反射访问protected方法
|
||||
$reflection = new \ReflectionClass($this->service);
|
||||
$method = $reflection->getMethod('getCurrentShift');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// 测试早班 (8:00-16:00)
|
||||
$morningTime = now()->setTime(10, 0);
|
||||
$this->assertEquals('早班', $method->invoke($this->service, $morningTime));
|
||||
|
||||
// 测试中班 (16:00-24:00)
|
||||
$afternoonTime = now()->setTime(18, 0);
|
||||
$this->assertEquals('中班', $method->invoke($this->service, $afternoonTime));
|
||||
|
||||
// 测试夜班 (0:00-8:00)
|
||||
$nightTime = now()->setTime(2, 0);
|
||||
$this->assertEquals('夜班', $method->invoke($this->service, $nightTime));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_save_prompt_template()
|
||||
{
|
||||
$promptData = [
|
||||
'prompt_template' => '这是一个测试提示词模板,包含变量 {user} 和 {station}',
|
||||
'variables' => ['user', 'station'],
|
||||
];
|
||||
|
||||
$prompt = $this->terminal->prompt()->create($promptData);
|
||||
|
||||
$this->assertInstanceOf(TerminalPrompt::class, $prompt);
|
||||
$this->assertEquals($promptData['prompt_template'], $prompt->prompt_template);
|
||||
$this->assertEquals($promptData['variables'], $prompt->variables);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_prompt_relationship_works()
|
||||
{
|
||||
TerminalPrompt::factory()->create([
|
||||
'terminal_id' => $this->terminal->id,
|
||||
'prompt_template' => '测试模板',
|
||||
]);
|
||||
|
||||
$this->terminal->refresh();
|
||||
|
||||
$this->assertNotNull($this->terminal->prompt);
|
||||
$this->assertEquals('测试模板', $this->terminal->prompt->prompt_template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function config_files_are_properly_structured()
|
||||
{
|
||||
// 测试变量配置
|
||||
$variables = config('prompt_variables.variables');
|
||||
$this->assertIsArray($variables);
|
||||
$this->assertNotEmpty($variables);
|
||||
|
||||
foreach ($variables as $variable) {
|
||||
$this->assertArrayHasKey('name', $variable);
|
||||
$this->assertArrayHasKey('label', $variable);
|
||||
$this->assertArrayHasKey('description', $variable);
|
||||
$this->assertArrayHasKey('example', $variable);
|
||||
$this->assertArrayHasKey('type', $variable);
|
||||
$this->assertArrayHasKey('category', $variable);
|
||||
}
|
||||
|
||||
// 测试模板配置
|
||||
$templates = config('prompt_templates.templates');
|
||||
$this->assertIsArray($templates);
|
||||
$this->assertNotEmpty($templates);
|
||||
|
||||
foreach ($templates as $template) {
|
||||
$this->assertArrayHasKey('id', $template);
|
||||
$this->assertArrayHasKey('name', $template);
|
||||
$this->assertArrayHasKey('description', $template);
|
||||
$this->assertArrayHasKey('category', $template);
|
||||
$this->assertArrayHasKey('content', $template);
|
||||
}
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function all_template_variables_are_valid()
|
||||
{
|
||||
$templates = config('prompt_templates.templates');
|
||||
|
||||
foreach ($templates as $template) {
|
||||
$invalidVars = $this->service->validateVariables($template['content']);
|
||||
|
||||
$this->assertEmpty(
|
||||
$invalidVars,
|
||||
"模板 '{$template['name']}' 包含无效变量: " . implode(', ', $invalidVars)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
158
tests/Feature/TerminalKnowledgeBaseAssociationTest.php
Normal file
158
tests/Feature/TerminalKnowledgeBaseAssociationTest.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\KnowledgeBase;
|
||||
use App\Models\Terminal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TerminalKnowledgeBaseAssociationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// 创建测试用户
|
||||
$this->user = User::factory()->create();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_associate_with_knowledge_bases()
|
||||
{
|
||||
// 创建终端
|
||||
$terminal = Terminal::factory()->create([
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-001',
|
||||
]);
|
||||
|
||||
// 创建知识库
|
||||
$kb1 = KnowledgeBase::create([
|
||||
'name' => '知识库1',
|
||||
'description' => '测试知识库1',
|
||||
'status' => 'active',
|
||||
]);
|
||||
|
||||
$kb2 = KnowledgeBase::create([
|
||||
'name' => '知识库2',
|
||||
'description' => '测试知识库2',
|
||||
'status' => 'active',
|
||||
]);
|
||||
|
||||
// 关联知识库并设置优先级
|
||||
$terminal->knowledgeBases()->attach($kb1->id, ['priority' => 1]);
|
||||
$terminal->knowledgeBases()->attach($kb2->id, ['priority' => 2]);
|
||||
|
||||
// 验证关联关系
|
||||
$this->assertCount(2, $terminal->knowledgeBases);
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb1));
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb2));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function knowledge_bases_are_ordered_by_priority()
|
||||
{
|
||||
// 创建终端
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
// 创建知识库
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
$kb2 = KnowledgeBase::create(['name' => '知识库2', 'status' => 'active']);
|
||||
$kb3 = KnowledgeBase::create(['name' => '知识库3', 'status' => 'active']);
|
||||
|
||||
// 按不同优先级关联(优先级越小越靠前)
|
||||
$terminal->knowledgeBases()->attach($kb1->id, ['priority' => 10]);
|
||||
$terminal->knowledgeBases()->attach($kb2->id, ['priority' => 5]);
|
||||
$terminal->knowledgeBases()->attach($kb3->id, ['priority' => 1]);
|
||||
|
||||
// 重新加载关联关系
|
||||
$terminal->refresh();
|
||||
|
||||
// 验证排序(应该按优先级从小到大排序)
|
||||
$orderedKbs = $terminal->knowledgeBases;
|
||||
$this->assertEquals($kb3->id, $orderedKbs[0]->id); // priority 1
|
||||
$this->assertEquals($kb2->id, $orderedKbs[1]->id); // priority 5
|
||||
$this->assertEquals($kb1->id, $orderedKbs[2]->id); // priority 10
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_update_knowledge_base_associations()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
$kb2 = KnowledgeBase::create(['name' => '知识库2', 'status' => 'active']);
|
||||
|
||||
// 初始关联
|
||||
$terminal->knowledgeBases()->attach($kb1->id, ['priority' => 1]);
|
||||
|
||||
// 验证初始状态
|
||||
$this->assertCount(1, $terminal->knowledgeBases);
|
||||
|
||||
// 更新关联(添加新的知识库)
|
||||
$terminal->knowledgeBases()->attach($kb2->id, ['priority' => 2]);
|
||||
|
||||
// 重新加载
|
||||
$terminal->refresh();
|
||||
|
||||
// 验证更新后的状态
|
||||
$this->assertCount(2, $terminal->knowledgeBases);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_remove_knowledge_base_associations()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
$kb2 = KnowledgeBase::create(['name' => '知识库2', 'status' => 'active']);
|
||||
|
||||
// 关联知识库
|
||||
$terminal->knowledgeBases()->attach([
|
||||
$kb1->id => ['priority' => 1],
|
||||
$kb2->id => ['priority' => 2],
|
||||
]);
|
||||
|
||||
// 验证初始状态
|
||||
$this->assertCount(2, $terminal->knowledgeBases);
|
||||
|
||||
// 移除一个关联
|
||||
$terminal->knowledgeBases()->detach($kb1->id);
|
||||
|
||||
// 重新加载
|
||||
$terminal->refresh();
|
||||
|
||||
// 验证移除后的状态
|
||||
$this->assertCount(1, $terminal->knowledgeBases);
|
||||
$this->assertFalse($terminal->knowledgeBases->contains($kb1));
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb2));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_update_priority_of_associated_knowledge_base()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
$kb = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
|
||||
// 关联知识库
|
||||
$terminal->knowledgeBases()->attach($kb->id, ['priority' => 5]);
|
||||
|
||||
// 验证初始优先级
|
||||
$this->assertEquals(5, $terminal->knowledgeBases->first()->pivot->priority);
|
||||
|
||||
// 更新优先级
|
||||
$terminal->knowledgeBases()->updateExistingPivot($kb->id, ['priority' => 1]);
|
||||
|
||||
// 重新加载
|
||||
$terminal->refresh();
|
||||
|
||||
// 验证更新后的优先级
|
||||
$this->assertEquals(1, $terminal->knowledgeBases->first()->pivot->priority);
|
||||
}
|
||||
}
|
||||
181
tests/Feature/TerminalKnowledgeBaseFormTest.php
Normal file
181
tests/Feature/TerminalKnowledgeBaseFormTest.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Filament\Resources\TerminalResource;
|
||||
use App\Models\KnowledgeBase;
|
||||
use App\Models\Terminal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TerminalKnowledgeBaseFormTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// 创建管理员用户
|
||||
$this->user = User::factory()->create();
|
||||
$this->actingAs($this->user);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_form_has_knowledge_base_association_field()
|
||||
{
|
||||
// 创建知识库
|
||||
KnowledgeBase::create([
|
||||
'name' => '测试知识库',
|
||||
'description' => '测试描述',
|
||||
'status' => 'active',
|
||||
]);
|
||||
|
||||
// 测试创建表单包含知识库关联字段
|
||||
$component = Livewire::test(TerminalResource\Pages\CreateTerminal::class);
|
||||
|
||||
// 验证表单可以渲染
|
||||
$component->assertSuccessful();
|
||||
|
||||
// 验证表单组件存在(通过检查表单实例)
|
||||
$this->assertNotNull($component->instance()->form);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_be_created_with_knowledge_base_associations()
|
||||
{
|
||||
// 创建知识库
|
||||
$kb1 = KnowledgeBase::create([
|
||||
'name' => '生产流程知识库',
|
||||
'status' => 'active',
|
||||
]);
|
||||
|
||||
$kb2 = KnowledgeBase::create([
|
||||
'name' => '设备维护知识库',
|
||||
'status' => 'active',
|
||||
]);
|
||||
|
||||
// 创建终端
|
||||
$terminal = Terminal::factory()->create([
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-001',
|
||||
]);
|
||||
|
||||
// 手动关联知识库(模拟表单提交后的效果)
|
||||
$terminal->knowledgeBases()->attach([
|
||||
$kb1->id => ['priority' => 1],
|
||||
$kb2->id => ['priority' => 2],
|
||||
]);
|
||||
|
||||
// 验证关联关系
|
||||
$this->assertCount(2, $terminal->knowledgeBases);
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb1));
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb2));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function edit_form_can_load_terminal_with_knowledge_bases()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
$kb2 = KnowledgeBase::create(['name' => '知识库2', 'status' => 'active']);
|
||||
|
||||
// 关联知识库
|
||||
$terminal->knowledgeBases()->attach([
|
||||
$kb1->id => ['priority' => 5],
|
||||
$kb2->id => ['priority' => 10],
|
||||
]);
|
||||
|
||||
// 测试编辑表单可以加载
|
||||
$component = Livewire::test(TerminalResource\Pages\EditTerminal::class, [
|
||||
'record' => $terminal->getRouteKey(),
|
||||
]);
|
||||
|
||||
// 验证表单可以渲染
|
||||
$component->assertSuccessful();
|
||||
|
||||
// 验证基本信息加载正确
|
||||
$component->assertFormSet([
|
||||
'name' => $terminal->name,
|
||||
'code' => $terminal->code,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_knowledge_base_associations_can_be_updated()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
$kb2 = KnowledgeBase::create(['name' => '知识库2', 'status' => 'active']);
|
||||
$kb3 = KnowledgeBase::create(['name' => '知识库3', 'status' => 'active']);
|
||||
|
||||
// 初始关联
|
||||
$terminal->knowledgeBases()->attach($kb1->id, ['priority' => 1]);
|
||||
|
||||
// 更新关联(移除旧的,添加新的)
|
||||
$terminal->knowledgeBases()->sync([
|
||||
$kb2->id => ['priority' => 5],
|
||||
$kb3->id => ['priority' => 10],
|
||||
]);
|
||||
|
||||
// 验证更新后的关联
|
||||
$terminal->refresh();
|
||||
$this->assertCount(2, $terminal->knowledgeBases);
|
||||
$this->assertFalse($terminal->knowledgeBases->contains($kb1));
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb2));
|
||||
$this->assertTrue($terminal->knowledgeBases->contains($kb3));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_remove_all_knowledge_base_associations()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
|
||||
// 初始关联
|
||||
$terminal->knowledgeBases()->attach($kb1->id, ['priority' => 1]);
|
||||
$this->assertCount(1, $terminal->knowledgeBases);
|
||||
|
||||
// 移除所有关联
|
||||
$terminal->knowledgeBases()->detach();
|
||||
|
||||
// 验证所有关联已移除
|
||||
$terminal->refresh();
|
||||
$this->assertCount(0, $terminal->knowledgeBases);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function knowledge_bases_are_ordered_by_priority_in_form()
|
||||
{
|
||||
// 创建终端和知识库
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$kb1 = KnowledgeBase::create(['name' => '知识库1', 'status' => 'active']);
|
||||
$kb2 = KnowledgeBase::create(['name' => '知识库2', 'status' => 'active']);
|
||||
$kb3 = KnowledgeBase::create(['name' => '知识库3', 'status' => 'active']);
|
||||
|
||||
// 按不同优先级关联
|
||||
$terminal->knowledgeBases()->attach([
|
||||
$kb1->id => ['priority' => 10],
|
||||
$kb2->id => ['priority' => 5],
|
||||
$kb3->id => ['priority' => 1],
|
||||
]);
|
||||
|
||||
// 重新加载并验证排序
|
||||
$terminal->refresh();
|
||||
$orderedKbs = $terminal->knowledgeBases;
|
||||
|
||||
$this->assertEquals($kb3->id, $orderedKbs[0]->id); // priority 1
|
||||
$this->assertEquals($kb2->id, $orderedKbs[1]->id); // priority 5
|
||||
$this->assertEquals($kb1->id, $orderedKbs[2]->id); // priority 10
|
||||
}
|
||||
}
|
||||
98
tests/Feature/TerminalPromptFormTest.php
Normal file
98
tests/Feature/TerminalPromptFormTest.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Filament\Resources\TerminalResource;
|
||||
use App\Models\Terminal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TerminalPromptFormTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->create();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_be_created_with_prompt()
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$terminalData = [
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-001',
|
||||
'ip_address' => '192.168.1.100',
|
||||
'station_id' => 1,
|
||||
'prompt' => [
|
||||
'prompt_template' => '你是一个智能助手,当前用户是 {user}。',
|
||||
],
|
||||
];
|
||||
|
||||
Livewire::test(TerminalResource\Pages\CreateTerminal::class)
|
||||
->fillForm($terminalData)
|
||||
->call('create')
|
||||
->assertHasNoFormErrors();
|
||||
|
||||
$this->assertDatabaseHas('terminals', [
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-001',
|
||||
]);
|
||||
|
||||
$terminal = Terminal::where('code', 'TEST-001')->first();
|
||||
$this->assertNotNull($terminal->prompt);
|
||||
$this->assertEquals('你是一个智能助手,当前用户是 {user}。', $terminal->prompt->prompt_template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_prompt_can_be_updated()
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$terminal = Terminal::factory()->create();
|
||||
$terminal->prompt()->create([
|
||||
'prompt_template' => '旧的提示词',
|
||||
'variables' => [],
|
||||
]);
|
||||
|
||||
$newPromptData = [
|
||||
'name' => $terminal->name,
|
||||
'code' => $terminal->code,
|
||||
'prompt' => [
|
||||
'prompt_template' => '新的提示词模板',
|
||||
],
|
||||
];
|
||||
|
||||
Livewire::test(TerminalResource\Pages\EditTerminal::class, ['record' => $terminal->id])
|
||||
->fillForm($newPromptData)
|
||||
->call('save')
|
||||
->assertHasNoFormErrors();
|
||||
|
||||
$terminal->refresh();
|
||||
$this->assertEquals('新的提示词模板', $terminal->prompt->prompt_template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function edit_form_loads_existing_prompt()
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$terminal = Terminal::factory()->create();
|
||||
$terminal->prompt()->create([
|
||||
'prompt_template' => '现有的提示词',
|
||||
'variables' => ['user'],
|
||||
]);
|
||||
|
||||
Livewire::test(TerminalResource\Pages\EditTerminal::class, ['record' => $terminal->id])
|
||||
->assertFormSet([
|
||||
'prompt.prompt_template' => '现有的提示词',
|
||||
]);
|
||||
}
|
||||
}
|
||||
118
tests/Feature/TerminalPromptTest.php
Normal file
118
tests/Feature/TerminalPromptTest.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Terminal;
|
||||
use App\Models\TerminalPrompt;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TerminalPromptTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->create();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function terminal_can_have_prompt()
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$prompt = TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
'prompt_template' => '你是一个智能助手,当前用户是 {user}。',
|
||||
'variables' => ['user', 'station', 'time'],
|
||||
]);
|
||||
|
||||
$this->assertInstanceOf(TerminalPrompt::class, $terminal->prompt);
|
||||
$this->assertEquals($prompt->id, $terminal->prompt->id);
|
||||
$this->assertEquals('你是一个智能助手,当前用户是 {user}。', $terminal->prompt->prompt_template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function prompt_belongs_to_terminal()
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$prompt = TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
'prompt_template' => '测试提示词',
|
||||
'variables' => [],
|
||||
]);
|
||||
|
||||
$this->assertInstanceOf(Terminal::class, $prompt->terminal);
|
||||
$this->assertEquals($terminal->id, $prompt->terminal->id);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function prompt_variables_are_cast_to_array()
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$prompt = TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
'prompt_template' => '测试提示词',
|
||||
'variables' => ['user', 'station', 'time'],
|
||||
]);
|
||||
|
||||
$this->assertIsArray($prompt->variables);
|
||||
$this->assertEquals(['user', 'station', 'time'], $prompt->variables);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function deleting_terminal_deletes_prompt()
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$prompt = TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
'prompt_template' => '测试提示词',
|
||||
'variables' => [],
|
||||
]);
|
||||
|
||||
$promptId = $prompt->id;
|
||||
|
||||
// 使用forceDelete来真正删除记录,触发级联删除
|
||||
$terminal->forceDelete();
|
||||
|
||||
$this->assertDatabaseMissing('terminal_prompts', ['id' => $promptId]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function prompt_template_can_be_empty()
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$prompt = TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
'prompt_template' => '',
|
||||
'variables' => [],
|
||||
]);
|
||||
|
||||
$this->assertEquals('', $prompt->prompt_template);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function prompt_logs_activity()
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$prompt = TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
'prompt_template' => '测试提示词',
|
||||
'variables' => [],
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('activity_log', [
|
||||
'subject_type' => TerminalPrompt::class,
|
||||
'subject_id' => $prompt->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
273
tests/Feature/TerminalResourceTest.php
Normal file
273
tests/Feature/TerminalResourceTest.php
Normal file
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Filament\Resources\TerminalResource;
|
||||
use App\Filament\Resources\TerminalResource\Pages\CreateTerminal;
|
||||
use App\Filament\Resources\TerminalResource\Pages\EditTerminal;
|
||||
use App\Filament\Resources\TerminalResource\Pages\ListTerminals;
|
||||
use App\Models\Terminal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TerminalResourceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// 创建测试用户并赋予管理员权限
|
||||
$this->user = User::factory()->create();
|
||||
|
||||
// 设置为Filament管理员
|
||||
config(['filament.auth.guard' => 'web']);
|
||||
|
||||
$this->actingAs($this->user);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_render_terminal_list_page(): void
|
||||
{
|
||||
Livewire::test(ListTerminals::class)
|
||||
->assertSuccessful();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_list_terminals(): void
|
||||
{
|
||||
$terminals = Terminal::factory()->count(10)->create();
|
||||
|
||||
Livewire::test(ListTerminals::class)
|
||||
->assertCanSeeTableRecords($terminals);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_render_create_page(): void
|
||||
{
|
||||
Livewire::test(CreateTerminal::class)
|
||||
->assertSuccessful();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_create_terminal(): void
|
||||
{
|
||||
$newData = [
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-0001',
|
||||
'ip_address' => '192.168.1.100',
|
||||
'station_id' => 1,
|
||||
'diagram_url' => 'https://example.com/diagram.png',
|
||||
'display_config' => [
|
||||
'resolution' => '1920x1080',
|
||||
'refresh_rate' => '60',
|
||||
],
|
||||
];
|
||||
|
||||
Livewire::test(CreateTerminal::class)
|
||||
->fillForm($newData)
|
||||
->call('create')
|
||||
->assertHasNoFormErrors();
|
||||
|
||||
$this->assertDatabaseHas('terminals', [
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-0001',
|
||||
'ip_address' => '192.168.1.100',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_validates_required_fields_on_create(): void
|
||||
{
|
||||
Livewire::test(CreateTerminal::class)
|
||||
->fillForm([
|
||||
'name' => '',
|
||||
'code' => '',
|
||||
])
|
||||
->call('create')
|
||||
->assertHasFormErrors([
|
||||
'name' => 'required',
|
||||
'code' => 'required',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_validates_unique_code(): void
|
||||
{
|
||||
$existingTerminal = Terminal::factory()->create([
|
||||
'code' => 'EXISTING-001',
|
||||
]);
|
||||
|
||||
Livewire::test(CreateTerminal::class)
|
||||
->fillForm([
|
||||
'name' => '新终端',
|
||||
'code' => 'EXISTING-001',
|
||||
])
|
||||
->call('create')
|
||||
->assertHasFormErrors(['code' => 'unique']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_validates_ip_address_format(): void
|
||||
{
|
||||
Livewire::test(CreateTerminal::class)
|
||||
->fillForm([
|
||||
'name' => '测试终端',
|
||||
'code' => 'TEST-0001',
|
||||
'ip_address' => 'invalid-ip',
|
||||
])
|
||||
->call('create')
|
||||
->assertHasFormErrors(['ip_address' => 'ip']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_validates_code_format(): void
|
||||
{
|
||||
Livewire::test(CreateTerminal::class)
|
||||
->fillForm([
|
||||
'name' => '测试终端',
|
||||
'code' => 'invalid code with spaces',
|
||||
])
|
||||
->call('create')
|
||||
->assertHasFormErrors(['code' => 'regex']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_render_edit_page(): void
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
Livewire::test(EditTerminal::class, ['record' => $terminal->getRouteKey()])
|
||||
->assertSuccessful();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_retrieve_data_for_edit(): void
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
Livewire::test(EditTerminal::class, ['record' => $terminal->getRouteKey()])
|
||||
->assertFormSet([
|
||||
'name' => $terminal->name,
|
||||
'code' => $terminal->code,
|
||||
'ip_address' => $terminal->ip_address,
|
||||
'station_id' => $terminal->station_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_update_terminal(): void
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
$newData = [
|
||||
'name' => '更新后的终端',
|
||||
'code' => $terminal->code,
|
||||
'ip_address' => '192.168.1.200',
|
||||
'station_id' => 2,
|
||||
];
|
||||
|
||||
Livewire::test(EditTerminal::class, ['record' => $terminal->getRouteKey()])
|
||||
->fillForm($newData)
|
||||
->call('save')
|
||||
->assertHasNoFormErrors();
|
||||
|
||||
$this->assertDatabaseHas('terminals', [
|
||||
'id' => $terminal->id,
|
||||
'name' => '更新后的终端',
|
||||
'ip_address' => '192.168.1.200',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_delete_terminal(): void
|
||||
{
|
||||
$terminal = Terminal::factory()->create();
|
||||
|
||||
Livewire::test(EditTerminal::class, ['record' => $terminal->getRouteKey()])
|
||||
->callAction('delete');
|
||||
|
||||
$this->assertSoftDeleted('terminals', [
|
||||
'id' => $terminal->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_filter_by_online_status(): void
|
||||
{
|
||||
$onlineTerminals = Terminal::factory()->count(3)->online()->create();
|
||||
$offlineTerminals = Terminal::factory()->count(2)->offline()->create();
|
||||
|
||||
Livewire::test(ListTerminals::class)
|
||||
->filterTable('is_online', true)
|
||||
->assertCanSeeTableRecords($onlineTerminals)
|
||||
->assertCanNotSeeTableRecords($offlineTerminals);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_search_terminals(): void
|
||||
{
|
||||
$terminal1 = Terminal::factory()->create(['name' => '生产线A-工位1']);
|
||||
$terminal2 = Terminal::factory()->create(['name' => '质检站-工位2']);
|
||||
|
||||
Livewire::test(ListTerminals::class)
|
||||
->searchTable('生产线A')
|
||||
->assertCanSeeTableRecords([$terminal1])
|
||||
->assertCanNotSeeTableRecords([$terminal2]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_sort_terminals(): void
|
||||
{
|
||||
$terminals = Terminal::factory()->count(3)->create();
|
||||
|
||||
Livewire::test(ListTerminals::class)
|
||||
->sortTable('name')
|
||||
->assertCanSeeTableRecords($terminals->sortBy('name'), inOrder: true);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_displays_online_status_badge(): void
|
||||
{
|
||||
$onlineTerminal = Terminal::factory()->online()->create();
|
||||
$offlineTerminal = Terminal::factory()->offline()->create();
|
||||
|
||||
Livewire::test(ListTerminals::class)
|
||||
->assertTableColumnStateSet('is_online', true, $onlineTerminal)
|
||||
->assertTableColumnStateSet('is_online', false, $offlineTerminal);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_group_by_station(): void
|
||||
{
|
||||
Terminal::factory()->count(3)->create(['station_id' => 1]);
|
||||
Terminal::factory()->count(2)->create(['station_id' => 2]);
|
||||
|
||||
// 测试分组功能是否可用
|
||||
$component = Livewire::test(ListTerminals::class);
|
||||
|
||||
// 验证表格可以正常渲染
|
||||
$component->assertSuccessful();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_bulk_delete_terminals(): void
|
||||
{
|
||||
$terminals = Terminal::factory()->count(3)->create();
|
||||
|
||||
Livewire::test(ListTerminals::class)
|
||||
->callTableBulkAction('delete', $terminals)
|
||||
->assertSuccessful();
|
||||
|
||||
foreach ($terminals as $terminal) {
|
||||
$this->assertSoftDeleted('terminals', [
|
||||
'id' => $terminal->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
280
tests/Feature/TerminalSyncTest.php
Normal file
280
tests/Feature/TerminalSyncTest.php
Normal file
@@ -0,0 +1,280 @@
|
||||
<?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.png',
|
||||
'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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user