diff --git a/frontend/src/components/common/__tests__/HelpTooltip.spec.ts b/frontend/src/components/common/__tests__/HelpTooltip.spec.ts deleted file mode 100644 index 778aabd9..00000000 --- a/frontend/src/components/common/__tests__/HelpTooltip.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { afterEach, describe, expect, it } from 'vitest' -import { mount } from '@vue/test-utils' -import { nextTick } from 'vue' -import HelpTooltip from '@/components/common/HelpTooltip.vue' - -function getTooltipElement(): HTMLDivElement { - const tooltip = document.body.querySelector('[role="tooltip"]') - if (!(tooltip instanceof HTMLDivElement)) { - throw new Error('tooltip element not found') - } - return tooltip -} - -describe('HelpTooltip', () => { - afterEach(() => { - document.body.innerHTML = '' - }) - - it('keeps the existing hover interaction by default', async () => { - const wrapper = mount(HelpTooltip, { - attachTo: document.body, - props: { - content: 'hover details', - }, - }) - - const trigger = wrapper.get('.group') - const tooltip = getTooltipElement() - - expect(tooltip.style.display).toBe('none') - - await trigger.trigger('mouseenter') - await nextTick() - expect(tooltip.style.display).not.toBe('none') - - await trigger.trigger('mouseleave') - await nextTick() - expect(tooltip.style.display).toBe('none') - - wrapper.unmount() - }) - - it('supports click-to-toggle details and closes on outside click', async () => { - const wrapper = mount(HelpTooltip, { - attachTo: document.body, - props: { - content: 'click details', - trigger: 'click', - }, - }) - - const trigger = wrapper.get('.group') - const tooltip = getTooltipElement() - - expect(tooltip.style.display).toBe('none') - - await trigger.trigger('click') - await nextTick() - expect(tooltip.style.display).not.toBe('none') - expect(tooltip.textContent).toContain('click details') - - const closeButton = tooltip.querySelector('button[aria-label="Close"]') - if (!(closeButton instanceof HTMLButtonElement)) { - throw new Error('close button not found') - } - closeButton.click() - await nextTick() - expect(tooltip.style.display).toBe('none') - - await trigger.trigger('click') - await nextTick() - expect(tooltip.style.display).not.toBe('none') - - document.body.dispatchEvent(new MouseEvent('click', { bubbles: true })) - await nextTick() - expect(tooltip.style.display).toBe('none') - - wrapper.unmount() - }) -}) diff --git a/frontend/src/components/payment/__tests__/PaymentProviderDialog.spec.ts b/frontend/src/components/payment/__tests__/PaymentProviderDialog.spec.ts deleted file mode 100644 index 637d805f..00000000 --- a/frontend/src/components/payment/__tests__/PaymentProviderDialog.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { mount } from '@vue/test-utils' -import { nextTick } from 'vue' -import PaymentProviderDialog from '@/components/payment/PaymentProviderDialog.vue' - -const messages: Record = { - 'admin.settings.payment.providerConfig': 'Credentials', - 'admin.settings.payment.paymentGuideTrigger': 'View payment guide', - 'admin.settings.payment.alipayGuideSummary': 'Desktop prefers QR precreate and falls back to cashier; mobile prefers WAP checkout.', - 'admin.settings.payment.wxpayGuideSummary': 'Desktop prefers Native QR; mobile routes to JSAPI or H5 based on browser context.', -} - -vi.mock('vue-i18n', () => ({ - useI18n: () => ({ - t: (key: string) => messages[key] ?? key, - }), -})) - -function mountDialog() { - return mount(PaymentProviderDialog, { - props: { - show: true, - saving: false, - editing: null, - allKeyOptions: [ - { value: 'alipay', label: 'Alipay' }, - { value: 'wxpay', label: 'WeChat Pay' }, - { value: 'stripe', label: 'Stripe' }, - ], - enabledKeyOptions: [ - { value: 'alipay', label: 'Alipay' }, - { value: 'wxpay', label: 'WeChat Pay' }, - ], - allPaymentTypes: [ - { value: 'alipay', label: 'Alipay' }, - { value: 'wxpay', label: 'WeChat Pay' }, - ], - redirectLabel: 'Redirect', - }, - global: { - stubs: { - BaseDialog: { - template: '
', - }, - Select: { - props: ['modelValue', 'options', 'disabled'], - template: '
', - }, - ToggleSwitch: { - template: '
', - }, - }, - }, - }) -} - -describe('PaymentProviderDialog payment guide', () => { - it('shows no payment guide for providers without a flow guide', () => { - const wrapper = mountDialog() - - expect(wrapper.text()).not.toContain(messages['admin.settings.payment.alipayGuideSummary']) - expect(wrapper.text()).not.toContain(messages['admin.settings.payment.wxpayGuideSummary']) - expect(wrapper.find('button[title="View payment guide"]').exists()).toBe(false) - }) - - it.each([ - ['alipay', 'admin.settings.payment.alipayGuideSummary'], - ['wxpay', 'admin.settings.payment.wxpayGuideSummary'], - ])('shows the payment guide summary for %s', async (providerKey, summaryKey) => { - const wrapper = mountDialog() - - ;(wrapper.vm as unknown as { reset: (key: string) => void }).reset(providerKey) - await nextTick() - - expect(wrapper.text()).toContain(messages[summaryKey]) - expect(wrapper.find('button[title="View payment guide"]').exists()).toBe(true) - }) -})