Files
client-web/src/modules/auth/views/AuthViews.test.mjs
T

91 lines
4.8 KiB
JavaScript
Raw Normal View History

2026-07-30 17:59:42 +08:00
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')
2026-08-03 20:50:32 +08:00
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')
2026-08-03 18:52:30 +08:00
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')
2026-07-30 17:59:42 +08:00
const authApiSource = readFileSync(new URL('../api/auth.ts', import.meta.url), 'utf8')
2026-08-03 18:52:30 +08:00
const mainSource = readFileSync(new URL('../../../main.ts', import.meta.url), 'utf8')
2026-07-30 17:59:42 +08:00
test('matches the backend username login contract', () => {
assert.match(loginSource, /label="用户名"/)
assert.match(loginSource, /\^\[A-Za-z0-9_\]/)
2026-07-31 15:34:22 +08:00
assert.match(loginSource, /typeof route\.query\.account === 'string'/)
assert.doesNotMatch(loginSource, /developmentHint|demo-tip|merchant_admin|联调账号|本地后端/)
2026-07-30 17:59:42 +08:00
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, /无需等待注册审核/)
2026-08-04 09:05:01 +08:00
assert.match(registerSource, /提交订单前还需完成企业审核/)
assert.match(registerSource, /营业执照、法人身份证、货代资质证书和银行开户许可证/)
assert.match(registerSource, /一次补齐四类必填资质并提交审核/)
2026-07-30 17:59:42 +08:00
assert.match(registerSource, /立即登录/)
})
2026-08-03 20:50:32 +08:00
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, /违禁品/)
})
2026-07-30 17:59:42 +08:00
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\)\}`\)/)
2026-07-30 17:59:42 +08:00
assert.match(authStoreSource, /decodeMerchantToken/)
assert.doesNotMatch(authStoreSource, /mock-client:/)
})
2026-07-30 21:23:06 +08:00
test('treats only body code 200 as success', () => {
assert.match(httpSource, /if \(envelope\.code !== '200'\)/)
assert.doesNotMatch(httpSource, /if \(envelope\.code !== '0'\)/)
})
2026-07-30 21:23:06 +08:00
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/)
})