Commit 0b28967aa4b875c627b521fb94313df82d3aff5b
Committed by
Moritz Wirger
1 parent
765b3315
Add tests for rule, fix bugs.
Showing
6 changed files
with
313 additions
and
34 deletions
include/hueplusplus/Rule.h
| ... | ... | @@ -141,6 +141,10 @@ private: |
| 141 | 141 | class CreateRule |
| 142 | 142 | { |
| 143 | 143 | public: |
| 144 | + //! \brief Construct with necessary parameters | |
| 145 | + //! \param conditions Conditions for the rule. Must not be empty | |
| 146 | + //! \param actions Actions for the rule. Must not be empty | |
| 147 | + CreateRule(const std::vector<Condition>& conditions, const std::vector<Action>& actions); | |
| 144 | 148 | //! \brief Set name |
| 145 | 149 | //! \see Rule::setName |
| 146 | 150 | CreateRule& setName(const std::string& name); |
| ... | ... | @@ -149,13 +153,6 @@ public: |
| 149 | 153 | //! \see Rule::setEnabled |
| 150 | 154 | CreateRule& setStatus(bool enabled); |
| 151 | 155 | |
| 152 | - //! \brief Set conditions | |
| 153 | - //! \see Rule::setConditions | |
| 154 | - CreateRule& setConditions(const std::vector<Condition>& conditions); | |
| 155 | - //! \brief Set actions | |
| 156 | - //! \see Rule::setActions | |
| 157 | - CreateRule& setActions(const std::vector<Action>& actions); | |
| 158 | - | |
| 159 | 156 | //! \brief Get request to create the rule. |
| 160 | 157 | //! \returns JSON request for a POST to create the new rule. |
| 161 | 158 | nlohmann::json getRequest() const; | ... | ... |
include/hueplusplus/TimePattern.h
| ... | ... | @@ -85,7 +85,7 @@ public: |
| 85 | 85 | |
| 86 | 86 | //! \brief Get formatted string as expected by Hue API |
| 87 | 87 | //! \returns Timestamp in the format |
| 88 | - //! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code> | |
| 88 | + //! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code> in local timezone | |
| 89 | 89 | std::string toString() const; |
| 90 | 90 | |
| 91 | 91 | //! \brief Parse AbsoluteTime from formatted string in local timezone | ... | ... |
src/CMakeLists.txt
| 1 | 1 | set(hueplusplus_SOURCES |
| 2 | + Action.cpp | |
| 2 | 3 | APICache.cpp |
| 3 | 4 | BaseDevice.cpp |
| 4 | 5 | BaseHttpHandler.cpp |
| 5 | 6 | Bridge.cpp |
| 6 | 7 | BridgeConfig.cpp |
| 8 | + CLIPSensors.cpp | |
| 7 | 9 | ColorUnits.cpp |
| 8 | 10 | ExtendedColorHueStrategy.cpp |
| 9 | 11 | ExtendedColorTemperatureStrategy.cpp |
| ... | ... | @@ -13,6 +15,8 @@ set(hueplusplus_SOURCES |
| 13 | 15 | HueException.cpp |
| 14 | 16 | Light.cpp |
| 15 | 17 | ModelPictures.cpp |
| 18 | + NewDeviceList.cpp | |
| 19 | + Rule.cpp | |
| 16 | 20 | Scene.cpp |
| 17 | 21 | Schedule.cpp |
| 18 | 22 | Sensor.cpp |
| ... | ... | @@ -22,7 +26,8 @@ set(hueplusplus_SOURCES |
| 22 | 26 | StateTransaction.cpp |
| 23 | 27 | TimePattern.cpp |
| 24 | 28 | UPnP.cpp |
| 25 | - Utils.cpp "ZLLSensors.cpp" "CLIPSensors.cpp" "NewDeviceList.cpp" "Action.cpp") | |
| 29 | + Utils.cpp | |
| 30 | + ZLLSensors.cpp) | |
| 26 | 31 | |
| 27 | 32 | # on windows we want to compile the WinHttpHandler |
| 28 | 33 | if(WIN32) | ... | ... |
src/Rule.cpp
| ... | ... | @@ -120,7 +120,7 @@ Condition Condition::parse(const nlohmann::json& json) |
| 120 | 120 | { |
| 121 | 121 | op = Operator::notIn; |
| 122 | 122 | } |
| 123 | - else | |
| 123 | + else if(opStr != "eq") | |
| 124 | 124 | { |
| 125 | 125 | throw HueException(CURRENT_FILE_INFO, "Unknown condition operator: " + opStr); |
| 126 | 126 | } |
| ... | ... | @@ -129,8 +129,10 @@ Condition Condition::parse(const nlohmann::json& json) |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | Rule::Rule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration) |
| 132 | - : id(id), state("/rules/" + id, commands, refreshDuration) | |
| 133 | -{ } | |
| 132 | + : id(id), state("/rules/" + std::to_string(id), commands, refreshDuration) | |
| 133 | +{ | |
| 134 | + state.refresh(); | |
| 135 | +} | |
| 134 | 136 | |
| 135 | 137 | void Rule::refresh(bool force) |
| 136 | 138 | { |
| ... | ... | @@ -163,12 +165,17 @@ void Rule::setName(const std::string& name) |
| 163 | 165 | |
| 164 | 166 | time::AbsoluteTime Rule::getCreated() const |
| 165 | 167 | { |
| 166 | - return time::AbsoluteTime::parseUTC(state.getValue().at("creationtime").get<std::string>()); | |
| 168 | + return time::AbsoluteTime::parseUTC(state.getValue().at("created").get<std::string>()); | |
| 167 | 169 | } |
| 168 | 170 | |
| 169 | 171 | time::AbsoluteTime Rule::getLastTriggered() const |
| 170 | 172 | { |
| 171 | - return time::AbsoluteTime::parseUTC(state.getValue().at("lasttriggered").get<std::string>()); | |
| 173 | + const std::string lasttriggered = state.getValue().value("lasttriggered", "none"); | |
| 174 | + if (lasttriggered.empty() || lasttriggered == "none") | |
| 175 | + { | |
| 176 | + return time::AbsoluteTime(std::chrono::system_clock::time_point(std::chrono::seconds(0))); | |
| 177 | + } | |
| 178 | + return time::AbsoluteTime::parseUTC(lasttriggered); | |
| 172 | 179 | } |
| 173 | 180 | |
| 174 | 181 | int Rule::getTimesTriggered() const |
| ... | ... | @@ -184,6 +191,7 @@ bool Rule::isEnabled() const |
| 184 | 191 | void Rule::setEnabled(bool enabled) |
| 185 | 192 | { |
| 186 | 193 | sendPutRequest({{"status", enabled ? "enabled" : "disabled"}}, CURRENT_FILE_INFO); |
| 194 | + refresh(true); | |
| 187 | 195 | } |
| 188 | 196 | |
| 189 | 197 | std::string Rule::getOwner() const |
| ... | ... | @@ -222,6 +230,7 @@ void Rule::setConditions(const std::vector<Condition>& conditions) |
| 222 | 230 | } |
| 223 | 231 | |
| 224 | 232 | sendPutRequest({{"conditions", json}}, CURRENT_FILE_INFO); |
| 233 | + refresh(true); | |
| 225 | 234 | } |
| 226 | 235 | |
| 227 | 236 | void Rule::setActions(const std::vector<Action>& actions) |
| ... | ... | @@ -233,26 +242,15 @@ void Rule::setActions(const std::vector<Action>& actions) |
| 233 | 242 | } |
| 234 | 243 | |
| 235 | 244 | sendPutRequest({{"actions", json}}, CURRENT_FILE_INFO); |
| 245 | + refresh(true); | |
| 236 | 246 | } |
| 237 | 247 | |
| 238 | 248 | nlohmann::json Rule::sendPutRequest(const nlohmann::json& request, FileInfo fileInfo) |
| 239 | 249 | { |
| 240 | - return state.getCommandAPI().PUTRequest("/groups/" + std::to_string(id), request, std::move(fileInfo)); | |
| 241 | -} | |
| 242 | - | |
| 243 | -CreateRule& CreateRule::setName(const std::string& name) | |
| 244 | -{ | |
| 245 | - request["name"] = name; | |
| 246 | - return *this; | |
| 250 | + return state.getCommandAPI().PUTRequest("/rules/" + std::to_string(id), request, std::move(fileInfo)); | |
| 247 | 251 | } |
| 248 | 252 | |
| 249 | -CreateRule& CreateRule::setStatus(bool enabled) | |
| 250 | -{ | |
| 251 | - request["status"] = enabled ? "enabled" : "disabled"; | |
| 252 | - return *this; | |
| 253 | -} | |
| 254 | - | |
| 255 | -CreateRule& CreateRule::setConditions(const std::vector<Condition>& conditions) | |
| 253 | +CreateRule::CreateRule(const std::vector<Condition>& conditions, const std::vector<Action>& actions) | |
| 256 | 254 | { |
| 257 | 255 | nlohmann::json conditionsJson; |
| 258 | 256 | for (const Condition& c : conditions) |
| ... | ... | @@ -260,17 +258,23 @@ CreateRule& CreateRule::setConditions(const std::vector<Condition>& conditions) |
| 260 | 258 | conditionsJson.push_back(c.toJson()); |
| 261 | 259 | } |
| 262 | 260 | request["conditions"] = conditionsJson; |
| 263 | - return *this; | |
| 264 | -} | |
| 265 | - | |
| 266 | -CreateRule& CreateRule::setActions(const std::vector<Action>& actions) | |
| 267 | -{ | |
| 268 | 261 | nlohmann::json actionsJson; |
| 269 | 262 | for (const Action& a : actions) |
| 270 | 263 | { |
| 271 | 264 | actionsJson.push_back(a.toJson()); |
| 272 | 265 | } |
| 273 | 266 | request["actions"] = actionsJson; |
| 267 | +} | |
| 268 | + | |
| 269 | +CreateRule& CreateRule::setName(const std::string& name) | |
| 270 | +{ | |
| 271 | + request["name"] = name; | |
| 272 | + return *this; | |
| 273 | +} | |
| 274 | + | |
| 275 | +CreateRule& CreateRule::setStatus(bool enabled) | |
| 276 | +{ | |
| 277 | + request["status"] = enabled ? "enabled" : "disabled"; | |
| 274 | 278 | return *this; |
| 275 | 279 | } |
| 276 | 280 | ... | ... |
test/CMakeLists.txt
| ... | ... | @@ -30,6 +30,7 @@ target_compile_features(gtest PUBLIC cxx_std_14) |
| 30 | 30 | |
| 31 | 31 | # define all test sources |
| 32 | 32 | set(TEST_SOURCES |
| 33 | + test_Action.cpp | |
| 33 | 34 | test_APICache.cpp |
| 34 | 35 | test_BaseDevice.cpp |
| 35 | 36 | test_BaseHttpHandler.cpp |
| ... | ... | @@ -44,8 +45,10 @@ set(TEST_SOURCES |
| 44 | 45 | test_Light.cpp |
| 45 | 46 | test_LightFactory.cpp |
| 46 | 47 | test_Main.cpp |
| 48 | + test_NewDeviceList.cpp | |
| 47 | 49 | test_UPnP.cpp |
| 48 | 50 | test_ResourceList.cpp |
| 51 | + test_Rule.cpp | |
| 49 | 52 | test_Scene.cpp |
| 50 | 53 | test_Schedule.cpp |
| 51 | 54 | test_Sensor.cpp |
| ... | ... | @@ -54,7 +57,7 @@ set(TEST_SOURCES |
| 54 | 57 | test_SimpleColorHueStrategy.cpp |
| 55 | 58 | test_SimpleColorTemperatureStrategy.cpp |
| 56 | 59 | test_StateTransaction.cpp |
| 57 | - test_TimePattern.cpp "test_NewDeviceList.cpp" "test_Action.cpp") | |
| 60 | + test_TimePattern.cpp) | |
| 58 | 61 | |
| 59 | 62 | set(HuePlusPlus_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include") |
| 60 | 63 | ... | ... |
test/test_Rule.cpp
0 โ 100644
| 1 | +/** | |
| 2 | + \file test_Rule.cpp | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2020 Jan Rogall - developer\n | |
| 5 | + | |
| 6 | + This file is part of hueplusplus. | |
| 7 | + | |
| 8 | + hueplusplus is free software: you can redistribute it and/or modify | |
| 9 | + it under the terms of the GNU Lesser General Public License as published by | |
| 10 | + the Free Software Foundation, either version 3 of the License, or | |
| 11 | + (at your option) any later version. | |
| 12 | + | |
| 13 | + hueplusplus is distributed in the hope that it will be useful, | |
| 14 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | + GNU Lesser General Public License for more details. | |
| 17 | + | |
| 18 | + You should have received a copy of the GNU Lesser General Public License | |
| 19 | + along with hueplusplus. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | +**/ | |
| 21 | + | |
| 22 | +#include <hueplusplus/Rule.h> | |
| 23 | + | |
| 24 | +#include <gtest/gtest.h> | |
| 25 | + | |
| 26 | +#include "testhelper.h" | |
| 27 | + | |
| 28 | +#include "mocks/mock_HttpHandler.h" | |
| 29 | + | |
| 30 | +using namespace hueplusplus; | |
| 31 | +using namespace testing; | |
| 32 | + | |
| 33 | +TEST(Condition, Constructor) | |
| 34 | +{ | |
| 35 | + const std::string address = "/api/abcd/test"; | |
| 36 | + const std::string value = "test value"; | |
| 37 | + Condition condition(address, Condition::Operator::eq, value); | |
| 38 | + EXPECT_EQ(address, condition.getAddress()); | |
| 39 | + EXPECT_EQ(Condition::Operator::eq, condition.getOperator()); | |
| 40 | + EXPECT_EQ(value, condition.getValue()); | |
| 41 | +} | |
| 42 | + | |
| 43 | +TEST(Condition, toJson) | |
| 44 | +{ | |
| 45 | + Condition condition("/abcd", Condition::Operator::lt, "3"); | |
| 46 | + EXPECT_EQ(nlohmann::json({{"address", "/abcd"}, {"operator", "lt"}, {"value", "3"}}), condition.toJson()); | |
| 47 | +} | |
| 48 | + | |
| 49 | +TEST(Condition, parse) | |
| 50 | +{ | |
| 51 | + Condition condition = Condition::parse(nlohmann::json({{"address", "/abcd"}, {"operator", "lt"}, {"value", "3"}})); | |
| 52 | + EXPECT_EQ("/abcd", condition.getAddress()); | |
| 53 | + EXPECT_EQ(Condition::Operator::lt, condition.getOperator()); | |
| 54 | + EXPECT_EQ("3", condition.getValue()); | |
| 55 | + EXPECT_THROW(Condition::parse(nlohmann::json({{"address", "/abcd"}, {"operator", "something"}, {"value", "3"}})), | |
| 56 | + HueException); | |
| 57 | +} | |
| 58 | + | |
| 59 | +TEST(Condition, operatorString) | |
| 60 | +{ | |
| 61 | + using Op = Condition::Operator; | |
| 62 | + std::map<Op, std::string> values = {{Op::eq, "eq"}, {Op::gt, "gt"}, {Op::lt, "lt"}, {Op::dx, "dx"}, | |
| 63 | + {Op::ddx, "ddx"}, {Op::stable, "stable"}, {Op::notStable, "not stable"}, {Op::in, "in"}, {Op::notIn, "not in"}}; | |
| 64 | + | |
| 65 | + for (const auto& pair : values) | |
| 66 | + { | |
| 67 | + Condition c("", pair.first, ""); | |
| 68 | + // Check that correct string is | |
| 69 | + EXPECT_EQ(pair.second, c.toJson().at("operator")); | |
| 70 | + EXPECT_EQ(pair.first, | |
| 71 | + Condition::parse(nlohmann::json {{"address", "/abcd"}, {"operator", pair.second}, {"value", "3"}}) | |
| 72 | + .getOperator()); | |
| 73 | + } | |
| 74 | +} | |
| 75 | + | |
| 76 | +class RuleTest : public Test | |
| 77 | +{ | |
| 78 | +protected: | |
| 79 | + std::shared_ptr<MockHttpHandler> handler; | |
| 80 | + HueCommandAPI commands; | |
| 81 | + nlohmann::json ruleState; | |
| 82 | + | |
| 83 | + RuleTest() | |
| 84 | + : handler(std::make_shared<MockHttpHandler>()), | |
| 85 | + commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler), | |
| 86 | + ruleState({{"name", "Rule 1"}, {"owner", "testOwner"}, {"created", "2020-06-01T10:00:00"}, | |
| 87 | + {"lasttriggered", "none"}, {"timestriggered", 0}, {"status", "enabled"}, | |
| 88 | + {"conditions", {{{"address", "testAddress"}, {"operator", "eq"}, {"value", "10"}}}}, | |
| 89 | + {"actions", {{{"address", "testAction"}, {"method", "PUT"}, {"body", {}}}}}}) | |
| 90 | + { } | |
| 91 | + | |
| 92 | + void expectGetState(int id) | |
| 93 | + { | |
| 94 | + EXPECT_CALL(*handler, | |
| 95 | + GETJson("/api/" + getBridgeUsername() + "/rules/" + std::to_string(id), _, getBridgeIp(), getBridgePort())) | |
| 96 | + .WillOnce(Return(ruleState)); | |
| 97 | + } | |
| 98 | + | |
| 99 | + Rule getRule(int id = 1) | |
| 100 | + { | |
| 101 | + expectGetState(id); | |
| 102 | + return Rule(id, commands, std::chrono::steady_clock::duration::max()); | |
| 103 | + } | |
| 104 | +}; | |
| 105 | + | |
| 106 | +TEST_F(RuleTest, getName) | |
| 107 | +{ | |
| 108 | + const std::string name = "Rule name"; | |
| 109 | + ruleState["name"] = name; | |
| 110 | + const Rule rule = getRule(); | |
| 111 | + EXPECT_EQ(name, rule.getName()); | |
| 112 | +} | |
| 113 | + | |
| 114 | +TEST_F(RuleTest, setName) | |
| 115 | +{ | |
| 116 | + Rule rule = getRule(); | |
| 117 | + const std::string name = "Test rule"; | |
| 118 | + nlohmann::json request = {{"name", name}}; | |
| 119 | + nlohmann::json response = {{"success", {"/rules/1/name", name}}}; | |
| 120 | + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/rules/1", request, getBridgeIp(), getBridgePort())) | |
| 121 | + .WillOnce(Return(response)); | |
| 122 | + expectGetState(1); | |
| 123 | + rule.setName(name); | |
| 124 | +} | |
| 125 | + | |
| 126 | +TEST_F(RuleTest, getCreated) | |
| 127 | +{ | |
| 128 | + const std::string timestamp = "2020-06-01T10:00:00"; | |
| 129 | + ruleState["created"] = timestamp; | |
| 130 | + const Rule rule = getRule(); | |
| 131 | + EXPECT_EQ(time::AbsoluteTime::parseUTC(timestamp).getBaseTime(), rule.getCreated().getBaseTime()); | |
| 132 | +} | |
| 133 | + | |
| 134 | +TEST_F(RuleTest, getLastTriggered) | |
| 135 | +{ | |
| 136 | + const std::string timestamp = "2020-06-01T10:00:00"; | |
| 137 | + ruleState["lasttriggered"] = timestamp; | |
| 138 | + const Rule rule = getRule(); | |
| 139 | + EXPECT_EQ(time::AbsoluteTime::parseUTC(timestamp).getBaseTime(), rule.getLastTriggered().getBaseTime()); | |
| 140 | + ruleState["lasttriggered"] = "none"; | |
| 141 | + const Rule rule2 = getRule(); | |
| 142 | + EXPECT_EQ(std::chrono::system_clock::time_point(std::chrono::seconds(0)), rule2.getLastTriggered().getBaseTime()); | |
| 143 | +} | |
| 144 | + | |
| 145 | +TEST_F(RuleTest, getTimesTriggered) | |
| 146 | +{ | |
| 147 | + const int times = 20; | |
| 148 | + ruleState["timestriggered"] = times; | |
| 149 | + EXPECT_EQ(times, getRule().getTimesTriggered()); | |
| 150 | +} | |
| 151 | + | |
| 152 | +TEST_F(RuleTest, isEnabled) | |
| 153 | +{ | |
| 154 | + ruleState["status"] = "enabled"; | |
| 155 | + EXPECT_TRUE(getRule().isEnabled()); | |
| 156 | + ruleState["status"] = "disabled"; | |
| 157 | + EXPECT_FALSE(getRule().isEnabled()); | |
| 158 | +} | |
| 159 | + | |
| 160 | +TEST_F(RuleTest, setEnabled) | |
| 161 | +{ | |
| 162 | + Rule rule = getRule(); | |
| 163 | + { | |
| 164 | + nlohmann::json request = {{"status", "enabled"}}; | |
| 165 | + nlohmann::json response = {{"success", {"/rules/1/status", "enabled"}}}; | |
| 166 | + EXPECT_CALL( | |
| 167 | + *handler, PUTJson("/api/" + getBridgeUsername() + "/rules/1", request, getBridgeIp(), getBridgePort())) | |
| 168 | + .WillOnce(Return(response)); | |
| 169 | + expectGetState(1); | |
| 170 | + rule.setEnabled(true); | |
| 171 | + } | |
| 172 | + { | |
| 173 | + nlohmann::json request = {{"status", "disabled"}}; | |
| 174 | + nlohmann::json response = {{"success", {"/rules/1/status", "disabled"}}}; | |
| 175 | + EXPECT_CALL( | |
| 176 | + *handler, PUTJson("/api/" + getBridgeUsername() + "/rules/1", request, getBridgeIp(), getBridgePort())) | |
| 177 | + .WillOnce(Return(response)); | |
| 178 | + expectGetState(1); | |
| 179 | + rule.setEnabled(false); | |
| 180 | + } | |
| 181 | +} | |
| 182 | + | |
| 183 | +TEST_F(RuleTest, getOwner) | |
| 184 | +{ | |
| 185 | + const std::string owner = "testowner"; | |
| 186 | + ruleState["owner"] = owner; | |
| 187 | + EXPECT_EQ(owner, getRule().getOwner()); | |
| 188 | +} | |
| 189 | + | |
| 190 | +TEST_F(RuleTest, getConditions) | |
| 191 | +{ | |
| 192 | + std::vector<Condition> conditions | |
| 193 | + = {Condition("/a/b/c", Condition::Operator::eq, "12"), Condition("/d/c", Condition::Operator::dx, "")}; | |
| 194 | + ruleState["conditions"] = {conditions[0].toJson(), conditions[1].toJson()}; | |
| 195 | + const std::vector<Condition> result = getRule().getConditions(); | |
| 196 | + ASSERT_EQ(2, result.size()); | |
| 197 | + EXPECT_EQ(conditions[0].toJson(), result[0].toJson()); | |
| 198 | + EXPECT_EQ(conditions[1].toJson(), result[1].toJson()); | |
| 199 | +} | |
| 200 | + | |
| 201 | +TEST_F(RuleTest, getActions) | |
| 202 | +{ | |
| 203 | + nlohmann::json action0 {{"address", "/a/b"}, {"method", "PUT"}, {"body", {{"value", "test"}}}}; | |
| 204 | + nlohmann::json action1 {{"address", "/c/d"}, {"method", "POST"}, {"body", {{"32", 1}}}}; | |
| 205 | + | |
| 206 | + ruleState["actions"] = {action0, action1}; | |
| 207 | + const std::vector<hueplusplus::Action> result = getRule().getActions(); | |
| 208 | + ASSERT_EQ(2, result.size()); | |
| 209 | + EXPECT_EQ(action0, result[0].toJson()); | |
| 210 | + EXPECT_EQ(action1, result[1].toJson()); | |
| 211 | +} | |
| 212 | + | |
| 213 | +TEST_F(RuleTest, setConditions) | |
| 214 | +{ | |
| 215 | + std::vector<Condition> conditions | |
| 216 | + = {Condition("/a/b/c", Condition::Operator::eq, "12"), Condition("/d/c", Condition::Operator::dx, "")}; | |
| 217 | + const nlohmann::json request = {{"conditions", {conditions[0].toJson(), conditions[1].toJson()}}}; | |
| 218 | + | |
| 219 | + Rule rule = getRule(); | |
| 220 | + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/rules/1", request, getBridgeIp(), getBridgePort())); | |
| 221 | + expectGetState(1); | |
| 222 | + rule.setConditions(conditions); | |
| 223 | +} | |
| 224 | + | |
| 225 | +TEST_F(RuleTest, setActions) | |
| 226 | +{ | |
| 227 | + using hueplusplus::Action; | |
| 228 | + nlohmann::json action0 {{"address", "/a/b"}, {"method", "PUT"}, {"body", {{"value", "test"}}}}; | |
| 229 | + nlohmann::json action1 {{"address", "/c/d"}, {"method", "POST"}, {"body", {{"32", 1}}}}; | |
| 230 | + const nlohmann::json request = {{"actions", {action0, action1}}}; | |
| 231 | + | |
| 232 | + const std::vector<Action> actions = {Action(action0), Action(action1)}; | |
| 233 | + | |
| 234 | + Rule rule = getRule(); | |
| 235 | + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/rules/1", request, getBridgeIp(), getBridgePort())); | |
| 236 | + expectGetState(1); | |
| 237 | + rule.setActions(actions); | |
| 238 | +} | |
| 239 | + | |
| 240 | +TEST(CreateRule, setName) | |
| 241 | +{ | |
| 242 | + const std::string name = "New rule"; | |
| 243 | + const nlohmann::json request = {{"conditions", {}}, {"actions", {}}, {"name", name}}; | |
| 244 | + EXPECT_EQ(request, CreateRule({}, {}).setName(name).getRequest()); | |
| 245 | +} | |
| 246 | + | |
| 247 | +TEST(CreateRule, setStatus) | |
| 248 | +{ | |
| 249 | + { | |
| 250 | + const nlohmann::json request = {{"conditions", {}}, {"actions", {}}, {"status", "enabled"}}; | |
| 251 | + EXPECT_EQ(request, CreateRule({}, {}).setStatus(true).getRequest()); | |
| 252 | + } | |
| 253 | + { | |
| 254 | + const nlohmann::json request = {{"conditions", {}}, {"actions", {}}, {"status", "disabled"}}; | |
| 255 | + EXPECT_EQ(request, CreateRule({}, {}).setStatus(false).getRequest()); | |
| 256 | + } | |
| 257 | +} | |
| 258 | + | |
| 259 | +TEST(CreateRule, Constructor) | |
| 260 | +{ | |
| 261 | + using hueplusplus::Action; | |
| 262 | + std::vector<Condition> conditions | |
| 263 | + = {Condition("/a/b/c", Condition::Operator::eq, "12"), Condition("/d/c", Condition::Operator::dx, "")}; | |
| 264 | + nlohmann::json action0 {{"address", "/a/b"}, {"method", "PUT"}, {"body", {{"value", "test"}}}}; | |
| 265 | + nlohmann::json action1 {{"address", "/c/d"}, {"method", "POST"}, {"body", {{"32", 1}}}}; | |
| 266 | + const std::vector<Action> actions = {Action(action0), Action(action1)}; | |
| 267 | + const nlohmann::json request | |
| 268 | + = {{"conditions", {conditions[0].toJson(), conditions[1].toJson()}}, {"actions", {action0, action1}}}; | |
| 269 | + EXPECT_EQ(request, CreateRule(conditions, actions).getRequest()); | |
| 270 | +} | ... | ... |