visitView.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { useApolloClient } from '@vue/apollo-composable'
  3. import { random } from 'lodash-es'
  4. // import authenticationGuard from '#shared/router/guards/before/authentication.ts'
  5. // import permissionGuard from '#shared/router/guards/before/permission.ts'
  6. import { useNotifications } from '#shared/components/CommonNotifications/useNotifications.ts'
  7. import { useLocaleStore } from '#shared/stores/locale.ts'
  8. import mockApolloClient from '../mock-apollo-client.ts'
  9. import LayoutTestDesktopView from './LayoutTestDesktopView.vue'
  10. import LayoutTestMobileView from './LayoutTestMobileView.vue'
  11. import renderComponent, {
  12. getHistory,
  13. getTestRouter,
  14. type ExtendedMountingOptions,
  15. } from './renderComponent.ts'
  16. import type { NavigationGuard, RouteRecordRaw } from 'vue-router'
  17. const isDesktop = await vi.hoisted(async () => {
  18. const { getTestAppName } = await import('./app.ts')
  19. return getTestAppName() === 'desktop'
  20. })
  21. vi.mock('#shared/server/apollo/client.ts', async () => {
  22. if (isDesktop) {
  23. const { mockedApolloClient } = await import(
  24. '#tests/graphql/builders/mocks.ts'
  25. )
  26. return {
  27. clearApolloClientStore: async () => {
  28. await mockedApolloClient.clearStore()
  29. },
  30. getApolloClient: () => mockedApolloClient,
  31. }
  32. }
  33. return {
  34. clearApolloClientStore: () => {
  35. return Promise.resolve()
  36. },
  37. getApolloClient: () => {
  38. return {
  39. cache: {
  40. gc: () => [],
  41. },
  42. }
  43. },
  44. }
  45. })
  46. Object.defineProperty(window, 'fetch', {
  47. value: (path: string) => {
  48. throw new Error(`calling fetch on ${path}`)
  49. },
  50. writable: true,
  51. configurable: true,
  52. })
  53. const html = String.raw
  54. interface VisitViewOptions extends ExtendedMountingOptions<unknown> {
  55. mockApollo?: boolean
  56. setLocale?: boolean
  57. }
  58. const { routes } = isDesktop
  59. ? await import('#desktop/router/index.ts')
  60. : await import('#mobile/router/index.ts')
  61. // remove LayoutMain layout, keep only actual content
  62. if (routes.at(-1)?.name === 'Main') {
  63. const [mainRoutes] = routes.splice(routes.length - 1, 1)
  64. routes.push(...(mainRoutes.children as RouteRecordRaw[]), {
  65. path: '/testing-environment',
  66. component: {
  67. template: '<div></div>',
  68. },
  69. })
  70. }
  71. // Always reset again before each renderComponent call. With this we
  72. // have an initial route for each test.
  73. const routerBeforeGuards: NavigationGuard[] = []
  74. // TODO: disable some stuff for now, because it will break a lot of test.
  75. // const routerBeforeGuards = [authenticationGuard, permissionGuard]
  76. if (isDesktop) {
  77. // Always reset again before each renderComponent call. With this we
  78. // have an initial route for each test.
  79. // const { default: systemSetupInfo } = await import(
  80. // '#desktop/router/guards/before/systemSetupInfo.ts'
  81. // )
  82. // routerBeforeGuards.push(systemSetupInfo)
  83. const { default: activeTaskbarTab } = await import(
  84. '#desktop/router/guards/before/activeTaskbarTab.ts'
  85. )
  86. routerBeforeGuards.push(activeTaskbarTab)
  87. }
  88. export const visitView = async (
  89. href: string,
  90. // rely on new way to mock apollo in desktop by default
  91. options: VisitViewOptions = { mockApollo: !isDesktop, setLocale: isDesktop },
  92. ) => {
  93. if (options.mockApollo) {
  94. mockApolloClient([])
  95. } else if (isDesktop) {
  96. // automocking is enabled when this file is imported because it happens on the top level
  97. await import('#tests/graphql/builders/mocks.ts')
  98. }
  99. // Reset the initial navigation state and the initial route.
  100. const testKey = random()
  101. useNotifications().clearAllNotifications()
  102. const history = getHistory()
  103. history.replace(href)
  104. const view = renderComponent(
  105. {
  106. template: html` <LayoutTest${isDesktop
  107. ? 'DesktopView'
  108. : 'MobileView'} />`,
  109. components: {
  110. LayoutTestDesktopView,
  111. LayoutTestMobileView,
  112. },
  113. },
  114. {
  115. store: true,
  116. router: true,
  117. form: true,
  118. unmount: true,
  119. routerRoutes: routes,
  120. routerBeforeGuards,
  121. propsData: {
  122. testKey,
  123. },
  124. ...options,
  125. },
  126. )
  127. const { client } = useApolloClient()
  128. await client.clearStore()
  129. const router = getTestRouter()
  130. // we don't call router.replace(href) here because it's called by the router plugin when mounting
  131. // and it gets the correct href from the `history` object
  132. await router.isReady()
  133. if (options.setLocale) {
  134. await useLocaleStore().setLocale()
  135. }
  136. return view
  137. }