Upstream version 10.39.225.0
[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/files/file_path.h"
6 #include "base/files/file_util.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/ui/browser.h"
18 #include "chrome/common/chrome_paths.h"
19 #include "chrome/common/importer/imported_bookmark_entry.h"
20 #include "chrome/common/importer/imported_favicon_usage.h"
21 #include "chrome/common/importer/importer_data_types.h"
22 #include "chrome/test/base/in_process_browser_test.h"
23 #include "components/autofill/core/browser/webdata/autofill_entry.h"
24 #include "components/autofill/core/common/password_form.h"
25 #include "components/search_engines/template_url.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 // TODO(estade): some of these are disabled on mac. http://crbug.com/48007
29 // TODO(jschuh): Disabled on Win64 build. http://crbug.com/179688
30 #if defined(OS_MACOSX) || (defined(OS_WIN) && defined(ARCH_CPU_X86_64))
31 #define MAYBE_IMPORTER(x) DISABLED_##x
32 #else
33 #define MAYBE_IMPORTER(x) x
34 #endif
35
36 namespace {
37
38 struct PasswordInfo {
39   const char* origin;
40   const char* action;
41   const char* realm;
42   const char* username_element;
43   const char* username;
44   const char* password_element;
45   const char* password;
46   bool blacklisted;
47 };
48
49 struct KeywordInfo {
50   const wchar_t* keyword_in_sqlite;
51   const wchar_t* keyword_in_json;
52   const char* url;
53 };
54
55 struct AutofillFormDataInfo {
56   const char* name;
57   const char* value;
58 };
59
60 const BookmarkInfo kFirefoxBookmarks[] = {
61   {true, 1, {"Bookmarks Toolbar"},
62     L"Toolbar",
63     "http://site/"},
64   {false, 0, {},
65     L"Title",
66     "http://www.google.com/"},
67 };
68
69 const PasswordInfo kFirefoxPasswords[] = {
70   {"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/",
71     "loginuser", "abc", "loginpass", "123", false},
72   {"http://localhost:8080/", "", "http://localhost:8080/localhost",
73     "", "http", "", "Http1+1abcdefg", false},
74 };
75
76 const KeywordInfo kFirefoxKeywords[] = {
77     {L"amazon.com", L"amazon.com",
78      "http://www.amazon.com/exec/obidos/external-search/?field-keywords="
79      "{searchTerms}&mode=blended"},
80     {L"answers.com", L"answers.com",
81      "http://www.answers.com/main/ntquery?s={searchTerms}&gwp=13"},
82     {L"search.creativecommons.org", L"search.creativecommons.org",
83      "http://search.creativecommons.org/?q={searchTerms}"},
84     {L"search.ebay.com", L"search.ebay.com",
85      "http://search.ebay.com/search/search.dll?query={searchTerms}&"
86      "MfcISAPICommand=GetResult&ht=1&ebaytag1=ebayreg&srchdesc=n&"
87      "maxRecordsReturned=300&maxRecordsPerPage=50&SortProperty=MetaEndSort"},
88     {L"google.com", L"google.com",
89      "http://www.google.com/search?q={searchTerms}&ie=utf-8&oe=utf-8&aq=t"},
90     {L"en.wikipedia.org", L"wiki",
91      "http://en.wikipedia.org/wiki/Special:Search?search={searchTerms}"},
92     {L"search.yahoo.com", L"search.yahoo.com",
93      "http://search.yahoo.com/search?p={searchTerms}&ei=UTF-8"},
94     {L"flickr.com", L"flickr.com",
95      "http://www.flickr.com/photos/tags/?q={searchTerms}"},
96     {L"imdb.com", L"imdb.com", "http://www.imdb.com/find?q={searchTerms}"},
97     {L"webster.com", L"webster.com",
98      "http://www.webster.com/cgi-bin/dictionary?va={searchTerms}"},
99     // Search keywords.
100     {L"\x4E2D\x6587", L"\x4E2D\x6587", "http://www.google.com/"},
101 };
102
103 const AutofillFormDataInfo kFirefoxAutofillEntries[] = {
104     {"name", "John"},
105     {"address", "#123 Cherry Ave"},
106     {"city", "Mountain View"},
107     {"zip", "94043"},
108     {"n300", "+1 (408) 871-4567"},
109     {"name", "john"},
110     {"name", "aguantó"},
111     {"address", "télévision@example.com"},
112     {"city", "&$%$$$ TESTO *&*&^&^& MOKO"},
113     {"zip", "WOHOOOO$$$$$$$$****"},
114     {"n300", "\xe0\xa4\x9f\xe2\x97\x8c\xe0\xa4\xbe\xe0\xa4\xaf\xe0\xa4\xb0"},
115     {"n300", "\xe4\xbb\xa5\xe7\x8e\xa9\xe4\xb8\xba\xe4\xb8\xbb"}
116 };
117
118 class FirefoxObserver : public ProfileWriter,
119                         public importer::ImporterProgressObserver {
120  public:
121   explicit FirefoxObserver(bool use_keyword_in_json)
122       : ProfileWriter(NULL),
123         bookmark_count_(0),
124         history_count_(0),
125         password_count_(0),
126         keyword_count_(0),
127         use_keyword_in_json_(use_keyword_in_json) {}
128
129   // importer::ImporterProgressObserver:
130   virtual void ImportStarted() OVERRIDE {}
131   virtual void ImportItemStarted(importer::ImportItem item) OVERRIDE {}
132   virtual void ImportItemEnded(importer::ImportItem item) OVERRIDE {}
133   virtual void ImportEnded() OVERRIDE {
134     base::MessageLoop::current()->Quit();
135     EXPECT_EQ(arraysize(kFirefoxBookmarks), bookmark_count_);
136     EXPECT_EQ(1U, history_count_);
137     EXPECT_EQ(arraysize(kFirefoxPasswords), password_count_);
138     EXPECT_EQ(arraysize(kFirefoxKeywords), keyword_count_);
139   }
140
141   virtual bool BookmarkModelIsLoaded() const OVERRIDE {
142     // Profile is ready for writing.
143     return true;
144   }
145
146   virtual bool TemplateURLServiceIsLoaded() const OVERRIDE {
147     return true;
148   }
149
150   virtual void AddPasswordForm(const autofill::PasswordForm& form) OVERRIDE {
151     PasswordInfo p = kFirefoxPasswords[password_count_];
152     EXPECT_EQ(p.origin, form.origin.spec());
153     EXPECT_EQ(p.realm, form.signon_realm);
154     EXPECT_EQ(p.action, form.action.spec());
155     EXPECT_EQ(base::ASCIIToUTF16(p.username_element), form.username_element);
156     EXPECT_EQ(base::ASCIIToUTF16(p.username), form.username_value);
157     EXPECT_EQ(base::ASCIIToUTF16(p.password_element), form.password_element);
158     EXPECT_EQ(base::ASCIIToUTF16(p.password), form.password_value);
159     EXPECT_EQ(p.blacklisted, form.blacklisted_by_user);
160     ++password_count_;
161   }
162
163   virtual void AddHistoryPage(const history::URLRows& page,
164                               history::VisitSource visit_source) OVERRIDE {
165     ASSERT_EQ(3U, page.size());
166     EXPECT_EQ("http://www.google.com/", page[0].url().spec());
167     EXPECT_EQ(base::ASCIIToUTF16("Google"), page[0].title());
168     EXPECT_EQ("http://www.google.com/", page[1].url().spec());
169     EXPECT_EQ(base::ASCIIToUTF16("Google"), page[1].title());
170     EXPECT_EQ("http://www.cs.unc.edu/~jbs/resources/perl/perl-cgi/programs/"
171               "form1-POST.html", page[2].url().spec());
172     EXPECT_EQ(base::ASCIIToUTF16("example form (POST)"), page[2].title());
173     EXPECT_EQ(history::SOURCE_FIREFOX_IMPORTED, visit_source);
174     ++history_count_;
175   }
176
177   virtual void AddBookmarks(
178       const std::vector<ImportedBookmarkEntry>& bookmarks,
179       const base::string16& top_level_folder_name) OVERRIDE {
180     ASSERT_LE(bookmark_count_ + bookmarks.size(), arraysize(kFirefoxBookmarks));
181     // Importer should import the FF favorites the same as the list, in the same
182     // order.
183     for (size_t i = 0; i < bookmarks.size(); ++i) {
184       EXPECT_NO_FATAL_FAILURE(
185           TestEqualBookmarkEntry(bookmarks[i],
186                                  kFirefoxBookmarks[bookmark_count_])) << i;
187       ++bookmark_count_;
188     }
189   }
190
191   virtual void AddAutofillFormDataEntries(
192       const std::vector<autofill::AutofillEntry>& autofill_entries) OVERRIDE {
193     EXPECT_EQ(arraysize(kFirefoxAutofillEntries), autofill_entries.size());
194     for (size_t i = 0; i < arraysize(kFirefoxAutofillEntries); ++i) {
195       EXPECT_EQ(kFirefoxAutofillEntries[i].name,
196                 base::UTF16ToUTF8(autofill_entries[i].key().name()));
197       EXPECT_EQ(kFirefoxAutofillEntries[i].value,
198                 base::UTF16ToUTF8(autofill_entries[i].key().value()));
199     }
200   }
201
202   virtual void AddKeywords(ScopedVector<TemplateURL> template_urls,
203                            bool unique_on_host_and_path) OVERRIDE {
204     for (size_t i = 0; i < template_urls.size(); ++i) {
205       // The order might not be deterministic, look in the expected list for
206       // that template URL.
207       bool found = false;
208       const base::string16& imported_keyword = template_urls[i]->keyword();
209       for (size_t j = 0; j < arraysize(kFirefoxKeywords); ++j) {
210         const base::string16 expected_keyword = base::WideToUTF16(
211             use_keyword_in_json_ ?
212             kFirefoxKeywords[j].keyword_in_json :
213             kFirefoxKeywords[j].keyword_in_sqlite);
214         if (imported_keyword == expected_keyword) {
215           EXPECT_EQ(kFirefoxKeywords[j].url, template_urls[i]->url());
216           found = true;
217           break;
218         }
219       }
220       EXPECT_TRUE(found);
221       ++keyword_count_;
222     }
223   }
224
225   virtual void AddFavicons(
226       const std::vector<ImportedFaviconUsage>& favicons) OVERRIDE {
227   }
228
229  private:
230   virtual ~FirefoxObserver() {}
231
232   size_t bookmark_count_;
233   size_t history_count_;
234   size_t password_count_;
235   size_t keyword_count_;
236
237   // Newer versions of Firefox can store custom keyword names in json, which
238   // override the sqlite values. To be able to test both older and newer
239   // versions, tests set this variable to indicate whether to expect the
240   // |keyword_in_sqlite| or |keyword_in_json| values from the reference data.
241   bool use_keyword_in_json_;
242 };
243
244 }  // namespace
245
246 // These tests need to be browser tests in order to be able to run the OOP
247 // import (via ExternalProcessImporterHost) which launches a utility process on
248 // supported platforms.
249 class FirefoxProfileImporterBrowserTest : public InProcessBrowserTest {
250  protected:
251   virtual void SetUp() OVERRIDE {
252     // Creates a new profile in a new subdirectory in the temp directory.
253     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
254     base::FilePath test_path = temp_dir_.path().AppendASCII("ImporterTest");
255     base::DeleteFile(test_path, true);
256     base::CreateDirectory(test_path);
257     profile_path_ = test_path.AppendASCII("profile");
258     app_path_ = test_path.AppendASCII("app");
259     base::CreateDirectory(app_path_);
260
261     // This will launch the browser test and thus needs to happen last.
262     InProcessBrowserTest::SetUp();
263   }
264
265   void FirefoxImporterBrowserTest(std::string profile_dir,
266                                   importer::ImporterProgressObserver* observer,
267                                   ProfileWriter* writer) {
268     base::FilePath data_path;
269     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
270     data_path = data_path.AppendASCII(profile_dir);
271     ASSERT_TRUE(base::CopyDirectory(data_path, profile_path_, true));
272
273     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
274     data_path = data_path.AppendASCII("firefox3_nss");
275     ASSERT_TRUE(base::CopyDirectory(data_path, profile_path_, false));
276
277     // Create a directory to house default search engines.
278     base::FilePath default_search_engine_path =
279         app_path_.AppendASCII("searchplugins");
280     base::CreateDirectory(default_search_engine_path);
281
282     // Create a directory to house custom/installed search engines.
283     base::FilePath custom_search_engine_path =
284         profile_path_.AppendASCII("searchplugins");
285     base::CreateDirectory(custom_search_engine_path);
286
287     // Copy over search engines.
288     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
289     data_path = data_path.AppendASCII("firefox_searchplugins");
290     base::FilePath default_search_engine_source_path =
291         data_path.AppendASCII("default");
292     base::FilePath custom_search_engine_source_path =
293         data_path.AppendASCII("custom");
294     ASSERT_TRUE(base::CopyDirectory(
295         default_search_engine_source_path, default_search_engine_path, false));
296     ASSERT_TRUE(base::CopyDirectory(
297         custom_search_engine_source_path, custom_search_engine_path, false));
298
299     importer::SourceProfile source_profile;
300     source_profile.importer_type = importer::TYPE_FIREFOX;
301     source_profile.app_path = app_path_;
302     source_profile.source_path = profile_path_;
303     source_profile.locale = "en-US";
304
305     int items = importer::HISTORY | importer::PASSWORDS | importer::FAVORITES |
306                 importer::SEARCH_ENGINES | importer::AUTOFILL_FORM_DATA;
307
308     // Deletes itself.
309     ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
310     host->set_observer(observer);
311     host->StartImportSettings(
312         source_profile, browser()->profile(), items, writer);
313     base::MessageLoop::current()->Run();
314   }
315
316   base::ScopedTempDir temp_dir_;
317   base::FilePath profile_path_;
318   base::FilePath app_path_;
319 };
320
321 IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
322                        MAYBE_IMPORTER(Firefox30Importer)) {
323   scoped_refptr<FirefoxObserver> observer(new FirefoxObserver(false));
324   FirefoxImporterBrowserTest(
325       "firefox3_profile", observer.get(), observer.get());
326 }
327
328 IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
329                        MAYBE_IMPORTER(Firefox35Importer)) {
330   scoped_refptr<FirefoxObserver> observer(new FirefoxObserver(false));
331   FirefoxImporterBrowserTest(
332       "firefox35_profile", observer.get(), observer.get());
333 }
334
335 IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
336                        MAYBE_IMPORTER(FirefoxImporter)) {
337   scoped_refptr<FirefoxObserver> observer(new FirefoxObserver(true));
338   FirefoxImporterBrowserTest("firefox_profile", observer.get(), observer.get());
339 }