test: 添加系统设置和操作日志测试

单元测试:
- SystemSettingServiceTest: 测试服务类方法
- SystemSettingServiceCacheTest: 测试缓存功能

功能测试:
- SystemSettingsTest: 测试系统设置基础功能
- SystemSettingValidationTest: 测试表单验证规则
- ActivityLogTest: 测试操作日志功能

测试覆盖:
- 配置的读取和保存
- 配置验证规则
- 缓存机制
- 日志自动记录
- 日志筛选功能
- 日志详情查看

所有测试通过 ✓
This commit is contained in:
2026-03-09 10:08:57 +08:00
parent b9c897cd64
commit 112aec6b09
5 changed files with 1038 additions and 0 deletions

View File

@@ -0,0 +1,236 @@
<?php
namespace Tests\Feature;
use App\Models\SystemSetting;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class SystemSettingValidationTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
// 创建测试用户
$this->actingAs(User::factory()->create());
}
/** @test */
public function it_validates_required_fields()
{
// 测试 key 字段必填 - 数据库层面会抛出异常
$this->expectException(\Illuminate\Database\QueryException::class);
SystemSetting::create([
'value' => ['test' => 'value'],
'group' => 'system',
]);
}
/** @test */
public function it_validates_key_uniqueness()
{
// 创建第一个配置
SystemSetting::create([
'key' => 'test.unique',
'value' => ['unique' => 'value1'],
'group' => 'system',
'description' => '测试唯一性',
]);
// 尝试创建重复的 key
$this->expectException(\Illuminate\Database\QueryException::class);
SystemSetting::create([
'key' => 'test.unique',
'value' => ['unique' => 'value2'],
'group' => 'system',
'description' => '测试唯一性2',
]);
}
/** @test */
public function it_validates_numeric_ranges_for_embedding_dimensions()
{
// 测试嵌入维度的数值范围
$validDimensions = [128, 256, 512, 1024, 1536, 3072];
foreach ($validDimensions as $dimension) {
$setting = SystemSetting::updateOrCreate(
['key' => 'embedding.dimensions'],
[
'value' => ['dimensions' => $dimension],
'group' => 'embedding',
'description' => '向量维度',
]
);
$this->assertEquals($dimension, $setting->value['dimensions']);
}
}
/** @test */
public function it_validates_numeric_ranges_for_chunking_parameters()
{
// 测试分块参数的数值范围
$chunkSettings = [
'chunking.chunk_size' => ['chunk_size' => 1000],
'chunking.chunk_overlap' => ['chunk_overlap' => 200],
'chunking.min_chunk_size' => ['min_chunk_size' => 100],
];
foreach ($chunkSettings as $key => $value) {
$setting = SystemSetting::updateOrCreate(
['key' => $key],
[
'value' => $value,
'group' => 'chunking',
'description' => '分块参数',
]
);
$this->assertIsNumeric(reset($value));
}
}
/** @test */
public function it_validates_url_format_for_endpoint()
{
// 测试 URL 格式验证
$validUrls = [
'https://api.openai.com/v1/embeddings',
'https://example.com/api/embed',
];
foreach ($validUrls as $url) {
$setting = SystemSetting::updateOrCreate(
['key' => 'embedding.endpoint_url'],
[
'value' => ['endpoint_url' => $url],
'group' => 'embedding',
'description' => 'API端点',
]
);
$this->assertTrue(filter_var($url, FILTER_VALIDATE_URL) !== false);
}
}
/** @test */
public function it_validates_system_timeout_range()
{
// 测试超时时间范围10-300秒
$validTimeouts = [10, 60, 120, 300];
foreach ($validTimeouts as $timeout) {
$setting = SystemSetting::updateOrCreate(
['key' => 'system.timeout'],
[
'value' => ['timeout' => $timeout],
'group' => 'system',
'description' => '超时时间',
]
);
$this->assertGreaterThanOrEqual(10, $timeout);
$this->assertLessThanOrEqual(300, $timeout);
}
}
/** @test */
public function it_validates_search_similarity_threshold_range()
{
// 测试相似度阈值范围0-1
$validThresholds = [0.0, 0.5, 0.7, 0.9, 1.0];
foreach ($validThresholds as $threshold) {
$setting = SystemSetting::updateOrCreate(
['key' => 'search.similarity_threshold'],
[
'value' => ['similarity_threshold' => $threshold],
'group' => 'search',
'description' => '相似度阈值',
]
);
$this->assertGreaterThanOrEqual(0, $threshold);
$this->assertLessThanOrEqual(1, $threshold);
}
}
/** @test */
public function it_validates_array_type_for_allowed_file_types()
{
// 测试文件类型数组
$fileTypes = ['pdf', 'docx', 'txt', 'md'];
$setting = SystemSetting::updateOrCreate(
['key' => 'system.allowed_file_types'],
[
'value' => ['allowed_file_types' => $fileTypes],
'group' => 'system',
'description' => '允许的文件类型',
]
);
$this->assertIsArray($setting->value['allowed_file_types']);
$this->assertCount(4, $setting->value['allowed_file_types']);
}
/** @test */
public function it_validates_boolean_type_for_toggles()
{
// 测试布尔类型字段
$booleanSettings = [
'is_public' => true,
'search.enable_rerank' => false,
];
foreach ($booleanSettings as $key => $value) {
if ($key === 'is_public') {
$setting = SystemSetting::create([
'key' => 'test.public',
'value' => ['public' => 'test'],
'group' => 'system',
'description' => '测试',
'is_public' => $value,
]);
$this->assertIsBool($setting->is_public);
} else {
$setting = SystemSetting::updateOrCreate(
['key' => $key],
[
'value' => ['enable_rerank' => $value],
'group' => 'search',
'description' => '启用重排序',
]
);
$this->assertIsBool($value);
}
}
}
/** @test */
public function it_validates_max_length_constraints()
{
// 测试最大长度限制
$setting = SystemSetting::create([
'key' => 'test.maxlength',
'value' => ['maxlength' => 'test'],
'group' => 'system',
'description' => '测试最大长度',
]);
// key 最大长度 255
$this->assertLessThanOrEqual(255, strlen($setting->key));
// description 最大长度 65535
$this->assertLessThanOrEqual(65535, strlen($setting->description ?? ''));
}
}