feat(usage): enrich audit metadata and detail views

This commit is contained in:
elky
2026-07-17 19:20:16 +08:00
parent 0be380243b
commit 664c063a06
79 changed files with 6968 additions and 1294 deletions
@@ -7,18 +7,23 @@ const source = readFileSync(
'utf8',
)
describe('AdminOperationsDashboard manual refresh', () => {
it('only starts a refresh from the explicit refresh button', () => {
expect(source).toContain('@click="refreshAll()"')
expect(source).not.toContain('onMounted(')
expect(source).not.toContain('setInterval(')
expect(source).not.toContain('visibilitychange')
describe('AdminOperationsDashboard refresh behavior', () => {
it('refreshes on entry and supports toggling automatic refresh', () => {
expect(source).not.toContain('手动刷新')
expect(source).toContain('@click="toggleAutoRefresh"')
expect(source).toContain("autoRefresh ? '点击关闭自动刷新' : '点击开启自动刷新'")
expect(source).toContain('onMounted(() => {')
expect(source).toContain('void refreshAll()')
expect(source).toContain('const AUTO_REFRESH_INTERVAL = 10_000')
expect(source).toContain('autoRefreshTimer = setInterval(')
expect(source).toContain('clearInterval(autoRefreshTimer)')
const rangeWatcher = source
.split('watch(timeRange, () => {')[1]
?.split('}, { deep: true })')[0]
expect(rangeWatcher).toBeTruthy()
expect(rangeWatcher).not.toContain('refreshAll(')
expect(rangeWatcher).toContain('if (autoRefresh.value)')
expect(rangeWatcher).toContain('refreshAll()')
})
it('does not request the heavyweight system-status fallback', () => {
@@ -53,4 +53,50 @@ describe('Users request loading', () => {
?.split('async function manageApiKeys')[0]
expect(formSubmit).toContain('Promise.all([refreshUsers(), loadUserWallets()])')
})
it('seeds a new managed key from the selected target user feature settings', () => {
const openCreateKey = source
.split('function openCreateUserApiKeyDialog()')[1]
?.split('function openEditUserApiKeyDialog')[0]
expect(openCreateKey).toBeTruthy()
expect(openCreateKey).toContain('selectedUser.value?.feature_settings')
expect(openCreateKey).not.toContain('authStore')
})
it('rejects a stale API key response after switching users or closing the dialog', () => {
const manageKeys = source
.split('async function manageApiKeys(user: User)')[1]
?.split('async function manageUserSessions')[0]
expect(manageKeys).toContain('userApiKeys.value = []')
expect(manageKeys).toContain('loadUserApiKeys(user.id)')
const loadKeys = source
.split('async function loadUserApiKeys(userId: string)')[1]
?.split('function openCreateUserApiKeyDialog')[0]
expect(loadKeys).toContain('const requestId = ++userApiKeysRequestId')
expect(loadKeys).toContain('requestId !== userApiKeysRequestId')
expect(loadKeys).toContain('selectedUser.value?.id !== userId')
expect(loadKeys).toContain('!showApiKeysDialog.value')
const closeKeys = source
.split('function closeApiKeysDialog()')[1]
?.split('async function manageUserSessions')[0]
expect(closeKeys).toContain('userApiKeysRequestId += 1')
expect(closeKeys).toContain('userApiKeys.value = []')
expect(source).toContain('@close="closeApiKeysDialog"')
})
it('keeps an in-flight key mutation bound to its original target user', () => {
const submitKey = source
.split('async function submitUserApiKeyForm()')[1]
?.split('async function revokeSelectedUserSession')[0]
expect(submitKey).toContain('const targetUserId = selectedUser.value.id')
expect(submitKey).toContain('const mutationRequestId = ++userApiKeyMutationRequestId')
expect(submitKey).toContain('selectedUser.value?.id === targetUserId')
expect(submitKey).toContain('usersStore.createApiKey(targetUserId')
expect(submitKey).toContain('usersStore.updateApiKey(targetUserId')
expect(submitKey).toContain('if (!mutationIsCurrent()) return')
})
})