@getmicdrop/svelte-components 5.17.1 → 5.17.4
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/dist/calendar/Calendar/MiniMonthCalendar.svelte +5 -7
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -1
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +2 -3
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +1 -1
- package/dist/calendar/PublicCard/PublicCard.svelte +23 -14
- package/dist/calendar/PublicCard/PublicCard.svelte.d.ts.map +1 -1
- package/dist/calendar/ShowCard/ShowCard.spec.js +1 -7
- package/dist/calendar/ShowCard/ShowCard.svelte +10 -1
- package/dist/calendar/ShowCard/ShowCard.svelte.d.ts.map +1 -1
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +11 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts +2 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +1 -1
- package/dist/components/Heading.spec.d.ts +2 -0
- package/dist/components/Heading.spec.d.ts.map +1 -0
- package/dist/components/Heading.spec.js +89 -0
- package/dist/components/Layout/__tests__/AppShell.test.js +140 -0
- package/dist/components/Text.spec.d.ts +2 -0
- package/dist/components/Text.spec.d.ts.map +1 -0
- package/dist/components/Text.spec.js +89 -0
- package/dist/config.d.ts +102 -0
- package/dist/config.js +147 -1
- package/dist/datetime/README.md +323 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts +2 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts.map +1 -0
- package/dist/forms/createFormStore.svelte.spec.js +387 -0
- package/dist/messages.d.ts +43 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +57 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.js +59 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatBubble.spec.js +91 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatContainer.spec.js +30 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatDateDivider.spec.js +30 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.js +46 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.js +32 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.js +58 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.js +65 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.js +79 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.js +81 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatTextBubble.spec.js +35 -0
- package/dist/patterns/data/DataTable.spec.js +61 -0
- package/dist/patterns/forms/FormGrid.spec.js +34 -0
- package/dist/patterns/layout/Sidebar.spec.js +240 -1
- package/dist/patterns/layout/SidebarTestWrapper.svelte +34 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts +23 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts.map +1 -0
- package/dist/patterns/navigation/Header.spec.js +123 -0
- package/dist/primitives/Accordion/Accordion.spec.js +112 -2
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte +28 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts +7 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.spec.js +23 -0
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +102 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte +20 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts +10 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts +2 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.js +44 -0
- package/dist/primitives/Checkbox/Checkbox.spec.js +32 -0
- package/dist/primitives/Drawer/Drawer.spec.js +437 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte +86 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts +26 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.spec.js +116 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.js +30 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.js +155 -1
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte +43 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts +17 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.d.ts +2 -0
- package/dist/primitives/Helper/Helper.spec.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.js +57 -0
- package/dist/primitives/Input/Input.spec.js +664 -0
- package/dist/primitives/Input/Input.svelte +18 -10
- package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.spec.js +414 -0
- package/dist/primitives/Label/Label.spec.js +9 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts +2 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts.map +1 -0
- package/dist/primitives/LandingButton/LandingButton.spec.js +61 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts +2 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts.map +1 -0
- package/dist/primitives/MenuItem/MenuItem.spec.js +130 -0
- package/dist/primitives/Modal/Modal.spec.js +215 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts +2 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts.map +1 -0
- package/dist/primitives/NavItem/NavItem.spec.js +97 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts +2 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts.map +1 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.js +78 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts +2 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts.map +1 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.js +61 -0
- package/dist/primitives/Spinner/Spinner.spec.js +13 -0
- package/dist/primitives/Toggle.spec.js +75 -0
- package/dist/primitives/ToggleTestWrapper.svelte +30 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts +29 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts +2 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.js +126 -0
- package/dist/recipes/inputs/Search.spec.js +66 -2
- package/dist/recipes/modals/ConfirmationModal.spec.js +190 -0
- package/dist/schemas/__tests__/auth.test.d.ts +2 -0
- package/dist/schemas/__tests__/auth.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/auth.test.js +210 -0
- package/dist/schemas/__tests__/common.test.d.ts +2 -0
- package/dist/schemas/__tests__/common.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/common.test.js +340 -0
- package/dist/schemas/__tests__/domain.test.d.ts +2 -0
- package/dist/schemas/__tests__/domain.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/domain.test.js +293 -0
- package/dist/schemas/__tests__/order.test.d.ts +2 -0
- package/dist/schemas/__tests__/order.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/order.test.js +349 -0
- package/dist/schemas/__tests__/user.test.d.ts +2 -0
- package/dist/schemas/__tests__/user.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/user.test.js +325 -0
- package/dist/schemas/auth.d.ts +41 -0
- package/dist/schemas/auth.d.ts.map +1 -0
- package/dist/schemas/auth.js +69 -0
- package/dist/schemas/common.d.ts +43 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +157 -0
- package/dist/schemas/event.d.ts +82 -0
- package/dist/schemas/event.d.ts.map +1 -0
- package/dist/schemas/event.js +58 -0
- package/dist/schemas/index.d.ts +10 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +9 -0
- package/dist/schemas/order.d.ts +111 -0
- package/dist/schemas/order.d.ts.map +1 -0
- package/dist/schemas/order.js +73 -0
- package/dist/schemas/performer.d.ts +133 -0
- package/dist/schemas/performer.d.ts.map +1 -0
- package/dist/schemas/performer.js +73 -0
- package/dist/schemas/promo.d.ts +87 -0
- package/dist/schemas/promo.d.ts.map +1 -0
- package/dist/schemas/promo.js +98 -0
- package/dist/schemas/ticket.d.ts +104 -0
- package/dist/schemas/ticket.d.ts.map +1 -0
- package/dist/schemas/ticket.js +82 -0
- package/dist/schemas/user.d.ts +92 -0
- package/dist/schemas/user.d.ts.map +1 -0
- package/dist/schemas/user.js +53 -0
- package/dist/schemas/venue.d.ts +95 -0
- package/dist/schemas/venue.d.ts.map +1 -0
- package/dist/schemas/venue.js +52 -0
- package/dist/stores/auth.svelte.spec.d.ts +2 -0
- package/dist/stores/auth.svelte.spec.d.ts.map +1 -0
- package/dist/stores/auth.svelte.spec.js +112 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts +2 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formDataStore.svelte.spec.js +150 -0
- package/dist/stores/formSave.svelte.spec.d.ts +2 -0
- package/dist/stores/formSave.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formSave.svelte.spec.js +196 -0
- package/dist/stores/navigation.spec.d.ts +2 -0
- package/dist/stores/navigation.spec.d.ts.map +1 -0
- package/dist/stores/navigation.spec.js +53 -0
- package/dist/telemetry.spec.js +5 -0
- package/dist/tokens/__tests__/sizing.test.js +2 -2
- package/dist/tokens/sizing.d.ts +5 -0
- package/dist/tokens/sizing.d.ts.map +1 -1
- package/dist/tokens/sizing.js +6 -0
- package/dist/utils/haptic.spec.d.ts +2 -0
- package/dist/utils/haptic.spec.d.ts.map +1 -0
- package/dist/utils/haptic.spec.js +153 -0
- package/dist/utils/imageOptimizer.spec.d.ts +2 -0
- package/dist/utils/imageOptimizer.spec.d.ts.map +1 -0
- package/dist/utils/imageOptimizer.spec.js +201 -0
- package/dist/utils/logger.spec.d.ts +2 -0
- package/dist/utils/logger.spec.d.ts.map +1 -0
- package/dist/utils/logger.spec.js +95 -0
- package/package.json +1 -2
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { forgotPasswordSchema, loginSchema, passwordChangeSchema, passwordSchema, profileUpdateSchema, registerSchema, resetPasswordSchema, } from '../auth';
|
|
3
|
+
describe('passwordSchema', () => {
|
|
4
|
+
it('accepts valid password', () => {
|
|
5
|
+
const result = passwordSchema.safeParse('SecurePass123');
|
|
6
|
+
expect(result.success).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
it('rejects password too short', () => {
|
|
9
|
+
const result = passwordSchema.safeParse('Short1');
|
|
10
|
+
expect(result.success).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
it('rejects password without uppercase', () => {
|
|
13
|
+
const result = passwordSchema.safeParse('securepass123');
|
|
14
|
+
expect(result.success).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
it('rejects password without lowercase', () => {
|
|
17
|
+
const result = passwordSchema.safeParse('SECUREPASS123');
|
|
18
|
+
expect(result.success).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
it('rejects password without number', () => {
|
|
21
|
+
const result = passwordSchema.safeParse('SecurePassword');
|
|
22
|
+
expect(result.success).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('loginSchema', () => {
|
|
26
|
+
it('accepts valid login data', () => {
|
|
27
|
+
const result = loginSchema.safeParse({
|
|
28
|
+
email: 'test@example.com',
|
|
29
|
+
password: 'anypassword',
|
|
30
|
+
});
|
|
31
|
+
expect(result.success).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
it('defaults rememberMe to false', () => {
|
|
34
|
+
const result = loginSchema.safeParse({
|
|
35
|
+
email: 'test@example.com',
|
|
36
|
+
password: 'anypassword',
|
|
37
|
+
});
|
|
38
|
+
expect(result.success).toBe(true);
|
|
39
|
+
if (result.success) {
|
|
40
|
+
expect(result.data.rememberMe).toBe(false);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
it('rejects invalid email', () => {
|
|
44
|
+
const result = loginSchema.safeParse({
|
|
45
|
+
email: 'invalid',
|
|
46
|
+
password: 'anypassword',
|
|
47
|
+
});
|
|
48
|
+
expect(result.success).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
it('rejects empty password', () => {
|
|
51
|
+
const result = loginSchema.safeParse({
|
|
52
|
+
email: 'test@example.com',
|
|
53
|
+
password: '',
|
|
54
|
+
});
|
|
55
|
+
expect(result.success).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe('registerSchema', () => {
|
|
59
|
+
it('accepts valid registration data', () => {
|
|
60
|
+
const result = registerSchema.safeParse({
|
|
61
|
+
email: 'test@example.com',
|
|
62
|
+
password: 'SecurePass123',
|
|
63
|
+
confirmPassword: 'SecurePass123',
|
|
64
|
+
firstName: 'John',
|
|
65
|
+
lastName: 'Doe',
|
|
66
|
+
acceptTerms: true,
|
|
67
|
+
});
|
|
68
|
+
expect(result.success).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
it('rejects mismatched passwords', () => {
|
|
71
|
+
const result = registerSchema.safeParse({
|
|
72
|
+
email: 'test@example.com',
|
|
73
|
+
password: 'SecurePass123',
|
|
74
|
+
confirmPassword: 'DifferentPass123',
|
|
75
|
+
firstName: 'John',
|
|
76
|
+
lastName: 'Doe',
|
|
77
|
+
acceptTerms: true,
|
|
78
|
+
});
|
|
79
|
+
expect(result.success).toBe(false);
|
|
80
|
+
if (!result.success) {
|
|
81
|
+
const error = result.error.issues.find(e => e.path.includes('confirmPassword'));
|
|
82
|
+
expect(error?.message).toBe('Passwords do not match');
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
it('rejects if terms not accepted', () => {
|
|
86
|
+
const result = registerSchema.safeParse({
|
|
87
|
+
email: 'test@example.com',
|
|
88
|
+
password: 'SecurePass123',
|
|
89
|
+
confirmPassword: 'SecurePass123',
|
|
90
|
+
firstName: 'John',
|
|
91
|
+
lastName: 'Doe',
|
|
92
|
+
acceptTerms: false,
|
|
93
|
+
});
|
|
94
|
+
expect(result.success).toBe(false);
|
|
95
|
+
});
|
|
96
|
+
it('rejects weak password', () => {
|
|
97
|
+
const result = registerSchema.safeParse({
|
|
98
|
+
email: 'test@example.com',
|
|
99
|
+
password: 'weak',
|
|
100
|
+
confirmPassword: 'weak',
|
|
101
|
+
firstName: 'John',
|
|
102
|
+
lastName: 'Doe',
|
|
103
|
+
acceptTerms: true,
|
|
104
|
+
});
|
|
105
|
+
expect(result.success).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('passwordChangeSchema', () => {
|
|
109
|
+
it('accepts valid password change data', () => {
|
|
110
|
+
const result = passwordChangeSchema.safeParse({
|
|
111
|
+
currentPassword: 'OldPassword123',
|
|
112
|
+
newPassword: 'NewSecurePass456',
|
|
113
|
+
confirmNewPassword: 'NewSecurePass456',
|
|
114
|
+
});
|
|
115
|
+
expect(result.success).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
it('rejects if new password same as current', () => {
|
|
118
|
+
const result = passwordChangeSchema.safeParse({
|
|
119
|
+
currentPassword: 'SecurePass123',
|
|
120
|
+
newPassword: 'SecurePass123',
|
|
121
|
+
confirmNewPassword: 'SecurePass123',
|
|
122
|
+
});
|
|
123
|
+
expect(result.success).toBe(false);
|
|
124
|
+
if (!result.success) {
|
|
125
|
+
const error = result.error.issues.find(e => e.path.includes('newPassword'));
|
|
126
|
+
expect(error?.message).toBe('New password must be different from current password');
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
it('rejects mismatched confirm password', () => {
|
|
130
|
+
const result = passwordChangeSchema.safeParse({
|
|
131
|
+
currentPassword: 'OldPassword123',
|
|
132
|
+
newPassword: 'NewSecurePass456',
|
|
133
|
+
confirmNewPassword: 'DifferentPass789',
|
|
134
|
+
});
|
|
135
|
+
expect(result.success).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe('forgotPasswordSchema', () => {
|
|
139
|
+
it('accepts valid email', () => {
|
|
140
|
+
const result = forgotPasswordSchema.safeParse({
|
|
141
|
+
email: 'test@example.com',
|
|
142
|
+
});
|
|
143
|
+
expect(result.success).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
it('rejects invalid email', () => {
|
|
146
|
+
const result = forgotPasswordSchema.safeParse({
|
|
147
|
+
email: 'invalid',
|
|
148
|
+
});
|
|
149
|
+
expect(result.success).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe('resetPasswordSchema', () => {
|
|
153
|
+
it('accepts valid reset data', () => {
|
|
154
|
+
const result = resetPasswordSchema.safeParse({
|
|
155
|
+
token: 'valid-token-123',
|
|
156
|
+
password: 'NewSecurePass123',
|
|
157
|
+
confirmPassword: 'NewSecurePass123',
|
|
158
|
+
});
|
|
159
|
+
expect(result.success).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
it('rejects mismatched passwords', () => {
|
|
162
|
+
const result = resetPasswordSchema.safeParse({
|
|
163
|
+
token: 'valid-token-123',
|
|
164
|
+
password: 'NewSecurePass123',
|
|
165
|
+
confirmPassword: 'DifferentPass456',
|
|
166
|
+
});
|
|
167
|
+
expect(result.success).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
it('rejects empty token', () => {
|
|
170
|
+
const result = resetPasswordSchema.safeParse({
|
|
171
|
+
token: '',
|
|
172
|
+
password: 'NewSecurePass123',
|
|
173
|
+
confirmPassword: 'NewSecurePass123',
|
|
174
|
+
});
|
|
175
|
+
expect(result.success).toBe(false);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
describe('profileUpdateSchema', () => {
|
|
179
|
+
it('accepts valid profile data', () => {
|
|
180
|
+
const result = profileUpdateSchema.safeParse({
|
|
181
|
+
firstName: 'John',
|
|
182
|
+
lastName: 'Doe',
|
|
183
|
+
});
|
|
184
|
+
expect(result.success).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
it('accepts profile with phone', () => {
|
|
187
|
+
const result = profileUpdateSchema.safeParse({
|
|
188
|
+
firstName: 'John',
|
|
189
|
+
lastName: 'Doe',
|
|
190
|
+
phone: '555-123-4567',
|
|
191
|
+
});
|
|
192
|
+
expect(result.success).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
it('accepts profile with bio', () => {
|
|
195
|
+
const result = profileUpdateSchema.safeParse({
|
|
196
|
+
firstName: 'John',
|
|
197
|
+
lastName: 'Doe',
|
|
198
|
+
bio: 'A short bio about me.',
|
|
199
|
+
});
|
|
200
|
+
expect(result.success).toBe(true);
|
|
201
|
+
});
|
|
202
|
+
it('rejects bio over 500 characters', () => {
|
|
203
|
+
const result = profileUpdateSchema.safeParse({
|
|
204
|
+
firstName: 'John',
|
|
205
|
+
lastName: 'Doe',
|
|
206
|
+
bio: 'x'.repeat(501),
|
|
207
|
+
});
|
|
208
|
+
expect(result.success).toBe(false);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.test.d.ts","sourceRoot":"","sources":["../../../src/lib/schemas/__tests__/common.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { addressSchema, dateSchema, emailSchema, futureDateSchema, nonNegativeIntSchema, numberRange, optionalString, percentageSchema, phoneSchema, positiveIntSchema, priceSchema, requiredString, stringToInt, stringToNumber, timezoneSchema, urlSchema, usStateSchema, uuidSchema, zipCodeSchema, } from '../common';
|
|
3
|
+
describe('emailSchema', () => {
|
|
4
|
+
it('accepts valid email', () => {
|
|
5
|
+
const result = emailSchema.safeParse('test@example.com');
|
|
6
|
+
expect(result.success).toBe(true);
|
|
7
|
+
if (result.success) {
|
|
8
|
+
expect(result.data).toBe('test@example.com');
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
it('lowercases and trims email', () => {
|
|
12
|
+
const result = emailSchema.safeParse(' TEST@EXAMPLE.COM ');
|
|
13
|
+
expect(result.success).toBe(true);
|
|
14
|
+
if (result.success) {
|
|
15
|
+
expect(result.data).toBe('test@example.com');
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
it('rejects invalid email', () => {
|
|
19
|
+
const result = emailSchema.safeParse('invalid-email');
|
|
20
|
+
expect(result.success).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
it('rejects empty string', () => {
|
|
23
|
+
const result = emailSchema.safeParse('');
|
|
24
|
+
expect(result.success).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('phoneSchema', () => {
|
|
28
|
+
it('accepts valid US phone number', () => {
|
|
29
|
+
const result = phoneSchema.safeParse('(555) 123-4567');
|
|
30
|
+
expect(result.success).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it('strips non-digit characters', () => {
|
|
33
|
+
const result = phoneSchema.safeParse('555-123-4567');
|
|
34
|
+
expect(result.success).toBe(true);
|
|
35
|
+
if (result.success) {
|
|
36
|
+
expect(result.data).toBe('5551234567');
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
it('accepts empty string as optional', () => {
|
|
40
|
+
const result = phoneSchema.safeParse('');
|
|
41
|
+
expect(result.success).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('urlSchema', () => {
|
|
45
|
+
it('accepts valid URL', () => {
|
|
46
|
+
const result = urlSchema.safeParse('https://example.com');
|
|
47
|
+
expect(result.success).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it('rejects invalid URL', () => {
|
|
50
|
+
const result = urlSchema.safeParse('not-a-url');
|
|
51
|
+
expect(result.success).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
it('accepts empty string as optional', () => {
|
|
54
|
+
const result = urlSchema.safeParse('');
|
|
55
|
+
expect(result.success).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe('uuidSchema', () => {
|
|
59
|
+
it('accepts valid UUID', () => {
|
|
60
|
+
const result = uuidSchema.safeParse('550e8400-e29b-41d4-a716-446655440000');
|
|
61
|
+
expect(result.success).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
it('rejects invalid UUID', () => {
|
|
64
|
+
const result = uuidSchema.safeParse('not-a-uuid');
|
|
65
|
+
expect(result.success).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('positiveIntSchema', () => {
|
|
69
|
+
it('accepts positive integer', () => {
|
|
70
|
+
const result = positiveIntSchema.safeParse(5);
|
|
71
|
+
expect(result.success).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
it('rejects zero', () => {
|
|
74
|
+
const result = positiveIntSchema.safeParse(0);
|
|
75
|
+
expect(result.success).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
it('rejects negative', () => {
|
|
78
|
+
const result = positiveIntSchema.safeParse(-1);
|
|
79
|
+
expect(result.success).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
it('rejects float', () => {
|
|
82
|
+
const result = positiveIntSchema.safeParse(1.5);
|
|
83
|
+
expect(result.success).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe('nonNegativeIntSchema', () => {
|
|
87
|
+
it('accepts zero', () => {
|
|
88
|
+
const result = nonNegativeIntSchema.safeParse(0);
|
|
89
|
+
expect(result.success).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
it('accepts positive integer', () => {
|
|
92
|
+
const result = nonNegativeIntSchema.safeParse(5);
|
|
93
|
+
expect(result.success).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
it('rejects negative', () => {
|
|
96
|
+
const result = nonNegativeIntSchema.safeParse(-1);
|
|
97
|
+
expect(result.success).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe('priceSchema', () => {
|
|
101
|
+
it('accepts valid price', () => {
|
|
102
|
+
const result = priceSchema.safeParse(25.99);
|
|
103
|
+
expect(result.success).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
it('rounds to 2 decimal places', () => {
|
|
106
|
+
const result = priceSchema.safeParse(25.999);
|
|
107
|
+
expect(result.success).toBe(true);
|
|
108
|
+
if (result.success) {
|
|
109
|
+
expect(result.data).toBe(26);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
it('accepts zero', () => {
|
|
113
|
+
const result = priceSchema.safeParse(0);
|
|
114
|
+
expect(result.success).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
it('rejects price over 10000', () => {
|
|
117
|
+
const result = priceSchema.safeParse(10001);
|
|
118
|
+
expect(result.success).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe('percentageSchema', () => {
|
|
122
|
+
it('accepts valid percentage', () => {
|
|
123
|
+
const result = percentageSchema.safeParse(50);
|
|
124
|
+
expect(result.success).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
it('accepts 0', () => {
|
|
127
|
+
const result = percentageSchema.safeParse(0);
|
|
128
|
+
expect(result.success).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
it('accepts 100', () => {
|
|
131
|
+
const result = percentageSchema.safeParse(100);
|
|
132
|
+
expect(result.success).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
it('rejects over 100', () => {
|
|
135
|
+
const result = percentageSchema.safeParse(101);
|
|
136
|
+
expect(result.success).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('dateSchema', () => {
|
|
140
|
+
it('accepts Date object', () => {
|
|
141
|
+
const date = new Date('2025-01-01');
|
|
142
|
+
const result = dateSchema.safeParse(date);
|
|
143
|
+
expect(result.success).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
it('accepts ISO string', () => {
|
|
146
|
+
const result = dateSchema.safeParse('2025-01-01T00:00:00Z');
|
|
147
|
+
expect(result.success).toBe(true);
|
|
148
|
+
if (result.success) {
|
|
149
|
+
expect(result.data).toBeInstanceOf(Date);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
it('rejects invalid date string', () => {
|
|
153
|
+
const result = dateSchema.safeParse('not-a-date');
|
|
154
|
+
expect(result.success).toBe(false);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('futureDateSchema', () => {
|
|
158
|
+
it('accepts future date', () => {
|
|
159
|
+
const futureDate = new Date();
|
|
160
|
+
futureDate.setFullYear(futureDate.getFullYear() + 1);
|
|
161
|
+
const result = futureDateSchema.safeParse(futureDate);
|
|
162
|
+
expect(result.success).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
it('rejects past date', () => {
|
|
165
|
+
const pastDate = new Date('2020-01-01');
|
|
166
|
+
const result = futureDateSchema.safeParse(pastDate);
|
|
167
|
+
expect(result.success).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe('timezoneSchema', () => {
|
|
171
|
+
it('accepts valid timezone', () => {
|
|
172
|
+
const result = timezoneSchema.safeParse('America/New_York');
|
|
173
|
+
expect(result.success).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
it('rejects invalid timezone', () => {
|
|
176
|
+
const result = timezoneSchema.safeParse('Invalid/Timezone');
|
|
177
|
+
expect(result.success).toBe(false);
|
|
178
|
+
});
|
|
179
|
+
it('rejects empty string', () => {
|
|
180
|
+
const result = timezoneSchema.safeParse('');
|
|
181
|
+
expect(result.success).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
describe('usStateSchema', () => {
|
|
185
|
+
it('accepts valid state code', () => {
|
|
186
|
+
const result = usStateSchema.safeParse('CA');
|
|
187
|
+
expect(result.success).toBe(true);
|
|
188
|
+
});
|
|
189
|
+
it('uppercases state code', () => {
|
|
190
|
+
const result = usStateSchema.safeParse('ca');
|
|
191
|
+
expect(result.success).toBe(true);
|
|
192
|
+
if (result.success) {
|
|
193
|
+
expect(result.data).toBe('CA');
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
it('rejects invalid length', () => {
|
|
197
|
+
const result = usStateSchema.safeParse('California');
|
|
198
|
+
expect(result.success).toBe(false);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
describe('zipCodeSchema', () => {
|
|
202
|
+
it('accepts 5-digit zip', () => {
|
|
203
|
+
const result = zipCodeSchema.safeParse('12345');
|
|
204
|
+
expect(result.success).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
it('accepts zip+4', () => {
|
|
207
|
+
const result = zipCodeSchema.safeParse('12345-6789');
|
|
208
|
+
expect(result.success).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
it('rejects invalid zip', () => {
|
|
211
|
+
const result = zipCodeSchema.safeParse('1234');
|
|
212
|
+
expect(result.success).toBe(false);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
describe('addressSchema', () => {
|
|
216
|
+
it('accepts valid address', () => {
|
|
217
|
+
const result = addressSchema.safeParse({
|
|
218
|
+
street: '123 Main St',
|
|
219
|
+
city: 'San Francisco',
|
|
220
|
+
state: 'CA',
|
|
221
|
+
zipCode: '94102',
|
|
222
|
+
});
|
|
223
|
+
expect(result.success).toBe(true);
|
|
224
|
+
});
|
|
225
|
+
it('defaults country to US', () => {
|
|
226
|
+
const result = addressSchema.safeParse({
|
|
227
|
+
street: '123 Main St',
|
|
228
|
+
city: 'San Francisco',
|
|
229
|
+
state: 'CA',
|
|
230
|
+
zipCode: '94102',
|
|
231
|
+
});
|
|
232
|
+
expect(result.success).toBe(true);
|
|
233
|
+
if (result.success) {
|
|
234
|
+
expect(result.data.country).toBe('US');
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
it('rejects missing required fields', () => {
|
|
238
|
+
const result = addressSchema.safeParse({
|
|
239
|
+
street: '123 Main St',
|
|
240
|
+
});
|
|
241
|
+
expect(result.success).toBe(false);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe('requiredString', () => {
|
|
245
|
+
it('creates schema that accepts valid string', () => {
|
|
246
|
+
const schema = requiredString(100, 'Name');
|
|
247
|
+
const result = schema.safeParse('John');
|
|
248
|
+
expect(result.success).toBe(true);
|
|
249
|
+
});
|
|
250
|
+
it('rejects empty string', () => {
|
|
251
|
+
const schema = requiredString(100, 'Name');
|
|
252
|
+
const result = schema.safeParse('');
|
|
253
|
+
expect(result.success).toBe(false);
|
|
254
|
+
});
|
|
255
|
+
it('rejects string over max length', () => {
|
|
256
|
+
const schema = requiredString(5, 'Name');
|
|
257
|
+
const result = schema.safeParse('Too Long');
|
|
258
|
+
expect(result.success).toBe(false);
|
|
259
|
+
});
|
|
260
|
+
it('trims whitespace', () => {
|
|
261
|
+
const schema = requiredString(100, 'Name');
|
|
262
|
+
const result = schema.safeParse(' John ');
|
|
263
|
+
expect(result.success).toBe(true);
|
|
264
|
+
if (result.success) {
|
|
265
|
+
expect(result.data).toBe('John');
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
describe('optionalString', () => {
|
|
270
|
+
it('accepts valid string', () => {
|
|
271
|
+
const schema = optionalString(100, 'Bio');
|
|
272
|
+
const result = schema.safeParse('Hello');
|
|
273
|
+
expect(result.success).toBe(true);
|
|
274
|
+
});
|
|
275
|
+
it('accepts empty string', () => {
|
|
276
|
+
const schema = optionalString(100, 'Bio');
|
|
277
|
+
const result = schema.safeParse('');
|
|
278
|
+
expect(result.success).toBe(true);
|
|
279
|
+
});
|
|
280
|
+
it('accepts undefined', () => {
|
|
281
|
+
const schema = optionalString(100, 'Bio');
|
|
282
|
+
const result = schema.safeParse(undefined);
|
|
283
|
+
expect(result.success).toBe(true);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
describe('numberRange', () => {
|
|
287
|
+
it('accepts number in range', () => {
|
|
288
|
+
const schema = numberRange(1, 10, 'Quantity');
|
|
289
|
+
const result = schema.safeParse(5);
|
|
290
|
+
expect(result.success).toBe(true);
|
|
291
|
+
});
|
|
292
|
+
it('rejects number below min', () => {
|
|
293
|
+
const schema = numberRange(1, 10, 'Quantity');
|
|
294
|
+
const result = schema.safeParse(0);
|
|
295
|
+
expect(result.success).toBe(false);
|
|
296
|
+
});
|
|
297
|
+
it('rejects number above max', () => {
|
|
298
|
+
const schema = numberRange(1, 10, 'Quantity');
|
|
299
|
+
const result = schema.safeParse(11);
|
|
300
|
+
expect(result.success).toBe(false);
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
describe('stringToNumber', () => {
|
|
304
|
+
it('parses string to number', () => {
|
|
305
|
+
const schema = stringToNumber();
|
|
306
|
+
const result = schema.safeParse('123.45');
|
|
307
|
+
expect(result.success).toBe(true);
|
|
308
|
+
if (result.success) {
|
|
309
|
+
expect(result.data).toBe(123.45);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
it('passes through number', () => {
|
|
313
|
+
const schema = stringToNumber();
|
|
314
|
+
const result = schema.safeParse(123.45);
|
|
315
|
+
expect(result.success).toBe(true);
|
|
316
|
+
if (result.success) {
|
|
317
|
+
expect(result.data).toBe(123.45);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
it('rejects invalid string', () => {
|
|
321
|
+
const schema = stringToNumber();
|
|
322
|
+
const result = schema.safeParse('not-a-number');
|
|
323
|
+
expect(result.success).toBe(false);
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
describe('stringToInt', () => {
|
|
327
|
+
it('parses string to integer', () => {
|
|
328
|
+
const schema = stringToInt();
|
|
329
|
+
const result = schema.safeParse('123');
|
|
330
|
+
expect(result.success).toBe(true);
|
|
331
|
+
if (result.success) {
|
|
332
|
+
expect(result.data).toBe(123);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
it('rejects float string', () => {
|
|
336
|
+
const schema = stringToInt();
|
|
337
|
+
const result = schema.safeParse('123.45');
|
|
338
|
+
expect(result.success).toBe(false);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.test.d.ts","sourceRoot":"","sources":["../../../src/lib/schemas/__tests__/domain.test.ts"],"names":[],"mappings":""}
|