d841c9b770210d897876c4fd488ee24c368931bb
[platform/framework/web/crosswalk.git] / src / chrome / browser / importer / firefox_importer_browsertest.cc
1 // Copyright (c) 2013 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/file_util.h"
6 #include "base/files/file_path.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/importer/external_process_importer_host.h"
15 #include "chrome/browser/importer/importer_progress_observer.h"
16 #include "chrome/browser/importer/importer_unittest_utils.h"
17 #include "chrome/browser/search_engines/template_url.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/importer/imported_bookmark_entry.h"
21 #include "chrome/common/importer/imported_favicon_usage.h"
22 #include "chrome/common/importer/importer_data_types.h"
23 #include "chrome/test/base/in_process_browser_test.h"
24 #include "components/autofill/core/common/password_form.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 // TODO(estade): some of these are disabled on mac. http://crbug.com/48007
28 // TODO(jschuh): Disabled on Win64 build. http://crbug.com/179688
29 #if defined(OS_MACOSX) || (defined(OS_WIN) && defined(ARCH_CPU_X86_64))
30 #define MAYBE_IMPORTER(x) DISABLED_##x
31 #else
32 #define MAYBE_IMPORTER(x) x
33 #endif
34
35 namespace {
36
37 struct PasswordInfo {
38   const char* origin;
39   const char* action;
40   const char* realm;
41   const wchar_t* username_element;
42   const wchar_t* username;
43   const wchar_t* password_element;
44   const wchar_t* password;
45   bool blacklisted;
46 };
47
48 struct KeywordInfo {
49   const wchar_t* keyword;
50   const char* url;
51 };
52
53 const BookmarkInfo kFirefoxBookmarks[] = {
54   {true, 1, {L"Bookmarks Toolbar"},
55     L"Toolbar",
56     "http://site/"},
57   {false, 0, {},
58     L"Title",
59     "http://www.google.com/"},
60 };
61
62 const PasswordInfo kFirefoxPasswords[] = {
63   {"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/",
64     L"loginuser", L"abc", L"loginpass", L"123", false},
65   {"http://localhost:8080/", "", "http://localhost:8080/localhost",
66     L"", L"http", L"", L"Http1+1abcdefg", false},
67 };
68
69 const KeywordInfo kFirefoxKeywords[] = {
70   { L"amazon.com",
71     "http://www.amazon.com/exec/obidos/external-search/?field-keywords="
72     "{searchTerms}&mode=blended" },
73   { L"answers.com",
74     "http://www.answers.com/main/ntquery?s={searchTerms}&gwp=13" },
75   { L"search.creativecommons.org",
76     "http://search.creativecommons.org/?q={searchTerms}" },
77   { L"search.ebay.com",
78     "http://search.ebay.com/search/search.dll?query={searchTerms}&"
79     "MfcISAPICommand=GetResult&ht=1&ebaytag1=ebayreg&srchdesc=n&"
80     "maxRecordsReturned=300&maxRecordsPerPage=50&SortProperty=MetaEndSort" },
81   { L"google.com",
82     "http://www.google.com/search?q={searchTerms}&ie=utf-8&oe=utf-8&aq=t" },
83   { L"en.wikipedia.org",
84     "http://en.wikipedia.org/wiki/Special:Search?search={searchTerms}" },
85   { L"search.yahoo.com",
86     "http://search.yahoo.com/search?p={searchTerms}&ei=UTF-8" },
87   { L"flickr.com",
88     "http://www.flickr.com/photos/tags/?q={searchTerms}" },
89   { L"imdb.com",
90     "http://www.imdb.com/find?q={searchTerms}" },
91   { L"webster.com",
92     "http://www.webster.com/cgi-bin/dictionary?va={searchTerms}" },
93   // Search keywords.
94   { L"\x4E2D\x6587", "http://www.google.com/" },
95 };
96
97 class FirefoxObserver : public ProfileWriter,
98                         public importer::ImporterProgressObserver {
99  public:
100   FirefoxObserver()
101       : ProfileWriter(NULL), bookmark_count_(0), history_count_(0),
102         password_count_(0), keyword_count_(0), import_search_engines_(true) {
103   }
104
105   explicit FirefoxObserver(bool import_search_engines)
106       : ProfileWriter(NULL), bookmark_count_(0), history_count_(0),
107         password_count_(0), keyword_count_(0),
108         import_search_engines_(import_search_engines) {
109   }
110
111   // importer::ImporterProgressObserver:
112   virtual void ImportStarted() OVERRIDE {}
113   virtual void ImportItemStarted(importer::ImportItem item) OVERRIDE {}
114   virtual void ImportItemEnded(importer::ImportItem item) OVERRIDE {}
115   virtual void ImportEnded() OVERRIDE {
116     base::MessageLoop::current()->Quit();
117     EXPECT_EQ(arraysize(kFirefoxBookmarks), bookmark_count_);
118     EXPECT_EQ(1U, history_count_);
119     EXPECT_EQ(arraysize(kFirefoxPasswords), password_count_);
120     if (import_search_engines_)
121       EXPECT_EQ(arraysize(kFirefoxKeywords), keyword_count_);
122   }
123
124   virtual bool BookmarkModelIsLoaded() const OVERRIDE {
125     // Profile is ready for writing.
126     return true;
127   }
128
129   virtual bool TemplateURLServiceIsLoaded() const OVERRIDE {
130     return true;
131   }
132
133   virtual void AddPasswordForm(const autofill::PasswordForm& form) OVERRIDE {
134     PasswordInfo p = kFirefoxPasswords[password_count_];
135     EXPECT_EQ(p.origin, form.origin.spec());
136     EXPECT_EQ(p.realm, form.signon_realm);
137     EXPECT_EQ(p.action, form.action.spec());
138     EXPECT_EQ(base::WideToUTF16(p.username_element), form.username_element);
139     EXPECT_EQ(base::WideToUTF16(p.username), form.username_value);
140     EXPECT_EQ(base::WideToUTF16(p.password_element), form.password_element);
141     EXPECT_EQ(base::WideToUTF16(p.password), form.password_value);
142     EXPECT_EQ(p.blacklisted, form.blacklisted_by_user);
143     ++password_count_;
144   }
145
146   virtual void AddHistoryPage(const history::URLRows& page,
147                               history::VisitSource visit_source) OVERRIDE {
148     ASSERT_EQ(3U, page.size());
149     EXPECT_EQ("http://www.google.com/", page[0].url().spec());
150     EXPECT_EQ(base::ASCIIToUTF16("Google"), page[0].title());
151     EXPECT_EQ("http://www.google.com/", page[1].url().spec());
152     EXPECT_EQ(base::ASCIIToUTF16("Google"), page[1].title());
153     EXPECT_EQ("http://www.cs.unc.edu/~jbs/resources/perl/perl-cgi/programs/"
154               "form1-POST.html", page[2].url().spec());
155     EXPECT_EQ(base::ASCIIToUTF16("example form (POST)"), page[2].title());
156     EXPECT_EQ(history::SOURCE_FIREFOX_IMPORTED, visit_source);
157     ++history_count_;
158   }
159
160   virtual void AddBookmarks(
161       const std::vector<ImportedBookmarkEntry>& bookmarks,
162       const base::string16& top_level_folder_name) OVERRIDE {
163     ASSERT_LE(bookmark_count_ + bookmarks.size(), arraysize(kFirefoxBookmarks));
164     // Importer should import the FF favorites the same as the list, in the same
165     // order.
166     for (size_t i = 0; i < bookmarks.size(); ++i) {
167       EXPECT_NO_FATAL_FAILURE(
168           TestEqualBookmarkEntry(bookmarks[i],
169                                  kFirefoxBookmarks[bookmark_count_])) << i;
170       ++bookmark_count_;
171     }
172   }
173
174   virtual void AddKeywords(ScopedVector<TemplateURL> template_urls,
175                            bool unique_on_host_and_path) OVERRIDE {
176     for (size_t i = 0; i < template_urls.size(); ++i) {
177       // The order might not be deterministic, look in the expected list for
178       // that template URL.
179       bool found = false;
180       base::string16 keyword = template_urls[i]->keyword();
181       for (size_t j = 0; j < arraysize(kFirefoxKeywords); ++j) {
182         if (template_urls[i]->keyword() ==
183                 base::WideToUTF16Hack(kFirefoxKeywords[j].keyword)) {
184           EXPECT_EQ(kFirefoxKeywords[j].url, template_urls[i]->url());
185           found = true;
186           break;
187         }
188       }
189       EXPECT_TRUE(found);
190       ++keyword_count_;
191     }
192   }
193
194   virtual void AddFavicons(
195       const std::vector<ImportedFaviconUsage>& favicons) OVERRIDE {
196   }
197
198  private:
199   virtual ~FirefoxObserver() {}
200
201   size_t bookmark_count_;
202   size_t history_count_;
203   size_t password_count_;
204   size_t keyword_count_;
205   bool import_search_engines_;
206 };
207
208 }  // namespace
209
210 // These tests need to be browser tests in order to be able to run the OOP
211 // import (via ExternalProcessImporterHost) which launches a utility process on
212 // supported platforms.
213 class FirefoxProfileImporterBrowserTest : public InProcessBrowserTest {
214  protected:
215   virtual void SetUp() OVERRIDE {
216     // Creates a new profile in a new subdirectory in the temp directory.
217     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
218     base::FilePath test_path = temp_dir_.path().AppendASCII("ImporterTest");
219     base::DeleteFile(test_path, true);
220     base::CreateDirectory(test_path);
221     profile_path_ = test_path.AppendASCII("profile");
222     app_path_ = test_path.AppendASCII("app");
223     base::CreateDirectory(app_path_);
224
225     // This will launch the browser test and thus needs to happen last.
226     InProcessBrowserTest::SetUp();
227   }
228
229   void Firefox3xImporterBrowserTest(
230       std::string profile_dir,
231       importer::ImporterProgressObserver* observer,
232       ProfileWriter* writer,
233       bool import_search_plugins) {
234     base::FilePath data_path;
235     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
236     data_path = data_path.AppendASCII(profile_dir);
237     ASSERT_TRUE(base::CopyDirectory(data_path, profile_path_, true));
238     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
239     data_path = data_path.AppendASCII("firefox3_nss");
240     ASSERT_TRUE(base::CopyDirectory(data_path, profile_path_, false));
241
242     base::FilePath search_engine_path = app_path_;
243     search_engine_path = search_engine_path.AppendASCII("searchplugins");
244     base::CreateDirectory(search_engine_path);
245     if (import_search_plugins) {
246       ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
247       data_path = data_path.AppendASCII("firefox3_searchplugins");
248       if (!base::PathExists(data_path)) {
249         // TODO(maruel):  Create search test data that we can open source!
250         LOG(ERROR) << L"Missing internal test data";
251         return;
252       }
253       ASSERT_TRUE(base::CopyDirectory(data_path, search_engine_path, false));
254     }
255
256     importer::SourceProfile source_profile;
257     source_profile.importer_type = importer::TYPE_FIREFOX;
258     source_profile.app_path = app_path_;
259     source_profile.source_path = profile_path_;
260     source_profile.locale = "en-US";
261
262     int items = importer::HISTORY | importer::PASSWORDS | importer::FAVORITES;
263     if (import_search_plugins)
264       items = items | importer::SEARCH_ENGINES;
265
266     // Deletes itself.
267     ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
268     host->set_observer(observer);
269     host->StartImportSettings(source_profile,
270                               browser()->profile(),
271                               items,
272                               make_scoped_refptr(writer).get());
273     base::MessageLoop::current()->Run();
274   }
275
276   base::ScopedTempDir temp_dir_;
277   base::FilePath profile_path_;
278   base::FilePath app_path_;
279 };
280
281 IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
282                        MAYBE_IMPORTER(Firefox30Importer)) {
283   scoped_refptr<FirefoxObserver> observer(new FirefoxObserver());
284   Firefox3xImporterBrowserTest("firefox3_profile", observer.get(),
285                                observer.get(), true);
286 }
287
288 IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
289                        MAYBE_IMPORTER(Firefox35Importer)) {
290   bool import_search_engines = false;
291   scoped_refptr<FirefoxObserver> observer(
292       new FirefoxObserver(import_search_engines));
293   Firefox3xImporterBrowserTest("firefox35_profile", observer.get(),
294                                observer.get(), import_search_engines);
295 }