Move from Create React to Vite
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { vi, type Mock } from 'vitest';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import Activate from './Activate';
|
||||
import { api } from '../api';
|
||||
import { AuthProvider } from '../auth';
|
||||
|
||||
jest.mock('../api', () => ({
|
||||
vi.mock('../api', () => ({
|
||||
api: {
|
||||
activate: jest.fn(),
|
||||
activate: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
const mockActivate = api.activate as jest.Mock;
|
||||
const mockActivate = api.activate as Mock;
|
||||
|
||||
function renderActivate(token = 'valid-token') {
|
||||
return render(
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { vi, type Mock } from 'vitest';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import Profile from './Profile';
|
||||
import { api, Volunteer } from '../api';
|
||||
import { AuthProvider } from '../auth';
|
||||
|
||||
jest.mock('../api', () => ({
|
||||
vi.mock('../api', () => ({
|
||||
api: {
|
||||
getVolunteer: jest.fn(),
|
||||
updateVolunteer: jest.fn(),
|
||||
getVolunteer: vi.fn(),
|
||||
updateVolunteer: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -21,8 +22,8 @@ function buildFakeJWT(payload: object): string {
|
||||
return `${header}.${body}.fakesig`;
|
||||
}
|
||||
|
||||
const mockGetVolunteer = api.getVolunteer as jest.Mock;
|
||||
const mockUpdateVolunteer = api.updateVolunteer as jest.Mock;
|
||||
const mockGetVolunteer = api.getVolunteer as Mock;
|
||||
const mockUpdateVolunteer = api.updateVolunteer as Mock;
|
||||
|
||||
const baseVolunteer: Volunteer = {
|
||||
id: 5,
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { vi, type Mock } from 'vitest';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import Schedules from './Schedules';
|
||||
import { api, ShiftInstance, ShiftTemplate } from '../api';
|
||||
|
||||
jest.mock('../api', () => ({
|
||||
...jest.requireActual('../api'),
|
||||
api: {
|
||||
listShifts: jest.fn(),
|
||||
listShiftTemplates: jest.fn(),
|
||||
listVolunteers: jest.fn(),
|
||||
listTimeOff: jest.fn(),
|
||||
generateShifts: jest.fn(),
|
||||
publishShifts: jest.fn(),
|
||||
unpublishShifts: jest.fn(),
|
||||
updateShift: jest.fn(),
|
||||
confirmShift: jest.fn(),
|
||||
createShiftTemplate: jest.fn(),
|
||||
updateShiftTemplate: jest.fn(),
|
||||
deleteShiftTemplate: jest.fn(),
|
||||
},
|
||||
vi.mock('../api', async () => {
|
||||
const actual = await vi.importActual<typeof import('../api')>('../api');
|
||||
return {
|
||||
...actual,
|
||||
api: {
|
||||
listShifts: vi.fn(),
|
||||
listShiftTemplates: vi.fn(),
|
||||
listVolunteers: vi.fn(),
|
||||
listTimeOff: vi.fn(),
|
||||
generateShifts: vi.fn(),
|
||||
publishShifts: vi.fn(),
|
||||
unpublishShifts: vi.fn(),
|
||||
updateShift: vi.fn(),
|
||||
confirmShift: vi.fn(),
|
||||
createShiftTemplate: vi.fn(),
|
||||
updateShiftTemplate: vi.fn(),
|
||||
deleteShiftTemplate: vi.fn(),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../auth', () => ({
|
||||
useAuth: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../auth', () => ({
|
||||
useAuth: jest.fn(),
|
||||
}));
|
||||
|
||||
const { useAuth } = require('../auth');
|
||||
const { useAuth } = await import('../auth');
|
||||
|
||||
const mockDraftInstance: ShiftInstance = {
|
||||
id: 1,
|
||||
@@ -75,8 +79,8 @@ function renderAt(path: string) {
|
||||
|
||||
describe('Schedules (volunteer view)', () => {
|
||||
beforeEach(() => {
|
||||
useAuth.mockReturnValue({ role: 'volunteer', volunteerID: 10 });
|
||||
(api.listShifts as jest.Mock).mockResolvedValue([mockPublishedInstance]);
|
||||
(useAuth as Mock).mockReturnValue({ role: 'volunteer', volunteerID: 10 });
|
||||
(api.listShifts as Mock).mockResolvedValue([mockPublishedInstance]);
|
||||
});
|
||||
|
||||
it('renders published shifts for a volunteer', async () => {
|
||||
@@ -98,9 +102,9 @@ describe('Schedules (volunteer view)', () => {
|
||||
|
||||
describe('Schedules (admin shifts view)', () => {
|
||||
beforeEach(() => {
|
||||
useAuth.mockReturnValue({ role: 'admin', volunteerID: 1 });
|
||||
(api.listShifts as jest.Mock).mockResolvedValue([mockDraftInstance]);
|
||||
(api.listShiftTemplates as jest.Mock).mockResolvedValue([mockTemplate]);
|
||||
(useAuth as Mock).mockReturnValue({ role: 'admin', volunteerID: 1 });
|
||||
(api.listShifts as Mock).mockResolvedValue([mockDraftInstance]);
|
||||
(api.listShiftTemplates as Mock).mockResolvedValue([mockTemplate]);
|
||||
});
|
||||
|
||||
it('shows Generate and Publish buttons when drafts exist', async () => {
|
||||
@@ -111,7 +115,7 @@ describe('Schedules (admin shifts view)', () => {
|
||||
});
|
||||
|
||||
it('calls generateShifts on Generate click', async () => {
|
||||
(api.generateShifts as jest.Mock).mockResolvedValue([mockDraftInstance]);
|
||||
(api.generateShifts as Mock).mockResolvedValue([mockDraftInstance]);
|
||||
renderAt('/schedules');
|
||||
await waitFor(() => expect(screen.getByText('Generate')).toBeInTheDocument());
|
||||
fireEvent.click(screen.getByText('Generate'));
|
||||
@@ -119,8 +123,8 @@ describe('Schedules (admin shifts view)', () => {
|
||||
});
|
||||
|
||||
it('calls publishShifts on Publish click', async () => {
|
||||
(api.publishShifts as jest.Mock).mockResolvedValue({ year: 2026, month: 4 });
|
||||
(api.listShifts as jest.Mock)
|
||||
(api.publishShifts as Mock).mockResolvedValue({ year: 2026, month: 4 });
|
||||
(api.listShifts as Mock)
|
||||
.mockResolvedValueOnce([mockDraftInstance])
|
||||
.mockResolvedValue([{ ...mockDraftInstance, status: 'published' }]);
|
||||
|
||||
@@ -131,7 +135,7 @@ describe('Schedules (admin shifts view)', () => {
|
||||
});
|
||||
|
||||
it('shows Unpublish button when all shifts are published', async () => {
|
||||
(api.listShifts as jest.Mock).mockResolvedValue([mockPublishedInstance]);
|
||||
(api.listShifts as Mock).mockResolvedValue([mockPublishedInstance]);
|
||||
renderAt('/schedules');
|
||||
await waitFor(() => expect(screen.getByText('Unpublish')).toBeInTheDocument());
|
||||
});
|
||||
@@ -143,11 +147,11 @@ describe('Schedules (admin shifts view)', () => {
|
||||
});
|
||||
|
||||
it('opens edit form with volunteer checkboxes when Edit is clicked', async () => {
|
||||
(api.listVolunteers as jest.Mock).mockResolvedValue([
|
||||
(api.listVolunteers as Mock).mockResolvedValue([
|
||||
{ id: 5, name: 'Alice', active: true, operational_roles: 'Dog Shelter Volunteer', is_trainee: false },
|
||||
{ id: 6, name: 'Bob', active: true, operational_roles: 'Behaviour Team', is_trainee: false },
|
||||
]);
|
||||
(api.listTimeOff as jest.Mock).mockResolvedValue([]);
|
||||
(api.listTimeOff as Mock).mockResolvedValue([]);
|
||||
renderAt('/schedules');
|
||||
await waitFor(() => expect(screen.getByText('Edit')).toBeInTheDocument());
|
||||
fireEvent.click(screen.getByText('Edit'));
|
||||
@@ -157,11 +161,11 @@ describe('Schedules (admin shifts view)', () => {
|
||||
});
|
||||
|
||||
it('hides volunteers with approved time off on the shift date', async () => {
|
||||
(api.listVolunteers as jest.Mock).mockResolvedValue([
|
||||
(api.listVolunteers as Mock).mockResolvedValue([
|
||||
{ id: 5, name: 'Alice', active: true, operational_roles: 'Dog Shelter Volunteer', is_trainee: false },
|
||||
{ id: 6, name: 'Bob', active: true, operational_roles: 'Behaviour Team', is_trainee: false },
|
||||
]);
|
||||
(api.listTimeOff as jest.Mock).mockResolvedValue([
|
||||
(api.listTimeOff as Mock).mockResolvedValue([
|
||||
{ id: 1, volunteer_id: 6, starts_at: '2026-04-06T00:00:00Z', ends_at: '2026-04-07T00:00:00Z', status: 'approved' },
|
||||
]);
|
||||
renderAt('/schedules');
|
||||
@@ -183,8 +187,8 @@ describe('Schedules (admin shifts view)', () => {
|
||||
|
||||
describe('Schedules (admin templates view)', () => {
|
||||
beforeEach(() => {
|
||||
useAuth.mockReturnValue({ role: 'admin', volunteerID: 1 });
|
||||
(api.listShiftTemplates as jest.Mock).mockResolvedValue([mockTemplate]);
|
||||
(useAuth as Mock).mockReturnValue({ role: 'admin', volunteerID: 1 });
|
||||
(api.listShiftTemplates as Mock).mockResolvedValue([mockTemplate]);
|
||||
});
|
||||
|
||||
it('renders templates at /schedules/templates', async () => {
|
||||
@@ -201,8 +205,8 @@ describe('Schedules (admin templates view)', () => {
|
||||
});
|
||||
|
||||
it('deletes a template', async () => {
|
||||
(api.deleteShiftTemplate as jest.Mock).mockResolvedValue(undefined);
|
||||
window.confirm = jest.fn().mockReturnValue(true);
|
||||
(api.deleteShiftTemplate as Mock).mockResolvedValue(undefined);
|
||||
window.confirm = vi.fn().mockReturnValue(true);
|
||||
renderAt('/schedules/templates');
|
||||
await waitFor(() => expect(screen.getAllByText('Delete')[0]).toBeInTheDocument());
|
||||
fireEvent.click(screen.getAllByText('Delete')[0]);
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { vi, type Mock } from 'vitest';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import Setup from './Setup';
|
||||
import { api } from '../api';
|
||||
import { AuthProvider } from '../auth';
|
||||
|
||||
jest.mock('../api', () => ({
|
||||
vi.mock('../api', () => ({
|
||||
api: {
|
||||
getSetupStatus: jest.fn(),
|
||||
createSetupAdmin: jest.fn(),
|
||||
getSetupStatus: vi.fn(),
|
||||
createSetupAdmin: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock useSetup from App to provide setNeedsSetup
|
||||
const mockSetNeedsSetup = jest.fn();
|
||||
jest.mock('../App', () => ({
|
||||
const mockSetNeedsSetup = vi.fn();
|
||||
vi.mock('../App', () => ({
|
||||
useSetup: () => ({ setNeedsSetup: mockSetNeedsSetup }),
|
||||
}));
|
||||
|
||||
const mockCreateSetupAdmin = api.createSetupAdmin as jest.Mock;
|
||||
const mockCreateSetupAdmin = api.createSetupAdmin as Mock;
|
||||
|
||||
function renderSetup() {
|
||||
return render(
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { vi, type Mock } from 'vitest';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import Volunteers from './Volunteers';
|
||||
import { api, AdminVolunteer } from '../api';
|
||||
import { AuthProvider } from '../auth';
|
||||
|
||||
jest.mock('../api', () => ({
|
||||
vi.mock('../api', () => ({
|
||||
api: {
|
||||
listVolunteers: jest.fn(),
|
||||
createVolunteer: jest.fn(),
|
||||
updateVolunteer: jest.fn(),
|
||||
resendInvite: jest.fn(),
|
||||
listVolunteers: vi.fn(),
|
||||
createVolunteer: vi.fn(),
|
||||
updateVolunteer: vi.fn(),
|
||||
resendInvite: vi.fn(),
|
||||
},
|
||||
OPERATIONAL_ROLES: ['Behaviour Team', 'Dog Log Monitor', 'Dog Shelter Volunteer', 'Trainee', 'Floater'],
|
||||
}));
|
||||
|
||||
const mockListVolunteers = api.listVolunteers as jest.Mock;
|
||||
const mockCreateVolunteer = api.createVolunteer as jest.Mock;
|
||||
const mockUpdateVolunteer = api.updateVolunteer as jest.Mock;
|
||||
const mockResendInvite = api.resendInvite as jest.Mock;
|
||||
const mockListVolunteers = api.listVolunteers as Mock;
|
||||
const mockCreateVolunteer = api.createVolunteer as Mock;
|
||||
const mockUpdateVolunteer = api.updateVolunteer as Mock;
|
||||
const mockResendInvite = api.resendInvite as Mock;
|
||||
|
||||
function buildFakeJWT(payload: object): string {
|
||||
const header = btoa(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
|
||||
|
||||
Reference in New Issue
Block a user