account.spec.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { getTestRouter } from '#tests/support/components/renderComponent.ts'
  3. import { visitView } from '#tests/support/components/visitView.ts'
  4. import { mockGraphQLApi } from '#tests/support/mock-graphql-api.ts'
  5. import { mockPermissions } from '#tests/support/mock-permissions.ts'
  6. import { setupView } from '#tests/support/mock-user.ts'
  7. import { mockUserCurrent } from '#tests/support/mock-userCurrent.ts'
  8. import { waitUntil, waitUntilApisResolved } from '#tests/support/utils.ts'
  9. import { UserCurrentLocaleDocument } from '#shared/entities/user/current/graphql/mutations/userCurrentLocale.api.ts'
  10. import { ProductAboutDocument } from '#shared/graphql/queries/about.api.ts'
  11. import { TranslationsDocument } from '#shared/graphql/queries/translations.api.ts'
  12. import { EnumTextDirection } from '#shared/graphql/types.ts'
  13. import type { LocalesQuery } from '#shared/graphql/types.ts'
  14. import { useLocaleStore } from '#shared/stores/locale.ts'
  15. const locales: Record<string, LocalesQuery['locales'][number]> = {
  16. de: {
  17. locale: 'de-de',
  18. name: 'Deutsch',
  19. dir: EnumTextDirection.Ltr,
  20. alias: 'de',
  21. active: true,
  22. },
  23. ar: {
  24. locale: 'ar',
  25. name: 'Arabic',
  26. dir: EnumTextDirection.Rtl,
  27. alias: null,
  28. active: true,
  29. },
  30. }
  31. describe('account page', () => {
  32. beforeEach(() => {
  33. mockUserCurrent({
  34. lastname: 'Doe',
  35. firstname: 'John',
  36. })
  37. const locale = useLocaleStore()
  38. locale.localeData = { ...locales.de }
  39. locale.locales = [{ ...locales.de }, { ...locales.ar }]
  40. })
  41. it('can view my account page', async () => {
  42. mockPermissions([
  43. 'user_preferences.avatar',
  44. 'user_preferences.language',
  45. 'admin',
  46. ])
  47. const languageApi = mockGraphQLApi(ProductAboutDocument).willResolve({
  48. productAbout: 'v1.0.0',
  49. })
  50. const view = await visitView('/account')
  51. await waitUntilApisResolved(languageApi)
  52. const mainContent = view.getByTestId('appMain')
  53. expect(mainContent, 'have avatar').toHaveTextContent('JD')
  54. expect(mainContent, 'have my name').toHaveTextContent('John Doe')
  55. expect(mainContent, 'have logout button').toHaveTextContent('Sign out')
  56. expect(mainContent, 'has language').toHaveTextContent('Deutsch')
  57. expect(languageApi.spies.resolve).toHaveBeenCalled()
  58. expect(mainContent, 'has version').toHaveTextContent('v1.0.0')
  59. })
  60. it('can change language', async () => {
  61. mockPermissions(['user_preferences.language'])
  62. const view = await visitView('/account')
  63. const mutationUpdate = mockGraphQLApi(
  64. UserCurrentLocaleDocument,
  65. ).willResolve({
  66. userCurrentLocale: { success: true, errors: null },
  67. })
  68. const translationsMock = mockGraphQLApi(TranslationsDocument).willResolve({
  69. translations: {
  70. isCacheStillValid: true,
  71. cacheKey: 'key',
  72. translations: [],
  73. },
  74. })
  75. await view.events.click(view.getByLabelText('Language'))
  76. await view.events.click(await view.findByText('Arabic'))
  77. await waitUntil(() => mutationUpdate.spies.resolve.mock.calls.length > 0)
  78. expect(mutationUpdate.spies.resolve).toHaveBeenCalledTimes(1)
  79. expect(translationsMock.spies.resolve).toHaveBeenCalledTimes(1)
  80. expect(
  81. mutationUpdate.spies.resolve,
  82. 'updated locale on backend',
  83. ).toHaveBeenCalledWith({ locale: 'ar' })
  84. expect(
  85. translationsMock.spies.resolve,
  86. 'updated translations',
  87. ).toHaveBeenCalledWith(expect.objectContaining({ locale: 'ar' }))
  88. await view.events.click(view.getByLabelText('Language'))
  89. await view.events.click(await view.findByText('Deutsch'))
  90. await waitUntil(() => mutationUpdate.spies.resolve.mock.calls.length > 1)
  91. expect(mutationUpdate.spies.resolve).toHaveBeenCalledTimes(2)
  92. expect(translationsMock.spies.resolve).toHaveBeenCalledTimes(2)
  93. expect(mutationUpdate.spies.resolve).toHaveBeenCalledWith({
  94. locale: 'de-de',
  95. })
  96. expect(translationsMock.spies.resolve).toHaveBeenCalledWith(
  97. expect.objectContaining({
  98. locale: 'de-de',
  99. }),
  100. )
  101. })
  102. it("can't see content without permissions", async () => {
  103. mockPermissions([])
  104. const languageApi = mockGraphQLApi(ProductAboutDocument).willResolve({
  105. productAbout: 'v1.0.0',
  106. })
  107. const view = await visitView('/account')
  108. expect(languageApi.spies.resolve).not.toHaveBeenCalled()
  109. const mainContent = view.getByTestId('appMain')
  110. expect(mainContent).not.toHaveTextContent('Language')
  111. expect(mainContent).not.toHaveTextContent('Version')
  112. expect(mainContent).not.toHaveTextContent('Avatar')
  113. })
  114. })
  115. test('correctly redirects from hash-based routes', async () => {
  116. setupView('agent')
  117. await visitView('/#profile')
  118. const router = getTestRouter()
  119. const route = router.currentRoute.value
  120. expect(route.name).toBe('AccountOverview')
  121. })
  122. test('correctly redirects from hash-based routes', async () => {
  123. setupView('agent')
  124. await visitView('/#profile/avatar')
  125. const router = getTestRouter()
  126. const route = router.currentRoute.value
  127. expect(route.name).toBe('PersonalSettingAvatar')
  128. })