boxons/app/store/__tests__/TimerContext.test.tsx

360 lines
9.8 KiB
TypeScript
Raw Normal View History

import { renderHook, act, waitFor } from '@testing-library/react-native';
import { TimerProvider, useTimerContext } from '../TimerContext';
import { timerStore } from '../TimerStore';
import '@testing-library/jest-native/extend-expect';
jest.mock('../TimerStore', () => ({
timerStore: {
getState: jest.fn(),
saveReps: jest.fn(),
saveWorkTime: jest.fn(),
saveRestTime: jest.fn(),
saveState: jest.fn(),
2025-04-08 21:29:14 +00:00
savePreparationTime: jest.fn(),
}
}));
const mockTimerState = {
reps: 5,
workTime: 30,
2025-04-08 21:29:14 +00:00
restTime: 10,
preparationTime: 3
};
describe('TimerContext', () => {
beforeEach(() => {
jest.clearAllMocks();
// Default configuration for getState
(timerStore.getState as jest.Mock<Promise<any>>).mockResolvedValue(mockTimerState);
});
it('should load initial data', async () => {
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Check initial loading state
expect(result.current.isLoading).toBe(true);
// Wait for loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Verify getState was called
expect(timerStore.getState).toHaveBeenCalledTimes(1);
// Verify data is correctly loaded
expect(result.current.timerState).toEqual(mockTimerState);
});
it('should handle errors when loading data', async () => {
// Simulate an error
(timerStore.getState as jest.Mock<Promise<any>>).mockRejectedValueOnce(new Error('Loading error'));
// Spy on console.error
jest.spyOn(console, 'error').mockImplementation(() => {});
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for loading to complete despite error
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Verify error was logged
expect(console.error).toHaveBeenCalledWith(
'Error loading data:',
expect.any(Error)
);
// Restore console.error
(console.error as jest.MockedFunction<typeof console.error>).mockRestore();
});
it('should update repetitions', async () => {
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Update repetitions
await act(async () => {
await result.current.updateReps(10);
});
// Verify saveReps was called with the correct value
expect(timerStore.saveReps).toHaveBeenCalledWith(10);
// Verify state was updated
expect(result.current.timerState.reps).toBe(10);
});
it('should handle errors when updating repetitions', async () => {
// Simulate an error
(timerStore.saveReps as jest.Mock<Promise<void>>).mockRejectedValueOnce(new Error('Saving error'));
// Spy on console.error
jest.spyOn(console, 'error').mockImplementation(() => {});
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Attempt to update repetitions
await act(async () => {
await result.current.updateReps(10);
});
// Verify error was logged
expect(console.error).toHaveBeenCalledWith(
'Error updating repetitions:',
expect.any(Error)
);
// Restore console.error
(console.error as jest.MockedFunction<typeof console.error>).mockRestore();
});
it('should update work time', async () => {
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Update work time
await act(async () => {
await result.current.updateWorkTime(45);
});
// Verify saveWorkTime was called with the correct value
expect(timerStore.saveWorkTime).toHaveBeenCalledWith(45);
// Verify state was updated
expect(result.current.timerState.workTime).toBe(45);
});
it('should update rest time', async () => {
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Update rest time
await act(async () => {
await result.current.updateRestTime(15);
});
// Verify saveRestTime was called with the correct value
expect(timerStore.saveRestTime).toHaveBeenCalledWith(15);
// Verify state was updated
expect(result.current.timerState.restTime).toBe(15);
});
2025-04-08 21:29:14 +00:00
it('should handle errors when updating rest time', async () => {
// Simulate an error
(timerStore.saveRestTime as jest.Mock<Promise<void>>).mockRejectedValueOnce(new Error('Saving error'));
// Spy on console.error
jest.spyOn(console, 'error').mockImplementation(() => {});
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Attempt to update rest time
await act(async () => {
await result.current.updateRestTime(15);
});
// Verify error was logged
expect(console.error).toHaveBeenCalledWith(
'Error updating rest time:',
expect.any(Error)
);
// Restore console.error
(console.error as jest.MockedFunction<typeof console.error>).mockRestore();
});
it('should handle errors when updating work time', async () => {
// Simulate an error
(timerStore.saveWorkTime as jest.Mock<Promise<void>>).mockRejectedValueOnce(new Error('Saving error'));
// Spy on console.error
jest.spyOn(console, 'error').mockImplementation(() => {});
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Attempt to update work time
await act(async () => {
await result.current.updateWorkTime(45);
});
// Verify error was logged
expect(console.error).toHaveBeenCalledWith(
'Error updating work time:',
expect.any(Error)
);
// Restore console.error
(console.error as jest.MockedFunction<typeof console.error>).mockRestore();
});
it('should update preparation time', async () => {
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Update preparation time
await act(async () => {
await result.current.updatePreparationTime(5);
});
// Verify savePreparationTime was called with the correct value
expect(timerStore.savePreparationTime).toHaveBeenCalledWith(5);
// Verify state was updated
expect(result.current.timerState.preparationTime).toBe(5);
});
it('should handle errors when updating preparation time', async () => {
// Simulate an error
(timerStore.savePreparationTime as jest.Mock<Promise<void>>).mockRejectedValueOnce(new Error('Saving error'));
// Spy on console.error
jest.spyOn(console, 'error').mockImplementation(() => {});
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
// Attempt to update preparation time
await act(async () => {
await result.current.updatePreparationTime(5);
});
// Verify error was logged
expect(console.error).toHaveBeenCalledWith(
'Error updating preparation time:',
expect.any(Error)
);
// Restore console.error
(console.error as jest.MockedFunction<typeof console.error>).mockRestore();
});
it('should handle errors when updating multiple values at once', async () => {
// Simulate an error
(timerStore.saveState as jest.Mock<Promise<void>>).mockRejectedValueOnce(new Error('Saving error'));
// Spy on console.error
jest.spyOn(console, 'error').mockImplementation(() => {});
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
const newState = {
reps: 8,
workTime: 60,
restTime: 20
};
// Attempt to update complete state
await act(async () => {
await result.current.updateState(newState);
});
// Verify error was logged
expect(console.error).toHaveBeenCalledWith(
'Error updating state:',
expect.any(Error)
);
// Restore console.error
(console.error as jest.MockedFunction<typeof console.error>).mockRestore();
});
it('should update multiple values at once', async () => {
const { result } = renderHook(() => useTimerContext(), {
wrapper: TimerProvider
});
// Wait for initial loading to complete
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
const newState = {
reps: 8,
workTime: 60,
restTime: 20
};
// Update complete state
await act(async () => {
await result.current.updateState(newState);
});
// Verify saveState was called with the correct state
expect(timerStore.saveState).toHaveBeenCalledWith({
...mockTimerState,
...newState
});
// Verify state was updated
expect(result.current.timerState).toEqual({
...mockTimerState,
...newState
});
});
});