import test from 'node:test' import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { parse, compileTemplate } from '@vue/compiler-sfc' import { PDA_AUTHORITY, PDA_ROLE, loadLoginPreference, saveLoginPreference, restoreSession, session, signInWithTokens, signOut } from '../src/stores/session.js' const source = readFileSync(new URL('../src/pages/login/login.vue', import.meta.url), 'utf8') const { descriptor, errors } = parse(source) const preferenceKey = 'overseas-pda-login-account-preference' function storage() { const values = new Map() globalThis.uni = { setStorageSync: (key, value) => values.set(key, JSON.parse(JSON.stringify(value))), getStorageSync: (key) => values.get(key), removeStorageSync: (key) => values.delete(key), reLaunch() {} } signOut() return values } function tokens() { const claims = { user_id: 42, membership_id: 84, tenant_id: 0, app_code: 'PLATFORM', overseas_warehouse_id: 900, exp: Math.floor(Date.now() / 1000) + 3600 } return { accessToken: `header.${Buffer.from(JSON.stringify(claims)).toString('base64url')}.signature`, refreshToken: 'refresh-42', roles: [PDA_ROLE], authorities: [PDA_AUTHORITY] } } function page(overrides = {}) { const dependencies = { DEV_LOGIN: { username: '', password: '' }, session, restoreSession, signInWithTokens, loadLoginPreference, saveLoginPreference, requireOnline() {}, loginRequest: async () => tokens(), console: { error() {} }, ...overrides } const script = descriptor.script.content.replace(/^\s*import .*$/gm, '').replace('export default', 'return') const definition = new Function(...Object.keys(dependencies), script)(...Object.values(dependencies)) const vm = definition.data() for (const [name, method] of Object.entries(definition.methods)) vm[name] = method.bind(vm) definition.onLoad.call(vm) return vm } test('login template compiles with an account switch and separate row and switch events', () => { assert.deepEqual(errors, []) const compiled = compileTemplate({ source: descriptor.template.content, filename: 'login.vue', id: 'login' }) assert.deepEqual(compiled.errors, []) assert.match(descriptor.template.content, /@tap="toggleRememberAccount"/) assert.match(descriptor.template.content, /]*:checked="rememberAccount"[^>]*@change="handleRememberChange"[^>]*@tap\.stop/) }) test('new installations default to remembering the account and an empty login form', () => { storage() assert.deepEqual(loadLoginPreference(), { rememberAccount: true, account: '' }) const vm = page() assert.equal(vm.rememberAccount, true) assert.deepEqual(vm.form, { userId: '', password: '' }) }) test('successful login remembers the trimmed account across sign out and page reopening', async () => { const values = storage() let credentials const vm = page({ loginRequest: async (...args) => { credentials = args; return tokens() } }) vm.form = { userId: ' picker-42 ', password: 'test-password' } await vm.login() assert.equal(vm.error, '') assert.deepEqual(credentials, ['picker-42', 'test-password']) assert.deepEqual(values.get(preferenceKey), { rememberAccount: true, account: 'picker-42' }) assert.equal(session.currentUser.id, '42') signOut() const reopened = page() assert.equal(reopened.form.userId, 'picker-42') assert.equal(reopened.form.password, '') assert.equal(reopened.rememberAccount, true) }) test('switch and row can each clear the saved account immediately without logging in', () => { storage() saveLoginPreference(true, 'picker-42') const vm = page() vm.handleRememberChange({ detail: { value: false } }) assert.equal(vm.rememberAccount, false) assert.deepEqual(loadLoginPreference(), { rememberAccount: false, account: '' }) assert.equal(page().form.userId, '') assert.equal(page().rememberAccount, false) vm.toggleRememberAccount() saveLoginPreference(true, 'picker-42') vm.toggleRememberAccount() assert.equal(vm.rememberAccount, false) assert.deepEqual(loadLoginPreference(), { rememberAccount: false, account: '' }) }) test('login with remembering disabled leaves the next login form empty', async () => { storage() const vm = page() vm.toggleRememberAccount() vm.form = { userId: 'picker-42', password: 'test-password' } await vm.login() assert.equal(vm.error, '') assert.equal(session.currentUser.id, '42') signOut() const reopened = page() assert.equal(reopened.rememberAccount, false) assert.deepEqual(reopened.form, { userId: '', password: '' }) }) test('failed authentication and rejected operator tokens preserve the last successful account', async () => { storage() saveLoginPreference(true, 'previous-picker') for (const loginRequest of [ async () => { throw new Error('密码错误') }, async () => ({ ...tokens(), authorities: [] }) ]) { const vm = page({ loginRequest }) vm.form = { userId: 'other-picker', password: 'test-password' } await vm.login() assert.ok(vm.error) assert.equal(vm.submitting, false) assert.equal(session.currentUser, null) assert.deepEqual(loadLoginPreference(), { rememberAccount: true, account: 'previous-picker' }) } })