Files
client-web/src/modules/auth/views/AuthViews.test.mjs
T
2026-08-04 09:05:01 +08:00

91 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
const loginSource = readFileSync(new URL('./LoginView.vue', import.meta.url), 'utf8')
const registerSource = readFileSync(new URL('./RegisterView.vue', import.meta.url), 'utf8')
const legalSource = readFileSync(new URL('./LegalDocumentView.vue', import.meta.url), 'utf8')
const legalDocumentsSource = readFileSync(new URL('../legalDocuments.ts', import.meta.url), 'utf8')
const authRoutesSource = readFileSync(new URL('../routes.ts', import.meta.url), 'utf8')
const authStoreSource = readFileSync(new URL('../store/auth.ts', import.meta.url), 'utf8')
const httpSource = readFileSync(new URL('../../../api/http.ts', import.meta.url), 'utf8')
const sessionSource = readFileSync(new URL('../../../api/session.ts', import.meta.url), 'utf8')
const authApiSource = readFileSync(new URL('../api/auth.ts', import.meta.url), 'utf8')
const mainSource = readFileSync(new URL('../../../main.ts', import.meta.url), 'utf8')
test('matches the backend username login contract', () => {
assert.match(loginSource, /label="用户名"/)
assert.match(loginSource, /\^\[A-Za-z0-9_\]/)
assert.match(loginSource, /typeof route\.query\.account === 'string'/)
assert.doesNotMatch(loginSource, /developmentHint|demo-tip|merchant_admin|联调账号|本地后端/)
assert.match(loginSource, /form\.remember/)
assert.match(loginSource, /忘记密码/)
})
test('persists both rotating tokens according to the remember choice', () => {
assert.match(sessionSource, /ACCESS_TOKEN_KEY/)
assert.match(sessionSource, /REFRESH_TOKEN_KEY/)
assert.match(sessionSource, /remember \? localStorage : sessionStorage/)
assert.match(sessionSource, /clearSessionTokens/)
})
test('implements every backend registration field and real submission', () => {
for (const field of ['username', 'companyName', 'displayName', 'legalPerson', 'legalPhone', 'contactEmail', 'countryCode', 'address', 'password', 'agreement']) {
assert.match(registerSource, new RegExp(`prop="${field}"`))
}
assert.match(registerSource, /registerMerchant\(/)
assert.match(registerSource, /4–64 位/)
assert.match(registerSource, /8–72 位/)
})
test('shows immediate login after registration and separates company review from account activation', () => {
assert.match(registerSource, /企业账号注册成功/)
assert.match(registerSource, /无需等待注册审核/)
assert.match(registerSource, /提交订单前还需完成企业审核/)
assert.match(registerSource, /营业执照、法人身份证、货代资质证书和银行开户许可证/)
assert.match(registerSource, /一次补齐四类必填资质并提交审核/)
assert.match(registerSource, /立即登录/)
})
test('opens complete service and privacy documents from registration', () => {
assert.match(registerSource, /to="\/legal\/terms" target="_blank"/)
assert.match(registerSource, /to="\/legal\/privacy" target="_blank"/)
assert.doesNotMatch(registerSource, /showDocument/)
assert.match(authRoutesSource, /path: '\/legal\/terms'/)
assert.match(authRoutesSource, /path: '\/legal\/privacy'/)
assert.match(legalSource, /document\.sections/)
assert.match(legalDocumentsSource, /跨境物流中的信息出境/)
assert.match(legalDocumentsSource, /违禁品/)
})
test('uses real auth endpoints and single-flight refresh handling', () => {
assert.match(authApiSource, /\/auth\/login/)
assert.match(authApiSource, /\/auth\/register/)
assert.match(authApiSource, /\/auth\/logout/)
assert.match(httpSource, /refreshPromise/)
assert.match(httpSource, /\/auth\/refresh/)
assert.match(httpSource, /envelope\.code !== '200'/)
assert.match(httpSource, /redirectToLoginAfterSessionExpiry/)
assert.match(httpSource, /window\.location\.replace\(`\/login\?redirect=\$\{encodeURIComponent\(redirect\)\}`\)/)
assert.match(authStoreSource, /decodeMerchantToken/)
assert.doesNotMatch(authStoreSource, /mock-client:/)
})
test('treats only body code 200 as success', () => {
assert.match(httpSource, /if \(envelope\.code !== '200'\)/)
assert.doesNotMatch(httpSource, /if \(envelope\.code !== '0'\)/)
})
test('keeps a valid local session during temporary context and refresh outages', () => {
assert.match(authStoreSource, /function isExpiredSessionError/)
assert.match(authStoreSource, /if \(isExpiredSessionError\(error\)\)/)
assert.match(authStoreSource, /sessionRestored\.value = true\s+return/)
assert.match(httpSource, /if \(mappedError\.status === 401 \|\| mappedError\.code === 'A0401'\)/)
assert.doesNotMatch(httpSource, /catch \(refreshError\) \{\s+clearSessionTokens\(\)/)
})
test('loads styles for programmatic Element Plus messages and dialogs', () => {
assert.match(mainSource, /element-plus\/es\/components\/message\/style\/css/)
assert.match(mainSource, /element-plus\/es\/components\/message-box\/style\/css/)
})