/** * API Key 创建逻辑测试 * 通过封装组件测试 API Key 创建的核心流程 */ import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' import { setActivePinia, createPinia } from 'pinia' import { defineComponent, ref, reactive } from 'vue' // Mock keysAPI const mockCreate = vi.fn() const mockList = vi.fn() vi.mock('@/api', () => ({ keysAPI: { create: (...args: any[]) => mockCreate(...args), list: (...args: any[]) => mockList(...args), }, authAPI: { getCurrentUser: vi.fn().mockResolvedValue({ data: {} }), logout: vi.fn(), refreshToken: vi.fn(), }, isTotp2FARequired: () => false, })) vi.mock('@/api/admin/system', () => ({ checkUpdates: vi.fn(), })) vi.mock('@/api/auth', () => ({ getPublicSettings: vi.fn().mockResolvedValue({}), })) // Mock app store - 使用固定引用确保组件和测试共享同一对象 const mockShowSuccess = vi.fn() const mockShowError = vi.fn() vi.mock('@/stores/app', () => ({ useAppStore: () => ({ showSuccess: mockShowSuccess, showError: mockShowError, }), })) import { useAppStore } from '@/stores/app' /** * 简化的 API Key 创建测试组件 */ const ApiKeyCreateTestComponent = defineComponent({ setup() { const appStore = useAppStore() const loading = ref(false) const createdKey = ref('') const formData = reactive({ name: '', group_id: null as number | null, }) const handleCreate = async () => { if (!formData.name) return loading.value = true try { const result = await mockCreate({ name: formData.name, group_id: formData.group_id, }) createdKey.value = result.key appStore.showSuccess('API Key 创建成功') } catch (error: any) { appStore.showError(error.message || '创建失败') } finally { loading.value = false } } return { formData, loading, createdKey, handleCreate } }, template: `
{{ createdKey }}
`, }) describe('ApiKey 创建流程', () => { beforeEach(() => { setActivePinia(createPinia()) vi.clearAllMocks() }) it('创建 API Key 调用 API 并显示结果', async () => { mockCreate.mockResolvedValue({ id: 1, key: 'sk-test-key-12345', name: 'My Test Key', }) const wrapper = mount(ApiKeyCreateTestComponent) await wrapper.find('#name').setValue('My Test Key') await wrapper.find('form').trigger('submit') await flushPromises() expect(mockCreate).toHaveBeenCalledWith({ name: 'My Test Key', group_id: null, }) expect(wrapper.find('.created-key').text()).toBe('sk-test-key-12345') }) it('选择分组后正确传参', async () => { mockCreate.mockResolvedValue({ id: 2, key: 'sk-group-key', name: 'Group Key', }) const wrapper = mount(ApiKeyCreateTestComponent) await wrapper.find('#name').setValue('Group Key') // 选择 group_id = 1 await wrapper.find('#group').setValue('1') await wrapper.find('form').trigger('submit') await flushPromises() expect(mockCreate).toHaveBeenCalledWith({ name: 'Group Key', group_id: 1, }) }) it('创建失败时显示错误', async () => { mockCreate.mockRejectedValue(new Error('配额不足')) const wrapper = mount(ApiKeyCreateTestComponent) await wrapper.find('#name').setValue('Fail Key') await wrapper.find('form').trigger('submit') await flushPromises() expect(mockShowError).toHaveBeenCalledWith('配额不足') expect(wrapper.find('.created-key').exists()).toBe(false) }) it('名称为空时不提交', async () => { const wrapper = mount(ApiKeyCreateTestComponent) await wrapper.find('form').trigger('submit') await flushPromises() expect(mockCreate).not.toHaveBeenCalled() }) it('创建过程中按钮被禁用', async () => { let resolveCreate: (v: any) => void mockCreate.mockImplementation( () => new Promise((resolve) => { resolveCreate = resolve }) ) const wrapper = mount(ApiKeyCreateTestComponent) await wrapper.find('#name').setValue('Test Key') await wrapper.find('form').trigger('submit') expect(wrapper.find('button').attributes('disabled')).toBeDefined() resolveCreate!({ id: 1, key: 'sk-test', name: 'Test Key' }) await flushPromises() expect(wrapper.find('button').attributes('disabled')).toBeUndefined() }) })