• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
6 
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/extensions/active_script_controller.h"
11 #include "chrome/browser/extensions/extension_action.h"
12 #include "chrome/browser/extensions/extension_action_manager.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/location_bar_controller.h"
15 #include "chrome/browser/extensions/tab_helper.h"
16 #include "chrome/browser/extensions/test_extension_system.h"
17 #include "chrome/browser/sessions/session_tab_helper.h"
18 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/crx_file/id_util.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_builder.h"
23 #include "extensions/common/feature_switch.h"
24 #include "extensions/common/value_builder.h"
25 
26 #if defined(OS_CHROMEOS)
27 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
28 #include "chrome/browser/chromeos/settings/cros_settings.h"
29 #include "chrome/browser/chromeos/settings/device_settings_service.h"
30 #endif
31 
32 namespace extensions {
33 namespace {
34 
35 class LocationBarControllerUnitTest : public ChromeRenderViewHostTestHarness {
36  protected:
SetUp()37   virtual void SetUp() OVERRIDE {
38     active_script_override_.reset(new FeatureSwitch::ScopedOverride(
39         FeatureSwitch::scripts_require_action(), true));
40 
41     ChromeRenderViewHostTestHarness::SetUp();
42 #if defined OS_CHROMEOS
43   test_user_manager_.reset(new chromeos::ScopedTestUserManager());
44 #endif
45     TabHelper::CreateForWebContents(web_contents());
46     // Create an ExtensionService so the LocationBarController can find its
47     // extensions.
48     CommandLine command_line(CommandLine::NO_PROGRAM);
49     Profile* profile =
50         Profile::FromBrowserContext(web_contents()->GetBrowserContext());
51     extension_service_ = static_cast<TestExtensionSystem*>(
52         ExtensionSystem::Get(profile))->CreateExtensionService(
53             &command_line, base::FilePath(), false);
54   }
55 
TearDown()56   virtual void TearDown() OVERRIDE {
57 #if defined OS_CHROMEOS
58     test_user_manager_.reset();
59 #endif
60     ChromeRenderViewHostTestHarness::TearDown();
61   }
62 
tab_id()63   int tab_id() {
64     return SessionTabHelper::IdForTab(web_contents());
65   }
66 
AddExtension(bool has_page_actions,const std::string & name)67   const Extension* AddExtension(bool has_page_actions,
68                                 const std::string& name) {
69     DictionaryBuilder manifest;
70     manifest.Set("name", name)
71             .Set("version", "1.0.0")
72             .Set("manifest_version", 2)
73             .Set("permissions", ListBuilder().Append("tabs"));
74     if (has_page_actions) {
75       manifest.Set("page_action", DictionaryBuilder()
76               .Set("default_title", "Hello"));
77     }
78     scoped_refptr<const Extension> extension =
79         ExtensionBuilder().SetManifest(manifest.Pass())
80                           .SetID(crx_file::id_util::GenerateId(name))
81                           .Build();
82     extension_service_->AddExtension(extension.get());
83     return extension.get();
84   }
85 
86   ExtensionService* extension_service_;
87 
88  private:
89 #if defined OS_CHROMEOS
90   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
91   chromeos::ScopedTestCrosSettings test_cros_settings_;
92   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
93 #endif
94 
95   // Since we also test that we show page actions for pending script requests,
96   // we need to enable that feature.
97   scoped_ptr<FeatureSwitch::ScopedOverride> active_script_override_;
98 };
99 
100 // Test that the location bar gets the proper current actions.
TEST_F(LocationBarControllerUnitTest,LocationBarDisplaysPageActions)101 TEST_F(LocationBarControllerUnitTest, LocationBarDisplaysPageActions) {
102   // Load up two extensions, one with a page action and one without.
103   const Extension* page_action = AddExtension(true, "page_actions");
104   const Extension* no_action = AddExtension(false, "no_actions");
105 
106   TabHelper* tab_helper = TabHelper::FromWebContents(web_contents());
107   ASSERT_TRUE(tab_helper);
108   LocationBarController* controller = tab_helper->location_bar_controller();
109   ASSERT_TRUE(controller);
110 
111   // There should only be one action - the action for the extension with a
112   // page action.
113   std::vector<ExtensionAction*> current_actions =
114       controller->GetCurrentActions();
115   ASSERT_EQ(1u, current_actions.size());
116   EXPECT_EQ(page_action->id(), current_actions[0]->extension_id());
117 
118   // If we request a script injection, then the location bar controller should
119   // also show a page action for that extension.
120   ActiveScriptController* active_script_controller =
121       ActiveScriptController::GetForWebContents(web_contents());
122   ASSERT_TRUE(active_script_controller);
123   active_script_controller->RequestScriptInjectionForTesting(no_action,
124                                                              base::Closure());
125   current_actions = controller->GetCurrentActions();
126   ASSERT_EQ(2u, current_actions.size());
127   // Check that each extension is present in the vector.
128   EXPECT_TRUE(current_actions[0]->extension_id() == no_action->id() ||
129               current_actions[1]->extension_id() == no_action->id());
130   EXPECT_TRUE(current_actions[0]->extension_id() == page_action->id() ||
131               current_actions[1]->extension_id() == page_action->id());
132 
133   // If we request a script injection for an extension that already has a
134   // page action, only one action should be visible.
135   active_script_controller->RequestScriptInjectionForTesting(page_action,
136                                                              base::Closure());
137   current_actions = controller->GetCurrentActions();
138   ASSERT_EQ(2u, current_actions.size());
139   EXPECT_TRUE(current_actions[0]->extension_id() == no_action->id() ||
140               current_actions[1]->extension_id() == no_action->id());
141   EXPECT_TRUE(current_actions[0]->extension_id() == page_action->id() ||
142               current_actions[1]->extension_id() == page_action->id());
143 
144   // Navigating away means that only page actions are shown again.
145   NavigateAndCommit(GURL("http://google.com"));
146   current_actions = controller->GetCurrentActions();
147   ASSERT_EQ(1u, current_actions.size());
148   EXPECT_EQ(page_action->id(), current_actions[0]->extension_id());
149 }
150 
151 // Test that navigating clears all state in a page action.
TEST_F(LocationBarControllerUnitTest,NavigationClearsState)152 TEST_F(LocationBarControllerUnitTest, NavigationClearsState) {
153   const Extension* extension = AddExtension(true, "page_actions");
154 
155   NavigateAndCommit(GURL("http://www.google.com"));
156 
157   ExtensionAction& page_action =
158       *ExtensionActionManager::Get(profile())->GetPageAction(*extension);
159   page_action.SetTitle(tab_id(), "Goodbye");
160   page_action.SetPopupUrl(tab_id(), extension->GetResourceURL("popup.html"));
161 
162   EXPECT_EQ("Goodbye", page_action.GetTitle(tab_id()));
163   EXPECT_EQ(extension->GetResourceURL("popup.html"),
164             page_action.GetPopupUrl(tab_id()));
165 
166   // Within-page navigation should keep the settings.
167   NavigateAndCommit(GURL("http://www.google.com/#hash"));
168 
169   EXPECT_EQ("Goodbye", page_action.GetTitle(tab_id()));
170   EXPECT_EQ(extension->GetResourceURL("popup.html"),
171             page_action.GetPopupUrl(tab_id()));
172 
173   // Should discard the settings, and go back to the defaults.
174   NavigateAndCommit(GURL("http://www.yahoo.com"));
175 
176   EXPECT_EQ("Hello", page_action.GetTitle(tab_id()));
177   EXPECT_EQ(GURL(), page_action.GetPopupUrl(tab_id()));
178 }
179 
180 }  // namespace
181 }  // namespace extensions
182