Files
xuetang/server/tests/CurrentTagChannelProjectionTest.php
2026-09-08 11:40:15 +08:00

167 lines
6.7 KiB
PHP

<?php
declare(strict_types=1);
use app\adminapi\logic\qywx\CustomerLogic;
use app\common\service\qywx\MediaChannelService;
require dirname(__DIR__) . '/vendor/autoload.php';
$mergeMethod = new ReflectionMethod(MediaChannelService::class, 'mergeCurrentTagsWithConfiguredChannels');
$mergeMethod->setAccessible(true);
$catalog = [
['tag_id' => 'tag-a', 'tag_name' => '最新标签 A', 'group_name' => '当前分组', 'customer_count' => 12],
['tag_id' => 'tag-disabled', 'tag_name' => '当前仍在用', 'group_name' => '当前分组', 'customer_count' => 8],
['tag_id' => 'tag-new', 'tag_name' => '新发现标签', 'group_name' => '其它', 'customer_count' => 3],
];
$configured = [
[
'id' => 1,
'channel_code' => 'stable-a',
'channel_name' => '人工渠道名',
'source_tag_id' => 'tag-a',
'source_tag_name' => '旧标签 A',
'source_group_name' => '旧分组',
'status' => 1,
],
[
'id' => 2,
'channel_code' => 'stable-disabled',
'channel_name' => '停用时名称',
'source_tag_id' => 'tag-disabled',
'source_tag_name' => '停用时名称',
'source_group_name' => '旧分组',
'status' => 0,
],
[
'id' => 3,
'channel_code' => 'legacy-name-only',
'channel_name' => '历史个人标签',
'source_tag_id' => '',
'source_tag_name' => '历史个人标签',
'source_group_name' => '历史',
'status' => 1,
],
];
/** @var array<int, array<string, mixed>> $rows */
$rows = $mergeMethod->invoke(null, $catalog, $configured);
if (count($rows) !== count($catalog)) {
throw new RuntimeException('Current-tag projection leaked a historical channel or lost a current tag');
}
$byTagId = [];
foreach ($rows as $row) {
$byTagId[(string) ($row['source_tag_id'] ?? '')] = $row;
}
$renamed = $byTagId['tag-a'] ?? null;
if (!is_array($renamed)
|| ($renamed['channel_code'] ?? '') !== 'stable-a'
|| ($renamed['channel_name'] ?? '') !== '最新标签 A'
|| ($renamed['source_tag_name'] ?? '') !== '最新标签 A'
|| ($renamed['source_group_name'] ?? '') !== '当前分组'
|| ($renamed['customer_count'] ?? 0) !== 12
|| ($renamed['legacy_channel_name'] ?? '') !== '人工渠道名'
|| ($renamed['legacy_source_tag_name'] ?? '') !== '旧标签 A') {
throw new RuntimeException('Current tag metadata did not override historical display metadata safely');
}
$disabled = $byTagId['tag-disabled'] ?? null;
if (!is_array($disabled)
|| ($disabled['channel_code'] ?? '') !== 'stable-disabled'
|| ($disabled['channel_name'] ?? '') !== '当前仍在用'
|| ($disabled['status'] ?? 0) !== 1) {
throw new RuntimeException('A current WeCom tag was hidden by historical registry status');
}
$newTag = $byTagId['tag-new'] ?? null;
if (!is_array($newTag)
|| ($newTag['channel_code'] ?? '') !== 'tag_tag-new'
|| ($newTag['channel_name'] ?? '') !== '新发现标签') {
throw new RuntimeException('A current unregistered tag did not receive its deterministic channel code');
}
if (isset($byTagId['']) || in_array('legacy-name-only', array_column($rows, 'channel_code'), true)) {
throw new RuntimeException('Historical name-only channels must not appear in the current-tag projection');
}
if (in_array('--integration', $argv, true)) {
$app = new think\App();
$app->initialize();
$startedAt = microtime(true);
$currentCatalog = MediaChannelService::getCurrentTagCatalog();
$catalogElapsedMs = round((microtime(true) - $startedAt) * 1000, 1);
$optionsStartedAt = microtime(true);
$currentOptions = MediaChannelService::getCurrentTagOptions();
$optionsElapsedMs = round((microtime(true) - $optionsStartedAt) * 1000, 1);
$statsStartedAt = microtime(true);
$tagStats = CustomerLogic::getTagStats();
$statsElapsedMs = round((microtime(true) - $statsStartedAt) * 1000, 1);
$elapsedMs = round((microtime(true) - $startedAt) * 1000, 1);
$catalogById = [];
foreach ($currentCatalog as $tag) {
$catalogById[(string) ($tag['tag_id'] ?? '')] = $tag;
}
$statsById = [];
foreach ($tagStats['groups'] ?? [] as $group) {
foreach ($group['tags'] ?? [] as $tag) {
$statsById[(string) ($tag['tag_id'] ?? '')] = [
'tag_name' => (string) ($tag['tag_name'] ?? ''),
'group_name' => (string) ($group['group_name'] ?? ''),
'customer_count' => (int) ($tag['customer_count'] ?? 0),
];
}
}
if (count($catalogById) !== count($currentCatalog)
|| count($currentOptions) !== count($currentCatalog)
|| count($statsById) !== count($currentCatalog)) {
throw new RuntimeException('Current catalog, qywx tag stats, and first-visit options are not one-to-one');
}
foreach ($currentOptions as $option) {
$tagId = (string) ($option['tag_id'] ?? '');
$catalogTag = $catalogById[$tagId] ?? null;
if (!is_array($catalogTag)
|| ($option['name'] ?? '') !== ($catalogTag['tag_name'] ?? '')
|| ($option['group_name'] ?? '') !== ($catalogTag['group_name'] ?? '')
|| ($option['customer_count'] ?? 0) !== ($catalogTag['customer_count'] ?? 0)
|| MediaChannelService::getCurrentTagChannelByCode((string) ($option['code'] ?? '')) === null) {
throw new RuntimeException("First-visit option {$tagId} differs from the current qywx tag catalog");
}
}
foreach ($catalogById as $tagId => $catalogTag) {
$statsTag = $statsById[$tagId] ?? null;
if (!is_array($statsTag)
|| $statsTag['tag_name'] !== (string) ($catalogTag['tag_name'] ?? '')
|| $statsTag['group_name'] !== (string) ($catalogTag['group_name'] ?? '')
|| $statsTag['customer_count'] !== (int) ($catalogTag['customer_count'] ?? 0)) {
throw new RuntimeException("Qywx tag stats {$tagId} differs from the shared current catalog");
}
}
echo json_encode([
'current_tag_count' => count($currentCatalog),
'first_visit_option_count' => count($currentOptions),
'qywx_tag_count' => count($statsById),
'matching_4' => array_values(array_map(
static fn (array $option): string => (string) ($option['name'] ?? ''),
array_filter(
$currentOptions,
static fn (array $option): bool => mb_strpos((string) ($option['name'] ?? ''), '4') !== false
)
)),
'catalog_ms' => $catalogElapsedMs,
'options_ms' => $optionsElapsedMs,
'qywx_stats_ms' => $statsElapsedMs,
'elapsed_ms' => $elapsedMs,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
}
echo "CURRENT_TAG_CHANNEL_PROJECTION_OK\n";