| Index: chrome/browser/extensions/api/tabs/tabs_test.cc | 
| diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc | 
| index 7e1e7c6f3ce25c27c16ec06435144b3bae2960ea..6eaf11791e08b1de669817ed7e0681ec205622b2 100644 | 
| --- a/chrome/browser/extensions/api/tabs/tabs_test.cc | 
| +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc | 
| @@ -20,9 +20,12 @@ | 
| #include "chrome/browser/ui/browser.h" | 
| #include "chrome/browser/ui/browser_commands.h" | 
| #include "chrome/browser/ui/browser_window.h" | 
| +#include "chrome/browser/ui/tabs/tab_strip_model.h" | 
| #include "chrome/test/base/in_process_browser_test.h" | 
| #include "chrome/test/base/ui_test_utils.h" | 
| +#include "content/public/common/page_zoom.h" | 
| #include "content/public/common/url_constants.h" | 
| +#include "extensions/common/manifest_constants.h" | 
| #include "ui/gfx/rect.h" | 
|  | 
| namespace extensions { | 
| @@ -591,4 +594,320 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DuplicateTabNoPermission) { | 
| EXPECT_FALSE(utils::HasPrivacySensitiveFields(duplicate_result.get())); | 
| } | 
|  | 
| +// Tester class for the tabs.zoom* api functions. | 
| +class ExtensionTabsZoomTest : public ExtensionTabsTest { | 
| + public: | 
| +  virtual void SetUpOnMainThread() OVERRIDE; | 
| + | 
| +  // Runs chrome.tabs.setZoom(). | 
| +  bool RunSetZoom(int tab_id, double zoom_factor); | 
| + | 
| +  // Runs chrome.tabs.getZoom(). | 
| +  testing::AssertionResult RunGetZoom(int tab_id, double* zoom_factor); | 
| + | 
| +  // Runs chrome.tabs.setZoomSettings(). | 
| +  bool RunSetZoomSettings(int tab_id, const char* mode, const char* scope); | 
| + | 
| +  // Runs chrome.tabs.getZoomSettings(). | 
| +  testing::AssertionResult RunGetZoomSettings(int tab_id, | 
| +                                              std::string* mode, | 
| +                                              std::string* scope); | 
| + | 
| +  // Runs chrome.tabs.setZoom(), expecting an error. | 
| +  std::string RunSetZoomExpectError(int tab_id, | 
| +                                    double zoom_factor); | 
| + | 
| +  // Runs chrome.tabs.setZoomSettings(), expecting an error. | 
| +  std::string RunSetZoomSettingsExpectError(int tab_id, | 
| +                                            const char* mode, | 
| +                                            const char* scope); | 
| + | 
| +  content::WebContents* OpenUrlAndWaitForLoad(const GURL& url); | 
| + | 
| + private: | 
| +  scoped_refptr<Extension> extension_; | 
| +}; | 
| + | 
| +void ExtensionTabsZoomTest::SetUpOnMainThread() { | 
| +  ExtensionTabsTest::SetUpOnMainThread(); | 
| +  extension_ = utils::CreateEmptyExtension(); | 
| +} | 
| + | 
| +bool ExtensionTabsZoomTest::RunSetZoom(int tab_id, double zoom_factor) { | 
| +  scoped_refptr<TabsSetZoomFunction> set_zoom_function( | 
| +      new TabsSetZoomFunction()); | 
| +  set_zoom_function->set_extension(extension_); | 
| +  set_zoom_function->set_has_callback(true); | 
| + | 
| +  return utils::RunFunction( | 
| +      set_zoom_function.get(), | 
| +      base::StringPrintf("[%u, %lf]", tab_id, zoom_factor), | 
| +      browser(), | 
| +      extension_function_test_utils::NONE); | 
| +} | 
| + | 
| +testing::AssertionResult ExtensionTabsZoomTest::RunGetZoom( | 
| +    int tab_id, | 
| +    double* zoom_factor) { | 
| +  scoped_refptr<TabsGetZoomFunction> get_zoom_function( | 
| +      new TabsGetZoomFunction()); | 
| +  get_zoom_function->set_extension(extension_); | 
| +  get_zoom_function->set_has_callback(true); | 
| + | 
| +  scoped_ptr<base::Value> get_zoom_result( | 
| +      utils::RunFunctionAndReturnSingleResult( | 
| +          get_zoom_function.get(), | 
| +          base::StringPrintf("[%u]", tab_id), | 
| +          browser())); | 
| + | 
| +  if (!get_zoom_result) | 
| +    return testing::AssertionFailure() << "no result"; | 
| +  if (!get_zoom_result->GetAsDouble(zoom_factor)) | 
| +    return testing::AssertionFailure() << "result was not a double"; | 
| + | 
| +  return testing::AssertionSuccess(); | 
| +} | 
| + | 
| +bool ExtensionTabsZoomTest::RunSetZoomSettings(int tab_id, | 
| +                                               const char* mode, | 
| +                                               const char* scope) { | 
| +  scoped_refptr<TabsSetZoomSettingsFunction> set_zoom_settings_function( | 
| +      new TabsSetZoomSettingsFunction()); | 
| +  set_zoom_settings_function->set_extension(extension_); | 
| + | 
| +  std::string args; | 
| +  if (scope) { | 
| +    args = base::StringPrintf("[%u, {\"mode\": \"%s\", \"scope\": \"%s\"}]", | 
| +                              tab_id, mode, scope); | 
| +  } else { | 
| +    args = base::StringPrintf("[%u, {\"mode\": \"%s\"}]", tab_id, mode); | 
| +  } | 
| + | 
| +  return utils::RunFunction(set_zoom_settings_function.get(), | 
| +                            args, | 
| +                            browser(), | 
| +                            extension_function_test_utils::NONE); | 
| +} | 
| + | 
| +testing::AssertionResult ExtensionTabsZoomTest::RunGetZoomSettings( | 
| +    int tab_id, | 
| +    std::string* mode, | 
| +    std::string* scope) { | 
| +  DCHECK(mode); | 
| +  DCHECK(scope); | 
| +  scoped_refptr<TabsGetZoomSettingsFunction> get_zoom_settings_function( | 
| +      new TabsGetZoomSettingsFunction()); | 
| +  get_zoom_settings_function->set_extension(extension_); | 
| +  get_zoom_settings_function->set_has_callback(true); | 
| + | 
| +  scoped_ptr<base::DictionaryValue> get_zoom_settings_result( | 
| +      utils::ToDictionary(utils::RunFunctionAndReturnSingleResult( | 
| +          get_zoom_settings_function.get(), | 
| +          base::StringPrintf("[%u]", tab_id), | 
| +          browser()))); | 
| + | 
| +  if (!get_zoom_settings_result) | 
| +    return testing::AssertionFailure() << "no result"; | 
| + | 
| +  *mode = utils::GetString(get_zoom_settings_result.get(), "mode"); | 
| +  *scope = utils::GetString(get_zoom_settings_result.get(), "scope"); | 
| + | 
| +  return testing::AssertionSuccess(); | 
| +} | 
| + | 
| +std::string ExtensionTabsZoomTest::RunSetZoomExpectError(int tab_id, | 
| +                                                         double zoom_factor) { | 
| +  scoped_refptr<TabsSetZoomFunction> set_zoom_function( | 
| +      new TabsSetZoomFunction()); | 
| +  set_zoom_function->set_extension(extension_); | 
| +  set_zoom_function->set_has_callback(true); | 
| + | 
| +  return utils::RunFunctionAndReturnError( | 
| +      set_zoom_function.get(), | 
| +      base::StringPrintf("[%u, %lf]", tab_id, zoom_factor), | 
| +      browser()); | 
| +} | 
| + | 
| +std::string ExtensionTabsZoomTest::RunSetZoomSettingsExpectError( | 
| +    int tab_id, | 
| +    const char* mode, | 
| +    const char* scope) { | 
| +  scoped_refptr<TabsSetZoomSettingsFunction> set_zoom_settings_function( | 
| +      new TabsSetZoomSettingsFunction()); | 
| +  set_zoom_settings_function->set_extension(extension_); | 
| + | 
| +  return utils::RunFunctionAndReturnError(set_zoom_settings_function.get(), | 
| +                                          base::StringPrintf( | 
| +                                              "[%u, {\"mode\": \"%s\", " | 
| +                                              "\"scope\": \"%s\"}]", | 
| +                                              tab_id, | 
| +                                              mode, | 
| +                                              scope), | 
| +                                          browser()); | 
| +} | 
| + | 
| +content::WebContents* ExtensionTabsZoomTest::OpenUrlAndWaitForLoad( | 
| +    const GURL& url) { | 
| +  ui_test_utils::NavigateToURLWithDisposition( | 
| +      browser(), | 
| +      url, | 
| +      NEW_FOREGROUND_TAB, | 
| +      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 
| +  return  browser()->tab_strip_model()->GetActiveWebContents(); | 
| +} | 
| + | 
| +namespace { | 
| + | 
| +double GetZoomLevel(const content::WebContents* web_contents) { | 
| +  return ZoomController::FromWebContents(web_contents)->GetZoomLevel(); | 
| +} | 
| + | 
| +content::OpenURLParams GetOpenParams(const char* url) { | 
| +  return content::OpenURLParams(GURL(url), | 
| +                                content::Referrer(), | 
| +                                NEW_FOREGROUND_TAB, | 
| +                                content::PAGE_TRANSITION_LINK, | 
| +                                false); | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, SetAndGetZoom) { | 
| +  content::OpenURLParams params(GetOpenParams(url::kAboutBlankURL)); | 
| +  content::WebContents* web_contents = OpenUrlAndWaitForLoad(params.url); | 
| +  int tab_id = ExtensionTabUtil::GetTabId(web_contents); | 
| + | 
| +  // Test default values before we set anything. | 
| +  double zoom_factor = -1; | 
| +  EXPECT_TRUE(RunGetZoom(tab_id, &zoom_factor)); | 
| +  EXPECT_EQ(1.0, zoom_factor); | 
| + | 
| +  // Test chrome.tabs.setZoom(). | 
| +  const double kZoomLevel = 0.8; | 
| +  EXPECT_TRUE(RunSetZoom(tab_id, kZoomLevel)); | 
| +  EXPECT_EQ(kZoomLevel, | 
| +            content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents))); | 
| + | 
| +  // Test chrome.tabs.getZoom(). | 
| +  zoom_factor = -1; | 
| +  EXPECT_TRUE(RunGetZoom(tab_id, &zoom_factor)); | 
| +  EXPECT_EQ(kZoomLevel, zoom_factor); | 
| +} | 
| + | 
| +IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, ZoomSettings) { | 
| +  const char kNewTestTabArgsA[] = "http://hostA/"; | 
| +  const char kNewTestTabArgsB[] = "http://hostB/"; | 
| + | 
| +  GURL url_A(kNewTestTabArgsA); | 
| +  GURL url_B(kNewTestTabArgsB); | 
| + | 
| +  // Tabs A1 and A2 are navigated to the same origin, while B is navigated | 
| +  // to a different one. | 
| +  content::WebContents* web_contents_A1 = OpenUrlAndWaitForLoad(url_A); | 
| +  content::WebContents* web_contents_A2 = OpenUrlAndWaitForLoad(url_A); | 
| +  content::WebContents* web_contents_B = OpenUrlAndWaitForLoad(url_B); | 
| + | 
| +  int tab_id_A1 = ExtensionTabUtil::GetTabId(web_contents_A1); | 
| +  int tab_id_A2 = ExtensionTabUtil::GetTabId(web_contents_A2); | 
| +  int tab_id_B = ExtensionTabUtil::GetTabId(web_contents_B); | 
| + | 
| +  ASSERT_FLOAT_EQ( | 
| +      1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); | 
| +  ASSERT_FLOAT_EQ( | 
| +      1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); | 
| +  ASSERT_FLOAT_EQ( | 
| +      1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B))); | 
| + | 
| +  // Test per-origin automatic zoom settings. | 
| +  EXPECT_TRUE(RunSetZoom(tab_id_B, 1.f)); | 
| +  EXPECT_TRUE(RunSetZoom(tab_id_A2, 1.1f)); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); | 
| +  EXPECT_FLOAT_EQ(1.f, | 
| +                  content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B))); | 
| + | 
| +  // Test per-tab automatic zoom settings. | 
| +  EXPECT_TRUE(RunSetZoomSettings(tab_id_A1, "automatic", "per-tab")); | 
| +  EXPECT_TRUE(RunSetZoom(tab_id_A1, 1.2f)); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.2f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); | 
| + | 
| +  // Test 'manual' mode. | 
| +  EXPECT_TRUE(RunSetZoomSettings(tab_id_A1, "manual", NULL)); | 
| +  EXPECT_TRUE(RunSetZoom(tab_id_A1, 1.3f)); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.3f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.1f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); | 
| + | 
| +  // Test 'disabled' mode, which will reset A1's zoom to 1.f. | 
| +  EXPECT_TRUE(RunSetZoomSettings(tab_id_A1, "disabled", NULL)); | 
| +  std::string error = RunSetZoomExpectError(tab_id_A1, 1.4f); | 
| +  EXPECT_TRUE(MatchPattern(error, keys::kCannotZoomDisabledTabError)); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1))); | 
| +  // We should still be able to zoom A2 though. | 
| +  EXPECT_TRUE(RunSetZoom(tab_id_A2, 1.4f)); | 
| +  EXPECT_FLOAT_EQ( | 
| +      1.4f, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2))); | 
| +} | 
| + | 
| +IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, GetZoomSettings) { | 
| +  content::OpenURLParams params(GetOpenParams(url::kAboutBlankURL)); | 
| +  content::WebContents* web_contents = OpenUrlAndWaitForLoad(params.url); | 
| +  int tab_id = ExtensionTabUtil::GetTabId(web_contents); | 
| + | 
| +  std::string mode; | 
| +  std::string scope; | 
| + | 
| +  EXPECT_TRUE(RunGetZoomSettings(tab_id, &mode, &scope)); | 
| +  EXPECT_EQ("automatic", mode); | 
| +  EXPECT_EQ("per-origin", scope); | 
| + | 
| +  EXPECT_TRUE(RunSetZoomSettings(tab_id, "automatic", "per-tab")); | 
| +  EXPECT_TRUE(RunGetZoomSettings(tab_id, &mode, &scope)); | 
| + | 
| +  EXPECT_EQ("automatic", mode); | 
| +  EXPECT_EQ("per-tab", scope); | 
| + | 
| +  std::string error = | 
| +      RunSetZoomSettingsExpectError(tab_id, "manual", "per-origin"); | 
| +  EXPECT_TRUE(MatchPattern(error, | 
| +                           keys::kPerOriginOnlyInAutomaticError)); | 
| +  error = | 
| +      RunSetZoomSettingsExpectError(tab_id, "disabled", "per-origin"); | 
| +  EXPECT_TRUE(MatchPattern(error, | 
| +                           keys::kPerOriginOnlyInAutomaticError)); | 
| +} | 
| + | 
| +IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, CannotZoomInvalidTab) { | 
| +  content::OpenURLParams params(GetOpenParams(url::kAboutBlankURL)); | 
| +  content::WebContents* web_contents = OpenUrlAndWaitForLoad(params.url); | 
| +  int tab_id = ExtensionTabUtil::GetTabId(web_contents); | 
| + | 
| +  int bogus_id = tab_id + 100; | 
| +  std::string error = RunSetZoomExpectError(bogus_id, 3.14159); | 
| +  EXPECT_TRUE(MatchPattern(error, keys::kTabNotFoundError)); | 
| + | 
| +  error = RunSetZoomSettingsExpectError(bogus_id, "manual", "per-tab"); | 
| +  EXPECT_TRUE(MatchPattern(error, keys::kTabNotFoundError)); | 
| + | 
| +  const char kNewTestTabArgs[] = "chrome://version"; | 
| +  params = GetOpenParams(kNewTestTabArgs); | 
| +  web_contents = browser()->OpenURL(params); | 
| +  tab_id = ExtensionTabUtil::GetTabId(web_contents); | 
| + | 
| +  // Test chrome.tabs.setZoom(). | 
| +  error = RunSetZoomExpectError(tab_id, 3.14159); | 
| +  EXPECT_TRUE(MatchPattern(error, manifest_errors::kCannotAccessChromeUrl)); | 
| + | 
| +  // chrome.tabs.setZoomSettings(). | 
| +  error = RunSetZoomSettingsExpectError(tab_id, "manual", "per-tab"); | 
| +  EXPECT_TRUE(MatchPattern(error, manifest_errors::kCannotAccessChromeUrl)); | 
| +} | 
| + | 
| }  // namespace extensions | 
|  |