@go-mondo/identity-sdk 0.0.2-beta.65 → 0.0.2-beta.67

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.
@@ -1,76 +1,274 @@
1
1
  import { describe, expect, test } from 'vitest';
2
2
  import { generateUserId } from '../schema.js';
3
- import { InsertUserPayloadSchema, UserPayloadSchema, UserStatus, } from './schema.js';
3
+ import { InsertUserPayloadSchema, UpdateUserPayloadSchema, UserPayloadSchema, UserSchema, UserStatus, UserStatusSchema, VerifiedEmailOrPhonePropertiesSchema, UnverifiedEmailOrPhonePropertiesSchema, VerifiableAttribute, UserNamePropertiesSchema, UpdateUserNamePropertiesSchema, EmailOrPhonePropertiesSchema, UserAssociationReferenceSchema, } from './schema.js';
4
4
  describe('Customer - User', () => {
5
+ describe('VerifiableAttribute', () => {
6
+ test('should have correct constants', () => {
7
+ expect(VerifiableAttribute.EMAIL).toBe('email');
8
+ expect(VerifiableAttribute.PHONE_NUMBER).toBe('phoneNumber');
9
+ });
10
+ });
11
+ describe('UserStatus', () => {
12
+ test('should have correct constants', () => {
13
+ expect(UserStatus.ACTIVE).toBe('active');
14
+ expect(UserStatus.SUSPENDED).toBe('suspended');
15
+ expect(UserStatus.UNVERIFIED).toBe('unverified');
16
+ });
17
+ test('should parse valid status values', () => {
18
+ expect(UserStatusSchema.safeParse('active').success).toBe(true);
19
+ expect(UserStatusSchema.safeParse('suspended').success).toBe(true);
20
+ expect(UserStatusSchema.safeParse('unverified').success).toBe(true);
21
+ });
22
+ test('should reject invalid status values', () => {
23
+ expect(UserStatusSchema.safeParse('invalid').success).toBe(false);
24
+ expect(UserStatusSchema.safeParse('').success).toBe(false);
25
+ });
26
+ });
27
+ describe('UserNamePropertiesSchema', () => {
28
+ test('should parse valid name properties', () => {
29
+ const result = UserNamePropertiesSchema.safeParse({
30
+ givenName: 'John',
31
+ middleName: 'Robert',
32
+ familyName: 'Doe',
33
+ honorificPrefix: 'Dr.',
34
+ honorificSuffix: 'Jr.',
35
+ });
36
+ expect(result.success).toBe(true);
37
+ if (result.success) {
38
+ expect(result.data.givenName).toBe('John');
39
+ expect(result.data.familyName).toBe('Doe');
40
+ }
41
+ });
42
+ test('should transform null values to undefined', () => {
43
+ const result = UserNamePropertiesSchema.safeParse({
44
+ givenName: null,
45
+ familyName: null,
46
+ });
47
+ expect(result.success).toBe(true);
48
+ if (result.success) {
49
+ expect(result.data.givenName).toBeUndefined();
50
+ expect(result.data.familyName).toBeUndefined();
51
+ }
52
+ });
53
+ test('should allow empty object', () => {
54
+ const result = UserNamePropertiesSchema.safeParse({});
55
+ expect(result.success).toBe(true);
56
+ });
57
+ });
58
+ describe('UpdateUserNamePropertiesSchema', () => {
59
+ test('should parse valid name properties', () => {
60
+ const result = UpdateUserNamePropertiesSchema.safeParse({
61
+ givenName: 'Jane',
62
+ familyName: 'Smith',
63
+ });
64
+ expect(result.success).toBe(true);
65
+ });
66
+ test('should allow null values without transforming', () => {
67
+ const result = UpdateUserNamePropertiesSchema.safeParse({
68
+ givenName: null,
69
+ familyName: 'Smith',
70
+ });
71
+ expect(result.success).toBe(true);
72
+ if (result.success) {
73
+ expect(result.data.givenName).toBeNull();
74
+ }
75
+ });
76
+ });
77
+ describe('VerifiedEmailOrPhonePropertiesSchema', () => {
78
+ test('should parse valid verified email', () => {
79
+ const result = VerifiedEmailOrPhonePropertiesSchema.safeParse({
80
+ verifiedEmail: 'test@example.com',
81
+ });
82
+ expect(result.success).toBe(true);
83
+ if (result.success) {
84
+ expect(result.data.verifiedEmail).toBe('test@example.com');
85
+ }
86
+ });
87
+ test('should parse valid verified phone number', () => {
88
+ const result = VerifiedEmailOrPhonePropertiesSchema.safeParse({
89
+ verifiedPhoneNumber: '+1234567890',
90
+ });
91
+ expect(result.success).toBe(true);
92
+ if (result.success) {
93
+ expect(result.data.verifiedPhoneNumber).toBe('+1234567890');
94
+ }
95
+ });
96
+ test('should parse both fields together', () => {
97
+ const result = VerifiedEmailOrPhonePropertiesSchema.safeParse({
98
+ verifiedEmail: 'verified@example.com',
99
+ verifiedPhoneNumber: '+1111111111',
100
+ });
101
+ expect(result.success).toBe(true);
102
+ if (result.success) {
103
+ expect(result.data.verifiedEmail).toBe('verified@example.com');
104
+ expect(result.data.verifiedPhoneNumber).toBe('+1111111111');
105
+ }
106
+ });
107
+ test('should transform null values to undefined', () => {
108
+ const result = VerifiedEmailOrPhonePropertiesSchema.safeParse({
109
+ verifiedEmail: null,
110
+ verifiedPhoneNumber: null,
111
+ });
112
+ expect(result.success).toBe(true);
113
+ if (result.success) {
114
+ expect(result.data.verifiedEmail).toBeUndefined();
115
+ expect(result.data.verifiedPhoneNumber).toBeUndefined();
116
+ }
117
+ });
118
+ test('should reject invalid email format', () => {
119
+ const result = VerifiedEmailOrPhonePropertiesSchema.safeParse({
120
+ verifiedEmail: 'not-an-email',
121
+ });
122
+ expect(result.success).toBe(false);
123
+ });
124
+ test('should allow empty object', () => {
125
+ const result = VerifiedEmailOrPhonePropertiesSchema.safeParse({});
126
+ expect(result.success).toBe(true);
127
+ });
128
+ });
129
+ describe('UnverifiedEmailOrPhonePropertiesSchema', () => {
130
+ test('should parse valid unverified email', () => {
131
+ const result = UnverifiedEmailOrPhonePropertiesSchema.safeParse({
132
+ unverifiedEmail: 'pending@example.com',
133
+ });
134
+ expect(result.success).toBe(true);
135
+ if (result.success) {
136
+ expect(result.data.unverifiedEmail).toBe('pending@example.com');
137
+ }
138
+ });
139
+ test('should parse valid unverified phone number', () => {
140
+ const result = UnverifiedEmailOrPhonePropertiesSchema.safeParse({
141
+ unverifiedPhoneNumber: '+0987654321',
142
+ });
143
+ expect(result.success).toBe(true);
144
+ if (result.success) {
145
+ expect(result.data.unverifiedPhoneNumber).toBe('+0987654321');
146
+ }
147
+ });
148
+ test('should parse both fields together', () => {
149
+ const result = UnverifiedEmailOrPhonePropertiesSchema.safeParse({
150
+ unverifiedEmail: 'pending@example.com',
151
+ unverifiedPhoneNumber: '+2222222222',
152
+ });
153
+ expect(result.success).toBe(true);
154
+ if (result.success) {
155
+ expect(result.data.unverifiedEmail).toBe('pending@example.com');
156
+ expect(result.data.unverifiedPhoneNumber).toBe('+2222222222');
157
+ }
158
+ });
159
+ test('should transform null values to undefined', () => {
160
+ const result = UnverifiedEmailOrPhonePropertiesSchema.safeParse({
161
+ unverifiedEmail: null,
162
+ unverifiedPhoneNumber: null,
163
+ });
164
+ expect(result.success).toBe(true);
165
+ if (result.success) {
166
+ expect(result.data.unverifiedEmail).toBeUndefined();
167
+ expect(result.data.unverifiedPhoneNumber).toBeUndefined();
168
+ }
169
+ });
170
+ test('should reject invalid unverified email format', () => {
171
+ const result = UnverifiedEmailOrPhonePropertiesSchema.safeParse({
172
+ unverifiedEmail: 'also-not-an-email',
173
+ });
174
+ expect(result.success).toBe(false);
175
+ });
176
+ test('should allow empty object', () => {
177
+ const result = UnverifiedEmailOrPhonePropertiesSchema.safeParse({});
178
+ expect(result.success).toBe(true);
179
+ });
180
+ });
181
+ describe('EmailOrPhonePropertiesSchema', () => {
182
+ test('should parse email and phone number', () => {
183
+ const result = EmailOrPhonePropertiesSchema.safeParse({
184
+ email: 'test@example.com',
185
+ phoneNumber: '+1234567890',
186
+ });
187
+ expect(result.success).toBe(true);
188
+ if (result.success) {
189
+ expect(result.data.email).toBe('test@example.com');
190
+ expect(result.data.phoneNumber).toBe('+1234567890');
191
+ }
192
+ });
193
+ test('should transform null values to undefined', () => {
194
+ const result = EmailOrPhonePropertiesSchema.safeParse({
195
+ email: null,
196
+ phoneNumber: null,
197
+ });
198
+ expect(result.success).toBe(true);
199
+ if (result.success) {
200
+ expect(result.data.email).toBeUndefined();
201
+ expect(result.data.phoneNumber).toBeUndefined();
202
+ }
203
+ });
204
+ });
5
205
  describe('User Payload', () => {
6
206
  test('should parse attributes successfully', async () => {
7
207
  const item = {
8
208
  foo: 'bar',
9
209
  id: generateUserId(),
10
- phoneNumber: '123',
210
+ verifiedPhoneNumber: '123',
11
211
  status: UserStatus.ACTIVE,
12
212
  createdAt: new Date(),
13
213
  updatedAt: new Date(),
14
214
  };
15
215
  const result = UserPayloadSchema.safeParse(item);
16
- // Parse succeeds for valid data
17
216
  expect(result.success).toBe(true);
18
217
  if (result.success) {
19
218
  expect(result.data.metadata).toBeUndefined();
20
219
  }
21
220
  });
22
- });
23
- describe('Insert User Payload', () => {
24
- test('should parse attributes successfully', async () => {
221
+ test('should parse with all verified and unverified email/phone properties', async () => {
25
222
  const item = {
26
- foo: 'bar',
27
223
  id: generateUserId(),
28
- familyName: 'Foo',
29
- phoneNumber: '123',
224
+ verifiedEmail: 'verified@example.com',
225
+ unverifiedEmail: 'pending@example.com',
226
+ verifiedPhoneNumber: '+1234567890',
227
+ unverifiedPhoneNumber: '+0987654321',
228
+ status: UserStatus.ACTIVE,
229
+ createdAt: new Date(),
230
+ updatedAt: new Date(),
30
231
  };
31
- const result = InsertUserPayloadSchema.safeParse(item);
32
- // Parse succeeds for valid data
232
+ const result = UserPayloadSchema.safeParse(item);
33
233
  expect(result.success).toBe(true);
34
234
  if (result.success) {
35
- expect(result.data.metadata).toBeUndefined();
36
- expect(result.data.familyName).toBe(item.familyName);
235
+ expect(result.data.verifiedEmail).toBe('verified@example.com');
236
+ expect(result.data.unverifiedEmail).toBe('pending@example.com');
237
+ expect(result.data.verifiedPhoneNumber).toBe('+1234567890');
238
+ expect(result.data.unverifiedPhoneNumber).toBe('+0987654321');
37
239
  }
38
240
  });
39
- test('should serialize successfully', async () => {
241
+ test('should provide email alias for verifiedEmail', async () => {
40
242
  const item = {
41
- foo: 'bar',
42
243
  id: generateUserId(),
43
- phoneNumber: '123',
44
- metadata: new Map(),
244
+ verifiedEmail: 'verified@example.com',
245
+ status: UserStatus.ACTIVE,
246
+ createdAt: new Date(),
247
+ updatedAt: new Date(),
45
248
  };
46
- const result = InsertUserPayloadSchema.safeParse(item);
47
- // Parse succeeds for valid data
249
+ const result = UserPayloadSchema.safeParse(item);
48
250
  expect(result.success).toBe(true);
49
251
  if (result.success) {
50
- expect(result.data.metadata).toBeNull();
252
+ expect(result.data.email).toBe('verified@example.com');
253
+ expect(result.data.verifiedEmail).toBe('verified@example.com');
51
254
  }
52
255
  });
53
- test('should serialize nulls successfully', async () => {
54
- const payload = {
256
+ test('should provide phoneNumber alias for verifiedPhoneNumber', async () => {
257
+ const item = {
55
258
  id: generateUserId(),
56
- status: 'unverified',
57
- givenName: null,
58
- middleName: null,
59
- familyName: null,
60
- honorificPrefix: null,
61
- honorificSuffix: null,
62
- email: null,
63
- verifiedEmail: null,
64
- phoneNumber: null,
65
- verifiedPhoneNumber: null,
66
- createdAt: '2025-04-02T03:50:40.812Z',
67
- updatedAt: '2025-04-02T03:50:40.812Z',
259
+ verifiedPhoneNumber: '+1234567890',
260
+ status: UserStatus.ACTIVE,
261
+ createdAt: new Date(),
262
+ updatedAt: new Date(),
68
263
  };
69
- const result = UserPayloadSchema.safeParse(payload);
70
- // Parse succeeds for valid data
264
+ const result = UserPayloadSchema.safeParse(item);
71
265
  expect(result.success).toBe(true);
266
+ if (result.success) {
267
+ expect(result.data.phoneNumber).toBe('+1234567890');
268
+ expect(result.data.verifiedPhoneNumber).toBe('+1234567890');
269
+ }
72
270
  });
73
- test('should serialize nulls successfully', async () => {
271
+ test('should serialize nulls to undefined', async () => {
74
272
  const payload = {
75
273
  id: generateUserId(),
76
274
  status: 'unverified',
@@ -79,16 +277,299 @@ describe('Customer - User', () => {
79
277
  familyName: null,
80
278
  honorificPrefix: null,
81
279
  honorificSuffix: null,
82
- email: null,
83
280
  verifiedEmail: null,
84
- phoneNumber: null,
281
+ unverifiedEmail: null,
85
282
  verifiedPhoneNumber: null,
283
+ unverifiedPhoneNumber: null,
86
284
  createdAt: '2025-04-02T03:50:40.812Z',
87
285
  updatedAt: '2025-04-02T03:50:40.812Z',
88
286
  };
89
287
  const result = UserPayloadSchema.safeParse(payload);
90
- // Parse succeeds for valid data
91
288
  expect(result.success).toBe(true);
289
+ if (result.success) {
290
+ expect(result.data.verifiedEmail).toBeUndefined();
291
+ expect(result.data.unverifiedEmail).toBeUndefined();
292
+ expect(result.data.verifiedPhoneNumber).toBeUndefined();
293
+ expect(result.data.unverifiedPhoneNumber).toBeUndefined();
294
+ expect(result.data.email).toBeUndefined();
295
+ expect(result.data.phoneNumber).toBeUndefined();
296
+ }
297
+ });
298
+ });
299
+ describe('User Schema', () => {
300
+ test('should parse complete user object', async () => {
301
+ const user = {
302
+ id: generateUserId(),
303
+ givenName: 'John',
304
+ familyName: 'Doe',
305
+ verifiedEmail: 'john@example.com',
306
+ verifiedPhoneNumber: '+1234567890',
307
+ status: UserStatus.ACTIVE,
308
+ lastLogin: new Date(),
309
+ createdAt: new Date(),
310
+ updatedAt: new Date(),
311
+ };
312
+ const result = UserSchema.safeParse(user);
313
+ expect(result.success).toBe(true);
314
+ if (result.success) {
315
+ expect(result.data.givenName).toBe('John');
316
+ expect(result.data.verifiedEmail).toBe('john@example.com');
317
+ expect(result.data.verifiedPhoneNumber).toBe('+1234567890');
318
+ }
319
+ });
320
+ test('should provide email alias for verifiedEmail', async () => {
321
+ const user = {
322
+ id: generateUserId(),
323
+ verifiedEmail: 'john@example.com',
324
+ status: UserStatus.ACTIVE,
325
+ createdAt: new Date(),
326
+ updatedAt: new Date(),
327
+ };
328
+ const result = UserSchema.safeParse(user);
329
+ expect(result.success).toBe(true);
330
+ if (result.success) {
331
+ expect(result.data.email).toBe('john@example.com');
332
+ expect(result.data.verifiedEmail).toBe('john@example.com');
333
+ }
334
+ });
335
+ test('should provide phoneNumber alias for verifiedPhoneNumber', async () => {
336
+ const user = {
337
+ id: generateUserId(),
338
+ verifiedPhoneNumber: '+1234567890',
339
+ status: UserStatus.ACTIVE,
340
+ createdAt: new Date(),
341
+ updatedAt: new Date(),
342
+ };
343
+ const result = UserSchema.safeParse(user);
344
+ expect(result.success).toBe(true);
345
+ if (result.success) {
346
+ expect(result.data.phoneNumber).toBe('+1234567890');
347
+ expect(result.data.verifiedPhoneNumber).toBe('+1234567890');
348
+ }
349
+ });
350
+ test('should have undefined aliases when verified fields are undefined', async () => {
351
+ const user = {
352
+ id: generateUserId(),
353
+ status: UserStatus.ACTIVE,
354
+ createdAt: new Date(),
355
+ updatedAt: new Date(),
356
+ };
357
+ const result = UserSchema.safeParse(user);
358
+ expect(result.success).toBe(true);
359
+ if (result.success) {
360
+ expect(result.data.email).toBeUndefined();
361
+ expect(result.data.phoneNumber).toBeUndefined();
362
+ expect(result.data.verifiedEmail).toBeUndefined();
363
+ expect(result.data.verifiedPhoneNumber).toBeUndefined();
364
+ }
365
+ });
366
+ test('should parse user with deletedAt and deactivatedAt', async () => {
367
+ const user = {
368
+ id: generateUserId(),
369
+ status: UserStatus.SUSPENDED,
370
+ createdAt: new Date(),
371
+ updatedAt: new Date(),
372
+ deletedAt: new Date(),
373
+ deactivatedAt: new Date(),
374
+ };
375
+ const result = UserSchema.safeParse(user);
376
+ expect(result.success).toBe(true);
377
+ if (result.success) {
378
+ expect(result.data.deletedAt).toBeInstanceOf(Date);
379
+ expect(result.data.deactivatedAt).toBeInstanceOf(Date);
380
+ }
381
+ });
382
+ test('should include unverified fields alongside aliases', async () => {
383
+ const user = {
384
+ id: generateUserId(),
385
+ verifiedEmail: 'verified@example.com',
386
+ unverifiedEmail: 'pending@example.com',
387
+ verifiedPhoneNumber: '+1111111111',
388
+ unverifiedPhoneNumber: '+2222222222',
389
+ status: UserStatus.ACTIVE,
390
+ createdAt: new Date(),
391
+ updatedAt: new Date(),
392
+ };
393
+ const result = UserSchema.safeParse(user);
394
+ expect(result.success).toBe(true);
395
+ if (result.success) {
396
+ expect(result.data.email).toBe('verified@example.com');
397
+ expect(result.data.verifiedEmail).toBe('verified@example.com');
398
+ expect(result.data.unverifiedEmail).toBe('pending@example.com');
399
+ expect(result.data.phoneNumber).toBe('+1111111111');
400
+ expect(result.data.verifiedPhoneNumber).toBe('+1111111111');
401
+ expect(result.data.unverifiedPhoneNumber).toBe('+2222222222');
402
+ }
403
+ });
404
+ });
405
+ describe('Insert User Payload', () => {
406
+ test('should parse attributes successfully', async () => {
407
+ const item = {
408
+ foo: 'bar',
409
+ id: generateUserId(),
410
+ familyName: 'Foo',
411
+ verifiedPhoneNumber: '123',
412
+ };
413
+ const result = InsertUserPayloadSchema.safeParse(item);
414
+ expect(result.success).toBe(true);
415
+ if (result.success) {
416
+ expect(result.data.metadata).toBeUndefined();
417
+ expect(result.data.familyName).toBe(item.familyName);
418
+ }
419
+ });
420
+ test('should parse with all verified and unverified email/phone properties', async () => {
421
+ const item = {
422
+ id: generateUserId(),
423
+ verifiedEmail: 'verified@example.com',
424
+ unverifiedEmail: 'pending@example.com',
425
+ verifiedPhoneNumber: '+1234567890',
426
+ unverifiedPhoneNumber: '+0987654321',
427
+ };
428
+ const result = InsertUserPayloadSchema.safeParse(item);
429
+ expect(result.success).toBe(true);
430
+ if (result.success) {
431
+ expect(result.data.verifiedEmail).toBe('verified@example.com');
432
+ expect(result.data.unverifiedEmail).toBe('pending@example.com');
433
+ expect(result.data.verifiedPhoneNumber).toBe('+1234567890');
434
+ expect(result.data.unverifiedPhoneNumber).toBe('+0987654321');
435
+ }
436
+ });
437
+ test('should serialize empty Map to null', async () => {
438
+ const item = {
439
+ foo: 'bar',
440
+ id: generateUserId(),
441
+ verifiedPhoneNumber: '123',
442
+ metadata: new Map(),
443
+ };
444
+ const result = InsertUserPayloadSchema.safeParse(item);
445
+ expect(result.success).toBe(true);
446
+ if (result.success) {
447
+ expect(result.data.metadata).toBeNull();
448
+ }
449
+ });
450
+ test('should allow optional id and status', async () => {
451
+ const item = {
452
+ verifiedEmail: 'test@example.com',
453
+ };
454
+ const result = InsertUserPayloadSchema.safeParse(item);
455
+ expect(result.success).toBe(true);
456
+ if (result.success) {
457
+ expect(result.data.id).toBeUndefined();
458
+ expect(result.data.status).toBeUndefined();
459
+ }
460
+ });
461
+ test('should parse with roles association', async () => {
462
+ const item = {
463
+ id: generateUserId(),
464
+ verifiedEmail: 'test@example.com',
465
+ roles: [
466
+ 'rol_2NfYOTzVqhCHgWFzUL0WPfRRuhH',
467
+ 'rol_2NfYOTzVqhCHgWFzUL0WPfRRuhI',
468
+ ],
469
+ };
470
+ const result = InsertUserPayloadSchema.safeParse(item);
471
+ expect(result.success).toBe(true);
472
+ if (result.success) {
473
+ expect(result.data.roles).toEqual([
474
+ 'rol_2NfYOTzVqhCHgWFzUL0WPfRRuhH',
475
+ 'rol_2NfYOTzVqhCHgWFzUL0WPfRRuhI',
476
+ ]);
477
+ }
478
+ });
479
+ });
480
+ describe('Update User Payload', () => {
481
+ test('should parse suspended flag', async () => {
482
+ const result = UpdateUserPayloadSchema.safeParse({
483
+ suspended: true,
484
+ });
485
+ expect(result.success).toBe(true);
486
+ if (result.success) {
487
+ expect(result.data.suspended).toBe(true);
488
+ }
489
+ });
490
+ test('should parse name updates', async () => {
491
+ const result = UpdateUserPayloadSchema.safeParse({
492
+ givenName: 'Jane',
493
+ familyName: null,
494
+ });
495
+ expect(result.success).toBe(true);
496
+ if (result.success) {
497
+ expect(result.data.givenName).toBe('Jane');
498
+ expect(result.data.familyName).toBeNull();
499
+ }
500
+ });
501
+ test('should parse verified and unverified email/phone updates', async () => {
502
+ const result = UpdateUserPayloadSchema.safeParse({
503
+ verifiedEmail: 'newemail@example.com',
504
+ unverifiedEmail: 'pending@example.com',
505
+ verifiedPhoneNumber: '+9999999999',
506
+ unverifiedPhoneNumber: '+8888888888',
507
+ });
508
+ expect(result.success).toBe(true);
509
+ if (result.success) {
510
+ expect(result.data.verifiedEmail).toBe('newemail@example.com');
511
+ expect(result.data.unverifiedEmail).toBe('pending@example.com');
512
+ expect(result.data.verifiedPhoneNumber).toBe('+9999999999');
513
+ expect(result.data.unverifiedPhoneNumber).toBe('+8888888888');
514
+ }
515
+ });
516
+ test('should parse metadata updates', async () => {
517
+ const result = UpdateUserPayloadSchema.safeParse({
518
+ metadata: { key: 'value' },
519
+ });
520
+ expect(result.success).toBe(true);
521
+ if (result.success) {
522
+ expect(result.data.metadata).toEqual({ key: 'value' });
523
+ }
524
+ });
525
+ test('should allow empty object', async () => {
526
+ const result = UpdateUserPayloadSchema.safeParse({});
527
+ expect(result.success).toBe(true);
528
+ });
529
+ });
530
+ describe('UserAssociationReferenceSchema', () => {
531
+ test('should parse valid association reference', () => {
532
+ const result = UserAssociationReferenceSchema.safeParse({
533
+ id: generateUserId(),
534
+ givenName: 'John',
535
+ familyName: 'Doe',
536
+ email: 'john@example.com',
537
+ phoneNumber: '+1234567890',
538
+ model: 'User',
539
+ });
540
+ expect(result.success).toBe(true);
541
+ if (result.success) {
542
+ expect(result.data.model).toBe('User');
543
+ expect(result.data.status).toBe('unverified');
544
+ }
545
+ });
546
+ test('should default status to unverified', () => {
547
+ const result = UserAssociationReferenceSchema.safeParse({
548
+ id: generateUserId(),
549
+ model: 'User',
550
+ });
551
+ expect(result.success).toBe(true);
552
+ if (result.success) {
553
+ expect(result.data.status).toBe('unverified');
554
+ }
555
+ });
556
+ test('should allow custom status', () => {
557
+ const result = UserAssociationReferenceSchema.safeParse({
558
+ id: generateUserId(),
559
+ status: 'active',
560
+ model: 'User',
561
+ });
562
+ expect(result.success).toBe(true);
563
+ if (result.success) {
564
+ expect(result.data.status).toBe('active');
565
+ }
566
+ });
567
+ test('should reject invalid model literal', () => {
568
+ const result = UserAssociationReferenceSchema.safeParse({
569
+ id: generateUserId(),
570
+ model: 'Organization',
571
+ });
572
+ expect(result.success).toBe(false);
92
573
  });
93
574
  });
94
575
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-mondo/identity-sdk",
3
- "version": "0.0.2-beta.65",
3
+ "version": "0.0.2-beta.67",
4
4
  "type": "module",
5
5
  "description": "A node SDK for Mondo Identity",
6
6
  "license": "MIT",