import { describe, expect, it } from 'vitest' import { mount } from '@vue/test-utils' import type { DefineComponent } from 'vue' import { Icon as IconifyIcon } from '@iconify/vue' import Drawer from './Drawer.vue' type DrawerProps = { modelValue?: boolean title?: string showClose?: boolean id?: string drawerClass?: string } const DrawerForTest = Drawer as DefineComponent function mountComponent(props: DrawerProps = {}, slots?: Record) { return mount(DrawerForTest, { props, slots, global: { stubs: { Teleport: true, }, }, }) } describe('MalioDrawer', () => { it('does not render when modelValue is false', () => { const wrapper = mountComponent({ modelValue: false }) expect(wrapper.find('[data-test="panel"]').exists()).toBe(false) }) it('renders when modelValue is true', () => { const wrapper = mountComponent({ modelValue: true }) expect(wrapper.find('[data-test="panel"]').exists()).toBe(true) }) it('renders the title', () => { const wrapper = mountComponent({ modelValue: true, title: 'Mon tiroir' }) expect(wrapper.find('h2').text()).toBe('Mon tiroir') }) it('renders slot content', () => { const wrapper = mountComponent( { modelValue: true }, { default: '

Contenu du drawer

' }, ) expect(wrapper.find('[data-test="content"]').text()).toBe('Contenu du drawer') }) it('emits update:modelValue false on backdrop click', async () => { const wrapper = mountComponent({ modelValue: true }) await wrapper.find('[data-test="backdrop"]').trigger('click') expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([false]) }) it('emits update:modelValue false on close button click', async () => { const wrapper = mountComponent({ modelValue: true }) await wrapper.find('[data-test="close-button"]').trigger('click') expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([false]) }) it('shows close button by default', () => { const wrapper = mountComponent({ modelValue: true }) expect(wrapper.find('[data-test="close-button"]').exists()).toBe(true) }) it('hides close button when showClose is false', () => { const wrapper = mountComponent({ modelValue: true, showClose: false }) expect(wrapper.find('[data-test="close-button"]').exists()).toBe(false) }) it('close button renders mdi:close icon', () => { const wrapper = mountComponent({ modelValue: true }) const icon = wrapper.findComponent(IconifyIcon) expect(icon.props('icon')).toBe('mdi:close') }) it('uses custom id when provided', () => { const wrapper = mountComponent({ modelValue: true, id: 'my-drawer' }) expect(wrapper.find('.fixed').attributes('id')).toBe('my-drawer') }) it('generates an id when not provided', () => { const wrapper = mountComponent({ modelValue: true }) const id = wrapper.find('.fixed').attributes('id') expect(id).toMatch(/^malio-drawer-/) }) it('has role="dialog" and aria-modal on panel', () => { const wrapper = mountComponent({ modelValue: true }) const panel = wrapper.find('[data-test="panel"]') expect(panel.attributes('role')).toBe('dialog') expect(panel.attributes('aria-modal')).toBe('true') }) it('aria-labelledby links to title id', () => { const wrapper = mountComponent({ modelValue: true, id: 'test-drawer' }) const panel = wrapper.find('[data-test="panel"]') expect(panel.attributes('aria-labelledby')).toBe('test-drawer-title') expect(wrapper.find('h2').attributes('id')).toBe('test-drawer-title') }) it('applies drawerClass to the panel', () => { const wrapper = mountComponent({ modelValue: true, drawerClass: 'max-w-lg' }) const panel = wrapper.find('[data-test="panel"]') expect(panel.classes()).toContain('max-w-lg') }) it('works in uncontrolled mode', () => { const wrapper = mountComponent() // Without modelValue, defaults to closed expect(wrapper.find('[data-test="panel"]').exists()).toBe(false) }) it('close button has aria-label "Fermer"', () => { const wrapper = mountComponent({ modelValue: true }) expect(wrapper.find('[data-test="close-button"]').attributes('aria-label')).toBe('Fermer') }) })