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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: components/password_manager/core/browser/import/password_importer_unittest.cc
diff --git a/components/password_manager/core/browser/import/password_importer_unittest.cc b/components/password_manager/core/browser/import/password_importer_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..69f25ee9d7598c40bac2d6a362c30b8db5f52b53
--- /dev/null
+++ b/components/password_manager/core/browser/import/password_importer_unittest.cc
@@ -0,0 +1,189 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/core/browser/import/password_importer.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "components/autofill/core/common/password_form.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace password_manager {
+
+namespace {
+
+const char kTestOriginURL[] = "http://accounts.google.com/a/LoginAuth";
+const char kTestUsername[] = "test@gmail.com";
+const char kTestPassword[] = "test1";
+
+// Creates a test input file in a temporary directory with the specified
+// contents and extension; and cleans it up when the object is destroyed.
+class ScopedInputFile {
+ public:
+ ScopedInputFile() {}
+ ~ScopedInputFile() { base::DeleteFile(input_file_path_.DirName(), true); }
+
+ void Create(const base::FilePath::CharType* extension,
+ base::StringPiece contents) {
+ base::FilePath temporary_dir;
+ ASSERT_TRUE(base::CreateNewTempDirectory(base::FilePath::StringType(),
+ &temporary_dir));
+ input_file_path_ =
+ temporary_dir.AppendASCII("passwords").AddExtension(extension);
+ ASSERT_TRUE(
+ base::WriteFile(input_file_path_, contents.data(), contents.size()));
+ }
+
+ base::FilePath path() { return input_file_path_; }
+
+ private:
+ base::FilePath input_file_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedInputFile);
+};
+
+} // namespace
+
+class PasswordImporterTest : public testing::Test {
+ public:
+ PasswordImporterTest()
+ : callback_called_(false), result_(PasswordImporter::SUCCESS) {}
+
+ protected:
+ void StartImportAndWaitForCompletion(const base::FilePath& input_file) {
+ PasswordImporter::Import(input_file, message_loop_.task_runner(),
+ base::Bind(&PasswordImporterTest::OnImportFinished,
+ base::Unretained(this)));
+
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ ASSERT_TRUE(callback_called_);
+ }
+
+ void OnImportFinished(PasswordImporter::Result result,
+ const std::vector<autofill::PasswordForm>& passwords) {
+ callback_called_ = true;
+ result_ = result;
+ imported_passwords_ = passwords;
+ }
+
+ const PasswordImporter::Result& result() { return result_; }
+ const std::vector<autofill::PasswordForm>& imported_passwords() {
+ return imported_passwords_;
+ }
+
+ private:
+ base::MessageLoop message_loop_;
+
+ bool callback_called_;
+ PasswordImporter::Result result_;
+ std::vector<autofill::PasswordForm> imported_passwords_;
+
+ DISALLOW_COPY_AND_ASSIGN(PasswordImporterTest);
+};
+
+TEST_F(PasswordImporterTest, CSVImport) {
+ const char kTestCSVInput[] =
+ "Url,Username,Password\n"
+ "http://accounts.google.com/a/LoginAuth,test@gmail.com,test1\n";
+
+ ScopedInputFile input_file;
+ ASSERT_NO_FATAL_FAILURE(
+ input_file.Create(FILE_PATH_LITERAL(".csv"), kTestCSVInput));
+
+ ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
+
+ EXPECT_EQ(PasswordImporter::SUCCESS, result());
+ ASSERT_EQ(1u, imported_passwords().size());
+ EXPECT_EQ(GURL(kTestOriginURL), imported_passwords()[0].origin);
+ EXPECT_EQ(base::ASCIIToUTF16(kTestUsername),
+ imported_passwords()[0].username_value);
+ EXPECT_EQ(base::ASCIIToUTF16(kTestPassword),
+ imported_passwords()[0].password_value);
+}
+
+TEST_F(PasswordImporterTest, JSONImport) {
+ const char kTestJSONInput[] =
+ "[{"
+ "\"password\":\"test1\","
+ "\"url\":\"http://accounts.google.com/a/LoginAuth\","
+ "\"username\":\"test@gmail.com\""
+ "},"
+ "{"
+ "\"this_is_not_really_a_password\":\"and should be ignored\""
+ "}]";
+
+ ScopedInputFile input_file;
+ ASSERT_NO_FATAL_FAILURE(
+ input_file.Create(FILE_PATH_LITERAL(".json"), kTestJSONInput));
+
+ ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
+
+ EXPECT_EQ(PasswordImporter::SUCCESS, result());
+ ASSERT_EQ(1u, imported_passwords().size());
+ EXPECT_EQ(GURL(kTestOriginURL), imported_passwords()[0].origin);
+ EXPECT_EQ(base::ASCIIToUTF16(kTestUsername),
+ imported_passwords()[0].username_value);
+ EXPECT_EQ(base::ASCIIToUTF16(kTestPassword),
+ imported_passwords()[0].password_value);
+}
+
+// A string that is not well-formed JSON in general should cause a syntax error.
+TEST_F(PasswordImporterTest, JSONImportSyntaxError) {
+ // String that is illegal JSON as it is missing closing curlies and brackets.
+ const char kTestJSONInput[] =
+ "[{"
+ "\"password\":\"test1\","
+ "\"url\":\"http://accounts.google.com/a/LoginAuth\","
+ "\"username\":\"test@gmail.com\"";
+
+ ScopedInputFile input_file;
+ ASSERT_NO_FATAL_FAILURE(
+ input_file.Create(FILE_PATH_LITERAL(".json"), kTestJSONInput));
+
+ ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
+
+ EXPECT_EQ(PasswordImporter::SYNTAX_ERROR, result());
+ ASSERT_EQ(0u, imported_passwords().size());
+}
+
+// A string that is legal JSON, but not the right structure should cause a
+// semantical error.
+TEST_F(PasswordImporterTest, JSONImportSemanticError) {
+ // JSON string that does not represent a list of dictionaries.
+ const char kTestJSONInput[] =
+ "{"
+ "\"password\":\"test1\","
+ "\"url\":\"http://accounts.google.com/a/LoginAuth\","
+ "\"username\":\"test@gmail.com\""
+ "}";
+
+ ScopedInputFile input_file;
+ ASSERT_NO_FATAL_FAILURE(
+ input_file.Create(FILE_PATH_LITERAL(".json"), kTestJSONInput));
+
+ ASSERT_NO_FATAL_FAILURE(StartImportAndWaitForCompletion(input_file.path()));
+
+ EXPECT_EQ(PasswordImporter::SEMANTICAL_ERROR, result());
+ ASSERT_EQ(0u, imported_passwords().size());
+}
+
+TEST_F(PasswordImporterTest, ImportIOErrorDueToUnreadableFile) {
+ base::FilePath non_existent_input_file(FILE_PATH_LITERAL("nonexistent.json"));
+ ASSERT_NO_FATAL_FAILURE(
+ StartImportAndWaitForCompletion(non_existent_input_file));
+
+ EXPECT_EQ(PasswordImporter::IO_ERROR, result());
+ ASSERT_EQ(0u, imported_passwords().size());
+}
+
+} // namespace password_manager

Powered by Google App Engine
This is Rietveld 408576698