diff --git a/frontend/src/components/admin/user/UserBalanceModal.vue b/frontend/src/components/admin/user/UserBalanceModal.vue index e8474cff02..f0070b0340 100644 --- a/frontend/src/components/admin/user/UserBalanceModal.vue +++ b/frontend/src/components/admin/user/UserBalanceModal.vue @@ -29,6 +29,7 @@ import { reactive, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import { useAppStore } from '@/stores/app' import { adminAPI } from '@/api/admin' +import { extractApiErrorMessage } from '@/utils/apiError' import type { AdminUser } from '@/types' import BaseDialog from '@/components/common/BaseDialog.vue' @@ -80,7 +81,7 @@ const handleBalanceSubmit = async () => { appStore.showSuccess(t('common.success')); emit('success'); emit('close') } catch (e: any) { console.error('Failed to update balance:', e) - appStore.showError(e.response?.data?.detail || t('common.error')) + appStore.showError(extractApiErrorMessage(e, t('common.error'))) } finally { submitting.value = false } } diff --git a/frontend/src/components/admin/user/__tests__/UserBalanceModal.spec.ts b/frontend/src/components/admin/user/__tests__/UserBalanceModal.spec.ts new file mode 100644 index 0000000000..068bc2424d --- /dev/null +++ b/frontend/src/components/admin/user/__tests__/UserBalanceModal.spec.ts @@ -0,0 +1,27 @@ +import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import UserBalanceModal from '../UserBalanceModal.vue' +import type { AdminUser } from '@/types' +const mocks = vi.hoisted(() => ({ updateBalance: vi.fn(), showError: vi.fn(), showSuccess: vi.fn() })) +vi.mock('@/api/admin', () => ({ adminAPI: { users: mocks } })) +vi.mock('@/stores/app', () => ({ useAppStore: () => mocks })) +vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key: string) => key }) })) +enableAutoUnmount(afterEach) +beforeEach(() => { vi.clearAllMocks(); vi.spyOn(console, 'error').mockImplementation(() => {}) }) +afterEach(() => vi.restoreAllMocks()) +describe('balance operation error feedback', () => { + it.each([ + [{ message: 'User balance changed; retry' }, 'User balance changed; retry'], + [{ response: { data: { detail: 'Legacy detail' } } }, 'Legacy detail'], + [{}, 'common.error'], + ])('shows the available API error and keeps the dialog open', async (error, message) => { + mocks.updateBalance.mockRejectedValueOnce(error) + const w = mount(UserBalanceModal, { props: { show: true, operation: 'add', user: { id: 1, email: 'a@example.com', balance: 5 } as AdminUser }, + global: { stubs: { BaseDialog: { template: '