File size: 2,717 Bytes
6137fac | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount, RouterLinkStub } from '@vue/test-utils'
import { createRouter, createWebHistory } from 'vue-router'
import { setActivePinia, createPinia } from 'pinia'
import Layout from './Layout.vue'
import { useAuthStore } from '../../stores/auth'
vi.mock('../../api', () => ({
default: { post: vi.fn(), defaults: { headers: { common: {} } } },
}))
async function mountLayout(path = '/admin/dashboard') {
setActivePinia(createPinia())
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/admin/login', component: { template: '<div/>' } },
{ path: '/admin/dashboard', component: { template: '<div>dashboard</div>' } },
{ path: '/admin/posts', component: { template: '<div/>' } },
],
})
router.push(path)
await router.isReady()
const wrapper = mount(Layout, {
global: { plugins: [router], stubs: { RouterLink: RouterLinkStub } },
})
return { wrapper, router }
}
describe('Layout (admin)', () => {
beforeEach(() => {
localStorage.clear()
vi.clearAllMocks()
})
it('renders the sidebar nav items and the current user', async () => {
const { wrapper } = await mountLayout()
const auth = useAuthStore()
auth.user = { name: 'Admin User', role: 'admin' }
await wrapper.vm.$nextTick()
expect(wrapper.text()).toContain('Dashboard')
expect(wrapper.text()).toContain('Posts')
expect(wrapper.text()).toContain('Admin User')
})
it('highlights the active nav item', async () => {
const { wrapper } = await mountLayout('/admin/posts')
const links = wrapper.findAllComponents(RouterLinkStub)
const postsLink = links.find(l => l.props('to') === '/admin/posts')
expect(postsLink.classes()).toContain('bg-primary-600')
})
it('logs out and redirects to the login page', async () => {
const { wrapper, router } = await mountLayout()
const pushSpy = vi.spyOn(router, 'push')
const auth = useAuthStore()
const logoutSpy = vi.spyOn(auth, 'logout')
const signOutBtn = wrapper.findAll('button').find(b => b.text().includes('Sign Out'))
await signOutBtn.trigger('click')
expect(logoutSpy).toHaveBeenCalled()
expect(pushSpy).toHaveBeenCalledWith('/admin/login')
})
it('opens and closes the mobile sidebar', async () => {
const { wrapper } = await mountLayout()
const findMobileHeader = () => wrapper.findAll('span').find(s => s.text() === 'Meridian Admin')
expect(findMobileHeader()).toBeUndefined()
const toggleBtn = wrapper.findAll('button').find(b => b.classes().includes('lg:hidden'))
await toggleBtn.trigger('click')
expect(findMobileHeader()).toBeDefined()
})
})
|