'use strict'; /** * 「卡密管理」分页契约。 * * 背景(两次演进): * 1) 翻页链接此前写作 add_query_arg('paged', N) —— 只有两个参数时 WordPress 会落到 * $_SERVER['REQUEST_URI'],链接绑在当前请求上,随请求形态漂移,列条件也容易丢。 * 2) render_pagenavi() 的 URL 推导是一串 if/elseif。页码越界时(例如 per_page 缩小后 * URL 里还留着 paged=2,而总数只剩 1 页)三个分支一个都不命中,上一页/下一页 * 同时停在 '#':按钮既不打 disabled 也点不动,还停在「第 1 页」状态无法自洽。 * 极端情况下 offset 落到数据之外,表格直接变空态并且连分页条都不输出,只能手改 URL 退出。 * 3) ice_perpage 只在服务端被读取、默认每页条数偏大。条数小于默认值时永远只有一页, * 四个按钮恒为 disabled —— 看上去就是「分页是坏的」。 * * 现状:渲染已迁移到共享助手 AdminListPagination,四按钮标记由助手统一输出 * (与这里原来那套逐行一致),基准 URL 与页码夹取也都在那里做。 * 本文件只固化卡密管理仍特有的部分: * - ice_perpage 仍作为 URL 参数被尊重,且工具栏不新增「每页显示」控件; * - 越界页码回退到最后一页并重查,不留空态死胡同; * - 筛选参数白名单化拼装,排序与每页条数随链接带走。 */ const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const root = path.resolve(__dirname, '..', '..'); const page = fs.readFileSync(path.join(root, 'src/Admin/Native/PayChargeCards.php'), 'utf8'); const count = (src, pattern) => (src.match(pattern) || []).length; const slice = (from, to) => { const start = page.indexOf(from); const end = page.indexOf(to); if (start === -1 || end === -1 || end <= start) { throw new Error(`切片失败:${from} → ${to}`); } return page.slice(start, end); }; const list = slice('private function render_list(', 'private function render_add_form('); const args = slice('private function list_query_args(', 'private function print_assets('); test('渲染已迁移到共享助手 AdminListPagination', () => { assert.match( list, /AdminListPagination::render\(self::PAGE_SLUG, \$count_all, \$paged, \$per_page, \$query_args\);/ ); // 自定义标记与专属常量都应清空。 assert.doesNotMatch(page, /render_pagenavi/); assert.doesNotMatch(page, /first-page button|prev-page button|next-page button|last-page button/); assert.doesNotMatch(page, /public const DEFAULT_PER_PAGE/); assert.doesNotMatch(page, /self::DEFAULT_PER_PAGE/); assert.match(page, /AdminListPagination::DEFAULT_PER_PAGE/); // 只服务自定义禁用按钮的 CSS 规则已随标记一起搬进助手。 assert.doesNotMatch(page, /\.tablenav-pages a\.disabled \{ pointer-events: none; \}/); }); test('ice_perpage 仍作为 URL 参数被尊重,默认每页 20', () => { assert.match( list, /\(int\) \(\$_REQUEST\['ice_perpage'\] \?\? AdminListPagination::DEFAULT_PER_PAGE\)/ ); // 明确约定:不在列表工具栏增加「每页显示」下拉/按钮。 assert.doesNotMatch(page, /per_page_selector/); assert.doesNotMatch(page, /PER_PAGE_CHOICES/); assert.doesNotMatch(page, /aksrt-perpage-form/); assert.doesNotMatch(page, /name="ice_perpage"/); assert.doesNotMatch(page, /order-header-right/); // 但 ice_perpage 仍随链接带走(无界面入口,供 URL / 程序化调用)。 assert.match(args, /\$args\['ice_perpage'\] =/); // 工具栏保持「过滤链接 + 搜索表单」两段式。 assert.match(list, /echo '