Skip to content

Commit 5cfe234

Browse files
committed
added sidbar elements tests
1 parent a4d40b7 commit 5cfe234

File tree

9 files changed

+394
-63
lines changed

9 files changed

+394
-63
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React from 'react';
2+
import { render, fireEvent , screen} from '@testing-library/react';
3+
import '@testing-library/jest-dom';
4+
import ClassSelectionMenu from './index';
5+
6+
// Mock regions data
7+
const mockRegionClsList = ['class1', 'class2', 'class3'];
8+
const mockRegionColorList = ['#ff0000', '#00ff00', '#0000ff'];
9+
const mockRegions = undefined
10+
const mockOnSelectCls = jest.fn();
11+
12+
// Mock the useTranslation hook
13+
jest.mock('react-i18next', () => ({
14+
useTranslation: () => ({
15+
t: key => ({
16+
"menu.classifications": "Labels",
17+
}[key]),
18+
}),
19+
}));
20+
21+
22+
describe('ClassSelectionMenu', () => {
23+
it('renders correctly', () => {
24+
const { getByText } = render(
25+
<ClassSelectionMenu
26+
selectedCls={'class1'}
27+
regionClsList={mockRegionClsList}
28+
regionColorList={mockRegionColorList}
29+
onSelectCls={mockOnSelectCls}
30+
regions={mockRegions}
31+
expandedByDefault={true}
32+
/>
33+
);
34+
35+
// Check if the component exists
36+
expect(getByText('Class1')).toBeInTheDocument();
37+
expect(getByText('Class2')).toBeInTheDocument();
38+
expect(getByText('Class3')).toBeInTheDocument();
39+
40+
});
41+
42+
it('calls onSelectCls with the correct class when a label is clicked', () => {
43+
const { getByText } = render(
44+
<ClassSelectionMenu
45+
selectedCls={'class1'}
46+
regionClsList={mockRegionClsList}
47+
regionColorList={mockRegionColorList}
48+
onSelectCls={mockOnSelectCls}
49+
regions={mockRegions}
50+
/>
51+
);
52+
53+
fireEvent.click(getByText('Class2'));
54+
55+
expect(mockOnSelectCls).toHaveBeenCalledWith('class2');
56+
});
57+
58+
it('selects the first class if no class is selected initially', () => {
59+
render(
60+
<ClassSelectionMenu
61+
selectedCls={null}
62+
regionClsList={mockRegionClsList}
63+
regionColorList={mockRegionColorList}
64+
onSelectCls={mockOnSelectCls}
65+
regions={mockRegions}
66+
/>
67+
);
68+
expect(mockOnSelectCls).toHaveBeenCalledWith('class1');
69+
});
70+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import React from 'react';
2+
import { render, fireEvent } from '@testing-library/react';
3+
import FilesListMenu from './index';
4+
import '@testing-library/jest-dom';
5+
6+
// Mock images data
7+
const mockAllImages = [
8+
{ name: 'Image1', processed: false },
9+
{ name: 'Image2', processed: true },
10+
{ name: 'Image3', processed: false }
11+
];
12+
13+
// Mock the useTranslation hook
14+
jest.mock('react-i18next', () => ({
15+
useTranslation: () => ({
16+
t: key => ({
17+
"menu.images": "Images",
18+
}[key]),
19+
}),
20+
}));
21+
22+
describe('FilesListMenu', () => {
23+
const state = {
24+
"annotationType": "image",
25+
"showTags": true,
26+
"selectedTool": "create-polygon",
27+
"mode": null,
28+
"taskDescription": "dgdg",
29+
"settings": {
30+
"taskDescription": "dgdg",
31+
"taskChoice": "image_segmentation",
32+
"images": [
33+
{
34+
"src": "http://127.0.0.1:5000/uploads/clothes.jpeg",
35+
"name": "clothes",
36+
"selectedClsList": "",
37+
"comment": "",
38+
"processed": false
39+
}
40+
],
41+
"dataTask": null,
42+
"configuration": {
43+
"labels": [
44+
{
45+
"id": "dfgd"
46+
},
47+
{
48+
"id": "dfg"
49+
}
50+
],
51+
"multipleRegions": true,
52+
"multipleRegionLabels": true,
53+
"regionTypesAllowed": [
54+
"polygon",
55+
"bounding-box",
56+
"circle"
57+
]
58+
}
59+
},
60+
"labelImages": false,
61+
"regionClsList": [
62+
"dfgd",
63+
"dfg"
64+
],
65+
"regionColorList": [],
66+
"preselectCls": null,
67+
"regionTagList": [],
68+
"imageClsList": [],
69+
"imageTagList": [],
70+
"currentVideoTime": 0,
71+
"enabledTools": [
72+
"create-box",
73+
"create-polygon",
74+
"create-circle"
75+
],
76+
"history": [],
77+
"enabledRegionProps": [
78+
"class",
79+
"comment"
80+
],
81+
"selectedImage": 0,
82+
"images": [
83+
{
84+
"src": "http://127.0.0.1:5000/uploads/clothes.jpeg",
85+
"name": "clothes",
86+
"selectedClsList": [
87+
"dfgd"
88+
],
89+
"comment": "",
90+
"processed": false
91+
}
92+
],
93+
"lastAction": {
94+
"type": "SELECT_IMAGE",
95+
"imageIndex": 0,
96+
"image": {
97+
"src": "http://127.0.0.1:5000/uploads/clothes.jpeg",
98+
"name": "clothes",
99+
"selectedClsList": [
100+
"dfgd"
101+
],
102+
"comment": "",
103+
"processed": false
104+
}
105+
},
106+
"selectedCls": "dfgd",
107+
"lastMouseMoveCall": 1718142223586
108+
}
109+
it('renders correctly', () => {
110+
const onSelectJumpMock = jest.fn();
111+
const saveActiveImageMock = jest.fn();
112+
const onClickMock = jest.fn();
113+
114+
const { getByText, getAllByTestId } = render(
115+
<FilesListMenu
116+
state={state}
117+
selectedImage={'image1'}
118+
allImages={mockAllImages}
119+
onSelectJump={onSelectJumpMock}
120+
saveActiveImage={saveActiveImageMock}
121+
onClick={onClickMock}
122+
/>
123+
);
124+
125+
// Check if the component title is rendered
126+
expect(getByText(/Images \[3\]/)).toBeInTheDocument();
127+
128+
// Check if each image name is rendered
129+
mockAllImages.forEach(image => {
130+
expect(getByText(image.name)).toBeInTheDocument();
131+
});
132+
133+
// Check if checkboxes are rendered for each image
134+
const checkboxes = getAllByTestId('checkbox');
135+
expect(checkboxes).toHaveLength(mockAllImages.length);
136+
137+
// Simulate click on an image
138+
fireEvent.click(getByText('Image1'));
139+
140+
// Check if the onClick callback is called with the correct arguments
141+
expect(onClickMock).toHaveBeenCalledWith({"activeImage": {"comment": "", "name": "clothes", "processed": false, "selectedClsList": ["dfgd"], "src": "http://127.0.0.1:5000/uploads/clothes.jpeg"}, "currentImageIndex": 0, "pathToActiveImage": ["images", 0]});
142+
143+
// Check if the onSelectJump and saveActiveImage callbacks are called with the correct arguments
144+
expect(onSelectJumpMock).toHaveBeenCalledWith('Image1');
145+
expect(saveActiveImageMock).toHaveBeenCalledWith({"comment": "", "name": "clothes", "processed": false, "selectedClsList": ["dfgd"], "src": "http://127.0.0.1:5000/uploads/clothes.jpeg"});
146+
});
147+
});

client/src/FilesListMenu/index.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export const FilesListMenu = ({
9797
color: image.processed ? 'green' : '', // Set color conditionally
9898
},
9999
}}
100+
data-testid="checkbox"
100101
/>
101102
<span style={index === selectedImage? {backgroundColor: "rgba(255, 124, 120, 0.5)"} : {}}>
102103
<Label className={classnames({ selected: image.name === selectedImage })} style={ { backgroundColor: "withe" }}>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from "react"
2+
import { render, fireEvent, screen } from "@testing-library/react"
3+
import "@testing-library/jest-dom"
4+
import { HistorySidebarBox } from "./index"
5+
6+
7+
// Mock the useTranslation hook
8+
jest.mock('react-i18next', () => ({
9+
useTranslation: () => ({
10+
t: key => ({
11+
"menu.history": "History",
12+
"no.history": "No History Yet",
13+
}[key]),
14+
}),
15+
}));
16+
17+
describe("HistorySidebarBox", () => {
18+
const history = [
19+
{ name: "History 1", time: new Date("2022-06-15T12:00:00Z") },
20+
{ name: "History 2", time: new Date("2022-06-16T12:00:00Z") },
21+
]
22+
23+
it("renders empty text when there is no history", () => {
24+
const { getByText } = render(<HistorySidebarBox history={[]} />)
25+
expect(getByText("No History Yet")).toBeInTheDocument()
26+
})
27+
28+
it("renders each history item correctly", () => {
29+
const mockHistory = [
30+
{ name: "History 1", time: new Date("2021-08-01T12:00:00Z") },
31+
{ name: "History 2", time: new Date("2021-08-01T12:00:00Z") },
32+
];
33+
34+
render(
35+
<HistorySidebarBox
36+
history={mockHistory}
37+
onRestoreHistory={() => {}}
38+
/>
39+
);
40+
41+
// Check if each history item name is rendered
42+
mockHistory.forEach((item) => {
43+
expect(screen.getByText(item.name)).toBeInTheDocument();
44+
});
45+
46+
// Check if each history item time is rendered using a more direct query
47+
mockHistory.forEach((item) => {
48+
const formattedTime = item.time.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" });
49+
50+
// Find all p elements and check if their textContent matches the formatted time
51+
const timeElements = screen.getAllByRole('listitem').map(listItem => listItem.querySelector('p'));
52+
const hasFormattedTime = timeElements.some(p => p.textContent === formattedTime);
53+
expect(hasFormattedTime).toBe(true);
54+
});
55+
56+
// Check if the undo icon is rendered
57+
expect(screen.getByTestId("undo-icon")).toBeInTheDocument();
58+
});
59+
60+
it("calls onRestoreHistory when undo icon is clicked for the first history item", () => {
61+
const onRestoreHistoryMock = jest.fn()
62+
const { getByTestId } = render(
63+
<HistorySidebarBox history={history} onRestoreHistory={onRestoreHistoryMock} />
64+
)
65+
fireEvent.click(getByTestId("undo-icon"))
66+
expect(onRestoreHistoryMock).toHaveBeenCalledTimes(2)
67+
})
68+
})

client/src/HistorySidebarBox/index.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export const HistorySidebarBox = ({
5757
{i === 0 && (
5858
<ListItemSecondaryAction onClick={() => onRestoreHistory()}>
5959
<Grid item xs={1} onClick={() => onRestoreHistory()}>
60-
<UndoIcon sx={{ fontSize: 14 }} />
60+
<UndoIcon sx={{ fontSize: 14 }} data-testid="undo-icon"/>
6161
</Grid>
6262
</ListItemSecondaryAction>
6363
)}

0 commit comments

Comments
 (0)