const assert = require("assert"); const fs = require("fs"); const path = require("path"); const vm = require("vm"); const root = path.resolve(__dirname, ".."); const authSource = fs.readFileSync(path.join(root, "utils", "AuthPageUtil.js"), "utf8"); const configSource = fs.readFileSync(path.join(root, "config.js"), "utf8"); const login = fs.readFileSync(path.join(root, "html", "login.html"), "utf8"); const register = fs.readFileSync(path.join(root, "html", "reg.html"), "utf8"); const usercenter = fs.readFileSync(path.join(root, "html", "usercenter.html"), "utf8"); const promo = fs.readFileSync(path.join(root, "html", "tuiguang.html"), "utf8"); const distribution = fs.readFileSync(path.join(root, "html", "fenxiao.html"), "utf8"); const resetPassword = fs.readFileSync(path.join(root, "html", "repwd.html"), "utf8"); [login, register, resetPassword].forEach(function (page) { Array.from(page.matchAll(/]*)?>([\s\S]*?)<\/script>/gi), function (match) { return match[1]; }).filter(Boolean).forEach(function (source) { new Function(source); }); }); const context = { URLSearchParams, window: { location: { search: "?inviteCode=invite-001" } } }; vm.runInNewContext(`${authSource}\nthis.AuthPageUtilForTest = AuthPageUtil;`, context); assert.strictEqual(context.AuthPageUtilForTest.getReferralInviteCodeFromUrl(), "invite-001"); assert.strictEqual(context.AuthPageUtilForTest.getReferralInviteCodeFromUrl("?referralCode=legacy"), ""); assert(register.includes('type="hidden" id="inviteCode" name="inviteCode"')); assert(register.includes('$("#inviteCode").val(AuthPageUtil.getReferralInviteCodeFromUrl());')); assert(register.includes('const inviteCode = $("#inviteCode").val().trim();')); assert(register.includes("registerData.inviteCode = inviteCode"), "registration must send a non-empty inviteCode"); assert(register.includes('$("#captchaGroup").hide();'), "registration verification must hide after SMS is sent"); assert(register.includes('$("#captchaGroup").show();'), "registration verification must return after the phone changes"); assert(/currentVerifyType === "slide"[\s\S]*?renderSlideCaptchaEntry\(\);[\s\S]*?#captchaGroup"\)\.hide\(\)/.test(register), "slide mode must not render an inline verification row"); assert(!login.includes("bindPendingReferralInviteCode"), "login must not bind referrals automatically"); assert(!register.includes("bindPendingReferralInviteCode"), "registration success must not issue a second bind request"); assert(usercenter.includes("ApiClient.API.referralBind, { inviteCode: inviteCode }"), "user center must provide manual binding"); assert(promo.includes("NavigationUtil.referralRegisterUrl"), "promotion page must normalize returned links to registration"); assert(login.includes('id="captchaGroup" style="display: none"')); assert(login.includes('$("#captchaGroup").show();')); assert(resetPassword.includes('id="captchaGroup" style="display: none"')); assert(resetPassword.includes('$("#captchaGroup").hide();')); assert(resetPassword.includes('$("#captchaGroup").show();')); [register].forEach(function (page) { assert(page.includes('id="captchaGroup" style="visibility: hidden"')); assert(page.includes('$("#captchaGroup").css("visibility", "visible");')); }); const configContext = { URL, MutationObserver: function () {}, location: { hostname: "example.com", port: "", href: "https://example.com/html/index.html?inviteCode=invite-001" }, document: { readyState: "loading", addEventListener() {} }, window: { location: { href: "https://example.com/html/index.html?inviteCode=invite-001" }, open() { return null; } }, }; vm.runInNewContext(configSource, configContext); assert.strictEqual( configContext.window.NavigationUtil.referralRegisterUrl("https://example.com/app?inviteCode=invite-001"), "https://example.com/html/reg.html?inviteCode=invite-001", ); assert(!distribution.includes("applyDistribution"), "the obsolete empty bind entry must be removed"); context.ApiClient = { API: { authVerifyConfig: "/api/web/auth/verify-config" }, get() { return Promise.reject(new Error("network unavailable")); }, }; context.AuthPageUtilForTest.loadVerifyType().then(function (type) { assert.strictEqual(type, "slide", "verify-config failure must not show image captcha"); console.log("referral register contract checks passed"); }).catch(function (error) { console.error(error); process.exitCode = 1; });