Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: chrome/browser/extensions/api/identity/identity_apitest.cc

Issue 14270007: Identity API: getAuthToken request queues (token cache prelude) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: fix test fixture init + address code review feedback Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/identity/identity_api.cc ('k') | chrome/browser/extensions/api/identity/identity_mint_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698