feat(admin-v2): add ProTable search, scenarios/quick_commands form, tests, remove quota_reset_interval
- Enable ProTable search on Accounts (username/email), Models (model_id/alias), Providers (display_name/name) with hideInSearch for non-searchable columns - Add scenarios (Select tags) and quick_commands (Form.List) to AgentTemplates create form, plus service type updates - Remove unused quota_reset_interval from ProviderKey model, key_pool SQL, handlers, and frontend types; add migration + bump schema to v11 - Add Vitest config, test setup, request interceptor tests (7 cases), authStore tests (8 cases) — all 15 passing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
115
admin-v2/tests/stores/authStore.test.ts
Normal file
115
admin-v2/tests/stores/authStore.test.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
// ============================================================
|
||||
// authStore 测试
|
||||
// ============================================================
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { AccountPublic } from '@/types'
|
||||
|
||||
// Mock fetch for logout
|
||||
const mockFetch = vi.fn().mockResolvedValue({ ok: true })
|
||||
vi.stubGlobal('fetch', mockFetch)
|
||||
|
||||
const mockAccount: AccountPublic = {
|
||||
id: 'test-id',
|
||||
username: 'testuser',
|
||||
display_name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
role: 'admin',
|
||||
status: 'active',
|
||||
totp_enabled: false,
|
||||
llm_routing: 'relay',
|
||||
created_at: '2026-01-01T00:00:00Z',
|
||||
updated_at: '2026-01-01T00:00:00Z',
|
||||
}
|
||||
|
||||
const superAdminAccount: AccountPublic = {
|
||||
...mockAccount,
|
||||
id: 'super-id',
|
||||
username: 'superadmin',
|
||||
role: 'super_admin',
|
||||
}
|
||||
|
||||
describe('authStore', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear()
|
||||
mockFetch.mockClear()
|
||||
// Reset store state
|
||||
useAuthStore.setState({
|
||||
token: null,
|
||||
refreshToken: null,
|
||||
account: null,
|
||||
permissions: [],
|
||||
})
|
||||
})
|
||||
|
||||
it('login sets token, refreshToken, account and permissions', () => {
|
||||
const store = useAuthStore.getState()
|
||||
store.login('jwt-token', 'refresh-token', mockAccount)
|
||||
|
||||
const state = useAuthStore.getState()
|
||||
expect(state.token).toBe('jwt-token')
|
||||
expect(state.refreshToken).toBe('refresh-token')
|
||||
expect(state.account).toEqual(mockAccount)
|
||||
expect(state.permissions).toContain('provider:manage')
|
||||
})
|
||||
|
||||
it('super_admin gets admin:full + all permissions', () => {
|
||||
const store = useAuthStore.getState()
|
||||
store.login('jwt', 'refresh', superAdminAccount)
|
||||
|
||||
const state = useAuthStore.getState()
|
||||
expect(state.permissions).toContain('admin:full')
|
||||
expect(state.permissions).toContain('account:admin')
|
||||
expect(state.permissions).toContain('prompt:admin')
|
||||
})
|
||||
|
||||
it('user role gets only basic permissions', () => {
|
||||
const userAccount: AccountPublic = { ...mockAccount, role: 'user' }
|
||||
const store = useAuthStore.getState()
|
||||
store.login('jwt', 'refresh', userAccount)
|
||||
|
||||
const state = useAuthStore.getState()
|
||||
expect(state.permissions).toContain('model:read')
|
||||
expect(state.permissions).toContain('relay:use')
|
||||
expect(state.permissions).not.toContain('provider:manage')
|
||||
})
|
||||
|
||||
it('logout clears all state', () => {
|
||||
useAuthStore.getState().login('jwt', 'refresh', mockAccount)
|
||||
|
||||
useAuthStore.getState().logout()
|
||||
|
||||
const state = useAuthStore.getState()
|
||||
expect(state.token).toBeNull()
|
||||
expect(state.refreshToken).toBeNull()
|
||||
expect(state.account).toBeNull()
|
||||
expect(state.permissions).toEqual([])
|
||||
expect(localStorage.getItem('zclaw_admin_account')).toBeNull()
|
||||
})
|
||||
|
||||
it('hasPermission returns true for matching permission', () => {
|
||||
useAuthStore.getState().login('jwt', 'refresh', mockAccount)
|
||||
expect(useAuthStore.getState().hasPermission('provider:manage')).toBe(true)
|
||||
expect(useAuthStore.getState().hasPermission('config:write')).toBe(true)
|
||||
})
|
||||
|
||||
it('hasPermission returns false for non-matching permission', () => {
|
||||
useAuthStore.getState().login('jwt', 'refresh', mockAccount)
|
||||
expect(useAuthStore.getState().hasPermission('admin:full')).toBe(false)
|
||||
})
|
||||
|
||||
it('admin:full grants all permissions via wildcard', () => {
|
||||
useAuthStore.getState().login('jwt', 'refresh', superAdminAccount)
|
||||
expect(useAuthStore.getState().hasPermission('anything:here')).toBe(true)
|
||||
expect(useAuthStore.getState().hasPermission('made:up')).toBe(true)
|
||||
})
|
||||
|
||||
it('persists account to localStorage on login', () => {
|
||||
useAuthStore.getState().login('jwt', 'refresh', mockAccount)
|
||||
|
||||
const stored = localStorage.getItem('zclaw_admin_account')
|
||||
expect(stored).not.toBeNull()
|
||||
expect(JSON.parse(stored!).username).toBe('testuser')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user