extension_override_apitest.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
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 "chrome/browser/browser_list.h"
6#include "chrome/browser/extensions/extension_apitest.h"
7#include "chrome/browser/extensions/extension_service.h"
8#include "chrome/browser/extensions/extension_web_ui.h"
9#include "chrome/browser/prefs/pref_service.h"
10#include "chrome/browser/profiles/profile.h"
11#include "chrome/browser/tab_contents/tab_contents.h"
12#include "chrome/browser/ui/browser.h"
13#include "chrome/common/url_constants.h"
14#include "chrome/test/ui_test_utils.h"
15
16class ExtensionOverrideTest : public ExtensionApiTest {
17 protected:
18  bool CheckHistoryOverridesContainsNoDupes() {
19    // There should be no duplicate entries in the preferences.
20    const DictionaryValue* overrides =
21        browser()->profile()->GetPrefs()->GetDictionary(
22            ExtensionWebUI::kExtensionURLOverrides);
23
24    ListValue* values = NULL;
25    if (!overrides->GetList("history", &values))
26      return false;
27
28    std::set<std::string> seen_overrides;
29    for (size_t i = 0; i < values->GetSize(); ++i) {
30      std::string value;
31      if (!values->GetString(i, &value))
32        return false;
33
34      if (seen_overrides.find(value) != seen_overrides.end())
35        return false;
36
37      seen_overrides.insert(value);
38    }
39
40    return true;
41  }
42
43#if defined(TOUCH_UI)
44  // Navigate to the keyboard page, and ensure we have arrived at an
45  // extension URL.
46  void NavigateToKeyboard() {
47    ui_test_utils::NavigateToURL(browser(), GURL("chrome://keyboard/"));
48    TabContents* tab = browser()->GetSelectedTabContents();
49    ASSERT_TRUE(tab->controller().GetActiveEntry());
50    EXPECT_TRUE(tab->controller().GetActiveEntry()->url().
51                SchemeIs(chrome::kExtensionScheme));
52  }
53#endif
54};
55
56IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, OverrideNewtab) {
57  ASSERT_TRUE(RunExtensionTest("override/newtab")) << message_;
58  {
59    ResultCatcher catcher;
60    // Navigate to the new tab page.  The overridden new tab page
61    // will call chrome.test.notifyPass() .
62    ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab/"));
63    TabContents* tab = browser()->GetSelectedTabContents();
64    ASSERT_TRUE(tab->controller().GetActiveEntry());
65    EXPECT_TRUE(tab->controller().GetActiveEntry()->url().
66                SchemeIs(chrome::kExtensionScheme));
67
68    ASSERT_TRUE(catcher.GetNextResult());
69  }
70
71  // TODO(erikkay) Load a second extension with the same override.
72  // Verify behavior, then unload the first and verify behavior, etc.
73}
74
75#if defined(OS_MACOSX)
76// Hangy: http://crbug.com/70511
77#define MAYBE_OverrideNewtabIncognito DISABLED_OverrideNewtabIncognito
78#else
79#define MAYBE_OverrideNewtabIncognito OverrideNewtabIncognito
80#endif
81IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, MAYBE_OverrideNewtabIncognito) {
82  ASSERT_TRUE(RunExtensionTest("override/newtab")) << message_;
83
84  // Navigate an incognito tab to the new tab page.  We should get the actual
85  // new tab page because we can't load chrome-extension URLs in incognito.
86  ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
87                                     GURL("chrome://newtab/"));
88  Browser* otr_browser = BrowserList::FindBrowserWithType(
89      browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL,
90      false);
91  TabContents* tab = otr_browser->GetSelectedTabContents();
92  ASSERT_TRUE(tab->controller().GetActiveEntry());
93  EXPECT_FALSE(tab->controller().GetActiveEntry()->url().
94               SchemeIs(chrome::kExtensionScheme));
95}
96
97// Times out consistently on Win, http://crbug.com/45173.
98#if defined(OS_WIN)
99#define MAYBE_OverrideHistory DISABLED_OverrideHistory
100#else
101#define MAYBE_OverrideHistory OverrideHistory
102#endif  // defined(OS_WIN)
103
104IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, MAYBE_OverrideHistory) {
105  ASSERT_TRUE(RunExtensionTest("override/history")) << message_;
106  {
107    ResultCatcher catcher;
108    // Navigate to the history page.  The overridden history page
109    // will call chrome.test.notifyPass() .
110    ui_test_utils::NavigateToURL(browser(), GURL("chrome://history/"));
111    ASSERT_TRUE(catcher.GetNextResult());
112  }
113}
114
115// Regression test for http://crbug.com/41442.
116IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, ShouldNotCreateDuplicateEntries) {
117  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("override/history")));
118
119  // Simulate several LoadExtension() calls happening over the lifetime of
120  // a preferences file without corresponding UnloadExtension() calls.
121  for (size_t i = 0; i < 3; ++i) {
122    ExtensionWebUI::RegisterChromeURLOverrides(
123        browser()->profile(),
124        browser()->profile()->GetExtensionService()->extensions()->back()->
125            GetChromeURLOverrides());
126  }
127
128  ASSERT_TRUE(CheckHistoryOverridesContainsNoDupes());
129}
130
131IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, ShouldCleanUpDuplicateEntries) {
132  // Simulate several LoadExtension() calls happening over the lifetime of
133  // a preferences file without corresponding UnloadExtension() calls. This is
134  // the same as the above test, except for that it is testing the case where
135  // the file already contains dupes when an extension is loaded.
136  ListValue* list = new ListValue();
137  for (size_t i = 0; i < 3; ++i)
138    list->Append(Value::CreateStringValue("http://www.google.com/"));
139
140  browser()->profile()->GetPrefs()->GetMutableDictionary(
141      ExtensionWebUI::kExtensionURLOverrides)->Set("history", list);
142
143  ASSERT_FALSE(CheckHistoryOverridesContainsNoDupes());
144
145  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("override/history")));
146
147  ASSERT_TRUE(CheckHistoryOverridesContainsNoDupes());
148}
149
150#if defined(TOUCH_UI)
151IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, OverrideKeyboard) {
152  ASSERT_TRUE(RunExtensionTest("override/keyboard")) << message_;
153  {
154    ResultCatcher catcher;
155    NavigateToKeyboard();
156    ASSERT_TRUE(catcher.GetNextResult());
157  }
158
159  // Load the failing version.  This should take precedence.
160  ASSERT_TRUE(LoadExtension(
161      test_data_dir_.AppendASCII("override").AppendASCII("keyboard_fails")));
162  {
163    ResultCatcher catcher;
164    NavigateToKeyboard();
165    ASSERT_FALSE(catcher.GetNextResult());
166  }
167
168  // Unload the failing version.  We should be back to passing now.
169  const ExtensionList *extensions =
170      browser()->profile()->GetExtensionService()->extensions();
171  UnloadExtension((*extensions->rbegin())->id());
172  {
173    ResultCatcher catcher;
174    NavigateToKeyboard();
175    ASSERT_TRUE(catcher.GetNextResult());
176  }
177}
178#endif
179