1// Copyright (c) 2011 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 <string>
6
7#include "base/logging.h"
8#include "base/message_loop.h"
9#include "base/values.h"
10#include "base/version.h"
11#include "chrome/browser/extensions/external_extension_provider_interface.h"
12#include "chrome/browser/extensions/external_extension_provider_impl.h"
13#include "chrome/browser/extensions/external_policy_extension_loader.h"
14#include "chrome/common/extensions/extension.h"
15#include "chrome/common/pref_names.h"
16#include "chrome/test/testing_pref_service.h"
17#include "chrome/test/testing_profile.h"
18#include "content/browser/browser_thread.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21class ExternalPolicyExtensionProviderTest : public testing::Test {
22 public:
23  ExternalPolicyExtensionProviderTest()
24      : loop_(MessageLoop::TYPE_IO),
25        ui_thread_(BrowserThread::UI, &loop_) {
26  }
27
28  virtual ~ExternalPolicyExtensionProviderTest() {}
29
30 private:
31  // We need these to satisfy BrowserThread::CurrentlyOn(BrowserThread::UI)
32  // checks in ExternalExtensionProviderImpl.
33  MessageLoop loop_;
34  BrowserThread ui_thread_;
35};
36
37class MockExternalPolicyExtensionProviderVisitor
38    : public ExternalExtensionProviderInterface::VisitorInterface {
39 public:
40  MockExternalPolicyExtensionProviderVisitor() {
41  }
42
43  // Initialize a provider with |policy_forcelist|, and check that it parses
44  // exactly those extensions, that are specified in |policy_validlist|.
45  void Visit(ListValue* policy_forcelist,
46             ListValue* policy_validlist,
47             const std::set<std::string>& ignore_list) {
48    profile_.reset(new TestingProfile);
49    profile_->GetTestingPrefService()->SetManagedPref(
50        prefs::kExtensionInstallForceList,
51        policy_forcelist->DeepCopy());
52    provider_.reset(new ExternalExtensionProviderImpl(
53        this,
54        new ExternalPolicyExtensionLoader(profile_.get()),
55        Extension::INVALID,
56        Extension::EXTERNAL_POLICY_DOWNLOAD));
57
58    // Extensions will be removed from this list as they visited,
59    // so it should be emptied by the end.
60    remaining_extensions = policy_validlist;
61    provider_->VisitRegisteredExtension();
62    EXPECT_EQ(0u, remaining_extensions->GetSize());
63  }
64
65  virtual void OnExternalExtensionFileFound(const std::string& id,
66                                            const Version* version,
67                                            const FilePath& path,
68                                            Extension::Location unused) {
69    ADD_FAILURE() << "There should be no external extensions from files.";
70  }
71
72  virtual void OnExternalExtensionUpdateUrlFound(
73      const std::string& id, const GURL& update_url,
74      Extension::Location location) {
75    // Extension has the correct location.
76    EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD, location);
77
78    // Provider returns the correct location when asked.
79    Extension::Location location1;
80    scoped_ptr<Version> version1;
81    provider_->GetExtensionDetails(id, &location1, &version1);
82    EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD, location1);
83    EXPECT_FALSE(version1.get());
84
85    // Remove the extension from our list.
86    StringValue ext_str(id + ";" + update_url.spec());
87    EXPECT_NE(-1, remaining_extensions->Remove(ext_str));
88  }
89
90  virtual void OnExternalProviderReady() {
91    EXPECT_TRUE(provider_->IsReady());
92  }
93
94 private:
95  ListValue* remaining_extensions;
96
97  scoped_ptr<TestingProfile> profile_;
98
99  scoped_ptr<ExternalExtensionProviderImpl> provider_;
100
101  DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyExtensionProviderVisitor);
102};
103
104TEST_F(ExternalPolicyExtensionProviderTest, PolicyIsParsed) {
105  ListValue forced_extensions;
106  forced_extensions.Append(Value::CreateStringValue(
107      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;http://www.example.com/crx?a=5;b=6"));
108  forced_extensions.Append(Value::CreateStringValue(
109      "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"
110      "https://clients2.google.com/service/update2/crx"));
111
112  MockExternalPolicyExtensionProviderVisitor mv;
113  std::set<std::string> empty;
114  mv.Visit(&forced_extensions, &forced_extensions, empty);
115}
116
117TEST_F(ExternalPolicyExtensionProviderTest, InvalidPolicyIsNotParsed) {
118  ListValue forced_extensions, valid_extensions;
119  StringValue valid(
120      "cccccccccccccccccccccccccccccccc;http://www.example.com/crx");
121  valid_extensions.Append(valid.DeepCopy());
122  forced_extensions.Append(valid.DeepCopy());
123  // Add invalid strings:
124  forced_extensions.Append(Value::CreateStringValue(""));
125  forced_extensions.Append(Value::CreateStringValue(";"));
126  forced_extensions.Append(Value::CreateStringValue(";;"));
127  forced_extensions.Append(Value::CreateStringValue(
128      ";http://www.example.com/crx"));
129  forced_extensions.Append(Value::CreateStringValue(
130      ";aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
131  forced_extensions.Append(Value::CreateStringValue(
132      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"));
133  forced_extensions.Append(Value::CreateStringValue(
134      "http://www.example.com/crx;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
135  forced_extensions.Append(Value::CreateStringValue(
136      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;http#//www.example.com/crx"));
137  forced_extensions.Append(Value::CreateStringValue(
138      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
139  forced_extensions.Append(Value::CreateStringValue(
140      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahttp#//www.example.com/crx"));
141
142  MockExternalPolicyExtensionProviderVisitor mv;
143  std::set<std::string> empty;
144  mv.Visit(&forced_extensions, &valid_extensions, empty);
145}
146