- 删除未使用的 getActiveEnv 解构、sender 参数改为 _sender - types.ts 重命名为 types.d.ts,消除无用的 dist/types.js 产物 - 测试文件引用路径从根目录改为 dist/
114 lines
4.8 KiB
JavaScript
114 lines
4.8 KiB
JavaScript
// tests/utils.test.js
|
||
// 测试 utils.js 中的纯函数:isDomainMatch(URL 路径匹配)和 escapeHtml(HTML 转义)
|
||
// 运行:node --test tests/utils.test.js
|
||
|
||
const { describe, it } = require("node:test");
|
||
const assert = require("node:assert/strict");
|
||
const { isDomainMatch, escapeHtml } = require("../dist/utils.js");
|
||
|
||
describe("isDomainMatch - 纯 hostname 匹配", () => {
|
||
it("精确域名匹配", () => {
|
||
assert.equal(isDomainMatch("https://example.com/login", "example.com"), true);
|
||
assert.equal(isDomainMatch("https://example.com/", "example.com"), true);
|
||
assert.equal(isDomainMatch("https://other.com/", "example.com"), false);
|
||
});
|
||
|
||
it("子域名通配符 *.example.com", () => {
|
||
assert.equal(isDomainMatch("https://oa.example.com/", "*.example.com"), true);
|
||
assert.equal(isDomainMatch("https://a.b.example.com/", "*.example.com"), true);
|
||
assert.equal(isDomainMatch("https://example.com/", "*.example.com"), true); // 根域也匹配
|
||
assert.equal(isDomainMatch("https://notexample.com/", "*.example.com"), false);
|
||
});
|
||
|
||
it("任意位置通配符", () => {
|
||
assert.equal(isDomainMatch("https://api.dev.example.com/", "api.*.example.com"), true);
|
||
assert.equal(isDomainMatch("https://api.prod.example.com/", "api.*.example.com"), true);
|
||
assert.equal(isDomainMatch("https://web.dev.example.com/", "api.*.example.com"), false);
|
||
});
|
||
|
||
it("端口和协议不影响匹配", () => {
|
||
assert.equal(isDomainMatch("http://example.com:8080/path", "example.com"), true);
|
||
assert.equal(isDomainMatch("https://example.com:443/", "example.com"), true);
|
||
});
|
||
|
||
it("非法 URL 返回 false", () => {
|
||
assert.equal(isDomainMatch("not-a-url", "example.com"), false);
|
||
assert.equal(isDomainMatch("", "example.com"), false);
|
||
assert.equal(isDomainMatch("https://example.com/", ""), false);
|
||
});
|
||
});
|
||
|
||
describe("isDomainMatch - hostname + path 匹配", () => {
|
||
it("精确路径匹配", () => {
|
||
assert.equal(isDomainMatch("https://oa.com/login", "oa.com/login"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/admin/login", "oa.com/login"), false);
|
||
assert.equal(isDomainMatch("https://oa.com/", "oa.com/login"), false);
|
||
});
|
||
|
||
it("路径前缀通配 login/*", () => {
|
||
assert.equal(isDomainMatch("https://oa.com/login", "oa.com/login/*"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/login/step2", "oa.com/login/*"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/login/sub/deep", "oa.com/login/*"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/logins", "oa.com/login/*"), false);
|
||
assert.equal(isDomainMatch("https://oa.com/admin", "oa.com/login/*"), false);
|
||
});
|
||
|
||
it("路径全通配 *", () => {
|
||
assert.equal(isDomainMatch("https://oa.com/anything", "oa.com/*"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/", "oa.com/*"), true);
|
||
});
|
||
|
||
it("仅 hostname + 空路径匹配该域名所有页面", () => {
|
||
assert.equal(isDomainMatch("https://oa.com/any/path", "oa.com/"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/", "oa.com/"), true);
|
||
});
|
||
|
||
it("路径内任意位置通配", () => {
|
||
assert.equal(isDomainMatch("https://site.com/a/123/b", "site.com/a/*/b"), true);
|
||
assert.equal(isDomainMatch("https://site.com/a/xyz/b", "site.com/a/*/b"), true);
|
||
assert.equal(isDomainMatch("https://site.com/a/123/c", "site.com/a/*/b"), false);
|
||
});
|
||
|
||
it("path 匹配与子域名通配组合", () => {
|
||
assert.equal(isDomainMatch("https://api.dev.com/login", "*.dev.com/login"), true);
|
||
assert.equal(isDomainMatch("https://web.dev.com/admin", "*.dev.com/login"), false);
|
||
assert.equal(isDomainMatch("https://api.dev.com/login/step2", "*.dev.com/login/*"), true);
|
||
});
|
||
|
||
it("带 query 和 hash 的 URL 不影响 path 匹配", () => {
|
||
assert.equal(isDomainMatch("https://oa.com/login?next=/home", "oa.com/login"), true);
|
||
assert.equal(isDomainMatch("https://oa.com/login#section", "oa.com/login"), true);
|
||
});
|
||
});
|
||
|
||
describe("escapeHtml", () => {
|
||
it("转义 5 个特殊字符", () => {
|
||
assert.equal(escapeHtml("<"), "<");
|
||
assert.equal(escapeHtml(">"), ">");
|
||
assert.equal(escapeHtml('"'), """);
|
||
assert.equal(escapeHtml("'"), "'");
|
||
assert.equal(escapeHtml("&"), "&");
|
||
});
|
||
|
||
it("组合转义", () => {
|
||
assert.equal(
|
||
escapeHtml('<a href="x" onclick="alert(\'hi\')">text & more</a>'),
|
||
"<a href="x" onclick="alert('hi')">text & more</a>"
|
||
);
|
||
});
|
||
|
||
it("null 和 undefined 返回空串", () => {
|
||
assert.equal(escapeHtml(null), "");
|
||
assert.equal(escapeHtml(undefined), "");
|
||
});
|
||
|
||
it("数字会被转成字符串", () => {
|
||
assert.equal(escapeHtml(123), "123");
|
||
});
|
||
|
||
it("普通文本不变", () => {
|
||
assert.equal(escapeHtml("hello world"), "hello world");
|
||
assert.equal(escapeHtml("中文测试123"), "中文测试123");
|
||
});
|
||
});
|