diff --git a/backend/target_zone_estimation.py b/backend/target_zone_estimation.py index 5ec03b4..7c2ac68 100644 --- a/backend/target_zone_estimation.py +++ b/backend/target_zone_estimation.py @@ -16,7 +16,7 @@ async def handle_data_streaming(websocket): data = await asyncio.wait_for(websocket.receive_text(), timeout=0.1) parsed_data = json.loads(data) threshold = list(parsed_data.values())[0] - print(f"First value received: {threshold}") + print(f"Received data: {str(parsed_data)}") except asyncio.TimeoutError: pass except json.JSONDecodeError: diff --git a/frontend/src/App.js b/frontend/src/App.js index d1000fe..8f2b7b8 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -118,11 +118,14 @@ function App() { }; }, [reconnectWebsocket]); - function sendThresholdToBackend() { + function sendDataToBackend(data) { if (websocket.current && websocket.current.readyState === WebSocket.OPEN) { - const data = { threshold }; - websocket.current.send(JSON.stringify(data)); - console.log("Threshold sent to backend:", data); + if (typeof data !== "object") { + console.error(`Error: Invalid data type - expected an object, but found a ${typeof data}`) + } else { + websocket.current.send(JSON.stringify(data)); + console.log("Data sent to backend:", data); + } } else { console.error("WebSocket is not open"); } @@ -158,7 +161,7 @@ function App() { setMovingAverageFactor={setMovingAverageFactor} threshold={threshold} setThreshold={setThreshold} - sendThresholdToBackend={sendThresholdToBackend} + sendDataToBackend={sendDataToBackend} />
diff --git a/frontend/src/__tests__/App.test.js b/frontend/src/__tests__/App.test.js index 36d7508..eb15dba 100644 --- a/frontend/src/__tests__/App.test.js +++ b/frontend/src/__tests__/App.test.js @@ -159,7 +159,7 @@ describe("WebSocket in App Component", () => { consoleLogSpy.mockRestore(); }); - test("sendThresholdToBackend sends correct data", async () => { + test("sendDataToBackend sends correct data", async () => { const consoleLogSpy = jest.spyOn(console, "log"); render(); @@ -168,11 +168,15 @@ describe("WebSocket in App Component", () => { const thresholdInput = screen.getByTestId("threshold-input"); await userEvent.clear(thresholdInput); await userEvent.type(thresholdInput, "25"); + + const MFAInput = screen.getByTestId("moving-average-input"); + await userEvent.clear(MFAInput); + await userEvent.type(MFAInput, "20"); - const sendButton = screen.getByTestId("threshold-btn"); + const sendButton = screen.getByTestId("send-data-btn"); await userEvent.click(sendButton); - expect(consoleLogSpy).toHaveBeenCalledWith("Threshold sent to backend:", { threshold: 25 }); + expect(consoleLogSpy).toHaveBeenCalledWith("Data sent to backend:", { threshold: 25, movingAverageFactor: 20 }); consoleLogSpy.mockRestore(); }); diff --git a/frontend/src/__tests__/ResearcherToolbar.test.js b/frontend/src/__tests__/ResearcherToolbar.test.js new file mode 100644 index 0000000..a278337 --- /dev/null +++ b/frontend/src/__tests__/ResearcherToolbar.test.js @@ -0,0 +1,78 @@ +import { render, screen, fireEvent } from "@testing-library/react"; +import ResearcherToolbar from "../components/ResearcherToolbar"; +import { useState } from "react"; + +function Wrapper({ sendDataToBackend }) { + const [threshold, setThreshold] = useState(5); + const [movingAverageFactor, setMovingAverageFactor] = useState(10); + + return ( + + ); + } + +describe("ResearcherToolbar data submission", () => { + let sendDataToBackend; + + beforeEach(() => sendDataToBackend = jest.fn()); + + test("Submit sends only threshold when only threshold is changed", () => { + render(); + + const thresholdInput = screen.getByTestId("threshold-input"); + fireEvent.change(thresholdInput, { target: { value: "15" } }); + + const submitButton = screen.getByTestId("send-data-btn"); + fireEvent.click(submitButton); + + expect(sendDataToBackend).toHaveBeenCalledTimes(1); + expect(sendDataToBackend).toHaveBeenCalledWith({ threshold: 15 }); + }); + + test("Submit sends only movingAverageFactor when only MAF is changed", () => { + render(); + + const mafInput = screen.getByTestId("moving-average-input"); + fireEvent.change(mafInput, { target: { value: "20" } }); + + const submitButton = screen.getByTestId("send-data-btn"); + fireEvent.click(submitButton); + + expect(sendDataToBackend).toHaveBeenCalledTimes(1); + expect(sendDataToBackend).toHaveBeenCalledWith({ movingAverageFactor: 20 }); + }); + + test("Submit sends both values when both inputs are changed", () => { + render(); + + const thresholdInput = screen.getByTestId("threshold-input"); + const mafInput = screen.getByTestId("moving-average-input"); + + fireEvent.change(thresholdInput, { target: { value: "30" } }); + fireEvent.change(mafInput, { target: { value: "40" } }); + + const submitButton = screen.getByTestId("send-data-btn"); + fireEvent.click(submitButton); + + expect(sendDataToBackend).toHaveBeenCalledTimes(1); + expect(sendDataToBackend).toHaveBeenCalledWith({ + threshold: 30, + movingAverageFactor: 40, + }); + }); + + test("Submit does not send data when nothing has changed", () => { + render(); + + const submitButton = screen.getByTestId("send-data-btn"); + fireEvent.click(submitButton); + + expect(sendDataToBackend).not.toHaveBeenCalled(); + }); +}); diff --git a/frontend/src/components/ResearcherToolbar.js b/frontend/src/components/ResearcherToolbar.js index 4cd7143..dd5beea 100644 --- a/frontend/src/components/ResearcherToolbar.js +++ b/frontend/src/components/ResearcherToolbar.js @@ -1,5 +1,5 @@ import "./ResearcherToolbar.css"; -import { useRef } from "react"; +import { useRef, useState } from "react"; import ToastNotification from "./toast/Toast"; function ResearcherToolbar({ @@ -7,14 +7,18 @@ function ResearcherToolbar({ setMovingAverageFactor, threshold, setThreshold, - sendThresholdToBackend, + sendDataToBackend, }) { - const threshold_toast = useRef(null); + const toast = useRef(null); + const [sendThreshold, setSendThreshold] = useState(false); + const [sendMAF, setSendMAF] = useState(false); - function activateToast() { - threshold_toast.current.show({ severity: "success", summary: "Submitted", detail: "Threshold successfully submitted!" }); - } + function toastNotifyChanged(parameterName="") { + if (parameterName !== "") toast.current.show({ severity: "success", detail: `${parameterName} updated successfully!` }); + else toast.current.show({ severity: "warn", summary: "Warning:", detail: "There are no changes to sumbit." }); + } + return (

Researcher Toolbar

@@ -24,7 +28,10 @@ function ResearcherToolbar({ setMovingAverageFactor(Number(e.target.value))} + onChange={ (e) => { + setMovingAverageFactor(Number(e.target.value)); + setSendMAF(true); + }} className="tool-input" data-testid="moving-average-input" /> @@ -37,20 +44,37 @@ function ResearcherToolbar({ setThreshold(Number(e.target.value))} + onChange={(e) => { + setThreshold(Number(e.target.value)); + setSendThreshold(true); + }} className="tool-input" data-testid="threshold-input" />
- +