162 lines
5.0 KiB
JavaScript
162 lines
5.0 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
|
|
const root = path.join(__dirname, '..');
|
|
|
|
function response(data) {
|
|
return {
|
|
headers: { get: () => '' },
|
|
ok: true,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
text: () => Promise.resolve(JSON.stringify({ code: 'OK', data })),
|
|
};
|
|
}
|
|
|
|
function browser(search = '') {
|
|
const requests = [];
|
|
const attributes = new Map();
|
|
const storage = new Map();
|
|
const location = {
|
|
hash: '',
|
|
hostname: 'h5.global-interaction.com',
|
|
href: `https://h5.global-interaction.com/guild/fami/host-center/${search}`,
|
|
origin: 'https://h5.global-interaction.com',
|
|
pathname: '/guild/fami/host-center/',
|
|
search,
|
|
};
|
|
const window = {
|
|
atob: (value) => Buffer.from(value, 'base64').toString('binary'),
|
|
document: {
|
|
documentElement: {
|
|
setAttribute: (key, value) => attributes.set(key, value),
|
|
},
|
|
},
|
|
dispatchEvent: () => {},
|
|
fetch: (url, options = {}) => {
|
|
requests.push({ url, options });
|
|
return Promise.resolve(response({ ok: true }));
|
|
},
|
|
localStorage: {
|
|
getItem: (key) => storage.get(key) || null,
|
|
removeItem: (key) => storage.delete(key),
|
|
setItem: (key, value) => storage.set(key, String(value)),
|
|
},
|
|
location,
|
|
};
|
|
window.window = window;
|
|
window.URL = URL;
|
|
window.URLSearchParams = URLSearchParams;
|
|
const context = vm.createContext({
|
|
Buffer,
|
|
CustomEvent: function CustomEvent() {},
|
|
Date,
|
|
Error,
|
|
FormData,
|
|
JSON,
|
|
Math,
|
|
Number,
|
|
Object,
|
|
Promise,
|
|
String,
|
|
URL,
|
|
URLSearchParams,
|
|
console,
|
|
document: window.document,
|
|
window,
|
|
});
|
|
return { attributes, context, requests, window };
|
|
}
|
|
|
|
function runScript(context, relativePath) {
|
|
const source = fs.readFileSync(path.join(root, relativePath), 'utf8');
|
|
vm.runInContext(source, context, { filename: relativePath });
|
|
}
|
|
|
|
async function requestAppCode({ product, search = '' }) {
|
|
const harness = browser(search);
|
|
if (product) {
|
|
runScript(harness.context, 'guild/packages/core/product-context.js');
|
|
runScript(harness.context, `guild/products/${product}/product.js`);
|
|
}
|
|
runScript(harness.context, 'common/api.js');
|
|
await harness.window.HyAppAPI.get('/api/v1/test');
|
|
return {
|
|
harness,
|
|
appCode: harness.requests[0].options.headers['X-App-Code'],
|
|
};
|
|
}
|
|
|
|
async function main() {
|
|
const legacy = await requestAppCode({ product: '' });
|
|
assert.equal(legacy.appCode, 'lalu', 'legacy pages must stay on Lalu');
|
|
|
|
const fami = await requestAppCode({ product: 'fami' });
|
|
assert.equal(fami.appCode, 'fami', 'Fami page default must be isolated');
|
|
assert.equal(fami.harness.window.HyAppAPI.getAppCode(), 'fami');
|
|
assert.equal(fami.harness.attributes.get('data-hy-product'), 'fami');
|
|
|
|
const explicit = await requestAppCode({
|
|
product: 'fami',
|
|
search: '?app_code=lalu&env=test',
|
|
});
|
|
assert.equal(
|
|
explicit.appCode,
|
|
'lalu',
|
|
'explicit diagnostic tenant must win over the page default'
|
|
);
|
|
|
|
const contextHarness = browser('?token=secret&env=test&language=ar&page=8');
|
|
runScript(contextHarness.context, 'guild/packages/core/product-context.js');
|
|
runScript(contextHarness.context, 'guild/products/fami/product.js');
|
|
const linked = new URL(
|
|
contextHarness.window.HyGuild.product.buildURL('../wallet/', {
|
|
mode: 'usdt',
|
|
})
|
|
);
|
|
assert.equal(linked.searchParams.get('app_code'), 'fami');
|
|
assert.equal(linked.searchParams.get('token'), 'secret');
|
|
assert.equal(linked.searchParams.get('env'), 'test');
|
|
assert.equal(linked.searchParams.get('language'), 'ar');
|
|
assert.equal(linked.searchParams.get('mode'), 'usdt');
|
|
assert.equal(linked.searchParams.has('page'), false);
|
|
|
|
const rangeHarness = browser();
|
|
runScript(rangeHarness.context, 'guild/packages/core/date-range.js');
|
|
const ranges = rangeHarness.window.HyGuild.dateRange;
|
|
assert.equal(
|
|
JSON.stringify(
|
|
ranges.create('last_7_days', { now: new Date(2026, 6, 12) })
|
|
),
|
|
JSON.stringify({
|
|
preset: 'last_7_days',
|
|
startDate: '2026-07-06',
|
|
endDate: '2026-07-12',
|
|
})
|
|
);
|
|
assert.equal(
|
|
JSON.stringify(
|
|
ranges.create('last_month', { now: new Date(2026, 0, 15) })
|
|
),
|
|
JSON.stringify({
|
|
preset: 'last_month',
|
|
startDate: '2025-12-01',
|
|
endDate: '2025-12-31',
|
|
})
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
ranges.create('custom', { start: '2026-07-12', end: '2026-07-01' }),
|
|
/Invalid custom date range/
|
|
);
|
|
|
|
console.log('guild product architecture tests passed');
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
});
|