Merge branch 'develop'
This commit is contained in:
82
__tests__/unit/components/DataSheet.test.js
Normal file
82
__tests__/unit/components/DataSheet.test.js
Normal file
@@ -0,0 +1,82 @@
|
||||
// __tests__/components/DataSheet.test.js
|
||||
import React from "react";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import DataSheet from "../../components/DataSheet";
|
||||
import { RecoilRoot } from "recoil";
|
||||
import * as Recoil from "recoil";
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import { gisStationsStaticDistrictState } from "../../store/atoms/gisStationState";
|
||||
import { gisSystemStaticState } from "../../store/atoms/gisSystemState";
|
||||
import { mapLayersState } from "../../store/atoms/mapLayersState";
|
||||
import { selectedAreaState } from "../../store/atoms/selectedAreaState";
|
||||
import { zoomTriggerState } from "../../store/atoms/zoomTriggerState";
|
||||
import { poiLayerVisibleState } from "../../store/atoms/poiLayerVisibleState";
|
||||
|
||||
// Stelle sicher, dass alle notwendigen Atome korrekt gemockt sind
|
||||
jest.mock("../../store/atoms/gisStationState", () => ({
|
||||
gisStationState: {
|
||||
subscribe: jest.fn(),
|
||||
getSnapshot: jest.fn(() => []), // Mocked return value
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("../../store/atoms/gisSystemState", () => ({
|
||||
gisSystemStaticState: {
|
||||
subscribe: jest.fn(),
|
||||
getSnapshot: jest.fn(() => []), // Mocked return value
|
||||
},
|
||||
}));
|
||||
|
||||
describe("DataSheet Component", () => {
|
||||
//--------------------------------------------------------------------------------
|
||||
it("renders the basic fields and initial station/system listings", async () => {
|
||||
render(
|
||||
<RecoilRoot>
|
||||
<DataSheet />
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
// Waiting for asynchronous tasks to complete
|
||||
await waitFor(() => {
|
||||
// Check if the specific elements are present after data processing
|
||||
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
||||
expect(screen.getByLabelText("POIs")).toBeInTheDocument();
|
||||
expect(screen.getByRole("option", { name: "Station wählen" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Optionally print out the full DOM for debugging
|
||||
screen.debug();
|
||||
});
|
||||
//--------------------------------------------------------------------------------
|
||||
test("should open dropdown on click", async () => {
|
||||
render(
|
||||
<RecoilRoot>
|
||||
<DataSheet />
|
||||
</RecoilRoot>
|
||||
);
|
||||
const combobox = screen.getByRole("combobox");
|
||||
userEvent.click(combobox);
|
||||
// Überprüfe, ob die Dropdown-Optionen angezeigt werden
|
||||
expect(screen.getByRole("option", { name: "Station wählen" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
test("should toggle checkbox", async () => {
|
||||
render(
|
||||
<RecoilRoot>
|
||||
<DataSheet />
|
||||
</RecoilRoot>
|
||||
);
|
||||
const checkbox = screen.getByLabelText("POIs");
|
||||
// Stelle sicher, dass die Checkbox nicht angekreuzt ist
|
||||
expect(checkbox).not.toBeChecked();
|
||||
// Klicke auf die Checkbox
|
||||
userEvent.click(checkbox);
|
||||
// Jetzt sollte sie angekreuzt sein
|
||||
expect(checkbox).toBeChecked();
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
});
|
||||
89
__tests__/unit/components/MapComponent.test.js
Normal file
89
__tests__/unit/components/MapComponent.test.js
Normal file
@@ -0,0 +1,89 @@
|
||||
// __tests__/MapComponent.test.js
|
||||
|
||||
// Ein einfacher Testfall, der sicherstellt, dass die Addition korrekt ist
|
||||
test("simple addition", () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = a + b;
|
||||
expect(c).toBe(3); // Überprüft, ob c gleich 3 ist
|
||||
});
|
||||
|
||||
//import L from "leaflet";
|
||||
//import { checkOverlappingMarkers } from "../utils/mapUtils"; // Passe den Pfad entsprechend an
|
||||
|
||||
/* describe("checkOverlappingMarkers", () => {
|
||||
let map;
|
||||
|
||||
beforeEach(() => {
|
||||
// Erstelle eine neue Leaflet-Karte für jeden Test
|
||||
map = L.map(document.createElement("div"));
|
||||
});
|
||||
|
||||
it("should group markers by coordinates and add plus icons for overlapping markers", () => {
|
||||
// Erstelle einige Beispielmarker
|
||||
const markers = [
|
||||
L.marker([51.505, -0.09]),
|
||||
L.marker([51.505, -0.09]),
|
||||
L.marker([51.51, -0.1]),
|
||||
];
|
||||
|
||||
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||
|
||||
// Rufe die Funktion auf
|
||||
checkOverlappingMarkers(map, markers, plusIcon);
|
||||
|
||||
// Überprüfe, dass die Marker zu Gruppen hinzugefügt wurden
|
||||
const overlappingGroups = map._layers;
|
||||
expect(Object.keys(overlappingGroups).length).toBeGreaterThan(0);
|
||||
|
||||
// Überprüfe, dass die Plus-Marker hinzugefügt wurden
|
||||
const plusMarkers = Object.values(overlappingGroups).filter(
|
||||
(layer) =>
|
||||
layer.options.icon &&
|
||||
layer.options.icon.options.className === "plus-icon"
|
||||
);
|
||||
expect(plusMarkers.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should handle non-array markers argument gracefully", () => {
|
||||
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||
|
||||
// Rufe die Funktion mit einem ungültigen Argument auf
|
||||
checkOverlappingMarkers(map, null, plusIcon);
|
||||
|
||||
// Stelle sicher, dass keine Marker hinzugefügt wurden
|
||||
const layers = map._layers;
|
||||
expect(Object.keys(layers).length).toBe(0);
|
||||
});
|
||||
|
||||
it("should not add plus markers if there are no overlaps", () => {
|
||||
// Erstelle einige Beispielmarker
|
||||
const markers = [
|
||||
L.marker([51.505, -0.09]),
|
||||
L.marker([51.51, -0.1]),
|
||||
L.marker([51.52, -0.12]),
|
||||
];
|
||||
|
||||
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||
|
||||
// Rufe die Funktion auf
|
||||
checkOverlappingMarkers(map, markers, plusIcon);
|
||||
|
||||
// Überprüfe, dass keine Plus-Marker hinzugefügt wurden
|
||||
const plusMarkers = Object.values(map._layers).filter(
|
||||
(layer) =>
|
||||
layer.options.icon &&
|
||||
layer.options.icon.options.className === "plus-icon"
|
||||
);
|
||||
expect(plusMarkers.length).toBe(0);
|
||||
});
|
||||
}); */
|
||||
/*
|
||||
In diesem Test:
|
||||
|
||||
Wird eine neue Leaflet-Karte vor jedem Test erstellt.
|
||||
checkOverlappingMarkers wird aufgerufen, um zu überprüfen, ob die Funktion die Marker richtig gruppiert und Plus-Icons für überlappende Marker hinzufügt.
|
||||
Der Test überprüft auch, ob die Funktion ungültige Argumente (wie null für Marker) korrekt behandelt.
|
||||
Es wird sichergestellt, dass keine Plus-Marker hinzugefügt werden, wenn keine Überlappungen vorliegen.
|
||||
Stelle sicher, dass du die Pfade und Importe entsprechend deiner Projektstruktur anpasst.
|
||||
*/
|
||||
@@ -0,0 +1,40 @@
|
||||
// __tests__/components/gisPolylines/icons/CircleIcon.test.js
|
||||
jest.mock("leaflet", () => {
|
||||
const actualLeaflet = jest.requireActual("leaflet");
|
||||
return {
|
||||
...actualLeaflet,
|
||||
DivIcon: jest.fn().mockImplementation((options) => ({
|
||||
...options,
|
||||
options,
|
||||
_leaflet_id: Math.random(),
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
import L from "leaflet";
|
||||
import CircleIcon from "../../../components/gisPolylines/icons/CircleIcon";
|
||||
|
||||
describe("CircleIcon", () => {
|
||||
test("should be a Leaflet divIcon with correct properties", () => {
|
||||
// console.log("CircleIcon options:", CircleIcon.options);
|
||||
expect(CircleIcon).toEqual(
|
||||
expect.objectContaining({
|
||||
options: expect.objectContaining({
|
||||
className: "custom-circle-icon leaflet-marker-icon",
|
||||
html: '<div style="background-color:gray; width:10px; height:10px; border-radius:50%; border: solid black 1px;"></div>',
|
||||
iconSize: [25, 25],
|
||||
iconAnchor: [5, 5],
|
||||
}),
|
||||
})
|
||||
);
|
||||
expect(CircleIcon.options.className).toContain("custom-circle-icon");
|
||||
expect(CircleIcon.options.html).toContain("<div");
|
||||
expect(CircleIcon.options.html).toContain("background-color:gray");
|
||||
expect(CircleIcon.options.html).toContain("border-radius:50%");
|
||||
expect(CircleIcon.options.html).toContain("width:10px");
|
||||
expect(CircleIcon.options.html).toContain("height:10px");
|
||||
expect(CircleIcon.options.html).toContain("border: solid black 1px");
|
||||
expect(CircleIcon.options.iconSize).toEqual([25, 25]);
|
||||
expect(CircleIcon.options.iconAnchor).toEqual([5, 5]);
|
||||
});
|
||||
});
|
||||
24
__tests__/unit/components/gisPolylines/icons/EndIcon.test.js
Normal file
24
__tests__/unit/components/gisPolylines/icons/EndIcon.test.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// __tests__/components/gisPolylines/icons/EndIcon.test.js
|
||||
jest.mock("leaflet", () => {
|
||||
const actualLeaflet = jest.requireActual("leaflet");
|
||||
return {
|
||||
...actualLeaflet,
|
||||
DivIcon: jest.fn().mockImplementation((options) => ({
|
||||
...options,
|
||||
options,
|
||||
_leaflet_id: Math.random(),
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
import L from "leaflet";
|
||||
import EndIcon from "../../../../components/gisPolylines/icons/EndIcon";
|
||||
//console.log("console log EndIcon: ", EndIcon);
|
||||
describe("endIcon", () => {
|
||||
test("should be a custom-end-icon with correct HTML and styles", () => {
|
||||
expect(EndIcon.options.className).toBe("custom-end-icon");
|
||||
expect(EndIcon.options.html).toBe("<div style='background-color: gray; width: 14px; height: 14px; border: solid black 2px;'></div>");
|
||||
expect(EndIcon.options.iconSize).toEqual([14, 14]);
|
||||
expect(EndIcon.options.iconAnchor).toEqual([7, 7]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
// __tests__/components/gisPolylines/icons/StartIcon.test.js
|
||||
jest.mock("leaflet", () => {
|
||||
const actualLeaflet = jest.requireActual("leaflet");
|
||||
return {
|
||||
...actualLeaflet,
|
||||
DivIcon: jest.fn().mockImplementation((options) => ({
|
||||
...options,
|
||||
options,
|
||||
_leaflet_id: Math.random(),
|
||||
_createIcon: jest.fn(),
|
||||
_createImg: jest.fn(),
|
||||
_getIconUrl: jest.fn(),
|
||||
_initHooks: [],
|
||||
_initHooksCalled: true,
|
||||
_setIconStyles: jest.fn(),
|
||||
callInitHooks: jest.fn(),
|
||||
createIcon: jest.fn(),
|
||||
createShadow: jest.fn(),
|
||||
initialize: jest.fn(),
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
import L from "leaflet";
|
||||
import StartIcon from "../../../../../components/gisPolylines/icons/StartIcon";
|
||||
|
||||
describe("StartIcon", () => {
|
||||
test("should be a Leaflet divIcon with correct properties", () => {
|
||||
//console.log("StartIcon options:", StartIcon.options);
|
||||
expect(StartIcon).toEqual(
|
||||
expect.objectContaining({
|
||||
options: expect.objectContaining({
|
||||
className: "custom-start-icon",
|
||||
html: expect.stringContaining("<svg"),
|
||||
iconSize: [18, 18],
|
||||
iconAnchor: [9, 10],
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
42
__tests__/unit/hooks/useLineData.test.js
Normal file
42
__tests__/unit/hooks/useLineData.test.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import { renderHook, act, waitFor } from "@testing-library/react";
|
||||
import useLineData from "../../../hooks/useLineData";
|
||||
import React from "react";
|
||||
|
||||
const mockUrl = "http://mockurl.com";
|
||||
const mockData1 = {
|
||||
Statis: [{ IdLD: 1, Modul: "mod1", PrioColor: "red", ModulName: "Module 1", ModulTyp: "Type 1", Message: "Message 1", PrioName: "High", DpName: "DP 1", Value: "Value 1" }],
|
||||
};
|
||||
const mockData2 = [{ idLD: 1, idModul: "mod1" }];
|
||||
|
||||
global.fetch = jest.fn((url) => {
|
||||
if (url === mockUrl) {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve(mockData1),
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve(mockData2),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe("useLineData", () => {
|
||||
test("should fetch line data and set line colors and tooltip contents", async () => {
|
||||
const setLineStatusData = jest.fn();
|
||||
|
||||
const { result } = renderHook(() => useLineData(mockUrl, setLineStatusData));
|
||||
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(setLineStatusData).toHaveBeenCalledWith(expect.any(Array));
|
||||
expect(result.current).toEqual(
|
||||
expect.objectContaining({
|
||||
lineColors: expect.any(Object),
|
||||
tooltipContents: expect.any(Object),
|
||||
})
|
||||
);
|
||||
},
|
||||
{ timeout: 5000 } // Increase the timeout to 5000ms
|
||||
);
|
||||
});
|
||||
});
|
||||
86
__tests__/unit/pois/AddPoiModalWindow.test.js
Normal file
86
__tests__/unit/pois/AddPoiModalWindow.test.js
Normal file
@@ -0,0 +1,86 @@
|
||||
// __tests__/components/pois/AddPoiModalWindow.test.js
|
||||
|
||||
import React from "react";
|
||||
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import AddPoiModalWindow from "../../../components/pois/AddPoiModalWindow";
|
||||
import { RecoilRoot } from "recoil";
|
||||
|
||||
// Mock für die fetch-Funktion
|
||||
global.fetch = jest.fn((url) => {
|
||||
if (url === "/api/talas_v5_DB/poiTyp/readPoiTyp") {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]),
|
||||
});
|
||||
} else if (url === "/api/talas5/location_device") {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve([{ idLD: "1", name: "Device1" }]),
|
||||
});
|
||||
} else if (url === "/api/talas_v5_DB/pois/addLocation") {
|
||||
return Promise.resolve({ ok: true });
|
||||
}
|
||||
});
|
||||
|
||||
describe("AddPoiModalWindow", () => {
|
||||
const mockOnClose = jest.fn();
|
||||
const mockMap = {
|
||||
closePopup: jest.fn(),
|
||||
};
|
||||
const mockLatLng = { lat: 52.52, lng: 13.405 };
|
||||
|
||||
// Mock window.location.reload
|
||||
beforeAll(() => {
|
||||
Object.defineProperty(window, "location", {
|
||||
value: {
|
||||
...window.location,
|
||||
reload: jest.fn(),
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fetch.mockClear();
|
||||
window.location.reload.mockClear(); // Clear the mock before each test
|
||||
});
|
||||
|
||||
test("renders correctly and allows form submission", async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<RecoilRoot>
|
||||
<AddPoiModalWindow onClose={mockOnClose} map={mockMap} latlng={mockLatLng} />
|
||||
</RecoilRoot>
|
||||
);
|
||||
});
|
||||
|
||||
// Überprüfen, ob die Formularelemente gerendert werden
|
||||
expect(screen.getByLabelText(/Name/i)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/Gerät/i)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/Typ/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Lat/i)).toHaveTextContent(`Lat : ${mockLatLng.lat.toFixed(5)}`);
|
||||
expect(screen.getByText(/Lng/i)).toHaveTextContent(`Lng : ${mockLatLng.lng.toFixed(5)}`);
|
||||
|
||||
// Simulieren der Eingabe in das Namensfeld
|
||||
fireEvent.change(screen.getByLabelText(/Name/i), { target: { value: "New POI" } });
|
||||
expect(screen.getByLabelText(/Name/i)).toHaveValue("New POI");
|
||||
|
||||
// Simulieren der Auswahl eines Geräts
|
||||
fireEvent.change(screen.getByLabelText(/Gerät/i), { target: { value: "Device1" } });
|
||||
expect(screen.getByLabelText(/Gerät/i)).toHaveValue("Device1");
|
||||
|
||||
// Simulieren der Auswahl eines Typs
|
||||
fireEvent.change(screen.getByLabelText(/Typ/i), { target: { value: "1" } });
|
||||
expect(screen.getByLabelText(/Typ/i)).toHaveValue("1");
|
||||
|
||||
// Simulieren des Formulareingabeverfahrens
|
||||
fireEvent.submit(screen.getByRole("button", { name: /POI hinzufügen/i }));
|
||||
|
||||
// Warten auf die Formulareinreichung und Überprüfen der Ergebnisse
|
||||
await waitFor(() => {
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
expect(mockMap.closePopup).toHaveBeenCalled();
|
||||
expect(fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/addLocation", expect.any(Object));
|
||||
expect(window.location.reload).toHaveBeenCalled(); // Verify that reload was called
|
||||
});
|
||||
});
|
||||
});
|
||||
77
__tests__/unit/pois/AddPoiModalWindowPopup.test.js
Normal file
77
__tests__/unit/pois/AddPoiModalWindowPopup.test.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// __tests__/components/pois/AddPoiModalWindowPopup.test.js
|
||||
|
||||
import React from "react";
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import AddPoiModalWindowPopup from "../../../components/pois/AddPoiModalWindowPopup";
|
||||
|
||||
// Mock the AddPoiModalWindow component
|
||||
jest.mock("../../../components/pois/AddPoiModalWindow", () => ({ onClose, onSubmit, latlng }) => (
|
||||
<div data-testid="add-poi-modal-window">
|
||||
<button onClick={() => console.log("Mocked Close Modal Click")}>Close Modal</button>
|
||||
<button onClick={onSubmit}>Submit</button>
|
||||
<div>
|
||||
Coordinates: {latlng.lat}, {latlng.lng}
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
describe("AddPoiModalWindowPopup", () => {
|
||||
const closePopupMock = jest.fn();
|
||||
const handleAddStationMock = jest.fn();
|
||||
const popupCoordinatesMock = { lat: 52.52, lng: 13.405 };
|
||||
|
||||
// Suppress console.log for the duration of these tests
|
||||
beforeAll(() => {
|
||||
jest.spyOn(console, "log").mockImplementation(() => {});
|
||||
});
|
||||
|
||||
// Restore console.log after all tests
|
||||
afterAll(() => {
|
||||
console.log.mockRestore();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
closePopupMock.mockClear();
|
||||
handleAddStationMock.mockClear();
|
||||
});
|
||||
|
||||
test("renders the popup when showPopup is true", () => {
|
||||
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
expect(screen.getByTestId("add-poi-modal-window")).toBeInTheDocument();
|
||||
expect(screen.getByText("Coordinates: 52.52, 13.405")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("does not render the popup when showPopup is false", () => {
|
||||
render(<AddPoiModalWindowPopup showPopup={false} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("closes the popup when the top right close button is clicked", () => {
|
||||
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
// Use the aria-label to uniquely identify the close button in the outer component
|
||||
const closeButton = screen.getByRole("button", { name: "Close" });
|
||||
|
||||
// Click the button with aria-label "Close"
|
||||
fireEvent.click(closeButton);
|
||||
expect(closePopupMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test("submits the form when the submit button is clicked", () => {
|
||||
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
fireEvent.click(screen.getByText("Submit"));
|
||||
expect(handleAddStationMock).toHaveBeenCalledTimes(1); // This should now pass
|
||||
});
|
||||
|
||||
test('clicking the "Close Modal" button inside AddPoiModalWindow should not close the popup', () => {
|
||||
render(<AddPoiModalWindowPopup showPopup={true} closePopup={closePopupMock} handleAddStation={handleAddStationMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
// Click the "Close Modal" button inside the mock
|
||||
fireEvent.click(screen.getByText("Close Modal"));
|
||||
expect(closePopupMock).toHaveBeenCalledTimes(0); // Should not call the popup close
|
||||
});
|
||||
});
|
||||
75
__tests__/unit/pois/AddPoiModalWindowWrapper.test.js
Normal file
75
__tests__/unit/pois/AddPoiModalWindowWrapper.test.js
Normal file
@@ -0,0 +1,75 @@
|
||||
// __tests__/components/pois/AddPoiModalWindowWrapper.test.js
|
||||
|
||||
import React from "react";
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import AddPoiModalWindowWrapper from "../../../components/pois/AddPoiModalWindowWrapper";
|
||||
|
||||
// Mock the AddPoiModalWindow component to avoid testing its internal implementation here
|
||||
jest.mock("../../../components/pois/AddPoiModalWindow", () => ({ onClose, onSubmit, latlng }) => (
|
||||
<div data-testid="add-poi-modal-window">
|
||||
<button onClick={onClose}>Mocked Close</button>
|
||||
<button onClick={onSubmit}>Mocked Submit</button>
|
||||
<div>
|
||||
Mocked Coordinates: {latlng.lat}, {latlng.lng}
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
describe("AddPoiModalWindowWrapper", () => {
|
||||
const onCloseMock = jest.fn();
|
||||
const handleAddStationMock = jest.fn();
|
||||
const latlngMock = { lat: 52.52, lng: 13.405 };
|
||||
|
||||
beforeEach(() => {
|
||||
onCloseMock.mockClear();
|
||||
handleAddStationMock.mockClear();
|
||||
});
|
||||
|
||||
test("renders the modal when 'show' is true", () => {
|
||||
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||
|
||||
// Check if the modal and its contents are in the document
|
||||
expect(screen.getByTestId("add-poi-modal-window")).toBeInTheDocument();
|
||||
expect(screen.getByText("Mocked Coordinates: 52.52, 13.405")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("does not render the modal when 'show' is false", () => {
|
||||
render(<AddPoiModalWindowWrapper show={false} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||
|
||||
// Check if the modal is not in the document
|
||||
expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("calls onClose when the close button is clicked", () => {
|
||||
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||
|
||||
// Click the close button
|
||||
fireEvent.click(screen.getByRole("button", { name: "Close" }));
|
||||
expect(onCloseMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test("calls onClose when the background is clicked", () => {
|
||||
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||
|
||||
// Click the background overlay
|
||||
fireEvent.click(screen.getByTestId("modal-overlay"));
|
||||
expect(onCloseMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test("does not call onClose when the modal content is clicked", () => {
|
||||
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||
|
||||
// Click the modal content
|
||||
fireEvent.click(screen.getByRole("dialog"));
|
||||
expect(onCloseMock).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test("calls handleAddStation when the submit button is clicked", () => {
|
||||
render(<AddPoiModalWindowWrapper show={true} onClose={onCloseMock} handleAddStation={handleAddStationMock} latlng={latlngMock} />);
|
||||
|
||||
// Click the submit button
|
||||
fireEvent.click(screen.getByText("Mocked Submit"));
|
||||
expect(handleAddStationMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
117
__tests__/unit/pois/PoiUpdateModal.test.js
Normal file
117
__tests__/unit/pois/PoiUpdateModal.test.js
Normal file
@@ -0,0 +1,117 @@
|
||||
// __tests__/components/pois/PoiUpdateModal.test.js
|
||||
|
||||
import React from "react";
|
||||
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import PoiUpdateModal from "../../../components/pois/PoiUpdateModal";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { selectedPoiState, currentPoiState } from "../../../store/atoms/poiState";
|
||||
|
||||
// Mock the recoil states
|
||||
jest.mock("recoil");
|
||||
|
||||
describe("PoiUpdateModal", () => {
|
||||
const mockOnClose = jest.fn();
|
||||
const mockOnSubmit = jest.fn();
|
||||
const poiDataMock = {
|
||||
idPoi: "123",
|
||||
name: "Test POI",
|
||||
description: "Test Description",
|
||||
idPoiTyp: "1",
|
||||
idLD: "2",
|
||||
};
|
||||
|
||||
const selectedPoiMock = {
|
||||
idPoi: "123",
|
||||
typ: "Type1",
|
||||
};
|
||||
|
||||
const currentPoiMock = {
|
||||
idLD: "2",
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
useRecoilValue.mockImplementation((state) => {
|
||||
if (state === selectedPoiState) return selectedPoiMock;
|
||||
if (state === currentPoiState) return currentPoiMock;
|
||||
});
|
||||
|
||||
mockOnClose.mockClear();
|
||||
mockOnSubmit.mockClear();
|
||||
|
||||
global.fetch = jest.fn((url) => {
|
||||
if (url === "/api/talas_v5_DB/poiTyp/readPoiTyp") {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]),
|
||||
});
|
||||
} else if (url === "/api/talas_v5_DB/locationDevice/locationDevices") {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve([{ id: "2", name: "Device1" }]),
|
||||
});
|
||||
} else if (url.startsWith("/api/talas_v5_DB/locationDevice/getDeviceId")) {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve({ idLD: "2", name: "Device1" }),
|
||||
});
|
||||
} else if (url.startsWith("/api/talas_v5_DB/pois/deletePoi")) {
|
||||
return Promise.resolve({ ok: true });
|
||||
} else if (url === "/api/talas_v5_DB/pois/updatePoi") {
|
||||
return Promise.resolve({ ok: true });
|
||||
}
|
||||
});
|
||||
|
||||
global.alert = jest.fn(); // Mock alert
|
||||
delete window.location;
|
||||
window.location = { reload: jest.fn() }; // Mock location.reload
|
||||
});
|
||||
|
||||
test("renders modal with correct data", async () => {
|
||||
await act(async () => {
|
||||
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||
});
|
||||
|
||||
expect(screen.getByDisplayValue("Test Description")).toBeInTheDocument();
|
||||
expect(screen.getByDisplayValue("Device1")).toBeInTheDocument();
|
||||
expect(screen.getByDisplayValue("Type1")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("handles POI update submission", async () => {
|
||||
await act(async () => {
|
||||
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||
});
|
||||
|
||||
fireEvent.change(screen.getByLabelText("Beschreibung:"), { target: { value: "Updated Description" } });
|
||||
fireEvent.click(screen.getByText("POI aktualisieren"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(global.fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/updatePoi", expect.any(Object));
|
||||
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
test("handles POI deletion", async () => {
|
||||
window.confirm = jest.fn().mockImplementation(() => true); // Mock confirm dialog to always accept
|
||||
|
||||
await act(async () => {
|
||||
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText("POI löschen"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(global.fetch).toHaveBeenCalledWith(expect.stringContaining("/api/talas_v5_DB/pois/deletePoi"), { method: "DELETE" });
|
||||
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||
expect(window.location.reload).toHaveBeenCalledTimes(1);
|
||||
expect(global.alert).toHaveBeenCalledWith("POI wurde erfolgreich gelöscht.");
|
||||
});
|
||||
});
|
||||
|
||||
test("closes the modal when the close button is clicked", async () => {
|
||||
await act(async () => {
|
||||
render(<PoiUpdateModal onClose={mockOnClose} poiData={poiDataMock} onSubmit={mockOnSubmit} />);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByLabelText("Close"));
|
||||
|
||||
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
57
__tests__/unit/pois/PoiUpdateModalWindow.test.js
Normal file
57
__tests__/unit/pois/PoiUpdateModalWindow.test.js
Normal file
@@ -0,0 +1,57 @@
|
||||
// __tests__/components/pois/PoiUpdateModalWindow.test.js
|
||||
|
||||
import React from "react";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import PoiUpdateModalWindow from "../../../components/pois/PoiUpdateModalWindow";
|
||||
import PoiUpdateModal from "../../../components/pois/PoiUpdateModal";
|
||||
|
||||
// Mock the PoiUpdateModal component to avoid testing its internal implementation here
|
||||
jest.mock("../../../components/pois/PoiUpdateModal", () => ({ onClose, poiData, onSubmit, latlng }) => (
|
||||
<div data-testid="poi-update-modal">
|
||||
<button onClick={onClose}>Close</button>
|
||||
<div>POI Data: {poiData ? poiData.name : "No Data"}</div>
|
||||
<div>LatLng: {latlng ? `${latlng.lat}, ${latlng.lng}` : "No Coordinates"}</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
describe("PoiUpdateModalWindow", () => {
|
||||
const closePoiUpdateModalMock = jest.fn();
|
||||
const currentPoiDataMock = {
|
||||
idPoi: "123",
|
||||
name: "Test POI",
|
||||
description: "Test Description",
|
||||
idPoiTyp: "1",
|
||||
idLD: "2",
|
||||
};
|
||||
|
||||
const popupCoordinatesMock = { lat: 52.52, lng: 13.405 };
|
||||
|
||||
beforeEach(() => {
|
||||
closePoiUpdateModalMock.mockClear();
|
||||
});
|
||||
|
||||
test("renders PoiUpdateModal when showPoiUpdateModal is true", () => {
|
||||
render(<PoiUpdateModalWindow showPoiUpdateModal={true} closePoiUpdateModal={closePoiUpdateModalMock} currentPoiData={currentPoiDataMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
// Check if the modal and its contents are in the document
|
||||
expect(screen.getByTestId("poi-update-modal")).toBeInTheDocument();
|
||||
expect(screen.getByText("POI Data: Test POI")).toBeInTheDocument();
|
||||
expect(screen.getByText("LatLng: 52.52, 13.405")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("does not render PoiUpdateModal when showPoiUpdateModal is false", () => {
|
||||
render(<PoiUpdateModalWindow showPoiUpdateModal={false} closePoiUpdateModal={closePoiUpdateModalMock} currentPoiData={currentPoiDataMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
// Check if the modal is not in the document
|
||||
expect(screen.queryByTestId("poi-update-modal")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("calls closePoiUpdateModal when the close button is clicked", () => {
|
||||
render(<PoiUpdateModalWindow showPoiUpdateModal={true} closePoiUpdateModal={closePoiUpdateModalMock} currentPoiData={currentPoiDataMock} popupCoordinates={popupCoordinatesMock} />);
|
||||
|
||||
// Click the close button
|
||||
screen.getByText("Close").click();
|
||||
expect(closePoiUpdateModalMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
79
__tests__/unit/pois/PoiUpdateModalWrapper.test.js
Normal file
79
__tests__/unit/pois/PoiUpdateModalWrapper.test.js
Normal file
@@ -0,0 +1,79 @@
|
||||
// __tests__/components/pois/PoiUpdateModalWrapper.test.js
|
||||
|
||||
import React from "react";
|
||||
import { render, screen, fireEvent, act } from "@testing-library/react";
|
||||
import "@testing-library/jest-dom";
|
||||
import PoiUpdateModalWrapper from "../../../components/pois/PoiUpdateModalWrapper";
|
||||
import { useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import { currentPoiState, selectedPoiState } from "../../../store/atoms/poiState";
|
||||
import { poiReadFromDbTriggerAtom } from "../../../store/atoms/poiReadFromDbTriggerAtom";
|
||||
|
||||
// Mock Recoil hooks
|
||||
jest.mock("recoil");
|
||||
|
||||
describe("PoiUpdateModalWrapper", () => {
|
||||
const mockOnClose = jest.fn();
|
||||
const currentPoiMock = {
|
||||
idPoi: "123",
|
||||
name: "Test POI",
|
||||
description: "Test Description",
|
||||
idPoiTyp: "1",
|
||||
idLD: "2",
|
||||
};
|
||||
const latlngMock = { lat: 52.52, lng: 13.405 };
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock the recoil values
|
||||
useRecoilValue.mockImplementation((atom) => {
|
||||
if (atom === currentPoiState) return currentPoiMock;
|
||||
if (atom === poiReadFromDbTriggerAtom) return 0;
|
||||
});
|
||||
useSetRecoilState.mockImplementation(() => jest.fn());
|
||||
|
||||
mockOnClose.mockClear();
|
||||
|
||||
// Mock global fetch
|
||||
global.fetch = jest.fn((url) =>
|
||||
Promise.resolve({
|
||||
json: () => {
|
||||
if (url.includes("getDeviceIdById")) {
|
||||
return Promise.resolve({ idLD: "2", name: "Device1" });
|
||||
}
|
||||
if (url.includes("readPoiTyp")) {
|
||||
return Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]);
|
||||
}
|
||||
if (url.includes("locationDevices")) {
|
||||
return Promise.resolve([{ id: "2", name: "Device1" }]);
|
||||
}
|
||||
return Promise.resolve({});
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test("renders PoiUpdateModal when 'show' is true", async () => {
|
||||
await act(async () => {
|
||||
render(<PoiUpdateModalWrapper show={true} onClose={mockOnClose} latlng={latlngMock} />);
|
||||
});
|
||||
|
||||
// Check if the modal and its contents are in the document
|
||||
expect(screen.getByDisplayValue("Test Description")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("does not render PoiUpdateModal when 'show' is false", () => {
|
||||
render(<PoiUpdateModalWrapper show={false} onClose={mockOnClose} latlng={latlngMock} />);
|
||||
|
||||
// Check if the modal is not in the document
|
||||
expect(screen.queryByDisplayValue("Test POI")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("calls onClose when the modal close button is clicked", async () => {
|
||||
await act(async () => {
|
||||
render(<PoiUpdateModalWrapper show={true} onClose={mockOnClose} latlng={latlngMock} />);
|
||||
});
|
||||
|
||||
// Simulate closing the modal
|
||||
fireEvent.click(screen.getByLabelText("Close"));
|
||||
expect(mockOnClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
111
__tests__/unit/pois/PoiUtils.test.js
Normal file
111
__tests__/unit/pois/PoiUtils.test.js
Normal file
@@ -0,0 +1,111 @@
|
||||
// __tests__/components/pois/PoiUtils.test.js
|
||||
|
||||
import { createPoiMarkers, addMarkersToMap, updateLocationInDatabase } from "../../../components/pois/PoiUtils";
|
||||
|
||||
// Mock Leaflet
|
||||
jest.mock("leaflet", () => {
|
||||
const Leaflet = {
|
||||
marker: jest.fn((latlng, options) => ({
|
||||
addTo: jest.fn(),
|
||||
on: jest.fn(),
|
||||
options: options,
|
||||
getLatLng: jest.fn(() => ({
|
||||
lat: latlng[0],
|
||||
lng: latlng[1],
|
||||
})),
|
||||
})),
|
||||
icon: jest.fn((options) => options),
|
||||
};
|
||||
return Leaflet;
|
||||
});
|
||||
|
||||
describe("PoiUtils", () => {
|
||||
describe("createPoiMarkers", () => {
|
||||
it("should create markers with correct coordinates and icon", () => {
|
||||
const poiData = [
|
||||
{ idPoi: "1", latitude: 52.52, longitude: 13.405 },
|
||||
{ idPoi: "2", latitude: 48.8566, longitude: 2.3522 },
|
||||
];
|
||||
const iconPath = "path/to/icon.png";
|
||||
const markers = createPoiMarkers(poiData, iconPath);
|
||||
|
||||
expect(markers).toHaveLength(2);
|
||||
|
||||
markers.forEach((marker, index) => {
|
||||
expect(marker.options.icon.iconUrl).toBe(iconPath);
|
||||
expect(marker.options.icon.iconSize).toEqual([25, 41]);
|
||||
expect(marker.options.id).toBe(poiData[index].idPoi);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("addMarkersToMap", () => {
|
||||
it("should add markers to map and bind events", () => {
|
||||
const mockMap = {};
|
||||
const mockLayerGroup = { addLayer: jest.fn() };
|
||||
const mockMarker = {
|
||||
addTo: jest.fn(),
|
||||
on: jest.fn(),
|
||||
};
|
||||
|
||||
const markers = [mockMarker, mockMarker];
|
||||
|
||||
addMarkersToMap(markers, mockMap, mockLayerGroup);
|
||||
|
||||
markers.forEach((marker) => {
|
||||
expect(marker.addTo).toHaveBeenCalledWith(mockLayerGroup);
|
||||
expect(marker.on).toHaveBeenCalledWith("mouseover", expect.any(Function));
|
||||
expect(marker.on).toHaveBeenCalledWith("mouseout", expect.any(Function));
|
||||
expect(marker.on).toHaveBeenCalledWith("dragend", expect.any(Function));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("updateLocationInDatabase", () => {
|
||||
beforeEach(() => {
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({}),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should call fetch with correct parameters", async () => {
|
||||
const id = "1";
|
||||
const newLatitude = 52.52;
|
||||
const newLongitude = 13.405;
|
||||
|
||||
await updateLocationInDatabase(id, newLatitude, newLongitude);
|
||||
|
||||
expect(fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/updateLocation", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
latitude: newLatitude,
|
||||
longitude: newLongitude,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it("should log error when fetch response is not ok", async () => {
|
||||
console.error = jest.fn();
|
||||
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: false,
|
||||
json: () => Promise.resolve({}),
|
||||
})
|
||||
);
|
||||
|
||||
await updateLocationInDatabase("1", 52.52, 13.405);
|
||||
|
||||
expect(console.error).toHaveBeenCalledWith("Fehler beim Aktualisieren der Position");
|
||||
});
|
||||
});
|
||||
});
|
||||
6
__tests__/unit/utils/mapUtils.test.js
Normal file
6
__tests__/unit/utils/mapUtils.test.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// __tests__/utils/mapUtils.test.js
|
||||
describe("Dummy test suite", () => {
|
||||
test("dummy test", () => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user