123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- import { h } from 'vue'
- import { renderComponent } from '#tests/support/components/index.ts'
- import CommonPopover from '../CommonPopover.vue'
- import CommonPopoverMenu from '../CommonPopoverMenu.vue'
- import { usePopover } from '../usePopover.ts'
- import type { MenuItem } from '../types.ts'
- const html = String.raw
- const fn = vi.fn()
- describe('rendering section', () => {
- it('no output without default slot and items', () => {
- const view = renderComponent(CommonPopoverMenu, {
- props: {
- popover: null,
- headerLabel: 'Test Header',
- },
- router: true,
- })
- expect(view.queryByText('Test Header')).not.toBeInTheDocument()
- })
- it('if have header prop, renders header', () => {
- const view = renderComponent(CommonPopoverMenu, {
- props: {
- popover: null,
- headerLabel: 'Test Header',
- items: [
- {
- label: 'Example',
- },
- ],
- },
- router: true,
- store: true,
- })
- expect(view.getByText('Test Header')).toBeInTheDocument()
- })
- it('if have header slot, renders header', () => {
- const view = renderComponent(CommonPopoverMenu, {
- props: {
- popover: null,
- },
- slots: {
- header: '<div>Test Header</div>',
- default: 'Example',
- },
- router: true,
- })
- expect(view.getByText('Test Header')).toBeInTheDocument()
- })
- it('rendering items', () => {
- const items: MenuItem[] = [
- { key: 'login', link: '/login', label: 'Login' },
- { key: 'dashboard', link: '/', label: 'Link' },
- ]
- const view = renderComponent(CommonPopoverMenu, {
- shallow: false,
- props: {
- popover: null,
- items,
- },
- router: true,
- })
- expect(view.getByText('Login')).toBeInTheDocument()
- expect(view.getByText('Link')).toBeInTheDocument()
- })
- it('rendering only items with permission', () => {
- const items: MenuItem[] = [
- { key: 'login', link: '/login', label: 'Login' },
- { key: 'dashboard', link: '/', label: 'Link', permission: ['example'] },
- ]
- const view = renderComponent(CommonPopoverMenu, {
- shallow: false,
- props: {
- popover: null,
- items,
- },
- router: true,
- })
- expect(view.getByText('Login')).toBeInTheDocument()
- expect(view.queryByText('Link')).not.toBeInTheDocument()
- })
- it('support click handler on item', async () => {
- const clickHandler = vi.fn()
- const items: MenuItem[] = [
- { key: 'example', onClick: clickHandler, label: 'Example' },
- ]
- const view = renderComponent(CommonPopoverMenu, {
- shallow: false,
- props: {
- popover: null,
- items,
- },
- router: true,
- })
- await view.events.click(view.getByText('Example'))
- expect(clickHandler).toHaveBeenCalledOnce()
- })
- it('close popover on click on item or avoid closing', async () => {
- const clickHandlerExample = vi.fn()
- const clickHandlerOther = vi.fn()
- const view = renderComponent({
- components: { CommonPopover, CommonPopoverMenu },
- template: html`
- <CommonPopover ref="popover" :owner="popoverTarget"
- ><CommonPopoverMenu :popover="popover" :items="items"
- /></CommonPopover>
- <button ref="popoverTarget" @click="toggle">Click me</button>
- `,
- setup() {
- const { popover, popoverTarget, toggle } = usePopover()
- const items: MenuItem[] = [
- { key: 'example', onClick: clickHandlerExample, label: 'Example' },
- {
- key: 'other',
- onClick: clickHandlerOther,
- label: 'Other',
- noCloseOnClick: true,
- },
- ]
- return {
- items,
- toggle,
- popover,
- popoverTarget,
- }
- },
- })
- await view.events.click(view.getByText('Click me'))
- expect(view.queryByText('Example')).toBeInTheDocument()
- await view.events.click(view.getByText('Example'))
- expect(clickHandlerExample).toHaveBeenCalledOnce()
- expect(view.queryByText('Example')).not.toBeInTheDocument()
- await view.events.click(view.getByText('Click me'))
- await view.events.click(view.getByText('Other'))
- expect(clickHandlerOther).toHaveBeenCalledOnce()
- expect(view.queryByText('Other')).toBeInTheDocument()
- })
- it('can use an own component for item rendering', async () => {
- const CustomComponent = (props: any) => {
- return h('div', `Example ${props.label}`)
- }
- CustomComponent.props = ['label']
- const items: MenuItem[] = [
- { key: 'menu-item', component: CustomComponent, label: 'Menu item' },
- ]
- const view = renderComponent(CommonPopoverMenu, {
- shallow: false,
- props: {
- popover: null,
- items,
- },
- router: true,
- })
- expect(view.getByText('Example Menu item')).toBeInTheDocument()
- })
- it('yields entity data on show if prop is passed', async () => {
- renderComponent(CommonPopoverMenu, {
- props: {
- popover: null,
- headerLabel: 'Test Header',
- entity: {
- id: 'example',
- name: 'vitest',
- },
- items: [
- {
- label: 'Example',
- show: (event: { id: string; name: string }) => {
- fn(event)
- return true
- },
- },
- ],
- },
- router: true,
- store: true,
- })
- expect(fn).toBeCalledWith({ id: 'example', name: 'vitest' })
- })
- })
|