更新
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use app\adminapi\logic\firstvisit\FirstVisitConversionLogic;
|
||||
use app\adminapi\logic\stats\ConversionLogic;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
function conversionFanDetailExpect(bool $condition, string $message): void
|
||||
{
|
||||
if (!$condition) {
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
$firstVisitReflection = new ReflectionClass(FirstVisitConversionLogic::class);
|
||||
|
||||
$conversionSource = file_get_contents((new ReflectionClass(ConversionLogic::class))->getFileName());
|
||||
conversionFanDetailExpect(is_string($conversionSource), 'Unable to read ConversionLogic source');
|
||||
$buildDetailRows = (new ReflectionClass(ConversionLogic::class))->getMethod('buildFanDetailRows');
|
||||
$buildDetailRows->setAccessible(true);
|
||||
$detailRows = $buildDetailRows->invoke(null, [
|
||||
['user_id' => 'staff-a', 'external_userid' => 'readded', 'add_time' => 100],
|
||||
['user_id' => 'staff-a', 'external_userid' => 'readded', 'add_time' => 200],
|
||||
['user_id' => 'staff-b', 'external_userid' => 'deleted', 'add_time' => 300],
|
||||
], [
|
||||
['user_id' => 'staff-a', 'external_userid' => 'readded', 'add_time' => 200],
|
||||
]);
|
||||
conversionFanDetailExpect(
|
||||
count($detailRows) === 2
|
||||
&& (int) ($detailRows[0]['add_time'] ?? 0) === 100
|
||||
&& empty($detailRows[0]['is_deleted'])
|
||||
&& !empty($detailRows[1]['is_deleted']),
|
||||
'Delete/re-add details must retain the first counted add time and final deletion state'
|
||||
);
|
||||
conversionFanDetailExpect(
|
||||
str_contains($conversionSource, 'self::loadFanDetailRows($startTimestamp, $endTimestamp, $mediaChannel, $adminIds)')
|
||||
&& str_contains($conversionSource, 'MIN(e.event_time) AS add_time')
|
||||
&& str_contains($conversionSource, "->where('e.event_time', 'between', [\$startTimestamp, \$endTimestamp])")
|
||||
&& str_contains($conversionSource, 'EXISTS (SELECT 1 FROM `')
|
||||
&& str_contains($conversionSource, 'MAX(event_time) AS delete_time'),
|
||||
'Aggregate and detail results must share the same distinct fan-pair loader and expose event times'
|
||||
);
|
||||
conversionFanDetailExpect(
|
||||
str_contains($conversionSource, "'external_userid' => \$externalUserId")
|
||||
&& str_contains($conversionSource, "'customer_name'")
|
||||
&& str_contains($conversionSource, "'wecom_staff_name'")
|
||||
&& str_contains($conversionSource, "'is_deleted'")
|
||||
&& str_contains($conversionSource, "'delete_time'"),
|
||||
'Fan detail response must expose customer, employee, add and deletion fields'
|
||||
);
|
||||
|
||||
$firstVisitSource = file_get_contents($firstVisitReflection->getFileName());
|
||||
conversionFanDetailExpect(
|
||||
is_string($firstVisitSource)
|
||||
&& !str_contains($firstVisitSource, '$dashboard = self::overview($params, $adminId, $adminInfo);')
|
||||
&& str_contains($firstVisitSource, 'resolveFanDetailEntity(')
|
||||
&& str_contains($firstVisitSource, 'resolveFanDetailMemberDeptId(')
|
||||
&& str_contains($firstVisitSource, "['channel_dept_ids']")
|
||||
&& str_contains($firstVisitSource, "preg_match('/^M([1-9]\\d*)_(-?\\d+)$/', \$entityId")
|
||||
&& str_contains($firstVisitSource, "MediaChannelService::getCurrentTagChannelByCode"),
|
||||
'Fan detail must authorize the exact structural entity without recomputing overview and retain current-tag channel scope'
|
||||
);
|
||||
conversionFanDetailExpect(
|
||||
str_contains($conversionSource, '$targetWorkWechatUserIds')
|
||||
&& str_contains($conversionSource, 'fanDetailChannelDeptIds($mediaChannel)')
|
||||
&& str_contains($conversionSource, 'filterEntitiesByChannelDeptScope(')
|
||||
&& str_contains($conversionSource, 'NOT EXISTS (SELECT 1 FROM `')
|
||||
&& str_contains($conversionSource, "':wecom:'")
|
||||
&& str_contains($conversionSource, '$matched = $pairs;'),
|
||||
'Fan detail must narrow the event query to the clicked employees/WeCom user before sorting and pagination'
|
||||
);
|
||||
|
||||
$controllerSource = file_get_contents(dirname(__DIR__) . '/app/adminapi/controller/firstvisit/ConversionController.php');
|
||||
conversionFanDetailExpect(
|
||||
is_string($controllerSource)
|
||||
&& str_contains($controllerSource, 'public function fansDetail()')
|
||||
&& str_contains($controllerSource, 'FirstVisitConversionLogic::fansDetail('),
|
||||
'First-visit conversion controller must expose the fansDetail endpoint'
|
||||
);
|
||||
|
||||
echo "FirstVisitConversionFanDetailTest passed\n";
|
||||
Reference in New Issue
Block a user