@digitaldefiance/express-suite-react-components 5.0.2 → 5.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/package.json +5 -4
  2. package/src/auth/AdminRoute.d.ts +8 -0
  3. package/src/auth/AdminRoute.d.ts.map +1 -0
  4. package/src/auth/AdminRoute.js +28 -0
  5. package/src/auth/Private.d.ts +6 -0
  6. package/src/auth/Private.d.ts.map +1 -0
  7. package/src/auth/Private.js +14 -0
  8. package/src/auth/PrivateRoute.d.ts +8 -0
  9. package/src/auth/PrivateRoute.d.ts.map +1 -0
  10. package/src/auth/PrivateRoute.js +23 -0
  11. package/src/auth/UnAuth.d.ts +6 -0
  12. package/src/auth/UnAuth.d.ts.map +1 -0
  13. package/src/auth/UnAuth.js +14 -0
  14. package/src/auth/UnAuthRoute.d.ts +8 -0
  15. package/src/auth/UnAuthRoute.d.ts.map +1 -0
  16. package/src/auth/UnAuthRoute.js +22 -0
  17. package/src/auth/{index.ts → index.d.ts} +3 -2
  18. package/src/auth/index.d.ts.map +1 -0
  19. package/src/auth/index.js +12 -0
  20. package/src/components/ApiAccess.d.ts +16 -0
  21. package/src/components/ApiAccess.d.ts.map +1 -0
  22. package/src/components/ApiAccess.js +77 -0
  23. package/src/components/BackupCodeLoginForm.d.ts +43 -0
  24. package/src/components/BackupCodeLoginForm.d.ts.map +1 -0
  25. package/src/components/BackupCodeLoginForm.js +139 -0
  26. package/src/components/BackupCodesForm.d.ts +26 -0
  27. package/src/components/BackupCodesForm.d.ts.map +1 -0
  28. package/src/components/BackupCodesForm.js +120 -0
  29. package/src/components/CategoryMenu.d.ts +17 -0
  30. package/src/components/CategoryMenu.d.ts.map +1 -0
  31. package/src/components/CategoryMenu.js +65 -0
  32. package/src/components/ChangePasswordForm.d.ts +26 -0
  33. package/src/components/ChangePasswordForm.d.ts.map +1 -0
  34. package/src/components/ChangePasswordForm.js +78 -0
  35. package/src/components/ConfirmationDialog.d.ts +13 -0
  36. package/src/components/ConfirmationDialog.d.ts.map +1 -0
  37. package/src/components/ConfirmationDialog.js +10 -0
  38. package/src/components/CurrencyCodeSelector.d.ts +9 -0
  39. package/src/components/CurrencyCodeSelector.d.ts.map +1 -0
  40. package/src/components/CurrencyCodeSelector.js +31 -0
  41. package/src/components/CurrencyInput.d.ts +13 -0
  42. package/src/components/CurrencyInput.d.ts.map +1 -0
  43. package/src/components/CurrencyInput.js +22 -0
  44. package/src/components/DashboardPage.d.ts +8 -0
  45. package/src/components/DashboardPage.d.ts.map +1 -0
  46. package/src/components/DashboardPage.js +10 -0
  47. package/src/components/DropdownMenu.d.ts +13 -0
  48. package/src/components/DropdownMenu.d.ts.map +1 -0
  49. package/src/components/DropdownMenu.js +63 -0
  50. package/src/components/ExpirationSecondsSelector.d.ts +13 -0
  51. package/src/components/ExpirationSecondsSelector.d.ts.map +1 -0
  52. package/src/components/ExpirationSecondsSelector.js +32 -0
  53. package/src/components/FakeEmailAdminPanel.d.ts +23 -0
  54. package/src/components/FakeEmailAdminPanel.d.ts.map +1 -0
  55. package/src/components/FakeEmailAdminPanel.js +147 -0
  56. package/src/components/Flag.d.ts +20 -0
  57. package/src/components/Flag.d.ts.map +1 -0
  58. package/src/components/Flag.js +43 -0
  59. package/src/components/ForgotPasswordForm.d.ts +18 -0
  60. package/src/components/ForgotPasswordForm.d.ts.map +1 -0
  61. package/src/components/ForgotPasswordForm.js +61 -0
  62. package/src/components/LoginForm.d.ts +44 -0
  63. package/src/components/LoginForm.d.ts.map +1 -0
  64. package/src/components/LoginForm.js +123 -0
  65. package/src/components/LogoutPage.d.ts +8 -0
  66. package/src/components/LogoutPage.d.ts.map +1 -0
  67. package/src/components/LogoutPage.js +16 -0
  68. package/src/components/RegisterForm.d.ts +100 -0
  69. package/src/components/RegisterForm.d.ts.map +1 -0
  70. package/src/components/RegisterForm.js +306 -0
  71. package/src/components/ResetPasswordForm.d.ts +23 -0
  72. package/src/components/ResetPasswordForm.d.ts.map +1 -0
  73. package/src/components/ResetPasswordForm.js +78 -0
  74. package/src/components/SideMenu.d.ts +8 -0
  75. package/src/components/SideMenu.d.ts.map +1 -0
  76. package/src/components/SideMenu.js +25 -0
  77. package/src/components/SideMenuListItem.d.ts +13 -0
  78. package/src/components/SideMenuListItem.d.ts.map +1 -0
  79. package/src/components/SideMenuListItem.js +44 -0
  80. package/src/components/T.d.ts +7 -0
  81. package/src/components/T.d.ts.map +1 -0
  82. package/src/components/T.js +13 -0
  83. package/src/components/TDiv.d.ts +9 -0
  84. package/src/components/TDiv.d.ts.map +1 -0
  85. package/src/components/TDiv.js +14 -0
  86. package/src/components/TImgAlt.d.ts +10 -0
  87. package/src/components/TImgAlt.d.ts.map +1 -0
  88. package/src/components/TImgAlt.js +14 -0
  89. package/src/components/TopMenu.d.ts +50 -0
  90. package/src/components/TopMenu.d.ts.map +1 -0
  91. package/src/components/TopMenu.js +79 -0
  92. package/src/components/TotpSetupForm.d.ts +24 -0
  93. package/src/components/TotpSetupForm.d.ts.map +1 -0
  94. package/src/components/TotpSetupForm.js +82 -0
  95. package/src/components/TotpVerificationForm.d.ts +23 -0
  96. package/src/components/TotpVerificationForm.d.ts.map +1 -0
  97. package/src/components/TotpVerificationForm.js +66 -0
  98. package/src/components/TranslatedTitle.d.ts +8 -0
  99. package/src/components/TranslatedTitle.d.ts.map +1 -0
  100. package/src/components/TranslatedTitle.js +15 -0
  101. package/src/components/UserLanguageSelector.d.ts +4 -0
  102. package/src/components/UserLanguageSelector.d.ts.map +1 -0
  103. package/src/components/UserLanguageSelector.js +31 -0
  104. package/src/components/UserMenu.d.ts +4 -0
  105. package/src/components/UserMenu.d.ts.map +1 -0
  106. package/src/components/UserMenu.js +12 -0
  107. package/src/components/UserSettingsForm.d.ts +113 -0
  108. package/src/components/UserSettingsForm.d.ts.map +1 -0
  109. package/src/components/UserSettingsForm.js +269 -0
  110. package/src/components/VerifyEmailPage.d.ts +24 -0
  111. package/src/components/VerifyEmailPage.d.ts.map +1 -0
  112. package/src/components/VerifyEmailPage.js +81 -0
  113. package/src/components/{index.ts → index.d.ts} +1 -1
  114. package/src/components/index.d.ts.map +1 -0
  115. package/src/components/index.js +35 -0
  116. package/src/contexts/AuthProvider.d.ts +186 -0
  117. package/src/contexts/AuthProvider.d.ts.map +1 -0
  118. package/src/contexts/AuthProvider.js +515 -0
  119. package/src/contexts/I18nProvider.d.ts +27 -0
  120. package/src/contexts/I18nProvider.d.ts.map +1 -0
  121. package/src/contexts/I18nProvider.js +60 -0
  122. package/src/contexts/MenuContext.d.ts +28 -0
  123. package/src/contexts/MenuContext.d.ts.map +1 -0
  124. package/src/contexts/MenuContext.js +292 -0
  125. package/src/contexts/SuiteConfigProvider.d.ts +44 -0
  126. package/src/contexts/SuiteConfigProvider.d.ts.map +1 -0
  127. package/src/contexts/SuiteConfigProvider.js +43 -0
  128. package/src/contexts/ThemeProvider.d.ts +15 -0
  129. package/src/contexts/ThemeProvider.d.ts.map +1 -0
  130. package/src/contexts/ThemeProvider.js +36 -0
  131. package/src/contexts/{index.ts → index.d.ts} +1 -0
  132. package/src/contexts/index.d.ts.map +1 -0
  133. package/src/contexts/index.js +8 -0
  134. package/src/hooks/{index.ts → index.d.ts} +1 -0
  135. package/src/hooks/index.d.ts.map +1 -0
  136. package/src/hooks/index.js +9 -0
  137. package/src/hooks/useAuthenticatedApi.d.ts +34 -0
  138. package/src/hooks/useAuthenticatedApi.d.ts.map +1 -0
  139. package/src/hooks/useAuthenticatedApi.js +46 -0
  140. package/src/hooks/useBackupCodes.d.ts +15 -0
  141. package/src/hooks/useBackupCodes.d.ts.map +1 -0
  142. package/src/hooks/useBackupCodes.js +74 -0
  143. package/src/hooks/useEmailVerification.d.ts +10 -0
  144. package/src/hooks/useEmailVerification.d.ts.map +1 -0
  145. package/src/hooks/useEmailVerification.js +40 -0
  146. package/src/hooks/useExpiringValue.d.ts +14 -0
  147. package/src/hooks/useExpiringValue.d.ts.map +1 -0
  148. package/src/hooks/useExpiringValue.js +53 -0
  149. package/src/hooks/useLocalStorage.d.ts +2 -0
  150. package/src/hooks/useLocalStorage.d.ts.map +1 -0
  151. package/src/hooks/useLocalStorage.js +15 -0
  152. package/src/hooks/useUserSettings.d.ts +48 -0
  153. package/src/hooks/useUserSettings.d.ts.map +1 -0
  154. package/src/hooks/useUserSettings.js +171 -0
  155. package/src/{index.ts → index.d.ts} +1 -1
  156. package/src/index.d.ts.map +1 -0
  157. package/src/index.js +12 -0
  158. package/src/interfaces/IAppConfig.d.ts +8 -0
  159. package/src/interfaces/IAppConfig.d.ts.map +1 -0
  160. package/src/interfaces/IAppConfig.js +2 -0
  161. package/src/interfaces/ICategoryConfig.d.ts +41 -0
  162. package/src/interfaces/ICategoryConfig.d.ts.map +1 -0
  163. package/src/interfaces/ICategoryConfig.js +2 -0
  164. package/src/interfaces/IMenuConfig.d.ts +28 -0
  165. package/src/interfaces/IMenuConfig.d.ts.map +1 -0
  166. package/src/interfaces/IMenuConfig.js +2 -0
  167. package/src/interfaces/IMenuOption.d.ts +82 -0
  168. package/src/interfaces/IMenuOption.d.ts.map +1 -0
  169. package/src/interfaces/IMenuOption.js +2 -0
  170. package/src/interfaces/{index.ts → index.d.ts} +1 -0
  171. package/src/interfaces/index.d.ts.map +1 -0
  172. package/src/interfaces/index.js +7 -0
  173. package/src/services/__mocks__/authService.d.ts +21 -0
  174. package/src/services/__mocks__/authService.d.ts.map +1 -0
  175. package/src/services/__mocks__/authService.js +15 -0
  176. package/src/services/api.d.ts +3 -0
  177. package/src/services/api.d.ts.map +1 -0
  178. package/src/services/api.js +14 -0
  179. package/src/services/authService.d.ts +126 -0
  180. package/src/services/authService.d.ts.map +1 -0
  181. package/src/services/authService.js +471 -0
  182. package/src/services/authenticatedApi.d.ts +3 -0
  183. package/src/services/authenticatedApi.d.ts.map +1 -0
  184. package/src/services/authenticatedApi.js +18 -0
  185. package/src/services/index.d.ts +4 -0
  186. package/src/services/index.d.ts.map +1 -0
  187. package/src/services/index.js +6 -0
  188. package/src/types/MenuType.d.ts +11 -0
  189. package/src/types/MenuType.d.ts.map +1 -0
  190. package/src/types/MenuType.js +12 -0
  191. package/src/types/expirationSeconds.d.ts +3 -0
  192. package/src/types/expirationSeconds.d.ts.map +1 -0
  193. package/src/types/expirationSeconds.js +17 -0
  194. package/src/types/index.d.ts +2 -0
  195. package/src/types/index.d.ts.map +1 -0
  196. package/src/types/index.js +4 -0
  197. package/src/types/translation.d.ts +10 -0
  198. package/src/types/translation.d.ts.map +1 -0
  199. package/src/types/translation.js +9 -0
  200. package/src/wrappers/BackupCodeLoginWrapper.d.ts +8 -0
  201. package/src/wrappers/BackupCodeLoginWrapper.d.ts.map +1 -0
  202. package/src/wrappers/BackupCodeLoginWrapper.js +20 -0
  203. package/src/wrappers/BackupCodesWrapper.d.ts +7 -0
  204. package/src/wrappers/BackupCodesWrapper.d.ts.map +1 -0
  205. package/src/wrappers/BackupCodesWrapper.js +17 -0
  206. package/src/wrappers/ChangePasswordFormWrapper.d.ts +8 -0
  207. package/src/wrappers/ChangePasswordFormWrapper.d.ts.map +1 -0
  208. package/src/wrappers/ChangePasswordFormWrapper.js +21 -0
  209. package/src/wrappers/ForgotPasswordFormWrapper.d.ts +8 -0
  210. package/src/wrappers/ForgotPasswordFormWrapper.d.ts.map +1 -0
  211. package/src/wrappers/ForgotPasswordFormWrapper.js +29 -0
  212. package/src/wrappers/LoginFormWrapper.d.ts +21 -0
  213. package/src/wrappers/LoginFormWrapper.d.ts.map +1 -0
  214. package/src/wrappers/LoginFormWrapper.js +72 -0
  215. package/src/wrappers/LogoutPageWrapper.d.ts +9 -0
  216. package/src/wrappers/LogoutPageWrapper.d.ts.map +1 -0
  217. package/src/wrappers/LogoutPageWrapper.js +21 -0
  218. package/src/wrappers/RegisterFormWrapper.d.ts +20 -0
  219. package/src/wrappers/RegisterFormWrapper.d.ts.map +1 -0
  220. package/src/wrappers/RegisterFormWrapper.js +51 -0
  221. package/src/wrappers/ResetPasswordFormWrapper.d.ts +9 -0
  222. package/src/wrappers/ResetPasswordFormWrapper.d.ts.map +1 -0
  223. package/src/wrappers/ResetPasswordFormWrapper.js +34 -0
  224. package/src/wrappers/UserSettingsFormWrapper.d.ts +29 -0
  225. package/src/wrappers/UserSettingsFormWrapper.d.ts.map +1 -0
  226. package/src/wrappers/UserSettingsFormWrapper.js +95 -0
  227. package/src/wrappers/VerifyEmailPageWrapper.d.ts +8 -0
  228. package/src/wrappers/VerifyEmailPageWrapper.d.ts.map +1 -0
  229. package/src/wrappers/VerifyEmailPageWrapper.js +21 -0
  230. package/src/wrappers/{index.tsx → index.d.ts} +1 -10
  231. package/src/wrappers/index.d.ts.map +1 -0
  232. package/src/wrappers/index.js +24 -0
  233. package/LICENSE +0 -21
  234. package/src/auth/AdminRoute.tsx +0 -54
  235. package/src/auth/Private.tsx +0 -17
  236. package/src/auth/PrivateRoute.tsx +0 -28
  237. package/src/auth/UnAuth.tsx +0 -16
  238. package/src/auth/UnAuthRoute.tsx +0 -30
  239. package/src/components/ApiAccess.tsx +0 -175
  240. package/src/components/BackupCodeLoginForm.tsx +0 -489
  241. package/src/components/BackupCodesForm.tsx +0 -287
  242. package/src/components/CategoryMenu.tsx +0 -155
  243. package/src/components/ChangePasswordForm.tsx +0 -273
  244. package/src/components/ConfirmationDialog.tsx +0 -48
  245. package/src/components/CurrencyCodeSelector.tsx +0 -60
  246. package/src/components/CurrencyInput.tsx +0 -80
  247. package/src/components/DashboardPage.tsx +0 -24
  248. package/src/components/DropdownMenu.tsx +0 -105
  249. package/src/components/ExpirationSecondsSelector.tsx +0 -60
  250. package/src/components/FakeEmailAdminPanel.tsx +0 -374
  251. package/src/components/Flag.tsx +0 -52
  252. package/src/components/ForgotPasswordForm.tsx +0 -174
  253. package/src/components/LoginForm.tsx +0 -468
  254. package/src/components/LogoutPage.tsx +0 -21
  255. package/src/components/RegisterForm.tsx +0 -1169
  256. package/src/components/ResetPasswordForm.tsx +0 -247
  257. package/src/components/SideMenu.tsx +0 -46
  258. package/src/components/SideMenuListItem.tsx +0 -75
  259. package/src/components/T.tsx +0 -24
  260. package/src/components/TDiv.tsx +0 -26
  261. package/src/components/TImgAlt.tsx +0 -28
  262. package/src/components/TopMenu.tsx +0 -252
  263. package/src/components/TotpSetupForm.tsx +0 -188
  264. package/src/components/TotpVerificationForm.tsx +0 -148
  265. package/src/components/TranslatedTitle.tsx +0 -31
  266. package/src/components/UserLanguageSelector.tsx +0 -45
  267. package/src/components/UserMenu.tsx +0 -15
  268. package/src/components/UserSettingsForm.tsx +0 -904
  269. package/src/components/VerifyEmailPage.tsx +0 -222
  270. package/src/components/__tests__/RegisterForm.totp.spec.tsx +0 -377
  271. package/src/components/__tests__/TotpSetupForm.spec.tsx +0 -258
  272. package/src/components/__tests__/TotpVerificationForm.spec.tsx +0 -259
  273. package/src/components/__tests__/UserSettingsForm.totp.spec.tsx +0 -396
  274. package/src/contexts/AuthProvider.spec.tsx +0 -1284
  275. package/src/contexts/AuthProvider.tsx +0 -977
  276. package/src/contexts/I18nProvider.tsx +0 -164
  277. package/src/contexts/MenuContext.tsx +0 -426
  278. package/src/contexts/SuiteConfigProvider.tsx +0 -93
  279. package/src/contexts/ThemeProvider.tsx +0 -67
  280. package/src/hooks/useAuthenticatedApi.tsx +0 -67
  281. package/src/hooks/useBackupCodes.ts +0 -105
  282. package/src/hooks/useEmailVerification.ts +0 -54
  283. package/src/hooks/useExpiringValue.ts +0 -78
  284. package/src/hooks/useLocalStorage.ts +0 -18
  285. package/src/hooks/useUserSettings.ts +0 -271
  286. package/src/interfaces/IAppConfig.ts +0 -7
  287. package/src/interfaces/ICategoryConfig.ts +0 -41
  288. package/src/interfaces/IMenuConfig.ts +0 -28
  289. package/src/interfaces/IMenuOption.ts +0 -79
  290. package/src/services/__mocks__/authService.ts +0 -14
  291. package/src/services/__tests__/authService.totp.property.spec.ts +0 -360
  292. package/src/services/__tests__/authService.totp.spec.ts +0 -439
  293. package/src/services/api.ts +0 -13
  294. package/src/services/authService.ts +0 -692
  295. package/src/services/authenticatedApi.ts +0 -17
  296. package/src/services/index.ts +0 -3
  297. package/src/types/MenuType.ts +0 -15
  298. package/src/types/expirationSeconds.ts +0 -18
  299. package/src/types/index.ts +0 -1
  300. package/src/types/translation.ts +0 -20
  301. package/src/wrappers/BackupCodeLoginWrapper.tsx +0 -34
  302. package/src/wrappers/BackupCodesWrapper.tsx +0 -28
  303. package/src/wrappers/ChangePasswordFormWrapper.tsx +0 -34
  304. package/src/wrappers/ForgotPasswordFormWrapper.tsx +0 -45
  305. package/src/wrappers/LoginFormWrapper.tsx +0 -108
  306. package/src/wrappers/LogoutPageWrapper.tsx +0 -30
  307. package/src/wrappers/RegisterFormWrapper.tsx +0 -109
  308. package/src/wrappers/ResetPasswordFormWrapper.tsx +0 -57
  309. package/src/wrappers/UserSettingsFormWrapper.tsx +0 -140
  310. package/src/wrappers/VerifyEmailPageWrapper.tsx +0 -27
  311. package/src/wrappers/__tests__/LoginFormWrapper.totp.spec.tsx +0 -339
@@ -1,339 +0,0 @@
1
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
2
- import { LoginFormWrapper, LoginFormWrapperProps } from '../LoginFormWrapper';
3
-
4
- // --- Mocks ---
5
-
6
- const mockNavigate = jest.fn();
7
- jest.mock('react-router', () => ({
8
- useNavigate: () => mockNavigate,
9
- }));
10
-
11
- const mockDirectLogin = jest.fn();
12
- const mockPasswordLogin = jest.fn();
13
- const mockSetUser = jest.fn();
14
- const mockVerifyTotpLogin = jest.fn();
15
- jest.mock('../../contexts', () => ({
16
- useAuth: () => ({
17
- directLogin: mockDirectLogin,
18
- passwordLogin: mockPasswordLogin,
19
- setUser: mockSetUser,
20
- verifyTotpLogin: mockVerifyTotpLogin,
21
- }),
22
- useSuiteConfig: () => ({
23
- routes: {
24
- dashboard: '/dashboard',
25
- login: '/login',
26
- },
27
- }),
28
- }));
29
-
30
- // Minimal LoginForm mock that exposes the onSubmit prop
31
- jest.mock('../../components/LoginForm', () => ({
32
- LoginForm: (props: {
33
- onSubmit: (values: Record<string, string>) => Promise<void>;
34
- }) => (
35
- <div data-testid="login-form">
36
- <button
37
- data-testid="login-password-btn"
38
- onClick={() =>
39
- props.onSubmit({ email: 'user@example.com', password: 'secret' })
40
- }
41
- >
42
- Login with password
43
- </button>
44
- <button
45
- data-testid="login-mnemonic-btn"
46
- onClick={() =>
47
- props.onSubmit({
48
- username: 'testuser',
49
- mnemonic: 'word1 word2 word3',
50
- })
51
- }
52
- >
53
- Login with mnemonic
54
- </button>
55
- </div>
56
- ),
57
- }));
58
-
59
- // Minimal TotpVerificationForm mock that exposes onSubmit
60
- jest.mock('../../components/TotpVerificationForm', () => ({
61
- TotpVerificationForm: (props: {
62
- pendingTotpToken: string;
63
- onSubmit: (
64
- code: string,
65
- token: string
66
- ) => Promise<{ token: string; user: object } | { error: string }>;
67
- }) => (
68
- <div data-testid="totp-verification-form">
69
- <span data-testid="pending-token">{props.pendingTotpToken}</span>
70
- <button
71
- data-testid="totp-submit-btn"
72
- onClick={() => props.onSubmit('123456', props.pendingTotpToken)}
73
- >
74
- Verify TOTP
75
- </button>
76
- </div>
77
- ),
78
- }));
79
-
80
- describe('LoginFormWrapper TOTP integration', () => {
81
- const originalError = console.error;
82
- beforeAll(() => {
83
- console.error = (...args: unknown[]) => {
84
- if (
85
- typeof args[0] === 'string' &&
86
- args[0].includes('not wrapped in act')
87
- ) {
88
- return;
89
- }
90
- originalError.call(console, ...args);
91
- };
92
- });
93
-
94
- afterAll(() => {
95
- console.error = originalError;
96
- });
97
-
98
- beforeEach(() => {
99
- jest.clearAllMocks();
100
- });
101
-
102
- const defaultProps: LoginFormWrapperProps = {
103
- onVerifyTotp: jest.fn(),
104
- };
105
-
106
- /**
107
- * Validates: Requirement 14.4
108
- * Existing login flow is unchanged when no pendingTotpToken is returned.
109
- */
110
- it('renders LoginForm and navigates to dashboard on normal login (no TOTP)', async () => {
111
- mockPasswordLogin.mockResolvedValue({
112
- token: 'full-jwt',
113
- user: { id: '1', email: 'user@example.com' },
114
- wallet: {},
115
- });
116
-
117
- render(<LoginFormWrapper {...defaultProps} />);
118
-
119
- // LoginForm should be rendered
120
- expect(screen.getByTestId('login-form')).toBeInTheDocument();
121
- expect(
122
- screen.queryByTestId('totp-verification-form')
123
- ).not.toBeInTheDocument();
124
-
125
- // Trigger a password login
126
- fireEvent.click(screen.getByTestId('login-password-btn'));
127
-
128
- await waitFor(() => {
129
- expect(mockPasswordLogin).toHaveBeenCalled();
130
- });
131
-
132
- await waitFor(() => {
133
- expect(mockNavigate).toHaveBeenCalledWith('/dashboard');
134
- });
135
- });
136
-
137
- /**
138
- * Validates: Requirement 6.6
139
- * When passwordLogin returns pendingTotpToken, TotpVerificationForm is rendered.
140
- */
141
- it('renders TotpVerificationForm when passwordLogin returns pendingTotpToken', async () => {
142
- mockPasswordLogin.mockResolvedValue({
143
- pendingTotpToken: 'pending-jwt-token',
144
- });
145
-
146
- render(<LoginFormWrapper {...defaultProps} />);
147
-
148
- // Trigger a password login that returns a pending TOTP token
149
- fireEvent.click(screen.getByTestId('login-password-btn'));
150
-
151
- await waitFor(() => {
152
- expect(screen.getByTestId('totp-verification-form')).toBeInTheDocument();
153
- });
154
-
155
- // LoginForm should no longer be visible
156
- expect(screen.queryByTestId('login-form')).not.toBeInTheDocument();
157
-
158
- // The pending token should be passed to the form
159
- expect(screen.getByTestId('pending-token')).toHaveTextContent(
160
- 'pending-jwt-token'
161
- );
162
- });
163
-
164
- /**
165
- * Validates: Requirement 6.6
166
- * When directLogin returns pendingTotpToken, TotpVerificationForm is rendered.
167
- */
168
- it('renders TotpVerificationForm when directLogin returns pendingTotpToken', async () => {
169
- mockDirectLogin.mockResolvedValue({
170
- pendingTotpToken: 'pending-mnemonic-token',
171
- });
172
-
173
- render(<LoginFormWrapper {...defaultProps} />);
174
-
175
- // Trigger a mnemonic login that returns a pending TOTP token
176
- fireEvent.click(screen.getByTestId('login-mnemonic-btn'));
177
-
178
- await waitFor(() => {
179
- expect(screen.getByTestId('totp-verification-form')).toBeInTheDocument();
180
- });
181
-
182
- expect(screen.getByTestId('pending-token')).toHaveTextContent(
183
- 'pending-mnemonic-token'
184
- );
185
- });
186
-
187
- /**
188
- * Validates: Requirement 6.3
189
- * On successful TOTP verification, navigates to dashboard.
190
- */
191
- it('navigates to dashboard on successful TOTP verification', async () => {
192
- mockPasswordLogin.mockResolvedValue({
193
- pendingTotpToken: 'pending-jwt-token',
194
- });
195
-
196
- const mockVerifyTotp = jest.fn().mockResolvedValue({
197
- token: 'full-jwt-after-totp',
198
- user: { id: '1', email: 'user@example.com' },
199
- });
200
-
201
- render(
202
- <LoginFormWrapper {...defaultProps} onVerifyTotp={mockVerifyTotp} />
203
- );
204
-
205
- // First, trigger login to get pending token
206
- fireEvent.click(screen.getByTestId('login-password-btn'));
207
-
208
- await waitFor(() => {
209
- expect(screen.getByTestId('totp-verification-form')).toBeInTheDocument();
210
- });
211
-
212
- // Now submit the TOTP code
213
- fireEvent.click(screen.getByTestId('totp-submit-btn'));
214
-
215
- await waitFor(() => {
216
- expect(mockVerifyTotp).toHaveBeenCalledWith(
217
- '123456',
218
- 'pending-jwt-token'
219
- );
220
- });
221
-
222
- await waitFor(() => {
223
- expect(mockNavigate).toHaveBeenCalledWith('/dashboard');
224
- });
225
- });
226
-
227
- /**
228
- * Validates: Requirement 14.4
229
- * Navigates to custom redirectTo path after successful login without TOTP.
230
- */
231
- it('navigates to custom redirectTo on normal login', async () => {
232
- mockPasswordLogin.mockResolvedValue({
233
- token: 'full-jwt',
234
- user: { id: '1' },
235
- wallet: {},
236
- });
237
-
238
- render(<LoginFormWrapper {...defaultProps} redirectTo="/custom-page" />);
239
-
240
- fireEvent.click(screen.getByTestId('login-password-btn'));
241
-
242
- await waitFor(() => {
243
- expect(mockNavigate).toHaveBeenCalledWith('/custom-page');
244
- });
245
- });
246
-
247
- /**
248
- * Validates: Requirement 6.3
249
- * Navigates to custom redirectTo after successful TOTP verification.
250
- */
251
- it('navigates to custom redirectTo after successful TOTP verification', async () => {
252
- mockPasswordLogin.mockResolvedValue({
253
- pendingTotpToken: 'pending-jwt-token',
254
- });
255
-
256
- const mockVerifyTotp = jest.fn().mockResolvedValue({
257
- token: 'full-jwt-after-totp',
258
- user: { id: '1' },
259
- });
260
-
261
- render(
262
- <LoginFormWrapper
263
- {...defaultProps}
264
- onVerifyTotp={mockVerifyTotp}
265
- redirectTo="/custom-page"
266
- />
267
- );
268
-
269
- fireEvent.click(screen.getByTestId('login-password-btn'));
270
-
271
- await waitFor(() => {
272
- expect(screen.getByTestId('totp-verification-form')).toBeInTheDocument();
273
- });
274
-
275
- fireEvent.click(screen.getByTestId('totp-submit-btn'));
276
-
277
- await waitFor(() => {
278
- expect(mockNavigate).toHaveBeenCalledWith('/custom-page');
279
- });
280
- });
281
-
282
- /**
283
- * Validates: Requirement 14.4
284
- * Calls onSuccess callback on normal login.
285
- */
286
- it('calls onSuccess callback on normal login', async () => {
287
- mockPasswordLogin.mockResolvedValue({
288
- token: 'full-jwt',
289
- user: { id: '1' },
290
- wallet: {},
291
- });
292
-
293
- const mockOnSuccess = jest.fn();
294
-
295
- render(<LoginFormWrapper {...defaultProps} onSuccess={mockOnSuccess} />);
296
-
297
- fireEvent.click(screen.getByTestId('login-password-btn'));
298
-
299
- await waitFor(() => {
300
- expect(mockOnSuccess).toHaveBeenCalled();
301
- });
302
- });
303
-
304
- /**
305
- * Validates: Requirement 6.3
306
- * Calls onSuccess callback after successful TOTP verification.
307
- */
308
- it('calls onSuccess callback after successful TOTP verification', async () => {
309
- mockPasswordLogin.mockResolvedValue({
310
- pendingTotpToken: 'pending-jwt-token',
311
- });
312
-
313
- const mockVerifyTotp = jest.fn().mockResolvedValue({
314
- token: 'full-jwt-after-totp',
315
- user: { id: '1' },
316
- });
317
- const mockOnSuccess = jest.fn();
318
-
319
- render(
320
- <LoginFormWrapper
321
- {...defaultProps}
322
- onVerifyTotp={mockVerifyTotp}
323
- onSuccess={mockOnSuccess}
324
- />
325
- );
326
-
327
- fireEvent.click(screen.getByTestId('login-password-btn'));
328
-
329
- await waitFor(() => {
330
- expect(screen.getByTestId('totp-verification-form')).toBeInTheDocument();
331
- });
332
-
333
- fireEvent.click(screen.getByTestId('totp-submit-btn'));
334
-
335
- await waitFor(() => {
336
- expect(mockOnSuccess).toHaveBeenCalled();
337
- });
338
- });
339
- });