Merge branch 'develop'

This commit is contained in:
ISA
2024-11-28 15:07:02 +01:00
243 changed files with 15697 additions and 4208 deletions

View 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();
});
//--------------------------------------------------------------------------------
});

View 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.
*/

View File

@@ -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]);
});
});

View 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]);
});
});

View File

@@ -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],
}),
})
);
});
});

View 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
);
});
});

View 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
});
});
});

View 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
});
});

View 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);
});
});

View 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);
});
});

View 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);
});
});

View 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);
});
});

View 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");
});
});
});

View File

@@ -0,0 +1,6 @@
// __tests__/utils/mapUtils.test.js
describe("Dummy test suite", () => {
test("dummy test", () => {
expect(true).toBe(true);
});
});