OrganizationInvite.utils.test.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { describe, expect, test } from 'vitest'
  2. import {
  3. getOrganizationInviteContent,
  4. getOrganizationInviteStatus,
  5. type OrganizationInviteStatus,
  6. } from '@/components/interfaces/OrganizationInvite/OrganizationInvite.utils'
  7. import type { OrganizationInviteByToken } from '@/data/organization-members/organization-invitation-token-query'
  8. import type { ResponseError } from '@/types'
  9. const READY_INVITE: OrganizationInviteByToken = {
  10. authorized_user: true,
  11. email_match: true,
  12. expired_token: false,
  13. invite_id: 42,
  14. organization_name: 'Acme Corp',
  15. sso_mismatch: false,
  16. token_does_not_exist: false,
  17. }
  18. const responseError = (message: string, code = 500) => ({ message, code }) as ResponseError
  19. type StatusOverrides = Partial<Parameters<typeof getOrganizationInviteStatus>[0]>
  20. const getStatus = (overrides: StatusOverrides = {}) =>
  21. getOrganizationInviteStatus({
  22. data: READY_INVITE,
  23. error: null,
  24. isErrorInvitation: false,
  25. isLoadingInvitation: false,
  26. isLoadingProfile: false,
  27. isLoggedIn: true,
  28. isRouterReady: true,
  29. isSuccessInvitation: true,
  30. profileExists: true,
  31. ...overrides,
  32. })
  33. describe('OrganizationInvite utils', () => {
  34. test.each<[string, OrganizationInviteStatus, StatusOverrides]>([
  35. ['signed out when there is no current user', 'signed-out', { isLoggedIn: false }],
  36. ['loading while the profile is loading', 'loading', { isLoadingProfile: true }],
  37. ['loading while the invite is loading', 'loading', { isLoadingInvitation: true }],
  38. [
  39. 'no longer valid for accepted or declined invites',
  40. 'no-longer-valid',
  41. {
  42. data: undefined,
  43. error: responseError('Failed to retrieve organization', 401),
  44. isErrorInvitation: true,
  45. isSuccessInvitation: false,
  46. },
  47. ],
  48. [
  49. 'invalid when the API returns a missing token response',
  50. 'invalid',
  51. {
  52. data: { ...READY_INVITE, token_does_not_exist: true },
  53. },
  54. ],
  55. [
  56. 'invalid when the invite lookup 404s',
  57. 'invalid',
  58. {
  59. data: undefined,
  60. error: responseError('Not Found', 404),
  61. isErrorInvitation: true,
  62. isSuccessInvitation: false,
  63. },
  64. ],
  65. [
  66. 'error for other API failures',
  67. 'error',
  68. {
  69. data: undefined,
  70. error: responseError('Failed to retrieve token', 500),
  71. isErrorInvitation: true,
  72. isSuccessInvitation: false,
  73. },
  74. ],
  75. [
  76. 'expired when the token has expired',
  77. 'expired',
  78. {
  79. data: { ...READY_INVITE, expired_token: true },
  80. },
  81. ],
  82. [
  83. 'wrong account when the invite email does not match',
  84. 'wrong-account',
  85. {
  86. data: { ...READY_INVITE, email_match: false },
  87. },
  88. ],
  89. ['ready when the invite can be accepted', 'ready', {}],
  90. ])('returns %s', (_name, expected, overrides) => {
  91. expect(getStatus(overrides)).toBe(expected)
  92. })
  93. test.each<[OrganizationInviteStatus, string, string | undefined]>([
  94. ['signed-out', 'View invitation', 'Sign in or create an account to view this invitation'],
  95. ['ready', 'Join Acme Corp', 'You have been invited to join this Briven organization'],
  96. ['wrong-account', 'Wrong account', undefined],
  97. ['expired', 'Invite expired', undefined],
  98. ['invalid', 'Invite invalid', undefined],
  99. ['no-longer-valid', 'Invite no longer available', undefined],
  100. ['error', 'Unable to load invitation', undefined],
  101. ])('returns content for %s', (status, title, description) => {
  102. expect(
  103. getOrganizationInviteContent({
  104. data: READY_INVITE,
  105. isSignUpEnabled: true,
  106. status,
  107. })
  108. ).toEqual({ title, ...(description ? { description } : {}) })
  109. })
  110. test('omits sign-up copy when sign-up is disabled', () => {
  111. expect(
  112. getOrganizationInviteContent({
  113. data: READY_INVITE,
  114. isSignUpEnabled: false,
  115. status: 'signed-out',
  116. }).description
  117. ).toBe('Sign in to view this invitation')
  118. })
  119. })