import assert from 'node:assert/strict'; import { createAdminViews } from '../src/client/admin-views.mjs'; import { createAdmissionViews } from '../src/client/admission-views.mjs'; import { api } from '../src/client/api.mjs'; import { createCandidateViews } from '../src/client/candidate-views.mjs'; import { createPublicViews } from '../src/client/public-views.mjs'; function protectedViewContext() { let loginRequests = 0; const context = { state: { user: null }, app: { classList: { add() {}, remove() {} } }, requireLogin() { loginRequests += 1; } }; return { context, loginRequests: () => loginRequests }; } for (const createView of [createAdminViews, createCandidateViews, createAdmissionViews]) { const fixture = protectedViewContext(); const views = createView(fixture.context); const render = views.renderAdmin || views.renderCandidate || views.renderAdmission; await render('dashboard'); assert.equal(fixture.loginRequests(), 1, '未登录访问受保护视图时应交给统一登录处理'); } { const app = { classList: { remove() {} }, innerHTML: '' }; const state = { user: null, authNotice: '登录状态已失效,请重新登录。', publicData: { selfRegistrationEnabled: false } }; const { renderAuth } = createPublicViews({ state, app, h: value => String(value ?? ''), icons: { arrow: '', menu: '' } }); renderAuth('login'); assert.match(app.innerHTML, /需要重新登录/); assert.match(app.innerHTML, /登录状态已失效,请重新登录/); } { const originalFetch = globalThis.fetch; globalThis.fetch = async () => new Response(JSON.stringify({ message: '请先登录' }), { status: 401, headers: { 'content-type': 'application/json' } }); try { await assert.rejects(() => api('/api/protected'), error => error.status === 401 && error.message === '请先登录'); } finally { globalThis.fetch = originalFetch; } } console.log('客户端登录失效处理测试通过');