import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import AppLayout from '../../components/AppLayout.vue'
describe('AppLayout', () => {
describe('rendering with default props', () => {
it('should render layout with default classes', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout').exists()).toBe(true)
expect(wrapper.find('.mint-layout--sidebar-right').exists()).toBe(false)
expect(wrapper.find('.mint-layout--floating').exists()).toBe(false)
})
it('should render body container', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout__body').exists()).toBe(true)
})
it('should render main content slot', () => {
const wrapper = mount(AppLayout, {
slots: {
default: '
Main content
',
},
})
expect(wrapper.find('.mint-layout__main').exists()).toBe(true)
expect(wrapper.find('.mint-layout__main').text()).toBe('Main content')
})
})
describe('topbar slot', () => {
it('should render topbar when slot is provided', () => {
const wrapper = mount(AppLayout, {
slots: {
topbar: 'Topbar
',
},
})
expect(wrapper.find('.mint-layout__topbar').exists()).toBe(true)
expect(wrapper.find('.custom-topbar').text()).toBe('Topbar')
})
it('should not render topbar when slot is not provided', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout__topbar').exists()).toBe(false)
})
})
describe('sidebar slot', () => {
it('should render sidebar when slot is provided', () => {
const wrapper = mount(AppLayout, {
slots: {
sidebar: '',
},
})
expect(wrapper.find('.mint-layout__sidebar').exists()).toBe(true)
expect(wrapper.find('.custom-sidebar').text()).toBe('Sidebar')
})
it('should not render sidebar when slot is not provided', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout__sidebar').exists()).toBe(false)
})
})
describe('sidebarPosition prop', () => {
it('should default to left position', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout--sidebar-right').exists()).toBe(false)
})
it('should add right class when sidebarPosition is right', () => {
const wrapper = mount(AppLayout, {
props: { sidebarPosition: 'right' },
})
expect(wrapper.find('.mint-layout--sidebar-right').exists()).toBe(true)
})
it('should not add right class when sidebarPosition is left', () => {
const wrapper = mount(AppLayout, {
props: { sidebarPosition: 'left' },
})
expect(wrapper.find('.mint-layout--sidebar-right').exists()).toBe(false)
})
})
describe('floating prop', () => {
it('should not add floating class by default', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout--floating').exists()).toBe(false)
})
it('should add floating class when floating is true', () => {
const wrapper = mount(AppLayout, {
props: { floating: true },
})
expect(wrapper.find('.mint-layout--floating').exists()).toBe(true)
})
})
describe('sidebar width styling', () => {
it('should not apply inline width when default auto is used', () => {
const wrapper = mount(AppLayout, {
slots: { sidebar: 'Sidebar
' },
})
const sidebar = wrapper.find('.mint-layout__sidebar')
expect(sidebar.attributes('style')).toBeUndefined()
})
it('should apply custom sidebar width', () => {
const wrapper = mount(AppLayout, {
props: { sidebarWidth: '300px' },
slots: { sidebar: 'Sidebar
' },
})
const sidebar = wrapper.find('.mint-layout__sidebar')
expect(sidebar.attributes('style')).toContain('width: 300px')
})
it('should handle width with different CSS units', () => {
const wrapper = mount(AppLayout, {
props: { sidebarWidth: '20rem' },
slots: { sidebar: 'Sidebar
' },
})
const sidebar = wrapper.find('.mint-layout__sidebar')
expect(sidebar.attributes('style')).toContain('width: 20rem')
})
})
describe('responsive sidebar shell', () => {
it('does not render mobile toggle by default', () => {
const wrapper = mount(AppLayout, {
slots: { sidebar: 'Sidebar
' },
})
expect(wrapper.find('.mint-layout__sidebar-toggle').exists()).toBe(false)
expect(wrapper.find('.mint-layout--responsive-sidebar').exists()).toBe(false)
})
it('renders a mobile toggle when responsiveSidebar is enabled', async () => {
const wrapper = mount(AppLayout, {
props: { responsiveSidebar: true },
slots: { sidebar: 'Sidebar
' },
})
const toggle = wrapper.get('.mint-layout__sidebar-toggle')
expect(toggle.attributes('aria-expanded')).toBe('false')
expect(wrapper.find('.mint-layout__sidebar-backdrop').exists()).toBe(false)
await toggle.trigger('click')
expect(wrapper.find('.mint-layout--sidebar-open').exists()).toBe(true)
expect(wrapper.get('.mint-layout__sidebar-toggle').attributes('aria-expanded')).toBe('true')
expect(wrapper.find('.mint-layout__sidebar-backdrop').exists()).toBe(true)
expect(wrapper.emitted('update:sidebarOpen')).toEqual([[true]])
})
it('supports controlled mobile sidebar open state and closes from backdrop', async () => {
const wrapper = mount(AppLayout, {
props: {
responsiveSidebar: true,
sidebarOpen: true,
},
slots: { sidebar: 'Sidebar
' },
})
expect(wrapper.find('.mint-layout--sidebar-open').exists()).toBe(true)
await wrapper.get('.mint-layout__sidebar-backdrop').trigger('click')
expect(wrapper.emitted('update:sidebarOpen')).toEqual([[false]])
})
})
describe('integration: all slots', () => {
it('should render topbar, sidebar, and main content together', () => {
const wrapper = mount(AppLayout, {
slots: {
topbar: 'Header
',
sidebar: '',
default: 'Content
',
},
})
expect(wrapper.find('.topbar-content').text()).toBe('Header')
expect(wrapper.find('.sidebar-content').text()).toBe('Sidebar')
expect(wrapper.find('.main-content').text()).toBe('Content')
})
it('should apply multiple modifier classes', () => {
const wrapper = mount(AppLayout, {
props: {
sidebarPosition: 'right',
floating: true,
},
})
const layout = wrapper.find('.mint-layout')
expect(layout.classes()).toContain('mint-layout--sidebar-right')
expect(layout.classes()).toContain('mint-layout--floating')
})
})
describe('edge cases', () => {
it('should handle empty default slot', () => {
const wrapper = mount(AppLayout)
expect(wrapper.find('.mint-layout__main').exists()).toBe(true)
expect(wrapper.find('.mint-layout__main').text()).toBe('')
})
})
})