1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <set> 6 #include <string> 7 8 #include "base/logging.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/values.h" 11 #include "base/version.h" 12 #include "chrome/browser/extensions/external_policy_loader.h" 13 #include "chrome/browser/extensions/external_provider_impl.h" 14 #include "chrome/common/pref_names.h" 15 #include "chrome/test/base/testing_pref_service_syncable.h" 16 #include "chrome/test/base/testing_profile.h" 17 #include "content/public/test/test_browser_thread.h" 18 #include "extensions/browser/external_provider_interface.h" 19 #include "extensions/browser/pref_names.h" 20 #include "extensions/common/extension.h" 21 #include "extensions/common/manifest.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 using content::BrowserThread; 25 26 namespace extensions { 27 28 class ExternalPolicyLoaderTest : public testing::Test { 29 public: 30 ExternalPolicyLoaderTest() : ui_thread_(BrowserThread::UI, &loop_) { 31 } 32 33 virtual ~ExternalPolicyLoaderTest() {} 34 35 private: 36 // We need these to satisfy BrowserThread::CurrentlyOn(BrowserThread::UI) 37 // checks in ExternalProviderImpl. 38 base::MessageLoopForIO loop_; 39 content::TestBrowserThread ui_thread_; 40 }; 41 42 class MockExternalPolicyProviderVisitor 43 : public ExternalProviderInterface::VisitorInterface { 44 public: 45 MockExternalPolicyProviderVisitor() { 46 } 47 48 // Initialize a provider with |policy_forcelist|, and check that it installs 49 // exactly the extensions specified in |expected_extensions|. 50 void Visit(const base::DictionaryValue& policy_forcelist, 51 const std::set<std::string>& expected_extensions) { 52 profile_.reset(new TestingProfile); 53 profile_->GetTestingPrefService()->SetManagedPref( 54 pref_names::kInstallForceList, policy_forcelist.DeepCopy()); 55 provider_.reset(new ExternalProviderImpl( 56 this, 57 new ExternalPolicyLoader(profile_.get()), 58 profile_.get(), 59 Manifest::INVALID_LOCATION, 60 Manifest::EXTERNAL_POLICY_DOWNLOAD, 61 Extension::NO_FLAGS)); 62 63 // Extensions will be removed from this list as they visited, 64 // so it should be emptied by the end. 65 expected_extensions_ = expected_extensions; 66 provider_->VisitRegisteredExtension(); 67 EXPECT_TRUE(expected_extensions_.empty()); 68 } 69 70 virtual bool OnExternalExtensionFileFound(const std::string& id, 71 const Version* version, 72 const base::FilePath& path, 73 Manifest::Location unused, 74 int unused2, 75 bool unused3) OVERRIDE { 76 ADD_FAILURE() << "There should be no external extensions from files."; 77 return false; 78 } 79 80 virtual bool OnExternalExtensionUpdateUrlFound( 81 const std::string& id, 82 const std::string& install_parameter, 83 const GURL& update_url, 84 Manifest::Location location, 85 int unused1, 86 bool unused2) OVERRIDE { 87 // Extension has the correct location. 88 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location); 89 90 // Provider returns the correct location when asked. 91 Manifest::Location location1; 92 scoped_ptr<Version> version1; 93 provider_->GetExtensionDetails(id, &location1, &version1); 94 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, location1); 95 EXPECT_FALSE(version1.get()); 96 97 // Remove the extension from our list. 98 EXPECT_EQ(1U, expected_extensions_.erase(id)); 99 return true; 100 } 101 102 virtual void OnExternalProviderReady( 103 const ExternalProviderInterface* provider) OVERRIDE { 104 EXPECT_EQ(provider, provider_.get()); 105 EXPECT_TRUE(provider->IsReady()); 106 } 107 108 private: 109 std::set<std::string> expected_extensions_; 110 111 scoped_ptr<TestingProfile> profile_; 112 113 scoped_ptr<ExternalProviderImpl> provider_; 114 115 DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyProviderVisitor); 116 }; 117 118 TEST_F(ExternalPolicyLoaderTest, PolicyIsParsed) { 119 base::DictionaryValue forced_extensions; 120 std::set<std::string> expected_extensions; 121 extensions::ExternalPolicyLoader::AddExtension( 122 &forced_extensions, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 123 "http://www.example.com/crx?a=5;b=6"); 124 expected_extensions.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 125 extensions::ExternalPolicyLoader::AddExtension( 126 &forced_extensions, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 127 "https://clients2.google.com/service/update2/crx"); 128 expected_extensions.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); 129 130 MockExternalPolicyProviderVisitor mv; 131 mv.Visit(forced_extensions, expected_extensions); 132 } 133 134 TEST_F(ExternalPolicyLoaderTest, InvalidEntriesIgnored) { 135 base::DictionaryValue forced_extensions; 136 std::set<std::string> expected_extensions; 137 138 extensions::ExternalPolicyLoader::AddExtension( 139 &forced_extensions, "cccccccccccccccccccccccccccccccc", 140 "http://www.example.com/crx"); 141 expected_extensions.insert("cccccccccccccccccccccccccccccccc"); 142 143 // Add invalid entries. 144 forced_extensions.SetString("invalid", "http://www.example.com/crx"); 145 forced_extensions.SetString("dddddddddddddddddddddddddddddddd", 146 std::string()); 147 forced_extensions.SetString("invalid", "bad"); 148 149 MockExternalPolicyProviderVisitor mv; 150 mv.Visit(forced_extensions, expected_extensions); 151 } 152 153 } // namespace extensions 154