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.
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"
28 namespace extensions
{
30 namespace keys
= tabs_constants
;
31 namespace utils
= extension_function_test_utils
;
35 class ExtensionTabsTest
: public InProcessBrowserTest
{
40 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetWindow
) {
41 int window_id
= ExtensionTabUtil::GetWindowId(browser());
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(
50 base::StringPrintf("[%u]", window_id
+ 1),
52 keys::kWindowNotFoundError
));
54 // Basic window details.
56 if (browser()->window()->IsMinimized())
57 bounds
= browser()->window()->GetRestoredBounds();
59 bounds
= browser()->window()->GetBounds();
61 function
= new WindowsGetFunction();
62 function
->set_extension(extension
.get());
63 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
64 utils::RunFunctionAndReturnSingleResult(
66 base::StringPrintf("[%u]", window_id
),
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"));
76 // With "populate" enabled.
77 function
= new WindowsGetFunction();
78 function
->set_extension(extension
.get());
79 result
.reset(utils::ToDictionary(
80 utils::RunFunctionAndReturnSingleResult(
82 base::StringPrintf("[%u, {\"populate\": true}]", window_id
),
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
));
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
93 EXPECT_EQ(browser()->window()->IsActive(),
94 utils::GetBoolean(result
.get(), "focused"));
96 // TODO(aa): Minimized and maximized dimensions. Is there a way to set
97 // minimize/maximize programmatically?
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(
109 "[%u]", ExtensionTabUtil::GetWindowId(popup_browser
)),
111 EXPECT_EQ("popup", utils::GetString(result
.get(), "type"));
114 Browser
* incognito_browser
= CreateIncognitoBrowser();
115 int incognito_window_id
= ExtensionTabUtil::GetWindowId(incognito_browser
);
117 // Without "include_incognito".
118 function
= new WindowsGetFunction();
119 function
->set_extension(extension
.get());
120 EXPECT_TRUE(MatchPattern(
121 utils::RunFunctionAndReturnError(
123 base::StringPrintf("[%u]", incognito_window_id
),
125 keys::kWindowNotFoundError
));
127 // With "include_incognito".
128 function
= new WindowsGetFunction();
129 function
->set_extension(extension
.get());
130 result
.reset(utils::ToDictionary(
131 utils::RunFunctionAndReturnSingleResult(
133 base::StringPrintf("[%u]", incognito_window_id
),
135 utils::INCLUDE_INCOGNITO
)));
136 EXPECT_TRUE(utils::GetBoolean(result
.get(), "incognito"));
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
);
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(),
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
));
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}]",
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
));
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()));
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
));
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(),
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"));
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
));
205 // The returned ids should contain all the current browser instance ids.
206 EXPECT_EQ(window_ids
, result_ids
);
209 function
= new WindowsGetAllFunction();
210 function
->set_extension(extension
.get());
211 result
.reset(utils::ToList(
212 utils::RunFunctionAndReturnSingleResult(function
.get(),
213 "[{\"populate\": true}]",
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"));
223 // "populate" was enabled so tabs should be populated.
224 base::ListValue
* tabs
= NULL
;
225 EXPECT_TRUE(result_window
->GetList(keys::kTabsKey
, &tabs
));
227 // The returned ids should contain all the current browser instance ids.
228 EXPECT_EQ(window_ids
, result_ids
);
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);
241 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
242 utils::RunFunctionAndReturnSingleResult(
243 update_tab_function
.get(),
244 "[null, {\"url\": \"about:blank\", \"pinned\": true}]",
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"));
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(
265 kArgsWithoutExplicitIncognitoParam
,
267 utils::INCLUDE_INCOGNITO
)));
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"));
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(
283 kArgsWithoutExplicitIncognitoParam
,
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"));
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(),
307 utils::INCLUDE_INCOGNITO
)));
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"));
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(),
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"));
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
);
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
,
348 keys::kIncognitoModeIsForced
));
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
,
359 keys::kIncognitoModeIsForced
));
362 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
363 DontCreateIncognitoWindowWhenIncognitoDisabled
) {
364 static const char kArgs
[] =
365 "[{\"url\": \"about:blank\", \"incognito\": true }]";
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(),
379 keys::kIncognitoModeIsDisabled
));
381 // Run in incognito window.
382 function
= new WindowsCreateFunction();
383 function
->set_extension(extension
.get());
384 EXPECT_TRUE(MatchPattern(
385 utils::RunFunctionAndReturnError(function
.get(),
388 keys::kIncognitoModeIsDisabled
));
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());
396 GURL
url(url::kAboutBlankURL
);
397 AddTabAtIndexToBrowser(browser(), 0, url
, content::PAGE_TRANSITION_LINK
);
398 int window_id
= ExtensionTabUtil::GetWindowId(browser());
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}]",
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
));
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}]",
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
));
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
);
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);
451 static const char kNewBlankTabArgs
[] =
452 "[{\"url\": \"about:blank\", \"windowId\": %u}]";
454 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
455 utils::RunFunctionAndReturnSingleResult(
456 create_tab_function
.get(),
457 base::StringPrintf(kNewBlankTabArgs
, window_id
),
460 EXPECT_NE(window_id
, utils::GetInteger(result
.get(), "windowId"));
463 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, InvalidUpdateWindowState
) {
464 int window_id
= ExtensionTabUtil::GetWindowId(browser());
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(
474 base::StringPrintf(kArgsMinimizedWithFocus
, window_id
),
476 keys::kInvalidWindowStateError
));
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(
485 base::StringPrintf(kArgsMaximizedWithoutFocus
, window_id
),
487 keys::kInvalidWindowStateError
));
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(
496 base::StringPrintf(kArgsMinimizedWithBounds
, window_id
),
498 keys::kInvalidWindowStateError
));
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(
507 base::StringPrintf(kArgsMaximizedWithBounds
, window_id
),
509 keys::kInvalidWindowStateError
));
512 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DuplicateTab
) {
513 content::OpenURLParams
params(GURL(url::kAboutBlankURL
),
516 content::PAGE_TRANSITION_LINK
,
518 content::WebContents
* web_contents
= browser()->OpenURL(params
);
519 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
520 int window_id
= ExtensionTabUtil::GetWindowIdOfTab(web_contents
);
522 TabStripModel
* tab_strip
;
523 ExtensionTabUtil::GetTabStripModel(web_contents
, &tab_strip
, &tab_index
);
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\"]}"
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);
536 scoped_ptr
<base::DictionaryValue
> duplicate_result(utils::ToDictionary(
537 utils::RunFunctionAndReturnSingleResult(
538 duplicate_tab_function
.get(), base::StringPrintf("[%u]", tab_id
),
541 int duplicate_tab_id
= utils::GetInteger(duplicate_result
.get(), "id");
542 int duplicate_tab_window_id
= utils::GetInteger(duplicate_result
.get(),
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()));
556 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DuplicateTabNoPermission
) {
557 content::OpenURLParams
params(GURL(url::kAboutBlankURL
),
560 content::PAGE_TRANSITION_LINK
,
562 content::WebContents
* web_contents
= browser()->OpenURL(params
);
563 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
564 int window_id
= ExtensionTabUtil::GetWindowIdOfTab(web_contents
);
566 TabStripModel
* tab_strip
;
567 ExtensionTabUtil::GetTabStripModel(web_contents
, &tab_strip
, &tab_index
);
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);
575 scoped_ptr
<base::DictionaryValue
> duplicate_result(utils::ToDictionary(
576 utils::RunFunctionAndReturnSingleResult(
577 duplicate_tab_function
.get(), base::StringPrintf("[%u]", tab_id
),
580 int duplicate_tab_id
= utils::GetInteger(duplicate_result
.get(), "id");
581 int duplicate_tab_window_id
= utils::GetInteger(duplicate_result
.get(),
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()));
594 } // namespace extensions