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