Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / components / password_manager / core / browser / password_store_default_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/bind_helpers.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/time/time.h"
15 #include "components/password_manager/core/browser/password_form_data.h"
16 #include "components/password_manager/core/browser/password_store_change.h"
17 #include "components/password_manager/core/browser/password_store_consumer.h"
18 #include "components/password_manager/core/browser/password_store_default.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using autofill::PasswordForm;
23 using base::WaitableEvent;
24 using testing::_;
25 using testing::DoAll;
26 using testing::ElementsAreArray;
27 using testing::Pointee;
28 using testing::Property;
29 using testing::WithArg;
30
31 namespace {
32
33 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
34  public:
35   MOCK_METHOD1(OnGetPasswordStoreResults,
36                void(const std::vector<PasswordForm*>&));
37 };
38
39 class MockPasswordStoreObserver : public PasswordStore::Observer {
40  public:
41   MOCK_METHOD1(OnLoginsChanged,
42                void(const PasswordStoreChangeList& changes));
43 };
44
45 }  // anonymous namespace
46
47 class PasswordStoreDefaultTest : public testing::Test {
48  protected:
49   virtual void SetUp() OVERRIDE {
50     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
51     login_db_.reset(new LoginDatabase());
52     ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append(
53         FILE_PATH_LITERAL("login_test"))));
54   }
55
56   virtual void TearDown() OVERRIDE {
57     ASSERT_TRUE(temp_dir_.Delete());
58   }
59
60   base::MessageLoopForUI message_loop_;
61   scoped_ptr<LoginDatabase> login_db_;
62   base::ScopedTempDir temp_dir_;
63 };
64
65 ACTION(STLDeleteElements0) {
66   STLDeleteContainerPointers(arg0.begin(), arg0.end());
67 }
68
69 TEST_F(PasswordStoreDefaultTest, NonASCIIData) {
70   scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
71       base::MessageLoopProxy::current(),
72       base::MessageLoopProxy::current(),
73       login_db_.release()));
74   store->Init();
75
76   // Some non-ASCII password form data.
77   static const PasswordFormData form_data[] = {
78     { PasswordForm::SCHEME_HTML,
79       "http://foo.example.com",
80       "http://foo.example.com/origin",
81       "http://foo.example.com/action",
82       L"มีสีสัน",
83       L"お元気ですか?",
84       L"盆栽",
85       L"أحب كرة",
86       L"£éä국수çà",
87       true, false, 1 },
88   };
89
90   // Build the expected forms vector and add the forms to the store.
91   std::vector<PasswordForm*> expected_forms;
92   for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(form_data); ++i) {
93     PasswordForm* form = CreatePasswordFormFromData(form_data[i]);
94     expected_forms.push_back(form);
95     store->AddLogin(*form);
96   }
97
98   base::MessageLoop::current()->RunUntilIdle();
99
100   MockPasswordStoreConsumer consumer;
101
102   // We expect to get the same data back, even though it's not all ASCII.
103   EXPECT_CALL(consumer,
104       OnGetPasswordStoreResults(ContainsAllPasswordForms(expected_forms)))
105       .WillOnce(WithArg<0>(STLDeleteElements0()));
106   store->GetAutofillableLogins(&consumer);
107
108   base::MessageLoop::current()->RunUntilIdle();
109
110   STLDeleteElements(&expected_forms);
111   store->Shutdown();
112 }
113
114 TEST_F(PasswordStoreDefaultTest, Notifications) {
115   scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
116       base::MessageLoopProxy::current(),
117       base::MessageLoopProxy::current(),
118       login_db_.release()));
119   store->Init();
120
121   PasswordFormData form_data =
122   { PasswordForm::SCHEME_HTML,
123     "http://bar.example.com",
124     "http://bar.example.com/origin",
125     "http://bar.example.com/action",
126     L"submit_element",
127     L"username_element",
128     L"password_element",
129     L"username_value",
130     L"password_value",
131     true, false, 1 };
132   scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(form_data));
133
134   MockPasswordStoreObserver observer;
135   store->AddObserver(&observer);
136
137   const PasswordStoreChange expected_add_changes[] = {
138     PasswordStoreChange(PasswordStoreChange::ADD, *form),
139   };
140
141   EXPECT_CALL(
142       observer,
143       OnLoginsChanged(ElementsAreArray(expected_add_changes)));
144
145   // Adding a login should trigger a notification.
146   store->AddLogin(*form);
147   base::MessageLoop::current()->RunUntilIdle();
148
149   // Change the password.
150   form->password_value = base::ASCIIToUTF16("a different password");
151
152   const PasswordStoreChange expected_update_changes[] = {
153     PasswordStoreChange(PasswordStoreChange::UPDATE, *form),
154   };
155
156   EXPECT_CALL(
157       observer,
158       OnLoginsChanged(ElementsAreArray(expected_update_changes)));
159
160   // Updating the login with the new password should trigger a notification.
161   store->UpdateLogin(*form);
162   base::MessageLoop::current()->RunUntilIdle();
163
164   const PasswordStoreChange expected_delete_changes[] = {
165     PasswordStoreChange(PasswordStoreChange::REMOVE, *form),
166   };
167
168   EXPECT_CALL(
169       observer,
170       OnLoginsChanged(ElementsAreArray(expected_delete_changes)));
171
172   // Deleting the login should trigger a notification.
173   store->RemoveLogin(*form);
174   base::MessageLoop::current()->RunUntilIdle();
175
176   store->RemoveObserver(&observer);
177   store->Shutdown();
178 }