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"
/>
-
+