Files
summercms/admin/tests/shell/Breadcrumbs.test.ts
Jakub Zych 1c2a66df45 test(10-05): bring every SPA module, composable and component under Vitest
- 41 unit and component suites under admin/tests/{app,state,shell,list,form,relation,views,ui}
  covering states and a11y roles; every src module is imported by a test
- typed fixture helper assigns each JSON fixture to its generated OpenAPI type
- fix: iconFor ignores inherited object members such as "constructor"
- fix: field controls import ./control instead of the registry (import cycle
  left a renderer unregistered depending on module load order)
- fix: dropdown shows the placeholder for an unknown stored value next to an emptyOption
- fix: list announces a failed schema load even when the rows arrive after it
- tailwind no longer scans admin/tests; boardwalk/dist rebuilt
2026-09-27 17:53:57 +02:00

80 lines
3.2 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
import Breadcrumbs from '../../src/components/shell/Breadcrumbs.vue'
import { setRecordCrumb } from '../../src/state/useBreadcrumbs'
import { setNavigation } from '../../src/state/useNavigation'
import { setSettings } from '../../src/state/useSettings'
import { navigationFixture, settingsFixture } from '../fixtures/typed'
import { resetState, routerAt, signIn } from '../helpers'
async function crumbsAt(path: string) {
await signIn()
setNavigation(navigationFixture.data)
setSettings(settingsFixture.list.data)
const router = await routerAt(path)
const wrapper = mount(Breadcrumbs, { global: { plugins: [router] } })
await flushPromises()
const items = wrapper.findAll('[data-crumb]')
return {
wrapper,
labels: items.map((item) => item.text()),
links: items.map((item) => (item.find('a').exists() ? item.find('a').attributes('href') : null)),
current: items.map((item) => item.find('[aria-current="page"]').exists()),
}
}
beforeEach(() => {
resetState()
})
afterEach(() => {
document.body.innerHTML = ''
})
enableAutoUnmount(afterEach)
describe('breadcrumbs', () => {
it('is a labelled nav listing plugin and controller, the last one current', async () => {
const { wrapper, labels, links, current } = await crumbsAt('/acme/demo/gadgets')
expect(wrapper.find('nav').attributes('aria-label')).toBe('Ścieżka nawigacji')
expect(wrapper.find('ol').exists()).toBe(true)
expect(labels).toEqual(['Demo', 'Gadgets'])
expect(links).toEqual(['/acme/demo/widgets', null])
expect(current).toEqual([false, true])
expect(wrapper.findAll('svg[aria-hidden="true"]')).toHaveLength(1)
})
it('adds the record title on record and create routes only', async () => {
setRecordCrumb('Blue widget')
let crumbs = await crumbsAt('/acme/demo/widgets/1')
expect(crumbs.labels).toEqual(['Demo', 'Widgets', 'Blue widget'])
expect(crumbs.links).toEqual(['/acme/demo/widgets', '/acme/demo/widgets', null])
expect(crumbs.current).toEqual([false, false, true])
setRecordCrumb('New widget')
crumbs = await crumbsAt('/acme/demo/widgets/create')
expect(crumbs.labels).toEqual(['Demo', 'Widgets', 'New widget'])
crumbs = await crumbsAt('/acme/demo/widgets')
expect(crumbs.labels).toEqual(['Demo', 'Widgets'])
})
it('leaves out an empty record title', async () => {
const { labels } = await crumbsAt('/acme/demo/widgets/1')
expect(labels).toEqual(['Demo', 'Widgets'])
})
it('shows Ustawienia and the page label on settings routes', async () => {
expect((await crumbsAt('/settings')).labels).toEqual(['Ustawienia'])
const page = await crumbsAt('/settings/mail')
expect(page.labels).toEqual(['Ustawienia', 'Mail'])
expect(page.links).toEqual(['/settings', null])
expect((await crumbsAt('/settings/unknown')).labels).toEqual(['Ustawienia'])
})
it('is empty outside any permitted plugin', async () => {
expect((await crumbsAt('/acme/secret/things')).labels).toEqual([])
expect((await crumbsAt('/acme/demo/unlisted')).labels).toEqual(['Demo'])
})
})