"use strict"; const assert = require("assert"); const fs = require("fs"); const path = require("path"); const toDataModuleUrl = (source) => `data:text/javascript;base64,${Buffer.from(source).toString("base64")}`; const run = async () => { const rawSource = fs.readFileSync(path.join(__dirname, "../utils/api.js"), "utf8"); const moduleBody = rawSource.slice(rawSource.indexOf("const successCodes")); const prelude = ` const currentUser = {}; const genealogies = []; const publicGenealogies = []; const treeMembers = []; const notifications = []; const joinApplications = []; const listFamilyFeedFixtures = () => []; const listFamilyArticleFixtures = () => []; const listFamilyAlbumFixtures = () => []; const listCeremonyFixtures = () => []; const listGrowthRecordFixtures = () => []; const listNotificationFixtures = () => []; const runtimeConfig = { baseUrl: "https://backend-api.ddxcjp.cn", clientId: "client-1", tenantId: "000000" }; const hasRemoteConfig = () => true; const resolveRuntimeMode = () => "remote"; const AUTH_TAC_SCENE = Object.freeze({}); const assertSmsCode = (value) => value; const GENEALOGY_ACCESS_PRESET = Object.freeze({ MEMBER_ONLY: "MEMBER_ONLY" }); const fromApiGenealogyAccess = () => null; const session = { getToken: () => "session-1", saveToken() {} }; `; const requests = []; let response; globalThis.uni = { request(options) { requests.push(options); queueMicrotask(() => options.success(response)); return { abort() {} }; }, }; const { appApi } = await import(toDataModuleUrl(`${prelude}\n${moduleBody}`)); const profile = { userId: "101", tenantId: "000000", userNo: "U-101", phone: "13800138000", nickName: "家谱用户", realName: "王小明", avatar: 900001, sex: "男", birthday: "1990-01-02", email: "ming@example.com", registerSource: "APP", status: "0", }; response = { statusCode: 200, data: { code: 200, data: profile } }; assert.deepStrictEqual(await appApi.getProfile(), profile); const profileRequest = requests.at(-1); assert.strictEqual(profileRequest.url, "https://backend-api.ddxcjp.cn/genealogy/app/auth/profile"); assert.strictEqual(profileRequest.method, "GET"); assert.strictEqual(profileRequest.timeout, 15000); assert.deepStrictEqual(profileRequest.header, { clientid: "client-1", tenantId: "000000", Authorization: "Bearer session-1" }); const highPrecisionUserId = "9007199254740993"; response = { statusCode: 200, data: { code: 200, data: { ...profile, userId: highPrecisionUserId } } }; assert.strictEqual( (await appApi.getProfile()).userId, highPrecisionUserId, "业务用户 ID 必须保留为精确字符串,不能按头像数值转换", ); response = { statusCode: 200, data: { code: 200, data: profile } }; await appApi.updateProfile({ nickName: " 新昵称 ", realName: "王小明", avatar: 900001, sex: "女", birthday: "1991-02-03", email: "new@example.com", }); assert.deepStrictEqual(requests.at(-1).data, { nickName: "新昵称", realName: "王小明", avatar: 900001, sex: "女", birthday: "1991-02-03", email: "new@example.com", }); await assert.rejects(appApi.updateProfile({}), /至少需要一个/); await assert.rejects(appApi.updateProfile({ avatar: Number.MAX_SAFE_INTEGER + 1 }), /安全整数/); await assert.rejects(appApi.updateProfile({ birthday: "1991-02-03T00:00:00+08:00" }), /yyyy-MM-dd/); await assert.rejects(appApi.updateProfile({ email: "bad-email" }), /email/); response = { statusCode: 200, data: { code: 200, data: { ...profile, avatar: 0 } } }; assert.strictEqual((await appApi.getProfile()).avatar, null, "未设置头像的 0 必须归一为 null"); response = { statusCode: 200, data: { code: 200, data: { ...profile, avatar: -1 } } }; assert.strictEqual((await appApi.getProfile()).avatar, null, "未设置头像的负值哨兵必须归一为 null"); delete globalThis.uni; process.stdout.write("PROFILE-API-RUNTIME-SMOKE PASS\n"); }; run().catch((error) => { process.stderr.write(`${error.stack || error.message}\n`); process.exit(1); });