guided-setup-manual-invite.spec.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { flushPromises } from '@vue/test-utils'
  3. import { mockApplicationConfig } from '#tests/support/mock-applicationConfig.ts'
  4. import { visitView } from '#tests/support/components/visitView.ts'
  5. import { EnumSystemSetupInfoStatus } from '#shared/graphql/types.ts'
  6. import { mockAuthentication } from '#tests/support/mock-authentication.ts'
  7. import { mockPermissions } from '#tests/support/mock-permissions.ts'
  8. import { mockFormUpdaterQuery } from '#shared/components/Form/graphql/queries/formUpdater.mocks.ts'
  9. import {
  10. mockUserAddMutation,
  11. waitForUserAddMutationCalls,
  12. } from '#shared/entities/user/graphql/mutations/add.mocks.ts'
  13. import { getAllByRole, getByRole, queryByRole } from '@testing-library/vue'
  14. import { mockSystemSetupInfoQuery } from '../graphql/queries/systemSetupInfo.mocks.ts'
  15. describe('guided setup manual invite', () => {
  16. describe('when system is not ready', () => {
  17. beforeEach(() => {
  18. mockApplicationConfig({
  19. system_init_done: false,
  20. })
  21. })
  22. it('redirects to guided setup start', async () => {
  23. mockSystemSetupInfoQuery({
  24. systemSetupInfo: {
  25. status: EnumSystemSetupInfoStatus.New,
  26. type: null,
  27. },
  28. })
  29. const view = await visitView('/guided-setup/manual/invite')
  30. await vi.waitFor(() => {
  31. expect(
  32. view,
  33. 'correctly redirects to guided setup start screen',
  34. ).toHaveCurrentUrl('/guided-setup')
  35. })
  36. view.getByText('Set up a new system')
  37. })
  38. })
  39. describe('when system is ready for optional steps', () => {
  40. beforeEach(() => {
  41. mockApplicationConfig({
  42. system_init_done: true,
  43. })
  44. mockPermissions(['admin'])
  45. mockAuthentication(true)
  46. mockFormUpdaterQuery({
  47. formUpdater: {
  48. role_ids: {
  49. initialValue: [2],
  50. options: [
  51. {
  52. value: 1,
  53. label: 'Admin',
  54. description: 'To configure your system.',
  55. },
  56. {
  57. value: 2,
  58. label: 'Agent',
  59. description: 'To work on Tickets.',
  60. },
  61. {
  62. value: 3,
  63. label: 'Customer',
  64. description: 'People who create Tickets ask for help.',
  65. },
  66. ],
  67. },
  68. group_ids: {
  69. options: [
  70. {
  71. value: 1,
  72. label: 'Users',
  73. },
  74. {
  75. value: 2,
  76. label: 'some group1',
  77. },
  78. ],
  79. },
  80. },
  81. })
  82. })
  83. it('can invite user and rerender the form', async () => {
  84. const view = await visitView('/guided-setup/manual/invite')
  85. await flushPromises()
  86. expect(view.getByText('Invite Colleagues')).toBeInTheDocument()
  87. expect(view.getByLabelText('First name')).toBeInTheDocument()
  88. expect(view.getByLabelText('Last name')).toBeInTheDocument()
  89. expect(view.getByLabelText('Email')).toBeInTheDocument()
  90. expect(view.getByLabelText('Roles')).toBeInTheDocument()
  91. expect(view.getByLabelText('Group permissions')).toBeInTheDocument()
  92. expect(
  93. view.getByRole('button', { name: 'Finish Setup' }),
  94. ).toBeInTheDocument()
  95. await view.events.type(view.getByLabelText('Email'), 'test@example.com')
  96. await view.events.click(view.getAllByRole('switch')[2])
  97. const groupPermissions = view.getByLabelText('Group permissions')
  98. const combobox = getByRole(groupPermissions, 'combobox')
  99. await view.events.click(combobox)
  100. const listbox = view.getByRole('listbox')
  101. const options = getAllByRole(listbox, 'option')
  102. await view.events.click(options[0])
  103. await view.events.click(view.getByLabelText('Full'))
  104. expect(view.getByLabelText('Email')).toHaveValue('test@example.com')
  105. expect(view.getAllByRole('switch')[2]).toHaveAttribute(
  106. 'aria-checked',
  107. 'true',
  108. )
  109. expect(queryByRole(combobox, 'listitem')).toBeInTheDocument()
  110. expect(view.getByLabelText('Full')).toBeChecked()
  111. const inviteButton = view.getByRole('button', {
  112. name: 'Send Invitation',
  113. })
  114. await view.events.click(inviteButton)
  115. const calls = await waitForUserAddMutationCalls()
  116. expect(calls.at(-1)?.variables).toEqual({
  117. input: {
  118. firstname: '',
  119. lastname: '',
  120. email: 'test@example.com',
  121. roleIds: ['gid://zammad/Role/2', 'gid://zammad/Role/3'],
  122. groupIds: [
  123. {
  124. groupInternalId: 1,
  125. accessType: ['full'],
  126. },
  127. ],
  128. objectAttributeValues: [],
  129. },
  130. sendInvite: true,
  131. })
  132. expect(await view.findByText('Invitation sent!')).toBeInTheDocument()
  133. expect(view.getByLabelText('Email')).toHaveValue('')
  134. expect(view.getAllByRole('switch')[2]).not.toHaveAttribute(
  135. 'aria-checked',
  136. 'true',
  137. )
  138. expect(queryByRole(combobox, 'listitem')).not.toBeInTheDocument()
  139. expect(view.getByLabelText('Full')).not.toBeChecked()
  140. expect(
  141. view,
  142. 'stays on the guided setup manual invite step',
  143. ).toHaveCurrentUrl('/guided-setup/manual/invite')
  144. })
  145. it('can display form errors', async () => {
  146. const view = await visitView('/guided-setup/manual/invite')
  147. mockUserAddMutation({
  148. userAdd: {
  149. user: null,
  150. errors: [
  151. {
  152. message:
  153. 'At least one identifier (firstname, lastname, phone or email) for user is required.',
  154. field: null,
  155. },
  156. ],
  157. },
  158. })
  159. const inviteButton = view.getByRole('button', {
  160. name: 'Send Invitation',
  161. })
  162. await view.events.click(inviteButton)
  163. expect(
  164. view.getByText(
  165. 'At least one identifier (firstname, lastname, phone or email) for user is required.',
  166. ),
  167. ).toHaveRole('alert')
  168. })
  169. it('redirects to guided setup finish screen when continued', async () => {
  170. const view = await visitView('/guided-setup/manual/invite')
  171. await view.events.click(
  172. view.getByRole('button', { name: 'Finish Setup' }),
  173. )
  174. await vi.waitFor(() => {
  175. expect(
  176. view,
  177. 'correctly redirects to guided setup finish screen',
  178. ).toHaveCurrentUrl('/guided-setup/manual/finish')
  179. })
  180. })
  181. })
  182. })