OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/password_manager/core/browser/form_fetcher_impl.h" | 5 #include "components/password_manager/core/browser/form_fetcher_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
18 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
21 #include "components/autofill/core/common/password_form.h" | 21 #include "components/autofill/core/common/password_form.h" |
22 #include "components/password_manager/core/browser/mock_password_store.h" | 22 #include "components/password_manager/core/browser/mock_password_store.h" |
| 23 #include "components/password_manager/core/browser/password_manager_test_utils.h
" |
23 #include "components/password_manager/core/browser/password_store.h" | 24 #include "components/password_manager/core/browser/password_store.h" |
24 #include "components/password_manager/core/browser/statistics_table.h" | 25 #include "components/password_manager/core/browser/statistics_table.h" |
25 #include "components/password_manager/core/browser/stub_credentials_filter.h" | 26 #include "components/password_manager/core/browser/stub_credentials_filter.h" |
26 #include "components/password_manager/core/browser/stub_password_manager_client.
h" | 27 #include "components/password_manager/core/browser/stub_password_manager_client.
h" |
27 #include "testing/gmock/include/gmock/gmock.h" | 28 #include "testing/gmock/include/gmock/gmock.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
29 #include "url/gurl.h" | 30 #include "url/gurl.h" |
30 #include "url/origin.h" | 31 #include "url/origin.h" |
31 #include "url/url_constants.h" | 32 #include "url/url_constants.h" |
32 | 33 |
33 using autofill::PasswordForm; | 34 using autofill::PasswordForm; |
34 using base::ASCIIToUTF16; | 35 using base::ASCIIToUTF16; |
35 using base::StringPiece; | 36 using base::StringPiece; |
36 using testing::_; | 37 using testing::_; |
37 using testing::IsEmpty; | 38 using testing::IsEmpty; |
38 using testing::Pointee; | 39 using testing::Pointee; |
39 using testing::Return; | 40 using testing::Return; |
40 using testing::UnorderedElementsAre; | 41 using testing::UnorderedElementsAre; |
| 42 using testing::UnorderedElementsAreArray; |
41 using testing::WithArg; | 43 using testing::WithArg; |
42 | 44 |
43 namespace password_manager { | 45 namespace password_manager { |
44 | 46 |
45 namespace { | 47 namespace { |
46 | 48 |
47 constexpr const char kTestHttpRealm[] = "http://example.in/"; | 49 constexpr const char kTestHttpURL[] = "http://example.in/"; |
48 constexpr const char kTestHttpActionURL[] = "http://login.example.org"; | 50 constexpr const char kTestHttpActionURL[] = "http://login.example.org/"; |
49 constexpr const char kTestHttpLoginURL[] = "http://example.in"; | |
50 | 51 |
51 constexpr const char kTestHttpsRealm[] = "https://example.in/"; | 52 constexpr const char kTestHttpsURL[] = "https://example.in/"; |
52 constexpr const char kTestHttpsActionURL[] = "https://login.example.org"; | 53 constexpr const char kTestHttpsActionURL[] = "https://login.example.org/"; |
53 constexpr const char kTestHttpsLoginURL[] = "https://example.in"; | |
54 | 54 |
| 55 constexpr const char kTestPSLMatchingHttpURL[] = "http://psl.example.in/"; |
| 56 constexpr const char kTestPSLMatchingHttpsURL[] = "https://psl.example.in/"; |
| 57 |
| 58 constexpr const char kTestHttpSameOrgNameURL[] = "http://sub.example.com/"; |
| 59 constexpr const char kTestHttpsSameOrgNameURL[] = "https://sub.example.com/"; |
| 60 |
| 61 constexpr const char kTestFederatedRealm[] = |
| 62 "federation://example.in/accounts.google.com"; |
55 constexpr const char kTestFederationURL[] = "https://accounts.google.com/"; | 63 constexpr const char kTestFederationURL[] = "https://accounts.google.com/"; |
56 | 64 |
57 class MockConsumer : public FormFetcher::Consumer { | 65 class MockConsumer : public FormFetcher::Consumer { |
58 public: | 66 public: |
59 MOCK_METHOD2(ProcessMatches, | 67 MOCK_METHOD2(ProcessMatches, |
60 void(const std::vector<const PasswordForm*>& non_federated, | 68 void(const std::vector<const PasswordForm*>& non_federated, |
61 size_t filtered_count)); | 69 size_t filtered_count)); |
62 }; | 70 }; |
63 | 71 |
64 class NameFilter : public StubCredentialsFilter { | 72 class NameFilter : public StubCredentialsFilter { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 } | 113 } |
106 | 114 |
107 PasswordStore* GetPasswordStore() const override { return store_; } | 115 PasswordStore* GetPasswordStore() const override { return store_; } |
108 | 116 |
109 std::unique_ptr<CredentialsFilter> filter_; | 117 std::unique_ptr<CredentialsFilter> filter_; |
110 PasswordStore* store_ = nullptr; | 118 PasswordStore* store_ = nullptr; |
111 | 119 |
112 DISALLOW_COPY_AND_ASSIGN(FakePasswordManagerClient); | 120 DISALLOW_COPY_AND_ASSIGN(FakePasswordManagerClient); |
113 }; | 121 }; |
114 | 122 |
| 123 PasswordForm CreateHTMLForm(const char* origin_url, |
| 124 const char* username_value, |
| 125 const char* password_value) { |
| 126 PasswordForm form; |
| 127 form.scheme = PasswordForm::SCHEME_HTML; |
| 128 form.origin = GURL(origin_url); |
| 129 form.signon_realm = origin_url; |
| 130 form.username_value = ASCIIToUTF16(username_value); |
| 131 form.password_value = ASCIIToUTF16(password_value); |
| 132 return form; |
| 133 } |
| 134 |
115 // Creates a dummy non-federated form with some basic arbitrary values. | 135 // Creates a dummy non-federated form with some basic arbitrary values. |
116 PasswordForm CreateNonFederated() { | 136 PasswordForm CreateNonFederated() { |
117 PasswordForm form; | 137 PasswordForm form = CreateHTMLForm(kTestHttpsURL, "user", "password"); |
118 form.origin = GURL(kTestHttpsLoginURL); | |
119 form.signon_realm = kTestHttpsRealm; | |
120 form.action = GURL(kTestHttpsActionURL); | 138 form.action = GURL(kTestHttpsActionURL); |
121 form.username_value = ASCIIToUTF16("user"); | |
122 form.password_value = ASCIIToUTF16("password"); | |
123 return form; | 139 return form; |
124 } | 140 } |
125 | 141 |
126 // Creates a dummy non-federated HTTP form with some basic arbitrary values. | 142 // Creates a dummy non-federated HTTP form with some basic arbitrary values. |
127 PasswordForm CreateHTTPNonFederated() { | 143 PasswordForm CreateHTTPNonFederated() { |
128 PasswordForm form; | 144 PasswordForm form = CreateHTMLForm(kTestHttpURL, "user", "password"); |
129 form.origin = GURL(kTestHttpLoginURL); | |
130 form.signon_realm = kTestHttpRealm; | |
131 form.action = GURL(kTestHttpActionURL); | 145 form.action = GURL(kTestHttpActionURL); |
132 form.username_value = ASCIIToUTF16("user"); | |
133 form.password_value = ASCIIToUTF16("password"); | |
134 return form; | 146 return form; |
135 } | 147 } |
136 | 148 |
137 // Creates a dummy federated form with some basic arbitrary values. | 149 // Creates a dummy federated form with some basic arbitrary values. |
138 PasswordForm CreateFederated() { | 150 PasswordForm CreateFederated() { |
139 PasswordForm form = CreateNonFederated(); | 151 PasswordForm form = CreateNonFederated(); |
| 152 form.signon_realm = kTestFederatedRealm; |
140 form.password_value.clear(); | 153 form.password_value.clear(); |
141 form.federation_origin = url::Origin(GURL(kTestFederationURL)); | 154 form.federation_origin = url::Origin(GURL(kTestFederationURL)); |
142 return form; | 155 return form; |
143 } | 156 } |
144 | 157 |
145 // Creates an Android federated credential. | 158 // Creates an Android federated credential. |
146 PasswordForm CreateAndroidFederated() { | 159 PasswordForm CreateAndroidFederated() { |
147 PasswordForm form = CreateFederated(); | 160 PasswordForm form = |
148 form.signon_realm = "android://hash@com.example.android/"; | 161 CreateHTMLForm("android://hash@com.example.android/", "user", ""); |
149 form.origin = GURL(form.signon_realm); | 162 form.federation_origin = url::Origin(GURL(kTestFederationURL)); |
150 form.action = GURL(); | |
151 form.is_affiliation_based_match = true; | 163 form.is_affiliation_based_match = true; |
152 return form; | 164 return form; |
153 } | 165 } |
154 | 166 |
155 // Small helper that wraps passed in forms in unique ptrs. | 167 // Small helper that wraps passed in forms in unique ptrs. |
156 std::vector<std::unique_ptr<PasswordForm>> MakeResults( | 168 std::vector<std::unique_ptr<PasswordForm>> MakeResults( |
157 const std::vector<PasswordForm>& forms) { | 169 const std::vector<PasswordForm>& forms) { |
158 std::vector<std::unique_ptr<PasswordForm>> results; | 170 std::vector<std::unique_ptr<PasswordForm>> results; |
159 results.reserve(forms.size()); | 171 results.reserve(forms.size()); |
160 for (const auto& form : forms) | 172 for (const auto& form : forms) |
161 results.push_back(base::MakeUnique<PasswordForm>(form)); | 173 results.push_back(base::MakeUnique<PasswordForm>(form)); |
162 return results; | 174 return results; |
163 } | 175 } |
164 | 176 |
| 177 std::vector<PasswordForm> PointeeValues( |
| 178 const std::vector<const PasswordForm*> forms) { |
| 179 std::vector<PasswordForm> result; |
| 180 result.reserve(forms.size()); |
| 181 for (const PasswordForm* form : forms) |
| 182 result.push_back(*form); |
| 183 return result; |
| 184 } |
| 185 |
165 ACTION_P(GetAndAssignWeakPtr, ptr) { | 186 ACTION_P(GetAndAssignWeakPtr, ptr) { |
166 *ptr = arg0->GetWeakPtr(); | 187 *ptr = arg0->GetWeakPtr(); |
167 } | 188 } |
168 | 189 |
169 } // namespace | 190 } // namespace |
170 | 191 |
171 class FormFetcherImplTest : public testing::Test { | 192 class FormFetcherImplTest : public testing::Test { |
172 public: | 193 public: |
173 FormFetcherImplTest() | 194 FormFetcherImplTest() |
174 : form_digest_(PasswordForm::SCHEME_HTML, | 195 : form_digest_(PasswordForm::SCHEME_HTML, |
175 kTestHttpRealm, | 196 kTestHttpURL, |
176 GURL(kTestHttpLoginURL)) { | 197 GURL(kTestHttpURL)) { |
177 mock_store_ = new MockPasswordStore(); | 198 mock_store_ = new MockPasswordStore(); |
178 client_.set_store(mock_store_.get()); | 199 client_.set_store(mock_store_.get()); |
179 | 200 |
180 form_fetcher_ = base::MakeUnique<FormFetcherImpl>( | 201 form_fetcher_ = base::MakeUnique<FormFetcherImpl>( |
181 form_digest_, &client_, false /* should_migrate_http_passwords */, | 202 form_digest_, &client_, false /* should_migrate_http_passwords */, |
182 false /* should_query_suppressed_https_forms */); | 203 false /* should_query_suppressed_https_forms */); |
183 } | 204 } |
184 | 205 |
185 ~FormFetcherImplTest() override { mock_store_->ShutdownOnUIThread(); } | 206 ~FormFetcherImplTest() override { mock_store_->ShutdownOnUIThread(); } |
186 | 207 |
187 protected: | 208 protected: |
188 // A wrapper around form_fetcher_.Fetch(), adding the call expectations. | 209 // A wrapper around form_fetcher_.Fetch(), adding the call expectations. |
189 void Fetch() { | 210 void Fetch() { |
190 #if !defined(OS_IOS) && !defined(OS_ANDROID) | 211 #if !defined(OS_IOS) && !defined(OS_ANDROID) |
191 EXPECT_CALL(*mock_store_, GetSiteStatsImpl(_)) | 212 EXPECT_CALL(*mock_store_, GetSiteStatsImpl(_)) |
192 .WillOnce(Return(std::vector<InteractionsStats>())); | 213 .WillOnce(Return(std::vector<InteractionsStats>())); |
193 #endif | 214 #endif |
194 EXPECT_CALL(*mock_store_, GetLogins(form_digest_, form_fetcher_.get())); | 215 EXPECT_CALL(*mock_store_, GetLogins(form_digest_, form_fetcher_.get())); |
195 form_fetcher_->Fetch(); | 216 form_fetcher_->Fetch(); |
196 base::RunLoop().RunUntilIdle(); | 217 base::RunLoop().RunUntilIdle(); |
197 testing::Mock::VerifyAndClearExpectations(mock_store_.get()); | 218 testing::Mock::VerifyAndClearExpectations(mock_store_.get()); |
198 } | 219 } |
199 | 220 |
200 void RecreateFormFetcherWithQueryingSuppressedHTTPSForms() { | 221 void RecreateFormFetcherWithQueryingSuppressedForms() { |
201 form_fetcher_ = base::MakeUnique<FormFetcherImpl>( | 222 form_fetcher_ = base::MakeUnique<FormFetcherImpl>( |
202 form_digest_, &client_, false /* should_migrate_http_passwords */, | 223 form_digest_, &client_, false /* should_migrate_http_passwords */, |
203 true /* should_query_suppressed_https_forms */); | 224 true /* should_query_suppressed_https_forms */); |
204 EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u)); | 225 EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u)); |
205 form_fetcher_->AddConsumer(&consumer_); | 226 form_fetcher_->AddConsumer(&consumer_); |
206 testing::Mock::VerifyAndClearExpectations(&consumer_); | 227 testing::Mock::VerifyAndClearExpectations(&consumer_); |
207 } | 228 } |
208 | 229 |
209 // Simulates a call to Fetch(), and supplies |simulated_matches| as the | 230 // Simulates a call to Fetch(), and supplies |simulated_matches| as the |
210 // PasswordStore results. Expects that this will trigger the querying of | 231 // PasswordStore results. Expects that this will trigger the querying of |
211 // suppressed HTTPS forms by means of a GetLoginsForSameOrganizationName call | 232 // suppressed forms by means of a GetLoginsForSameOrganizationName call |
212 // being issued against the |expected_signon_realm|. | 233 // being issued against the |expected_signon_realm|. |
213 // | 234 // |
214 // Call CompleteQueryingSuppressedHTTPSForms with the emitted |consumer_ptr| | 235 // Call CompleteQueryingSuppressedForms with the emitted |consumer_ptr| |
215 // to complete the query. | 236 // to complete the query. |
216 void SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 237 void SimulateFetchAndExpectQueryingSuppressedForms( |
217 const std::vector<PasswordForm>& simulated_http_matches, | 238 const std::vector<PasswordForm>& simulated_get_logins_matches, |
218 const std::string& expected_signon_realm, | 239 const std::string& expected_signon_realm, |
219 base::WeakPtr<PasswordStoreConsumer>* consumer_ptr /* out */) { | 240 base::WeakPtr<PasswordStoreConsumer>* consumer_ptr /* out */) { |
220 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); | 241 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); |
221 | 242 |
222 Fetch(); | 243 Fetch(); |
223 | 244 |
224 EXPECT_CALL(*mock_store_, | 245 EXPECT_CALL(*mock_store_, |
225 GetLoginsForSameOrganizationName(expected_signon_realm, _)) | 246 GetLoginsForSameOrganizationName(expected_signon_realm, _)) |
226 .WillOnce(::testing::WithArg<1>(GetAndAssignWeakPtr(consumer_ptr))); | 247 .WillOnce(::testing::WithArg<1>(GetAndAssignWeakPtr(consumer_ptr))); |
227 const size_t num_matches = simulated_http_matches.size(); | 248 const size_t num_matches = simulated_get_logins_matches.size(); |
228 EXPECT_CALL(consumer_, ProcessMatches(::testing::SizeIs(num_matches), 0u)); | 249 EXPECT_CALL(consumer_, ProcessMatches(::testing::SizeIs(num_matches), 0u)); |
229 | 250 |
230 form_fetcher_->OnGetPasswordStoreResults( | 251 form_fetcher_->OnGetPasswordStoreResults( |
231 MakeResults(simulated_http_matches)); | 252 MakeResults(simulated_get_logins_matches)); |
232 | 253 |
233 ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&consumer_)); | 254 ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&consumer_)); |
234 ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock_store_.get())); | 255 ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock_store_.get())); |
235 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); | 256 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); |
236 ASSERT_TRUE(*consumer_ptr); | 257 ASSERT_TRUE(*consumer_ptr); |
237 } | 258 } |
238 | 259 |
239 void CompleteQueryingSuppressedHTTPSForms( | 260 void CompleteQueryingSuppressedForms( |
240 const std::vector<PasswordForm>& simulated_suppressed_https_forms, | 261 const std::vector<PasswordForm>& simulated_suppressed_forms, |
241 base::WeakPtr<PasswordStoreConsumer> consumer_ptr) { | 262 base::WeakPtr<PasswordStoreConsumer> consumer_ptr) { |
242 ASSERT_TRUE(consumer_ptr); | 263 ASSERT_TRUE(consumer_ptr); |
243 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); | 264 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); |
244 consumer_ptr->OnGetPasswordStoreResults( | 265 consumer_ptr->OnGetPasswordStoreResults( |
245 MakeResults(simulated_suppressed_https_forms)); | 266 MakeResults(simulated_suppressed_forms)); |
246 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); | 267 ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); |
247 } | 268 } |
248 | 269 |
249 base::MessageLoop message_loop_; // Used by mock_store_. | 270 base::MessageLoop message_loop_; // Used by mock_store_. |
250 PasswordStore::FormDigest form_digest_; | 271 PasswordStore::FormDigest form_digest_; |
251 std::unique_ptr<FormFetcherImpl> form_fetcher_; | 272 std::unique_ptr<FormFetcherImpl> form_fetcher_; |
252 MockConsumer consumer_; | 273 MockConsumer consumer_; |
253 scoped_refptr<MockPasswordStore> mock_store_; | 274 scoped_refptr<MockPasswordStore> mock_store_; |
254 FakePasswordManagerClient client_; | 275 FakePasswordManagerClient client_; |
255 | 276 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 // should be still waiting for the migrator. | 628 // should be still waiting for the migrator. |
608 EXPECT_EQ(FormFetcher::State::WAITING, form_fetcher_->GetState()); | 629 EXPECT_EQ(FormFetcher::State::WAITING, form_fetcher_->GetState()); |
609 | 630 |
610 // Now perform the actual migration. | 631 // Now perform the actual migration. |
611 EXPECT_CALL(*mock_store_, AddLogin(https_form)); | 632 EXPECT_CALL(*mock_store_, AddLogin(https_form)); |
612 static_cast<HttpPasswordStoreMigrator*>(migrator_ptr.get()) | 633 static_cast<HttpPasswordStoreMigrator*>(migrator_ptr.get()) |
613 ->OnGetPasswordStoreResults(MakeResults({http_form})); | 634 ->OnGetPasswordStoreResults(MakeResults({http_form})); |
614 EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); | 635 EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); |
615 } | 636 } |
616 | 637 |
617 TEST_F(FormFetcherImplTest, SuppressedHTTPSForms_QueriedForHTTPOrigins) { | 638 TEST_F(FormFetcherImplTest, SuppressedForms_QueriedForHTTPAndHTTPSOrigins) { |
618 RecreateFormFetcherWithQueryingSuppressedHTTPSForms(); | 639 static const PasswordStore::FormDigest kObservedHTTPSFormDigest( |
| 640 PasswordForm::SCHEME_HTML, kTestHttpsURL, GURL(kTestHttpsURL)); |
619 | 641 |
620 // The matching PasswordStore results coming in should trigger another | 642 static const PasswordForm kFormHttpSameHost = |
621 // GetLogins request to fetcht the suppressed HTTPS forms. | 643 CreateHTMLForm(kTestHttpURL, "user_1", "pass_1"); |
622 const PasswordForm matching_http_form = CreateHTTPNonFederated(); | 644 static const PasswordForm kFormHttpsSameHost = |
623 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; | 645 CreateHTMLForm(kTestHttpsURL, "user_2", "pass_2"); |
624 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 646 static const PasswordForm kFormHttpPSLMatchingHost = |
625 {matching_http_form}, kTestHttpRealm, &https_form_fetcher_ptr)); | 647 CreateHTMLForm(kTestPSLMatchingHttpURL, "user_3", "pass_3"); |
| 648 static const PasswordForm kFormHttpsPSLMatchingHost = |
| 649 CreateHTMLForm(kTestPSLMatchingHttpsURL, "user_4", "pass_4"); |
| 650 static const PasswordForm kFormHttpSameOrgNameHost = |
| 651 CreateHTMLForm(kTestHttpSameOrgNameURL, "user_5", "pass_5"); |
| 652 static const PasswordForm kFormHttpsSameOrgNameHost = |
| 653 CreateHTMLForm(kTestHttpsSameOrgNameURL, "user_6", "pass_6"); |
626 | 654 |
627 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 655 static const struct { |
628 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), IsEmpty()); | 656 const char* observed_form_origin; |
| 657 const char* observed_form_realm; |
| 658 std::vector<PasswordForm> matching_forms; |
| 659 std::vector<PasswordForm> all_suppressed_forms; |
| 660 std::vector<PasswordForm> expected_suppressed_https_forms; |
| 661 std::vector<PasswordForm> expected_suppressed_psl_forms; |
| 662 std::vector<PasswordForm> expected_suppressed_same_org_name_forms; |
| 663 } kTestCases[] = { |
| 664 {kTestHttpURL, |
| 665 kTestHttpURL, |
| 666 {kFormHttpSameHost}, |
| 667 {kFormHttpsSameHost, kFormHttpPSLMatchingHost, kFormHttpsPSLMatchingHost, |
| 668 kFormHttpSameOrgNameHost, kFormHttpsSameOrgNameHost}, |
| 669 {kFormHttpsSameHost}, |
| 670 {kFormHttpPSLMatchingHost}, |
| 671 {kFormHttpsPSLMatchingHost, kFormHttpSameOrgNameHost, |
| 672 kFormHttpsSameOrgNameHost}}, |
629 | 673 |
630 const PasswordForm suppressed_https_form1 = CreateNonFederated(); | 674 {kTestHttpsURL, |
631 const PasswordForm suppressed_https_form2 = CreateFederated(); | 675 kTestHttpsURL, |
632 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedHTTPSForms( | 676 {kFormHttpsSameHost}, |
633 {suppressed_https_form1, suppressed_https_form2}, | 677 {kFormHttpSameHost, kFormHttpPSLMatchingHost, kFormHttpsPSLMatchingHost, |
634 https_form_fetcher_ptr)); | 678 kFormHttpSameOrgNameHost, kFormHttpsSameOrgNameHost}, |
| 679 std::vector<PasswordForm>(), |
| 680 {kFormHttpsPSLMatchingHost}, |
| 681 {kFormHttpPSLMatchingHost, kFormHttpSameOrgNameHost, |
| 682 kFormHttpsSameOrgNameHost}}, |
| 683 }; |
635 | 684 |
636 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 685 for (const auto& test_case : kTestCases) { |
637 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), | 686 SCOPED_TRACE(test_case.observed_form_origin); |
638 UnorderedElementsAre(Pointee(suppressed_https_form1), | 687 |
639 Pointee(suppressed_https_form2))); | 688 form_digest_ = PasswordStore::FormDigest( |
| 689 PasswordForm::SCHEME_HTML, test_case.observed_form_origin, |
| 690 GURL(test_case.observed_form_origin)); |
| 691 RecreateFormFetcherWithQueryingSuppressedForms(); |
| 692 |
| 693 // The matching PasswordStore results coming in should trigger another |
| 694 // GetLogins request to fetcht the suppressed forms. |
| 695 base::WeakPtr<PasswordStoreConsumer> suppressed_form_fetcher_ptr = nullptr; |
| 696 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
| 697 test_case.matching_forms, test_case.observed_form_realm, |
| 698 &suppressed_form_fetcher_ptr)); |
| 699 |
| 700 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
| 701 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), IsEmpty()); |
| 702 |
| 703 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms( |
| 704 test_case.all_suppressed_forms, suppressed_form_fetcher_ptr)); |
| 705 |
| 706 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
| 707 EXPECT_THAT( |
| 708 PointeeValues(form_fetcher_->GetSuppressedHTTPSForms()), |
| 709 UnorderedElementsAreArray(test_case.expected_suppressed_https_forms)); |
| 710 EXPECT_THAT( |
| 711 PointeeValues(form_fetcher_->GetSuppressedPSLMatchingForms()), |
| 712 UnorderedElementsAreArray(test_case.expected_suppressed_psl_forms)); |
| 713 EXPECT_THAT( |
| 714 PointeeValues(form_fetcher_->GetSuppressedSameOrganizationNameForms()), |
| 715 UnorderedElementsAreArray( |
| 716 test_case.expected_suppressed_same_org_name_forms)); |
| 717 } |
640 } | 718 } |
641 | 719 |
642 TEST_F(FormFetcherImplTest, SuppressedHTTPSForms_RequeriedOnRefetch) { | 720 TEST_F(FormFetcherImplTest, SuppressedForms_RequeriedOnRefetch) { |
643 RecreateFormFetcherWithQueryingSuppressedHTTPSForms(); | 721 RecreateFormFetcherWithQueryingSuppressedForms(); |
644 | 722 |
645 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; | 723 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; |
646 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 724 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
647 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr)); | 725 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr)); |
648 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedHTTPSForms( | 726 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms( |
649 std::vector<PasswordForm>(), https_form_fetcher_ptr)); | 727 std::vector<PasswordForm>(), https_form_fetcher_ptr)); |
650 | 728 |
651 // Another call to Fetch() should refetch the list of suppressed HTTPS | 729 // Another call to Fetch() should refetch the list of suppressed credentials. |
652 // credentials as well. | |
653 const PasswordForm suppressed_https_form = CreateNonFederated(); | 730 const PasswordForm suppressed_https_form = CreateNonFederated(); |
654 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 731 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
655 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr)); | 732 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr)); |
656 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedHTTPSForms( | 733 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms( |
657 {suppressed_https_form}, https_form_fetcher_ptr)); | 734 {suppressed_https_form}, https_form_fetcher_ptr)); |
658 | 735 |
659 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), | 736 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), |
660 UnorderedElementsAre(Pointee(suppressed_https_form))); | 737 UnorderedElementsAre(Pointee(suppressed_https_form))); |
661 } | 738 } |
662 | 739 |
663 TEST_F(FormFetcherImplTest, SuppressedHTTPSForms_NeverWiped) { | 740 TEST_F(FormFetcherImplTest, SuppressedForms_NeverWiped) { |
664 RecreateFormFetcherWithQueryingSuppressedHTTPSForms(); | 741 RecreateFormFetcherWithQueryingSuppressedForms(); |
665 | 742 |
666 const PasswordForm suppressed_https_form = CreateNonFederated(); | 743 static const PasswordForm kFormHttpsSameHost = |
| 744 CreateHTMLForm(kTestHttpsURL, "user_1", "pass_1"); |
| 745 static const PasswordForm kFormHttpPSLMatchingHost = |
| 746 CreateHTMLForm(kTestPSLMatchingHttpURL, "user_2", "pass_2"); |
| 747 static const PasswordForm kFormHttpSameOrgNameHost = |
| 748 CreateHTMLForm(kTestHttpSameOrgNameURL, "user_3", "pass_3"); |
| 749 |
667 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; | 750 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; |
668 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 751 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
669 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr)); | 752 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr)); |
670 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedHTTPSForms( | 753 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms( |
671 {suppressed_https_form}, https_form_fetcher_ptr)); | 754 {kFormHttpsSameHost, kFormHttpPSLMatchingHost, kFormHttpSameOrgNameHost}, |
| 755 https_form_fetcher_ptr)); |
672 | 756 |
673 // Ensure that calling Fetch() does not wipe (even temporarily) the previously | 757 // Ensure that calling Fetch() does not wipe (even temporarily) the previously |
674 // fetched list of suppressed HTTPS credentials. Stale is better than nothing. | 758 // fetched list of suppressed HTTPS credentials. Stale is better than nothing. |
675 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 759 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
676 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr)); | 760 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr)); |
677 | 761 |
678 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 762 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
679 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), | 763 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), |
680 UnorderedElementsAre(Pointee(suppressed_https_form))); | 764 UnorderedElementsAre(Pointee(kFormHttpsSameHost))); |
| 765 EXPECT_THAT(form_fetcher_->GetSuppressedPSLMatchingForms(), |
| 766 UnorderedElementsAre(Pointee(kFormHttpPSLMatchingHost))); |
| 767 EXPECT_THAT(form_fetcher_->GetSuppressedSameOrganizationNameForms(), |
| 768 UnorderedElementsAre(Pointee(kFormHttpSameOrgNameHost))); |
681 } | 769 } |
682 | 770 |
683 TEST_F(FormFetcherImplTest, | 771 TEST_F(FormFetcherImplTest, SuppressedForms_FormFetcherDestroyedWhileQuerying) { |
684 SuppressedHTTPSForms_FormFetcherDestroyedWhileQuerying) { | 772 RecreateFormFetcherWithQueryingSuppressedForms(); |
685 RecreateFormFetcherWithQueryingSuppressedHTTPSForms(); | |
686 | 773 |
687 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; | 774 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr; |
688 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 775 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
689 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr)); | 776 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr)); |
690 | 777 |
691 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 778 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
692 | 779 |
693 // Destroy FormFetcher while SuppressedHTTPSFormFetcher is busy. | 780 // Destroy FormFetcher while SuppressedHTTPSFormFetcher is busy. |
694 form_fetcher_.reset(); | 781 form_fetcher_.reset(); |
695 } | 782 } |
696 | 783 |
697 // Exercise the scenario where querying the suppressed HTTPS logins takes so | 784 // Exercise the scenario where querying the suppressed HTTPS logins takes so |
698 // long that in the meantime there is another call to Fetch(), which completes, | 785 // long that in the meantime there is another call to Fetch(), which completes, |
699 // and triggers fetching HTTPS suppressed forms yet again. In this case, the | 786 // and triggers fetching HTTPS suppressed forms yet again. In this case, the |
700 // first SuppressedHTTPSFormFetcher is destroyed and its query cancelled. | 787 // first SuppressedHTTPSFormFetcher is destroyed and its query cancelled. |
701 TEST_F(FormFetcherImplTest, SuppressedHTTPSForms_SimultaneousQueries) { | 788 TEST_F(FormFetcherImplTest, SuppressedForms_SimultaneousQueries) { |
702 RecreateFormFetcherWithQueryingSuppressedHTTPSForms(); | 789 RecreateFormFetcherWithQueryingSuppressedForms(); |
703 | 790 |
704 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr1; | 791 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr1; |
705 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 792 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
706 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr1)); | 793 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr1)); |
707 | 794 |
708 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr2; | 795 base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr2; |
709 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedHTTPSForms( | 796 ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms( |
710 std::vector<PasswordForm>(), kTestHttpRealm, &https_form_fetcher_ptr2)); | 797 std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr2)); |
711 | 798 |
712 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 799 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
713 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), IsEmpty()); | 800 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), IsEmpty()); |
714 EXPECT_FALSE(https_form_fetcher_ptr1); | 801 EXPECT_FALSE(https_form_fetcher_ptr1); |
715 ASSERT_TRUE(https_form_fetcher_ptr2); | 802 ASSERT_TRUE(https_form_fetcher_ptr2); |
716 | 803 |
717 const PasswordForm suppressed_https_form = CreateNonFederated(); | 804 static const PasswordForm kFormHttpsSameHost = |
718 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedHTTPSForms( | 805 CreateHTMLForm(kTestHttpsURL, "user_1", "pass_1"); |
719 {suppressed_https_form}, https_form_fetcher_ptr2)); | 806 static const PasswordForm kFormHttpPSLMatchingHost = |
| 807 CreateHTMLForm(kTestPSLMatchingHttpURL, "user_2", "pass_2"); |
| 808 static const PasswordForm kFormHttpSameOrgNameHost = |
| 809 CreateHTMLForm(kTestHttpSameOrgNameURL, "user_3", "pass_3"); |
720 | 810 |
721 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 811 ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms( |
| 812 {kFormHttpsSameHost, kFormHttpPSLMatchingHost, kFormHttpSameOrgNameHost}, |
| 813 https_form_fetcher_ptr2)); |
| 814 |
| 815 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
| 816 |
| 817 EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
722 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), | 818 EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), |
723 UnorderedElementsAre(Pointee(suppressed_https_form))); | 819 UnorderedElementsAre(Pointee(kFormHttpsSameHost))); |
| 820 EXPECT_THAT(form_fetcher_->GetSuppressedPSLMatchingForms(), |
| 821 UnorderedElementsAre(Pointee(kFormHttpPSLMatchingHost))); |
| 822 EXPECT_THAT(form_fetcher_->GetSuppressedSameOrganizationNameForms(), |
| 823 UnorderedElementsAre(Pointee(kFormHttpSameOrgNameHost))); |
724 } | 824 } |
725 | 825 |
726 TEST_F(FormFetcherImplTest, SuppressedHTTPSForms_NotQueriedForHTTPSOrigins) { | 826 TEST_F(FormFetcherImplTest, SuppressedForms_NotQueriedForFederatedRealms) { |
727 form_digest_ = PasswordStore::FormDigest( | 827 form_digest_ = PasswordStore::FormDigest( |
728 PasswordForm::SCHEME_HTML, kTestHttpsRealm, GURL(kTestHttpsLoginURL)); | 828 PasswordForm::SCHEME_HTML, kTestFederatedRealm, GURL(kTestFederationURL)); |
729 RecreateFormFetcherWithQueryingSuppressedHTTPSForms(); | 829 RecreateFormFetcherWithQueryingSuppressedForms(); |
730 Fetch(); | 830 Fetch(); |
731 | 831 |
732 EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); | 832 EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); |
733 EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u)); | 833 EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u)); |
734 | 834 |
735 form_fetcher_->OnGetPasswordStoreResults( | 835 form_fetcher_->OnGetPasswordStoreResults( |
736 MakeResults(std::vector<PasswordForm>())); | 836 MakeResults(std::vector<PasswordForm>())); |
737 | 837 |
738 EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); | 838 EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); |
739 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedHTTPSForms()); | 839 EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms()); |
740 } | 840 } |
741 | 841 |
742 // Cloning a FormFetcherImpl with empty results should result in an | 842 // Cloning a FormFetcherImpl with empty results should result in an |
743 // instance with empty results. | 843 // instance with empty results. |
744 TEST_F(FormFetcherImplTest, Clone_EmptyResults) { | 844 TEST_F(FormFetcherImplTest, Clone_EmptyResults) { |
| 845 RecreateFormFetcherWithQueryingSuppressedForms(); |
745 Fetch(); | 846 Fetch(); |
| 847 EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u)); |
| 848 EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _)); |
746 form_fetcher_->OnGetPasswordStoreResults( | 849 form_fetcher_->OnGetPasswordStoreResults( |
747 std::vector<std::unique_ptr<PasswordForm>>()); | 850 std::vector<std::unique_ptr<PasswordForm>>()); |
| 851 ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(mock_store_.get())); |
748 | 852 |
749 // Clone() should not cause re-fetching from PasswordStore. | 853 // Clone() should not cause re-fetching from PasswordStore. |
750 EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); | 854 EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); |
| 855 EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _)).Times(0); |
751 auto clone = form_fetcher_->Clone(); | 856 auto clone = form_fetcher_->Clone(); |
752 EXPECT_EQ(FormFetcher::State::NOT_WAITING, clone->GetState()); | 857 EXPECT_EQ(FormFetcher::State::NOT_WAITING, clone->GetState()); |
753 EXPECT_THAT(clone->GetInteractionsStats(), IsEmpty()); | 858 EXPECT_THAT(clone->GetInteractionsStats(), IsEmpty()); |
754 EXPECT_THAT(clone->GetFederatedMatches(), IsEmpty()); | 859 EXPECT_THAT(clone->GetFederatedMatches(), IsEmpty()); |
755 EXPECT_THAT(clone->GetSuppressedHTTPSForms(), IsEmpty()); | 860 EXPECT_THAT(clone->GetSuppressedHTTPSForms(), IsEmpty()); |
756 MockConsumer consumer; | 861 MockConsumer consumer; |
757 EXPECT_CALL(consumer, ProcessMatches(IsEmpty(), 0u)); | 862 EXPECT_CALL(consumer, ProcessMatches(IsEmpty(), 0u)); |
758 clone->AddConsumer(&consumer); | 863 clone->AddConsumer(&consumer); |
759 } | 864 } |
760 | 865 |
761 // Cloning a FormFetcherImpl with non-empty results should result in an | 866 // Cloning a FormFetcherImpl with non-empty results should result in an |
762 // instance with the same results. | 867 // instance with the same results. |
763 TEST_F(FormFetcherImplTest, Clone_NonEmptyResults) { | 868 TEST_F(FormFetcherImplTest, Clone_NonEmptyResults) { |
| 869 RecreateFormFetcherWithQueryingSuppressedForms(); |
764 Fetch(); | 870 Fetch(); |
765 PasswordForm non_federated = CreateNonFederated(); | 871 PasswordForm non_federated = CreateNonFederated(); |
766 PasswordForm federated = CreateFederated(); | 872 PasswordForm federated = CreateFederated(); |
767 PasswordForm android_federated = CreateAndroidFederated(); | 873 PasswordForm android_federated = CreateAndroidFederated(); |
768 std::vector<std::unique_ptr<PasswordForm>> results; | 874 std::vector<std::unique_ptr<PasswordForm>> results; |
769 results.push_back(base::MakeUnique<PasswordForm>(non_federated)); | 875 results.push_back(base::MakeUnique<PasswordForm>(non_federated)); |
770 results.push_back(base::MakeUnique<PasswordForm>(federated)); | 876 results.push_back(base::MakeUnique<PasswordForm>(federated)); |
771 results.push_back(base::MakeUnique<PasswordForm>(android_federated)); | 877 results.push_back(base::MakeUnique<PasswordForm>(android_federated)); |
| 878 |
| 879 EXPECT_CALL(consumer_, ProcessMatches(::testing::SizeIs(1), 0u)); |
| 880 EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _)); |
772 form_fetcher_->OnGetPasswordStoreResults(std::move(results)); | 881 form_fetcher_->OnGetPasswordStoreResults(std::move(results)); |
| 882 ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(mock_store_.get())); |
773 | 883 |
774 // Clone() should not cause re-fetching from PasswordStore. | 884 // Clone() should not cause re-fetching from PasswordStore. |
775 EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); | 885 EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); |
| 886 EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _)).Times(0); |
776 auto clone = form_fetcher_->Clone(); | 887 auto clone = form_fetcher_->Clone(); |
777 | 888 |
778 // Additionally, destroy the original FormFetcher. This should not invalidate | 889 // Additionally, destroy the original FormFetcher. This should not invalidate |
779 // the data in |clone|. | 890 // the data in |clone|. |
780 form_fetcher_.reset(); | 891 form_fetcher_.reset(); |
781 | 892 |
782 EXPECT_EQ(FormFetcher::State::NOT_WAITING, clone->GetState()); | 893 EXPECT_EQ(FormFetcher::State::NOT_WAITING, clone->GetState()); |
783 EXPECT_THAT(clone->GetInteractionsStats(), IsEmpty()); | 894 EXPECT_THAT(clone->GetInteractionsStats(), IsEmpty()); |
784 EXPECT_THAT( | 895 EXPECT_THAT( |
785 clone->GetFederatedMatches(), | 896 clone->GetFederatedMatches(), |
(...skipping 11 matching lines...) Expand all Loading... |
797 // Pass empty results to make the state NOT_WAITING. | 908 // Pass empty results to make the state NOT_WAITING. |
798 form_fetcher_->OnGetPasswordStoreResults( | 909 form_fetcher_->OnGetPasswordStoreResults( |
799 std::vector<std::unique_ptr<PasswordForm>>()); | 910 std::vector<std::unique_ptr<PasswordForm>>()); |
800 std::vector<InteractionsStats> stats(1); | 911 std::vector<InteractionsStats> stats(1); |
801 form_fetcher_->OnGetSiteStatistics(std::move(stats)); | 912 form_fetcher_->OnGetSiteStatistics(std::move(stats)); |
802 | 913 |
803 auto clone = form_fetcher_->Clone(); | 914 auto clone = form_fetcher_->Clone(); |
804 EXPECT_EQ(1u, clone->GetInteractionsStats().size()); | 915 EXPECT_EQ(1u, clone->GetInteractionsStats().size()); |
805 } | 916 } |
806 | 917 |
807 // Cloning a FormFetcherImpl with some suppressed HTTPS credentials should | 918 // Cloning a FormFetcherImpl with some suppressed credentials should |
808 // result in an instance with the same suppressed credentials. | 919 // result in an instance with the same suppressed credentials. |
809 TEST_F(FormFetcherImplTest, Clone_SuppressedHTTPSCredentials) { | 920 TEST_F(FormFetcherImplTest, Clone_SuppressedCredentials) { |
810 Fetch(); | 921 Fetch(); |
811 form_fetcher_->OnGetPasswordStoreResults( | 922 form_fetcher_->OnGetPasswordStoreResults( |
812 std::vector<std::unique_ptr<PasswordForm>>()); | 923 std::vector<std::unique_ptr<PasswordForm>>()); |
813 form_fetcher_->ProcessSuppressedHTTPSForms( | 924 |
814 MakeResults({CreateNonFederated()})); | 925 static const PasswordForm kFormHttpsSameHost = |
| 926 CreateHTMLForm(kTestHttpsURL, "user_1", "pass_1"); |
| 927 static const PasswordForm kFormHttpPSLMatchingHost = |
| 928 CreateHTMLForm(kTestPSLMatchingHttpURL, "user_2", "pass_2"); |
| 929 static const PasswordForm kFormHttpSameOrgNameHost = |
| 930 CreateHTMLForm(kTestHttpSameOrgNameURL, "user_3", "pass_3"); |
| 931 |
| 932 form_fetcher_->ProcessSuppressedForms( |
| 933 MakeResults({kFormHttpsSameHost, kFormHttpPSLMatchingHost, |
| 934 kFormHttpSameOrgNameHost})); |
815 | 935 |
816 auto clone = form_fetcher_->Clone(); | 936 auto clone = form_fetcher_->Clone(); |
817 EXPECT_EQ(1u, clone->GetSuppressedHTTPSForms().size()); | 937 EXPECT_THAT(PointeeValues(clone->GetSuppressedHTTPSForms()), |
| 938 UnorderedElementsAre(kFormHttpsSameHost)); |
| 939 EXPECT_THAT(PointeeValues(clone->GetSuppressedPSLMatchingForms()), |
| 940 UnorderedElementsAre(kFormHttpPSLMatchingHost)); |
| 941 EXPECT_THAT(PointeeValues(clone->GetSuppressedSameOrganizationNameForms()), |
| 942 UnorderedElementsAre(kFormHttpSameOrgNameHost)); |
818 } | 943 } |
819 | 944 |
820 // Check that removing consumers stops them from receiving store updates. | 945 // Check that removing consumers stops them from receiving store updates. |
821 TEST_F(FormFetcherImplTest, RemoveConsumer) { | 946 TEST_F(FormFetcherImplTest, RemoveConsumer) { |
822 Fetch(); | 947 Fetch(); |
823 form_fetcher_->AddConsumer(&consumer_); | 948 form_fetcher_->AddConsumer(&consumer_); |
824 form_fetcher_->RemoveConsumer(&consumer_); | 949 form_fetcher_->RemoveConsumer(&consumer_); |
825 EXPECT_CALL(consumer_, ProcessMatches(_, _)).Times(0); | 950 EXPECT_CALL(consumer_, ProcessMatches(_, _)).Times(0); |
826 form_fetcher_->OnGetPasswordStoreResults( | 951 form_fetcher_->OnGetPasswordStoreResults( |
827 std::vector<std::unique_ptr<PasswordForm>>()); | 952 std::vector<std::unique_ptr<PasswordForm>>()); |
828 } | 953 } |
829 | 954 |
830 } // namespace password_manager | 955 } // namespace password_manager |
OLD | NEW |