users-invite-dialog.test.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { useState } from 'react'
  2. import { describe, expect, it, vi } from 'vitest'
  3. import { render } from 'vitest-browser-react'
  4. import { userEvent } from 'vitest/browser'
  5. import { showSubmittedData } from '@/lib/show-submitted-data'
  6. import { UsersInviteDialog } from './users-invite-dialog'
  7. vi.mock('@/lib/show-submitted-data', () => ({ showSubmittedData: vi.fn() }))
  8. describe('UsersInviteDialog', () => {
  9. it('renders the dialog title and description', async () => {
  10. const { getByRole, getByText } = await render(
  11. <UsersInviteDialog open onOpenChange={vi.fn()} />
  12. )
  13. const title = getByRole('heading', {
  14. level: 2,
  15. name: /Invite User/i,
  16. })
  17. const desc = getByText(/Invite new user to join your team/i)
  18. await expect.element(title).toBeInTheDocument()
  19. await expect.element(desc).toBeInTheDocument()
  20. })
  21. it('closes when the dialog close button is clicked', async () => {
  22. const onOpenChange = vi.fn()
  23. const { getByRole } = await render(
  24. <UsersInviteDialog open onOpenChange={onOpenChange} />
  25. )
  26. const closeButton = getByRole('button', { name: /Close/i })
  27. await userEvent.click(closeButton)
  28. expect(onOpenChange).toHaveBeenCalledOnce()
  29. expect(onOpenChange).toHaveBeenCalledWith(false)
  30. })
  31. it('closes when Cancel is clicked', async () => {
  32. const onOpenChange = vi.fn()
  33. const { getByRole } = await render(
  34. <UsersInviteDialog open onOpenChange={onOpenChange} />
  35. )
  36. const cancelButton = getByRole('button', { name: /Cancel/i })
  37. await userEvent.click(cancelButton)
  38. expect(onOpenChange).toHaveBeenCalledOnce()
  39. expect(onOpenChange).toHaveBeenCalledWith(false)
  40. })
  41. it('shows error messages when submitting empty form, and clears them as fields are filled', async () => {
  42. const onOpenChange = vi.fn()
  43. const { getByRole, getByText } = await render(
  44. <UsersInviteDialog open onOpenChange={onOpenChange} />
  45. )
  46. const emailErrorMessage = getByText(/Please enter an email to invite./i)
  47. const roleErrorMessage = getByText(/Role is required./i)
  48. const submitButton = getByRole('button', { name: /Invite/i })
  49. await userEvent.click(submitButton)
  50. await expect.element(emailErrorMessage).toBeInTheDocument()
  51. await expect.element(roleErrorMessage).toBeInTheDocument()
  52. const emailInput = getByRole('textbox', { name: /Email/i })
  53. await userEvent.fill(emailInput, 'test@example.com')
  54. const roleSelect = getByRole('combobox', { name: /Role/i })
  55. await userEvent.click(roleSelect)
  56. await userEvent.click(getByRole('option', { name: /Superadmin/i }))
  57. await expect.element(emailErrorMessage).not.toBeInTheDocument()
  58. await expect.element(roleErrorMessage).not.toBeInTheDocument()
  59. })
  60. it('resets entered values when the dialog is closed and reopened', async () => {
  61. function Harness() {
  62. const [open, setOpen] = useState(true)
  63. return (
  64. <>
  65. <button type='button' onClick={() => setOpen(true)}>
  66. Reopen
  67. </button>
  68. <UsersInviteDialog open={open} onOpenChange={setOpen} />
  69. </>
  70. )
  71. }
  72. const { getByRole } = await render(<Harness />)
  73. const EMAIL_VALUE = 'test@example.com'
  74. const ROLE_VALUE = 'Superadmin'
  75. const DESC_VALUE = 'This is a test description'
  76. const emailInput = getByRole('textbox', { name: /Email/i })
  77. await userEvent.fill(emailInput, EMAIL_VALUE)
  78. const roleSelect = getByRole('combobox', { name: /Role/i })
  79. await userEvent.click(roleSelect)
  80. await userEvent.click(getByRole('option', { name: ROLE_VALUE }))
  81. const descInput = getByRole('textbox', { name: /Description/i })
  82. await userEvent.fill(descInput, DESC_VALUE)
  83. await expect.element(emailInput).toHaveValue(EMAIL_VALUE)
  84. await expect.element(roleSelect).toHaveTextContent(ROLE_VALUE)
  85. await expect.element(descInput).toHaveValue(DESC_VALUE)
  86. const cancelButton = getByRole('button', { name: /Cancel/i })
  87. await userEvent.click(cancelButton)
  88. const reopenButton = getByRole('button', { name: /Reopen/i })
  89. await userEvent.click(reopenButton)
  90. await expect.element(emailInput).toHaveValue('')
  91. await expect.element(roleSelect).toHaveTextContent('Select a role')
  92. await expect.element(descInput).toHaveValue('')
  93. })
  94. it('shows submitted data when the form is submitted successfully', async () => {
  95. const onOpenChange = vi.fn()
  96. const { getByRole } = await render(
  97. <UsersInviteDialog open onOpenChange={onOpenChange} />
  98. )
  99. const EMAIL_VALUE = 'test@example.com'
  100. const ROLE_VALUE = 'superadmin'
  101. const DESC_VALUE = 'Welcome aboard!'
  102. const emailInput = getByRole('textbox', { name: /Email/i })
  103. await userEvent.fill(emailInput, EMAIL_VALUE)
  104. const roleSelect = getByRole('combobox', { name: /Role/i })
  105. await userEvent.click(roleSelect)
  106. await userEvent.click(getByRole('option', { name: ROLE_VALUE }))
  107. const descInput = getByRole('textbox', { name: /Description/i })
  108. await userEvent.fill(descInput, DESC_VALUE)
  109. const submitButton = getByRole('button', { name: /Invite/i })
  110. await userEvent.click(submitButton)
  111. expect(onOpenChange).toHaveBeenCalledOnce()
  112. expect(onOpenChange).toHaveBeenCalledWith(false)
  113. expect(showSubmittedData).toHaveBeenCalledOnce()
  114. expect(showSubmittedData).toHaveBeenCalledWith({
  115. email: EMAIL_VALUE,
  116. role: ROLE_VALUE,
  117. desc: DESC_VALUE,
  118. })
  119. })
  120. })