diff --git a/include/hueplusplus/HueCommandAPI.h b/include/hueplusplus/HueCommandAPI.h index 63ddc96..ab747cd 100644 --- a/include/hueplusplus/HueCommandAPI.h +++ b/include/hueplusplus/HueCommandAPI.h @@ -119,6 +119,9 @@ public: //! \overload nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request) const; + //! \brief Combines path with api prefix and username + //! \returns "/api//" + std::string combinedPath(const std::string& path) const; private: struct TimeoutData { @@ -131,10 +134,6 @@ private: //! \returns \ref response if there is no error nlohmann::json HandleError(FileInfo fileInfo, const nlohmann::json& response) const; - //! \brief Combines path with api prefix and username - //! \returns "/api//" - std::string CombinedPath(const std::string& path) const; - private: std::string ip; int port; diff --git a/include/hueplusplus/StateTransaction.h b/include/hueplusplus/StateTransaction.h index bd397a6..1030cb8 100644 --- a/include/hueplusplus/StateTransaction.h +++ b/include/hueplusplus/StateTransaction.h @@ -26,6 +26,7 @@ #include #include "HueCommandAPI.h" +#include "Schedule.h" #include "json/json.hpp" @@ -64,6 +65,10 @@ public: //! \throws nlohmann::json::parse_error when response could not be parsed bool commit(bool trimRequest = true) &&; + //! \brief Create a ScheduleCommand from the transaction + //! \returns A ScheduleCommand that can be used to execute this transaction on a Schedule. + ScheduleCommand toScheduleCommand() &&; + //! \brief Turn light on or off. //! \param on true for on, false for off //! \returns This transaction for chaining calls diff --git a/src/HueCommandAPI.cpp b/src/HueCommandAPI.cpp index 4ae7986..f5d80e5 100644 --- a/src/HueCommandAPI.cpp +++ b/src/HueCommandAPI.cpp @@ -81,7 +81,7 @@ nlohmann::json HueCommandAPI::PUTRequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() { - return httpHandler->PUTJson(CombinedPath(path), request, ip, port); + return httpHandler->PUTJson(combinedPath(path), request, ip, port); })); } @@ -94,7 +94,7 @@ nlohmann::json HueCommandAPI::GETRequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() { - return httpHandler->GETJson(CombinedPath(path), request, ip, port); + return httpHandler->GETJson(combinedPath(path), request, ip, port); })); } @@ -107,7 +107,7 @@ nlohmann::json HueCommandAPI::DELETERequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() { - return httpHandler->DELETEJson(CombinedPath(path), request, ip, port); + return httpHandler->DELETEJson(combinedPath(path), request, ip, port); })); } @@ -120,7 +120,7 @@ nlohmann::json HueCommandAPI::POSTRequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() { - return httpHandler->POSTJson(CombinedPath(path), request, ip, port); + return httpHandler->POSTJson(combinedPath(path), request, ip, port); })); } @@ -143,7 +143,7 @@ nlohmann::json HueCommandAPI::HandleError(FileInfo fileInfo, const nlohmann::jso return response; } -std::string HueCommandAPI::CombinedPath(const std::string& path) const +std::string HueCommandAPI::combinedPath(const std::string& path) const { std::string result = "/api/"; result.append(username); diff --git a/src/StateTransaction.cpp b/src/StateTransaction.cpp index 4e6efcb..8661098 100644 --- a/src/StateTransaction.cpp +++ b/src/StateTransaction.cpp @@ -68,6 +68,12 @@ bool StateTransaction::commit(bool trimRequest) && return true; } +ScheduleCommand StateTransaction::toScheduleCommand() && +{ + nlohmann::json command {{"method", "PUT"}, {"address", commands.combinedPath(path)}, {"body", request}}; + return ScheduleCommand(command); +} + StateTransaction&& StateTransaction::setOn(bool on) && { request["on"] = on; diff --git a/test/test_StateTransaction.cpp b/test/test_StateTransaction.cpp index 28aa2e6..1c2751e 100644 --- a/test/test_StateTransaction.cpp +++ b/test/test_StateTransaction.cpp @@ -49,6 +49,32 @@ TEST(StateTransaction, commit) StateTransaction(commands, "/path", nlohmann::json::object()).setOn(false).setBrightness(100).commit()); Mock::VerifyAndClearExpectations(handler.get()); } + // Do not trim + { + const nlohmann::json request = {{"on", false}, {"bri", 100}}; + const nlohmann::json state = {{"on", false}, {"bri", 100}}; + nlohmann::json response = {{{"success", {{"/path/on", false}}}}, {{"success", {{"/path/bri", 100}}}}}; + EXPECT_CALL(*handler, PUTJson(requestPath, request, getBridgeIp(), getBridgePort())).WillOnce(Return(response)); + EXPECT_TRUE(StateTransaction(commands, "/path", state).setOn(false).setBrightness(100).commit(false)); + Mock::VerifyAndClearExpectations(handler.get()); + } +} + +TEST(StateTransaction, toScheduleCommand) +{ + auto handler = std::make_shared(); + HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + const std::string requestPath = "/api/" + getBridgeUsername() + "/path"; + nlohmann::json request = {{"on", false}, {"bri", 100}}; + + ScheduleCommand command = StateTransaction(commands, "/path", nlohmann::json::object()) + .setOn(false) + .setBrightness(100) + .toScheduleCommand(); + Mock::VerifyAndClearExpectations(handler.get()); + EXPECT_EQ(ScheduleCommand::Method::put, command.getMethod()); + EXPECT_EQ(request, command.getBody()); + EXPECT_EQ(requestPath, command.getAddress()); } TEST(StateTransaction, setOn)