import { mount } from '@vue/test-utils'; import RichTranslation from '../RichTranslation.vue'; import { createStore } from 'vuex'; import { h } from 'vue'; // Mock the i18n store getter const mockI18nStore = createStore({ getters: { 'i18n/t': () => (key: string, args: any, noMarkup: boolean) => { const translations: Record = { 'test.simple': 'Hello World', 'test.html': 'This is bold and italic.', 'test.custom': 'This has a link and .', 'test.mixed': 'Text before content1 text in middle text after.', 'test.noString': 123, }; return translations[key] || key; }, }, }); describe('richTranslation', () => { it('renders a simple translation correctly', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.simple' }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.text()).toBe('Hello World'); expect(wrapper.html()).toContain('Hello World'); }); it('renders HTML tags correctly', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.html' }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.html()).toContain('This is bold and italic.'); expect(wrapper.find('b').exists()).toBe(true); expect(wrapper.find('i').exists()).toBe(true); }); it('renders custom components via slots (enclosing tag)', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.custom' }, slots: { customLink: ({ content }: { content: string }) => h('a', { href: '/test' }, content) }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.html()).toContain('link'); expect(wrapper.find('a').text()).toBe('link'); }); it('renders custom components via slots (self-closing tag)', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.custom' }, slots: { anotherTag: () => h('span', { class: 'self-closed' }, 'Self-closed content') }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.html()).toContain('Self-closed content'); expect(wrapper.find('.self-closed').text()).toBe('Self-closed content'); }); it('handles mixed content with multiple custom components', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.mixed' }, slots: { tag1: ({ content }: { content: string }) => h('strong', {}, content), tag2: () => h('em', {}, 'emphasized'), }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.html()).toContain('Text before content1 text in middle emphasized text after.'); expect(wrapper.find('strong').text()).toBe('content1'); expect(wrapper.find('em').text()).toBe('emphasized'); }); it('renders correctly when translation is not a string', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.noString' }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.text()).toBe('123'); expect(wrapper.html()).toContain('123'); }); it('uses the specified root tag', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.simple', tag: 'div', }, global: { plugins: [mockI18nStore] }, }); expect(wrapper.html()).toContain('
Hello World
'); expect(wrapper.find('div').exists()).toBe(true); expect(wrapper.find('span').exists()).toBe(true); // Inner span for content }); it('falls back to raw tag content if slot is not provided for enclosing tag', () => { const wrapper = mount(RichTranslation, { props: { k: 'test.custom' }, // Contains and // No slots provided global: { plugins: [mockI18nStore] }, }); expect(wrapper.find('a').exists()).toBe(false); // Should not render as }); });