Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / password_manager / core / browser / password_store_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/time/time.h"
12 #include "components/password_manager/core/browser/password_form_data.h"
13 #include "components/password_manager/core/browser/password_store_consumer.h"
14 #include "components/password_manager/core/browser/password_store_default.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using autofill::PasswordForm;
19 using base::WaitableEvent;
20 using testing::_;
21 using testing::DoAll;
22 using testing::WithArg;
23
24 namespace password_manager {
25
26 namespace {
27
28 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
29  public:
30   MOCK_METHOD1(OnGetPasswordStoreResults,
31                void(const std::vector<PasswordForm*>&));
32 };
33
34 class StartSyncFlareMock {
35  public:
36   StartSyncFlareMock() {}
37   ~StartSyncFlareMock() {}
38
39   MOCK_METHOD1(StartSyncFlare, void(syncer::ModelType));
40 };
41
42 }  // namespace
43
44 class PasswordStoreTest : public testing::Test {
45  protected:
46   void SetUp() override {
47     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
48     login_db_.reset(new LoginDatabase());
49     ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append(
50         FILE_PATH_LITERAL("login_test"))));
51   }
52
53   void TearDown() override { ASSERT_TRUE(temp_dir_.Delete()); }
54
55   base::MessageLoopForUI message_loop_;
56   scoped_ptr<LoginDatabase> login_db_;
57   base::ScopedTempDir temp_dir_;
58 };
59
60 ACTION(STLDeleteElements0) {
61   STLDeleteContainerPointers(arg0.begin(), arg0.end());
62 }
63
64 TEST_F(PasswordStoreTest, IgnoreOldWwwGoogleLogins) {
65   scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
66       base::MessageLoopProxy::current(),
67       base::MessageLoopProxy::current(),
68       login_db_.release()));
69   store->Init(syncer::SyncableService::StartSyncFlare());
70
71   const time_t cutoff = 1325376000;  // 00:00 Jan 1 2012 UTC
72   // The passwords are all empty because PasswordStoreDefault doesn't store the
73   // actual passwords on OS X (they're stored in the Keychain instead). We could
74   // special-case it, but it's easier to just have empty passwords.
75   static const PasswordFormData form_data[] = {
76     // A form on https://www.google.com/ older than the cutoff. Will be ignored.
77     { PasswordForm::SCHEME_HTML,
78       "https://www.google.com",
79       "https://www.google.com/origin",
80       "https://www.google.com/action",
81       L"submit_element",
82       L"username_element",
83       L"password_element",
84       L"username_value_1",
85       L"",
86       true, true, cutoff - 1 },
87     // A form on https://www.google.com/ older than the cutoff. Will be ignored.
88     { PasswordForm::SCHEME_HTML,
89       "https://www.google.com",
90       "https://www.google.com/origin",
91       "https://www.google.com/action",
92       L"submit_element",
93       L"username_element",
94       L"password_element",
95       L"username_value_2",
96       L"",
97       true, true, cutoff - 1 },
98     // A form on https://www.google.com/ newer than the cutoff.
99     { PasswordForm::SCHEME_HTML,
100       "https://www.google.com",
101       "https://www.google.com/origin",
102       "https://www.google.com/action",
103       L"submit_element",
104       L"username_element",
105       L"password_element",
106       L"username_value_3",
107       L"",
108       true, true, cutoff + 1 },
109     // A form on https://accounts.google.com/ older than the cutoff.
110     { PasswordForm::SCHEME_HTML,
111       "https://accounts.google.com",
112       "https://accounts.google.com/origin",
113       "https://accounts.google.com/action",
114       L"submit_element",
115       L"username_element",
116       L"password_element",
117       L"username_value",
118       L"",
119       true, true, cutoff - 1 },
120     // A form on http://bar.example.com/ older than the cutoff.
121     { PasswordForm::SCHEME_HTML,
122       "http://bar.example.com",
123       "http://bar.example.com/origin",
124       "http://bar.example.com/action",
125       L"submit_element",
126       L"username_element",
127       L"password_element",
128       L"username_value",
129       L"",
130       true, false, cutoff - 1 },
131   };
132
133   // Build the forms vector and add the forms to the store.
134   std::vector<PasswordForm*> all_forms;
135   for (size_t i = 0; i < arraysize(form_data); ++i) {
136     PasswordForm* form = CreatePasswordFormFromData(form_data[i]);
137     all_forms.push_back(form);
138     store->AddLogin(*form);
139   }
140   base::MessageLoop::current()->RunUntilIdle();
141
142   // We expect to get back only the "recent" www.google.com login.
143   // Theoretically these should never actually exist since there are no longer
144   // any login forms on www.google.com to save, but we technically allow them.
145   // We should not get back the older saved password though.
146   PasswordForm www_google;
147   www_google.scheme = PasswordForm::SCHEME_HTML;
148   www_google.signon_realm = "https://www.google.com";
149   std::vector<PasswordForm*> www_google_expected;
150   www_google_expected.push_back(all_forms[2]);
151
152   // We should still get the accounts.google.com login even though it's older
153   // than our cutoff - this is the new location of all Google login forms.
154   PasswordForm accounts_google;
155   accounts_google.scheme = PasswordForm::SCHEME_HTML;
156   accounts_google.signon_realm = "https://accounts.google.com";
157   std::vector<PasswordForm*> accounts_google_expected;
158   accounts_google_expected.push_back(all_forms[3]);
159
160   // Same thing for a generic saved login.
161   PasswordForm bar_example;
162   bar_example.scheme = PasswordForm::SCHEME_HTML;
163   bar_example.signon_realm = "http://bar.example.com";
164   std::vector<PasswordForm*> bar_example_expected;
165   bar_example_expected.push_back(all_forms[4]);
166
167   MockPasswordStoreConsumer consumer;
168
169   // Expect the appropriate replies, as above, in reverse order than we will
170   // issue the queries. Each retires on saturation to avoid matcher spew.
171   EXPECT_CALL(consumer,
172       OnGetPasswordStoreResults(ContainsAllPasswordForms(bar_example_expected)))
173       .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation();
174   EXPECT_CALL(consumer,
175       OnGetPasswordStoreResults(
176           ContainsAllPasswordForms(accounts_google_expected)))
177       .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation();
178   EXPECT_CALL(consumer,
179       OnGetPasswordStoreResults(
180           ContainsAllPasswordForms(www_google_expected)))
181       .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation();
182
183   store->GetLogins(www_google, PasswordStore::ALLOW_PROMPT, &consumer);
184   store->GetLogins(accounts_google, PasswordStore::ALLOW_PROMPT, &consumer);
185   store->GetLogins(bar_example, PasswordStore::ALLOW_PROMPT, &consumer);
186
187   base::MessageLoop::current()->RunUntilIdle();
188
189   STLDeleteElements(&all_forms);
190   store->Shutdown();
191   base::MessageLoop::current()->RunUntilIdle();
192 }
193
194 TEST_F(PasswordStoreTest, StartSyncFlare) {
195   scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
196       base::MessageLoopProxy::current(),
197       base::MessageLoopProxy::current(),
198       login_db_.release()));
199   StartSyncFlareMock mock;
200   store->Init(
201       base::Bind(&StartSyncFlareMock::StartSyncFlare, base::Unretained(&mock)));
202   {
203     PasswordForm form;
204     EXPECT_CALL(mock, StartSyncFlare(syncer::PASSWORDS));
205     store->AddLogin(form);
206     base::MessageLoop::current()->RunUntilIdle();
207   }
208   store->Shutdown();
209   base::MessageLoop::current()->RunUntilIdle();
210 }
211
212 }  // namespace password_manager