You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
szkp-map-service/tests/Unit/StudyTourDeclarationExporte...

128 lines
4.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace Tests\Unit;
use App\Support\StudyTourDeclarationExporter;
use PhpOffice\PhpWord\IOFactory;
use Tests\TestCase;
use ZipArchive;
class StudyTourDeclarationExporterTest extends TestCase
{
public function test_html_to_plain_text_keeps_paragraphs(): void
{
$html = '<p>第一段</p><p>第二段<br/>续行</p><ul><li>要点A</li><li>要点B</li></ul>';
$text = StudyTourDeclarationExporter::htmlToPlainText($html);
$this->assertStringContainsString("第一段", $text);
$this->assertStringContainsString("第二段", $text);
$this->assertStringContainsString("续行", $text);
$this->assertStringContainsString("要点A", $text);
$this->assertStringContainsString("要点B", $text);
}
public function test_sanitize_filename_strips_illegal_chars(): void
{
$this->assertSame('线路A_B', StudyTourDeclarationExporter::sanitizeFilename('线路A/B'));
$this->assertSame('研学线路', StudyTourDeclarationExporter::sanitizeFilename(' '));
}
public function test_docx_contains_declaration_sections_and_cover_image(): void
{
$png = sys_get_temp_dir().'/st-cover-test.png';
file_put_contents($png, base64_decode(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=='
));
$uploadDir = storage_path('app/public/uploads');
if (! is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
$implPng = $uploadDir.'/st-impl-test.png';
copy($png, $implPng);
$path = StudyTourDeclarationExporter::writeDocxFile([
'name' => '太湖蚕桑研学',
'org_name' => '苏州市科协',
'seasons' => ['spring', 'autumn'],
'venue_names' => ['苏州丝绸博物馆', '自定义营地'],
'suitable_count' => '30人',
'suitable_audience' => 'primaryjunior',
'duration' => '2天1晚',
'contact_person' => '张老师',
'contact_phones' => '13800000000',
'cover_image_path' => $png,
'intro_html' => '<p>走进蚕桑文化。</p>',
'route_plans' => [[
'date_label' => '第一天',
'items' => [[
'time' => '09:00',
'activity' => '开营仪式',
'location' => '活动中心',
]],
]],
'courses' => [[
'sort' => 1,
'name' => '缫丝体验',
'content' => '了解传统缫丝工艺',
]],
'fee_html' => '<p>680元/人</p>',
'implementation_html' => '<p>2026年7月1日第1场</p><p><img src="/storage/uploads/st-impl-test.png"></p>',
'season_options' => [
['value' => 'spring', 'label' => '春季'],
['value' => 'summer', 'label' => '夏季'],
['value' => 'autumn', 'label' => '秋季'],
['value' => 'winter', 'label' => '冬季'],
],
'audience_options' => [
['value' => 'kindergarten', 'label' => '幼儿园'],
['value' => 'primary', 'label' => '小学'],
['value' => 'junior', 'label' => '初中'],
['value' => 'high', 'label' => '高中'],
['value' => 'all', 'label' => '全学段'],
],
]);
$this->assertFileExists($path);
$zip = new ZipArchive();
$this->assertTrue($zip->open($path) === true);
$xml = (string) $zip->getFromName('word/document.xml');
$mediaCount = 0;
for ($i = 0; $i < $zip->numFiles; $i++) {
$name = (string) $zip->getNameIndex($i);
if (str_starts_with($name, 'word/media/')) {
$mediaCount++;
}
}
$zip->close();
foreach ([
'一、线路基本情况',
'二、线路简介',
'三、线路规划',
'四、研学课程',
'五、线路收费标准',
'六、线路计划实施情况',
'太湖蚕桑研学',
'苏州市科协',
'苏州丝绸博物馆',
'走进蚕桑文化',
'开营仪式',
'缫丝体验',
'680元/人',
'封面图',
'2026年7月1日第1场',
] as $needle) {
$this->assertStringContainsString($needle, $xml, "missing {$needle}");
}
$this->assertGreaterThanOrEqual(2, $mediaCount, 'cover and implementation images should be embedded');
$phpWord = IOFactory::load($path);
$this->assertNotEmpty($phpWord->getSections());
@unlink($path);
@unlink($png);
@unlink($implPng);
}
}