100 lines
5.4 KiB
PHP
100 lines
5.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
// Render real templates without invoking controllers or production services.
|
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
|
$root = dirname(__DIR__) . '/';
|
|
$app = new think\App($root);
|
|
$app->initialize();
|
|
$app->http->name('home');
|
|
$app->lang->load($root . 'app/home/lang/zh-cn.php');
|
|
$template = new think\Template([
|
|
'view_path' => $root . 'app/home/view/',
|
|
'cache_path' => $root . 'runtime/homepage-test/',
|
|
'tpl_cache' => false,
|
|
]);
|
|
$vars = [
|
|
'seo' => ['title' => 'EVUS 中文登记服务', 'description' => '首页本地预览', 'keywords' => 'EVUS'],
|
|
'logo_icon' => '', 'asset_version' => 'preview', 'menu_url' => 'index/index',
|
|
'footer' => '', 'phone' => '', 'base_path' => '/evus',
|
|
];
|
|
foreach ([[], [['id' => 7, 'title' => '<script>alert(1)</script>', 'create_time' => '2026-10-29']]] as $news) {
|
|
ob_start();
|
|
$template->fetch('index/index', $vars + ['data' => $news]);
|
|
$html = ob_get_clean();
|
|
preg_match('~<header\b.*?</header>~s', $html, $header);
|
|
$homepageNavigation = str_replace('aria-current="page"', '', $header[0]);
|
|
preg_match_all('~<nav\b[^>]*>(.*?)</nav>~s', $header[0], $menus);
|
|
preg_match_all('~href="([^"]+)"~', $menus[1][0], $desktopLinks);
|
|
preg_match_all('~href="([^"]+)"~', $menus[1][1], $mobileLinks);
|
|
$desktopLinks[1][] = (string) url('home/user/order');
|
|
if (count($mobileLinks[1]) !== 8 || $desktopLinks[1] !== $mobileLinks[1]) {
|
|
throw new RuntimeException('Homepage desktop and mobile menus must share all eight entries in order');
|
|
}
|
|
if (str_contains($html, 'https://visa.evus.cn')) {
|
|
throw new RuntimeException('Unfinished US visa website must not be linked from the homepage');
|
|
}
|
|
if (substr_count($html, 'src="/static/home/images/logo_113.png"') !== 2 || !str_contains($html, 'href="/static/home/images/evus-icon.png"')) {
|
|
throw new RuntimeException('Original EVUS logo and default site icon must render');
|
|
}
|
|
foreach (['home/detail/index', 'home/lookup/index', 'home/esta/index', 'home/news/index', 'home/user/order'] as $route) {
|
|
if (!str_contains(strtolower($html), strtolower((string) url($route)))) {
|
|
throw new RuntimeException('Missing existing route: ' . $route);
|
|
}
|
|
}
|
|
if (str_contains($html, '<script>alert(1)</script>')) {
|
|
throw new RuntimeException('News titles must be escaped');
|
|
}
|
|
if (!str_contains($html, '<main') || !str_contains($html, '<summary')) {
|
|
throw new RuntimeException('Homepage needs a main landmark and keyboard-accessible FAQ');
|
|
}
|
|
if (!str_contains($html, '独立') || !str_contains($html, '政府')) {
|
|
throw new RuntimeException('Commercial service disclosure must remain visible');
|
|
}
|
|
if (!str_contains($html, '<details class="ac-mobile-menu">') || !str_contains($html, 'aria-label="手机导航"')) {
|
|
throw new RuntimeException('Mobile navigation needs a closed native disclosure');
|
|
}
|
|
if (!str_contains($html, '济南经纬九州出入境服务有限公司') || !str_contains($html, '鲁ICP备18006241号-8') || !str_contains($html, 'https://beian.miit.gov.cn/')) {
|
|
throw new RuntimeException('Original company and filing link must render without backend footer data');
|
|
}
|
|
if (!$news) {
|
|
file_put_contents($root . 'runtime/homepage-preview.html', $html);
|
|
} else {
|
|
file_put_contents($root . 'runtime/homepage-news-preview.html', $html);
|
|
}
|
|
}
|
|
ob_start();
|
|
$template->fetch('index/index', array_replace($vars, ['footer' => '<p>Configured company footer</p>', 'logo_icon' => '/configured-icon.png', 'data' => []]));
|
|
$configuredHtml = ob_get_clean();
|
|
if (!str_contains($configuredHtml, '<p>Configured company footer</p>') || str_contains($configuredHtml, '鲁ICP备18006241号-8')) {
|
|
throw new RuntimeException('Configured footer must take precedence without duplicate company details');
|
|
}
|
|
if (!str_contains($configuredHtml, 'href="/configured-icon.png"')) {
|
|
throw new RuntimeException('Configured site icon must retain precedence');
|
|
}
|
|
ob_start();
|
|
$template->fetch('index/screen', []);
|
|
$screenHtml = ob_get_clean();
|
|
if (!str_contains($screenHtml, 'href="' . url('home/detail/index') . '"')) {
|
|
throw new RuntimeException('Display page must link to the current EVUS registration route');
|
|
}
|
|
foreach (['detail/index' => 'detail/index', 'lookup/index' => 'lookup/index', 'news/detail' => 'news/index', 'esta/index' => 'esta/index', 'user/order_esta' => 'user/order'] as $current => $active) {
|
|
ob_start();
|
|
$template->fetch('public/home_menu', array_replace($vars, ['menu_url' => $current]));
|
|
$navigation = ob_get_clean();
|
|
preg_match('~<header\b.*?</header>~s', $navigation, $innerHeader);
|
|
if (str_replace('aria-current="page"', '', $innerHeader[0]) !== $homepageNavigation) {
|
|
throw new RuntimeException('Homepage and inner navigation must match apart from the active page');
|
|
}
|
|
$activeLink = 'href="' . url('home/' . $active) . '" aria-current="page"';
|
|
if (substr_count($navigation, $activeLink) !== 2) {
|
|
throw new RuntimeException('Desktop and mobile navigation must highlight: ' . $current);
|
|
}
|
|
foreach ([(string) url('home/esta/index'), 'class="ac-mobile-menu"', 'id="ac-mobile-menu-dismiss"'] as $required) {
|
|
if (!str_contains($navigation, $required)) {
|
|
throw new RuntimeException('Shared navigation must retain: ' . $required);
|
|
}
|
|
}
|
|
}
|
|
echo "PASS: homepage, shared navigation active states, legacy routes, menu, escaping and footer\n";
|