import { describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia } from 'pinia'
import AppShellV2 from '@/layouts/components/AppShellV2.vue'
describe('AppShellV2 (skeleton)', () => {
it('renders the grid regions and default slot content', () => {
const wrapper = mount(AppShellV2, {
global: { plugins: [createPinia()] },
slots: {
sidebar: '',
topbar: '',
default: 'CONTENT',
drawer: '',
},
})
expect(wrapper.find('[data-testid="appshell-v2"]').exists()).toBe(true)
expect(wrapper.find('[data-testid="sb"]').exists()).toBe(true)
expect(wrapper.find('[data-testid="tb"]').exists()).toBe(true)
expect(wrapper.find('[data-testid="content"]').text()).toBe('CONTENT')
expect(wrapper.find('[data-testid="dr"]').exists()).toBe(true)
})
it('applies the collapsed modifier from useShellUiStore', async () => {
const pinia = createPinia()
const wrapper = mount(AppShellV2, { global: { plugins: [pinia] } })
const { useShellUiStore } = await import('@/stores/useShellUiStore')
useShellUiStore().toggleSidebar()
await wrapper.vm.$nextTick()
expect(wrapper.find('[data-testid="appshell-v2"]').classes()).toContain('is-collapsed')
})
// Plan 2.5 P8 dedupe — AppShellV2's watch([theme, density]) is the single
// applyDomAttributes() authority. toggleDensity() (useShellUiStore) no longer
// writes the DOM itself; the watch covers it. These specs lock that contract:
// the density change reaches via the watch, and exactly one
// applyDomAttributes() call fires per toggle (no redundant double-call).
it('watch writes the toggled density to ', async () => {
document.documentElement.removeAttribute('data-density')
const pinia = createPinia()
const wrapper = mount(AppShellV2, { global: { plugins: [pinia] } })
const { useShellUiStore } = await import('@/stores/useShellUiStore')
const shell = useShellUiStore()
// onMounted seeded the comfortable default.
expect(document.documentElement.getAttribute('data-density')).toBe('comfortable')
shell.toggleDensity()
await wrapper.vm.$nextTick()
expect(document.documentElement.getAttribute('data-density')).toBe('compact')
})
it('density toggle fires applyDomAttributes exactly once (via the watch, not toggleDensity)', async () => {
const pinia = createPinia()
const wrapper = mount(AppShellV2, { global: { plugins: [pinia] } })
const { useShellUiStore } = await import('@/stores/useShellUiStore')
const shell = useShellUiStore()
// Spy AFTER mount so the onMounted seed call is excluded from the count.
const spy = vi.spyOn(shell, 'applyDomAttributes')
shell.toggleDensity()
await wrapper.vm.$nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
})