- 创建 SopTemplateTest 测试文件(13个测试) - 测试模板 CRUD 操作 - 测试步骤管理和排序 - 测试交互任务关联 - 测试状态转换 - 测试版本快照 - 测试活动日志 - 测试筛选和软删除 - 创建 SopTemplateServiceTest 测试文件(12个测试) - 测试 JSON 导出导入 - 测试发布和归档 - 测试版本管理 - 测试模板复制 - 测试数据验证 所有 25 个测试通过
247 lines
6.9 KiB
PHP
247 lines
6.9 KiB
PHP
<?php
|
|
|
|
use App\Models\SopTemplate;
|
|
use App\Models\User;
|
|
use App\Services\SopTemplateService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$this->user = User::factory()->create();
|
|
$this->actingAs($this->user);
|
|
$this->service = new SopTemplateService();
|
|
});
|
|
|
|
test('可以导出模板为 JSON', function () {
|
|
$template = SopTemplate::factory()->create([
|
|
'name' => '测试模板',
|
|
'version' => '1.0.0',
|
|
]);
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'content' => '内容',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$json = $this->service->exportToJson($template);
|
|
$data = json_decode($json, true);
|
|
|
|
expect($data)->toHaveKey('template')
|
|
->and($data)->toHaveKey('steps')
|
|
->and($data['template']['name'])->toBe('测试模板')
|
|
->and($data['steps'])->toHaveCount(1);
|
|
});
|
|
|
|
test('导出的 JSON 包含步骤信息', function () {
|
|
$template = SopTemplate::factory()->create();
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'content' => '<p>这是内容</p>',
|
|
'sort_order' => 1,
|
|
'is_required' => true,
|
|
]);
|
|
|
|
$json = $this->service->exportToJson($template);
|
|
$data = json_decode($json, true);
|
|
|
|
expect($data['steps'][0])->toHaveKey('step_number')
|
|
->and($data['steps'][0])->toHaveKey('title')
|
|
->and($data['steps'][0])->toHaveKey('content')
|
|
->and($data['steps'][0]['title'])->toBe('第一步');
|
|
});
|
|
|
|
test('可以从 JSON 导入模板', function () {
|
|
$jsonData = [
|
|
'template' => [
|
|
'name' => '导入的模板',
|
|
'description' => '这是描述',
|
|
'category' => '测试分类',
|
|
'version' => '1.0.0',
|
|
],
|
|
'steps' => [
|
|
[
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'content' => '内容',
|
|
'sort_order' => 1,
|
|
'is_required' => true,
|
|
],
|
|
],
|
|
];
|
|
|
|
$json = json_encode($jsonData);
|
|
$template = $this->service->importFromJson($json);
|
|
|
|
expect($template)->toBeInstanceOf(SopTemplate::class)
|
|
->and($template->name)->toBe('导入的模板')
|
|
->and($template->status)->toBe('draft')
|
|
->and($template->steps)->toHaveCount(1);
|
|
});
|
|
|
|
test('导入时会创建步骤', function () {
|
|
$jsonData = [
|
|
'template' => [
|
|
'name' => '测试模板',
|
|
'version' => '1.0.0',
|
|
],
|
|
'steps' => [
|
|
[
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'sort_order' => 1,
|
|
],
|
|
[
|
|
'step_number' => 2,
|
|
'title' => '第二步',
|
|
'sort_order' => 2,
|
|
],
|
|
],
|
|
];
|
|
|
|
$json = json_encode($jsonData);
|
|
$template = $this->service->importFromJson($json);
|
|
|
|
expect($template->steps)->toHaveCount(2)
|
|
->and($template->steps->first()->title)->toBe('第一步')
|
|
->and($template->steps->last()->title)->toBe('第二步');
|
|
});
|
|
|
|
test('导入无效 JSON 会抛出异常', function () {
|
|
$invalidJson = 'invalid json';
|
|
|
|
$this->service->importFromJson($invalidJson);
|
|
})->throws(\Illuminate\Validation\ValidationException::class);
|
|
|
|
test('导入缺少必需字段会抛出异常', function () {
|
|
$jsonData = [
|
|
'template' => [
|
|
'name' => '测试模板',
|
|
// 缺少 version
|
|
],
|
|
'steps' => [],
|
|
];
|
|
|
|
$json = json_encode($jsonData);
|
|
|
|
$this->service->importFromJson($json);
|
|
})->throws(\Illuminate\Validation\ValidationException::class);
|
|
|
|
test('可以发布模板', function () {
|
|
$template = SopTemplate::factory()->create([
|
|
'status' => 'draft',
|
|
]);
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$this->service->publish($template, '首次发布');
|
|
|
|
expect($template->fresh()->status)->toBe('published')
|
|
->and($template->fresh()->published_at)->not->toBeNull()
|
|
->and($template->versions)->toHaveCount(1);
|
|
});
|
|
|
|
test('发布时会创建版本快照', function () {
|
|
$template = SopTemplate::factory()->create([
|
|
'status' => 'draft',
|
|
'version' => '1.0.0',
|
|
]);
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$this->service->publish($template, '测试发布');
|
|
|
|
$version = $template->versions->first();
|
|
|
|
expect($version)->not->toBeNull()
|
|
->and($version->version)->toBe('1.0.0')
|
|
->and($version->change_log)->toBe('测试发布')
|
|
->and($version->content_snapshot)->toHaveKey('template')
|
|
->and($version->content_snapshot)->toHaveKey('steps');
|
|
});
|
|
|
|
test('可以归档模板', function () {
|
|
$template = SopTemplate::factory()->create([
|
|
'status' => 'published',
|
|
]);
|
|
|
|
$this->service->archive($template);
|
|
|
|
expect($template->fresh()->status)->toBe('archived');
|
|
});
|
|
|
|
test('可以复制模板', function () {
|
|
$template = SopTemplate::factory()->create([
|
|
'name' => '原始模板',
|
|
]);
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$newTemplate = $this->service->duplicate($template, '复制的模板');
|
|
|
|
expect($newTemplate->name)->toBe('复制的模板')
|
|
->and($newTemplate->status)->toBe('draft')
|
|
->and($newTemplate->steps)->toHaveCount(1)
|
|
->and($newTemplate->id)->not->toBe($template->id);
|
|
});
|
|
|
|
test('复制模板时会复制所有步骤', function () {
|
|
$template = SopTemplate::factory()->create();
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$template->steps()->create([
|
|
'step_number' => 2,
|
|
'title' => '第二步',
|
|
'sort_order' => 2,
|
|
]);
|
|
|
|
$newTemplate = $this->service->duplicate($template, '复制的模板');
|
|
|
|
expect($newTemplate->steps)->toHaveCount(2)
|
|
->and($newTemplate->steps->first()->title)->toBe('第一步')
|
|
->and($newTemplate->steps->last()->title)->toBe('第二步');
|
|
});
|
|
|
|
test('复制模板时会复制交互任务', function () {
|
|
$template = SopTemplate::factory()->create();
|
|
|
|
$step = $template->steps()->create([
|
|
'step_number' => 1,
|
|
'title' => '第一步',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$step->interactiveTasks()->create([
|
|
'task_type' => 'confirm',
|
|
'task_config' => ['message' => '确认?'],
|
|
'is_required' => true,
|
|
]);
|
|
|
|
$newTemplate = $this->service->duplicate($template, '复制的模板');
|
|
$newStep = $newTemplate->steps->first();
|
|
|
|
expect($newStep->interactiveTasks)->toHaveCount(1)
|
|
->and($newStep->interactiveTasks->first()->task_type)->toBe('confirm');
|
|
});
|