Vitaly Buka | 4615e0d | 2015-10-14 15:35:12 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Weave Authors. All rights reserved. |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 5 | #include "src/base_api_handler.h" |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 6 | |
| 7 | #include <base/strings/string_number_conversions.h> |
| 8 | #include <base/values.h> |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 9 | #include <gtest/gtest.h> |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 10 | #include <weave/provider/test/mock_config_store.h> |
| 11 | #include <weave/provider/test/mock_http_client.h> |
Vitaly Buka | 266e88b | 2015-10-06 11:33:00 -0700 | [diff] [blame] | 12 | #include <weave/test/mock_device.h> |
Alex Vakulenko | 8a05beb | 2015-11-24 17:13:20 -0800 | [diff] [blame] | 13 | #include <weave/test/unittest_utils.h> |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 14 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 15 | #include "src/component_manager_impl.h" |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 16 | #include "src/config.h" |
| 17 | #include "src/device_registration_info.h" |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 18 | |
Vitaly Buka | 6b61e57 | 2015-08-05 23:16:13 -0700 | [diff] [blame] | 19 | using testing::_; |
Vitaly Buka | 695a5fb | 2015-10-06 16:26:08 -0700 | [diff] [blame] | 20 | using testing::AnyOf; |
| 21 | using testing::Eq; |
Vitaly Buka | 9acf8aa | 2015-08-16 01:55:41 -0700 | [diff] [blame] | 22 | using testing::Invoke; |
Vitaly Buka | 6b61e57 | 2015-08-05 23:16:13 -0700 | [diff] [blame] | 23 | using testing::Return; |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 24 | using testing::ReturnRef; |
Vitaly Buka | 9acf8aa | 2015-08-16 01:55:41 -0700 | [diff] [blame] | 25 | using testing::StrictMock; |
Vitaly Buka | 6b61e57 | 2015-08-05 23:16:13 -0700 | [diff] [blame] | 26 | |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 27 | namespace weave { |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 28 | |
| 29 | class BaseApiHandlerTest : public ::testing::Test { |
| 30 | protected: |
| 31 | void SetUp() override { |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 32 | EXPECT_CALL(device_, AddTraitDefinitionsFromJson(_)) |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 33 | .WillRepeatedly(Invoke([this](const std::string& json) { |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 34 | EXPECT_TRUE(component_manager_.LoadTraits(json, nullptr)); |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 35 | })); |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 36 | EXPECT_CALL(device_, SetStateProperties(_, _, _)) |
| 37 | .WillRepeatedly(Invoke(&component_manager_, |
| 38 | &ComponentManager::SetStateProperties)); |
| 39 | EXPECT_CALL(device_, SetStateProperty(_, _, _, _)) |
| 40 | .WillRepeatedly(Invoke(&component_manager_, |
| 41 | &ComponentManager::SetStateProperty)); |
| 42 | EXPECT_CALL(device_, AddComponent(_, _, _)) |
| 43 | .WillRepeatedly(Invoke([this](const std::string& name, |
| 44 | const std::vector<std::string>& traits, |
| 45 | ErrorPtr* error) { |
| 46 | return component_manager_.AddComponent("", name, traits, error); |
Vitaly Buka | 3110deb | 2015-10-06 19:54:09 -0700 | [diff] [blame] | 47 | })); |
| 48 | |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 49 | EXPECT_CALL(device_, AddCommandHandler(_, |
| 50 | AnyOf("base.updateBaseConfiguration", |
Vitaly Buka | 695a5fb | 2015-10-06 16:26:08 -0700 | [diff] [blame] | 51 | "base.updateDeviceInfo"), |
| 52 | _)) |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 53 | .WillRepeatedly(Invoke(&component_manager_, |
| 54 | &ComponentManager::AddCommandHandler)); |
Vitaly Buka | 266e88b | 2015-10-06 11:33:00 -0700 | [diff] [blame] | 55 | |
Vitaly Buka | 666b43e | 2015-12-08 16:35:47 -0800 | [diff] [blame] | 56 | config_.Load(); |
| 57 | dev_reg_.reset(new DeviceRegistrationInfo(&config_, &component_manager_, |
| 58 | nullptr, &http_client_, nullptr, |
| 59 | nullptr)); |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 60 | |
| 61 | EXPECT_CALL(device_, GetSettings()) |
| 62 | .WillRepeatedly(ReturnRef(dev_reg_->GetSettings())); |
| 63 | |
Vitaly Buka | 266e88b | 2015-10-06 11:33:00 -0700 | [diff] [blame] | 64 | handler_.reset(new BaseApiHandler{dev_reg_.get(), &device_}); |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 65 | } |
| 66 | |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 67 | void AddCommand(const std::string& command) { |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 68 | std::string id; |
| 69 | auto command_instance = component_manager_.ParseCommandInstance( |
| 70 | *test::CreateDictionaryValue(command.c_str()), Command::Origin::kLocal, |
| 71 | UserRole::kOwner, &id, nullptr); |
| 72 | ASSERT_NE(nullptr, command_instance.get()); |
| 73 | component_manager_.AddCommand(std::move(command_instance)); |
Vitaly Buka | 0209da4 | 2015-10-08 00:07:18 -0700 | [diff] [blame] | 74 | EXPECT_EQ(Command::State::kDone, |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 75 | component_manager_.FindCommand(id)->GetState()); |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 76 | } |
| 77 | |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 78 | std::unique_ptr<base::DictionaryValue> GetBaseState() { |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 79 | std::unique_ptr<base::DictionaryValue> state; |
| 80 | std::string path = component_manager_.FindComponentWithTrait("base"); |
| 81 | EXPECT_FALSE(path.empty()); |
| 82 | const auto* component = component_manager_.FindComponent(path, nullptr); |
| 83 | CHECK(component); |
| 84 | const base::DictionaryValue* base_state = nullptr; |
| 85 | if (component->GetDictionary("state.base", &base_state)) |
| 86 | state.reset(base_state->DeepCopy()); |
| 87 | else |
| 88 | state.reset(new base::DictionaryValue); |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 89 | return state; |
| 90 | } |
| 91 | |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 92 | provider::test::MockConfigStore config_store_; |
Vitaly Buka | 666b43e | 2015-12-08 16:35:47 -0800 | [diff] [blame] | 93 | Config config_{&config_store_}; |
Vitaly Buka | 1e36367 | 2015-09-25 14:01:16 -0700 | [diff] [blame] | 94 | StrictMock<provider::test::MockHttpClient> http_client_; |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 95 | std::unique_ptr<DeviceRegistrationInfo> dev_reg_; |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 96 | ComponentManagerImpl component_manager_; |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 97 | std::unique_ptr<BaseApiHandler> handler_; |
Vitaly Buka | 266e88b | 2015-10-06 11:33:00 -0700 | [diff] [blame] | 98 | StrictMock<test::MockDevice> device_; |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 99 | }; |
| 100 | |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 101 | TEST_F(BaseApiHandlerTest, Initialization) { |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 102 | const base::DictionaryValue* trait = nullptr; |
| 103 | ASSERT_TRUE(component_manager_.GetTraits().GetDictionary("base", &trait)); |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 104 | |
| 105 | auto expected = R"({ |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 106 | "commands": { |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 107 | "updateBaseConfiguration": { |
Alex Vakulenko | 7e894da | 2015-11-23 11:47:49 -0800 | [diff] [blame] | 108 | "minimalRole": "manager", |
| 109 | "parameters": { |
| 110 | "localAnonymousAccessMaxRole": { |
| 111 | "enum": [ "none", "viewer", "user" ], |
| 112 | "type": "string" |
| 113 | }, |
| 114 | "localDiscoveryEnabled": { |
| 115 | "type": "boolean" |
| 116 | }, |
| 117 | "localPairingEnabled": { |
| 118 | "type": "boolean" |
| 119 | } |
| 120 | } |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 121 | }, |
| 122 | "updateDeviceInfo": { |
Alex Vakulenko | 7e894da | 2015-11-23 11:47:49 -0800 | [diff] [blame] | 123 | "minimalRole": "manager", |
| 124 | "parameters": { |
| 125 | "description": { |
| 126 | "type": "string" |
| 127 | }, |
| 128 | "location": { |
| 129 | "type": "string" |
| 130 | }, |
| 131 | "name": { |
| 132 | "type": "string" |
| 133 | } |
| 134 | } |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 135 | } |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 136 | }, |
| 137 | "state": { |
| 138 | "firmwareVersion": "string", |
| 139 | "localAnonymousAccessMaxRole": [ "none", "viewer", "user" ], |
| 140 | "localDiscoveryEnabled": "boolean", |
| 141 | "localPairingEnabled": "boolean" |
| 142 | } |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 143 | })"; |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 144 | EXPECT_JSON_EQ(expected, *trait); |
Vitaly Buka | 80d6653 | 2015-10-27 23:06:11 -0700 | [diff] [blame] | 145 | } |
| 146 | |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 147 | TEST_F(BaseApiHandlerTest, UpdateBaseConfiguration) { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 148 | const Settings& settings = dev_reg_->GetSettings(); |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 149 | |
| 150 | AddCommand(R"({ |
| 151 | 'name' : 'base.updateBaseConfiguration', |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 152 | 'component': 'weave', |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 153 | 'parameters': { |
| 154 | 'localDiscoveryEnabled': false, |
| 155 | 'localAnonymousAccessMaxRole': 'none', |
| 156 | 'localPairingEnabled': false |
| 157 | } |
| 158 | })"); |
Vitaly Buka | b624bc4 | 2015-09-29 19:13:55 -0700 | [diff] [blame] | 159 | EXPECT_EQ(AuthScope::kNone, settings.local_anonymous_access_role); |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 160 | EXPECT_FALSE(settings.local_discovery_enabled); |
| 161 | EXPECT_FALSE(settings.local_pairing_enabled); |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 162 | |
| 163 | auto expected = R"({ |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 164 | 'firmwareVersion': 'TEST_FIRMWARE', |
| 165 | 'localAnonymousAccessMaxRole': 'none', |
| 166 | 'localDiscoveryEnabled': false, |
| 167 | 'localPairingEnabled': false |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 168 | })"; |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 169 | EXPECT_JSON_EQ(expected, *GetBaseState()); |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 170 | |
| 171 | AddCommand(R"({ |
| 172 | 'name' : 'base.updateBaseConfiguration', |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 173 | 'component': 'weave', |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 174 | 'parameters': { |
| 175 | 'localDiscoveryEnabled': true, |
| 176 | 'localAnonymousAccessMaxRole': 'user', |
| 177 | 'localPairingEnabled': true |
| 178 | } |
| 179 | })"); |
Vitaly Buka | b624bc4 | 2015-09-29 19:13:55 -0700 | [diff] [blame] | 180 | EXPECT_EQ(AuthScope::kUser, settings.local_anonymous_access_role); |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 181 | EXPECT_TRUE(settings.local_discovery_enabled); |
| 182 | EXPECT_TRUE(settings.local_pairing_enabled); |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 183 | expected = R"({ |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 184 | 'firmwareVersion': 'TEST_FIRMWARE', |
| 185 | 'localAnonymousAccessMaxRole': 'user', |
| 186 | 'localDiscoveryEnabled': true, |
| 187 | 'localPairingEnabled': true |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 188 | })"; |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 189 | EXPECT_JSON_EQ(expected, *GetBaseState()); |
Vitaly Buka | 4c808b2 | 2015-08-02 13:44:52 -0700 | [diff] [blame] | 190 | |
| 191 | { |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 192 | Config::Transaction change{dev_reg_->GetMutableConfig()}; |
Vitaly Buka | b624bc4 | 2015-09-29 19:13:55 -0700 | [diff] [blame] | 193 | change.set_local_anonymous_access_role(AuthScope::kViewer); |
Vitaly Buka | 4c808b2 | 2015-08-02 13:44:52 -0700 | [diff] [blame] | 194 | } |
| 195 | expected = R"({ |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 196 | 'firmwareVersion': 'TEST_FIRMWARE', |
| 197 | 'localAnonymousAccessMaxRole': 'viewer', |
| 198 | 'localDiscoveryEnabled': true, |
| 199 | 'localPairingEnabled': true |
Vitaly Buka | 4c808b2 | 2015-08-02 13:44:52 -0700 | [diff] [blame] | 200 | })"; |
Vitaly Buka | 68af387 | 2015-10-27 16:19:00 -0700 | [diff] [blame] | 201 | EXPECT_JSON_EQ(expected, *GetBaseState()); |
Vitaly Buka | 2f7efdb | 2015-05-27 16:00:21 -0700 | [diff] [blame] | 202 | } |
| 203 | |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 204 | TEST_F(BaseApiHandlerTest, UpdateDeviceInfo) { |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 205 | AddCommand(R"({ |
| 206 | 'name' : 'base.updateDeviceInfo', |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 207 | 'component': 'weave', |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 208 | 'parameters': { |
| 209 | 'name': 'testName', |
| 210 | 'description': 'testDescription', |
| 211 | 'location': 'testLocation' |
| 212 | } |
| 213 | })"); |
| 214 | |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 215 | const Settings& config = dev_reg_->GetSettings(); |
| 216 | EXPECT_EQ("testName", config.name); |
| 217 | EXPECT_EQ("testDescription", config.description); |
| 218 | EXPECT_EQ("testLocation", config.location); |
Alex Vakulenko | 7e8df46 | 2015-07-07 10:59:20 -0700 | [diff] [blame] | 219 | |
| 220 | AddCommand(R"({ |
| 221 | 'name' : 'base.updateDeviceInfo', |
Alex Vakulenko | d91d625 | 2015-12-05 17:14:39 -0800 | [diff] [blame] | 222 | 'component': 'weave', |
Alex Vakulenko | 7e8df46 | 2015-07-07 10:59:20 -0700 | [diff] [blame] | 223 | 'parameters': { |
| 224 | 'location': 'newLocation' |
| 225 | } |
| 226 | })"); |
| 227 | |
Vitaly Buka | 5cf12a3 | 2015-09-15 21:25:48 -0700 | [diff] [blame] | 228 | EXPECT_EQ("testName", config.name); |
| 229 | EXPECT_EQ("testDescription", config.description); |
| 230 | EXPECT_EQ("newLocation", config.location); |
Vitaly Buka | 72410b2 | 2015-05-13 13:48:59 -0700 | [diff] [blame] | 231 | } |
| 232 | |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 233 | } // namespace weave |