@umituz/react-native-auth 3.4.21 → 3.4.23

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-auth",
3
- "version": "3.4.21",
3
+ "version": "3.4.23",
4
4
  "description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -1,7 +1,3 @@
1
- /**
2
- * AnonymousModeService Tests
3
- */
4
-
5
1
  import { AnonymousModeService } from '../../infrastructure/services/AnonymousModeService';
6
2
  import type { IStorageProvider } from '../../infrastructure/services/AuthPackage';
7
3
 
@@ -10,188 +6,61 @@ describe('AnonymousModeService', () => {
10
6
  let mockStorageProvider: jest.Mocked<IStorageProvider>;
11
7
 
12
8
  beforeEach(() => {
13
- mockStorageProvider = {
14
- get: jest.fn(),
15
- set: jest.fn(),
16
- remove: jest.fn(),
17
- };
18
-
9
+ mockStorageProvider = { get: jest.fn(), set: jest.fn(), remove: jest.fn() };
19
10
  anonymousModeService = new AnonymousModeService('@test_anonymous_mode');
20
11
  });
21
12
 
22
- describe('constructor', () => {
23
- it('should use default storage key when none provided', () => {
24
- const service = new AnonymousModeService();
25
- expect(service.getIsAnonymousMode()).toBe(false);
26
- });
27
-
28
- it('should use custom storage key when provided', () => {
29
- const service = new AnonymousModeService('@custom_key');
13
+ describe('configuration', () => {
14
+ it('should use storage keys correctly', () => {
15
+ const service = new AnonymousModeService('@custom');
30
16
  expect(service.getIsAnonymousMode()).toBe(false);
31
17
  });
32
18
  });
33
19
 
34
- describe('load', () => {
35
- it('should load false when storage returns null', async () => {
36
- mockStorageProvider.get.mockResolvedValue(null);
37
-
38
- const result = await anonymousModeService.load(mockStorageProvider);
39
-
40
- expect(result).toBe(false);
41
- expect(mockStorageProvider.get).toHaveBeenCalledWith('@test_anonymous_mode');
42
- });
43
-
44
- it('should load false when storage returns "false"', async () => {
45
- mockStorageProvider.get.mockResolvedValue('false');
46
-
47
- const result = await anonymousModeService.load(mockStorageProvider);
48
-
49
- expect(result).toBe(false);
50
- });
51
-
52
- it('should load true when storage returns "true"', async () => {
20
+ describe('persistence', () => {
21
+ it('should load state from storage', async () => {
53
22
  mockStorageProvider.get.mockResolvedValue('true');
54
-
55
23
  const result = await anonymousModeService.load(mockStorageProvider);
56
-
57
24
  expect(result).toBe(true);
58
25
  expect(anonymousModeService.getIsAnonymousMode()).toBe(true);
59
26
  });
60
27
 
61
- it('should handle storage errors gracefully', async () => {
62
- mockStorageProvider.get.mockRejectedValue(new Error('Storage error'));
63
-
64
- const result = await anonymousModeService.load(mockStorageProvider);
65
-
66
- expect(result).toBe(false);
28
+ it('should handle missing storage state', async () => {
29
+ mockStorageProvider.get.mockResolvedValue(null);
30
+ expect(await anonymousModeService.load(mockStorageProvider)).toBe(false);
67
31
  });
68
- });
69
32
 
70
- describe('save', () => {
71
- it('should save true to storage when anonymous mode is enabled', async () => {
33
+ it('should save state to storage', async () => {
72
34
  anonymousModeService.setAnonymousMode(true);
73
-
74
35
  await anonymousModeService.save(mockStorageProvider);
75
-
76
36
  expect(mockStorageProvider.set).toHaveBeenCalledWith('@test_anonymous_mode', 'true');
77
37
  });
78
38
 
79
- it('should save false to storage when anonymous mode is disabled', async () => {
80
- anonymousModeService.setAnonymousMode(false);
81
-
82
- await anonymousModeService.save(mockStorageProvider);
83
-
84
- expect(mockStorageProvider.set).toHaveBeenCalledWith('@test_anonymous_mode', 'false');
85
- });
86
-
87
- it('should handle storage errors gracefully', async () => {
88
- anonymousModeService.setAnonymousMode(true);
89
- mockStorageProvider.set.mockRejectedValue(new Error('Storage error'));
90
-
91
- await expect(anonymousModeService.save(mockStorageProvider)).resolves.not.toThrow();
92
- });
93
- });
94
-
95
- describe('clear', () => {
96
- it('should clear anonymous mode and remove from storage', async () => {
97
- anonymousModeService.setAnonymousMode(true);
98
-
39
+ it('should clear state from storage', async () => {
99
40
  await anonymousModeService.clear(mockStorageProvider);
100
-
101
41
  expect(anonymousModeService.getIsAnonymousMode()).toBe(false);
102
42
  expect(mockStorageProvider.remove).toHaveBeenCalledWith('@test_anonymous_mode');
103
43
  });
104
-
105
- it('should handle storage errors gracefully', async () => {
106
- mockStorageProvider.remove.mockRejectedValue(new Error('Storage error'));
107
-
108
- await expect(anonymousModeService.clear(mockStorageProvider)).resolves.not.toThrow();
109
- expect(anonymousModeService.getIsAnonymousMode()).toBe(false);
110
- });
111
44
  });
112
45
 
113
- describe('enable', () => {
114
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
- let mockAuthProvider: any;
116
-
117
- beforeEach(() => {
118
- mockAuthProvider = {
119
- getCurrentUser: jest.fn(),
120
- signOut: jest.fn(),
121
- };
122
- });
123
-
124
- it('should enable anonymous mode without provider', async () => {
125
- await anonymousModeService.enable(mockStorageProvider);
126
-
127
- expect(anonymousModeService.getIsAnonymousMode()).toBe(true);
128
- expect(mockStorageProvider.set).toHaveBeenCalledWith('@test_anonymous_mode', 'true');
129
- });
130
-
131
- it('should sign out provider if user is logged in', async () => {
132
- mockAuthProvider.getCurrentUser.mockReturnValue({ uid: 'test-user' });
133
- mockAuthProvider.signOut.mockResolvedValue(undefined);
134
-
135
- await anonymousModeService.enable(mockStorageProvider, mockAuthProvider);
136
-
137
- expect(mockAuthProvider.signOut).toHaveBeenCalled();
138
- expect(anonymousModeService.getIsAnonymousMode()).toBe(true);
139
- });
140
-
141
- it('should ignore sign out errors', async () => {
142
- mockAuthProvider.getCurrentUser.mockReturnValue({ uid: 'test-user' });
143
- mockAuthProvider.signOut.mockRejectedValue(new Error('Sign out error'));
144
-
145
- await expect(anonymousModeService.enable(mockStorageProvider, mockAuthProvider)).resolves.not.toThrow();
46
+ describe('auth integration', () => {
47
+ it('should enable and sign out if user is logged in', async () => {
48
+ const mockAuth = { getCurrentUser: jest.fn().mockReturnValue({ uid: 'u' }), signOut: jest.fn() };
49
+ await anonymousModeService.enable(mockStorageProvider, mockAuth as any);
50
+ expect(mockAuth.signOut).toHaveBeenCalled();
146
51
  expect(anonymousModeService.getIsAnonymousMode()).toBe(true);
147
52
  });
148
- });
149
53
 
150
- describe('wrapAuthStateCallback', () => {
151
- it('should call callback with user when not in anonymous mode', () => {
54
+ it('should wrap auth state callback correctly', () => {
152
55
  const callback = jest.fn();
153
- const wrappedCallback = anonymousModeService.wrapAuthStateCallback(callback);
154
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
155
- const mockUser = { uid: 'test-user' } as any;
156
-
157
- wrappedCallback(mockUser);
158
-
159
- expect(callback).toHaveBeenCalledWith(mockUser);
160
- });
56
+ const wrapped = anonymousModeService.wrapAuthStateCallback(callback);
57
+
58
+ wrapped({ uid: 'u' } as any);
59
+ expect(callback).toHaveBeenCalledWith({ uid: 'u' });
161
60
 
162
- it('should call callback with null when in anonymous mode', () => {
163
61
  anonymousModeService.setAnonymousMode(true);
164
- const callback = jest.fn();
165
- const wrappedCallback = anonymousModeService.wrapAuthStateCallback(callback);
166
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
- const mockUser = { uid: 'test-user' } as any;
168
-
169
- wrappedCallback(mockUser);
170
-
171
- expect(callback).toHaveBeenCalledWith(null);
172
- });
173
-
174
- it('should call callback with null when user is null', () => {
175
- const callback = jest.fn();
176
- const wrappedCallback = anonymousModeService.wrapAuthStateCallback(callback);
177
-
178
- wrappedCallback(null);
179
-
62
+ wrapped({ uid: 'u' } as any);
180
63
  expect(callback).toHaveBeenCalledWith(null);
181
64
  });
182
65
  });
183
-
184
- describe('getIsAnonymousMode and setAnonymousMode', () => {
185
- it('should return initial anonymous mode state', () => {
186
- expect(anonymousModeService.getIsAnonymousMode()).toBe(false);
187
- });
188
-
189
- it('should set and get anonymous mode state', () => {
190
- anonymousModeService.setAnonymousMode(true);
191
- expect(anonymousModeService.getIsAnonymousMode()).toBe(true);
192
-
193
- anonymousModeService.setAnonymousMode(false);
194
- expect(anonymousModeService.getIsAnonymousMode()).toBe(false);
195
- });
196
- });
197
66
  });
@@ -0,0 +1,45 @@
1
+ import { AuthCoreService } from '../../../src/infrastructure/services/AuthCoreService';
2
+ import { DEFAULT_AUTH_CONFIG } from '../../../src/domain/value-objects/AuthConfig';
3
+ import type { IAuthProvider } from '../../../src/application/ports/IAuthProvider';
4
+
5
+ describe('AuthCoreInitialization', () => {
6
+ let authCoreService: AuthCoreService;
7
+ let mockProvider: jest.Mocked<IAuthProvider>;
8
+
9
+ beforeEach(() => {
10
+ mockProvider = {
11
+ initialize: jest.fn(),
12
+ isInitialized: jest.fn().mockReturnValue(true),
13
+ signIn: jest.fn(),
14
+ signUp: jest.fn(),
15
+ signOut: jest.fn(),
16
+ getCurrentUser: jest.fn(),
17
+ onAuthStateChange: jest.fn().mockReturnValue(jest.fn()),
18
+ };
19
+ authCoreService = new AuthCoreService(DEFAULT_AUTH_CONFIG);
20
+ });
21
+
22
+ it('should initialize with provided config', () => {
23
+ const customConfig = { ...DEFAULT_AUTH_CONFIG, password: { ...DEFAULT_AUTH_CONFIG.password, minLength: 12 } };
24
+ const service = new AuthCoreService(customConfig);
25
+ expect(service.getConfig()).toEqual(customConfig);
26
+ });
27
+
28
+ it('should initialize with IAuthProvider', async () => {
29
+ await authCoreService.initialize(mockProvider);
30
+ expect(mockProvider.initialize).toHaveBeenCalled();
31
+ });
32
+
33
+ it('should throw error when no provider provided', async () => {
34
+ await expect(authCoreService.initialize(null as any)).rejects.toThrow();
35
+ });
36
+
37
+ it('should return false when not initialized', () => {
38
+ expect(authCoreService.isInitialized()).toBe(false);
39
+ });
40
+
41
+ it('should return true when initialized', async () => {
42
+ await authCoreService.initialize(mockProvider);
43
+ expect(authCoreService.isInitialized()).toBe(true);
44
+ });
45
+ });
@@ -0,0 +1,71 @@
1
+ import { AuthCoreService } from '../../../src/infrastructure/services/AuthCoreService';
2
+ import { DEFAULT_AUTH_CONFIG } from '../../../src/domain/value-objects/AuthConfig';
3
+ import type { IAuthProvider } from '../../../src/application/ports/IAuthProvider';
4
+ import type { AuthUser } from '../../../src/domain/entities/AuthUser';
5
+
6
+ describe('AuthCoreOperations', () => {
7
+ let authCoreService: AuthCoreService;
8
+ let mockProvider: jest.Mocked<IAuthProvider>;
9
+ const mockUser: AuthUser = {
10
+ uid: 'test-uid',
11
+ email: 'test@example.com',
12
+ displayName: 'Test User',
13
+ isAnonymous: false,
14
+ emailVerified: false,
15
+ photoURL: null,
16
+ };
17
+
18
+ beforeEach(async () => {
19
+ mockProvider = {
20
+ initialize: jest.fn(),
21
+ isInitialized: jest.fn().mockReturnValue(true),
22
+ signIn: jest.fn(),
23
+ signUp: jest.fn(),
24
+ signOut: jest.fn(),
25
+ getCurrentUser: jest.fn(),
26
+ onAuthStateChange: jest.fn().mockReturnValue(jest.fn()),
27
+ };
28
+ authCoreService = new AuthCoreService(DEFAULT_AUTH_CONFIG);
29
+ await authCoreService.initialize(mockProvider);
30
+ });
31
+
32
+ describe('Auth Flow', () => {
33
+ it('should sign up successfully', async () => {
34
+ mockProvider.signUp.mockResolvedValue(mockUser);
35
+ const result = await authCoreService.signUp({ email: 'test@example.com', password: 'password123' });
36
+ expect(result).toEqual(mockUser);
37
+ });
38
+
39
+ it('should sign in successfully', async () => {
40
+ mockProvider.signIn.mockResolvedValue(mockUser);
41
+ const result = await authCoreService.signIn({ email: 'test@example.com', password: 'password123' });
42
+ expect(result).toEqual(mockUser);
43
+ });
44
+
45
+ it('should sign out successfully', async () => {
46
+ await authCoreService.signOut();
47
+ expect(mockProvider.signOut).toHaveBeenCalled();
48
+ });
49
+ });
50
+
51
+ describe('User State', () => {
52
+ it('should return current user', () => {
53
+ mockProvider.getCurrentUser.mockReturnValue(mockUser);
54
+ expect(authCoreService.getCurrentUser()).toEqual(mockUser);
55
+ });
56
+
57
+ it('should return null when no user', () => {
58
+ mockProvider.getCurrentUser.mockReturnValue(null);
59
+ expect(authCoreService.getCurrentUser()).toBeNull();
60
+ });
61
+
62
+ it('should subscribe to auth state changes', () => {
63
+ const callback = jest.fn();
64
+ const mockCleanup = jest.fn();
65
+ mockProvider.onAuthStateChange.mockReturnValue(mockCleanup);
66
+ const cleanup = authCoreService.onAuthStateChange(callback);
67
+ expect(mockProvider.onAuthStateChange).toHaveBeenCalledWith(callback);
68
+ expect(cleanup).toBe(mockCleanup);
69
+ });
70
+ });
71
+ });
@@ -1,7 +1,3 @@
1
- /**
2
- * AuthPackage Tests
3
- */
4
-
5
1
  import {
6
2
  AuthPackage,
7
3
  initializeAuthPackage,
@@ -17,210 +13,67 @@ describe('AuthPackage', () => {
17
13
  let mockValidationProvider: jest.Mocked<IValidationProvider>;
18
14
 
19
15
  beforeEach(() => {
20
- mockStorageProvider = {
21
- get: jest.fn(),
22
- set: jest.fn(),
23
- remove: jest.fn(),
24
- };
25
-
26
- mockUIProvider = {
27
- getTheme: jest.fn(),
28
- getLocalization: jest.fn(),
29
- };
30
-
31
- mockValidationProvider = {
32
- validateEmail: jest.fn(),
33
- validatePassword: jest.fn(),
34
- };
35
-
36
- // Reset package state
16
+ mockStorageProvider = { get: jest.fn(), set: jest.fn(), remove: jest.fn() };
17
+ mockUIProvider = { getTheme: jest.fn(), getLocalization: jest.fn() };
18
+ mockValidationProvider = { validateEmail: jest.fn(), validatePassword: jest.fn() };
37
19
  resetAuthPackage();
38
20
  });
39
21
 
40
22
  describe('constructor', () => {
41
23
  it('should initialize with default config', () => {
42
- const authPackage = new AuthPackage();
43
- const config = authPackage.getConfig();
44
-
45
- expect(config).toEqual(DEFAULT_AUTH_PACKAGE_CONFIG);
46
- });
47
-
48
- it('should merge custom config with defaults', () => {
49
- const customConfig = {
50
- storageKeys: {
51
- anonymousMode: '@custom_anonymous_mode',
52
- showRegister: 'custom_show_register',
53
- },
54
- features: {
55
- anonymousMode: false,
56
- registration: false,
57
- passwordStrength: false,
58
- },
59
- };
60
-
61
- const authPackage = new AuthPackage(customConfig);
62
- const config = authPackage.getConfig();
63
-
64
- expect(config.storageKeys).toEqual(customConfig.storageKeys);
65
- expect(config.features).toEqual(customConfig.features);
66
- expect(config.validation).toEqual(DEFAULT_AUTH_PACKAGE_CONFIG.validation);
67
- expect(config.ui).toEqual(DEFAULT_AUTH_PACKAGE_CONFIG.ui);
24
+ expect(new AuthPackage().getConfig()).toEqual(DEFAULT_AUTH_PACKAGE_CONFIG);
68
25
  });
69
26
 
70
- it('should deeply merge nested config', () => {
71
- const customConfig = {
72
- validation: {
73
- passwordConfig: {
74
- minLength: 12,
75
- requireUppercase: true,
76
- },
77
- },
78
- };
79
-
27
+ it('should merge custom config and deeply nested config', () => {
28
+ const customConfig = { features: { anonymousMode: false }, validation: { passwordConfig: { minLength: 12 } } };
80
29
  const authPackage = new AuthPackage(customConfig);
81
30
  const config = authPackage.getConfig();
82
-
31
+ expect(config.features.anonymousMode).toBe(false);
83
32
  expect(config.validation.passwordConfig.minLength).toBe(12);
84
- expect(config.validation.passwordConfig.requireUppercase).toBe(true);
85
- expect(config.validation.passwordConfig.requireLowercase).toBe(true); // Should keep default
33
+ expect(config.validation.passwordConfig.requireLowercase).toBe(true);
86
34
  });
87
35
  });
88
36
 
89
- describe('provider setters and getters', () => {
90
- let authPackage: AuthPackage;
91
-
92
- beforeEach(() => {
93
- authPackage = new AuthPackage();
94
- });
95
-
96
- it('should set and get storage provider', () => {
37
+ describe('provider management', () => {
38
+ it('should set and get providers', () => {
39
+ const authPackage = new AuthPackage();
97
40
  authPackage.setStorageProvider(mockStorageProvider);
98
- expect(authPackage.getStorageProvider()).toBe(mockStorageProvider);
99
- });
100
-
101
- it('should set and get UI provider', () => {
102
41
  authPackage.setUIProvider(mockUIProvider);
103
- expect(authPackage.getUIProvider()).toBe(mockUIProvider);
104
- });
105
-
106
- it('should set and get validation provider', () => {
107
42
  authPackage.setValidationProvider(mockValidationProvider);
43
+ expect(authPackage.getStorageProvider()).toBe(mockStorageProvider);
44
+ expect(authPackage.getUIProvider()).toBe(mockUIProvider);
108
45
  expect(authPackage.getValidationProvider()).toBe(mockValidationProvider);
109
46
  });
110
47
  });
111
48
 
112
- describe('isFeatureEnabled', () => {
113
- let authPackage: AuthPackage;
114
-
115
- beforeEach(() => {
116
- authPackage = new AuthPackage();
117
- });
118
-
49
+ describe('feature flags', () => {
119
50
  it('should return feature status from config', () => {
120
- expect(authPackage.isFeatureEnabled('anonymousMode')).toBe(true);
51
+ const authPackage = new AuthPackage({ features: { anonymousMode: false } });
52
+ expect(authPackage.isFeatureEnabled('anonymousMode')).toBe(false);
121
53
  expect(authPackage.isFeatureEnabled('registration')).toBe(true);
122
- expect(authPackage.isFeatureEnabled('passwordStrength')).toBe(true);
123
- });
124
-
125
- it('should return custom feature status', () => {
126
- const customConfig = {
127
- features: {
128
- anonymousMode: false,
129
- registration: false,
130
- passwordStrength: false,
131
- },
132
- };
133
-
134
- const customPackage = new AuthPackage(customConfig);
135
-
136
- expect(customPackage.isFeatureEnabled('anonymousMode')).toBe(false);
137
- expect(customPackage.isFeatureEnabled('registration')).toBe(false);
138
- expect(customPackage.isFeatureEnabled('passwordStrength')).toBe(false);
139
54
  });
140
55
  });
141
56
 
142
- describe('global package instance', () => {
143
- it('should initialize package globally', () => {
144
- const customConfig = {
145
- storageKeys: {
146
- anonymousMode: '@global_anonymous_mode',
147
- },
148
- };
149
-
150
- const packageInstance = initializeAuthPackage(customConfig);
151
- expect(packageInstance.getConfig().storageKeys.anonymousMode).toBe('@global_anonymous_mode');
152
- });
153
-
154
- it('should return existing package instance', () => {
155
- const firstInstance = initializeAuthPackage();
156
- const secondInstance = getAuthPackage();
57
+ describe('global instance', () => {
58
+ it('should manage global instances correctly', () => {
59
+ const instance = initializeAuthPackage({ storageKeys: { anonymousMode: '@custom' } });
60
+ expect(getAuthPackage()).toBe(instance);
61
+ expect(getAuthPackage()?.getConfig().storageKeys.anonymousMode).toBe('@custom');
157
62
 
158
- expect(firstInstance).toBe(secondInstance);
159
- });
160
-
161
- it('should return null when no package initialized', () => {
162
63
  resetAuthPackage();
163
- const packageInstance = getAuthPackage();
164
- expect(packageInstance).toBeNull();
165
- });
166
-
167
- it('should not reinitialize when already initialized', () => {
168
- const firstInstance = initializeAuthPackage();
169
- const secondInstance = initializeAuthPackage({
170
- storageKeys: { anonymousMode: '@different' },
171
- });
172
-
173
- expect(firstInstance).toBe(secondInstance);
174
- expect(secondInstance.getConfig().storageKeys.anonymousMode).toBe('@auth_anonymous_mode');
64
+ expect(getAuthPackage()).toBeNull();
175
65
  });
176
66
 
177
- it('should reset package instance', () => {
178
- initializeAuthPackage();
179
- expect(getAuthPackage()).not.toBeNull();
180
-
67
+ it('should return null when not initialized', () => {
181
68
  resetAuthPackage();
182
69
  expect(getAuthPackage()).toBeNull();
183
70
  });
184
- });
185
-
186
- describe('provider integration', () => {
187
- let authPackage: AuthPackage;
188
-
189
- beforeEach(() => {
190
- authPackage = new AuthPackage();
191
- authPackage.setStorageProvider(mockStorageProvider);
192
- authPackage.setUIProvider(mockUIProvider);
193
- authPackage.setValidationProvider(mockValidationProvider);
194
- });
195
-
196
- it('should integrate all providers', () => {
197
- expect(authPackage.getStorageProvider()).toBe(mockStorageProvider);
198
- expect(authPackage.getUIProvider()).toBe(mockUIProvider);
199
- expect(authPackage.getValidationProvider()).toBe(mockValidationProvider);
200
- });
201
- });
202
-
203
- describe('config validation', () => {
204
- it('should handle empty config', () => {
205
- const authPackage = new AuthPackage({});
206
- const config = authPackage.getConfig();
207
-
208
- expect(config).toEqual(DEFAULT_AUTH_PACKAGE_CONFIG);
209
- });
210
71
 
211
72
  it('should handle partial config', () => {
212
- const partialConfig = {
213
- features: {
214
- anonymousMode: false,
215
- },
216
- };
217
-
218
- const authPackage = new AuthPackage(partialConfig);
73
+ const authPackage = new AuthPackage({ features: { anonymousMode: false } });
219
74
  const config = authPackage.getConfig();
220
-
221
75
  expect(config.features.anonymousMode).toBe(false);
222
76
  expect(config.features.registration).toBe(true);
223
- expect(config.features.passwordStrength).toBe(true);
224
77
  });
225
78
  });
226
79
  });
@@ -0,0 +1,44 @@
1
+ import { validateDisplayName } from '../../../src/infrastructure/utils/AuthValidation';
2
+
3
+ describe('AuthDisplayNameValidation', () => {
4
+ describe('validateDisplayName', () => {
5
+ it('should reject empty name', () => {
6
+ const result = validateDisplayName('');
7
+ expect(result.isValid).toBe(false);
8
+ expect(result.error).toBe('Name is required');
9
+ });
10
+
11
+ it('should reject whitespace-only name', () => {
12
+ const result = validateDisplayName(' ');
13
+ expect(result.isValid).toBe(false);
14
+ expect(result.error).toBe('Name is required');
15
+ });
16
+
17
+ it('should reject name that is too short', () => {
18
+ const result = validateDisplayName('A');
19
+ expect(result.isValid).toBe(false);
20
+ expect(result.error).toBe('Name must be at least 2 characters');
21
+ });
22
+
23
+ it('should accept name that meets minimum length', () => {
24
+ const result = validateDisplayName('Al');
25
+ expect(result.isValid).toBe(true);
26
+ });
27
+
28
+ it('should use custom minimum length', () => {
29
+ const result = validateDisplayName('Al', 3);
30
+ expect(result.isValid).toBe(false);
31
+ expect(result.error).toBe('Name must be at least 3 characters');
32
+ });
33
+
34
+ it('should trim whitespace', () => {
35
+ const result = validateDisplayName(' John Doe ');
36
+ expect(result.isValid).toBe(true);
37
+ });
38
+
39
+ it('should accept name with special characters', () => {
40
+ const result = validateDisplayName('John-O\'Connor');
41
+ expect(result.isValid).toBe(true);
42
+ });
43
+ });
44
+ });
@@ -0,0 +1,38 @@
1
+ import { validateEmail } from '../../../src/infrastructure/utils/AuthValidation';
2
+
3
+ describe('AuthEmailValidation', () => {
4
+ describe('validateEmail', () => {
5
+ it('should reject empty email', () => {
6
+ const result = validateEmail('');
7
+ expect(result.isValid).toBe(false);
8
+ expect(result.error).toBe('Email is required');
9
+ });
10
+
11
+ it('should reject whitespace-only email', () => {
12
+ const result = validateEmail(' ');
13
+ expect(result.isValid).toBe(false);
14
+ expect(result.error).toBe('Email is required');
15
+ });
16
+
17
+ it('should reject invalid email format', () => {
18
+ const result = validateEmail('invalid-email');
19
+ expect(result.isValid).toBe(false);
20
+ expect(result.error).toBe('Please enter a valid email address');
21
+ });
22
+
23
+ it('should accept valid email format', () => {
24
+ const result = validateEmail('test@example.com');
25
+ expect(result.isValid).toBe(true);
26
+ });
27
+
28
+ it('should accept valid email with subdomain', () => {
29
+ const result = validateEmail('test@mail.example.com');
30
+ expect(result.isValid).toBe(true);
31
+ });
32
+
33
+ it('should trim whitespace', () => {
34
+ const result = validateEmail(' test@example.com ');
35
+ expect(result.isValid).toBe(true);
36
+ });
37
+ });
38
+ });