1// Copyright 2014 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 "base/command_line.h"
6#include "base/message_loop/message_loop.h"
7#include "chrome/browser/extensions/extension_service.h"
8#include "chrome/browser/extensions/extension_web_ui.h"
9#include "chrome/browser/extensions/test_extension_system.h"
10#include "chrome/test/base/testing_profile.h"
11#include "content/public/test/test_browser_thread.h"
12#include "extensions/browser/extension_system.h"
13#include "extensions/common/extension.h"
14#include "extensions/common/extension_builder.h"
15#include "extensions/common/manifest_constants.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18#if defined(OS_CHROMEOS)
19#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
20#include "chrome/browser/chromeos/settings/cros_settings.h"
21#include "chrome/browser/chromeos/settings/device_settings_service.h"
22#endif
23
24namespace extensions {
25
26class ExtensionWebUITest : public testing::Test {
27 public:
28  ExtensionWebUITest()
29      : ui_thread_(content::BrowserThread::UI, &message_loop_) {}
30
31 protected:
32  virtual void SetUp() OVERRIDE {
33    profile_.reset(new TestingProfile());
34    TestExtensionSystem* system =
35        static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_.get()));
36    extension_service_ = system->CreateExtensionService(
37        CommandLine::ForCurrentProcess(), base::FilePath(), false);
38  }
39
40  virtual void TearDown() OVERRIDE {
41    profile_.reset();
42    message_loop_.RunUntilIdle();
43  }
44
45  scoped_ptr<TestingProfile> profile_;
46  ExtensionService* extension_service_;
47  base::MessageLoop message_loop_;
48  content::TestBrowserThread ui_thread_;
49
50#if defined OS_CHROMEOS
51  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
52  chromeos::ScopedTestCrosSettings test_cros_settings_;
53  chromeos::ScopedTestUserManager test_user_manager_;
54#endif
55};
56
57// Test that component extension url overrides have lower priority than
58// non-component extension url overrides.
59TEST_F(ExtensionWebUITest, ExtensionURLOverride) {
60  // Register a non-component extension.
61  DictionaryBuilder manifest;
62  manifest.Set(manifest_keys::kName, "ext1")
63      .Set(manifest_keys::kVersion, "0.1")
64      .Set(std::string(manifest_keys::kChromeURLOverrides),
65           DictionaryBuilder().Set("bookmarks", "1.html"));
66  scoped_refptr<Extension> ext_unpacked(
67      ExtensionBuilder()
68          .SetManifest(manifest)
69          .SetLocation(Manifest::UNPACKED)
70          .SetID("abcdefghijabcdefghijabcdefghijaa")
71          .Build());
72  extension_service_->AddExtension(ext_unpacked.get());
73
74  GURL expected_unpacked_override_url(std::string(ext_unpacked->url().spec()) +
75                                      "1.html");
76  GURL url("chrome://bookmarks");
77  EXPECT_TRUE(ExtensionWebUI::HandleChromeURLOverride(&url, profile_.get()));
78  EXPECT_EQ(url, expected_unpacked_override_url);
79
80  // Register a component extension
81  DictionaryBuilder manifest2;
82  manifest2.Set(manifest_keys::kName, "ext2")
83      .Set(manifest_keys::kVersion, "0.1")
84      .Set(std::string(manifest_keys::kChromeURLOverrides),
85           DictionaryBuilder().Set("bookmarks", "2.html"));
86  scoped_refptr<Extension> ext_component(
87      ExtensionBuilder()
88          .SetManifest(manifest2)
89          .SetLocation(Manifest::COMPONENT)
90          .SetID("bbabcdefghijabcdefghijabcdefghij")
91          .Build());
92  extension_service_->AddComponentExtension(ext_component.get());
93
94  // Despite being registered more recently, the component extension should
95  // not take precedence over the non-component extension.
96  url = GURL("chrome://bookmarks");
97  EXPECT_TRUE(ExtensionWebUI::HandleChromeURLOverride(&url, profile_.get()));
98  EXPECT_EQ(url, expected_unpacked_override_url);
99
100  GURL expected_component_override_url(
101      std::string(ext_component->url().spec()) + "2.html");
102
103  // Unregister non-component extension. Only component extension remaining.
104  ExtensionWebUI::UnregisterChromeURLOverrides(
105      profile_.get(), URLOverrides::GetChromeURLOverrides(ext_unpacked.get()));
106  url = GURL("chrome://bookmarks");
107  EXPECT_TRUE(ExtensionWebUI::HandleChromeURLOverride(&url, profile_.get()));
108  EXPECT_EQ(url, expected_component_override_url);
109
110  // This time the non-component extension was registered more recently and
111  // should still take precedence.
112  ExtensionWebUI::RegisterChromeURLOverrides(
113      profile_.get(), URLOverrides::GetChromeURLOverrides(ext_unpacked.get()));
114  url = GURL("chrome://bookmarks");
115  EXPECT_TRUE(ExtensionWebUI::HandleChromeURLOverride(&url, profile_.get()));
116  EXPECT_EQ(url, expected_unpacked_override_url);
117}
118
119}  // namespace extensions
120