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

Side by Side Diff: chrome/browser/extensions/api/web_request/web_request_api_unittest.cc

Issue 10694055: Add read-only access to POST data for webRequest's onBeforeRequest (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Now checking the channel for real Created 8 years, 4 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 <queue> 5 #include <queue>
6 #include <map> 6 #include <map>
7 7
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/json/json_reader.h"
11 #include "base/json/json_string_value_serializer.h" 12 #include "base/json/json_string_value_serializer.h"
12 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop.h" 14 #include "base/message_loop.h"
14 #include "base/path_service.h" 15 #include "base/path_service.h"
15 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/string_piece.h"
16 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
17 #include "chrome/browser/content_settings/cookie_settings.h" 19 #include "chrome/browser/content_settings/cookie_settings.h"
18 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 20 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
19 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" 21 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h"
20 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" 22 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
21 #include "chrome/browser/extensions/event_router_forwarder.h" 23 #include "chrome/browser/extensions/event_router_forwarder.h"
22 #include "chrome/browser/net/chrome_network_delegate.h" 24 #include "chrome/browser/net/chrome_network_delegate.h"
23 #include "chrome/browser/prefs/pref_member.h" 25 #include "chrome/browser/prefs/pref_member.h"
24 #include "chrome/common/extensions/extension_messages.h" 26 #include "chrome/common/extensions/extension_messages.h"
25 #include "chrome/common/pref_names.h" 27 #include "chrome/common/pref_names.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 } 68 }
67 69
68 // Searches |key| in |collection| by iterating over its elements and returns 70 // Searches |key| in |collection| by iterating over its elements and returns
69 // true if found. 71 // true if found.
70 template <typename Collection, typename Key> 72 template <typename Collection, typename Key>
71 bool Contains(const Collection& collection, const Key& key) { 73 bool Contains(const Collection& collection, const Key& key) {
72 return std::find(collection.begin(), collection.end(), key) != 74 return std::find(collection.begin(), collection.end(), key) !=
73 collection.end(); 75 collection.end();
74 } 76 }
75 77
78 // Parses |json_string| as a Value. Returns NULL on failure. The caller owns
79 // the returned object.
80 const Value* GetValueFromJson(const base::StringPiece& json_string) {
81 const Value* parsed = base::JSONReader::Read(json_string);
82 return parsed;
83 }
84
85 // Parses |json_string| as a DictionaryValue. Returns NULL on failure. The
86 // caller owns the returned object.
87 const DictionaryValue* GetDictionaryFromJson(
88 const base::StringPiece& json_string) {
89 const Value* value = GetValueFromJson(json_string);
90 if (value == NULL)
91 return NULL;
92 // Now we own the object pointed to by |value|.
93 const DictionaryValue* dictionary = NULL;
94 if (value->GetAsDictionary(&dictionary)) {
95 // We pass the ownership of the object |value|==|dictionary| to the caller.
96 return dictionary;
97 } else {
98 // The object at |value| is no longer needed.
99 delete value;
Matt Perry 2012/08/01 09:46:31 Prefer using scoped_ptr<Value> for stuff like this
vabr (Chromium) 2012/08/01 18:03:22 Done.
100 return NULL;
101 }
102 }
103
104 // Parses the JSON data attached to the |message| and tries to return it.
105 // Returns NULL on failure.
106 scoped_ptr<const DictionaryValue> GetPartOfMessageArguments(
107 IPC::Message* message) {
108 CHECK(message->type() == ExtensionMsg_MessageInvoke::ID);
Matt Perry 2012/08/01 09:46:31 Don't use CHECK in tests. If it fails, you bring d
vabr (Chromium) 2012/08/01 18:03:22 Needed to use EXPECT_*, because ASSERT_* does not
109 ExtensionMsg_MessageInvoke::Param param;
110 Value* temp_value = NULL;
111 CHECK(ExtensionMsg_MessageInvoke::Read(message, &param));
112 CHECK(param.c.GetSize() >= 2);
113 CHECK(param.c.Get(1, &temp_value));
114 std::string args;
115 CHECK(temp_value->GetAsString(&args));
116 const Value* value = GetValueFromJson(args);
117 if (value == NULL) {
118 DLOG(INFO) << "Failed to parse JSON in the message arguments.";
Matt Perry 2012/08/01 09:46:31 Do these messages represent test failures? If so,
vabr (Chromium) 2012/08/01 18:03:22 Unified with the redone CHECKs above.
119 return scoped_ptr<const DictionaryValue>();
120 }
121 const ListValue* list = NULL;
122 if (!value->GetAsList(&list)) {
123 DLOG(INFO) << "Parsed message argument is not a ListValue.";
124 return scoped_ptr<const DictionaryValue>();
125 }
126 scoped_ptr<const ListValue> list_scoped(list); // To ensure clean-up.
Matt Perry 2012/08/01 09:46:31 comment is unnecessary
vabr (Chromium) 2012/08/01 18:03:22 Done.
127 if (list->GetSize() != 1) {
128 DLOG(INFO) << "The Listvalue in message arguments has not size 1.";
129 return scoped_ptr<const DictionaryValue>();
130 }
131 // TODO(vabr): Add const once ListValue getters get corrected.
Matt Perry 2012/08/01 09:46:31 Realistically, this will never happen :). Just rem
vabr (Chromium) 2012/08/01 18:03:22 Oh it will happen, that CL (10837044) is done, rev
132 DictionaryValue* dictionary = NULL;
133 if (!list->GetDictionary(0, &dictionary)) {
134 DLOG(INFO) << "The only Value in the list in message arguments"
135 "is not a DictionaryiValue.";
136 return scoped_ptr<const DictionaryValue>();
137 }
138 return scoped_ptr<const DictionaryValue>(dictionary->DeepCopy());
139 }
140
76 } // namespace 141 } // namespace
77 142
78 // A mock event router that responds to events with a pre-arranged queue of 143 // A mock event router that responds to events with a pre-arranged queue of
79 // Tasks. 144 // Tasks.
80 class TestIPCSender : public IPC::Sender { 145 class TestIPCSender : public IPC::Sender {
81 public: 146 public:
82 typedef std::list<linked_ptr<IPC::Message> > SentMessages; 147 typedef std::list<linked_ptr<IPC::Message> > SentMessages;
83 148
84 // Adds a Task to the queue. We will fire these in order as events are 149 // Adds a Task to the queue. We will fire these in order as events are
85 // dispatched. 150 // dispatched.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL); 192 prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL);
128 network_delegate_.reset(new ChromeNetworkDelegate( 193 network_delegate_.reset(new ChromeNetworkDelegate(
129 event_router_.get(), NULL, NULL, &profile_, 194 event_router_.get(), NULL, NULL, &profile_,
130 CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_, 195 CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_,
131 NULL)); 196 NULL));
132 context_.reset(new TestURLRequestContext(true)); 197 context_.reset(new TestURLRequestContext(true));
133 context_->set_network_delegate(network_delegate_.get()); 198 context_->set_network_delegate(network_delegate_.get());
134 context_->Init(); 199 context_->Init();
135 } 200 }
136 201
202 // Fires a URLRequest with the specified |content_type|. Method will be "POST"
203 // and the data will be |bytes|.
204 void FireURLRequestWithPostData(const char* content_type,
205 const char* bytes, size_t bytes_length);
206
137 MessageLoopForIO message_loop_; 207 MessageLoopForIO message_loop_;
138 content::TestBrowserThread ui_thread_; 208 content::TestBrowserThread ui_thread_;
139 content::TestBrowserThread io_thread_; 209 content::TestBrowserThread io_thread_;
140 TestingProfile profile_; 210 TestingProfile profile_;
141 TestDelegate delegate_; 211 TestDelegate delegate_;
142 BooleanPrefMember enable_referrers_; 212 BooleanPrefMember enable_referrers_;
143 TestIPCSender ipc_sender_; 213 TestIPCSender ipc_sender_;
144 scoped_refptr<extensions::EventRouterForwarder> event_router_; 214 scoped_refptr<extensions::EventRouterForwarder> event_router_;
145 scoped_refptr<ExtensionInfoMap> extension_info_map_; 215 scoped_refptr<ExtensionInfoMap> extension_info_map_;
146 scoped_ptr<ChromeNetworkDelegate> network_delegate_; 216 scoped_ptr<ChromeNetworkDelegate> network_delegate_;
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 EXPECT_TRUE(!request.is_pending()); 462 EXPECT_TRUE(!request.is_pending());
393 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); 463 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status());
394 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); 464 EXPECT_EQ(net::ERR_ABORTED, request.status().error());
395 EXPECT_EQ(request_url, request.url()); 465 EXPECT_EQ(request_url, request.url());
396 EXPECT_EQ(1U, request.url_chain().size()); 466 EXPECT_EQ(1U, request.url_chain().size());
397 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); 467 EXPECT_EQ(0U, ipc_sender_.GetNumTasks());
398 468
399 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( 469 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
400 &profile_, extension_id, kEventName + "/1"); 470 &profile_, extension_id, kEventName + "/1");
401 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( 471 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
402 &profile_, extension_id, kEventName2 + "/1"); 472 &profile_, extension_id, kEventName2 + "/1");
473 }
474
475 namespace {
476
477 // Based on the string with extraInfoSpec |values|, create the numerical
478 // representation. Returns true on success, otherwise false.
479 bool GenerateInfoSpec(const std::string& values, int* result) {
480 // Create a ListValue of strings.
481 std::vector<std::string> split_values;
482 scoped_ptr<base::ListValue> list_value(new base::ListValue());
483 size_t num_values = Tokenize(values, ",", &split_values);
484 for (size_t i = 0; i < num_values ; ++i)
485 list_value->Append(new base::StringValue(split_values[i]));
486 return ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
487 *list_value, result);
488 }
489
490 } // namespace
491
492 void ExtensionWebRequestTest::FireURLRequestWithPostData(
493 const char* content_type,
494 const char* bytes, size_t bytes_length) {
495 // The request URL can be arbitrary but must have an HTTP or HTTPS scheme.
496 GURL request_url("http://www.example.com");
497 net::URLRequest request(request_url, &delegate_, context_.get());
498 request.set_method("POST");
499 request.SetExtraRequestHeaderByName(
500 net::HttpRequestHeaders::kContentType, content_type, true);
501 request.AppendBytesToUpload(bytes, bytes_length);
502 ipc_sender_.PushTask(base::Bind(&base::DoNothing));
503 request.Start();
504 }
505
506 TEST_F(ExtensionWebRequestTest, AccessPostData) {
507 // We verify that POST data are accessible to OnBeforeRequest listeners.
508 // Three testing steps:
509 // 1. Register an extension requesting ExtraInfoSpec::POST_DATA and file a
510 // URLRequest with a multipart-encoded form. See it getting parsed.
511 // 2. Do the same, but without requesting ExtraInfoSpec::POST_DATA. Nothing
512 // should be parsed.
513 // 3. With ExtraInfoSpec::POST_DATA, fire a URLRequest with a chunked
514 // upload. Get the error message.
515 // This test is done also for channels other than dev or canary, when
516 // PostData access is not enabled. In that case steps 1 and 3 should give the
517 // same result as step 2.
518 #define kBoundary "THIS_IS_A_BOUNDARY"
519 #define kBlock "--" kBoundary "\r\n" \
520 "Content-Disposition: form-data; name=\"text\"\r\n" \
521 "\r\n" \
522 "test text\r\n" \
523 "--" kBoundary "--"
524 // POST data input.
525 const char kMultipartBytes[] = kBlock;
526 // Expected POST data output.
527 const std::string kPostDataPath(keys::kPostDataKey);
528 const std::string kFormDataPath(kPostDataPath + "." + keys::kFormDataKey);
529 const std::string kErrorPath(kPostDataPath + "." + keys::kPostDataErrorKey);
530 const std::string* kPath[] = {&kFormDataPath, &kPostDataPath, &kErrorPath};
531 // formData
532 const char kFormDataString[] = "{\"text\":[\"test text\"]}";
533 scoped_ptr<const DictionaryValue> form_data(
534 GetDictionaryFromJson(kFormDataString));
535 ASSERT_TRUE(form_data.get() != NULL);
536 // error
537 const StringValue error("chunked_encoding");
538 // Summary.
539 const Value* kExpected[] = {form_data.get(), NULL, &error};
540 // Header.
541 const char kMultipart[] = "multipart/form-data; boundary=" kBoundary;
542 #undef kBlock
543 #undef kBoundary
544
545 // Set up a dummy extension name.
546 ExtensionWebRequestEventRouter::RequestFilter filter;
547 std::string extension_id("1");
548 const std::string string_spec_post("blocking,postData");
549 const std::string string_spec_no_post("blocking");
550 int extra_info_spec_no_post;
551 int extra_info_spec_post;
552 ASSERT_TRUE(GenerateInfoSpec(string_spec_post, &extra_info_spec_post));
553 ASSERT_TRUE(GenerateInfoSpec(string_spec_no_post, &extra_info_spec_no_post));
554
555 // Part 1.
556 // Subscribe to OnBeforeRequest with POST data requirement.
557 const std::string kEventName(keys::kOnBeforeRequest);
558 base::WeakPtrFactory<TestIPCSender> ipc_sender_factory(&ipc_sender_);
559 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
560 &profile_, extension_id, extension_id, kEventName, kEventName + "/1",
561 filter, extra_info_spec_post, ipc_sender_factory.GetWeakPtr());
562
563 FireURLRequestWithPostData(
564 kMultipart, kMultipartBytes, strlen(kMultipartBytes));
565
566 MessageLoop::current()->RunAllPending();
567
568 // Part 2.
569 // Now remove the requirement of POST data.
570 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
571 &profile_, extension_id, kEventName + "/1");
572 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
573 &profile_, extension_id, extension_id, kEventName, kEventName + "/1",
574 filter, extra_info_spec_no_post, ipc_sender_factory.GetWeakPtr());
575
576 FireURLRequestWithPostData(
577 kMultipart, kMultipartBytes, strlen(kMultipartBytes));
578
579 // Part 3.
580 // Get back the requirement of POST data.
581 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
582 &profile_, extension_id, kEventName + "/1");
583 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
584 &profile_, extension_id, extension_id, kEventName, kEventName + "/1",
585 filter, extra_info_spec_post, ipc_sender_factory.GetWeakPtr());
586 {
587 GURL request_url("http://www.example.com");
588 net::URLRequest request(request_url, &delegate_, context_.get());
589 request.set_method("POST");
590 request.EnableChunkedUpload();
591 const char kDummyBytes[] = "dummy";
592 request.AppendChunkToUpload(kDummyBytes, strlen(kDummyBytes), true);
593 net::HttpRequestHeaders headers(request.extra_request_headers());
594 headers.SetHeader(net::HttpRequestHeaders::kTransferEncoding, "chunked");
595 request.SetExtraRequestHeaders(headers);
596 ipc_sender_.PushTask(base::Bind(&base::DoNothing));
597 request.Start();
598 }
599
600 MessageLoop::current()->RunAllPending();
601
602 IPC::Message* message = NULL;
603 TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin();
604 for (size_t test = 0; test < arraysize(kExpected); ++test) {
605 EXPECT_NE(i, ipc_sender_.sent_end());
606 message = (i++)->get();
607 scoped_ptr<const DictionaryValue>
608 details(GetPartOfMessageArguments(message).Pass());
609 ASSERT_TRUE(details.get() != NULL);
610 const Value* result = NULL;
611 const bool anything_expected = IsPostDataEnabled() &&
612 kExpected[test] != NULL;
613 EXPECT_EQ(anything_expected, details->Get(*(kPath[test]), &result));
614 if (anything_expected) {
615 EXPECT_TRUE(kExpected[test]->Equals(result));
616 }
617 }
618
619 EXPECT_EQ(i, ipc_sender_.sent_end());
620
621 // Clean-up.
622 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
623 &profile_, extension_id, kEventName + "/1");
403 } 624 }
404 625
405 struct HeaderModificationTest_Header { 626 struct HeaderModificationTest_Header {
406 const char* name; 627 const char* name;
407 const char* value; 628 const char* value;
408 }; 629 };
409 630
410 struct HeaderModificationTest_Modification { 631 struct HeaderModificationTest_Modification {
411 enum Type { 632 enum Type {
412 SET, 633 SET,
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( 843 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
623 &profile_, extension2_id, kEventName + "/2"); 844 &profile_, extension2_id, kEventName + "/2");
624 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( 845 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
625 &profile_, extension3_id, std::string(keys::kOnSendHeaders) + "/3"); 846 &profile_, extension3_id, std::string(keys::kOnSendHeaders) + "/3");
626 }; 847 };
627 848
628 namespace { 849 namespace {
629 850
630 void TestInitFromValue(const std::string& values, bool expected_return_code, 851 void TestInitFromValue(const std::string& values, bool expected_return_code,
631 int expected_extra_info_spec) { 852 int expected_extra_info_spec) {
632 // Create a ListValue of strings.
633 std::vector<std::string> split_values;
634 scoped_ptr<base::ListValue> list_value(new base::ListValue());
635 size_t num_values = Tokenize(values, ",", &split_values);
636 for (size_t i = 0; i < num_values ; ++i)
637 list_value->Append(new base::StringValue(split_values[i]));
638 int actual_info_spec; 853 int actual_info_spec;
639 bool actual_return_code = 854 bool actual_return_code = GenerateInfoSpec(values, &actual_info_spec);
640 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
641 *list_value, &actual_info_spec);
642 EXPECT_EQ(expected_return_code, actual_return_code); 855 EXPECT_EQ(expected_return_code, actual_return_code);
643 if (expected_return_code) 856 if (expected_return_code)
644 EXPECT_EQ(expected_extra_info_spec, actual_info_spec); 857 EXPECT_EQ(expected_extra_info_spec, actual_info_spec);
645 } 858 }
646 859
647 } 860 }
648 TEST_F(ExtensionWebRequestTest, InitFromValue) { 861 TEST_F(ExtensionWebRequestTest, InitFromValue) {
649 TestInitFromValue("", true, 0); 862 TestInitFromValue("", true, 0);
650 863
651 // Single valid values. 864 // Single valid values.
652 TestInitFromValue( 865 TestInitFromValue(
653 "requestHeaders", 866 "requestHeaders",
654 true, 867 true,
655 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS); 868 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS);
656 TestInitFromValue( 869 TestInitFromValue(
657 "responseHeaders", 870 "responseHeaders",
658 true, 871 true,
659 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); 872 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS);
660 TestInitFromValue( 873 TestInitFromValue(
661 "blocking", 874 "blocking",
662 true, 875 true,
663 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); 876 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING);
664 TestInitFromValue( 877 TestInitFromValue(
665 "asyncBlocking", 878 "asyncBlocking",
666 true, 879 true,
667 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); 880 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING);
881 TestInitFromValue(
882 "postData",
883 IsPostDataEnabled(),
884 ExtensionWebRequestEventRouter::ExtraInfoSpec::POST_DATA);
668 885
669 // Multiple valid values are bitwise-or'ed. 886 // Multiple valid values are bitwise-or'ed.
670 TestInitFromValue( 887 TestInitFromValue(
671 "requestHeaders,blocking", 888 "requestHeaders,blocking",
672 true, 889 true,
673 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | 890 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS |
674 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); 891 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING);
675 892
676 // Any invalid values lead to a bad parse. 893 // Any invalid values lead to a bad parse.
677 TestInitFromValue("invalidValue", false, 0); 894 TestInitFromValue("invalidValue", false, 0);
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 credentials_set = MergeOnAuthRequiredResponses( 1698 credentials_set = MergeOnAuthRequiredResponses(
1482 deltas, &auth3, &conflicting_extensions, &net_log); 1699 deltas, &auth3, &conflicting_extensions, &net_log);
1483 EXPECT_TRUE(credentials_set); 1700 EXPECT_TRUE(credentials_set);
1484 EXPECT_FALSE(auth3.Empty()); 1701 EXPECT_FALSE(auth3.Empty());
1485 EXPECT_EQ(username, auth1.username()); 1702 EXPECT_EQ(username, auth1.username());
1486 EXPECT_EQ(password, auth1.password()); 1703 EXPECT_EQ(password, auth1.password());
1487 EXPECT_EQ(1u, conflicting_extensions.size()); 1704 EXPECT_EQ(1u, conflicting_extensions.size());
1488 EXPECT_TRUE(ContainsKey(conflicting_extensions, "extid2")); 1705 EXPECT_TRUE(ContainsKey(conflicting_extensions, "extid2"));
1489 EXPECT_EQ(3u, capturing_net_log.GetSize()); 1706 EXPECT_EQ(3u, capturing_net_log.GetSize());
1490 } 1707 }
1491
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698