Home | History | Annotate | Download | only in tabs
      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 
      6 #include <string>
      7 
      8 #include "base/memory/ref_counted.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/values.h"
     14 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
     15 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
     16 #include "chrome/browser/extensions/extension_function_test_utils.h"
     17 #include "chrome/browser/extensions/extension_tab_util.h"
     18 #include "chrome/browser/prefs/incognito_mode_prefs.h"
     19 #include "chrome/browser/profiles/profile.h"
     20 #include "chrome/browser/ui/browser.h"
     21 #include "chrome/browser/ui/browser_commands.h"
     22 #include "chrome/browser/ui/browser_window.h"
     23 #include "chrome/test/base/in_process_browser_test.h"
     24 #include "chrome/test/base/ui_test_utils.h"
     25 #include "content/public/common/url_constants.h"
     26 #include "ui/gfx/rect.h"
     27 
     28 namespace extensions {
     29 
     30 namespace keys = tabs_constants;
     31 namespace utils = extension_function_test_utils;
     32 
     33 namespace {
     34 
     35 class ExtensionTabsTest : public InProcessBrowserTest {
     36 };
     37 
     38 }
     39 
     40 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) {
     41   int window_id = ExtensionTabUtil::GetWindowId(browser());
     42 
     43   // Invalid window ID error.
     44   scoped_refptr<WindowsGetFunction> function = new WindowsGetFunction();
     45   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
     46   function->set_extension(extension.get());
     47   EXPECT_TRUE(MatchPattern(
     48       utils::RunFunctionAndReturnError(
     49           function.get(),
     50           base::StringPrintf("[%u]", window_id + 1),
     51           browser()),
     52       keys::kWindowNotFoundError));
     53 
     54   // Basic window details.
     55   gfx::Rect bounds;
     56   if (browser()->window()->IsMinimized())
     57     bounds = browser()->window()->GetRestoredBounds();
     58   else
     59     bounds = browser()->window()->GetBounds();
     60 
     61   function = new WindowsGetFunction();
     62   function->set_extension(extension.get());
     63   scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
     64       utils::RunFunctionAndReturnSingleResult(
     65           function.get(),
     66           base::StringPrintf("[%u]", window_id),
     67           browser())));
     68   EXPECT_EQ(window_id, utils::GetInteger(result.get(), "id"));
     69   EXPECT_FALSE(utils::GetBoolean(result.get(), "incognito"));
     70   EXPECT_EQ("normal", utils::GetString(result.get(), "type"));
     71   EXPECT_EQ(bounds.x(), utils::GetInteger(result.get(), "left"));
     72   EXPECT_EQ(bounds.y(), utils::GetInteger(result.get(), "top"));
     73   EXPECT_EQ(bounds.width(), utils::GetInteger(result.get(), "width"));
     74   EXPECT_EQ(bounds.height(), utils::GetInteger(result.get(), "height"));
     75 
     76   // With "populate" enabled.
     77   function = new WindowsGetFunction();
     78   function->set_extension(extension.get());
     79   result.reset(utils::ToDictionary(
     80       utils::RunFunctionAndReturnSingleResult(
     81           function.get(),
     82           base::StringPrintf("[%u, {\"populate\": true}]", window_id),
     83           browser())));
     84 
     85   EXPECT_EQ(window_id, utils::GetInteger(result.get(), "id"));
     86   // "populate" was enabled so tabs should be populated.
     87   base::ListValue* tabs = NULL;
     88   EXPECT_TRUE(result.get()->GetList(keys::kTabsKey, &tabs));
     89 
     90   // TODO(aa): Can't assume window is focused. On mac, calling Activate() from a
     91   // browser test doesn't seem to do anything, so can't test the opposite
     92   // either.
     93   EXPECT_EQ(browser()->window()->IsActive(),
     94             utils::GetBoolean(result.get(), "focused"));
     95 
     96   // TODO(aa): Minimized and maximized dimensions. Is there a way to set
     97   // minimize/maximize programmatically?
     98 
     99   // Popup.
    100   Browser* popup_browser = new Browser(
    101       Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(),
    102                             browser()->host_desktop_type()));
    103   function = new WindowsGetFunction();
    104   function->set_extension(extension.get());
    105   result.reset(utils::ToDictionary(
    106       utils::RunFunctionAndReturnSingleResult(
    107           function.get(),
    108           base::StringPrintf(
    109               "[%u]", ExtensionTabUtil::GetWindowId(popup_browser)),
    110           browser())));
    111   EXPECT_EQ("popup", utils::GetString(result.get(), "type"));
    112 
    113   // Incognito.
    114   Browser* incognito_browser = CreateIncognitoBrowser();
    115   int incognito_window_id = ExtensionTabUtil::GetWindowId(incognito_browser);
    116 
    117   // Without "include_incognito".
    118   function = new WindowsGetFunction();
    119   function->set_extension(extension.get());
    120   EXPECT_TRUE(MatchPattern(
    121       utils::RunFunctionAndReturnError(
    122           function.get(),
    123           base::StringPrintf("[%u]", incognito_window_id),
    124           browser()),
    125       keys::kWindowNotFoundError));
    126 
    127   // With "include_incognito".
    128   function = new WindowsGetFunction();
    129   function->set_extension(extension.get());
    130   result.reset(utils::ToDictionary(
    131       utils::RunFunctionAndReturnSingleResult(
    132           function.get(),
    133           base::StringPrintf("[%u]", incognito_window_id),
    134           browser(),
    135           utils::INCLUDE_INCOGNITO)));
    136   EXPECT_TRUE(utils::GetBoolean(result.get(), "incognito"));
    137 }
    138 
    139 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetCurrentWindow) {
    140   int window_id = ExtensionTabUtil::GetWindowId(browser());
    141   Browser* new_browser = CreateBrowser(browser()->profile());
    142   int new_id = ExtensionTabUtil::GetWindowId(new_browser);
    143 
    144   // Get the current window using new_browser.
    145   scoped_refptr<WindowsGetCurrentFunction> function =
    146       new WindowsGetCurrentFunction();
    147   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    148   function->set_extension(extension.get());
    149   scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
    150       utils::RunFunctionAndReturnSingleResult(function.get(),
    151                                               "[]",
    152                                               new_browser)));
    153 
    154   // The id should match the window id of the browser instance that was passed
    155   // to RunFunctionAndReturnSingleResult.
    156   EXPECT_EQ(new_id, utils::GetInteger(result.get(), "id"));
    157   base::ListValue* tabs = NULL;
    158   EXPECT_FALSE(result.get()->GetList(keys::kTabsKey, &tabs));
    159 
    160   // Get the current window using the old window and make the tabs populated.
    161   function = new WindowsGetCurrentFunction();
    162   function->set_extension(extension.get());
    163   result.reset(utils::ToDictionary(
    164       utils::RunFunctionAndReturnSingleResult(function.get(),
    165                                               "[{\"populate\": true}]",
    166                                               browser())));
    167 
    168   // The id should match the window id of the browser instance that was passed
    169   // to RunFunctionAndReturnSingleResult.
    170   EXPECT_EQ(window_id, utils::GetInteger(result.get(), "id"));
    171   // "populate" was enabled so tabs should be populated.
    172   EXPECT_TRUE(result.get()->GetList(keys::kTabsKey, &tabs));
    173 }
    174 
    175 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetAllWindows) {
    176   const size_t NUM_WINDOWS = 5;
    177   std::set<int> window_ids;
    178   std::set<int> result_ids;
    179   window_ids.insert(ExtensionTabUtil::GetWindowId(browser()));
    180 
    181   for (size_t i = 0; i < NUM_WINDOWS - 1; ++i) {
    182     Browser* new_browser = CreateBrowser(browser()->profile());
    183     window_ids.insert(ExtensionTabUtil::GetWindowId(new_browser));
    184   }
    185 
    186   scoped_refptr<WindowsGetAllFunction> function = new WindowsGetAllFunction();
    187   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    188   function->set_extension(extension.get());
    189   scoped_ptr<base::ListValue> result(utils::ToList(
    190       utils::RunFunctionAndReturnSingleResult(function.get(),
    191                                               "[]",
    192                                               browser())));
    193 
    194   base::ListValue* windows = result.get();
    195   EXPECT_EQ(NUM_WINDOWS, windows->GetSize());
    196   for (size_t i = 0; i < NUM_WINDOWS; ++i) {
    197     base::DictionaryValue* result_window = NULL;
    198     EXPECT_TRUE(windows->GetDictionary(i, &result_window));
    199     result_ids.insert(utils::GetInteger(result_window, "id"));
    200 
    201     // "populate" was not passed in so tabs are not populated.
    202     base::ListValue* tabs = NULL;
    203     EXPECT_FALSE(result_window->GetList(keys::kTabsKey, &tabs));
    204   }
    205   // The returned ids should contain all the current browser instance ids.
    206   EXPECT_EQ(window_ids, result_ids);
    207 
    208   result_ids.clear();
    209   function = new WindowsGetAllFunction();
    210   function->set_extension(extension.get());
    211   result.reset(utils::ToList(
    212       utils::RunFunctionAndReturnSingleResult(function.get(),
    213                                               "[{\"populate\": true}]",
    214                                               browser())));
    215 
    216   windows = result.get();
    217   EXPECT_EQ(NUM_WINDOWS, windows->GetSize());
    218   for (size_t i = 0; i < windows->GetSize(); ++i) {
    219     base::DictionaryValue* result_window = NULL;
    220     EXPECT_TRUE(windows->GetDictionary(i, &result_window));
    221     result_ids.insert(utils::GetInteger(result_window, "id"));
    222 
    223     // "populate" was enabled so tabs should be populated.
    224     base::ListValue* tabs = NULL;
    225     EXPECT_TRUE(result_window->GetList(keys::kTabsKey, &tabs));
    226   }
    227   // The returned ids should contain all the current browser instance ids.
    228   EXPECT_EQ(window_ids, result_ids);
    229 }
    230 
    231 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, UpdateNoPermissions) {
    232   // The test empty extension has no permissions, therefore it should not get
    233   // tab data in the function result.
    234   scoped_refptr<TabsUpdateFunction> update_tab_function(
    235       new TabsUpdateFunction());
    236   scoped_refptr<Extension> empty_extension(utils::CreateEmptyExtension());
    237   update_tab_function->set_extension(empty_extension.get());
    238   // Without a callback the function will not generate a result.
    239   update_tab_function->set_has_callback(true);
    240 
    241   scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
    242       utils::RunFunctionAndReturnSingleResult(
    243           update_tab_function.get(),
    244           "[null, {\"url\": \"about:blank\", \"pinned\": true}]",
    245           browser())));
    246   // The url is stripped since the extension does not have tab permissions.
    247   EXPECT_FALSE(result->HasKey("url"));
    248   EXPECT_TRUE(utils::GetBoolean(result.get(), "pinned"));
    249 }
    250 
    251 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest,
    252                        DefaultToIncognitoWhenItIsForced) {
    253   static const char kArgsWithoutExplicitIncognitoParam[] =
    254       "[{\"url\": \"about:blank\"}]";
    255   // Force Incognito mode.
    256   IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
    257                                       IncognitoModePrefs::FORCED);
    258   // Run without an explicit "incognito" param.
    259   scoped_refptr<WindowsCreateFunction> function(new WindowsCreateFunction());
    260   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    261   function->set_extension(extension.get());
    262   scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
    263       utils::RunFunctionAndReturnSingleResult(
    264           function.get(),
    265           kArgsWithoutExplicitIncognitoParam,
    266           browser(),
    267           utils::INCLUDE_INCOGNITO)));
    268 
    269   // Make sure it is a new(different) window.
    270   EXPECT_NE(ExtensionTabUtil::GetWindowId(browser()),
    271             utils::GetInteger(result.get(), "id"));
    272   // ... and it is incognito.
    273   EXPECT_TRUE(utils::GetBoolean(result.get(), "incognito"));
    274 
    275   // Now try creating a window from incognito window.
    276   Browser* incognito_browser = CreateIncognitoBrowser();
    277   // Run without an explicit "incognito" param.
    278   function = new WindowsCreateFunction();
    279   function->set_extension(extension.get());
    280   result.reset(utils::ToDictionary(
    281       utils::RunFunctionAndReturnSingleResult(
    282           function.get(),
    283           kArgsWithoutExplicitIncognitoParam,
    284           incognito_browser,
    285           utils::INCLUDE_INCOGNITO)));
    286   // Make sure it is a new(different) window.
    287   EXPECT_NE(ExtensionTabUtil::GetWindowId(incognito_browser),
    288             utils::GetInteger(result.get(), "id"));
    289   // ... and it is incognito.
    290   EXPECT_TRUE(utils::GetBoolean(result.get(), "incognito"));
    291 }
    292 
    293 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest,
    294                        DefaultToIncognitoWhenItIsForcedAndNoArgs) {
    295   static const char kEmptyArgs[] = "[]";
    296   // Force Incognito mode.
    297   IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
    298                                       IncognitoModePrefs::FORCED);
    299   // Run without an explicit "incognito" param.
    300   scoped_refptr<WindowsCreateFunction> function = new WindowsCreateFunction();
    301   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    302   function->set_extension(extension.get());
    303   scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
    304       utils::RunFunctionAndReturnSingleResult(function.get(),
    305                                               kEmptyArgs,
    306                                               browser(),
    307                                               utils::INCLUDE_INCOGNITO)));
    308 
    309   // Make sure it is a new(different) window.
    310   EXPECT_NE(ExtensionTabUtil::GetWindowId(browser()),
    311             utils::GetInteger(result.get(), "id"));
    312   // ... and it is incognito.
    313   EXPECT_TRUE(utils::GetBoolean(result.get(), "incognito"));
    314 
    315   // Now try creating a window from incognito window.
    316   Browser* incognito_browser = CreateIncognitoBrowser();
    317   // Run without an explicit "incognito" param.
    318   function = new WindowsCreateFunction();
    319   function->set_extension(extension.get());
    320   result.reset(utils::ToDictionary(
    321       utils::RunFunctionAndReturnSingleResult(function.get(),
    322                                               kEmptyArgs,
    323                                               incognito_browser,
    324                                               utils::INCLUDE_INCOGNITO)));
    325   // Make sure it is a new(different) window.
    326   EXPECT_NE(ExtensionTabUtil::GetWindowId(incognito_browser),
    327             utils::GetInteger(result.get(), "id"));
    328   // ... and it is incognito.
    329   EXPECT_TRUE(utils::GetBoolean(result.get(), "incognito"));
    330 }
    331 
    332 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest,
    333                        DontCreateNormalWindowWhenIncognitoForced) {
    334   static const char kArgsWithExplicitIncognitoParam[] =
    335       "[{\"url\": \"about:blank\", \"incognito\": false }]";
    336   // Force Incognito mode.
    337   IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
    338                                       IncognitoModePrefs::FORCED);
    339 
    340   // Run with an explicit "incognito" param.
    341   scoped_refptr<WindowsCreateFunction> function = new WindowsCreateFunction();
    342   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    343   function->set_extension(extension.get());
    344   EXPECT_TRUE(MatchPattern(
    345       utils::RunFunctionAndReturnError(function.get(),
    346                                        kArgsWithExplicitIncognitoParam,
    347                                        browser()),
    348       keys::kIncognitoModeIsForced));
    349 
    350   // Now try opening a normal window from incognito window.
    351   Browser* incognito_browser = CreateIncognitoBrowser();
    352   // Run with an explicit "incognito" param.
    353   function = new WindowsCreateFunction();
    354   function->set_extension(extension.get());
    355   EXPECT_TRUE(MatchPattern(
    356       utils::RunFunctionAndReturnError(function.get(),
    357                                        kArgsWithExplicitIncognitoParam,
    358                                        incognito_browser),
    359       keys::kIncognitoModeIsForced));
    360 }
    361 
    362 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest,
    363                        DontCreateIncognitoWindowWhenIncognitoDisabled) {
    364   static const char kArgs[] =
    365       "[{\"url\": \"about:blank\", \"incognito\": true }]";
    366 
    367   Browser* incognito_browser = CreateIncognitoBrowser();
    368   // Disable Incognito mode.
    369   IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
    370                                       IncognitoModePrefs::DISABLED);
    371   // Run in normal window.
    372   scoped_refptr<WindowsCreateFunction> function = new WindowsCreateFunction();
    373   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    374   function->set_extension(extension.get());
    375   EXPECT_TRUE(MatchPattern(
    376       utils::RunFunctionAndReturnError(function.get(),
    377                                        kArgs,
    378                                        browser()),
    379       keys::kIncognitoModeIsDisabled));
    380 
    381   // Run in incognito window.
    382   function = new WindowsCreateFunction();
    383   function->set_extension(extension.get());
    384   EXPECT_TRUE(MatchPattern(
    385       utils::RunFunctionAndReturnError(function.get(),
    386                                        kArgs,
    387                                        incognito_browser),
    388       keys::kIncognitoModeIsDisabled));
    389 }
    390 
    391 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, QueryCurrentWindowTabs) {
    392   const size_t kExtraWindows = 3;
    393   for (size_t i = 0; i < kExtraWindows; ++i)
    394     CreateBrowser(browser()->profile());
    395 
    396   GURL url(url::kAboutBlankURL);
    397   AddTabAtIndexToBrowser(browser(), 0, url, content::PAGE_TRANSITION_LINK);
    398   int window_id = ExtensionTabUtil::GetWindowId(browser());
    399 
    400   // Get tabs in the 'current' window called from non-focused browser.
    401   scoped_refptr<TabsQueryFunction> function = new TabsQueryFunction();
    402   function->set_extension(utils::CreateEmptyExtension().get());
    403   scoped_ptr<base::ListValue> result(utils::ToList(
    404       utils::RunFunctionAndReturnSingleResult(function.get(),
    405                                               "[{\"currentWindow\":true}]",
    406                                               browser())));
    407 
    408   base::ListValue* result_tabs = result.get();
    409   // We should have one initial tab and one added tab.
    410   EXPECT_EQ(2u, result_tabs->GetSize());
    411   for (size_t i = 0; i < result_tabs->GetSize(); ++i) {
    412     base::DictionaryValue* result_tab = NULL;
    413     EXPECT_TRUE(result_tabs->GetDictionary(i, &result_tab));
    414     EXPECT_EQ(window_id, utils::GetInteger(result_tab, keys::kWindowIdKey));
    415   }
    416 
    417   // Get tabs NOT in the 'current' window called from non-focused browser.
    418   function = new TabsQueryFunction();
    419   function->set_extension(utils::CreateEmptyExtension().get());
    420   result.reset(utils::ToList(
    421       utils::RunFunctionAndReturnSingleResult(function.get(),
    422                                               "[{\"currentWindow\":false}]",
    423                                               browser())));
    424 
    425   result_tabs = result.get();
    426   // We should have one tab for each extra window.
    427   EXPECT_EQ(kExtraWindows, result_tabs->GetSize());
    428   for (size_t i = 0; i < kExtraWindows; ++i) {
    429     base::DictionaryValue* result_tab = NULL;
    430     EXPECT_TRUE(result_tabs->GetDictionary(i, &result_tab));
    431     EXPECT_NE(window_id, utils::GetInteger(result_tab, keys::kWindowIdKey));
    432   }
    433 }
    434 
    435 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DontCreateTabInClosingPopupWindow) {
    436   // Test creates new popup window, closes it right away and then tries to open
    437   // a new tab in it. Tab should not be opened in the popup window, but in a
    438   // tabbed browser window.
    439   Browser* popup_browser = new Browser(
    440       Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(),
    441                             browser()->host_desktop_type()));
    442   int window_id = ExtensionTabUtil::GetWindowId(popup_browser);
    443   chrome::CloseWindow(popup_browser);
    444 
    445   scoped_refptr<TabsCreateFunction> create_tab_function(
    446       new TabsCreateFunction());
    447   create_tab_function->set_extension(utils::CreateEmptyExtension().get());
    448   // Without a callback the function will not generate a result.
    449   create_tab_function->set_has_callback(true);
    450 
    451   static const char kNewBlankTabArgs[] =
    452       "[{\"url\": \"about:blank\", \"windowId\": %u}]";
    453 
    454   scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
    455       utils::RunFunctionAndReturnSingleResult(
    456           create_tab_function.get(),
    457           base::StringPrintf(kNewBlankTabArgs, window_id),
    458           browser())));
    459 
    460   EXPECT_NE(window_id, utils::GetInteger(result.get(), "windowId"));
    461 }
    462 
    463 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, InvalidUpdateWindowState) {
    464   int window_id = ExtensionTabUtil::GetWindowId(browser());
    465 
    466   static const char kArgsMinimizedWithFocus[] =
    467       "[%u, {\"state\": \"minimized\", \"focused\": true}]";
    468   scoped_refptr<WindowsUpdateFunction> function = new WindowsUpdateFunction();
    469   scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
    470   function->set_extension(extension.get());
    471   EXPECT_TRUE(MatchPattern(
    472       utils::RunFunctionAndReturnError(
    473           function.get(),
    474           base::StringPrintf(kArgsMinimizedWithFocus, window_id),
    475           browser()),
    476       keys::kInvalidWindowStateError));
    477 
    478   static const char kArgsMaximizedWithoutFocus[] =
    479       "[%u, {\"state\": \"maximized\", \"focused\": false}]";
    480   function = new WindowsUpdateFunction();
    481   function->set_extension(extension.get());
    482   EXPECT_TRUE(MatchPattern(
    483       utils::RunFunctionAndReturnError(
    484           function.get(),
    485           base::StringPrintf(kArgsMaximizedWithoutFocus, window_id),
    486           browser()),
    487       keys::kInvalidWindowStateError));
    488 
    489   static const char kArgsMinimizedWithBounds[] =
    490       "[%u, {\"state\": \"minimized\", \"width\": 500}]";
    491   function = new WindowsUpdateFunction();
    492   function->set_extension(extension.get());
    493   EXPECT_TRUE(MatchPattern(
    494       utils::RunFunctionAndReturnError(
    495           function.get(),
    496           base::StringPrintf(kArgsMinimizedWithBounds, window_id),
    497           browser()),
    498       keys::kInvalidWindowStateError));
    499 
    500   static const char kArgsMaximizedWithBounds[] =
    501       "[%u, {\"state\": \"maximized\", \"width\": 500}]";
    502   function = new WindowsUpdateFunction();
    503   function->set_extension(extension.get());
    504   EXPECT_TRUE(MatchPattern(
    505       utils::RunFunctionAndReturnError(
    506           function.get(),
    507           base::StringPrintf(kArgsMaximizedWithBounds, window_id),
    508           browser()),
    509       keys::kInvalidWindowStateError));
    510 }
    511 
    512 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DuplicateTab) {
    513   content::OpenURLParams params(GURL(url::kAboutBlankURL),
    514                                 content::Referrer(),
    515                                 NEW_FOREGROUND_TAB,
    516                                 content::PAGE_TRANSITION_LINK,
    517                                 false);
    518   content::WebContents* web_contents = browser()->OpenURL(params);
    519   int tab_id = ExtensionTabUtil::GetTabId(web_contents);
    520   int window_id = ExtensionTabUtil::GetWindowIdOfTab(web_contents);
    521   int tab_index = -1;
    522   TabStripModel* tab_strip;
    523   ExtensionTabUtil::GetTabStripModel(web_contents, &tab_strip, &tab_index);
    524 
    525   scoped_refptr<TabsDuplicateFunction> duplicate_tab_function(
    526       new TabsDuplicateFunction());
    527   scoped_ptr<base::DictionaryValue> test_extension_value(
    528       utils::ParseDictionary(
    529       "{\"name\": \"Test\", \"version\": \"1.0\", \"permissions\": [\"tabs\"]}"
    530       ));
    531   scoped_refptr<Extension> empty_tab_extension(
    532       utils::CreateExtension(test_extension_value.get()));
    533   duplicate_tab_function->set_extension(empty_tab_extension.get());
    534   duplicate_tab_function->set_has_callback(true);
    535 
    536   scoped_ptr<base::DictionaryValue> duplicate_result(utils::ToDictionary(
    537       utils::RunFunctionAndReturnSingleResult(
    538           duplicate_tab_function.get(), base::StringPrintf("[%u]", tab_id),
    539           browser())));
    540 
    541   int duplicate_tab_id = utils::GetInteger(duplicate_result.get(), "id");
    542   int duplicate_tab_window_id = utils::GetInteger(duplicate_result.get(),
    543                                                   "windowId");
    544   int duplicate_tab_index = utils::GetInteger(duplicate_result.get(), "index");
    545   EXPECT_EQ(base::Value::TYPE_DICTIONARY, duplicate_result->GetType());
    546   // Duplicate tab id should be different from the original tab id.
    547   EXPECT_NE(tab_id, duplicate_tab_id);
    548   EXPECT_EQ(window_id, duplicate_tab_window_id);
    549   EXPECT_EQ(tab_index + 1, duplicate_tab_index);
    550   // The test empty tab extension has tabs permissions, therefore
    551   // |duplicate_result| should contain url, title, and faviconUrl
    552   // in the function result.
    553   EXPECT_TRUE(utils::HasPrivacySensitiveFields(duplicate_result.get()));
    554 }
    555 
    556 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DuplicateTabNoPermission) {
    557   content::OpenURLParams params(GURL(url::kAboutBlankURL),
    558                                 content::Referrer(),
    559                                 NEW_FOREGROUND_TAB,
    560                                 content::PAGE_TRANSITION_LINK,
    561                                 false);
    562   content::WebContents* web_contents = browser()->OpenURL(params);
    563   int tab_id = ExtensionTabUtil::GetTabId(web_contents);
    564   int window_id = ExtensionTabUtil::GetWindowIdOfTab(web_contents);
    565   int tab_index = -1;
    566   TabStripModel* tab_strip;
    567   ExtensionTabUtil::GetTabStripModel(web_contents, &tab_strip, &tab_index);
    568 
    569   scoped_refptr<TabsDuplicateFunction> duplicate_tab_function(
    570       new TabsDuplicateFunction());
    571   scoped_refptr<Extension> empty_extension(utils::CreateEmptyExtension());
    572   duplicate_tab_function->set_extension(empty_extension.get());
    573   duplicate_tab_function->set_has_callback(true);
    574 
    575   scoped_ptr<base::DictionaryValue> duplicate_result(utils::ToDictionary(
    576       utils::RunFunctionAndReturnSingleResult(
    577           duplicate_tab_function.get(), base::StringPrintf("[%u]", tab_id),
    578           browser())));
    579 
    580   int duplicate_tab_id = utils::GetInteger(duplicate_result.get(), "id");
    581   int duplicate_tab_window_id = utils::GetInteger(duplicate_result.get(),
    582                                                   "windowId");
    583   int duplicate_tab_index = utils::GetInteger(duplicate_result.get(), "index");
    584   EXPECT_EQ(base::Value::TYPE_DICTIONARY, duplicate_result->GetType());
    585   // Duplicate tab id should be different from the original tab id.
    586   EXPECT_NE(tab_id, duplicate_tab_id);
    587   EXPECT_EQ(window_id, duplicate_tab_window_id);
    588   EXPECT_EQ(tab_index + 1, duplicate_tab_index);
    589   // The test empty extension has no permissions, therefore |duplicate_result|
    590   // should not contain url, title, and faviconUrl in the function result.
    591   EXPECT_FALSE(utils::HasPrivacySensitiveFields(duplicate_result.get()));
    592 }
    593 
    594 }  // namespace extensions
    595