| import { describe, expect, it, vi, beforeEach } from 'vitest' |
| import { flushPromises, mount } from '@vue/test-utils' |
| import BulkEditAccountModal from '../BulkEditAccountModal.vue' |
| import ModelWhitelistSelector from '../ModelWhitelistSelector.vue' |
| import { adminAPI } from '@/api/admin' |
|
|
| vi.mock('@/stores/app', () => ({ |
| useAppStore: () => ({ |
| showError: vi.fn(), |
| showSuccess: vi.fn(), |
| showInfo: vi.fn() |
| }) |
| })) |
|
|
| vi.mock('@/api/admin', () => ({ |
| adminAPI: { |
| accounts: { |
| bulkUpdate: vi.fn(), |
| checkMixedChannelRisk: vi.fn() |
| } |
| } |
| })) |
|
|
| vi.mock('@/api/admin/accounts', () => ({ |
| getAntigravityDefaultModelMapping: vi.fn() |
| })) |
|
|
| vi.mock('vue-i18n', async () => { |
| const actual = await vi.importActual<typeof import('vue-i18n')>('vue-i18n') |
| return { |
| ...actual, |
| useI18n: () => ({ |
| t: (key: string) => key |
| }) |
| } |
| }) |
|
|
| function mountModal(extraProps: Record<string, unknown> = {}) { |
| return mount(BulkEditAccountModal, { |
| props: { |
| show: true, |
| accountIds: [1, 2], |
| selectedPlatforms: ['antigravity'], |
| selectedTypes: ['apikey'], |
| proxies: [], |
| groups: [], |
| ...extraProps |
| } as any, |
| global: { |
| stubs: { |
| BaseDialog: { template: '<div><slot /><slot name="footer" /></div>' }, |
| ConfirmDialog: true, |
| Select: true, |
| ProxySelector: true, |
| GroupSelector: true, |
| Icon: true |
| } |
| } |
| }) |
| } |
|
|
| describe('BulkEditAccountModal', () => { |
| beforeEach(() => { |
| vi.mocked(adminAPI.accounts.bulkUpdate).mockReset() |
| vi.mocked(adminAPI.accounts.checkMixedChannelRisk).mockReset() |
|
|
| vi.mocked(adminAPI.accounts.bulkUpdate).mockResolvedValue({ |
| success: 2, |
| failed: 0, |
| results: [] |
| } as any) |
| vi.mocked(adminAPI.accounts.checkMixedChannelRisk).mockResolvedValue({ |
| has_risk: false |
| } as any) |
| }) |
|
|
| it('antigravity 白名单包含 Gemini 图片模型且过滤掉普通 GPT 模型', async () => { |
| const wrapper = mountModal() |
| const selector = wrapper.findComponent(ModelWhitelistSelector) |
| expect(selector.exists()).toBe(true) |
|
|
| await selector.find('div.cursor-pointer').trigger('click') |
|
|
| expect(wrapper.text()).toContain('gemini-3.1-flash-image') |
| expect(wrapper.text()).toContain('gemini-2.5-flash-image') |
| expect(wrapper.text()).not.toContain('gpt-5.3-codex') |
| }) |
|
|
| it('antigravity 映射预设包含图片映射并过滤 OpenAI 预设', async () => { |
| const wrapper = mountModal() |
|
|
| const mappingTab = wrapper.findAll('button').find((btn) => btn.text().includes('admin.accounts.modelMapping')) |
| expect(mappingTab).toBeTruthy() |
| await mappingTab!.trigger('click') |
|
|
| expect(wrapper.text()).toContain('3.1-Flash-Image透传') |
| expect(wrapper.text()).toContain('3-Pro-Image→3.1') |
| expect(wrapper.text()).not.toContain('GPT-5.3 Codex Spark') |
| }) |
|
|
| it('仅勾选模型限制且白名单留空时,应提交空 model_mapping 以支持所有模型', async () => { |
| const wrapper = mountModal({ |
| selectedPlatforms: ['anthropic'], |
| selectedTypes: ['apikey'] |
| }) |
|
|
| await wrapper.get('#bulk-edit-model-restriction-enabled').setValue(true) |
| await wrapper.get('#bulk-edit-account-form').trigger('submit.prevent') |
| await flushPromises() |
|
|
| expect(adminAPI.accounts.bulkUpdate).toHaveBeenCalledTimes(1) |
| expect(adminAPI.accounts.bulkUpdate).toHaveBeenCalledWith([1, 2], { |
| credentials: { |
| model_mapping: {} |
| } |
| }) |
| }) |
| }) |
|
|