blob: d7bb4e631151b65d9e1a7fc68d62d9e2335cb087 [file] [log] [blame]
// Copyright 2016 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/access_api_handler.h"
#include <gtest/gtest.h>
#include <weave/provider/test/fake_task_runner.h>
#include <weave/test/mock_device.h>
#include <weave/test/unittest_utils.h>
#include "src/access_revocation_manager.h"
#include "src/component_manager_impl.h"
#include "src/data_encoding.h"
#include "src/test/mock_access_revocation_manager.h"
using testing::_;
using testing::AnyOf;
using testing::Invoke;
using testing::Return;
using testing::StrictMock;
using testing::WithArgs;
namespace weave {
class AccessApiHandlerTest : public ::testing::Test {
protected:
void SetUp() override {
EXPECT_CALL(device_, AddTraitDefinitionsFromJson(_))
.WillRepeatedly(Invoke([this](const std::string& json) {
EXPECT_TRUE(component_manager_.LoadTraits(json, nullptr));
}));
EXPECT_CALL(device_, SetStateProperties(_, _, _))
.WillRepeatedly(
Invoke(&component_manager_, &ComponentManager::SetStateProperties));
EXPECT_CALL(device_, SetStateProperty(_, _, _, _))
.WillRepeatedly(
Invoke(&component_manager_, &ComponentManager::SetStateProperty));
EXPECT_CALL(device_, AddComponent(_, _, _))
.WillRepeatedly(Invoke([this](const std::string& name,
const std::vector<std::string>& traits,
ErrorPtr* error) {
return component_manager_.AddComponent("", name, traits, error);
}));
EXPECT_CALL(device_,
AddCommandHandler(_, AnyOf("blacklist.add", "blacklist.list"),
_))
.WillRepeatedly(
Invoke(&component_manager_, &ComponentManager::AddCommandHandler));
EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(0));
EXPECT_CALL(access_manager_, GetCapacity()).WillRepeatedly(Return(10));
handler_.reset(new AccessApiHandler{&device_, &access_manager_});
}
const base::DictionaryValue& AddCommand(const std::string& command) {
std::string id;
auto command_instance = component_manager_.ParseCommandInstance(
*test::CreateDictionaryValue(command.c_str()), Command::Origin::kLocal,
UserRole::kOwner, &id, nullptr);
EXPECT_NE(nullptr, command_instance.get());
component_manager_.AddCommand(std::move(command_instance));
EXPECT_EQ(Command::State::kDone,
component_manager_.FindCommand(id)->GetState());
return component_manager_.FindCommand(id)->GetResults();
}
std::unique_ptr<base::DictionaryValue> GetState() {
std::string path =
component_manager_.FindComponentWithTrait("blacklist");
EXPECT_FALSE(path.empty());
const auto* component = component_manager_.FindComponent(path, nullptr);
EXPECT_TRUE(component);
const base::DictionaryValue* state = nullptr;
EXPECT_TRUE(
component->GetDictionary("state.blacklist", &state));
return state->CreateDeepCopy();
}
StrictMock<provider::test::FakeTaskRunner> task_runner_;
ComponentManagerImpl component_manager_{&task_runner_};
StrictMock<test::MockDevice> device_;
StrictMock<test::MockAccessRevocationManager> access_manager_;
std::unique_ptr<AccessApiHandler> handler_;
};
TEST_F(AccessApiHandlerTest, Initialization) {
const base::DictionaryValue* trait = nullptr;
ASSERT_TRUE(component_manager_.GetTraits().GetDictionary(
"blacklist", &trait));
auto expected = R"({
"commands": {
"add": {
"minimalRole": "owner",
"parameters": {
"userId": {
"type": "string"
},
"applicationId": {
"type": "string"
},
"revocationTimestamp": {
"type": "integer"
},
"expirationTime": {
"type": "integer"
}
}
},
"list": {
"minimalRole": "owner",
"parameters": {},
"results": {
"blacklistEntries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"applicationId": {
"type": "string"
},
"revocationTimestamp": {
"type": "integer"
},
"expirationTime": {
"type": "integer"
}
},
"additionalProperties": false
}
}
}
}
},
"state": {
"capacity": {
"type": "integer",
"isRequired": true
}
}
})";
EXPECT_JSON_EQ(expected, *trait);
expected = R"({
"capacity": 10
})";
EXPECT_JSON_EQ(expected, *GetState());
}
TEST_F(AccessApiHandlerTest, Revoke) {
EXPECT_CALL(
access_manager_,
Block(AccessRevocationManager::Entry{std::vector<uint8_t>{1, 2, 3},
std::vector<uint8_t>{3, 4, 5},
base::Time::FromTimeT(946686034),
base::Time::FromTimeT(946692690)},
_))
.WillOnce(WithArgs<1>(
Invoke([](const DoneCallback& callback) { callback.Run(nullptr); })));
EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(1));
AddCommand(R"({
'name' : 'blacklist.add',
'component': 'accessControl',
'parameters': {
'userId': 'AQID',
'applicationId': 'AwQF',
'expirationTime': 7890,
'revocationTimestamp': 1234
}
})");
auto expected = R"({
"capacity": 10
})";
EXPECT_JSON_EQ(expected, *GetState());
}
TEST_F(AccessApiHandlerTest, List) {
std::vector<AccessRevocationManager::Entry> entries{
{{11, 12, 13},
{21, 22, 23},
base::Time::FromTimeT(1310000000),
base::Time::FromTimeT(1410000000)},
{{31, 32, 33},
{41, 42, 43},
base::Time::FromTimeT(1300000000),
base::Time::FromTimeT(1420000000)},
};
EXPECT_CALL(access_manager_, GetEntries()).WillOnce(Return(entries));
EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(4));
auto expected = R"({
"blacklistEntries": [ {
"applicationId": "FRYX",
"userId": "CwwN"
}, {
"applicationId": "KSor",
"userId": "HyAh"
} ]
})";
const auto& results = AddCommand(R"({
'name' : 'blacklist.list',
'component': 'accessControl',
'parameters': {
}
})");
EXPECT_JSON_EQ(expected, results);
}
} // namespace weave