Upstream version 5.34.104.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 {
25
26 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
27  public:
28   MOCK_METHOD1(OnGetPasswordStoreResults,
29                void(const std::vector<PasswordForm*>&));
30 };
31
32 }  // namespace
33
34 class PasswordStoreTest : public testing::Test {
35  protected:
36   virtual void SetUp() OVERRIDE {
37     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
38     login_db_.reset(new LoginDatabase());
39     ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append(
40         FILE_PATH_LITERAL("login_test"))));
41   }
42
43   virtual void TearDown() OVERRIDE {
44     ASSERT_TRUE(temp_dir_.Delete());
45   }
46
47   base::MessageLoopForUI message_loop_;
48   scoped_ptr<LoginDatabase> login_db_;
49   base::ScopedTempDir temp_dir_;
50 };
51
52 ACTION(STLDeleteElements0) {
53   STLDeleteContainerPointers(arg0.begin(), arg0.end());
54 }
55
56 TEST_F(PasswordStoreTest, IgnoreOldWwwGoogleLogins) {
57   scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
58       base::MessageLoopProxy::current(),
59       base::MessageLoopProxy::current(),
60       login_db_.release()));
61   store->Init();
62
63   const time_t cutoff = 1325376000;  // 00:00 Jan 1 2012 UTC
64   // The passwords are all empty because PasswordStoreDefault doesn't store the
65   // actual passwords on OS X (they're stored in the Keychain instead). We could
66   // special-case it, but it's easier to just have empty passwords.
67   static const PasswordFormData form_data[] = {
68     // A form on https://www.google.com/ older than the cutoff. Will be ignored.
69     { PasswordForm::SCHEME_HTML,
70       "https://www.google.com",
71       "https://www.google.com/origin",
72       "https://www.google.com/action",
73       L"submit_element",
74       L"username_element",
75       L"password_element",
76       L"username_value_1",
77       L"",
78       true, true, cutoff - 1 },
79     // A form on https://www.google.com/ older than the cutoff. Will be ignored.
80     { PasswordForm::SCHEME_HTML,
81       "https://www.google.com",
82       "https://www.google.com/origin",
83       "https://www.google.com/action",
84       L"submit_element",
85       L"username_element",
86       L"password_element",
87       L"username_value_2",
88       L"",
89       true, true, cutoff - 1 },
90     // A form on https://www.google.com/ newer than the cutoff.
91     { PasswordForm::SCHEME_HTML,
92       "https://www.google.com",
93       "https://www.google.com/origin",
94       "https://www.google.com/action",
95       L"submit_element",
96       L"username_element",
97       L"password_element",
98       L"username_value_3",
99       L"",
100       true, true, cutoff + 1 },
101     // A form on https://accounts.google.com/ older than the cutoff.
102     { PasswordForm::SCHEME_HTML,
103       "https://accounts.google.com",
104       "https://accounts.google.com/origin",
105       "https://accounts.google.com/action",
106       L"submit_element",
107       L"username_element",
108       L"password_element",
109       L"username_value",
110       L"",
111       true, true, cutoff - 1 },
112     // A form on http://bar.example.com/ older than the cutoff.
113     { PasswordForm::SCHEME_HTML,
114       "http://bar.example.com",
115       "http://bar.example.com/origin",
116       "http://bar.example.com/action",
117       L"submit_element",
118       L"username_element",
119       L"password_element",
120       L"username_value",
121       L"",
122       true, false, cutoff - 1 },
123   };
124
125   // Build the forms vector and add the forms to the store.
126   std::vector<PasswordForm*> all_forms;
127   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(form_data); ++i) {
128     PasswordForm* form = CreatePasswordFormFromData(form_data[i]);
129     all_forms.push_back(form);
130     store->AddLogin(*form);
131   }
132   base::MessageLoop::current()->RunUntilIdle();
133
134   // We expect to get back only the "recent" www.google.com login.
135   // Theoretically these should never actually exist since there are no longer
136   // any login forms on www.google.com to save, but we technically allow them.
137   // We should not get back the older saved password though.
138   PasswordForm www_google;
139   www_google.scheme = PasswordForm::SCHEME_HTML;
140   www_google.signon_realm = "https://www.google.com";
141   std::vector<PasswordForm*> www_google_expected;
142   www_google_expected.push_back(all_forms[2]);
143
144   // We should still get the accounts.google.com login even though it's older
145   // than our cutoff - this is the new location of all Google login forms.
146   PasswordForm accounts_google;
147   accounts_google.scheme = PasswordForm::SCHEME_HTML;
148   accounts_google.signon_realm = "https://accounts.google.com";
149   std::vector<PasswordForm*> accounts_google_expected;
150   accounts_google_expected.push_back(all_forms[3]);
151
152   // Same thing for a generic saved login.
153   PasswordForm bar_example;
154   bar_example.scheme = PasswordForm::SCHEME_HTML;
155   bar_example.signon_realm = "http://bar.example.com";
156   std::vector<PasswordForm*> bar_example_expected;
157   bar_example_expected.push_back(all_forms[4]);
158
159   MockPasswordStoreConsumer consumer;
160
161   // Expect the appropriate replies, as above, in reverse order than we will
162   // issue the queries. Each retires on saturation to avoid matcher spew.
163   EXPECT_CALL(consumer,
164       OnGetPasswordStoreResults(ContainsAllPasswordForms(bar_example_expected)))
165       .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation();
166   EXPECT_CALL(consumer,
167       OnGetPasswordStoreResults(
168           ContainsAllPasswordForms(accounts_google_expected)))
169       .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation();
170   EXPECT_CALL(consumer,
171       OnGetPasswordStoreResults(
172           ContainsAllPasswordForms(www_google_expected)))
173       .WillOnce(WithArg<0>(STLDeleteElements0())).RetiresOnSaturation();
174
175   store->GetLogins(www_google, PasswordStore::ALLOW_PROMPT, &consumer);
176   store->GetLogins(accounts_google, PasswordStore::ALLOW_PROMPT, &consumer);
177   store->GetLogins(bar_example, PasswordStore::ALLOW_PROMPT, &consumer);
178
179   base::MessageLoop::current()->RunUntilIdle();
180
181   STLDeleteElements(&all_forms);
182   store->Shutdown();
183 }