diff --git a/frontend/src/components/account/__tests__/BulkEditAccountModal.spec.ts b/frontend/src/components/account/__tests__/BulkEditAccountModal.spec.ts index 7390e723..2e360978 100644 --- a/frontend/src/components/account/__tests__/BulkEditAccountModal.spec.ts +++ b/frontend/src/components/account/__tests__/BulkEditAccountModal.spec.ts @@ -217,4 +217,41 @@ describe('BulkEditAccountModal', () => { }) expect(wrapper.text()).toContain('admin.accounts.openai.modelRestrictionDisabledByPassthrough') }) + + it('filtered-results 模式下应提交 filters 而不是 account_ids', async () => { + const wrapper = mountModal({ + accountIds: [], + target: { + mode: 'filtered', + filters: { + platform: 'openai', + type: 'oauth', + status: 'active', + group: '12', + search: 'bulk-target', + privacy_mode: 'training_set_cf_blocked' + }, + previewCount: 5, + selectedPlatforms: ['openai'], + selectedTypes: ['oauth'] + } + }) + + await wrapper.get('#bulk-edit-status-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({ + filters: { + platform: 'openai', + type: 'oauth', + status: 'active', + group: '12', + search: 'bulk-target', + privacy_mode: 'training_set_cf_blocked' + }, + status: 'active' + }) + }) }) diff --git a/frontend/src/views/admin/__tests__/AccountsView.bulkEdit.spec.ts b/frontend/src/views/admin/__tests__/AccountsView.bulkEdit.spec.ts new file mode 100644 index 00000000..112baf22 --- /dev/null +++ b/frontend/src/views/admin/__tests__/AccountsView.bulkEdit.spec.ts @@ -0,0 +1,152 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { flushPromises, mount } from '@vue/test-utils' + +import AccountsView from '../AccountsView.vue' + +const { + listAccounts, + listWithEtag, + getBatchTodayStats, + getAllProxies, + getAllGroups +} = vi.hoisted(() => ({ + listAccounts: vi.fn(), + listWithEtag: vi.fn(), + getBatchTodayStats: vi.fn(), + getAllProxies: vi.fn(), + getAllGroups: vi.fn() +})) + +vi.mock('@/api/admin', () => ({ + adminAPI: { + accounts: { + list: listAccounts, + listWithEtag, + getBatchTodayStats, + delete: vi.fn(), + batchClearError: vi.fn(), + batchRefresh: vi.fn(), + toggleSchedulable: vi.fn() + }, + proxies: { + getAll: getAllProxies + }, + groups: { + getAll: getAllGroups + } + } +})) + +vi.mock('@/stores/app', () => ({ + useAppStore: () => ({ + showError: vi.fn(), + showSuccess: vi.fn(), + showInfo: vi.fn() + }) +})) + +vi.mock('@/stores/auth', () => ({ + useAuthStore: () => ({ + token: 'test-token' + }) +})) + +vi.mock('vue-i18n', async () => { + const actual = await vi.importActual('vue-i18n') + return { + ...actual, + useI18n: () => ({ + t: (key: string) => key + }) + } +}) + +const DataTableStub = { + props: ['columns', 'data'], + template: '
' +} + +const AccountBulkActionsBarStub = { + props: ['selectedIds'], + emits: ['edit-filtered'], + template: '' +} + +const BulkEditAccountModalStub = { + props: ['show', 'target'], + template: '
' +} + +describe('admin AccountsView bulk edit scope', () => { + beforeEach(() => { + localStorage.clear() + + listAccounts.mockReset() + listWithEtag.mockReset() + getBatchTodayStats.mockReset() + getAllProxies.mockReset() + getAllGroups.mockReset() + + listAccounts.mockResolvedValue({ + items: [], + total: 0, + page: 1, + page_size: 20, + pages: 0 + }) + listWithEtag.mockResolvedValue({ + notModified: true, + etag: null, + data: null + }) + getBatchTodayStats.mockResolvedValue({ stats: {} }) + getAllProxies.mockResolvedValue([]) + getAllGroups.mockResolvedValue([]) + }) + + it('opens bulk edit in filtered-results mode from the bulk actions dropdown', async () => { + const wrapper = mount(AccountsView, { + global: { + stubs: { + AppLayout: { template: '
' }, + TablePageLayout: { + template: '
' + }, + DataTable: DataTableStub, + Pagination: true, + ConfirmDialog: true, + AccountTableActions: { template: '
' }, + AccountTableFilters: { template: '
' }, + AccountBulkActionsBar: AccountBulkActionsBarStub, + AccountActionMenu: true, + ImportDataModal: true, + ReAuthAccountModal: true, + AccountTestModal: true, + AccountStatsModal: true, + ScheduledTestsPanel: true, + SyncFromCrsModal: true, + TempUnschedStatusModal: true, + ErrorPassthroughRulesModal: true, + TLSFingerprintProfilesModal: true, + CreateAccountModal: true, + EditAccountModal: true, + BulkEditAccountModal: BulkEditAccountModalStub, + PlatformTypeBadge: true, + AccountCapacityCell: true, + AccountStatusIndicator: true, + AccountTodayStatsCell: true, + AccountGroupsCell: true, + AccountUsageCell: true, + Icon: true + } + } + }) + + await flushPromises() + await wrapper.get('[data-test="edit-filtered"]').trigger('click') + await flushPromises() + + expect(wrapper.get('[data-test="bulk-edit-modal"]').attributes('data-show')).toBe('true') + expect(wrapper.get('[data-test="bulk-edit-modal"]').attributes('data-target-mode')).toBe('filtered') + }) +})