Files
prop-ai-hr/mobile-uni/tests/request-scope.test.mjs
T

112 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import test, { after } from 'node:test';
import { fileURLToPath } from 'node:url';
import { createServer } from 'vite';
const storage = new Map();
globalThis.uni = {
getStorageSync: (key) => storage.get(key) || '',
setStorageSync: (key, value) => storage.set(key, value),
removeStorageSync: (key) => storage.delete(key)
};
const vite = await createServer({
root: fileURLToPath(new URL('..', import.meta.url)),
configFile: false,
optimizeDeps: { noDiscovery: true },
server: { middlewareMode: true, hmr: false },
appType: 'custom'
});
after(async () => {
await vite.close();
delete globalThis.uni;
});
const { createPageRequestScope } = await vite.ssrLoadModule('/src/services/request-scope.ts');
const { getCurrentProject, reconcileCurrentProject, saveAuth, saveCurrentProject } =
await vite.ssrLoadModule('/src/services/auth.ts');
const loginAs = (phone, token) => {
storage.set('aihr_mobile_phone', phone);
storage.set('aihr_mobile_client_id', 'mobile-client');
storage.set('aihr_mobile_access_token', token);
};
test('同一加载通道只允许最新请求回写,不同通道可以并行', () => {
loginAs('13800138000', 'token-a');
const scope = createPageRequestScope();
scope.activate();
const first = scope.begin('assignments');
const parallel = scope.begin('knowledge');
assert.equal(scope.isCurrent(first), true);
assert.equal(scope.isCurrent(parallel), true);
const second = scope.begin('assignments');
assert.equal(scope.isCurrent(first), false);
assert.equal(scope.isCurrent(second), true);
assert.equal(scope.isCurrent(parallel), true);
});
test('切号、换 token 和页面隐藏后旧请求全部失效', () => {
loginAs('13800138000', 'token-a');
const scope = createPageRequestScope();
scope.activate();
const oldAccount = scope.begin('page');
loginAs('13900139000', 'token-b');
assert.equal(scope.isCurrent(oldAccount), false);
const newAccount = scope.begin('page');
assert.equal(scope.isCurrent(newAccount), true);
storage.set('aihr_mobile_access_token', 'token-b-refreshed');
assert.equal(scope.isCurrent(newAccount), false);
const refreshedToken = scope.begin('page');
assert.equal(scope.isCurrent(refreshedToken), true);
scope.invalidate();
assert.equal(scope.isCurrent(refreshedToken), false);
const hiddenRequest = scope.begin('page');
assert.equal(scope.isCurrent(hiddenRequest), false, '页面隐藏后启动的后续请求不能重新激活页面作用域');
});
test('五个账号敏感页在显示时捕获账号并在隐藏和卸载时失效', async () => {
const pages = [
'../src/pages/user/today/index.vue',
'../src/pages/user/learning/index.vue',
'../src/pages/user/practice/index.vue',
'../src/pages/supervisor/team/index.vue',
'../src/pages/supervisor/index/index.vue'
];
const sources = await Promise.all(pages.map((page) => readFile(new URL(page, import.meta.url), 'utf8')));
for (const source of sources) {
assert.match(source, /currentAccountKey\(\)/);
assert.match(source, /requests\.activate\(\)/);
assert.match(source, /onHide\(/);
assert.match(source, /onUnload\(/);
assert.match(source, /requests\.invalidate\(\)/);
assert.match(source, /requests\.isCurrent\(/);
}
});
test('当前项目按租户和登录账号隔离并在权限变化后重新校验', () => {
saveAuth({ access_token: 'token-a', client_id: 'mobile-client' }, '13800138000', '000000');
saveCurrentProject({ projectCode: 'P1', projectName: '星河湾一期' });
assert.equal(getCurrentProject()?.projectCode, 'P1');
saveAuth({ access_token: 'token-b', client_id: 'mobile-client' }, '13900139000', '000000');
assert.equal(getCurrentProject(), null);
assert.equal(reconcileCurrentProject([
{ projectCode: 'P2', projectName: '星河湾二期' }
])?.projectCode, 'P2');
assert.equal(reconcileCurrentProject([
{ projectCode: 'P3', projectName: '星河湾三期' },
{ projectCode: 'P4', projectName: '星河湾四期' }
]), null);
assert.equal(getCurrentProject(), null);
});