From df5289cc38a268c06a020f20dec1372e33b94b6c Mon Sep 17 00:00:00 2001 From: ISA Date: Fri, 6 Dec 2024 14:18:05 +0100 Subject: [PATCH] MAP_VERSION = "1.0.12" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: Integrationstest für openInNewTab erfolgreich implementiert - Mocking für Leaflet-Objekte (Marker, Polyline) erstellt. - Tests hinzugefügt, die sicherstellen: - Marker-Links werden korrekt generiert und geöffnet. - Polyline-Links werden korrekt generiert und geöffnet. - Fehler ausgegeben werden, wenn kein gültiger Link gefunden wird. - Jest-Konfiguration angepasst, um globale Objekte wie window zu mocken. - Funktionalität und Tests erfolgreich überprüft. --- __mocks__/leaflet.js | 23 ---- __tests__/MapComponent.test.js | 89 ------------- __tests__/unit/components/DataSheet.test.js | 82 ------------ .../unit/components/MapComponent.test.js | 89 ------------- .../gisPolylines/icons/CircleIcon.test.js | 40 ------ .../gisPolylines/icons/EndIcon.test.js | 24 ---- .../gisPolylines/icons/StartIcon.test.js | 41 ------ __tests__/unit/hooks/useLineData.test.js | 42 ------- __tests__/unit/pois/AddPoiModalWindow.test.js | 86 ------------- .../unit/pois/AddPoiModalWindowPopup.test.js | 77 ------------ .../pois/AddPoiModalWindowWrapper.test.js | 75 ----------- __tests__/unit/pois/PoiUpdateModal.test.js | 117 ------------------ .../unit/pois/PoiUpdateModalWindow.test.js | 57 --------- .../unit/pois/PoiUpdateModalWrapper.test.js | 79 ------------ __tests__/unit/pois/PoiUtils.test.js | 111 ----------------- __tests__/unit/utils/mapUtils.test.js | 6 - config/settings.js | 2 +- utils/openInNewTab.js | 3 +- utils/openInNewTab.test.js | 54 ++++++++ 19 files changed, 57 insertions(+), 1040 deletions(-) delete mode 100644 __mocks__/leaflet.js delete mode 100644 __tests__/MapComponent.test.js delete mode 100644 __tests__/unit/components/DataSheet.test.js delete mode 100644 __tests__/unit/components/MapComponent.test.js delete mode 100644 __tests__/unit/components/gisPolylines/icons/CircleIcon.test.js delete mode 100644 __tests__/unit/components/gisPolylines/icons/EndIcon.test.js delete mode 100644 __tests__/unit/components/gisPolylines/icons/StartIcon.test.js delete mode 100644 __tests__/unit/hooks/useLineData.test.js delete mode 100644 __tests__/unit/pois/AddPoiModalWindow.test.js delete mode 100644 __tests__/unit/pois/AddPoiModalWindowPopup.test.js delete mode 100644 __tests__/unit/pois/AddPoiModalWindowWrapper.test.js delete mode 100644 __tests__/unit/pois/PoiUpdateModal.test.js delete mode 100644 __tests__/unit/pois/PoiUpdateModalWindow.test.js delete mode 100644 __tests__/unit/pois/PoiUpdateModalWrapper.test.js delete mode 100644 __tests__/unit/pois/PoiUtils.test.js delete mode 100644 __tests__/unit/utils/mapUtils.test.js create mode 100644 utils/openInNewTab.test.js diff --git a/__mocks__/leaflet.js b/__mocks__/leaflet.js deleted file mode 100644 index 2ef6e4a0a..000000000 --- a/__mocks__/leaflet.js +++ /dev/null @@ -1,23 +0,0 @@ -// __mocks__/leaflet.js -const L = { - divIcon: jest.fn(() => new L.DivIcon()), - DivIcon: function () { - this.options = { - className: "custom-start-icon", - html: ` - - - - - `, - iconSize: [18, 18], - iconAnchor: [9, 10], - }; - }, -}; - -L.DivIcon.prototype = { - constructor: L.DivIcon, -}; - -module.exports = L; diff --git a/__tests__/MapComponent.test.js b/__tests__/MapComponent.test.js deleted file mode 100644 index ea9be1af6..000000000 --- a/__tests__/MapComponent.test.js +++ /dev/null @@ -1,89 +0,0 @@ -// __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. -*/ diff --git a/__tests__/unit/components/DataSheet.test.js b/__tests__/unit/components/DataSheet.test.js deleted file mode 100644 index f390de883..000000000 --- a/__tests__/unit/components/DataSheet.test.js +++ /dev/null @@ -1,82 +0,0 @@ -// __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( - - - - ); - - // 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( - - - - ); - 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( - - - - ); - 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(); - }); - - //-------------------------------------------------------------------------------- -}); diff --git a/__tests__/unit/components/MapComponent.test.js b/__tests__/unit/components/MapComponent.test.js deleted file mode 100644 index ea9be1af6..000000000 --- a/__tests__/unit/components/MapComponent.test.js +++ /dev/null @@ -1,89 +0,0 @@ -// __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. -*/ diff --git a/__tests__/unit/components/gisPolylines/icons/CircleIcon.test.js b/__tests__/unit/components/gisPolylines/icons/CircleIcon.test.js deleted file mode 100644 index efc9e485e..000000000 --- a/__tests__/unit/components/gisPolylines/icons/CircleIcon.test.js +++ /dev/null @@ -1,40 +0,0 @@ -// __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: '
', - iconSize: [25, 25], - iconAnchor: [5, 5], - }), - }) - ); - expect(CircleIcon.options.className).toContain("custom-circle-icon"); - expect(CircleIcon.options.html).toContain(" { - 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("
"); - expect(EndIcon.options.iconSize).toEqual([14, 14]); - expect(EndIcon.options.iconAnchor).toEqual([7, 7]); - }); -}); diff --git a/__tests__/unit/components/gisPolylines/icons/StartIcon.test.js b/__tests__/unit/components/gisPolylines/icons/StartIcon.test.js deleted file mode 100644 index 2769119ea..000000000 --- a/__tests__/unit/components/gisPolylines/icons/StartIcon.test.js +++ /dev/null @@ -1,41 +0,0 @@ -// __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(" { - 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 - ); - }); -}); diff --git a/__tests__/unit/pois/AddPoiModalWindow.test.js b/__tests__/unit/pois/AddPoiModalWindow.test.js deleted file mode 100644 index 5a95b654f..000000000 --- a/__tests__/unit/pois/AddPoiModalWindow.test.js +++ /dev/null @@ -1,86 +0,0 @@ -// __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( - - - - ); - }); - - // Ü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 - }); - }); -}); diff --git a/__tests__/unit/pois/AddPoiModalWindowPopup.test.js b/__tests__/unit/pois/AddPoiModalWindowPopup.test.js deleted file mode 100644 index e55327219..000000000 --- a/__tests__/unit/pois/AddPoiModalWindowPopup.test.js +++ /dev/null @@ -1,77 +0,0 @@ -// __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 }) => ( -
- - -
- Coordinates: {latlng.lat}, {latlng.lng} -
-
-)); - -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(); - - 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(); - - expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument(); - }); - - test("closes the popup when the top right close button is clicked", () => { - render(); - - // 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(); - - 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(); - - // Click the "Close Modal" button inside the mock - fireEvent.click(screen.getByText("Close Modal")); - expect(closePopupMock).toHaveBeenCalledTimes(0); // Should not call the popup close - }); -}); diff --git a/__tests__/unit/pois/AddPoiModalWindowWrapper.test.js b/__tests__/unit/pois/AddPoiModalWindowWrapper.test.js deleted file mode 100644 index c8fddf41b..000000000 --- a/__tests__/unit/pois/AddPoiModalWindowWrapper.test.js +++ /dev/null @@ -1,75 +0,0 @@ -// __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 }) => ( -
- - -
- Mocked Coordinates: {latlng.lat}, {latlng.lng} -
-
-)); - -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(); - - // 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(); - - // 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(); - - // Click the close button - fireEvent.click(screen.getByRole("button", { name: "Close" })); - expect(onCloseMock).toHaveBeenCalledTimes(1); - }); - - test("calls onClose when the background is clicked", () => { - render(); - - // 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(); - - // Click the modal content - fireEvent.click(screen.getByRole("dialog")); - expect(onCloseMock).toHaveBeenCalledTimes(0); - }); - - test("calls handleAddStation when the submit button is clicked", () => { - render(); - - // Click the submit button - fireEvent.click(screen.getByText("Mocked Submit")); - expect(handleAddStationMock).toHaveBeenCalledTimes(1); - }); -}); diff --git a/__tests__/unit/pois/PoiUpdateModal.test.js b/__tests__/unit/pois/PoiUpdateModal.test.js deleted file mode 100644 index b99db4dfd..000000000 --- a/__tests__/unit/pois/PoiUpdateModal.test.js +++ /dev/null @@ -1,117 +0,0 @@ -// __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(); - }); - - 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(); - }); - - 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(); - }); - - 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(); - }); - - fireEvent.click(screen.getByLabelText("Close")); - - expect(mockOnClose).toHaveBeenCalledTimes(1); - }); -}); diff --git a/__tests__/unit/pois/PoiUpdateModalWindow.test.js b/__tests__/unit/pois/PoiUpdateModalWindow.test.js deleted file mode 100644 index 8ad912330..000000000 --- a/__tests__/unit/pois/PoiUpdateModalWindow.test.js +++ /dev/null @@ -1,57 +0,0 @@ -// __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 }) => ( -
- -
POI Data: {poiData ? poiData.name : "No Data"}
-
LatLng: {latlng ? `${latlng.lat}, ${latlng.lng}` : "No Coordinates"}
-
-)); - -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(); - - // 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(); - - // 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(); - - // Click the close button - screen.getByText("Close").click(); - expect(closePoiUpdateModalMock).toHaveBeenCalledTimes(1); - }); -}); diff --git a/__tests__/unit/pois/PoiUpdateModalWrapper.test.js b/__tests__/unit/pois/PoiUpdateModalWrapper.test.js deleted file mode 100644 index 034550342..000000000 --- a/__tests__/unit/pois/PoiUpdateModalWrapper.test.js +++ /dev/null @@ -1,79 +0,0 @@ -// __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(); - }); - - // 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(); - - // 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(); - }); - - // Simulate closing the modal - fireEvent.click(screen.getByLabelText("Close")); - expect(mockOnClose).toHaveBeenCalledTimes(1); - }); -}); diff --git a/__tests__/unit/pois/PoiUtils.test.js b/__tests__/unit/pois/PoiUtils.test.js deleted file mode 100644 index 85bafff99..000000000 --- a/__tests__/unit/pois/PoiUtils.test.js +++ /dev/null @@ -1,111 +0,0 @@ -// __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"); - }); - }); -}); diff --git a/__tests__/unit/utils/mapUtils.test.js b/__tests__/unit/utils/mapUtils.test.js deleted file mode 100644 index b72a59f6f..000000000 --- a/__tests__/unit/utils/mapUtils.test.js +++ /dev/null @@ -1,6 +0,0 @@ -// __tests__/utils/mapUtils.test.js -describe("Dummy test suite", () => { - test("dummy test", () => { - expect(true).toBe(true); - }); -}); diff --git a/config/settings.js b/config/settings.js index 72e20cbbd..96119f494 100644 --- a/config/settings.js +++ b/config/settings.js @@ -1,5 +1,5 @@ // /config/settings.js // Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte -export const MAP_VERSION = "1.0.11"; +export const MAP_VERSION = "1.0.12"; //export const STANDARD_SIDE_MENU = true; //export const FULL_SIDE_MENU = false; diff --git a/utils/openInNewTab.js b/utils/openInNewTab.js index 83037f49c..b693ceb27 100644 --- a/utils/openInNewTab.js +++ b/utils/openInNewTab.js @@ -3,7 +3,7 @@ export function openInNewTab(e, target) { const url = new URL(window.location.origin); const originWithoutPort = `${url.protocol}//${url.hostname}`; // Protokoll und Hostname, ohne Port - const BASE_URL = originWithoutPort; + let link; // Prüfen, ob der Kontextmenü-Eintrag aufgerufen wird, ohne dass ein Marker oder Polyline direkt angesprochen wird @@ -17,6 +17,7 @@ export function openInNewTab(e, target) { if (target instanceof L.Marker && target.options.link) { link = `${originWithoutPort}/talas5/devices/${target.options.link}`; + console.log("Link des Markers", link); } else if (target instanceof L.Polyline) { const idLD = target.options.idLD; console.log("idLD der Linie", idLD); diff --git a/utils/openInNewTab.test.js b/utils/openInNewTab.test.js new file mode 100644 index 000000000..e82fa7e8e --- /dev/null +++ b/utils/openInNewTab.test.js @@ -0,0 +1,54 @@ +// utils/openInNewTab.test.js +import { openInNewTab } from "./openInNewTab"; + +// Leaflet manuell mocken +global.L = { + Marker: class { + constructor(options) { + this.options = options || {}; + } + }, + Polyline: class { + constructor(options) { + this.options = options || {}; + } + }, +}; + +describe("Integrationstest für openInNewTab", () => { + const mockWindowOpen = jest.fn(); + + beforeAll(() => { + global.window = Object.create(window); + window.open = mockWindowOpen; + delete window.location; + window.location = new URL("http://10.10.0.13"); + }); + + afterEach(() => { + mockWindowOpen.mockClear(); + }); + + it("soll den Link korrekt für einen Marker öffnen", () => { + const marker = new L.Marker({ link: "cpl.aspx?ver=35&kue=24&id=50922" }); + openInNewTab(null, marker); + + expect(mockWindowOpen).toHaveBeenCalledWith("http://10.10.0.13/talas5/devices/cpl.aspx?ver=35&kue=24&id=50922", "_blank"); + }); + + it("soll den Link korrekt für eine Polyline öffnen", () => { + const polyline = new L.Polyline({ idLD: 50922 }); + openInNewTab(null, polyline); + + expect(mockWindowOpen).toHaveBeenCalledWith("http://10.10.0.13/talas5/devices/cpl.aspx?id=50922", "_blank"); + }); + + it("soll einen Fehler ausgeben, wenn kein Link gefunden wird", () => { + console.error = jest.fn(); + + openInNewTab(); + + expect(console.error).toHaveBeenCalledWith("Fehler: Es wurde kein gültiger Link gefunden."); + expect(mockWindowOpen).not.toHaveBeenCalled(); + }); +});