From dfdd7a67e6a0524a6259181f70247bbf621b59e9 Mon Sep 17 00:00:00 2001 From: jing <1683105490@qq.com> Date: Wed, 28 Oct 2026 09:09:39 +0800 Subject: [PATCH] =?UTF-8?q?chore=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/card-mini-code-scene.test.js | 127 ----------------------------- 1 file changed, 127 deletions(-) delete mode 100644 tests/card-mini-code-scene.test.js diff --git a/tests/card-mini-code-scene.test.js b/tests/card-mini-code-scene.test.js deleted file mode 100644 index 3edf114..0000000 --- a/tests/card-mini-code-scene.test.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * 名片小程序码 · scene 解析契约测试(2.21) - * - * 背景: - * 微信 getwxacodeunlimit 的 scene 只有 32 可见字符, 装不下业务 card_id - * (形如 c_1_shop_20261013111612_9588EA, 30 字符; 加前缀更长), - * 故 scene 里放的是名片**主键 id**(数字): "id=448"。 - * - * 扫码进入小程序后, 微信把 scene 放在 options.scene(整体 encodeURIComponent - * 过), 小程序端需: - * ① decodeURIComponent(options.scene) - * ② 解析出主键 id - * ③ 用 id 向后端换业务 card_id(后端 /card/api/diy/card 支持 id 寻址) - * - * 覆盖: - * 1. scene 解析: "id=448" / 裸 "448" / URL 编码形态 - * 2. 常规入口(query 带 card_id)不受影响 - * 3. 解析不出时走「缺少名片编号」提示(不得白屏) - * 4. 换 card_id 走公开读接口且带 id 参数 - * 5. 反例: 不得把 scene 当 card_id 直接用(会查不到名片) - * - * 跑法: node --test tests/card-mini-code-scene.test.js - */ - -'use strict'; - -const test = require('node:test'); -const assert = require('node:assert/strict'); -const fs = require('fs'); -const path = require('path'); - -const PAGE = path.resolve(__dirname, '../pages_tool/card/detail.vue'); -const src = fs.readFileSync(PAGE, 'utf8'); -// 先剥注释再断言 —— 注释里写「绝不能写 X」会被自判违规 -const strip = s => s.replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, ''); - -const body = strip(src); - -// ================================================================ -// 1. scene 解析 -// ================================================================ -test('scene 解析: 从 options.scene 取名片主键 id', () => { - assert.match(body, /pickSceneRelId\s*\(\s*options\s*\)/); - // 必须先 decodeURIComponent(微信对 scene 整体做过编码) - assert.match(body, /decodeURIComponent\(opt\.scene\)/); - // 解析 "id=xxx" 形态 - assert.match(body, /kv\[0\]\s*===\s*'id'/); -}); - -test('scene 解析: 兼容裸 id(无前缀)', () => { - // 无 "=" 时整体当 id - assert.match(body, /let val = scene;/); - assert.match(body, /String\(val\)\.replace\(\/\[\^0-9\]\/g, ''\)/); -}); - -test('scene 解析: 只取数字(防脏值/防注入)', () => { - assert.match(body, /replace\(\/\[\^0-9\]\/g, ''\)/); - assert.match(body, /parseInt\(val, 10\)/); -}); - -test('scene 解析: 取不到时返回 0', () => { - assert.match(body, /return val \? parseInt\(val, 10\) : 0;/); -}); - -// ================================================================ -// 2. 常规入口不受影响 -// ================================================================ -test('常规入口: query 带 card_id 时直接使用', () => { - assert.match(body, /pickDirectCardId\s*\(\s*options\s*\)/); - assert.match(body, /if \(opt\.card_id\)/); - assert.match(body, /decodeURIComponent\(opt\.card_id\)/); -}); - -test('onLoad: 常规入口直连, scene 入口走换卡流程', () => { - assert.match(body, /const directId = this\.pickDirectCardId\(options\);/); - assert.match(body, /const sceneId = this\.pickSceneRelId\(options\);/); - assert.match(body, /if \(directId\)\s*\{[\s\S]*?this\.cardId = directId;/); - assert.match(body, /else if \(sceneId\)\s*\{\s*this\.resolveCardIdByRelId\(sceneId\);/); -}); - -// ================================================================ -// 3. 换 card_id -// ================================================================ -test('换 card_id: 走公开读接口且带 id 参数', () => { - assert.match(body, /resolveCardIdByRelId\s*\(\s*relId\s*\)\s*\{/); - assert.match(body, /url:\s*'\/card\/api\/diy\/card'/); - assert.match(body, /data:\s*\{\s*id:\s*relId\s*\}/); -}); - -test('换 card_id: 从返回里取业务 card_id', () => { - assert.match(body, /res\.data && res\.data\.card/); - assert.match(body, /card\.card_id/); - assert.match(body, /this\.cardId = bizId;/); -}); - -test('换 card_id: 失败时给明确提示(不白屏)', () => { - assert.match(body, /errorMsg = '名片不存在或已被删除'/); - assert.match(body, /errorMsg = '网络异常,请稍后重试'/); -}); - -test('换 card_id: 成功后继续加载详情', () => { - assert.match(body, /this\.cardId = bizId;[\s\S]*?this\.loadDetail\(\);/); -}); - -// ================================================================ -// 4. 缺少名片编号的兜底 -// ================================================================ -test('既无 card_id 也无 scene: 提示「缺少名片编号」', () => { - assert.match(body, /this\.errorMsg = '缺少名片编号';/); -}); - -// ================================================================ -// 5. 反例(防恒真 / 防走偏) -// ================================================================ -test('反例: 不得把 scene 整体当 card_id 直接用', () => { - // 若把 scene 当 card_id 传, 后端按业务 card_id 查不到 → 必然查不到名片 - assert.doesNotMatch(body, /this\.cardId = decodeURIComponent\(opt\.scene\)/); - assert.doesNotMatch(body, /card_id:\s*decodeURIComponent\(opt\.scene\)/); -}); - -test('反例: 不得用 card_id= 前缀解析 scene(scene 用 id= 前缀)', () => { - assert.doesNotMatch(body, /kv\[0\]\s*===\s*'card_id'/); -}); - -test('反例: 不得硬编码名片 id', () => { - assert.doesNotMatch(body, /card_id:\s*['"]\d+['"]/); -});