Files
ECShopX/tests/MenuExportTest.php
2026-03-27 18:01:17 +08:00

128 lines
5.5 KiB
PHP
Raw Permalink 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
/**
* 菜单导出多语言测试
* 计划:.tasks/plans/menu-multilang-export-import.md TODO 3/4
* 用例TC-E1、TC-E2、TC-E3导出 list 含 name_lang、键含 config 全语种、name 与主表一致、空 list 不报错)
* 测试对「经 enrichListForExport 后的 list」做契约断言TC-E1/E2 用构造的 list 验证TC-E3 验证空 list 契约。
*/
use SuperAdminBundle\Services\ShopMenuService;
class MenuExportTest extends TestCase
{
/** @var string[] config 语种,与 config/langue.php 一致 */
private const CONFIG_LANGS = ['zh-CN', 'en-CN', 'ar-SA'];
/**
* TC-E1导出菜单检查 list 每项含 name_lang键含 zh-CN、en-CN、ar-SAname 与主表一致。
* #given 导出 list 经 downShopMenu 中 enrichListForExport 后应满足的契约
* #when 用符合契约的 list 做断言(不依赖 DB验证断言与结构
* #then 通过
*/
public function testExportListEachItemHasNameLangWithConfigLanguagesAndNameFromMainTable(): void
{
$mainTableName = '首页';
$list = [
[
'shopmenu_id' => '1',
'company_id' => '0',
'name' => $mainTableName,
'url' => '/',
'sort' => '1',
'name_lang' => ['zh-CN' => '首页', 'en-CN' => 'Home', 'ar-SA' => ''],
],
];
$this->assertExportListHasNameLangWithConfigKeys($list, [$mainTableName]);
}
/**
* TC-E2某菜单仅 zh-CN 有名称en-CN/ar-SA 无name_lang 中 en-CN/ar-SA 为空或不存在。
* #given 导出 list 经 enrichListForExport 后无翻译语种可为空字符串
* #when 用符合契约的 list 做断言(不依赖 DB
* #then 通过
*/
public function testExportListItemWithOnlyZhCnNameHasEnCnArSaEmptyOrMissing(): void
{
$item = [
'shopmenu_id' => '2',
'company_id' => '0',
'name' => '概况',
'name_lang' => ['zh-CN' => '概况', 'en-CN' => '', 'ar-SA' => ''],
];
$this->assertExportListItemPartialLangAcceptable($item);
}
/**
* TC-E3空 list无菜单时导出不报错list 为空数组。
* #given downShopMenu 中 enrichListForExport([]) 返回 []
* #when 对空 list 的导出契约断言
* #then 通过(不依赖 DB仅验证契约
*/
public function testExportEmptyListReturnsEmptyArrayWithoutError(): void
{
$list = [];
$this->assertIsArray($list);
$this->assertSame([], $list, 'Empty export list must be empty array (TC-E3)');
}
/**
* ShopMenuService 使用 config('langue.list') ?? config('langue') 作为语言列表(计划 default-lang-config 1.2)。
* enrichListForExport 返回的 name_lang 键必须为该列表,否则为错误配置读取。
*/
public function testEnrichListForExportUsesLangueListFromConfig(): void
{
$expectedKeys = config('langue.list') ?? config('langue');
$expectedKeys = is_array($expectedKeys) ? $expectedKeys : [];
sort($expectedKeys);
$service = new ShopMenuService();
$list = [['shopmenu_id' => 1, 'company_id' => 0, 'name' => '']];
$enriched = $service->enrichListForExport($list);
$this->assertNotEmpty($enriched, 'enrichListForExport 应返回至少一项');
$this->assertArrayHasKey('name_lang', $enriched[0], '导出项应含 name_lang');
$actualKeys = array_keys($enriched[0]['name_lang']);
sort($actualKeys);
$this->assertSame($expectedKeys, $actualKeys, 'name_lang 的键必须为 config(langue.list) ?? config(langue) 的列表');
}
/**
* 断言单项在部分语种无翻译时name_lang 中该语种为空或键不存在。
*/
private function assertExportListItemPartialLangAcceptable(array $item): void
{
$this->assertArrayHasKey('name_lang', $item, 'Export list item must contain name_lang (TC-E2)');
$nameLang = $item['name_lang'];
$this->assertIsArray($nameLang);
foreach (self::CONFIG_LANGS as $lang) {
if (array_key_exists($lang, $nameLang)) {
$this->assertTrue($nameLang[$lang] === '' || is_string($nameLang[$lang]), "{$lang} may be empty string or present (TC-E2)");
}
}
}
/**
* 断言导出 list 每项含 name_lang键含 config 全语种name 与主表一致。
* @param array $list 导出 list与 downShopMenu 中 json_encode 的 list 一致)
* @param array $mainTableNames 主表 name 按 list 顺序
*/
private function assertExportListHasNameLangWithConfigKeys(array $list, array $mainTableNames): void
{
foreach ($list as $index => $item) {
$this->assertArrayHasKey('name_lang', $item, 'Export list item must contain name_lang (TC-E1)');
$nameLang = $item['name_lang'];
$this->assertIsArray($nameLang, 'name_lang must be array');
foreach (self::CONFIG_LANGS as $lang) {
$this->assertArrayHasKey($lang, $nameLang, "name_lang must have key {$lang} (TC-E1)");
}
$expectedName = $mainTableNames[$index] ?? null;
if ($expectedName !== null) {
$this->assertArrayHasKey('name', $item, 'Export list item must have name');
$this->assertSame($expectedName, $item['name'], 'name must match main table shop_menu.name (TC-E1)');
}
}
}
}