useOverlayContainer.spec.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { flushPromises, mount } from '@vue/test-utils'
  3. import {
  4. destroyComponent,
  5. pushComponent,
  6. } from '#shared/components/DynamicInitializer/manage.ts'
  7. import {
  8. getOverlayContainerMeta,
  9. useOverlayContainer,
  10. } from '../useOverlayContainer.ts'
  11. vi.mock('#shared/components/DynamicInitializer/manage.ts', () => {
  12. return {
  13. destroyComponent: vi.fn(),
  14. pushComponent: vi.fn(),
  15. }
  16. })
  17. const inContext = (fn: () => void) => {
  18. const component = {
  19. setup() {
  20. fn()
  21. return () => null
  22. },
  23. }
  24. return mount(component)
  25. }
  26. describe('use dialog usage', () => {
  27. beforeEach(() => {
  28. const { options } = getOverlayContainerMeta('dialog')
  29. options.clear()
  30. })
  31. test('name and component are required', () => {
  32. // @ts-expect-error - component is required
  33. useOverlayContainer('dialog', { name: 'name' })
  34. // @ts-expect-error - name is required
  35. useOverlayContainer('dialog', {
  36. component: vi.fn(),
  37. })
  38. useOverlayContainer('dialog', {
  39. name: 'name',
  40. component: vi.fn(),
  41. })
  42. })
  43. test('adds and removes meta data', async () => {
  44. const vm = inContext(() => {
  45. useOverlayContainer('dialog', {
  46. name: 'name',
  47. component: vi.fn(),
  48. })
  49. })
  50. const { options } = getOverlayContainerMeta('dialog')
  51. expect(options.size).toBe(1)
  52. expect(options.has('name')).toBe(true)
  53. vm.unmount()
  54. await flushPromises()
  55. expect(options.size).toBe(0)
  56. expect(options.has('name')).toBe(false)
  57. })
  58. test('opens and closes dialog', async () => {
  59. const component = vi.fn().mockResolvedValue({})
  60. const dialog = useOverlayContainer('dialog', {
  61. name: 'name',
  62. component,
  63. })
  64. await dialog.open()
  65. const { opened } = getOverlayContainerMeta('dialog')
  66. expect(dialog.isOpened.value).toBe(true)
  67. expect(component).toHaveBeenCalled()
  68. expect(opened.value.has('name')).toBe(true)
  69. expect(pushComponent).toHaveBeenCalledWith(
  70. 'dialog',
  71. 'name',
  72. expect.anything(),
  73. {},
  74. )
  75. await dialog.close()
  76. expect(dialog.isOpened.value).toBe(false)
  77. expect(opened.value.has('name')).toBe(false)
  78. expect(destroyComponent).toHaveBeenCalledWith('dialog', 'name')
  79. })
  80. test('opens and closes already opned dialog', async () => {
  81. const component = vi.fn().mockResolvedValue({})
  82. const dialog = useOverlayContainer('dialog', {
  83. name: 'name',
  84. component,
  85. })
  86. const additionalDialog = useOverlayContainer('dialog', {
  87. name: 'additional-name',
  88. component,
  89. })
  90. await dialog.open()
  91. const { opened } = getOverlayContainerMeta('dialog')
  92. expect(dialog.isOpened.value).toBe(true)
  93. expect(component).toHaveBeenCalled()
  94. expect(opened.value.has('name')).toBe(true)
  95. expect(pushComponent).toHaveBeenCalledWith(
  96. 'dialog',
  97. 'name',
  98. expect.anything(),
  99. {},
  100. )
  101. await additionalDialog.open()
  102. expect(dialog.isOpened.value).toBe(false)
  103. expect(opened.value.has('name')).toBe(false)
  104. expect(destroyComponent).toHaveBeenCalledWith('dialog', 'name')
  105. expect(additionalDialog.isOpened.value).toBe(true)
  106. expect(component).toHaveBeenCalled()
  107. expect(opened.value.has('additional-name')).toBe(true)
  108. expect(pushComponent).toHaveBeenCalledWith(
  109. 'dialog',
  110. 'additional-name',
  111. expect.anything(),
  112. {},
  113. )
  114. })
  115. test('prefetch starts loading', async () => {
  116. const component = vi.fn().mockResolvedValue({})
  117. const dialog = useOverlayContainer('dialog', {
  118. name: 'name',
  119. component,
  120. })
  121. await dialog.prefetch()
  122. expect(component).toHaveBeenCalled()
  123. })
  124. test('hooks are called', async () => {
  125. const component = vi.fn().mockResolvedValue({})
  126. const beforeOpen = vi.fn()
  127. const afterClose = vi.fn()
  128. const dialog = useOverlayContainer('flyout', {
  129. name: 'name',
  130. component,
  131. beforeOpen,
  132. afterClose,
  133. })
  134. await dialog.open()
  135. expect(beforeOpen).toHaveBeenCalled()
  136. expect(afterClose).not.toHaveBeenCalled()
  137. await dialog.close()
  138. expect(afterClose).toHaveBeenCalled()
  139. })
  140. })