@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,293 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { eventFilterSchema, eventSchema } from '../event';
|
|
3
|
+
import { performerBasicInfoSchema, performerSchema } from '../performer';
|
|
4
|
+
import { promoCodeSchema } from '../promo';
|
|
5
|
+
import { cartItemSchema, ticketSectionSchema, ticketTypeSchema, } from '../ticket';
|
|
6
|
+
import { stageSchema, venueSchema } from '../venue';
|
|
7
|
+
describe('eventSchema', () => {
|
|
8
|
+
const validEvent = {
|
|
9
|
+
title: 'Comedy Night',
|
|
10
|
+
startDateTime: new Date('2025-06-01T20:00:00'),
|
|
11
|
+
endDateTime: new Date('2025-06-01T22:00:00'),
|
|
12
|
+
timezone: 'America/Los_Angeles',
|
|
13
|
+
venueId: '550e8400-e29b-41d4-a716-446655440000',
|
|
14
|
+
};
|
|
15
|
+
it('accepts valid event', () => {
|
|
16
|
+
const result = eventSchema.safeParse(validEvent);
|
|
17
|
+
expect(result.success).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('rejects end date before start date', () => {
|
|
20
|
+
const result = eventSchema.safeParse({
|
|
21
|
+
...validEvent,
|
|
22
|
+
startDateTime: new Date('2025-06-01T22:00:00'),
|
|
23
|
+
endDateTime: new Date('2025-06-01T20:00:00'),
|
|
24
|
+
});
|
|
25
|
+
expect(result.success).toBe(false);
|
|
26
|
+
if (!result.success) {
|
|
27
|
+
const error = result.error.issues.find(e => e.path.includes('endDateTime'));
|
|
28
|
+
expect(error).toBeDefined();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
it('defaults status to draft', () => {
|
|
32
|
+
const result = eventSchema.safeParse(validEvent);
|
|
33
|
+
expect(result.success).toBe(true);
|
|
34
|
+
if (result.success) {
|
|
35
|
+
expect(result.data.status).toBe('draft');
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
it('rejects invalid timezone', () => {
|
|
39
|
+
const result = eventSchema.safeParse({
|
|
40
|
+
...validEvent,
|
|
41
|
+
timezone: 'Invalid/Timezone',
|
|
42
|
+
});
|
|
43
|
+
expect(result.success).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe('eventFilterSchema', () => {
|
|
47
|
+
it('accepts empty filter', () => {
|
|
48
|
+
const result = eventFilterSchema.safeParse({});
|
|
49
|
+
expect(result.success).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
it('accepts filter with search', () => {
|
|
52
|
+
const result = eventFilterSchema.safeParse({
|
|
53
|
+
search: 'comedy',
|
|
54
|
+
status: 'published',
|
|
55
|
+
});
|
|
56
|
+
expect(result.success).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('ticketTypeSchema', () => {
|
|
60
|
+
const validTicket = {
|
|
61
|
+
name: 'General Admission',
|
|
62
|
+
ticketType: 'paid',
|
|
63
|
+
price: 25,
|
|
64
|
+
quantity: 100,
|
|
65
|
+
minimumTickets: 1,
|
|
66
|
+
maximumTickets: 10,
|
|
67
|
+
};
|
|
68
|
+
it('accepts valid ticket', () => {
|
|
69
|
+
const result = ticketTypeSchema.safeParse(validTicket);
|
|
70
|
+
expect(result.success).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
it('rejects min exceeding max', () => {
|
|
73
|
+
const result = ticketTypeSchema.safeParse({
|
|
74
|
+
...validTicket,
|
|
75
|
+
minimumTickets: 10,
|
|
76
|
+
maximumTickets: 5,
|
|
77
|
+
});
|
|
78
|
+
expect(result.success).toBe(false);
|
|
79
|
+
if (!result.success) {
|
|
80
|
+
const error = result.error.issues.find(e => e.path.includes('minimumTickets'));
|
|
81
|
+
expect(error?.message).toBe('Minimum cannot exceed maximum');
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
it('rejects sales end before start', () => {
|
|
85
|
+
const result = ticketTypeSchema.safeParse({
|
|
86
|
+
...validTicket,
|
|
87
|
+
salesStartDateTime: new Date('2025-06-01'),
|
|
88
|
+
salesEndDateTime: new Date('2025-05-01'),
|
|
89
|
+
});
|
|
90
|
+
expect(result.success).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
it('defaults visibility to visible', () => {
|
|
93
|
+
const result = ticketTypeSchema.safeParse(validTicket);
|
|
94
|
+
expect(result.success).toBe(true);
|
|
95
|
+
if (result.success) {
|
|
96
|
+
expect(result.data.visibility).toBe('visible');
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe('ticketSectionSchema', () => {
|
|
101
|
+
it('accepts valid section', () => {
|
|
102
|
+
const result = ticketSectionSchema.safeParse({
|
|
103
|
+
name: 'VIP Section',
|
|
104
|
+
capacity: 50,
|
|
105
|
+
});
|
|
106
|
+
expect(result.success).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
it('rejects zero capacity', () => {
|
|
109
|
+
const result = ticketSectionSchema.safeParse({
|
|
110
|
+
name: 'VIP Section',
|
|
111
|
+
capacity: 0,
|
|
112
|
+
});
|
|
113
|
+
expect(result.success).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('cartItemSchema', () => {
|
|
117
|
+
it('accepts valid cart item with UUID', () => {
|
|
118
|
+
const result = cartItemSchema.safeParse({
|
|
119
|
+
ticketTypeId: '550e8400-e29b-41d4-a716-446655440000',
|
|
120
|
+
quantity: 2,
|
|
121
|
+
});
|
|
122
|
+
expect(result.success).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
it('accepts valid cart item with number ID', () => {
|
|
125
|
+
const result = cartItemSchema.safeParse({
|
|
126
|
+
ticketTypeId: 123,
|
|
127
|
+
quantity: 2,
|
|
128
|
+
});
|
|
129
|
+
expect(result.success).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
it('rejects quantity over max', () => {
|
|
132
|
+
const result = cartItemSchema.safeParse({
|
|
133
|
+
ticketTypeId: 123,
|
|
134
|
+
quantity: 100,
|
|
135
|
+
});
|
|
136
|
+
expect(result.success).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('venueSchema', () => {
|
|
140
|
+
const validVenue = {
|
|
141
|
+
name: 'The Comedy Club',
|
|
142
|
+
address: {
|
|
143
|
+
street: '123 Main St',
|
|
144
|
+
city: 'San Francisco',
|
|
145
|
+
state: 'CA',
|
|
146
|
+
zipCode: '94102',
|
|
147
|
+
},
|
|
148
|
+
timezone: 'America/Los_Angeles',
|
|
149
|
+
};
|
|
150
|
+
it('accepts valid venue', () => {
|
|
151
|
+
const result = venueSchema.safeParse(validVenue);
|
|
152
|
+
expect(result.success).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
it('rejects missing name', () => {
|
|
155
|
+
const { name, ...venueWithoutName } = validVenue;
|
|
156
|
+
const result = venueSchema.safeParse(venueWithoutName);
|
|
157
|
+
expect(result.success).toBe(false);
|
|
158
|
+
});
|
|
159
|
+
it('defaults isActive to true', () => {
|
|
160
|
+
const result = venueSchema.safeParse(validVenue);
|
|
161
|
+
expect(result.success).toBe(true);
|
|
162
|
+
if (result.success) {
|
|
163
|
+
expect(result.data.isActive).toBe(true);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe('stageSchema', () => {
|
|
168
|
+
it('accepts valid stage', () => {
|
|
169
|
+
const result = stageSchema.safeParse({
|
|
170
|
+
name: 'Main Stage',
|
|
171
|
+
capacity: 200,
|
|
172
|
+
});
|
|
173
|
+
expect(result.success).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
it('accepts stage without capacity', () => {
|
|
176
|
+
const result = stageSchema.safeParse({
|
|
177
|
+
name: 'Main Stage',
|
|
178
|
+
});
|
|
179
|
+
expect(result.success).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('performerBasicInfoSchema', () => {
|
|
183
|
+
it('accepts valid performer info', () => {
|
|
184
|
+
const result = performerBasicInfoSchema.safeParse({
|
|
185
|
+
firstName: 'John',
|
|
186
|
+
lastName: 'Comedian',
|
|
187
|
+
email: 'john@example.com',
|
|
188
|
+
});
|
|
189
|
+
expect(result.success).toBe(true);
|
|
190
|
+
});
|
|
191
|
+
it('rejects invalid email', () => {
|
|
192
|
+
const result = performerBasicInfoSchema.safeParse({
|
|
193
|
+
firstName: 'John',
|
|
194
|
+
lastName: 'Comedian',
|
|
195
|
+
email: 'invalid-email',
|
|
196
|
+
});
|
|
197
|
+
expect(result.success).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
describe('performerSchema', () => {
|
|
201
|
+
it('accepts full performer data', () => {
|
|
202
|
+
const result = performerSchema.safeParse({
|
|
203
|
+
firstName: 'John',
|
|
204
|
+
lastName: 'Comedian',
|
|
205
|
+
email: 'john@example.com',
|
|
206
|
+
bio: 'A funny person',
|
|
207
|
+
tier: 3,
|
|
208
|
+
});
|
|
209
|
+
expect(result.success).toBe(true);
|
|
210
|
+
});
|
|
211
|
+
it('rejects tier over max', () => {
|
|
212
|
+
const result = performerSchema.safeParse({
|
|
213
|
+
firstName: 'John',
|
|
214
|
+
lastName: 'Comedian',
|
|
215
|
+
email: 'john@example.com',
|
|
216
|
+
tier: 10,
|
|
217
|
+
});
|
|
218
|
+
expect(result.success).toBe(false);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe('promoCodeSchema', () => {
|
|
222
|
+
it('accepts valid percent discount promo', () => {
|
|
223
|
+
const result = promoCodeSchema.safeParse({
|
|
224
|
+
code: 'SUMMER20',
|
|
225
|
+
discountType: 'percent',
|
|
226
|
+
percentAmount: 20,
|
|
227
|
+
});
|
|
228
|
+
expect(result.success).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
it('accepts valid dollar discount promo', () => {
|
|
231
|
+
const result = promoCodeSchema.safeParse({
|
|
232
|
+
code: 'SAVE10',
|
|
233
|
+
discountType: 'dollar',
|
|
234
|
+
dollarAmount: 10,
|
|
235
|
+
});
|
|
236
|
+
expect(result.success).toBe(true);
|
|
237
|
+
});
|
|
238
|
+
it('rejects both discount types', () => {
|
|
239
|
+
const result = promoCodeSchema.safeParse({
|
|
240
|
+
code: 'INVALID',
|
|
241
|
+
discountType: 'percent',
|
|
242
|
+
percentAmount: 20,
|
|
243
|
+
dollarAmount: 10,
|
|
244
|
+
});
|
|
245
|
+
expect(result.success).toBe(false);
|
|
246
|
+
});
|
|
247
|
+
it('allows promo without discount if reveals hidden tickets', () => {
|
|
248
|
+
const result = promoCodeSchema.safeParse({
|
|
249
|
+
code: 'REVEAL',
|
|
250
|
+
discountType: 'percent',
|
|
251
|
+
revealHiddenTickets: true,
|
|
252
|
+
});
|
|
253
|
+
expect(result.success).toBe(true);
|
|
254
|
+
});
|
|
255
|
+
it('requires usage limit when limited', () => {
|
|
256
|
+
const result = promoCodeSchema.safeParse({
|
|
257
|
+
code: 'LIMITED',
|
|
258
|
+
discountType: 'percent',
|
|
259
|
+
percentAmount: 20,
|
|
260
|
+
limitType: 'limited',
|
|
261
|
+
});
|
|
262
|
+
expect(result.success).toBe(false);
|
|
263
|
+
});
|
|
264
|
+
it('accepts limited promo with usage limit', () => {
|
|
265
|
+
const result = promoCodeSchema.safeParse({
|
|
266
|
+
code: 'LIMITED100',
|
|
267
|
+
discountType: 'percent',
|
|
268
|
+
percentAmount: 20,
|
|
269
|
+
limitType: 'limited',
|
|
270
|
+
usageLimit: 100,
|
|
271
|
+
});
|
|
272
|
+
expect(result.success).toBe(true);
|
|
273
|
+
});
|
|
274
|
+
it('uppercases promo code', () => {
|
|
275
|
+
const result = promoCodeSchema.safeParse({
|
|
276
|
+
code: 'summer20',
|
|
277
|
+
discountType: 'percent',
|
|
278
|
+
percentAmount: 20,
|
|
279
|
+
});
|
|
280
|
+
expect(result.success).toBe(true);
|
|
281
|
+
if (result.success) {
|
|
282
|
+
expect(result.data.code).toBe('SUMMER20');
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
it('rejects invalid promo code format', () => {
|
|
286
|
+
const result = promoCodeSchema.safeParse({
|
|
287
|
+
code: 'invalid code!',
|
|
288
|
+
discountType: 'percent',
|
|
289
|
+
percentAmount: 20,
|
|
290
|
+
});
|
|
291
|
+
expect(result.success).toBe(false);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.test.d.ts","sourceRoot":"","sources":["../../../src/lib/schemas/__tests__/order.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { boxOfficeCheckoutSchema, checkoutSchema, customerInfoSchema, orderFilterSchema, orderNoteSchema, orderResendSchema, orderStatusSchema, paymentMethodSchema, refundRequestSchema, } from '../order';
|
|
3
|
+
describe('orderStatusSchema', () => {
|
|
4
|
+
it('accepts valid statuses', () => {
|
|
5
|
+
const statuses = [
|
|
6
|
+
'pending',
|
|
7
|
+
'processing',
|
|
8
|
+
'completed',
|
|
9
|
+
'cancelled',
|
|
10
|
+
'refunded',
|
|
11
|
+
'partially_refunded',
|
|
12
|
+
];
|
|
13
|
+
statuses.forEach(status => {
|
|
14
|
+
const result = orderStatusSchema.safeParse(status);
|
|
15
|
+
expect(result.success).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
it('rejects invalid status', () => {
|
|
19
|
+
const result = orderStatusSchema.safeParse('invalid');
|
|
20
|
+
expect(result.success).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('paymentMethodSchema', () => {
|
|
24
|
+
it('accepts valid payment methods', () => {
|
|
25
|
+
const methods = ['credit_card', 'apple_pay', 'google_pay', 'cash'];
|
|
26
|
+
methods.forEach(method => {
|
|
27
|
+
const result = paymentMethodSchema.safeParse(method);
|
|
28
|
+
expect(result.success).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it('rejects invalid payment method', () => {
|
|
32
|
+
const result = paymentMethodSchema.safeParse('bitcoin');
|
|
33
|
+
expect(result.success).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('customerInfoSchema', () => {
|
|
37
|
+
it('accepts valid customer info', () => {
|
|
38
|
+
const result = customerInfoSchema.safeParse({
|
|
39
|
+
firstName: 'John',
|
|
40
|
+
lastName: 'Doe',
|
|
41
|
+
email: 'john@example.com',
|
|
42
|
+
});
|
|
43
|
+
expect(result.success).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
it('accepts customer with phone', () => {
|
|
46
|
+
const result = customerInfoSchema.safeParse({
|
|
47
|
+
firstName: 'John',
|
|
48
|
+
lastName: 'Doe',
|
|
49
|
+
email: 'john@example.com',
|
|
50
|
+
phone: '555-123-4567',
|
|
51
|
+
});
|
|
52
|
+
expect(result.success).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('rejects missing first name', () => {
|
|
55
|
+
const result = customerInfoSchema.safeParse({
|
|
56
|
+
lastName: 'Doe',
|
|
57
|
+
email: 'john@example.com',
|
|
58
|
+
});
|
|
59
|
+
expect(result.success).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
it('rejects invalid email', () => {
|
|
62
|
+
const result = customerInfoSchema.safeParse({
|
|
63
|
+
firstName: 'John',
|
|
64
|
+
lastName: 'Doe',
|
|
65
|
+
email: 'invalid',
|
|
66
|
+
});
|
|
67
|
+
expect(result.success).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('checkoutSchema', () => {
|
|
71
|
+
const validCheckout = {
|
|
72
|
+
eventId: 1,
|
|
73
|
+
items: [{ ticketTypeId: 1, quantity: 2 }],
|
|
74
|
+
customer: {
|
|
75
|
+
firstName: 'John',
|
|
76
|
+
lastName: 'Doe',
|
|
77
|
+
email: 'john@example.com',
|
|
78
|
+
},
|
|
79
|
+
acceptTerms: true,
|
|
80
|
+
};
|
|
81
|
+
it('accepts valid checkout data', () => {
|
|
82
|
+
const result = checkoutSchema.safeParse(validCheckout);
|
|
83
|
+
expect(result.success).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
it('accepts checkout with promo code', () => {
|
|
86
|
+
const result = checkoutSchema.safeParse({
|
|
87
|
+
...validCheckout,
|
|
88
|
+
promoCode: 'SAVE10',
|
|
89
|
+
});
|
|
90
|
+
expect(result.success).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
it('accepts checkout with billing address', () => {
|
|
93
|
+
const result = checkoutSchema.safeParse({
|
|
94
|
+
...validCheckout,
|
|
95
|
+
billingAddress: {
|
|
96
|
+
street: '123 Main St',
|
|
97
|
+
city: 'San Francisco',
|
|
98
|
+
state: 'CA',
|
|
99
|
+
zipCode: '94102',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
expect(result.success).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
it('rejects empty cart', () => {
|
|
105
|
+
const result = checkoutSchema.safeParse({
|
|
106
|
+
...validCheckout,
|
|
107
|
+
items: [],
|
|
108
|
+
});
|
|
109
|
+
expect(result.success).toBe(false);
|
|
110
|
+
if (!result.success) {
|
|
111
|
+
const error = result.error.issues.find(e => e.path.includes('items'));
|
|
112
|
+
expect(error?.message).toBe('Cart must have at least one item');
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
it('rejects if terms not accepted', () => {
|
|
116
|
+
const result = checkoutSchema.safeParse({
|
|
117
|
+
...validCheckout,
|
|
118
|
+
acceptTerms: false,
|
|
119
|
+
});
|
|
120
|
+
expect(result.success).toBe(false);
|
|
121
|
+
if (!result.success) {
|
|
122
|
+
const error = result.error.issues.find(e => e.path.includes('acceptTerms'));
|
|
123
|
+
expect(error?.message).toBe('You must accept the terms and conditions');
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
it('rejects invalid event ID', () => {
|
|
127
|
+
const result = checkoutSchema.safeParse({
|
|
128
|
+
...validCheckout,
|
|
129
|
+
eventId: -1,
|
|
130
|
+
});
|
|
131
|
+
expect(result.success).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('boxOfficeCheckoutSchema', () => {
|
|
135
|
+
const validBoxOffice = {
|
|
136
|
+
eventId: 1,
|
|
137
|
+
items: [{ ticketTypeId: 1, quantity: 2 }],
|
|
138
|
+
customer: {},
|
|
139
|
+
paymentMethod: 'cash',
|
|
140
|
+
};
|
|
141
|
+
it('accepts valid box office checkout', () => {
|
|
142
|
+
const result = boxOfficeCheckoutSchema.safeParse(validBoxOffice);
|
|
143
|
+
expect(result.success).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
it('accepts box office with partial customer', () => {
|
|
146
|
+
const result = boxOfficeCheckoutSchema.safeParse({
|
|
147
|
+
...validBoxOffice,
|
|
148
|
+
customer: {
|
|
149
|
+
firstName: 'John',
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
expect(result.success).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
it('accepts box office with full customer and notes', () => {
|
|
155
|
+
const result = boxOfficeCheckoutSchema.safeParse({
|
|
156
|
+
...validBoxOffice,
|
|
157
|
+
customer: {
|
|
158
|
+
firstName: 'John',
|
|
159
|
+
lastName: 'Doe',
|
|
160
|
+
email: 'john@example.com',
|
|
161
|
+
},
|
|
162
|
+
notes: 'VIP customer',
|
|
163
|
+
});
|
|
164
|
+
expect(result.success).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
it('accepts credit card payment', () => {
|
|
167
|
+
const result = boxOfficeCheckoutSchema.safeParse({
|
|
168
|
+
...validBoxOffice,
|
|
169
|
+
paymentMethod: 'credit_card',
|
|
170
|
+
});
|
|
171
|
+
expect(result.success).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
it('rejects invalid payment method', () => {
|
|
174
|
+
const result = boxOfficeCheckoutSchema.safeParse({
|
|
175
|
+
...validBoxOffice,
|
|
176
|
+
paymentMethod: 'invalid',
|
|
177
|
+
});
|
|
178
|
+
expect(result.success).toBe(false);
|
|
179
|
+
});
|
|
180
|
+
it('rejects empty cart', () => {
|
|
181
|
+
const result = boxOfficeCheckoutSchema.safeParse({
|
|
182
|
+
...validBoxOffice,
|
|
183
|
+
items: [],
|
|
184
|
+
});
|
|
185
|
+
expect(result.success).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe('refundRequestSchema', () => {
|
|
189
|
+
const validRefund = {
|
|
190
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
191
|
+
ticketIds: ['550e8400-e29b-41d4-a716-446655440001'],
|
|
192
|
+
reason: 'Customer requested refund',
|
|
193
|
+
};
|
|
194
|
+
it('accepts valid refund request', () => {
|
|
195
|
+
const result = refundRequestSchema.safeParse(validRefund);
|
|
196
|
+
expect(result.success).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
it('accepts partial refund with amount', () => {
|
|
199
|
+
const result = refundRequestSchema.safeParse({
|
|
200
|
+
...validRefund,
|
|
201
|
+
refundAmount: 25.5,
|
|
202
|
+
isPartial: true,
|
|
203
|
+
});
|
|
204
|
+
expect(result.success).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
it('defaults isPartial to false', () => {
|
|
207
|
+
const result = refundRequestSchema.safeParse(validRefund);
|
|
208
|
+
expect(result.success).toBe(true);
|
|
209
|
+
if (result.success) {
|
|
210
|
+
expect(result.data.isPartial).toBe(false);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
it('rejects empty ticketIds', () => {
|
|
214
|
+
const result = refundRequestSchema.safeParse({
|
|
215
|
+
...validRefund,
|
|
216
|
+
ticketIds: [],
|
|
217
|
+
});
|
|
218
|
+
expect(result.success).toBe(false);
|
|
219
|
+
if (!result.success) {
|
|
220
|
+
const error = result.error.issues.find(e => e.path.includes('ticketIds'));
|
|
221
|
+
expect(error?.message).toBe('At least one ticket must be selected');
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
it('rejects empty reason', () => {
|
|
225
|
+
const result = refundRequestSchema.safeParse({
|
|
226
|
+
...validRefund,
|
|
227
|
+
reason: '',
|
|
228
|
+
});
|
|
229
|
+
expect(result.success).toBe(false);
|
|
230
|
+
});
|
|
231
|
+
it('rejects invalid order UUID', () => {
|
|
232
|
+
const result = refundRequestSchema.safeParse({
|
|
233
|
+
...validRefund,
|
|
234
|
+
orderId: 'not-a-uuid',
|
|
235
|
+
});
|
|
236
|
+
expect(result.success).toBe(false);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
describe('orderNoteSchema', () => {
|
|
240
|
+
it('accepts valid order note', () => {
|
|
241
|
+
const result = orderNoteSchema.safeParse({
|
|
242
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
243
|
+
content: 'Customer called about their order',
|
|
244
|
+
});
|
|
245
|
+
expect(result.success).toBe(true);
|
|
246
|
+
});
|
|
247
|
+
it('defaults isInternal to true', () => {
|
|
248
|
+
const result = orderNoteSchema.safeParse({
|
|
249
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
250
|
+
content: 'Internal note',
|
|
251
|
+
});
|
|
252
|
+
expect(result.success).toBe(true);
|
|
253
|
+
if (result.success) {
|
|
254
|
+
expect(result.data.isInternal).toBe(true);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
it('accepts external note', () => {
|
|
258
|
+
const result = orderNoteSchema.safeParse({
|
|
259
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
260
|
+
content: 'Thank you for your order!',
|
|
261
|
+
isInternal: false,
|
|
262
|
+
});
|
|
263
|
+
expect(result.success).toBe(true);
|
|
264
|
+
if (result.success) {
|
|
265
|
+
expect(result.data.isInternal).toBe(false);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
it('rejects empty content', () => {
|
|
269
|
+
const result = orderNoteSchema.safeParse({
|
|
270
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
271
|
+
content: '',
|
|
272
|
+
});
|
|
273
|
+
expect(result.success).toBe(false);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
describe('orderFilterSchema', () => {
|
|
277
|
+
it('accepts empty filter', () => {
|
|
278
|
+
const result = orderFilterSchema.safeParse({});
|
|
279
|
+
expect(result.success).toBe(true);
|
|
280
|
+
});
|
|
281
|
+
it('accepts filter with status', () => {
|
|
282
|
+
const result = orderFilterSchema.safeParse({
|
|
283
|
+
status: 'completed',
|
|
284
|
+
});
|
|
285
|
+
expect(result.success).toBe(true);
|
|
286
|
+
});
|
|
287
|
+
it('accepts filter with date range', () => {
|
|
288
|
+
const result = orderFilterSchema.safeParse({
|
|
289
|
+
startDate: new Date('2025-01-01'),
|
|
290
|
+
endDate: new Date('2025-12-31'),
|
|
291
|
+
});
|
|
292
|
+
expect(result.success).toBe(true);
|
|
293
|
+
});
|
|
294
|
+
it('accepts filter with pagination', () => {
|
|
295
|
+
const result = orderFilterSchema.safeParse({
|
|
296
|
+
limit: 10,
|
|
297
|
+
offset: 20,
|
|
298
|
+
});
|
|
299
|
+
expect(result.success).toBe(true);
|
|
300
|
+
});
|
|
301
|
+
it('accepts filter with search', () => {
|
|
302
|
+
const result = orderFilterSchema.safeParse({
|
|
303
|
+
search: 'john@example.com',
|
|
304
|
+
eventId: 123,
|
|
305
|
+
venueId: 456,
|
|
306
|
+
});
|
|
307
|
+
expect(result.success).toBe(true);
|
|
308
|
+
});
|
|
309
|
+
it('rejects invalid status', () => {
|
|
310
|
+
const result = orderFilterSchema.safeParse({
|
|
311
|
+
status: 'invalid',
|
|
312
|
+
});
|
|
313
|
+
expect(result.success).toBe(false);
|
|
314
|
+
});
|
|
315
|
+
it('rejects negative offset', () => {
|
|
316
|
+
const result = orderFilterSchema.safeParse({
|
|
317
|
+
offset: -1,
|
|
318
|
+
});
|
|
319
|
+
expect(result.success).toBe(false);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
describe('orderResendSchema', () => {
|
|
323
|
+
it('accepts valid resend request', () => {
|
|
324
|
+
const result = orderResendSchema.safeParse({
|
|
325
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
326
|
+
});
|
|
327
|
+
expect(result.success).toBe(true);
|
|
328
|
+
});
|
|
329
|
+
it('accepts resend with custom email', () => {
|
|
330
|
+
const result = orderResendSchema.safeParse({
|
|
331
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
332
|
+
email: 'different@example.com',
|
|
333
|
+
});
|
|
334
|
+
expect(result.success).toBe(true);
|
|
335
|
+
});
|
|
336
|
+
it('rejects invalid order UUID', () => {
|
|
337
|
+
const result = orderResendSchema.safeParse({
|
|
338
|
+
orderId: 'not-a-uuid',
|
|
339
|
+
});
|
|
340
|
+
expect(result.success).toBe(false);
|
|
341
|
+
});
|
|
342
|
+
it('rejects invalid email', () => {
|
|
343
|
+
const result = orderResendSchema.safeParse({
|
|
344
|
+
orderId: '550e8400-e29b-41d4-a716-446655440000',
|
|
345
|
+
email: 'invalid-email',
|
|
346
|
+
});
|
|
347
|
+
expect(result.success).toBe(false);
|
|
348
|
+
});
|
|
349
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.test.d.ts","sourceRoot":"","sources":["../../../src/lib/schemas/__tests__/user.test.ts"],"names":[],"mappings":""}
|