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

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