12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/onc/onc_merger.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/network/onc/onc_signature.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/onc/onc_test_utils.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/onc/onc_constants.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace onc {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Checks that both dictionaries contain an entry at |path| with the same value.
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)::testing::AssertionResult HaveSameValueAt(const base::DictionaryValue& a,
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const base::DictionaryValue& b,
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const std::string& path) {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* a_value = NULL;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!a.Get(path, &a_value)) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ::testing::AssertionFailure()
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "First dictionary '" << a << "' doesn't contain " << path;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* b_value = NULL;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!b.Get(path, &b_value)) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ::testing::AssertionFailure()
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Second dictionary '" << b << "' doesn't contain " << path;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::Value::Equals(a_value, b_value)) {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ::testing::AssertionSuccess()
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Entries at '" << path << "' are equal";
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ::testing::AssertionFailure()
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Entries at '" << path << "' not equal but are '"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << *a_value << "' and '" << *b_value << "'";
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace merger {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ONCMergerTest : public testing::Test {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<const base::DictionaryValue> user_;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<const base::DictionaryValue> policy_;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<const base::DictionaryValue> policy_without_recommended_;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<const base::DictionaryValue> device_policy_;
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<const base::DictionaryValue> active_;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy_ = test_utils::ReadTestDictionary("managed_vpn.onc");
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy_without_recommended_ =
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_utils::ReadTestDictionary("managed_vpn_without_recommended.onc");
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    user_ = test_utils::ReadTestDictionary("user.onc");
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_policy_ = test_utils::ReadTestDictionary("device_policy.onc");
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    active_ = test_utils::ReadTestDictionary("vpn_active_settings.onc");
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MandatoryValueOverwritesUserValue) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), NULL, user_.get(), NULL));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *policy_, "Type"));
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(HaveSameValueAt(*merged, *policy_, "StaticIPConfig"));
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MandatoryValueAndNoUserValue) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), NULL, user_.get(), NULL));
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *policy_, "GUID"));
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *policy_, "VPN.OpenVPN.Username"));
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MandatoryDictionaryAndNoUserValue) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          policy_.get(), NULL, user_.get(), NULL));
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *policy_without_recommended_,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              "VPN.OpenVPN.ClientCertPattern"));
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, UserValueOverwritesRecommendedValue) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), NULL, user_.get(), NULL));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *user_, "VPN.Host"));
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, UserValueAndRecommendedUnset) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), NULL, user_.get(), NULL));
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *user_, "VPN.OpenVPN.Password"));
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, UserDictionaryAndNoPolicyValue) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), NULL, user_.get(), NULL));
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* value = NULL;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(merged->Get("ProxySettings", &value));
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MergeWithEmptyPolicyProhibitsEverything) {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue emptyDict;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MergeSettingsAndPoliciesToEffective(&emptyDict, NULL, user_.get(), NULL));
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(merged->empty());
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MergeWithoutPolicyAllowsAnything) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MergeSettingsAndPoliciesToEffective(NULL, NULL, user_.get(), NULL));
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(test_utils::Equals(user_.get(), merged.get()));
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MergeWithoutUserSettings) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue emptyDict;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merged = MergeSettingsAndPoliciesToEffective(
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), NULL, &emptyDict, NULL);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(test_utils::Equals(policy_without_recommended_.get(),
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 merged.get()));
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merged = MergeSettingsAndPoliciesToEffective(policy_.get(), NULL, NULL, NULL);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(test_utils::Equals(policy_without_recommended_.get(),
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 merged.get()));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MandatoryUserPolicyOverwritesDevicePolicy) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), device_policy_.get(), user_.get(), NULL));
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *policy_, "VPN.OpenVPN.Port"));
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MandatoryDevicePolicyOverwritesRecommendedUserPolicy) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToEffective(
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy_.get(), device_policy_.get(), user_.get(), NULL));
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(HaveSameValueAt(*merged, *device_policy_,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              "VPN.OpenVPN.Username"));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ONCMergerTest, MergeToAugmented) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> expected_augmented =
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_utils::ReadTestDictionary("augmented_merge.json");
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> merged(MergeSettingsAndPoliciesToAugmented(
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kNetworkConfigurationSignature, policy_.get(), device_policy_.get(),
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      user_.get(), NULL, active_.get()));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(test_utils::Equals(expected_augmented.get(), merged.get()));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace merger
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace onc
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
160