blob: c2aa328fc7987c062e695a57d362a75cd517a3fb [file] [log] [blame]
// Copyright 2019 The Chromium 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 "chromeos/components/sync_wifi/wifi_configuration_bridge.h"
#include <map>
#include <set>
#include <utility>
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "chromeos/components/sync_wifi/synced_network_updater.h"
#include "chromeos/components/sync_wifi/test_specifics_generator.h"
#include "components/sync/model/entity_change.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mock_model_type_change_processor.h"
#include "components/sync/model/model_type_store_test_util.h"
#include "components/sync/model_impl/in_memory_metadata_change_list.h"
#include "components/sync/protocol/model_type_state.pb.h"
#include "components/sync/test/test_matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace sync_wifi {
namespace {
using sync_pb::WifiConfigurationSpecificsData;
using testing::_;
using testing::AllOf;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::Pair;
using testing::Return;
using testing::SizeIs;
using testing::UnorderedElementsAre;
const char kSsidMeow[] = "meow";
const char kSsidWoof[] = "woof";
std::unique_ptr<syncer::EntityData> GenerateWifiEntityData(
const sync_pb::WifiConfigurationSpecificsData& data) {
auto entity_data = std::make_unique<syncer::EntityData>();
entity_data->specifics.mutable_wifi_configuration()
->mutable_client_only_encrypted_data()
->CopyFrom(data);
entity_data->name = data.ssid();
return entity_data;
}
bool VectorContainsString(std::vector<std::string> v, std::string s) {
return std::find(v.begin(), v.end(), s) != v.end();
}
bool VectorContainsSsid(
const std::vector<sync_pb::WifiConfigurationSpecificsData>& v,
std::string s) {
for (sync_pb::WifiConfigurationSpecificsData specifics : v) {
if (specifics.ssid() == s)
return true;
}
return false;
}
class TestSyncedNetworkUpdater : public SyncedNetworkUpdater {
public:
TestSyncedNetworkUpdater() = default;
~TestSyncedNetworkUpdater() override = default;
const std::vector<sync_pb::WifiConfigurationSpecificsData>&
add_or_update_calls() {
return add_update_calls_;
}
const std::vector<std::string>& remove_calls() { return remove_calls_; }
private:
void AddOrUpdateNetwork(
const sync_pb::WifiConfigurationSpecificsData& specifics) override {
add_update_calls_.push_back(specifics);
}
void RemoveNetwork(const std::string& ssid) override {
remove_calls_.push_back(ssid);
}
std::vector<sync_pb::WifiConfigurationSpecificsData> add_update_calls_;
std::vector<std::string> remove_calls_;
};
class WifiConfigurationBridgeTest : public testing::Test {
protected:
WifiConfigurationBridgeTest()
: store_(syncer::ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()) {}
void SetUp() override {
ON_CALL(mock_processor_, IsTrackingMetadata()).WillByDefault(Return(true));
synced_network_updater_ = std::make_unique<TestSyncedNetworkUpdater>();
bridge_ = std::make_unique<WifiConfigurationBridge>(
synced_network_updater(), mock_processor_.CreateForwardingProcessor(),
syncer::ModelTypeStoreTestUtil::MoveStoreToFactory(std::move(store_)));
}
void DisableBridge() {
ON_CALL(mock_processor_, IsTrackingMetadata()).WillByDefault(Return(false));
}
syncer::EntityChangeList CreateEntityAddList(
const std::vector<WifiConfigurationSpecificsData>& specifics_list) {
syncer::EntityChangeList changes;
for (const auto& data : specifics_list) {
auto entity_data = std::make_unique<syncer::EntityData>();
sync_pb::WifiConfigurationSpecifics specifics;
specifics.mutable_client_only_encrypted_data()->CopyFrom(data);
entity_data->specifics.mutable_wifi_configuration()->CopyFrom(specifics);
entity_data->name = data.ssid();
changes.push_back(
syncer::EntityChange::CreateAdd(data.ssid(), std::move(entity_data)));
}
return changes;
}
syncer::MockModelTypeChangeProcessor* processor() { return &mock_processor_; }
WifiConfigurationBridge* bridge() { return bridge_.get(); }
TestSyncedNetworkUpdater* synced_network_updater() {
return synced_network_updater_.get();
}
private:
base::test::TaskEnvironment task_environment_;
std::unique_ptr<syncer::ModelTypeStore> store_;
testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_;
std::unique_ptr<WifiConfigurationBridge> bridge_;
std::unique_ptr<TestSyncedNetworkUpdater> synced_network_updater_;
DISALLOW_COPY_AND_ASSIGN(WifiConfigurationBridgeTest);
};
TEST_F(WifiConfigurationBridgeTest, InitWithTwoNetworksFromServer) {
syncer::EntityChangeList remote_input;
WifiConfigurationSpecificsData entry1 = CreateSpecifics(kSsidMeow);
WifiConfigurationSpecificsData entry2 = CreateSpecifics(kSsidWoof);
remote_input.push_back(syncer::EntityChange::CreateAdd(
kSsidMeow, GenerateWifiEntityData(entry1)));
remote_input.push_back(syncer::EntityChange::CreateAdd(
kSsidWoof, GenerateWifiEntityData(entry2)));
bridge()->MergeSyncData(
std::make_unique<syncer::InMemoryMetadataChangeList>(),
std::move(remote_input));
std::vector<std::string> ssids = bridge()->GetAllSsidsForTesting();
EXPECT_EQ(2u, ssids.size());
EXPECT_TRUE(VectorContainsString(ssids, kSsidMeow));
EXPECT_TRUE(VectorContainsString(ssids, kSsidWoof));
const std::vector<sync_pb::WifiConfigurationSpecificsData>& networks =
synced_network_updater()->add_or_update_calls();
EXPECT_EQ(2u, networks.size());
EXPECT_TRUE(VectorContainsSsid(networks, kSsidMeow));
EXPECT_TRUE(VectorContainsSsid(networks, kSsidWoof));
}
TEST_F(WifiConfigurationBridgeTest, ApplySyncChangesAddTwoSpecifics) {
const WifiConfigurationSpecificsData specifics1 = CreateSpecifics(kSsidMeow);
const WifiConfigurationSpecificsData specifics2 = CreateSpecifics(kSsidWoof);
base::Optional<syncer::ModelError> error =
bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
CreateEntityAddList({specifics1, specifics2}));
EXPECT_FALSE(error);
std::vector<std::string> ssids = bridge()->GetAllSsidsForTesting();
EXPECT_EQ(2u, ssids.size());
EXPECT_TRUE(VectorContainsString(ssids, kSsidMeow));
EXPECT_TRUE(VectorContainsString(ssids, kSsidWoof));
const std::vector<sync_pb::WifiConfigurationSpecificsData>& networks =
synced_network_updater()->add_or_update_calls();
EXPECT_EQ(2u, networks.size());
EXPECT_TRUE(VectorContainsSsid(networks, kSsidMeow));
EXPECT_TRUE(VectorContainsSsid(networks, kSsidWoof));
}
TEST_F(WifiConfigurationBridgeTest, ApplySyncChangesOneAdd) {
WifiConfigurationSpecificsData entry = CreateSpecifics(kSsidMeow);
syncer::EntityChangeList add_changes;
add_changes.push_back(syncer::EntityChange::CreateAdd(
kSsidMeow, GenerateWifiEntityData(entry)));
bridge()->ApplySyncChanges(
std::make_unique<syncer::InMemoryMetadataChangeList>(),
std::move(add_changes));
std::vector<std::string> ssids = bridge()->GetAllSsidsForTesting();
EXPECT_EQ(1u, ssids.size());
EXPECT_TRUE(VectorContainsString(ssids, kSsidMeow));
const std::vector<sync_pb::WifiConfigurationSpecificsData>& networks =
synced_network_updater()->add_or_update_calls();
EXPECT_EQ(1u, networks.size());
EXPECT_TRUE(VectorContainsSsid(networks, kSsidMeow));
}
TEST_F(WifiConfigurationBridgeTest, ApplySyncChangesOneDeletion) {
WifiConfigurationSpecificsData entry = CreateSpecifics(kSsidMeow);
syncer::EntityChangeList add_changes;
add_changes.push_back(syncer::EntityChange::CreateAdd(
kSsidMeow, GenerateWifiEntityData(entry)));
bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
std::move(add_changes));
std::vector<std::string> ssids = bridge()->GetAllSsidsForTesting();
EXPECT_EQ(1u, ssids.size());
EXPECT_TRUE(VectorContainsString(ssids, kSsidMeow));
const std::vector<sync_pb::WifiConfigurationSpecificsData>& networks =
synced_network_updater()->add_or_update_calls();
EXPECT_EQ(1u, networks.size());
EXPECT_TRUE(VectorContainsSsid(networks, kSsidMeow));
syncer::EntityChangeList delete_changes;
delete_changes.push_back(syncer::EntityChange::CreateDelete(kSsidMeow));
bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
std::move(delete_changes));
EXPECT_TRUE(bridge()->GetAllSsidsForTesting().empty());
const std::vector<std::string>& removed_networks =
synced_network_updater()->remove_calls();
EXPECT_EQ(1u, removed_networks.size());
EXPECT_TRUE(VectorContainsString(removed_networks, kSsidMeow));
}
} // namespace
} // namespace sync_wifi