完善手工开票页面文案国际化
This commit is contained in:
@@ -4,6 +4,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { nextTick } from 'vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
import enUS from '@/i18n/locales/en-US'
|
||||
import thTH from '@/i18n/locales/th-TH'
|
||||
import zhCN from '@/i18n/locales/zh-CN'
|
||||
import { ApiError } from '@/services/httpClient'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
@@ -46,12 +48,17 @@ function createResult(): ManualInvoiceGenerationResult {
|
||||
const nativeCreateObjectURL = URL.createObjectURL
|
||||
const nativeRevokeObjectURL = URL.revokeObjectURL
|
||||
|
||||
function mountView(options: { timeZone?: string; extraHotels?: AuthHotelResult[] } = {}) {
|
||||
type ManualInvoiceTestLocale = 'zh-CN' | 'en-US' | 'th-TH'
|
||||
|
||||
function mountView(options: { timeZone?: string; extraHotels?: AuthHotelResult[]; locale?: ManualInvoiceTestLocale } = {}) {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh-CN',
|
||||
locale: options.locale ?? 'zh-CN',
|
||||
fallbackLocale: 'zh-CN',
|
||||
messages: {
|
||||
'zh-CN': zhCN,
|
||||
'en-US': enUS,
|
||||
'th-TH': thTH,
|
||||
},
|
||||
})
|
||||
const pinia = createPinia()
|
||||
@@ -80,11 +87,17 @@ function mountView(options: { timeZone?: string; extraHotels?: AuthHotelResult[]
|
||||
menus: [],
|
||||
})
|
||||
|
||||
return mount(ReservationManualInvoiceView, {
|
||||
const wrapper = mount(ReservationManualInvoiceView, {
|
||||
global: {
|
||||
plugins: [i18n, pinia],
|
||||
},
|
||||
})
|
||||
return Object.assign(wrapper, {
|
||||
async setLocale(locale: ManualInvoiceTestLocale) {
|
||||
i18n.global.locale.value = locale
|
||||
await nextTick()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async function fillMinimumInvoiceForm(wrapper: ReturnType<typeof mountView>) {
|
||||
@@ -214,15 +227,49 @@ describe('ReservationManualInvoiceView', () => {
|
||||
|
||||
expect(wrapper.find('[data-testid="manual-invoice-prototype-page"]').exists()).toBe(true)
|
||||
expect(wrapper.text()).toContain('创建 Invoice')
|
||||
expect(wrapper.text()).not.toContain('草稿')
|
||||
expect(wrapper.text()).toContain('01')
|
||||
expect(wrapper.text()).toContain('Basic Information')
|
||||
expect(wrapper.text()).toContain('02')
|
||||
expect(wrapper.text()).toContain('Please refer to the following reservation')
|
||||
expect(wrapper.text()).not.toContain('Group Name 与 Group Code 在本流程中为同一字段。')
|
||||
expect(wrapper.text()).toContain('03')
|
||||
expect(wrapper.text()).toContain('Description&Amount')
|
||||
expect(wrapper.find('[data-testid="manual-invoice-action-bar"]').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('localizes the highlighted invoice title and recipient placeholders', () => {
|
||||
const wrapper = mountView({ locale: 'en-US' })
|
||||
const placeholders = wrapper.findAll('input, textarea').map((field) => field.attributes('placeholder'))
|
||||
|
||||
expect(wrapper.text()).toContain('Create Invoice')
|
||||
expect(wrapper.text()).not.toContain('创建 Invoice')
|
||||
expect(placeholders).toContain('Enter company')
|
||||
expect(placeholders).toContain('Enter attention')
|
||||
expect(placeholders).toContain('Enter full billing address')
|
||||
expect(placeholders).not.toContain('输入 Company')
|
||||
expect(placeholders).not.toContain('输入 Attention')
|
||||
expect(placeholders).not.toContain('输入客户完整账单地址')
|
||||
})
|
||||
|
||||
it('localizes the invoice action controls and room rate note placeholder', async () => {
|
||||
const wrapper = mountView({ locale: 'en-US' })
|
||||
|
||||
expect((wrapper.find('[data-testid="booking-room-rate-note"]').element as HTMLInputElement).placeholder).toBe(
|
||||
'e.g. including BF',
|
||||
)
|
||||
expect(wrapper.find('[data-testid="manual-invoice-add-charge"]').text()).toContain('Add row')
|
||||
expect(wrapper.find('[data-testid="manual-invoice-submit"]').text()).toContain('Confirm and generate PDF')
|
||||
|
||||
await wrapper.find('[data-testid="manual-invoice-add-charge"]').trigger('click')
|
||||
|
||||
expect(wrapper.findAll('.remove-button')[1]?.text()).toContain('Remove')
|
||||
expect(wrapper.findAll('.remove-button')[1]?.attributes('aria-label')).toBe('Remove row 2')
|
||||
expect(wrapper.text()).not.toContain('新增一行')
|
||||
expect(wrapper.text()).not.toContain('确认并生成 PDF')
|
||||
expect(wrapper.text()).not.toContain('例如 includingBF')
|
||||
})
|
||||
|
||||
it('shows final-format date previews like the invoice prototype', async () => {
|
||||
const wrapper = mountView()
|
||||
|
||||
@@ -287,8 +334,8 @@ describe('ReservationManualInvoiceView', () => {
|
||||
await wrapper.find('[data-testid="recipient-company-code"]').setValue('MANUAL')
|
||||
|
||||
expect((wrapper.find('[data-testid="recipient-contact-id"]').element as HTMLSelectElement).value).toBe('MANUAL')
|
||||
expect((wrapper.find('input[placeholder="输入 Company"]').element as HTMLInputElement).value).toBe('')
|
||||
expect((wrapper.find('input[placeholder="输入 Attention"]').element as HTMLInputElement).value).toBe('')
|
||||
expect((wrapper.find('[data-testid="recipient-company-input"]').element as HTMLInputElement).value).toBe('')
|
||||
expect((wrapper.find('[data-testid="recipient-attention-input"]').element as HTMLInputElement).value).toBe('')
|
||||
expect((wrapper.find('[data-testid="recipient-email"]').element as HTMLInputElement).value).toBe('')
|
||||
})
|
||||
|
||||
@@ -370,6 +417,32 @@ describe('ReservationManualInvoiceView', () => {
|
||||
expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:manual-invoice-pdf')
|
||||
})
|
||||
|
||||
it('localizes the PDF download fallback message after a locale switch', async () => {
|
||||
vi.mocked(service.generateManualReservationInvoice).mockResolvedValue(createResult())
|
||||
const fetchMock = vi.fn().mockRejectedValue(new Error('CORS blocked'))
|
||||
const openSpy = vi.spyOn(window, 'open').mockReturnValue(null)
|
||||
vi.stubGlobal('fetch', fetchMock)
|
||||
const wrapper = mountView()
|
||||
|
||||
await wrapper.find('[data-testid="recipient-company-code"]').setValue('QBD')
|
||||
await fillMinimumInvoiceForm(wrapper)
|
||||
await wrapper.find('[data-testid="manual-invoice-submit"]').trigger('click')
|
||||
await flushPromises()
|
||||
await wrapper.find('[data-testid="manual-invoice-download-pdf"]').trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(openSpy).toHaveBeenCalledWith('https://oss.example/invoices/manual-91001.pdf', '_blank', 'noopener,noreferrer')
|
||||
expect(wrapper.find('[data-testid="manual-invoice-download-message"]').text()).toBe(
|
||||
zhCN.manualInvoice.downloadFallback,
|
||||
)
|
||||
|
||||
await wrapper.setLocale('en-US')
|
||||
|
||||
expect(wrapper.find('[data-testid="manual-invoice-download-message"]').text()).toBe(
|
||||
enUS.manualInvoice.downloadFallback,
|
||||
)
|
||||
})
|
||||
|
||||
it('submits complete numeric input values instead of parseFloat prefixes', async () => {
|
||||
vi.mocked(service.generateManualReservationInvoice).mockResolvedValue(createResult())
|
||||
const wrapper = mountView()
|
||||
|
||||
Reference in New Issue
Block a user