diff --git a/frontend/src/components/ui/__tests__/EmptyState.test.js b/frontend/src/components/ui/__tests__/EmptyState.test.js new file mode 100644 index 0000000..b9e0a0f --- /dev/null +++ b/frontend/src/components/ui/__tests__/EmptyState.test.js @@ -0,0 +1,80 @@ +import { describe, it, expect } from 'vitest' +import { mount } from '@vue/test-utils' +import EmptyState from '../EmptyState.vue' + +describe('EmptyState', () => { + it('renders headline text from the headline prop', () => { + const w = mount(EmptyState, { + props: { headline: 'Nothing here' }, + global: { stubs: { AppIcon: true } }, + }) + expect(w.text()).toContain('Nothing here') + }) + + it('renders subtext when provided; omits when empty', () => { + const w = mount(EmptyState, { + props: { headline: 'Title', subtext: 'hello' }, + global: { stubs: { AppIcon: true } }, + }) + expect(w.text()).toContain('hello') + + const w2 = mount(EmptyState, { + props: { headline: 'Title' }, + global: { stubs: { AppIcon: true } }, + }) + const paragraphs = w2.findAll('p') + expect(paragraphs.length).toBe(1) + }) + + it('renders AppIcon when icon prop is set; renders no icon when null', () => { + const w = mount(EmptyState, { + props: { headline: 'Title', icon: 'folder' }, + global: { stubs: { AppIcon: true } }, + }) + expect(w.findComponent({ name: 'AppIcon' }).exists()).toBe(true) + + const w2 = mount(EmptyState, { + props: { headline: 'Title', icon: null }, + global: { stubs: { AppIcon: true } }, + }) + expect(w2.findComponent({ name: 'AppIcon' }).exists()).toBe(false) + }) + + it('renders nothing in the CTA area when #cta slot is empty', () => { + const w = mount(EmptyState, { + props: { headline: 'Title' }, + global: { stubs: { AppIcon: true } }, + }) + expect(w.find('button').exists()).toBe(false) + expect(w.find('a').exists()).toBe(false) + }) + + it('renders the #cta slot content when provided', () => { + const w = mount(EmptyState, { + props: { headline: 'Title' }, + slots: { cta: '' }, + global: { stubs: { AppIcon: true } }, + }) + expect(w.find('[data-test="cta-btn"]').exists()).toBe(true) + }) + + it("size='sm' applies the sidebar micro layout (flex container with gap-2)", () => { + const w = mount(EmptyState, { + props: { headline: 'No folders yet', size: 'sm' }, + global: { stubs: { AppIcon: true } }, + }) + const root = w.element + expect(root.classList.contains('flex')).toBe(true) + expect(root.classList.contains('gap-2')).toBe(true) + }) + + it('default size (md) applies the centered layout (text-center py-10)', () => { + const w = mount(EmptyState, { + props: { headline: 'Nothing here' }, + global: { stubs: { AppIcon: true } }, + }) + const root = w.element + expect(root.classList.contains('text-center')).toBe(true) + expect(root.classList.contains('py-10')).toBe(true) + }) +})