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

Side by Side Diff: components/password_manager/core/browser/import/password_importer_unittest.cc

Issue 1193143003: Enable import/export of passwords into/from Password Manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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
(Empty)
1 // Copyright 2014 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 "components/password_manager/core/browser/import/password_importer.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/file_util.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/test_simple_task_runner.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "components/autofill/core/common/password_form.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace password_manager {
20
21 namespace {
22
23 const char kTestOriginURL[] = "http://accounts.google.com/a/LoginAuth";
24 const char kTestUsername[] = "test@gmail.com";
25 const char kTestPassword[] = "test1";
26
27 // Creates a test input file in a temporary directory with the specified
28 // contents and extension; and cleans it up when the object is destroyed.
29 class ScopedInputFile {
30 public:
31 ScopedInputFile() {}
32 ~ScopedInputFile() { base::DeleteFile(input_file_path_.DirName(), true); }
33
34 void Create(const base::FilePath::CharType* extension,
35 base::StringPiece contents) {
36 base::FilePath temporary_dir;
37 ASSERT_TRUE(base::CreateNewTempDirectory(base::FilePath::StringType(),
38 &temporary_dir));
39 input_file_path_ =
40 temporary_dir.AppendASCII("passwords").AddExtension(extension);
41 ASSERT_TRUE(
42 base::WriteFile(input_file_path_, contents.data(), contents.size()));
43 }
44
45 base::FilePath path() { return input_file_path_; }
46
47 private:
48 base::FilePath input_file_path_;
49
50 DISALLOW_COPY_AND_ASSIGN(ScopedInputFile);
51 };
52
53 } // namespace
54
55 class PasswordImporterTest : public testing::Test {
56 public:
57 PasswordImporterTest()
58 : callback_called_(false), result_(PasswordImporter::SUCCESS) {}
59
60 protected:
61 void StartImportAndWaitForCompletion(const base::FilePath& input_file) {
62 PasswordImporter::Import(input_file, message_loop_.task_runner(),
63 base::Bind(&PasswordImporterTest::OnImportFinished,
64 base::Unretained(this)));
65
66 base::RunLoop run_loop;
67 run_loop.RunUntilIdle();
68
69 ASSERT_TRUE(callback_called_);
70 }
71
72 void OnImportFinished(PasswordImporter::Result result,
73 const std::vector<autofill::PasswordForm>& passwords) {
74 callback_called_ = true;
75 result_ = result;
76 imported_passwords_ = passwords;
77 }
78
79 const PasswordImporter::Result& result() { return result_; }
80 const std::vector<autofill::PasswordForm>& imported_passwords() {
81 return imported_passwords_;
82 }
83
84 private:
85 base::MessageLoop message_loop_;
86
87 bool callback_called_;
88 PasswordImporter::Result result_;
89 std::vector<autofill::PasswordForm> imported_passwords_;
90
91 DISALLOW_COPY_AND_ASSIGN(PasswordImporterTest);
92 };
93
94 TEST_F(PasswordImporterTest, CSVImport) {
95 const char kTestCSVInput[] =
96 "Url,Username,Password\n"
97 "http://accounts.google.com/a/LoginAuth,test@gmail.com,test1\n";
98
99 ScopedInputFile input_file;
100 ASSERT_NO_FATAL_FAILURE(
101 input_file.Create(FILE_PATH_LITERAL(".csv"), kTestCSVInput));
102
103 ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
104
105 EXPECT_EQ(PasswordImporter::SUCCESS, result());
106 ASSERT_EQ(1u, imported_passwords().size());
107 EXPECT_EQ(GURL(kTestOriginURL), imported_passwords()[0].origin);
108 EXPECT_EQ(base::ASCIIToUTF16(kTestUsername),
109 imported_passwords()[0].username_value);
110 EXPECT_EQ(base::ASCIIToUTF16(kTestPassword),
111 imported_passwords()[0].password_value);
112 }
113
114 TEST_F(PasswordImporterTest, JSONImport) {
115 const char kTestJSONInput[] =
116 "[{"
117 "\"password\":\"test1\","
118 "\"url\":\"http://accounts.google.com/a/LoginAuth\","
119 "\"username\":\"test@gmail.com\""
120 "},"
121 "{"
122 "\"this_is_not_really_a_password\":\"and should be ignored\""
123 "}]";
124
125 ScopedInputFile input_file;
126 ASSERT_NO_FATAL_FAILURE(
127 input_file.Create(FILE_PATH_LITERAL(".json"), kTestJSONInput));
128
129 ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
130
131 EXPECT_EQ(PasswordImporter::SUCCESS, result());
132 ASSERT_EQ(1u, imported_passwords().size());
133 EXPECT_EQ(GURL(kTestOriginURL), imported_passwords()[0].origin);
134 EXPECT_EQ(base::ASCIIToUTF16(kTestUsername),
135 imported_passwords()[0].username_value);
136 EXPECT_EQ(base::ASCIIToUTF16(kTestPassword),
137 imported_passwords()[0].password_value);
138 }
139
140 // A string that is not well-formed JSON in general should cause a syntax error.
141 TEST_F(PasswordImporterTest, JSONImportSyntaxError) {
142 // String that is illegal JSON as it is missing closing curlies and brackets.
143 const char kTestJSONInput[] =
144 "[{"
145 "\"password\":\"test1\","
146 "\"url\":\"http://accounts.google.com/a/LoginAuth\","
147 "\"username\":\"test@gmail.com\"";
148
149 ScopedInputFile input_file;
150 ASSERT_NO_FATAL_FAILURE(
151 input_file.Create(FILE_PATH_LITERAL(".json"), kTestJSONInput));
152
153 ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
154
155 EXPECT_EQ(PasswordImporter::SYNTAX_ERROR, result());
156 ASSERT_EQ(0u, imported_passwords().size());
157 }
158
159 // A string that is legal JSON, but not the right structure should cause a
160 // semantical error.
161 TEST_F(PasswordImporterTest, JSONImportSemanticError) {
162 // JSON string that does not represent a list of dictionaries.
163 const char kTestJSONInput[] =
164 "{"
165 "\"password\":\"test1\","
166 "\"url\":\"http://accounts.google.com/a/LoginAuth\","
167 "\"username\":\"test@gmail.com\""
168 "}";
169
170 ScopedInputFile input_file;
171 ASSERT_NO_FATAL_FAILURE(
172 input_file.Create(FILE_PATH_LITERAL(".json"), kTestJSONInput));
173
174 ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
175
176 EXPECT_EQ(PasswordImporter::SEMANTICAL_ERROR, result());
177 ASSERT_EQ(0u, imported_passwords().size());
178 }
179
180 TEST_F(PasswordImporterTest, ImportIOErrorDueToUnreadableFile) {
181 base::FilePath non_existent_input_file(FILE_PATH_LITERAL("nonexistent.json"));
182 ASSERT_NO_FATAL_FAILURE(
183 StartImportAndWaitForCompletion(non_existent_input_file));
184
185 EXPECT_EQ(PasswordImporter::IO_ERROR, result());
186 ASSERT_EQ(0u, imported_passwords().size());
187 }
188
189 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698