// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include #include #include #include #include #include #include "../detector_control/DectrisSimplonClient.h" // A minimal SIMPLON server: the detector state and error list, and a disarm command that fails. TEST_CASE("DectrisSimplonClient_MockServer", "[detector]") { httplib::Server server; std::mutex m; std::set client_ports; std::string state = "idle"; server.Get("/detector/api/1.8.0/status/state", [&](const httplib::Request &req, httplib::Response &res) { std::lock_guard lg(m); client_ports.insert(req.remote_port); if (state == "unavailable") { res.status = 503; res.set_content("DCU busy", "text/plain"); } else res.set_content(nlohmann::json{{"value", state}}.dump(), "application/json"); }); server.Get("/detector/api/1.8.0/status/error", [&](const httplib::Request &, httplib::Response &res) { res.set_content(nlohmann::json{{"value", {"overheating"}}}.dump(), "application/json"); }); server.Post("/detector/api/1.8.0/command/disarm", [&](const httplib::Request &, httplib::Response &res) { res.status = 500; res.set_content("disarm refused", "text/plain"); }); const int port = server.bind_to_any_port("127.0.0.1"); REQUIRE(port > 0); struct ServerThread { httplib::Server &server; std::thread thread; explicit ServerThread(httplib::Server &s) : server(s), thread([&s] { s.listen_after_bind(); }) {} ~ServerThread() { server.stop(); thread.join(); } } server_thread(server); server.wait_until_ready(); DectrisSimplonClient client("127.0.0.1", port); // Repeated polling reuses one connection instead of opening a new one per request for (int i = 0; i < 10; i++) REQUIRE(client.GetState() == SimplonState::Idle); CHECK(client_ports.size() == 1); CHECK(client.GetErrorStatus() == R"(["overheating"])"); // Failures carry the HTTP status and the body the DCU sent { std::lock_guard lg(m); state = "unavailable"; } REQUIRE_THROWS_WITH(client.GetState(), Catch::Matchers::ContainsSubstring("HTTP503") && Catch::Matchers::ContainsSubstring("DCU busy")); REQUIRE_THROWS_WITH(client.EndAcquisitionFinished(), Catch::Matchers::ContainsSubstring("HTTP500") && Catch::Matchers::ContainsSubstring("disarm refused")); }