Skip to content

Commit 268032d

Browse files
committed
added more actions buttons tests working on theme toggle tests
1 parent 5e3e6b2 commit 268032d

File tree

4 files changed

+452
-175
lines changed

4 files changed

+452
-175
lines changed

src/app/FrontendTypes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ export interface BarGraphComparisonAction {
104104
}
105105

106106
export interface ActionContainerProps {
107-
snapshots: any;
108-
currLocation: any;
107+
snapshots?: any;
108+
currLocation?: any;
109109
}
110110

111111
export interface ProvConContainerProps {
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
import React from 'react';
2+
import { render as rtlRender, screen, fireEvent } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
4+
import { Provider } from 'react-redux';
5+
import { store } from '../store';
6+
import { useDispatch } from 'react-redux';
7+
import { mainSlice, changeSlider, emptySnapshots } from '../slices/mainSlice';
8+
9+
import { useTheme } from '../ThemeProvider';
10+
import { configureStore } from '@reduxjs/toolkit';
11+
12+
import DropDown from '../components/Actions/DropDown';
13+
import RecordButton from '../components/Actions/RecordButton';
14+
import ThemeToggle from '../components/Actions/ThemeToggle';
15+
import ProvConContainer from '../containers/ProvConContainer';
16+
import ActionContainer from '../containers/ActionContainer';
17+
18+
// @ts-ignore
19+
const useDispatchMock = useDispatch as jest.Mock;
20+
const dummyDispatch = jest.fn();
21+
22+
// Mock ThemeToggle for RecordButton tests
23+
jest.mock('../components/Actions/ThemeToggle', () => {
24+
return function MockThemeToggle() {
25+
return <div data-testid='mock-theme-toggle'>Theme Toggle</div>;
26+
};
27+
});
28+
29+
// Mock useTheme hook
30+
jest.mock('../ThemeProvider', () => ({
31+
useTheme: jest.fn(),
32+
}));
33+
34+
// Mock react-redux
35+
jest.mock('react-redux', () => ({
36+
...jest.requireActual('react-redux'),
37+
useDispatch: jest.fn(),
38+
}));
39+
40+
window.HTMLElement.prototype.scrollIntoView = jest.fn();
41+
42+
// Setup mock before tests
43+
beforeAll(() => {
44+
useDispatchMock.mockReturnValue(dummyDispatch);
45+
});
46+
47+
// Clear mocks after each test
48+
afterEach(() => {
49+
dummyDispatch.mockClear();
50+
});
51+
52+
// Helper function for redux wrapped renders
53+
const render = (component) => rtlRender(<Provider store={store}>{component}</Provider>);
54+
55+
// DropDown Component Tests
56+
describe('DropDown Component', () => {
57+
const mockSetDropdownSelection = jest.fn();
58+
59+
beforeEach(() => {
60+
mockSetDropdownSelection.mockClear();
61+
});
62+
63+
test('renders with placeholder text', () => {
64+
render(<DropDown dropdownSelection='' setDropdownSelection={mockSetDropdownSelection} />);
65+
expect(screen.getByText('Select Hook')).toBeInTheDocument();
66+
});
67+
68+
test('shows correct options when clicked', () => {
69+
render(<DropDown dropdownSelection='' setDropdownSelection={mockSetDropdownSelection} />);
70+
const dropdown = screen.getByText('Select Hook');
71+
fireEvent.mouseDown(dropdown);
72+
expect(screen.getByText('Time Jump')).toBeInTheDocument();
73+
expect(screen.getByText('Providers / Consumers')).toBeInTheDocument();
74+
});
75+
76+
test('displays selected value', () => {
77+
render(
78+
<DropDown dropdownSelection='Time Jump' setDropdownSelection={mockSetDropdownSelection} />,
79+
);
80+
expect(screen.getByText('Time Jump')).toBeInTheDocument();
81+
});
82+
});
83+
84+
// RecordButton Component Tests
85+
describe('RecordButton Component', () => {
86+
const mockOnToggle = jest.fn();
87+
88+
beforeEach(() => {
89+
mockOnToggle.mockClear();
90+
});
91+
92+
test('renders record button with initial state', () => {
93+
render(<RecordButton isRecording={false} onToggle={mockOnToggle} />);
94+
expect(screen.getByText('Record')).toBeInTheDocument();
95+
});
96+
97+
test('calls onToggle when switch is clicked', () => {
98+
render(<RecordButton isRecording={false} onToggle={mockOnToggle} />);
99+
const switchElement = screen.getByRole('checkbox');
100+
fireEvent.click(switchElement);
101+
expect(mockOnToggle).toHaveBeenCalled();
102+
});
103+
104+
test('renders ThemeToggle component', () => {
105+
render(<RecordButton isRecording={false} onToggle={mockOnToggle} />);
106+
expect(screen.getByTestId('mock-theme-toggle')).toBeInTheDocument();
107+
});
108+
});
109+
110+
// // ThemeToggle Component Tests
111+
describe('ThemeToggle Component', () => {
112+
const mockToggleTheme = jest.fn();
113+
114+
beforeEach(() => {
115+
mockToggleTheme.mockClear();
116+
(useTheme as jest.Mock).mockImplementation(() => ({
117+
isDark: false,
118+
toggleTheme: mockToggleTheme,
119+
}));
120+
});
121+
122+
test('renders theme toggle', () => {
123+
render(<ThemeToggle />);
124+
expect(screen.getByTestId('mock-theme-toggle')).toBeInTheDocument();
125+
});
126+
127+
test('renders with correct text', () => {
128+
render(<ThemeToggle />);
129+
expect(screen.getByTestId('mock-theme-toggle')).toHaveTextContent('Theme Toggle');
130+
});
131+
132+
test('toggles between light and dark mode classes', () => {
133+
// First render in light mode
134+
(useTheme as jest.Mock).mockImplementation(() => ({
135+
isDark: false,
136+
toggleTheme: mockToggleTheme,
137+
}));
138+
const { rerender } = render(<ThemeToggle />);
139+
const toggle = screen.getByTestId('mock-theme-toggle');
140+
expect(toggle).toHaveClass('theme-toggle');
141+
expect(toggle).not.toHaveClass('dark');
142+
143+
// Rerender in dark mode
144+
(useTheme as jest.Mock).mockImplementation(() => ({
145+
isDark: true,
146+
toggleTheme: mockToggleTheme,
147+
}));
148+
rerender(<ThemeToggle />);
149+
expect(toggle).toHaveClass('theme-toggle');
150+
expect(toggle).toHaveClass('dark');
151+
});
152+
});
153+
154+
// // ProvConContainer Component Tests
155+
// describe('ProvConContainer Component', () => {
156+
// const mockSnapshot = {
157+
// componentData: {
158+
// context: {
159+
// theme: { dark: true },
160+
// user: { id: 1, name: 'Test' },
161+
// },
162+
// hooksState: {
163+
// useState: [{ value: 'test' }],
164+
// },
165+
// },
166+
// children: [
167+
// {
168+
// name: 'ThemeProvider',
169+
// componentData: {
170+
// context: { theme: 'dark' },
171+
// },
172+
// children: [],
173+
// },
174+
// ],
175+
// };
176+
177+
// test('renders empty state message when no providers/consumers found', () => {
178+
// render(<ProvConContainer currentSnapshot={{}} />);
179+
// expect(screen.getByText(/No providers or consumers found/)).toBeInTheDocument();
180+
// });
181+
182+
// test('renders context data correctly', () => {
183+
// render(<ProvConContainer currentSnapshot={mockSnapshot} />);
184+
185+
// // Use getAllByText to get all theme spans and verify at least one exists
186+
// const themeElements = screen.getAllByText((content, element) => {
187+
// return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'theme:';
188+
// });
189+
// expect(themeElements.length).toBeGreaterThan(0);
190+
191+
// // Do the same for user spans
192+
// const userElements = screen.getAllByText((content, element) => {
193+
// return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'user:';
194+
// });
195+
// expect(userElements.length).toBeGreaterThan(0);
196+
// });
197+
198+
// test('renders provider components correctly', () => {
199+
// render(<ProvConContainer currentSnapshot={mockSnapshot} />);
200+
201+
// // Get all theme elements and use the first one to find its parent
202+
// const themeElements = screen.getAllByText((content, element) => {
203+
// return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'theme:';
204+
// });
205+
// const parentElement = themeElements[0].closest('div');
206+
207+
// expect(parentElement).toBeInTheDocument();
208+
// });
209+
210+
// test('correctly parses stringified JSON values', () => {
211+
// const snapshotWithStringifiedJSON = {
212+
// componentData: {
213+
// context: {
214+
// data: JSON.stringify({ key: 'value' }),
215+
// },
216+
// },
217+
// };
218+
// render(<ProvConContainer currentSnapshot={snapshotWithStringifiedJSON} />);
219+
220+
// // Look for the key-value pair in the rendered structure
221+
// expect(
222+
// screen.getByText((content, element) => {
223+
// return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'key:';
224+
// }),
225+
// ).toBeInTheDocument();
226+
227+
// expect(
228+
// screen.getByText((content, element) => {
229+
// return element?.tagName.toLowerCase() === 'span' && element?.textContent === '"value"';
230+
// }),
231+
// ).toBeInTheDocument();
232+
// });
233+
// });
234+
235+
// // Clear Button Tests
236+
// describe('Clear Button', () => {
237+
// // Create mock store
238+
// const mockStore = configureStore({
239+
// reducer: {
240+
// main: mainSlice.reducer,
241+
// },
242+
// preloadedState: {
243+
// main: {
244+
// port: null,
245+
// currentTab: 0,
246+
// currentTitle: 'No Target',
247+
// tabs: {
248+
// 0: {
249+
// currLocation: {
250+
// index: 0,
251+
// stateSnapshot: {
252+
// children: [],
253+
// route: {
254+
// url: '/test',
255+
// },
256+
// },
257+
// },
258+
// hierarchy: {
259+
// index: 0,
260+
// stateSnapshot: {
261+
// children: [],
262+
// route: {
263+
// url: '/test',
264+
// },
265+
// },
266+
// children: [],
267+
// },
268+
// sliderIndex: 0,
269+
// viewIndex: 0,
270+
// snapshots: [],
271+
// playing: false,
272+
// intervalId: null,
273+
// mode: { paused: false },
274+
// status: {
275+
// reactDevToolsInstalled: true,
276+
// targetPageisaReactApp: true,
277+
// },
278+
// },
279+
// },
280+
// currentTabInApp: null,
281+
// connectionStatus: true,
282+
// connectRequested: true,
283+
// },
284+
// },
285+
// });
286+
287+
// // @ts-ignore
288+
// const useDispatchMock = useDispatch as jest.Mock;
289+
// const dummyDispatch = jest.fn();
290+
291+
// beforeEach(() => {
292+
// useDispatchMock.mockReturnValue(dummyDispatch);
293+
// dummyDispatch.mockClear();
294+
// });
295+
296+
// test('renders clear button with correct text', () => {
297+
// render(
298+
// <Provider store={mockStore}>
299+
// <ActionContainer snapshots={[]} />
300+
// </Provider>,
301+
// );
302+
// expect(screen.getByText('Clear')).toBeInTheDocument();
303+
// });
304+
305+
// test('dispatches both emptySnapshots and changeSlider actions when clicked', () => {
306+
// render(
307+
// <Provider store={mockStore}>
308+
// <ActionContainer snapshots={[]} />
309+
// </Provider>,
310+
// );
311+
// fireEvent.click(screen.getByText('Clear'));
312+
// expect(dummyDispatch).toHaveBeenCalledWith(emptySnapshots());
313+
// expect(dummyDispatch).toHaveBeenCalledWith(changeSlider(0));
314+
// });
315+
// });

src/app/__tests__/ButtonContainer.test.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ import { toggleMode, mainSlice } from '../slices/mainSlice';
99
import { useDispatch, Provider } from 'react-redux';
1010
import { configureStore } from '@reduxjs/toolkit';
1111

12-
// const { Steps } = require('intro.js-react');
13-
// jest.mock('../store');
14-
// const mockedUsedStoreContext = jest.mocked(useStoreContext);
15-
// useStoreContext as jest.Mock<useStoreContext>.mockImplementaton(() => [state, dispatch])
16-
1712
const customTabs = {
1813
87: {
1914
snapshots: [1, 2, 3, 4],

0 commit comments

Comments
 (0)