@getmicdrop/svelte-components 5.4.2 → 5.5.1
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/AboutShow/AboutShow.svelte +172 -172
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
- package/dist/calendar/FAQs/FAQs.svelte +75 -75
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
- package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
- package/dist/calendar/PublicCard/PublicCard.svelte +134 -134
- package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
- package/dist/components/Layout/Grid.svelte +4 -4
- package/dist/components/Layout/Section.svelte +80 -80
- package/dist/components/Layout/Sidebar.svelte +108 -108
- package/dist/components/Layout/Stack.svelte +6 -6
- package/dist/constants/validation.js +91 -91
- package/dist/constants/validation.spec.js +64 -64
- package/dist/index.d.ts +112 -4
- package/dist/index.js +225 -47
- package/dist/patterns/data/DataGrid.svelte +45 -45
- package/dist/patterns/data/DataList.svelte +24 -24
- package/dist/patterns/data/DataTable.svelte +36 -36
- package/dist/patterns/forms/FormActions.spec.js +88 -88
- package/dist/patterns/forms/FormActions.stories.svelte +97 -97
- package/dist/patterns/forms/FormActions.svelte +46 -46
- package/dist/patterns/forms/FormGrid.svelte +33 -33
- package/dist/patterns/forms/FormSection.svelte +32 -32
- package/dist/patterns/forms/FormValidationSummary.stories.svelte +83 -83
- package/dist/patterns/forms/FormValidationSummary.svelte +32 -32
- package/dist/patterns/layout/Sidebar.svelte +39 -39
- package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
- package/dist/patterns/navigation/BottomNav.svelte +20 -20
- package/dist/patterns/navigation/Header.stories.svelte +77 -77
- package/dist/patterns/navigation/Header.svelte +193 -193
- package/dist/patterns/page/PageHeader.svelte +18 -18
- package/dist/patterns/page/PageLayout.svelte +40 -40
- package/dist/patterns/page/PageLoader.spec.js +54 -54
- package/dist/patterns/page/PageLoader.stories.svelte +137 -137
- package/dist/patterns/page/PageLoader.svelte +24 -24
- package/dist/patterns/page/SectionHeader.svelte +29 -29
- package/dist/presets/badges.js +112 -112
- package/dist/presets/buttons.js +76 -76
- package/dist/presets/index.js +9 -9
- package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
- package/dist/primitives/Accordion/Accordion.svelte +42 -42
- package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
- package/dist/primitives/Alert/Alert.spec.js +170 -170
- package/dist/primitives/Alert/Alert.stories.svelte +88 -88
- package/dist/primitives/Alert/Alert.svelte +27 -27
- package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
- package/dist/primitives/Avatar/Avatar.svelte +66 -66
- package/dist/primitives/Badges/Badge.spec.js +103 -103
- package/dist/primitives/Badges/Badge.stories.svelte +86 -86
- package/dist/primitives/Badges/Badge.svelte +79 -79
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +127 -127
- package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
- package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +120 -120
- package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +89 -89
- package/dist/primitives/Button/Button.spec.js +211 -211
- package/dist/primitives/Button/Button.stories.svelte +76 -76
- package/dist/primitives/Button/Button.svelte +270 -269
- package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
- package/dist/primitives/Button/ButtonSaveDemo.spec.js +48 -48
- package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
- package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
- package/dist/primitives/Card.spec.js +49 -49
- package/dist/primitives/Card.stories.svelte +22 -22
- package/dist/primitives/Card.svelte +28 -28
- package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
- package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
- package/dist/primitives/DarkModeToggle.spec.js +357 -357
- package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
- package/dist/primitives/DarkModeToggle.svelte +136 -136
- package/dist/primitives/Drawer/Drawer.stories.svelte +80 -80
- package/dist/primitives/Drawer/Drawer.svelte +120 -120
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
- package/dist/primitives/Dropdown/Dropdown.svelte +14 -14
- package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
- package/dist/primitives/Icons/ArrowLeft.svelte +8 -8
- package/dist/primitives/Icons/ArrowRight.svelte +8 -8
- package/dist/primitives/Icons/Availability.svelte +14 -14
- package/dist/primitives/Icons/Back.svelte +14 -14
- package/dist/primitives/Icons/CheckCircle.svelte +6 -6
- package/dist/primitives/Icons/CheckCircleOutline.svelte +15 -15
- package/dist/primitives/Icons/ChevronLeft.svelte +4 -4
- package/dist/primitives/Icons/ChevronRight.svelte +4 -4
- package/dist/primitives/Icons/Copy.svelte +15 -15
- package/dist/primitives/Icons/Cross.svelte +5 -5
- package/dist/primitives/Icons/DownArrow.svelte +8 -8
- package/dist/primitives/Icons/ErrorCircle.svelte +6 -6
- package/dist/primitives/Icons/FacebookIcon.svelte +2 -2
- package/dist/primitives/Icons/Home.svelte +15 -15
- package/dist/primitives/Icons/Icon.spec.js +169 -169
- package/dist/primitives/Icons/Icon.stories.svelte +100 -100
- package/dist/primitives/Icons/Icon.svelte +52 -52
- package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
- package/dist/primitives/Icons/Info.svelte +7 -7
- package/dist/primitives/Icons/InstagramIcon.svelte +4 -4
- package/dist/primitives/Icons/LogoInstagram.svelte +2 -2
- package/dist/primitives/Icons/Message.svelte +15 -15
- package/dist/primitives/Icons/MoonIcon.svelte +5 -5
- package/dist/primitives/Icons/More.svelte +21 -21
- package/dist/primitives/Icons/MoreHori.spec.js +61 -61
- package/dist/primitives/Icons/MoreHori.svelte +22 -22
- package/dist/primitives/Icons/Notification.svelte +14 -14
- package/dist/primitives/Icons/Payment.svelte +14 -14
- package/dist/primitives/Icons/Profile.svelte +21 -21
- package/dist/primitives/Icons/Reload.svelte +29 -29
- package/dist/primitives/Icons/Shows.svelte +21 -21
- package/dist/primitives/Icons/Signout.svelte +21 -21
- package/dist/primitives/Icons/SunIcon.svelte +8 -8
- package/dist/primitives/Icons/TiktokIcon.svelte +2 -2
- package/dist/primitives/Icons/TwitterIcon.svelte +2 -2
- package/dist/primitives/Icons/WarningIcon.spec.js +18 -18
- package/dist/primitives/Icons/WarningIcon.svelte +5 -5
- package/dist/primitives/Input/Input.spec.js +573 -573
- package/dist/primitives/Input/Input.stories.svelte +139 -139
- package/dist/primitives/Input/Input.svelte +391 -391
- package/dist/primitives/Input/Select.spec.js +218 -218
- package/dist/primitives/Input/Select.stories.svelte +112 -112
- package/dist/primitives/Input/Select.svelte +128 -128
- package/dist/primitives/Input/Textarea.stories.svelte +137 -137
- package/dist/primitives/Input/Textarea.svelte +35 -35
- package/dist/primitives/Label/Label.svelte +37 -37
- package/dist/primitives/Modal/Modal.spec.js +95 -95
- package/dist/primitives/Modal/Modal.stories.svelte +86 -86
- package/dist/primitives/Modal/Modal.svelte +158 -158
- package/dist/primitives/NumberInput/NumberInput.svelte +106 -0
- package/dist/primitives/NumberInput/NumberInput.svelte.d.ts +23 -0
- package/dist/primitives/NumberInput/NumberInput.svelte.d.ts.map +1 -0
- package/dist/primitives/NumberInput/index.d.ts +2 -0
- package/dist/primitives/NumberInput/index.d.ts.map +1 -0
- package/dist/primitives/NumberInput/index.js +1 -0
- package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
- package/dist/primitives/Pagination/Pagination.svelte +261 -261
- package/dist/primitives/Radio/Radio.stories.svelte +80 -80
- package/dist/primitives/Radio/Radio.svelte +67 -67
- package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
- package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
- package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
- package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
- package/dist/primitives/Skeleton/Skeleton.svelte +26 -26
- package/dist/primitives/Spinner/Spinner.spec.js +75 -75
- package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
- package/dist/primitives/Spinner/Spinner.svelte +20 -20
- package/dist/primitives/Tabs/TabItem.svelte +49 -49
- package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
- package/dist/primitives/Tabs/Tabs.svelte +123 -123
- package/dist/primitives/Toggle.spec.js +127 -127
- package/dist/primitives/Toggle.stories.svelte +92 -92
- package/dist/primitives/Toggle.svelte +71 -71
- package/dist/primitives/Typography/Typography.svelte +53 -53
- package/dist/primitives/ValidationError.spec.js +103 -103
- package/dist/primitives/ValidationError.stories.svelte +69 -69
- package/dist/primitives/ValidationError.svelte +29 -29
- package/dist/recipes/CropImage/CropImage.spec.js +216 -216
- package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
- package/dist/recipes/CropImage/CropImage.svelte +238 -238
- package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
- package/dist/recipes/ImageUploader/ImageUploader.svelte +804 -804
- package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
- package/dist/recipes/feedback/EmptyState/EmptyState.svelte +1 -1
- package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
- package/dist/recipes/feedback/ErrorDisplay.stories.svelte +101 -101
- package/dist/recipes/feedback/ErrorDisplay.svelte +1 -1
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +129 -129
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +157 -157
- package/dist/recipes/fields/CheckboxField.svelte +85 -85
- package/dist/recipes/fields/FormField.svelte +58 -58
- package/dist/recipes/fields/RadioGroup.svelte +95 -95
- package/dist/recipes/fields/SelectField.svelte +80 -80
- package/dist/recipes/fields/TextareaField.svelte +97 -97
- package/dist/recipes/fields/ToggleField.svelte +60 -60
- package/dist/recipes/fields/index.js +7 -7
- package/dist/recipes/inputs/MultiSelect.spec.js +257 -257
- package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
- package/dist/recipes/inputs/MultiSelect.svelte +249 -276
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts +28 -17
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/OTPInput.spec.js +238 -238
- package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
- package/dist/recipes/inputs/OTPInput.svelte +29 -29
- package/dist/recipes/inputs/PasswordInput.svelte +22 -22
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +173 -173
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +42 -42
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +300 -300
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +326 -326
- package/dist/recipes/inputs/Search.svelte +37 -37
- package/dist/recipes/inputs/SelectDropdown.svelte +57 -57
- package/dist/recipes/modals/AlertModal.svelte +130 -130
- package/dist/recipes/modals/ConfirmationModal.spec.js +191 -191
- package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
- package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
- package/dist/recipes/modals/InputModal.svelte +182 -182
- package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
- package/dist/recipes/modals/ModalStateManager.svelte +77 -77
- package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
- package/dist/recipes/modals/StatusModal.svelte +206 -206
- package/dist/services/EventService.js +75 -75
- package/dist/services/EventService.spec.js +217 -217
- package/dist/services/ShowService.spec.js +342 -342
- package/dist/stores/auth.js +36 -36
- package/dist/stores/auth.spec.js +139 -139
- package/dist/stores/toaster.js +13 -13
- package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
- package/dist/stories/ButtonAuditReview.svelte +427 -427
- package/dist/stories/PatternsGallery.stories.svelte +19 -19
- package/dist/stories/PatternsGallery.svelte +206 -206
- package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
- package/dist/stories/PrimitivesGallery.svelte +725 -725
- package/dist/stories/RecipesGallery.stories.svelte +19 -19
- package/dist/stories/RecipesGallery.svelte +271 -271
- package/dist/stories/button-audit-manifest.json +11186 -11186
- package/dist/tailwind/preset.cjs +82 -82
- package/dist/tokens/tokens.css +87 -87
- package/dist/utils/utils.js +354 -354
- package/package.json +283 -283
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
|
|
3
|
-
// Create mock functions we'll spy on
|
|
4
|
-
const mockEvents = [
|
|
5
|
-
{ ID: 1, startDateTime: '2025-01-15T20:00:00', title: 'Comedy Night' },
|
|
6
|
-
{ ID: 2, startDateTime: '2025-01-15T21:00:00', title: 'Open Mic' },
|
|
7
|
-
{ ID: 3, startDateTime: '2025-02-10T19:00:00', title: 'Improv Show' },
|
|
8
|
-
];
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
fetchEventsFromAPI,
|
|
12
|
-
fetchEventsForMonth,
|
|
13
|
-
fetchEventsForWeek,
|
|
14
|
-
fetchEventsForDay,
|
|
15
|
-
} from './EventService';
|
|
16
|
-
|
|
17
|
-
describe('EventService', () => {
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
vi.clearAllMocks();
|
|
20
|
-
global.fetch = vi.fn();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
describe('fetchEventsFromAPI', () => {
|
|
24
|
-
it('fetches events from the API', async () => {
|
|
25
|
-
global.fetch.mockResolvedValue({
|
|
26
|
-
ok: true,
|
|
27
|
-
json: () => Promise.resolve(mockEvents),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const events = await fetchEventsFromAPI();
|
|
31
|
-
|
|
32
|
-
expect(global.fetch).toHaveBeenCalledWith(
|
|
33
|
-
'https://get-micdrop.com/api/public/getEventsForVenue'
|
|
34
|
-
);
|
|
35
|
-
expect(events).toHaveLength(3);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('transforms event data correctly', async () => {
|
|
39
|
-
global.fetch.mockResolvedValue({
|
|
40
|
-
ok: true,
|
|
41
|
-
json: () => Promise.resolve([mockEvents[0]]),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const events = await fetchEventsFromAPI();
|
|
45
|
-
|
|
46
|
-
expect(events[0]).toEqual({
|
|
47
|
-
id: 1,
|
|
48
|
-
date: '2025-01-15T20:00:00',
|
|
49
|
-
title: 'Comedy Night',
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('returns empty array on failed response', async () => {
|
|
54
|
-
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
55
|
-
global.fetch.mockResolvedValue({
|
|
56
|
-
ok: false,
|
|
57
|
-
status: 500,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const events = await fetchEventsFromAPI();
|
|
61
|
-
|
|
62
|
-
expect(events).toEqual([]);
|
|
63
|
-
consoleSpy.mockRestore();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('returns empty array on network error', async () => {
|
|
67
|
-
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
68
|
-
global.fetch.mockRejectedValue(new Error('Network error'));
|
|
69
|
-
|
|
70
|
-
const events = await fetchEventsFromAPI();
|
|
71
|
-
|
|
72
|
-
expect(events).toEqual([]);
|
|
73
|
-
consoleSpy.mockRestore();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe('fetchEventsForMonth', () => {
|
|
78
|
-
it('filters events by year and month', async () => {
|
|
79
|
-
global.fetch.mockResolvedValue({
|
|
80
|
-
ok: true,
|
|
81
|
-
json: () => Promise.resolve(mockEvents),
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const events = await fetchEventsForMonth(2025, 1);
|
|
85
|
-
|
|
86
|
-
expect(events.length).toBe(2);
|
|
87
|
-
expect(events[0].title).toBe('Comedy Night');
|
|
88
|
-
expect(events[1].title).toBe('Open Mic');
|
|
89
|
-
}, 10000);
|
|
90
|
-
|
|
91
|
-
it('returns empty for month with no events', async () => {
|
|
92
|
-
global.fetch.mockResolvedValue({
|
|
93
|
-
ok: true,
|
|
94
|
-
json: () => Promise.resolve(mockEvents),
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const events = await fetchEventsForMonth(2025, 3);
|
|
98
|
-
|
|
99
|
-
expect(events).toEqual([]);
|
|
100
|
-
}, 10000);
|
|
101
|
-
|
|
102
|
-
it('pads single digit months correctly', async () => {
|
|
103
|
-
global.fetch.mockResolvedValue({
|
|
104
|
-
ok: true,
|
|
105
|
-
json: () => Promise.resolve(mockEvents),
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
const events = await fetchEventsForMonth(2025, 2);
|
|
109
|
-
|
|
110
|
-
expect(events.length).toBe(1);
|
|
111
|
-
expect(events[0].title).toBe('Improv Show');
|
|
112
|
-
}, 10000);
|
|
113
|
-
|
|
114
|
-
it('handles double digit months', async () => {
|
|
115
|
-
const decemberEvents = [
|
|
116
|
-
{ ID: 4, startDateTime: '2025-12-25T20:00:00', title: 'Holiday Show' },
|
|
117
|
-
];
|
|
118
|
-
global.fetch.mockResolvedValue({
|
|
119
|
-
ok: true,
|
|
120
|
-
json: () => Promise.resolve(decemberEvents),
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const events = await fetchEventsForMonth(2025, 12);
|
|
124
|
-
|
|
125
|
-
expect(events.length).toBe(1);
|
|
126
|
-
}, 10000);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
describe('fetchEventsForWeek', () => {
|
|
130
|
-
it('filters events within the week', async () => {
|
|
131
|
-
// Events on Jan 13-14, 2025 (Monday-Tuesday of that week)
|
|
132
|
-
const weekEvents = [
|
|
133
|
-
{ ID: 1, startDateTime: '2025-01-13T20:00:00', title: 'Monday Show' },
|
|
134
|
-
{ ID: 2, startDateTime: '2025-01-14T19:00:00', title: 'Tuesday Show' },
|
|
135
|
-
{ ID: 3, startDateTime: '2025-01-20T20:00:00', title: 'Next Week Show' },
|
|
136
|
-
];
|
|
137
|
-
global.fetch.mockResolvedValue({
|
|
138
|
-
ok: true,
|
|
139
|
-
json: () => Promise.resolve(weekEvents),
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Jan 15, 2025 is a Wednesday
|
|
143
|
-
const date = new Date('2025-01-15');
|
|
144
|
-
const events = await fetchEventsForWeek(date);
|
|
145
|
-
|
|
146
|
-
// Should include Monday and Tuesday shows (same week)
|
|
147
|
-
expect(events.length).toBe(2);
|
|
148
|
-
}, 10000);
|
|
149
|
-
|
|
150
|
-
it('uses Monday as week start', async () => {
|
|
151
|
-
const events = [
|
|
152
|
-
{ ID: 1, startDateTime: '2025-01-12T20:00:00', title: 'Sunday Show' },
|
|
153
|
-
{ ID: 2, startDateTime: '2025-01-13T20:00:00', title: 'Monday Show' },
|
|
154
|
-
];
|
|
155
|
-
global.fetch.mockResolvedValue({
|
|
156
|
-
ok: true,
|
|
157
|
-
json: () => Promise.resolve(events),
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// Pass a date in the week starting Jan 13
|
|
161
|
-
const date = new Date('2025-01-15');
|
|
162
|
-
const result = await fetchEventsForWeek(date);
|
|
163
|
-
|
|
164
|
-
// Sunday should be excluded, Monday included
|
|
165
|
-
expect(result.some((e) => e.title === 'Monday Show')).toBe(true);
|
|
166
|
-
}, 10000);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
describe('fetchEventsForDay', () => {
|
|
170
|
-
it('filters events for specific day', async () => {
|
|
171
|
-
// Use Z suffix for UTC dates to avoid timezone issues
|
|
172
|
-
const dayEvents = [
|
|
173
|
-
{ ID: 1, startDateTime: '2025-01-15T14:00:00Z', title: 'Afternoon Show' },
|
|
174
|
-
{ ID: 2, startDateTime: '2025-01-15T20:00:00Z', title: 'Evening Show' },
|
|
175
|
-
{ ID: 3, startDateTime: '2025-01-16T20:00:00Z', title: 'Next Day Show' },
|
|
176
|
-
];
|
|
177
|
-
global.fetch.mockResolvedValue({
|
|
178
|
-
ok: true,
|
|
179
|
-
json: () => Promise.resolve(dayEvents),
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
const date = new Date(Date.UTC(2025, 0, 15)); // Jan 15, 2025 UTC
|
|
183
|
-
const events = await fetchEventsForDay(date);
|
|
184
|
-
|
|
185
|
-
expect(events.length).toBe(2);
|
|
186
|
-
expect(events[0].title).toBe('Afternoon Show');
|
|
187
|
-
expect(events[1].title).toBe('Evening Show');
|
|
188
|
-
}, 10000);
|
|
189
|
-
|
|
190
|
-
it('returns empty array for day with no events', async () => {
|
|
191
|
-
global.fetch.mockResolvedValue({
|
|
192
|
-
ok: true,
|
|
193
|
-
json: () => Promise.resolve(mockEvents),
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const date = new Date(Date.UTC(2025, 0, 20)); // Jan 20, 2025
|
|
197
|
-
const events = await fetchEventsForDay(date);
|
|
198
|
-
|
|
199
|
-
expect(events).toEqual([]);
|
|
200
|
-
}, 10000);
|
|
201
|
-
|
|
202
|
-
it('matches dates using UTC methods', async () => {
|
|
203
|
-
const dayEvents = [
|
|
204
|
-
{ ID: 1, startDateTime: '2025-06-15T23:00:00Z', title: 'Late Show' },
|
|
205
|
-
];
|
|
206
|
-
global.fetch.mockResolvedValue({
|
|
207
|
-
ok: true,
|
|
208
|
-
json: () => Promise.resolve(dayEvents),
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
const date = new Date(Date.UTC(2025, 5, 15)); // June 15, 2025 UTC
|
|
212
|
-
const events = await fetchEventsForDay(date);
|
|
213
|
-
|
|
214
|
-
expect(events.length).toBe(1);
|
|
215
|
-
}, 10000);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Create mock functions we'll spy on
|
|
4
|
+
const mockEvents = [
|
|
5
|
+
{ ID: 1, startDateTime: '2025-01-15T20:00:00', title: 'Comedy Night' },
|
|
6
|
+
{ ID: 2, startDateTime: '2025-01-15T21:00:00', title: 'Open Mic' },
|
|
7
|
+
{ ID: 3, startDateTime: '2025-02-10T19:00:00', title: 'Improv Show' },
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
fetchEventsFromAPI,
|
|
12
|
+
fetchEventsForMonth,
|
|
13
|
+
fetchEventsForWeek,
|
|
14
|
+
fetchEventsForDay,
|
|
15
|
+
} from './EventService';
|
|
16
|
+
|
|
17
|
+
describe('EventService', () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
vi.clearAllMocks();
|
|
20
|
+
global.fetch = vi.fn();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('fetchEventsFromAPI', () => {
|
|
24
|
+
it('fetches events from the API', async () => {
|
|
25
|
+
global.fetch.mockResolvedValue({
|
|
26
|
+
ok: true,
|
|
27
|
+
json: () => Promise.resolve(mockEvents),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const events = await fetchEventsFromAPI();
|
|
31
|
+
|
|
32
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
33
|
+
'https://get-micdrop.com/api/public/getEventsForVenue'
|
|
34
|
+
);
|
|
35
|
+
expect(events).toHaveLength(3);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('transforms event data correctly', async () => {
|
|
39
|
+
global.fetch.mockResolvedValue({
|
|
40
|
+
ok: true,
|
|
41
|
+
json: () => Promise.resolve([mockEvents[0]]),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const events = await fetchEventsFromAPI();
|
|
45
|
+
|
|
46
|
+
expect(events[0]).toEqual({
|
|
47
|
+
id: 1,
|
|
48
|
+
date: '2025-01-15T20:00:00',
|
|
49
|
+
title: 'Comedy Night',
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('returns empty array on failed response', async () => {
|
|
54
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
55
|
+
global.fetch.mockResolvedValue({
|
|
56
|
+
ok: false,
|
|
57
|
+
status: 500,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const events = await fetchEventsFromAPI();
|
|
61
|
+
|
|
62
|
+
expect(events).toEqual([]);
|
|
63
|
+
consoleSpy.mockRestore();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('returns empty array on network error', async () => {
|
|
67
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
68
|
+
global.fetch.mockRejectedValue(new Error('Network error'));
|
|
69
|
+
|
|
70
|
+
const events = await fetchEventsFromAPI();
|
|
71
|
+
|
|
72
|
+
expect(events).toEqual([]);
|
|
73
|
+
consoleSpy.mockRestore();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('fetchEventsForMonth', () => {
|
|
78
|
+
it('filters events by year and month', async () => {
|
|
79
|
+
global.fetch.mockResolvedValue({
|
|
80
|
+
ok: true,
|
|
81
|
+
json: () => Promise.resolve(mockEvents),
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const events = await fetchEventsForMonth(2025, 1);
|
|
85
|
+
|
|
86
|
+
expect(events.length).toBe(2);
|
|
87
|
+
expect(events[0].title).toBe('Comedy Night');
|
|
88
|
+
expect(events[1].title).toBe('Open Mic');
|
|
89
|
+
}, 10000);
|
|
90
|
+
|
|
91
|
+
it('returns empty for month with no events', async () => {
|
|
92
|
+
global.fetch.mockResolvedValue({
|
|
93
|
+
ok: true,
|
|
94
|
+
json: () => Promise.resolve(mockEvents),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const events = await fetchEventsForMonth(2025, 3);
|
|
98
|
+
|
|
99
|
+
expect(events).toEqual([]);
|
|
100
|
+
}, 10000);
|
|
101
|
+
|
|
102
|
+
it('pads single digit months correctly', async () => {
|
|
103
|
+
global.fetch.mockResolvedValue({
|
|
104
|
+
ok: true,
|
|
105
|
+
json: () => Promise.resolve(mockEvents),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const events = await fetchEventsForMonth(2025, 2);
|
|
109
|
+
|
|
110
|
+
expect(events.length).toBe(1);
|
|
111
|
+
expect(events[0].title).toBe('Improv Show');
|
|
112
|
+
}, 10000);
|
|
113
|
+
|
|
114
|
+
it('handles double digit months', async () => {
|
|
115
|
+
const decemberEvents = [
|
|
116
|
+
{ ID: 4, startDateTime: '2025-12-25T20:00:00', title: 'Holiday Show' },
|
|
117
|
+
];
|
|
118
|
+
global.fetch.mockResolvedValue({
|
|
119
|
+
ok: true,
|
|
120
|
+
json: () => Promise.resolve(decemberEvents),
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const events = await fetchEventsForMonth(2025, 12);
|
|
124
|
+
|
|
125
|
+
expect(events.length).toBe(1);
|
|
126
|
+
}, 10000);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('fetchEventsForWeek', () => {
|
|
130
|
+
it('filters events within the week', async () => {
|
|
131
|
+
// Events on Jan 13-14, 2025 (Monday-Tuesday of that week)
|
|
132
|
+
const weekEvents = [
|
|
133
|
+
{ ID: 1, startDateTime: '2025-01-13T20:00:00', title: 'Monday Show' },
|
|
134
|
+
{ ID: 2, startDateTime: '2025-01-14T19:00:00', title: 'Tuesday Show' },
|
|
135
|
+
{ ID: 3, startDateTime: '2025-01-20T20:00:00', title: 'Next Week Show' },
|
|
136
|
+
];
|
|
137
|
+
global.fetch.mockResolvedValue({
|
|
138
|
+
ok: true,
|
|
139
|
+
json: () => Promise.resolve(weekEvents),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Jan 15, 2025 is a Wednesday
|
|
143
|
+
const date = new Date('2025-01-15');
|
|
144
|
+
const events = await fetchEventsForWeek(date);
|
|
145
|
+
|
|
146
|
+
// Should include Monday and Tuesday shows (same week)
|
|
147
|
+
expect(events.length).toBe(2);
|
|
148
|
+
}, 10000);
|
|
149
|
+
|
|
150
|
+
it('uses Monday as week start', async () => {
|
|
151
|
+
const events = [
|
|
152
|
+
{ ID: 1, startDateTime: '2025-01-12T20:00:00', title: 'Sunday Show' },
|
|
153
|
+
{ ID: 2, startDateTime: '2025-01-13T20:00:00', title: 'Monday Show' },
|
|
154
|
+
];
|
|
155
|
+
global.fetch.mockResolvedValue({
|
|
156
|
+
ok: true,
|
|
157
|
+
json: () => Promise.resolve(events),
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Pass a date in the week starting Jan 13
|
|
161
|
+
const date = new Date('2025-01-15');
|
|
162
|
+
const result = await fetchEventsForWeek(date);
|
|
163
|
+
|
|
164
|
+
// Sunday should be excluded, Monday included
|
|
165
|
+
expect(result.some((e) => e.title === 'Monday Show')).toBe(true);
|
|
166
|
+
}, 10000);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('fetchEventsForDay', () => {
|
|
170
|
+
it('filters events for specific day', async () => {
|
|
171
|
+
// Use Z suffix for UTC dates to avoid timezone issues
|
|
172
|
+
const dayEvents = [
|
|
173
|
+
{ ID: 1, startDateTime: '2025-01-15T14:00:00Z', title: 'Afternoon Show' },
|
|
174
|
+
{ ID: 2, startDateTime: '2025-01-15T20:00:00Z', title: 'Evening Show' },
|
|
175
|
+
{ ID: 3, startDateTime: '2025-01-16T20:00:00Z', title: 'Next Day Show' },
|
|
176
|
+
];
|
|
177
|
+
global.fetch.mockResolvedValue({
|
|
178
|
+
ok: true,
|
|
179
|
+
json: () => Promise.resolve(dayEvents),
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const date = new Date(Date.UTC(2025, 0, 15)); // Jan 15, 2025 UTC
|
|
183
|
+
const events = await fetchEventsForDay(date);
|
|
184
|
+
|
|
185
|
+
expect(events.length).toBe(2);
|
|
186
|
+
expect(events[0].title).toBe('Afternoon Show');
|
|
187
|
+
expect(events[1].title).toBe('Evening Show');
|
|
188
|
+
}, 10000);
|
|
189
|
+
|
|
190
|
+
it('returns empty array for day with no events', async () => {
|
|
191
|
+
global.fetch.mockResolvedValue({
|
|
192
|
+
ok: true,
|
|
193
|
+
json: () => Promise.resolve(mockEvents),
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const date = new Date(Date.UTC(2025, 0, 20)); // Jan 20, 2025
|
|
197
|
+
const events = await fetchEventsForDay(date);
|
|
198
|
+
|
|
199
|
+
expect(events).toEqual([]);
|
|
200
|
+
}, 10000);
|
|
201
|
+
|
|
202
|
+
it('matches dates using UTC methods', async () => {
|
|
203
|
+
const dayEvents = [
|
|
204
|
+
{ ID: 1, startDateTime: '2025-06-15T23:00:00Z', title: 'Late Show' },
|
|
205
|
+
];
|
|
206
|
+
global.fetch.mockResolvedValue({
|
|
207
|
+
ok: true,
|
|
208
|
+
json: () => Promise.resolve(dayEvents),
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const date = new Date(Date.UTC(2025, 5, 15)); // June 15, 2025 UTC
|
|
212
|
+
const events = await fetchEventsForDay(date);
|
|
213
|
+
|
|
214
|
+
expect(events.length).toBe(1);
|
|
215
|
+
}, 10000);
|
|
216
|
+
});
|
|
217
|
+
});
|