Skip to content

Commit 86bac43

Browse files
Copilothotlong
andcommitted
Add comprehensive tests for identity data models (User, Account, Session)
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent a1a5a58 commit 86bac43

1 file changed

Lines changed: 281 additions & 0 deletions

File tree

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
import { describe, it, expect } from 'vitest';
2+
import {
3+
UserSchema,
4+
AccountSchema,
5+
SessionSchema,
6+
VerificationTokenSchema,
7+
type User,
8+
type Account,
9+
type Session,
10+
type VerificationToken,
11+
} from "./identity.zod";
12+
13+
describe('UserSchema', () => {
14+
it('should accept valid user data', () => {
15+
const user: User = {
16+
id: 'user_123',
17+
email: 'test@example.com',
18+
emailVerified: true,
19+
name: 'Test User',
20+
image: 'https://example.com/avatar.jpg',
21+
createdAt: new Date(),
22+
updatedAt: new Date(),
23+
};
24+
25+
expect(() => UserSchema.parse(user)).not.toThrow();
26+
});
27+
28+
it('should accept minimal user data', () => {
29+
const user = {
30+
id: 'user_123',
31+
email: 'test@example.com',
32+
createdAt: new Date(),
33+
updatedAt: new Date(),
34+
};
35+
36+
const result = UserSchema.parse(user);
37+
expect(result.emailVerified).toBe(false); // default value
38+
});
39+
40+
it('should validate email format', () => {
41+
const user = {
42+
id: 'user_123',
43+
email: 'invalid-email',
44+
createdAt: new Date(),
45+
updatedAt: new Date(),
46+
};
47+
48+
expect(() => UserSchema.parse(user)).toThrow();
49+
});
50+
51+
it('should validate image URL format', () => {
52+
const user = {
53+
id: 'user_123',
54+
email: 'test@example.com',
55+
image: 'not-a-url',
56+
createdAt: new Date(),
57+
updatedAt: new Date(),
58+
};
59+
60+
expect(() => UserSchema.parse(user)).toThrow();
61+
});
62+
63+
it('should accept user without optional fields', () => {
64+
const user = {
65+
id: 'user_123',
66+
email: 'test@example.com',
67+
createdAt: new Date(),
68+
updatedAt: new Date(),
69+
};
70+
71+
expect(() => UserSchema.parse(user)).not.toThrow();
72+
});
73+
});
74+
75+
describe('AccountSchema', () => {
76+
it('should accept valid OAuth account', () => {
77+
const account: Account = {
78+
id: 'account_123',
79+
userId: 'user_123',
80+
type: 'oauth',
81+
provider: 'google',
82+
providerAccountId: 'google_user_123',
83+
accessToken: 'access_token_xyz',
84+
refreshToken: 'refresh_token_xyz',
85+
expiresAt: Date.now() + 3600000,
86+
tokenType: 'Bearer',
87+
scope: 'openid profile email',
88+
createdAt: new Date(),
89+
updatedAt: new Date(),
90+
};
91+
92+
expect(() => AccountSchema.parse(account)).not.toThrow();
93+
});
94+
95+
it('should accept minimal account data', () => {
96+
const account = {
97+
id: 'account_123',
98+
userId: 'user_123',
99+
type: 'email',
100+
provider: 'email',
101+
providerAccountId: 'email_user_123',
102+
createdAt: new Date(),
103+
updatedAt: new Date(),
104+
};
105+
106+
expect(() => AccountSchema.parse(account)).not.toThrow();
107+
});
108+
109+
it('should accept all account types', () => {
110+
const types = ['oauth', 'oidc', 'email', 'credentials', 'saml', 'ldap'] as const;
111+
112+
types.forEach((type) => {
113+
const account = {
114+
id: 'account_123',
115+
userId: 'user_123',
116+
type,
117+
provider: 'provider',
118+
providerAccountId: 'provider_account_123',
119+
createdAt: new Date(),
120+
updatedAt: new Date(),
121+
};
122+
expect(() => AccountSchema.parse(account)).not.toThrow();
123+
});
124+
});
125+
126+
it('should reject invalid account type', () => {
127+
const account = {
128+
id: 'account_123',
129+
userId: 'user_123',
130+
type: 'invalid',
131+
provider: 'provider',
132+
providerAccountId: 'provider_account_123',
133+
createdAt: new Date(),
134+
updatedAt: new Date(),
135+
};
136+
137+
expect(() => AccountSchema.parse(account)).toThrow();
138+
});
139+
});
140+
141+
describe('SessionSchema', () => {
142+
it('should accept valid session data', () => {
143+
const session: Session = {
144+
id: 'session_123',
145+
sessionToken: 'session_token_xyz',
146+
userId: 'user_123',
147+
expires: new Date(Date.now() + 86400000),
148+
createdAt: new Date(),
149+
updatedAt: new Date(),
150+
ipAddress: '192.168.1.1',
151+
userAgent: 'Mozilla/5.0',
152+
fingerprint: 'fingerprint_xyz',
153+
};
154+
155+
expect(() => SessionSchema.parse(session)).not.toThrow();
156+
});
157+
158+
it('should accept minimal session data', () => {
159+
const session = {
160+
id: 'session_123',
161+
sessionToken: 'session_token_xyz',
162+
userId: 'user_123',
163+
expires: new Date(),
164+
createdAt: new Date(),
165+
updatedAt: new Date(),
166+
};
167+
168+
expect(() => SessionSchema.parse(session)).not.toThrow();
169+
});
170+
171+
it('should accept session with device information', () => {
172+
const session = {
173+
id: 'session_123',
174+
sessionToken: 'session_token_xyz',
175+
userId: 'user_123',
176+
expires: new Date(),
177+
createdAt: new Date(),
178+
updatedAt: new Date(),
179+
ipAddress: '10.0.0.1',
180+
userAgent: 'Chrome/120.0.0.0',
181+
fingerprint: 'device_fingerprint',
182+
};
183+
184+
expect(() => SessionSchema.parse(session)).not.toThrow();
185+
});
186+
});
187+
188+
describe('VerificationTokenSchema', () => {
189+
it('should accept valid verification token', () => {
190+
const token: VerificationToken = {
191+
identifier: 'test@example.com',
192+
token: 'verification_token_xyz',
193+
expires: new Date(Date.now() + 3600000),
194+
createdAt: new Date(),
195+
};
196+
197+
expect(() => VerificationTokenSchema.parse(token)).not.toThrow();
198+
});
199+
200+
it('should accept token with phone identifier', () => {
201+
const token = {
202+
identifier: '+1234567890',
203+
token: 'verification_token_xyz',
204+
expires: new Date(),
205+
createdAt: new Date(),
206+
};
207+
208+
expect(() => VerificationTokenSchema.parse(token)).not.toThrow();
209+
});
210+
211+
it('should accept token with email identifier', () => {
212+
const token = {
213+
identifier: 'user@example.com',
214+
token: 'reset_password_token',
215+
expires: new Date(),
216+
createdAt: new Date(),
217+
};
218+
219+
expect(() => VerificationTokenSchema.parse(token)).not.toThrow();
220+
});
221+
});
222+
223+
describe('Type inference', () => {
224+
it('should correctly infer User type', () => {
225+
const user: User = {
226+
id: 'user_123',
227+
email: 'test@example.com',
228+
emailVerified: true,
229+
createdAt: new Date(),
230+
updatedAt: new Date(),
231+
};
232+
233+
// This test passes if TypeScript compiles without errors
234+
expect(user.id).toBe('user_123');
235+
expect(user.email).toBe('test@example.com');
236+
});
237+
238+
it('should correctly infer Account type', () => {
239+
const account: Account = {
240+
id: 'account_123',
241+
userId: 'user_123',
242+
type: 'oauth',
243+
provider: 'google',
244+
providerAccountId: 'google_123',
245+
createdAt: new Date(),
246+
updatedAt: new Date(),
247+
};
248+
249+
// This test passes if TypeScript compiles without errors
250+
expect(account.type).toBe('oauth');
251+
expect(account.provider).toBe('google');
252+
});
253+
254+
it('should correctly infer Session type', () => {
255+
const session: Session = {
256+
id: 'session_123',
257+
sessionToken: 'token_xyz',
258+
userId: 'user_123',
259+
expires: new Date(),
260+
createdAt: new Date(),
261+
updatedAt: new Date(),
262+
};
263+
264+
// This test passes if TypeScript compiles without errors
265+
expect(session.id).toBe('session_123');
266+
expect(session.userId).toBe('user_123');
267+
});
268+
269+
it('should correctly infer VerificationToken type', () => {
270+
const token: VerificationToken = {
271+
identifier: 'test@example.com',
272+
token: 'token_xyz',
273+
expires: new Date(),
274+
createdAt: new Date(),
275+
};
276+
277+
// This test passes if TypeScript compiles without errors
278+
expect(token.identifier).toBe('test@example.com');
279+
expect(token.token).toBe('token_xyz');
280+
});
281+
});

0 commit comments

Comments
 (0)