OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/string_util.h" | 5 #include "base/string_util.h" |
6 #include "base/stringprintf.h" | 6 #include "base/stringprintf.h" |
7 #include "base/values.h" | 7 #include "base/values.h" |
8 #include "chrome/browser/extensions/api/identity/identity_api.h" | 8 #include "chrome/browser/extensions/api/identity/identity_api.h" |
9 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" | 9 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" |
10 #include "chrome/browser/extensions/extension_apitest.h" | 10 #include "chrome/browser/extensions/extension_apitest.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 namespace extensions { | 32 namespace extensions { |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 namespace errors = identity_constants; | 36 namespace errors = identity_constants; |
37 namespace utils = extension_function_test_utils; | 37 namespace utils = extension_function_test_utils; |
38 | 38 |
39 static const char kAccessToken[] = "auth_token"; | 39 static const char kAccessToken[] = "auth_token"; |
40 | 40 |
| 41 // This helps us be able to wait until an AsyncExtensionFunction calls |
| 42 // SendResponse. |
| 43 class SendResponseDelegate |
| 44 : public UIThreadExtensionFunction::DelegateForTests { |
| 45 public: |
| 46 SendResponseDelegate() : should_post_quit_(false) {} |
| 47 |
| 48 virtual ~SendResponseDelegate() {} |
| 49 |
| 50 void set_should_post_quit(bool should_quit) { |
| 51 should_post_quit_ = should_quit; |
| 52 } |
| 53 |
| 54 bool HasResponse() { |
| 55 return response_.get() != NULL; |
| 56 } |
| 57 |
| 58 bool GetResponse() { |
| 59 EXPECT_TRUE(HasResponse()); |
| 60 return *response_.get(); |
| 61 } |
| 62 |
| 63 virtual void OnSendResponse(UIThreadExtensionFunction* function, |
| 64 bool success, |
| 65 bool bad_message) OVERRIDE { |
| 66 ASSERT_FALSE(bad_message); |
| 67 ASSERT_FALSE(HasResponse()); |
| 68 response_.reset(new bool); |
| 69 *response_ = success; |
| 70 if (should_post_quit_) { |
| 71 MessageLoopForUI::current()->Quit(); |
| 72 } |
| 73 } |
| 74 |
| 75 private: |
| 76 scoped_ptr<bool> response_; |
| 77 bool should_post_quit_; |
| 78 }; |
| 79 |
| 80 class AsyncExtensionBrowserTest : public ExtensionBrowserTest { |
| 81 protected: |
| 82 // Asynchronous function runner allows tests to manipulate the browser window |
| 83 // after the call happens. |
| 84 void RunFunctionAsync( |
| 85 UIThreadExtensionFunction* function, |
| 86 const std::string& args) { |
| 87 response_delegate_.reset(new SendResponseDelegate); |
| 88 function->set_test_delegate(response_delegate_.get()); |
| 89 scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args)); |
| 90 EXPECT_TRUE(parsed_args.get()) << |
| 91 "Could not parse extension function arguments: " << args; |
| 92 function->SetArgs(parsed_args.get()); |
| 93 |
| 94 if (!function->GetExtension()) { |
| 95 scoped_refptr<Extension> empty_extension( |
| 96 utils::CreateEmptyExtension()); |
| 97 function->set_extension(empty_extension.get()); |
| 98 } |
| 99 |
| 100 function->set_profile(browser()->profile()); |
| 101 function->set_has_callback(true); |
| 102 function->Run(); |
| 103 } |
| 104 |
| 105 std::string WaitForError(UIThreadExtensionFunction* function) { |
| 106 RunMessageLoopUntilResponse(); |
| 107 EXPECT_FALSE(function->GetResultList()) << "Did not expect a result"; |
| 108 return function->GetError(); |
| 109 } |
| 110 |
| 111 base::Value* WaitForSingleResult(UIThreadExtensionFunction* function) { |
| 112 RunMessageLoopUntilResponse(); |
| 113 EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: " |
| 114 << function->GetError(); |
| 115 const base::Value* single_result = NULL; |
| 116 if (function->GetResultList() != NULL && |
| 117 function->GetResultList()->Get(0, &single_result)) { |
| 118 return single_result->DeepCopy(); |
| 119 } |
| 120 return NULL; |
| 121 } |
| 122 |
| 123 private: |
| 124 void RunMessageLoopUntilResponse() { |
| 125 // If the RunImpl of |function| didn't already call SendResponse, run the |
| 126 // message loop until they do. |
| 127 if (!response_delegate_->HasResponse()) { |
| 128 response_delegate_->set_should_post_quit(true); |
| 129 content::RunMessageLoop(); |
| 130 } |
| 131 EXPECT_TRUE(response_delegate_->HasResponse()); |
| 132 } |
| 133 |
| 134 scoped_ptr<SendResponseDelegate> response_delegate_; |
| 135 }; |
| 136 |
41 class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow { | 137 class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow { |
42 public: | 138 public: |
43 enum ResultType { | 139 enum ResultType { |
44 ISSUE_ADVICE_SUCCESS, | 140 ISSUE_ADVICE_SUCCESS, |
45 MINT_TOKEN_SUCCESS, | 141 MINT_TOKEN_SUCCESS, |
46 MINT_TOKEN_FAILURE, | 142 MINT_TOKEN_FAILURE, |
47 MINT_TOKEN_BAD_CREDENTIALS | 143 MINT_TOKEN_BAD_CREDENTIALS |
48 }; | 144 }; |
49 | 145 |
50 TestOAuth2MintTokenFlow(ResultType result, | 146 TestOAuth2MintTokenFlow(ResultType result, |
(...skipping 26 matching lines...) Expand all Loading... |
77 break; | 173 break; |
78 } | 174 } |
79 } | 175 } |
80 } | 176 } |
81 | 177 |
82 private: | 178 private: |
83 ResultType result_; | 179 ResultType result_; |
84 OAuth2MintTokenFlow::Delegate* delegate_; | 180 OAuth2MintTokenFlow::Delegate* delegate_; |
85 }; | 181 }; |
86 | 182 |
| 183 ProfileKeyedService* IdentityAPITestFactory(Profile* profile) { |
| 184 return new IdentityAPI(profile); |
| 185 } |
| 186 |
87 } // namespace | 187 } // namespace |
88 | 188 |
89 class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction { | 189 class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction { |
90 public: | 190 public: |
91 MockGetAuthTokenFunction() : login_ui_result_(true), | 191 MockGetAuthTokenFunction() : login_ui_result_(true), |
92 install_ui_result_(false), | 192 install_ui_result_(false), |
93 login_ui_shown_(false), | 193 login_ui_shown_(false), |
94 install_ui_shown_(false) { | 194 install_ui_shown_(false) { |
95 } | 195 } |
96 | 196 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 OAuth2MintTokenFlow* (OAuth2MintTokenFlow::Mode mode)); | 235 OAuth2MintTokenFlow* (OAuth2MintTokenFlow::Mode mode)); |
136 | 236 |
137 private: | 237 private: |
138 ~MockGetAuthTokenFunction() {} | 238 ~MockGetAuthTokenFunction() {} |
139 bool login_ui_result_; | 239 bool login_ui_result_; |
140 bool install_ui_result_; | 240 bool install_ui_result_; |
141 bool login_ui_shown_; | 241 bool login_ui_shown_; |
142 bool install_ui_shown_; | 242 bool install_ui_shown_; |
143 }; | 243 }; |
144 | 244 |
145 class GetAuthTokenFunctionTest : public ExtensionBrowserTest { | 245 class MockQueuedMintRequest : public IdentityMintRequestQueue::Request { |
| 246 public: |
| 247 MOCK_METHOD1(StartMintToken, void(IdentityMintRequestQueue::MintType)); |
| 248 }; |
| 249 |
| 250 class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest { |
146 protected: | 251 protected: |
147 enum OAuth2Fields { | 252 enum OAuth2Fields { |
148 NONE = 0, | 253 NONE = 0, |
149 CLIENT_ID = 1, | 254 CLIENT_ID = 1, |
150 SCOPES = 2 | 255 SCOPES = 2 |
151 }; | 256 }; |
152 | 257 |
153 virtual ~GetAuthTokenFunctionTest() {} | 258 virtual ~GetAuthTokenFunctionTest() {} |
154 | 259 |
155 // Helper to create an extension with specific OAuth2Info fields set. | 260 // Helper to create an extension with specific OAuth2Info fields set. |
156 // |fields_to_set| should be computed by using fields of Oauth2Fields enum. | 261 // |fields_to_set| should be computed by using fields of Oauth2Fields enum. |
157 const Extension* CreateExtension(int fields_to_set) { | 262 const Extension* CreateExtension(int fields_to_set) { |
158 const Extension* ext = LoadExtension( | 263 const Extension* ext = LoadExtension( |
159 test_data_dir_.AppendASCII("platform_apps/oauth2")); | 264 test_data_dir_.AppendASCII("platform_apps/oauth2")); |
160 OAuth2Info& oauth2_info = const_cast<OAuth2Info&>( | 265 OAuth2Info& oauth2_info = const_cast<OAuth2Info&>( |
161 OAuth2Info::GetOAuth2Info(ext)); | 266 OAuth2Info::GetOAuth2Info(ext)); |
162 if ((fields_to_set & CLIENT_ID) != 0) | 267 if ((fields_to_set & CLIENT_ID) != 0) |
163 oauth2_info.client_id = "client1"; | 268 oauth2_info.client_id = "client1"; |
164 if ((fields_to_set & SCOPES) != 0) { | 269 if ((fields_to_set & SCOPES) != 0) { |
165 oauth2_info.scopes.push_back("scope1"); | 270 oauth2_info.scopes.push_back("scope1"); |
166 oauth2_info.scopes.push_back("scope2"); | 271 oauth2_info.scopes.push_back("scope2"); |
167 } | 272 } |
168 return ext; | 273 return ext; |
169 } | 274 } |
| 275 |
| 276 void InitializeTestAPIFactory() { |
| 277 IdentityAPI::GetFactoryInstance()->SetTestingFactory( |
| 278 browser()->profile(), &IdentityAPITestFactory); |
| 279 } |
170 }; | 280 }; |
171 | 281 |
172 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, | 282 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, |
173 NoClientId) { | 283 NoClientId) { |
174 scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction()); | 284 scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction()); |
175 func->set_extension(CreateExtension(SCOPES)); | 285 func->set_extension(CreateExtension(SCOPES)); |
176 std::string error = utils::RunFunctionAndReturnError( | 286 std::string error = utils::RunFunctionAndReturnError( |
177 func.get(), "[{}]", browser()); | 287 func.get(), "[{}]", browser()); |
178 EXPECT_EQ(std::string(errors::kInvalidClientId), error); | 288 EXPECT_EQ(std::string(errors::kInvalidClientId), error); |
179 EXPECT_FALSE(func->login_ui_shown()); | 289 EXPECT_FALSE(func->login_ui_shown()); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 .WillOnce(Return(flow2)); | 564 .WillOnce(Return(flow2)); |
455 | 565 |
456 func->set_install_ui_result(true); | 566 func->set_install_ui_result(true); |
457 std::string error = utils::RunFunctionAndReturnError( | 567 std::string error = utils::RunFunctionAndReturnError( |
458 func.get(), "[{\"interactive\": true}]", browser()); | 568 func.get(), "[{\"interactive\": true}]", browser()); |
459 EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false)); | 569 EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false)); |
460 EXPECT_FALSE(func->login_ui_shown()); | 570 EXPECT_FALSE(func->login_ui_shown()); |
461 EXPECT_TRUE(func->install_ui_shown()); | 571 EXPECT_TRUE(func->install_ui_shown()); |
462 } | 572 } |
463 | 573 |
464 // This helps us be able to wait until an AsyncExtensionFunction calls | 574 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveQueue) { |
465 // SendResponse. | 575 InitializeTestAPIFactory(); |
466 class SendResponseDelegate | 576 scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES)); |
467 : public UIThreadExtensionFunction::DelegateForTests { | 577 scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction()); |
468 public: | 578 func->set_extension(extension); |
469 SendResponseDelegate() : should_post_quit_(false) {} | |
470 | 579 |
471 virtual ~SendResponseDelegate() {} | 580 // Create a fake request to block the queue. |
| 581 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension); |
| 582 std::set<std::string> scopes(oauth2_info.scopes.begin(), |
| 583 oauth2_info.scopes.end()); |
| 584 IdentityAPI* id_api = |
| 585 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( |
| 586 browser()->profile()); |
| 587 IdentityMintRequestQueue* queue = id_api->mint_queue(); |
| 588 MockQueuedMintRequest queued_request; |
| 589 IdentityMintRequestQueue::MintType type = |
| 590 IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE; |
472 | 591 |
473 void set_should_post_quit(bool should_quit) { | 592 EXPECT_CALL(queued_request, StartMintToken(type)).Times(1); |
474 should_post_quit_ = should_quit; | 593 queue->RequestStart(type, extension->id(), scopes, &queued_request); |
475 } | |
476 | 594 |
477 bool HasResponse() { | 595 // The real request will start processing, but wait in the queue behind |
478 return response_.get() != NULL; | 596 // the blocker. |
479 } | 597 EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true)); |
| 598 RunFunctionAsync(func, "[{}]"); |
| 599 // Verify that we have fetched the login token at this point. |
| 600 testing::Mock::VerifyAndClearExpectations(func); |
480 | 601 |
481 bool GetResponse() { | 602 // The flow will be created after the first queued request clears. |
482 EXPECT_TRUE(HasResponse()); | 603 TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow( |
483 return *response_.get(); | 604 TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get()); |
484 } | 605 EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow)); |
485 | 606 |
486 virtual void OnSendResponse(UIThreadExtensionFunction* function, | 607 queue->RequestComplete(type, extension->id(), scopes, &queued_request); |
487 bool success, | |
488 bool bad_message) OVERRIDE { | |
489 ASSERT_FALSE(bad_message); | |
490 ASSERT_FALSE(HasResponse()); | |
491 response_.reset(new bool); | |
492 *response_ = success; | |
493 if (should_post_quit_) { | |
494 MessageLoopForUI::current()->Quit(); | |
495 } | |
496 } | |
497 | 608 |
498 private: | 609 scoped_ptr<base::Value> value(WaitForSingleResult(func)); |
499 scoped_ptr<bool> response_; | 610 std::string access_token; |
500 bool should_post_quit_; | 611 EXPECT_TRUE(value->GetAsString(&access_token)); |
501 }; | 612 EXPECT_EQ(std::string(kAccessToken), access_token); |
| 613 EXPECT_FALSE(func->login_ui_shown()); |
| 614 EXPECT_FALSE(func->install_ui_shown()); |
| 615 } |
502 | 616 |
503 class LaunchWebAuthFlowFunctionTest : public ExtensionBrowserTest { | 617 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueue) { |
| 618 InitializeTestAPIFactory(); |
| 619 scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES)); |
| 620 scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction()); |
| 621 func->set_extension(extension); |
| 622 |
| 623 // Create a fake request to block the queue. |
| 624 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension); |
| 625 std::set<std::string> scopes(oauth2_info.scopes.begin(), |
| 626 oauth2_info.scopes.end()); |
| 627 IdentityAPI* id_api = |
| 628 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( |
| 629 browser()->profile()); |
| 630 IdentityMintRequestQueue* queue = id_api->mint_queue(); |
| 631 MockQueuedMintRequest queued_request; |
| 632 IdentityMintRequestQueue::MintType type = |
| 633 IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE; |
| 634 |
| 635 EXPECT_CALL(queued_request, StartMintToken(type)).Times(1); |
| 636 queue->RequestStart(type, extension->id(), scopes, &queued_request); |
| 637 |
| 638 // The real request will start processing, but wait in the queue behind |
| 639 // the blocker. |
| 640 EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true)); |
| 641 TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow( |
| 642 TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get()); |
| 643 EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1)); |
| 644 RunFunctionAsync(func, "[{\"interactive\": true}]"); |
| 645 // Verify that we have fetched the login token and run the first flow. |
| 646 testing::Mock::VerifyAndClearExpectations(func); |
| 647 EXPECT_FALSE(func->install_ui_shown()); |
| 648 |
| 649 // The UI will be displayed and the second flow will be created |
| 650 // after the first queued request clears. |
| 651 func->set_install_ui_result(true); |
| 652 TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow( |
| 653 TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get()); |
| 654 EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow2)); |
| 655 |
| 656 queue->RequestComplete(type, extension->id(), scopes, &queued_request); |
| 657 |
| 658 scoped_ptr<base::Value> value(WaitForSingleResult(func)); |
| 659 std::string access_token; |
| 660 EXPECT_TRUE(value->GetAsString(&access_token)); |
| 661 EXPECT_EQ(std::string(kAccessToken), access_token); |
| 662 EXPECT_FALSE(func->login_ui_shown()); |
| 663 EXPECT_TRUE(func->install_ui_shown()); |
| 664 } |
| 665 |
| 666 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, |
| 667 InteractiveQueuedNoninteractiveFails) { |
| 668 InitializeTestAPIFactory(); |
| 669 scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES)); |
| 670 scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction()); |
| 671 func->set_extension(extension); |
| 672 |
| 673 // Create a fake request to block the interactive queue. |
| 674 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension); |
| 675 std::set<std::string> scopes(oauth2_info.scopes.begin(), |
| 676 oauth2_info.scopes.end()); |
| 677 IdentityAPI* id_api = |
| 678 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( |
| 679 browser()->profile()); |
| 680 IdentityMintRequestQueue* queue = id_api->mint_queue(); |
| 681 MockQueuedMintRequest queued_request; |
| 682 IdentityMintRequestQueue::MintType type = |
| 683 IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE; |
| 684 |
| 685 EXPECT_CALL(queued_request, StartMintToken(type)).Times(1); |
| 686 queue->RequestStart(type, extension->id(), scopes, &queued_request); |
| 687 |
| 688 // Non-interactive requests fail without hitting GAIA, because a |
| 689 // consent UI is known to be up. |
| 690 EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true)); |
| 691 std::string error = utils::RunFunctionAndReturnError( |
| 692 func.get(), "[{}]", browser()); |
| 693 EXPECT_EQ(std::string(errors::kNoGrant), error); |
| 694 EXPECT_FALSE(func->login_ui_shown()); |
| 695 EXPECT_FALSE(func->install_ui_shown()); |
| 696 |
| 697 queue->RequestComplete(type, extension->id(), scopes, &queued_request); |
| 698 } |
| 699 |
| 700 class LaunchWebAuthFlowFunctionTest : public AsyncExtensionBrowserTest { |
504 protected: | 701 protected: |
505 void RunAndCheckBounds( | 702 void RunAndCheckBounds( |
506 const std::string& extra_params, | 703 const std::string& extra_params, |
507 int expected_x, | 704 int expected_x, |
508 int expected_y, | 705 int expected_y, |
509 int expected_width, | 706 int expected_width, |
510 int expected_height) { | 707 int expected_height) { |
511 content::WindowedNotificationObserver observer( | 708 content::WindowedNotificationObserver observer( |
512 chrome::NOTIFICATION_BROWSER_WINDOW_READY, | 709 chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
513 content::NotificationService::AllSources()); | 710 content::NotificationService::AllSources()); |
(...skipping 13 matching lines...) Expand all Loading... |
527 Browser* web_auth_flow_browser = | 724 Browser* web_auth_flow_browser = |
528 content::Source<Browser>(observer.source()).ptr(); | 725 content::Source<Browser>(observer.source()).ptr(); |
529 EXPECT_EQ(expected_x, web_auth_flow_browser->override_bounds().x()); | 726 EXPECT_EQ(expected_x, web_auth_flow_browser->override_bounds().x()); |
530 EXPECT_EQ(expected_y, web_auth_flow_browser->override_bounds().y()); | 727 EXPECT_EQ(expected_y, web_auth_flow_browser->override_bounds().y()); |
531 EXPECT_EQ(expected_width, web_auth_flow_browser->override_bounds().width()); | 728 EXPECT_EQ(expected_width, web_auth_flow_browser->override_bounds().width()); |
532 EXPECT_EQ( | 729 EXPECT_EQ( |
533 expected_height, web_auth_flow_browser->override_bounds().height()); | 730 expected_height, web_auth_flow_browser->override_bounds().height()); |
534 | 731 |
535 web_auth_flow_browser->window()->Close(); | 732 web_auth_flow_browser->window()->Close(); |
536 } | 733 } |
537 | |
538 // Asynchronous function runner allows tests to manipulate the browser window | |
539 // after the call happens. | |
540 void RunFunctionAsync( | |
541 UIThreadExtensionFunction* function, | |
542 const std::string& args) { | |
543 response_delegate_.reset(new SendResponseDelegate); | |
544 function->set_test_delegate(response_delegate_.get()); | |
545 scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args)); | |
546 EXPECT_TRUE(parsed_args.get()) << | |
547 "Could not parse extension function arguments: " << args; | |
548 function->SetArgs(parsed_args.get()); | |
549 | |
550 scoped_refptr<Extension> empty_extension( | |
551 utils::CreateEmptyExtension()); | |
552 function->set_extension(empty_extension.get()); | |
553 | |
554 function->set_profile(browser()->profile()); | |
555 function->set_has_callback(true); | |
556 function->Run(); | |
557 } | |
558 | |
559 std::string WaitForError(UIThreadExtensionFunction* function) { | |
560 // If the RunImpl of |function| didn't already call SendResponse, run the | |
561 // message loop until they do. | |
562 if (!response_delegate_->HasResponse()) { | |
563 response_delegate_->set_should_post_quit(true); | |
564 content::RunMessageLoop(); | |
565 } | |
566 | |
567 EXPECT_TRUE(response_delegate_->HasResponse()); | |
568 return function->GetError(); | |
569 } | |
570 | |
571 private: | |
572 scoped_ptr<SendResponseDelegate> response_delegate_; | |
573 }; | 734 }; |
574 | 735 |
575 IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, Bounds) { | 736 IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, Bounds) { |
576 RunAndCheckBounds(std::string(), 0, 0, 0, 0); | 737 RunAndCheckBounds(std::string(), 0, 0, 0, 0); |
577 RunAndCheckBounds("\"width\": 100, \"height\": 200", 0, 0, 100, 200); | 738 RunAndCheckBounds("\"width\": 100, \"height\": 200", 0, 0, 100, 200); |
578 RunAndCheckBounds("\"left\": 100, \"top\": 200", 100, 200, 0, 0); | 739 RunAndCheckBounds("\"left\": 100, \"top\": 200", 100, 200, 0, 0); |
579 RunAndCheckBounds( | 740 RunAndCheckBounds( |
580 "\"left\": 100, \"top\": 200, \"width\": 300, \"height\": 400", | 741 "\"left\": 100, \"top\": 200, \"width\": 300, \"height\": 400", |
581 100, 200, 300, 400); | 742 100, 200, 300, 400); |
582 } | 743 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 "https://abcdefghij.chromiumapp.org/callback#test')</script>\"}]", | 861 "https://abcdefghij.chromiumapp.org/callback#test')</script>\"}]", |
701 browser())); | 862 browser())); |
702 | 863 |
703 std::string url; | 864 std::string url; |
704 EXPECT_TRUE(value->GetAsString(&url)); | 865 EXPECT_TRUE(value->GetAsString(&url)); |
705 EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"), | 866 EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"), |
706 url); | 867 url); |
707 } | 868 } |
708 | 869 |
709 } // namespace extensions | 870 } // namespace extensions |
OLD | NEW |