2025-04-08 20:30:14 +00:00
|
|
|
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(),
|
2025-04-08 20:30:14 +00:00
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
const mockTimerState = {
|
|
|
|
|
reps: 5,
|
|
|
|
|
workTime: 30,
|
2025-04-08 21:29:14 +00:00
|
|
|
restTime: 10,
|
|
|
|
|
preparationTime: 3
|
2025-04-08 20:30:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
});
|
|
|
|
|
|
2025-04-08 20:30:14 +00:00
|
|
|
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
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|